SimpleFIBlackOilModel.hpp
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
28#ifndef SIMPLE_FI_BLACK_OIL_MODEL_HPP
29#define SIMPLE_FI_BLACK_OIL_MODEL_HPP
30
36
37#include <opm/common/ErrorMacros.hpp>
38
39#include <opm/grid/CpGrid.hpp>
40#include <opm/grid/utility/ElementChunks.hpp>
41
43
44#include <opm/material/fluidmatrixinteractions/EclMultiplexerMaterialParams.hpp>
45
46#include <cassert>
47#include <cstddef>
48#include <stdexcept>
49#include <type_traits>
50#include <vector>
51
52#ifdef _OPENMP
53#include <omp.h>
54#endif
55
56/*
57 This file implements a simplified version of the FIBlackOilModel
58 which can be used in a GPU environment.
59 This is developed while parallelizing the tpfa matrix assembly, so
60 only functionality needed there is implemented.
61 To start with this means just being able to access intensiveQuantities.
62*/
63
64namespace Opm
65{
66
67template <typename TypeTag, template <class> class Storage = Opm::VectorWithDefaultAllocator>
69{
70public:
72 using TypeTagPublic = TypeTag;
74
76 const Storage<BlackOilIntensiveQuantities<TypeTag>>& cachedIntensiveQuantities0,
77 const Storage<BlackOilIntensiveQuantities<TypeTag>>& cachedIntensiveQuantities1,
78 const Storage<Scalar>& volumes)
79 : cachedIntensiveQuantities0_(cachedIntensiveQuantities0)
80 , cachedIntensiveQuantities1_(cachedIntensiveQuantities1)
81 , volumes_(volumes)
82 {
83 }
84
85 // Special ctor because fvbasediscretization stores BOIQs with a custom allocator.
86 // OtherIQContainer can be any container (e.g. std::vector with a non-default allocator).
87 // Could this be using refs instead of making the copy? Then the copy-to-gpu would have to be
88 // rewritten a bit
89 template <typename OtherIQContainer>
90 SimpleFIBlackOilModel(const OtherIQContainer& cachedIntensiveQuantities0,
91 const OtherIQContainer& cachedIntensiveQuantities1,
92 const Storage<Scalar>& volumes)
93 : cachedIntensiveQuantities0_(cachedIntensiveQuantities0.begin(),
94 cachedIntensiveQuantities0.end())
95 , cachedIntensiveQuantities1_(cachedIntensiveQuantities1.begin(),
96 cachedIntensiveQuantities1.end())
97 , volumes_(volumes)
98 {
99 }
100
102
103 OPM_HOST_DEVICE Scalar dofTotalVolume(unsigned int globalIdx) const
104 {
105 return volumes_[globalIdx];
106 }
107
108 OPM_HOST_DEVICE const auto& intensiveQuantities(unsigned int globalIdx,
109 unsigned int timeIdx) const
110 {
111 assert(timeIdx == 0
112 || timeIdx
113 == 1); // TODO: do not use assert for this because it can be run in GPU kernel...
114 if (timeIdx == 0) {
115 return cachedIntensiveQuantities0_[globalIdx];
116 } else {
117 return cachedIntensiveQuantities1_[globalIdx];
118 }
119 }
120
121public:
122 // assumes --enable-storage-cache=false so that we need not worry about updating cpu-caches from
123 // gpu kernels
124 Storage<BlackOilIntensiveQuantities<TypeTag>> cachedIntensiveQuantities0_;
125 Storage<BlackOilIntensiveQuantities<TypeTag>> cachedIntensiveQuantities1_;
126 Storage<Scalar> volumes_;
127};
128
129#if HAVE_CUDA && OPM_IS_COMPILING_WITH_GPU_COMPILER
130namespace gpuistl
131{
132 // For now we make a copy of the simplified CPU model because we need to set the fluid system
133 // pointer without breaking copy semantics
134 template <class TypeTag, typename GpuFluidSystem>
135 auto copy_to_gpu(const SimpleFIBlackOilModel<TypeTag>& cpuModel, const GpuFluidSystem& fsys)
136 {
137 using Scalar = typename SimpleFIBlackOilModel<TypeTag>::Scalar;
138 // In this copy_to_gpu we need to take care of two things:
139 // 1) Copy the cachedIntensiveQuantities_ to GPU (go from vector to GpuBuffer to allocate
140 // things on GPU) 2) Ensure that the FluidSystem pointer inside each IntensiveQuantities
141 // points to a GPU FluidSystem
142 // The pointer should be set before we move the entire thing to the GPU.
143
144 // set pointers
145 using CorrectTypeTagView =
146 typename ::Opm::Properties::TTag::to_gpu_type_t<TypeTag, GpuView>;
148 using SimplifiedGpuBufferModel = SimpleFIBlackOilModel<CorrectTypeTagView, GpuBuffer>;
149
150 assert(cpuModel.cachedIntensiveQuantities0_.size() == cpuModel.cachedIntensiveQuantities1_.size());
151 const std::size_t nCells = cpuModel.cachedIntensiveQuantities0_.size();
152 assert(nCells > 0);
153 // CorrectBOIQ is not default-constructible (non-static FluidSystem requires a pointer at
154 // construction time). To enable parallel fill, we create a prototype from the first element
155 // and use it to pre-size the vector with valid objects, then overwrite in parallel.
156 // Assumption: all cells share the same fsys pointer, so the prototype object is a valid
157 // stand-in until it is overwritten.
158 std::vector<CorrectBOIQ> cpuIntQuantsWithGpuPtr0;
159 std::vector<CorrectBOIQ> cpuIntQuantsWithGpuPtr1;
160 CorrectBOIQ proto0 = cpuModel.cachedIntensiveQuantities0_[0]
161 .template withOtherFluidSystem<CorrectTypeTagView>(fsys);
162 CorrectBOIQ proto1 = cpuModel.cachedIntensiveQuantities1_[0]
163 .template withOtherFluidSystem<CorrectTypeTagView>(fsys);
164 cpuIntQuantsWithGpuPtr0.resize(nCells, proto0);
165 cpuIntQuantsWithGpuPtr1.resize(nCells, proto1);
166
167#ifdef _OPENMP
168#pragma omp parallel for schedule(static)
169#endif
170 for (std::size_t i = 1; i < nCells; ++i) {
171 cpuIntQuantsWithGpuPtr0[i]
172 = cpuModel.cachedIntensiveQuantities0_[i]
173 .template withOtherFluidSystem<CorrectTypeTagView>(fsys);
174 cpuIntQuantsWithGpuPtr1[i]
175 = cpuModel.cachedIntensiveQuantities1_[i]
176 .template withOtherFluidSystem<CorrectTypeTagView>(fsys);
177 }
178
179 GpuBuffer<CorrectBOIQ> gpuBuf0(cpuIntQuantsWithGpuPtr0);
180 GpuBuffer<CorrectBOIQ> gpuBuf1(cpuIntQuantsWithGpuPtr1);
181 GpuBuffer<Scalar> gpuVolumes(cpuModel.volumes_);
182
183 // create new blackoil model providing a gpubuffer allocated version of the intQuants
184 auto result = SimplifiedGpuBufferModel(
185 std::move(gpuBuf0), std::move(gpuBuf1), std::move(gpuVolumes));
186
187 return result;
188 }
189
190 template <typename LocalTypeTag>
191 auto make_view(SimpleFIBlackOilModel<LocalTypeTag, GpuBuffer>& gpuSimpleFIBlackOilModel)
192 {
193 return SimpleFIBlackOilModel<LocalTypeTag, gpuistl::GpuView>(
194 make_view(gpuSimpleFIBlackOilModel.cachedIntensiveQuantities0_),
195 make_view(gpuSimpleFIBlackOilModel.cachedIntensiveQuantities1_),
196 make_view(gpuSimpleFIBlackOilModel.volumes_));
197 }
198} // namespace gpuistl
199#endif
200
201} // namespace Opm
202
203#endif // SIMPLE_FI_BLACK_OIL_MODEL_HPP
Classes required for dynamic convective mixing.
Contains the quantities which are are constant within a finite volume in the black-oil model.
Definition: blackoilintensivequantities.hh:79
Definition: SimpleFIBlackOilModel.hpp:69
GetPropType< TypeTag, Properties::FluidSystem > FluidSystem
Definition: SimpleFIBlackOilModel.hpp:71
Storage< BlackOilIntensiveQuantities< TypeTag > > cachedIntensiveQuantities0_
Definition: SimpleFIBlackOilModel.hpp:124
TypeTag TypeTagPublic
Definition: SimpleFIBlackOilModel.hpp:72
Storage< BlackOilIntensiveQuantities< TypeTag > > cachedIntensiveQuantities1_
Definition: SimpleFIBlackOilModel.hpp:125
OPM_HOST_DEVICE const auto & intensiveQuantities(unsigned int globalIdx, unsigned int timeIdx) const
Definition: SimpleFIBlackOilModel.hpp:108
SimpleFIBlackOilModel(const Storage< BlackOilIntensiveQuantities< TypeTag > > &cachedIntensiveQuantities0, const Storage< BlackOilIntensiveQuantities< TypeTag > > &cachedIntensiveQuantities1, const Storage< Scalar > &volumes)
Definition: SimpleFIBlackOilModel.hpp:75
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: SimpleFIBlackOilModel.hpp:73
Storage< Scalar > volumes_
Definition: SimpleFIBlackOilModel.hpp:126
SimpleFIBlackOilModel(const OtherIQContainer &cachedIntensiveQuantities0, const OtherIQContainer &cachedIntensiveQuantities1, const Storage< Scalar > &volumes)
Definition: SimpleFIBlackOilModel.hpp:90
OPM_HOST_DEVICE Scalar dofTotalVolume(unsigned int globalIdx) const
Definition: SimpleFIBlackOilModel.hpp:103
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
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
The Opm property system, traits with inheritance.