tpfalinearizerstructs.hh
Go to the documentation of this file.
1/*
2 Copyright 2026 Equinor ASA
3 This file is part of the Open Porous Media project (OPM).
4 OPM is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8 OPM is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with OPM. If not, see <http://www.gnu.org/licenses/>.
14*/
15
16#ifndef TPFA_LINEARIZER_STRUCTS_HH
17#define TPFA_LINEARIZER_STRUCTS_HH
18
24#include <cassert>
25#include <vector>
26
27#include <opm/common/Exceptions.hpp>
28#include <opm/grid/utility/SparseTable.hpp>
29#include <opm/input/eclipse/Schedule/BCProp.hpp>
30
31#include <opm/common/utility/gpuistl_if_available.hpp>
32#include <opm/common/utility/pointerArithmetic.hpp>
33
34namespace Opm {
35
36template <class Storage = std::vector<int>>
38{
39 Storage cells;
40};
41
42#if HAVE_CUDA && OPM_IS_COMPILING_WITH_GPU_COMPILER
44{
45 if (CPUDomain.cells.size() == 0) {
46 OPM_THROW(std::runtime_error, "Cannot copy empty full domain to GPU.");
47 }
48 return FullDomain<gpuistl::GpuBuffer<int>>{
49 gpuistl::GpuBuffer<int>(CPUDomain.cells)
50 };
51};
52
53inline FullDomain<gpuistl::GpuView<int>> make_view(FullDomain<gpuistl::GpuBuffer<int>>& buffer)
54{
55 if (buffer.cells.size() == 0) {
56 OPM_THROW(std::runtime_error, "Cannot make view of empty full domain buffer.");
57 }
58 return FullDomain<gpuistl::GpuView<int>>{
59 gpuistl::make_view(buffer.cells)
60 };
61};
62#endif
63
64template <class ResidualNBInfoType, class BlockType>
66{
67 unsigned int neighbor;
68 ResidualNBInfoType res_nbinfo;
69 BlockType* matBlockAddress;
70
71 template <class PtrType>
72 NeighborInfoStruct(unsigned int n, const ResidualNBInfoType& r, PtrType ptr)
73 : neighbor(n)
74 , res_nbinfo(r)
75 , matBlockAddress(static_cast<BlockType*>(ptr))
76 {
77 }
78
79 // Add a default constructor
81 : neighbor(0)
82 , res_nbinfo()
83 , matBlockAddress(nullptr)
84 {
85 }
86};
87
88template <class VectorBlock, class ScalarFluidState>
90 BCType type;
91 VectorBlock massRate;
92 unsigned pvtRegionIdx;
94 double faceArea;
95 double faceZCoord;
96 ScalarFluidState exFluidState;
97};
98
99template <class BoundaryConditionData>
101 unsigned int cell;
102 int dir;
103 unsigned int bfIndex;
105};
106
107#if HAVE_CUDA && OPM_IS_COMPILING_WITH_GPU_COMPILER
108namespace gpuistl {
109
110 template <class MiniMatrixType,
111 class GpuMatrixType,
112 class CpuMatrixType,
113 class MatrixBlockType,
114 class ResidualNBInfoType>
116 cpuNeighborInfoTable,
117 GpuMatrixType& gpuJacobian,
118 CpuMatrixType& cpuJacobian)
119 {
120 // Convert the DUNE FieldVectors to MiniMatrix types
122 using Scalar = typename GpuMatrixType::field_type;
123 std::vector<StructWithMinimatrix> minimatrices(cpuNeighborInfoTable.dataSize());
124 Scalar* gpuBufStart = gpuJacobian.getNonZeroValues().data();
125 Scalar* cpuBufStart = &(cpuJacobian[0][0][0][0]);
126
127 // To compute the length of the buffer of the cpuJacobian we here assume we have a blocked
128 // BCRS matrix with square blocks and that the blocks are stored as Dune::FieldMatrix
129 using CpuBlockType = typename CpuMatrixType::block_type::BaseType;
130
131 const size_t gpuBufferSize
132 = gpuJacobian.nonzeroes() * gpuJacobian.blockSize() * gpuJacobian.blockSize();
133 const size_t cpuBufferSize
134 = cpuJacobian.nonzeroes() * CpuBlockType::rows * CpuBlockType::cols;
135 assert(gpuBufferSize == cpuBufferSize);
136
137 const auto& dataStorage = cpuNeighborInfoTable.dataStorage();
138 const size_t dataSize = cpuNeighborInfoTable.dataSize();
139#ifdef _OPENMP
140#pragma omp parallel for
141#endif
142 for (size_t idx = 0; idx < dataSize; ++idx) {
143 const auto& e = dataStorage[idx];
144 Scalar* cpuPtr = &((*e.matBlockAddress)[0][0]);
145
146 // convert the pointer from CPU to GPU pointer based on offset in CPU jacobian
147 Scalar* gpuPtr = ComputePtrBasedOnOffsetInOtherBuffer(
148 gpuBufStart, gpuBufferSize, cpuBufStart, cpuBufferSize, cpuPtr);
149
150 minimatrices[idx] = StructWithMinimatrix(
151 e.neighbor, e.res_nbinfo, reinterpret_cast<MiniMatrixType*>(gpuPtr));
152 }
153
155 gpuistl::GpuBuffer<StructWithMinimatrix>(minimatrices),
156 gpuistl::GpuBuffer<int>(cpuNeighborInfoTable.rowStarts())
157 );
158 }
159
160 // Handle the BoundaryInfo structs
161 template <class GpuVecBlock,
162 class GpuFluidState,
163 class BoundaryInfoTypeGPU,
164 class BoundaryInfoTypeCPU,
165 typename GpuFluidSystemPtr>
166 auto copy_to_gpu(const std::vector<BoundaryInfoTypeCPU>& cpu_boundary_info,
167 const GpuFluidSystemPtr& dynamicGpuFluidSystemPtr)
168 {
169 std::vector<BoundaryInfoTypeGPU> gpu_boundary_info;
170 for (const auto& info : cpu_boundary_info) {
171 gpu_boundary_info.push_back(BoundaryInfoTypeGPU {
172 info.cell,
173 info.dir,
174 info.bfIndex,
175 BoundaryConditionData<GpuVecBlock, GpuFluidState> {
176 info.bcdata.type,
177 GpuVecBlock(info.bcdata.massRate),
178 info.bcdata.pvtRegionIdx,
179 info.bcdata.boundaryFaceIndex,
180 info.bcdata.faceArea,
181 info.bcdata.faceZCoord,
182 info.bcdata.exFluidState.withOtherFluidSystem(dynamicGpuFluidSystemPtr)}});
183 }
184
185 return gpuistl::GpuBuffer<BoundaryInfoTypeGPU>(gpu_boundary_info);
186 }
187
188 // Implemented for residual_, which is a vector of FieldVectors.
189 // We then make a GpuBuffer of MiniVectors.
190 template <class CPUResidualType, class GpuMiniVector>
191 auto copy_to_gpu_residual(CPUResidualType& residual)
192 {
193 std::vector<GpuMiniVector> vectorOfMiniVectors;
194 for (const auto& minivec : residual) {
195 vectorOfMiniVectors.emplace_back(minivec);
196 }
197
198 return gpuistl::GpuBuffer<GpuMiniVector>(vectorOfMiniVectors);
199 }
200
201} // namespace gpuistl
202#endif
203
204} // namespace Opm
205
206#endif // TPFA_LINEARIZER_STRUCTS_HH
Definition: BlackoilWellModel.hpp:88
ThermalGasWaterFlowProblem< Scalar, GpuView > make_view(ThermalGasWaterFlowProblem< Scalar, GpuBuffer > &buffer)
Definition: ThermalGasWaterFlowProblem.hpp:111
ThermalGasWaterFlowProblem< Scalar, GpuBuffer > copy_to_gpu(ThermalGasWaterFlowProblem< Scalar, Opm::VectorWithDefaultAllocator > &cpuProblem)
Definition: ThermalGasWaterFlowProblem.hpp:99
Definition: blackoilbioeffectsmodules.hh:45
Definition: tpfalinearizerstructs.hh:89
double faceArea
Definition: tpfalinearizerstructs.hh:94
VectorBlock massRate
Definition: tpfalinearizerstructs.hh:91
BCType type
Definition: tpfalinearizerstructs.hh:90
unsigned boundaryFaceIndex
Definition: tpfalinearizerstructs.hh:93
double faceZCoord
Definition: tpfalinearizerstructs.hh:95
ScalarFluidState exFluidState
Definition: tpfalinearizerstructs.hh:96
unsigned pvtRegionIdx
Definition: tpfalinearizerstructs.hh:92
Definition: tpfalinearizerstructs.hh:100
unsigned int cell
Definition: tpfalinearizerstructs.hh:101
unsigned int bfIndex
Definition: tpfalinearizerstructs.hh:103
BoundaryConditionData bcdata
Definition: tpfalinearizerstructs.hh:104
int dir
Definition: tpfalinearizerstructs.hh:102
Definition: tpfalinearizerstructs.hh:38
Storage cells
Definition: tpfalinearizerstructs.hh:39
Definition: tpfalinearizerstructs.hh:66
NeighborInfoStruct(unsigned int n, const ResidualNBInfoType &r, PtrType ptr)
Definition: tpfalinearizerstructs.hh:72
NeighborInfoStruct()
Definition: tpfalinearizerstructs.hh:80
BlockType * matBlockAddress
Definition: tpfalinearizerstructs.hh:69
ResidualNBInfoType res_nbinfo
Definition: tpfalinearizerstructs.hh:68
unsigned int neighbor
Definition: tpfalinearizerstructs.hh:67