diff --git a/flow/flow_blackoil.cpp b/flow/flow_blackoil.cpp index b957316125..ce284beb32 100644 --- a/flow/flow_blackoil.cpp +++ b/flow/flow_blackoil.cpp @@ -38,6 +38,9 @@ namespace Opm { template struct EnableDiffusion { static constexpr bool value = false; }; + template + struct AvoidElementContext { static constexpr bool value = true; }; + } } diff --git a/opm/simulators/flow/FIBlackoilModel.hpp b/opm/simulators/flow/FIBlackoilModel.hpp index 175f28f65f..dda15a4ea1 100644 --- a/opm/simulators/flow/FIBlackoilModel.hpp +++ b/opm/simulators/flow/FIBlackoilModel.hpp @@ -32,6 +32,7 @@ #include #include +#include #include #include @@ -69,6 +70,8 @@ class FIBlackOilModel : public BlackOilModel static constexpr bool gridIsUnchanging = std::is_same_v, Dune::CpGrid>; + static constexpr bool avoidElementContext = getPropValue(); + public: explicit FIBlackOilModel(Simulator& simulator) : BlackOilModel(simulator) @@ -81,20 +84,24 @@ public: void invalidateAndUpdateIntensiveQuantities(unsigned timeIdx) const { this->invalidateIntensiveQuantitiesCache(timeIdx); - const auto& elementMapper = this->simulator_.model().elementMapper(); - - using Dispatch = EclMultiplexerDispatch; - - OPM_BEGIN_PARALLEL_TRY_CATCH(); if constexpr (gridIsUnchanging) { + if constexpr (avoidElementContext) { + updateCachedIntQuants(timeIdx); + return; + } + OPM_BEGIN_PARALLEL_TRY_CATCH(); #ifdef _OPENMP #pragma omp parallel for #endif for (const auto& chunk : element_chunks_) { + ElementContext elemCtx(this->simulator_); for (const auto& elem : chunk) { - this->template updateSingleCachedIntQuantUnchecked(elementMapper.index(elem), timeIdx); + elemCtx.updatePrimaryStencil(elem); + elemCtx.updatePrimaryIntensiveQuantities(timeIdx); } } + OPM_END_PARALLEL_TRY_CATCH("invalidateAndUpdateIntensiveQuantities: state error", + this->simulator_.vanguard().grid().comm()); } else { // Grid is possibly refined or otherwise changed between calls. ElementContext elemCtx(this->simulator_); @@ -103,8 +110,6 @@ public: elemCtx.updatePrimaryIntensiveQuantities(timeIdx); } } - OPM_END_PARALLEL_TRY_CATCH("InvalideAndUpdateIntensiveQuantities: state error", - this->simulator_.vanguard().grid().comm()); } void invalidateAndUpdateIntensiveQuantitiesOverlap(unsigned timeIdx) const @@ -202,6 +207,24 @@ public: protected: + + void updateCachedIntQuants(const unsigned timeIdx) const + { + using Dispatch = EclMultiplexerDispatch; + updateCachedIntQuantsLoop<>(timeIdx); + } + + template + void updateCachedIntQuantsLoop(const unsigned timeIdx) const + { + const auto& elementMapper = this->simulator_.model().elementMapper(); + for (const auto& chunk : element_chunks_) { + for (const auto& elem : chunk) { + this->template updateSingleCachedIntQuantUnchecked(elementMapper.index(elem), timeIdx); + } + } + } + template void updateSingleCachedIntQuantUnchecked(const unsigned globalIdx, const unsigned timeIdx) const { diff --git a/opm/simulators/flow/FlowBaseProblemProperties.hpp b/opm/simulators/flow/FlowBaseProblemProperties.hpp index 4b7dd4066a..396d07aab2 100644 --- a/opm/simulators/flow/FlowBaseProblemProperties.hpp +++ b/opm/simulators/flow/FlowBaseProblemProperties.hpp @@ -77,6 +77,10 @@ struct EnableApiTracking { using type = UndefinedProperty; }; template struct EnableDebuggingChecks { using type = Properties::UndefinedProperty; }; +// Avoid using ElementContext-based code if possible. +template +struct AvoidElementContext { using type = Properties::UndefinedProperty; }; + // if thermal flux boundaries are enabled an effort is made to preserve the initial // thermal gradient specified via the TEMPVD keyword template @@ -241,6 +245,12 @@ template struct EnableDebuggingChecks { static constexpr bool value = true; }; +// Most modules are implemented only in terms of element contexts, +// so this must default to false. +template +struct AvoidElementContext +{ static constexpr bool value = false; }; + } // namespace Opm::Properties #endif // OPM_BASE_FLOW_PROBLEM_PROPERTIES_HPP