30#ifndef TPFA_LINEARIZER_GPU_PARAMS_HH
31#define TPFA_LINEARIZER_GPU_PARAMS_HH
33#if HAVE_CUDA && OPM_IS_COMPILING_WITH_GPU_COMPILER
39#include <opm/common/utility/gpuistl_if_available.hpp>
42#include <opm/simulators/linalg/gpuistl_hip/GpuSparseMatrixWrapper.hpp>
43#include <opm/simulators/linalg/gpuistl_hip/MiniMatrix.hpp>
44#include <opm/simulators/linalg/gpuistl_hip/MiniVector.hpp>
51#include <opm/common/utility/SparseTable.hpp>
73template <
class TypeTag>
74class TpfaLinearizerGpuParams
76 using Scalar = GetPropType<TypeTag, Properties::Scalar>;
77 using GlobalEqVector = GetPropType<TypeTag, Properties::GlobalEqVector>;
78 using SparseMatrixAdapter = GetPropType<TypeTag, Properties::SparseMatrixAdapter>;
79 using LocalResidual = GetPropType<TypeTag, Properties::LocalResidual>;
80 using IntensiveQuantities = GetPropType<TypeTag, Properties::IntensiveQuantities>;
81 using FluidSystem = GetPropType<TypeTag, Properties::FluidSystem>;
82 using Model = GetPropType<TypeTag, Properties::Model>;
83 using Problem = GetPropType<TypeTag, Properties::Problem>;
85 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
87 using MatrixBlockCPU =
typename SparseMatrixAdapter::MatrixBlock;
88 using VectorBlockCPU = Dune::FieldVector<Scalar, numEq>;
89 using MatrixBlockGPU = gpuistl::MiniMatrix<Scalar, numEq>;
90 using VectorBlockGPU = gpuistl::MiniVector<Scalar, numEq>;
92 using ResidualNBInfo =
typename LocalResidual::ResidualNBInfo;
93 using NeighborInfoCPU = NeighborInfoStruct<ResidualNBInfo, MatrixBlockCPU>;
94 using NeighborInfoGPU = NeighborInfoStruct<ResidualNBInfo, MatrixBlockGPU>;
96 using ScalarFluidState =
typename IntensiveQuantities::ScalarFluidState;
97 using BoundaryConditionDataCPU = BoundaryConditionData<VectorBlockCPU, ScalarFluidState>;
98 using BoundaryInfoCPU = BoundaryInfo<BoundaryConditionDataCPU>;
102 using NonStaticFluidSystem = std::decay_t<
decltype(FluidSystem::getNonStaticInstance())>;
104 std::declval<NonStaticFluidSystem&>()))>;
105 using GpuFluidSystemView
106 = std::decay_t<decltype(::Opm::gpuistl::make_view(std::declval<GpuFluidSystemBuffer&>()))>;
107 using GpuFluidSystemPtr = std::shared_ptr<GpuFluidSystemView>;
111 using CorrectTypeTagView =
112 typename ::Opm::Properties::TTag::to_gpu_type_t<TypeTag, gpuistl::GpuView>;
116 using GPUBOIQ = BlackOilIntensiveQuantities<CorrectTypeTagView>;
117 using LocalResidualGPU = BlackOilLocalResidualTPFA<CorrectTypeTagView>;
120 using GpuScalarFluidState =
typename GPUBOIQ::ScalarFluidState;
121 using BoundaryConditionDataGPU = BoundaryConditionData<VectorBlockGPU, GpuScalarFluidState>;
122 using BoundaryInfoGPU = BoundaryInfo<BoundaryConditionDataGPU>;
124 using GpuModelBufferType = SimpleFIBlackOilModel<CorrectTypeTagView, gpuistl::GpuBuffer>;
125 using GpuFlowProblemBufferType = ThermalGasWaterFlowProblem<Scalar, gpuistl::GpuBuffer>;
127 using GpuModel = GetPropType<TypeTag, Properties::GpuFIBlackOilModel>;
129 FullDomain<gpuistl::GpuBuffer<int>> domainBuffer_;
130 SparseTable<NeighborInfoGPU, gpuistl::GpuBuffer> neighborInfoBuffer_;
132 gpuistl::GpuView<MatrixBlockGPU*> diagMatAddressView_;
133 gpuistl::GpuBuffer<VectorBlockGPU> residualBuffer_;
134 gpuistl::GpuView<VectorBlockGPU>
138 GpuFluidSystemBuffer dynamicGpuFluidSystemBuffer_;
141 GpuFluidSystemPtr dynamicGpuFluidSystemPtr_;
142 GpuModelBufferType gpuModelBuffer_;
143 GpuFlowProblemBufferType gpuFlowProblemBuffer_;
144 gpuistl::GpuBuffer<BoundaryInfoGPU> boundaryInfoBuffer_;
167 TpfaLinearizerGpuParams(
const FullDomain<>& domain,
168 const SparseTable<NeighborInfoCPU>& neighborInfo,
169 gpuistl::GpuSparseMatrixWrapper<Scalar>& gpuJacobian,
170 gpuistl::GpuBuffer<MatrixBlockGPU*>& gpuBufferDiagMatAddress,
171 typename SparseMatrixAdapter::IstlMatrix& cpuJacobian,
172 GlobalEqVector& residual,
173 const std::vector<BoundaryInfoCPU>& boundaryInfo,
175 const Problem& problem,
176 unsigned int numCells)
178 , neighborInfoBuffer_(
179 gpuistl::
copy_to_gpu<MatrixBlockGPU>(neighborInfo, gpuJacobian, cpuJacobian))
180 , diagMatAddressView_(gpuistl::
make_view(gpuBufferDiagMatAddress))
181 , residualBuffer_(gpuistl::copy_to_gpu_residual<GlobalEqVector, VectorBlockGPU>(residual))
182 , residualView_(gpuistl::
make_view(residualBuffer_))
183 , dynamicGpuFluidSystemBuffer_(
185 , dynamicGpuFluidSystemPtr_(
187 , gpuModelBuffer_([&]() -> GpuModelBufferType {
188 std::vector<Scalar> volumes(numCells);
189 for (
unsigned i = 0; i < numCells; ++i) {
190 volumes[domain.cells[i]] = model.dofTotalVolume(domain.cells[i]);
193 model.intensiveQuantityCache()[0], model.intensiveQuantityCache()[1], volumes);
196 , gpuFlowProblemBuffer_([&]() -> GpuFlowProblemBufferType {
197 std::vector<Scalar> alpha0(numCells);
198 std::vector<Scalar> alpha1(numCells);
199 std::vector<Scalar> alpha2(numCells);
200 std::vector<Scalar> alpha3(numCells);
201 std::vector<Scalar> alpha4(numCells);
202 std::vector<Scalar> alpha5(numCells);
203 const auto& thermalHalfTransBoundary
204 = problem.eclTransmissibilities().getThermalHalfTransBoundary();
205 for (
const auto& [key, value] : thermalHalfTransBoundary) {
206 const unsigned cell = key.first;
207 const unsigned dir = key.second;
209 alpha0[cell] = value;
210 }
else if (dir == 1) {
211 alpha1[cell] = value;
212 }
else if (dir == 2) {
213 alpha2[cell] = value;
214 }
else if (dir == 3) {
215 alpha3[cell] = value;
216 }
else if (dir == 4) {
217 alpha4[cell] = value;
218 }
else if (dir == 5) {
219 alpha5[cell] = value;
221 OPM_THROW(std::logic_error,
222 "Invalid direction for thermal half transmissibility: "
226 ThermalGasWaterFlowProblem<Scalar> gpuFlowProblem(
227 alpha0, alpha1, alpha2, alpha3, alpha4, alpha5, problem.moduleParams());
230 , boundaryInfoBuffer_(
231 gpuistl::copy_to_gpu<VectorBlockGPU, GpuScalarFluidState, BoundaryInfoGPU>(
232 boundaryInfo, *dynamicGpuFluidSystemPtr_.get()))
241 auto neighborInfoView()
246 auto& diagMatAddressView()
248 return diagMatAddressView_;
253 return residualView_;
261 auto flowProblemView()
266 auto boundaryInfoView()
271 std::size_t boundaryInfoSize()
const
273 return boundaryInfoBuffer_.size();
282 void copyResidualToHost(GlobalEqVector& residual,
unsigned numCells)
284 auto cpuResidualFromGpu = residualBuffer_.asStdVector();
285 std::memcpy(residual.data(), cpuResidualFromGpu.data(), numCells * numEq *
sizeof(Scalar));
293 void copyJacobianToHost(SparseMatrixAdapter& jacobian,
294 gpuistl::GpuSparseMatrixWrapper<Scalar>& gpuJacobian)
296 auto gpuJacobianNonZeroes = gpuJacobian.getNonZeroValues().asStdVector();
297 auto& cpuJacobian = jacobian.istlMatrix();
298 const std::size_t totalMatrixSize = cpuJacobian.nonzeroes() * numEq * numEq;
299 std::memcpy(&(cpuJacobian[0][0][0][0]),
300 gpuJacobianNonZeroes.data(),
301 totalMatrixSize *
sizeof(Scalar));
inline ::Opm::NoThermalLawManager make_view(::Opm::NoThermalLawManager &)
make_view overload for the no-op thermal manager.
Definition: GpuFlowProblem.hpp:102
std::shared_ptr< T > make_gpu_shared_ptr()
Creates a shared pointer managing GPU-allocated memory of the specified element type.
Definition: gpu_smart_pointer.hpp:49
inline ::Opm::NoThermalLawManager copy_to_gpu(const ::Opm::NoThermalLawManager &)
copy_to_gpu overload for the no-op thermal manager.
Definition: GpuFlowProblem.hpp:95
Definition: blackoilbioeffectsmodules.hh:45
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)