28#ifndef FI_BLACK_OIL_MODEL_HPP
29#define FI_BLACK_OIL_MODEL_HPP
34#include <opm/common/ErrorMacros.hpp>
37#include <opm/grid/CpGrid.hpp>
38#include <opm/grid/utility/ElementChunks.hpp>
43#include <opm/material/fluidmatrixinteractions/EclMultiplexerMaterialParams.hpp>
59template <
typename TypeTag>
68 using Element =
typename GridView::template Codim<0>::Entity;
69 using ElementIterator =
typename GridView::template Codim<0>::Iterator;
71 numEq = getPropValue<TypeTag, Properties::NumEq>(),
72 historySize = getPropValue<TypeTag, Properties::TimeDiscHistorySize>(),
78 static constexpr bool gridIsUnchanging =
79 std::is_same_v<GetPropType<TypeTag, Properties::Grid>, Dune::CpGrid>;
81 static constexpr bool avoidElementContext = getPropValue<TypeTag, Properties::AvoidElementContext>();
87 Dune::Partitions::all,
88 ThreadManager::maxThreads())
91 if constexpr (gpuistl::GpuBlackoilIntensiveQuantitiesDispatcherSupport<TypeTag>::value) {
92 useGpuIntensiveQuantitiesDispatcher_ =
93 Parameters::Get<Parameters::ExperimentalComputePropertiesOnGpu>();
102 if constexpr (gpuistl::GpuBlackoilIntensiveQuantitiesDispatcherSupport<TypeTag>::value) {
103 Parameters::Register<Parameters::ExperimentalComputePropertiesOnGpu>
104 (
"Experimental: compute BlackOilIntensiveQuantities on the GPU "
105 "via the GpuBlackoilIntensiveQuantitiesDispatcher.");
112 this->invalidateIntensiveQuantitiesCache(timeIdx);
113 if constexpr (gridIsUnchanging) {
114 if constexpr (avoidElementContext) {
119 if constexpr (Opm::gpuistl::GpuBlackoilIntensiveQuantitiesDispatcherSupport<TypeTag>::value)
121 if (useGpuIntensiveQuantitiesDispatcher_) {
122 if constexpr (getPropValue<TypeTag, Properties::EnableDiffusion>()
123 || getPropValue<TypeTag, Properties::EnableDispersion>()) {
124 OPM_THROW(std::logic_error,
125 "GPU intensive quantities dispatcher does not support diffusion or dispersion");
127 runGpuIntensiveQuantitiesDispatcher_(timeIdx);
128 const std::size_t numCells = this->intensiveQuantityCache_[timeIdx].size();
129 for (std::size_t i = 0; i < numCells; ++i) {
130 this->setIntensiveQuantitiesCacheEntryValidity(i, timeIdx,
true);
138#pragma omp parallel for
141 ElementContext elemCtx(this->simulator_);
142 for (
const auto& elem : chunk) {
143 elemCtx.updatePrimaryStencil(elem);
144 elemCtx.updatePrimaryIntensiveQuantities(timeIdx);
148 this->simulator_.vanguard().grid().comm());
151 ElementContext elemCtx(this->simulator_);
152 for (
const auto& elem : elements(this->gridView_)) {
153 elemCtx.updatePrimaryStencil(elem);
154 elemCtx.updatePrimaryIntensiveQuantities(timeIdx);
168 ElementContext elemCtx(this->simulator_);
171 if (elemIt->partitionType() != Dune::OverlapEntity) {
174 const Element& elem = *elemIt;
175 elemCtx.updatePrimaryStencil(elem);
177 const std::size_t numPrimaryDof = elemCtx.numPrimaryDof(timeIdx);
178 for (
unsigned dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx) {
179 const unsigned globalIndex = elemCtx.globalSpaceIndex(dofIdx, timeIdx);
180 this->setIntensiveQuantitiesCacheEntryValidity(globalIndex, timeIdx,
false);
183 elemCtx.updatePrimaryIntensiveQuantities(0);
187 this->simulator_.vanguard().grid().comm());
190 template <
class Gr
idSubDomain>
194 using GridViewType =
decltype(gridSubDomain.view);
200 ElementContext elemCtx(this->simulator_);
203 if (elemIt->partitionType() != Dune::InteriorEntity) {
206 const Element& elem = *elemIt;
207 elemCtx.updatePrimaryStencil(elem);
209 const std::size_t numPrimaryDof = elemCtx.numPrimaryDof(timeIdx);
210 for (
unsigned dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx) {
211 const unsigned globalIndex = elemCtx.globalSpaceIndex(dofIdx, timeIdx);
212 this->setIntensiveQuantitiesCacheEntryValidity(globalIndex, timeIdx,
false);
215 elemCtx.updatePrimaryIntensiveQuantities(0);
231 ParentType::updateFailed();
238 if (!this->enableIntensiveQuantityCache_) {
239 OPM_THROW(std::logic_error,
240 "Run without intensive quantites not enabled: "
241 "Use --enable-intensive-quantity=true");
244 assert(timeIdx < this->cachedIntensiveQuantityHistorySize());
245 const auto* intquant = this->cachedIntensiveQuantities(globalIdx, timeIdx);
247 OPM_THROW(std::logic_error,
"Intensive quantites need to be updated in code");
254 template <EclMultiplexerApproach ApproachArg>
255 using EMD = EclMultiplexerDispatch<ApproachArg>;
260 switch (this->simulator_.problem().materialLawManager()->threePhaseApproach()) {
261 case EclMultiplexerApproach::Stone1:
262 updateCachedIntQuants1<EclMultiplexerDispatch<EclMultiplexerApproach::Stone1>>(timeIdx);
265 case EclMultiplexerApproach::Stone2:
266 updateCachedIntQuants1<EMD<EclMultiplexerApproach::Stone2>>(timeIdx);
269 case EclMultiplexerApproach::Default:
270 updateCachedIntQuants1<EMD<EclMultiplexerApproach::Default>>(timeIdx);
273 case EclMultiplexerApproach::TwoPhase:
274 updateCachedIntQuants1<EMD<EclMultiplexerApproach::TwoPhase>>(timeIdx);
277 case EclMultiplexerApproach::OnePhase:
278 updateCachedIntQuants1<EMD<EclMultiplexerApproach::OnePhase>>(timeIdx);
283 template <
class EMDArg>
287 if (this->simulator_.problem().materialLawManager()->satCurveIsAllPiecewiseLinear()) {
288 using PL = SatCurveMultiplexerDispatch<SatCurveMultiplexerApproach::PiecewiseLinear>;
289 updateCachedIntQuantsLoop<EMDArg, PL>(timeIdx);
292 updateCachedIntQuantsLoop<EMDArg>(timeIdx);
297 template <
class ...Args>
300 const auto& elementMapper = this->simulator_.model().elementMapper();
302#pragma omp parallel for
305 for (
const auto& elem : chunk) {
311 template <
class ...Args>
315 auto& intquant = this->intensiveQuantityCache_[timeIdx][globalIdx];
317 intquant.template update<Args...>(this->simulator_.problem(), this->solution(timeIdx)[globalIdx], globalIdx, timeIdx);
319 this->intensiveQuantityCacheUpToDate_[timeIdx][globalIdx] = 1;
325 bool useGpuIntensiveQuantitiesDispatcher_{
false};
326 using GpuDispatcherStorage = std::conditional_t<
327 Opm::gpuistl::GpuBlackoilIntensiveQuantitiesDispatcherSupport<TypeTag>::value,
328 std::unique_ptr<Opm::gpuistl::GpuBlackoilIntensiveQuantitiesDispatcher<TypeTag>>,
330 mutable GpuDispatcherStorage gpuIntensiveQuantitiesDispatcher_{};
332 void runGpuIntensiveQuantitiesDispatcher_(
const unsigned timeIdx)
const
334 if constexpr (Opm::gpuistl::GpuBlackoilIntensiveQuantitiesDispatcherSupport<TypeTag>::value) {
335 if (!gpuIntensiveQuantitiesDispatcher_) {
336 gpuIntensiveQuantitiesDispatcher_ =
338 Opm::gpuistl::GpuBlackoilIntensiveQuantitiesDispatcher<TypeTag>>();
340 using PV = GetPropType<TypeTag, Properties::PrimaryVariables>;
341 const auto& sol = this->solution(timeIdx);
342 const std::size_t numCells = this->intensiveQuantityCache_[timeIdx].size();
343 std::vector<const PV*> priVarsPtrs(numCells);
344 std::vector<IntensiveQuantities*> outIqPtrs(numCells);
345 for (std::size_t i = 0; i < numCells; ++i) {
346 priVarsPtrs[i] = &sol[i];
347 outIqPtrs[i] = &this->intensiveQuantityCache_[timeIdx][i];
349 gpuIntensiveQuantitiesDispatcher_->update(
350 this->simulator_.problem(),
#define OPM_END_PARALLEL_TRY_CATCH(prefix, comm)
Catch exception and throw in a parallel try-catch clause.
Definition: DeferredLoggingErrorHelpers.hpp:197
#define OPM_BEGIN_PARALLEL_TRY_CATCH()
Macro to setup the try of a parallel try-catch.
Definition: DeferredLoggingErrorHelpers.hpp:160
A fully-implicit black-oil flow model.
Definition: blackoilmodel.hh:329
static void registerParameters()
Register all run-time parameters for the immiscible model.
Definition: blackoilmodel.hh:379
Definition: FIBlackoilModel.hpp:61
static void registerParameters()
Definition: FIBlackoilModel.hpp:98
void updateCachedIntQuantsLoop(const unsigned timeIdx) const
Definition: FIBlackoilModel.hpp:298
void invalidateAndUpdateIntensiveQuantities(unsigned timeIdx, const GridSubDomain &gridSubDomain) const
Definition: FIBlackoilModel.hpp:191
void updateCachedIntQuants(const unsigned timeIdx) const
Definition: FIBlackoilModel.hpp:257
void updateSingleCachedIntQuantUnchecked(const unsigned globalIdx, const unsigned timeIdx) const
Definition: FIBlackoilModel.hpp:312
void invalidateAndUpdateIntensiveQuantitiesOverlap(unsigned timeIdx) const
Definition: FIBlackoilModel.hpp:159
void updateFailed()
Called by the update() method if it was unsuccessful. This is primary a hook which the actual model c...
Definition: FIBlackoilModel.hpp:225
const IntensiveQuantities & intensiveQuantities(unsigned globalIdx, unsigned timeIdx) const
Definition: FIBlackoilModel.hpp:236
void updateCachedIntQuants1(const unsigned timeIdx) const
Definition: FIBlackoilModel.hpp:284
EclMultiplexerDispatch< ApproachArg > EMD
Definition: FIBlackoilModel.hpp:255
void invalidateAndUpdateIntensiveQuantities(unsigned timeIdx) const
Definition: FIBlackoilModel.hpp:110
FIBlackOilModel(Simulator &simulator)
Definition: FIBlackoilModel.hpp:84
ElementChunks< GridView, Dune::Partitions::All > element_chunks_
Definition: FIBlackoilModel.hpp:322
A base class for fully-implicit multi-phase porous-media flow models which assume multiple fluid phas...
Definition: multiphasebasemodel.hh:161
Provides an STL-iterator like interface to iterate over the enties of a GridView in OpenMP threaded a...
Definition: threadedentityiterator.hh:42
bool isFinished(const EntityIterator &it) const
Definition: threadedentityiterator.hh:67
EntityIterator increment()
Definition: threadedentityiterator.hh:80
EntityIterator beginParallel()
Definition: threadedentityiterator.hh:54
Definition: fvbaseprimaryvariables.hh:161
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.