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> 41 #include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp> 43 #include <opm/material/fluidmatrixinteractions/EclMultiplexerMaterialParams.hpp> 47 #include <type_traits> 51 template <
typename TypeTag>
60 using Element =
typename GridView::template Codim<0>::Entity;
61 using ElementIterator =
typename GridView::template Codim<0>::Iterator;
63 numEq = getPropValue<TypeTag, Properties::NumEq>(),
64 historySize = getPropValue<TypeTag, Properties::TimeDiscHistorySize>(),
70 static constexpr
bool gridIsUnchanging =
71 std::is_same_v<GetPropType<TypeTag, Properties::Grid>, Dune::CpGrid>;
73 static constexpr
bool avoidElementContext = getPropValue<TypeTag, Properties::AvoidElementContext>();
78 , element_chunks_(this->gridView_,
79 Dune::Partitions::all,
84 void invalidateAndUpdateIntensiveQuantities(
unsigned timeIdx)
const 86 this->invalidateIntensiveQuantitiesCache(timeIdx);
87 if constexpr (gridIsUnchanging) {
88 if constexpr (avoidElementContext) {
89 updateCachedIntQuants(timeIdx);
92 OPM_BEGIN_PARALLEL_TRY_CATCH();
94 #pragma omp parallel for 96 for (
const auto& chunk : element_chunks_) {
97 ElementContext elemCtx(this->simulator_);
98 for (
const auto& elem : chunk) {
99 elemCtx.updatePrimaryStencil(elem);
100 elemCtx.updatePrimaryIntensiveQuantities(timeIdx);
103 OPM_END_PARALLEL_TRY_CATCH(
"invalidateAndUpdateIntensiveQuantities: state error",
104 this->simulator_.vanguard().grid().comm());
107 ElementContext elemCtx(this->simulator_);
108 for (
const auto& elem : elements(this->gridView_)) {
109 elemCtx.updatePrimaryStencil(elem);
110 elemCtx.updatePrimaryIntensiveQuantities(timeIdx);
115 void invalidateAndUpdateIntensiveQuantitiesOverlap(
unsigned timeIdx)
const 119 OPM_BEGIN_PARALLEL_TRY_CATCH()
124 ElementContext elemCtx(this->simulator_);
125 auto elemIt = threadedElemIt.beginParallel();
126 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
127 if (elemIt->partitionType() != Dune::OverlapEntity) {
130 const Element& elem = *elemIt;
131 elemCtx.updatePrimaryStencil(elem);
133 const std::size_t numPrimaryDof = elemCtx.numPrimaryDof(timeIdx);
134 for (
unsigned dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx) {
135 const unsigned globalIndex = elemCtx.globalSpaceIndex(dofIdx, timeIdx);
136 this->setIntensiveQuantitiesCacheEntryValidity(globalIndex, timeIdx,
false);
139 elemCtx.updatePrimaryIntensiveQuantities(0);
142 OPM_END_PARALLEL_TRY_CATCH(
"InvalideAndUpdateIntensiveQuantitiesOverlap: state error",
143 this->simulator_.vanguard().grid().comm());
146 template <
class Gr
idSubDomain>
147 void invalidateAndUpdateIntensiveQuantities(
unsigned timeIdx,
const GridSubDomain& gridSubDomain)
const 150 using GridViewType = decltype(gridSubDomain.view);
156 ElementContext elemCtx(this->simulator_);
157 auto elemIt = threadedElemIt.beginParallel();
158 for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) {
159 if (elemIt->partitionType() != Dune::InteriorEntity) {
162 const Element& elem = *elemIt;
163 elemCtx.updatePrimaryStencil(elem);
165 const std::size_t numPrimaryDof = elemCtx.numPrimaryDof(timeIdx);
166 for (
unsigned dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx) {
167 const unsigned globalIndex = elemCtx.globalSpaceIndex(dofIdx, timeIdx);
168 this->setIntensiveQuantitiesCacheEntryValidity(globalIndex, timeIdx,
false);
171 elemCtx.updatePrimaryIntensiveQuantities(0);
187 ParentType::updateFailed();
188 invalidateAndUpdateIntensiveQuantities(0);
192 const IntensiveQuantities& intensiveQuantities(
unsigned globalIdx,
unsigned timeIdx)
const 194 if (!this->enableIntensiveQuantityCache_) {
195 OPM_THROW(std::logic_error,
196 "Run without intensive quantites not enabled: " 197 "Use --enable-intensive-quantity=true");
200 assert(timeIdx < this->cachedIntensiveQuantityHistorySize());
201 const auto* intquant = this->cachedIntensiveQuantities(globalIdx, timeIdx);
203 OPM_THROW(std::logic_error,
"Intensive quantites need to be updated in code");
210 template <EclMultiplexerApproach ApproachArg>
211 using EMD = EclMultiplexerDispatch<ApproachArg>;
213 void updateCachedIntQuants(
const unsigned timeIdx)
const 216 switch (this->simulator_.problem().materialLawManager()->threePhaseApproach()) {
217 case EclMultiplexerApproach::Stone1:
218 updateCachedIntQuants1<EclMultiplexerDispatch<EclMultiplexerApproach::Stone1>>(timeIdx);
221 case EclMultiplexerApproach::Stone2:
222 updateCachedIntQuants1<EMD<EclMultiplexerApproach::Stone2>>(timeIdx);
225 case EclMultiplexerApproach::Default:
226 updateCachedIntQuants1<EMD<EclMultiplexerApproach::Default>>(timeIdx);
229 case EclMultiplexerApproach::TwoPhase:
230 updateCachedIntQuants1<EMD<EclMultiplexerApproach::TwoPhase>>(timeIdx);
233 case EclMultiplexerApproach::OnePhase:
234 updateCachedIntQuants1<EMD<EclMultiplexerApproach::OnePhase>>(timeIdx);
239 template <
class EMDArg>
240 void updateCachedIntQuants1(
const unsigned timeIdx)
const 243 if (this->simulator_.problem().materialLawManager()->satCurveIsAllPiecewiseLinear()) {
244 using PL = SatCurveMultiplexerDispatch<SatCurveMultiplexerApproach::PiecewiseLinear>;
245 updateCachedIntQuantsLoop<EMDArg, PL>(timeIdx);
248 updateCachedIntQuantsLoop<EMDArg>(timeIdx);
253 template <
class ...Args>
254 void updateCachedIntQuantsLoop(
const unsigned timeIdx)
const 256 const auto& elementMapper = this->simulator_.model().elementMapper();
258 #pragma omp parallel for 260 for (
const auto& chunk : element_chunks_) {
261 for (
const auto& elem : chunk) {
262 this->
template updateSingleCachedIntQuantUnchecked<Args...>(elementMapper.index(elem), timeIdx);
267 template <
class ...Args>
268 void updateSingleCachedIntQuantUnchecked(
const unsigned globalIdx,
const unsigned timeIdx)
const 271 auto& intquant = this->intensiveQuantityCache_[timeIdx][globalIdx];
273 intquant.template update<Args...>(this->simulator_.problem(), this->solution(timeIdx)[globalIdx], globalIdx, timeIdx);
275 this->intensiveQuantityCacheUpToDate_[timeIdx][globalIdx] = 1;
278 ElementChunks<GridView, Dune::Partitions::All> element_chunks_;
283 #endif // FI_BLACK_OIL_MODEL_HPP Definition: FIBlackoilModel.hpp:52
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
static unsigned maxThreads()
Return the maximum number of threads of the current process.
Definition: threadmanager.hpp:66
void updateFailed()
Called by the update() method if it was unsuccessful.
Definition: FIBlackoilModel.hpp:181
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition: blackoilbioeffectsmodules.hh:45
A fully-implicit black-oil flow model.
Provides an STL-iterator like interface to iterate over the enties of a GridView in OpenMP threaded a...
Definition: threadedentityiterator.hh:41
The Opm property system, traits with inheritance.
Simplifies multi-threaded capabilities.
A fully-implicit black-oil flow model.
Definition: blackoilmodel.hh:76
A base class for fully-implicit multi-phase porous-media flow models which assume multiple fluid phas...
Definition: multiphasebasemodel.hh:57