opm-simulators
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 
33 #include <opm/models/blackoil/blackoilmoduleparams.hh>
36 
37 #include <opm/common/ErrorMacros.hpp>
38 
39 #include <opm/grid/CpGrid.hpp>
40 #include <opm/grid/utility/ElementChunks.hpp>
41 
42 #include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
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 
64 namespace Opm
65 {
66 
67 template <typename TypeTag, template <class> class Storage = Opm::VectorWithDefaultAllocator>
69 {
70 public:
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 
101  SimpleFIBlackOilModel() = delete;
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 
121 public:
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
130 namespace 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
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
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:67
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
A fully-implicit black-oil flow model.
The Opm property system, traits with inheritance.
Simplifies multi-threaded capabilities.
Definition: SimpleFIBlackOilModel.hpp:68