From 59de5091053404591d42db966aba39369f402af1 Mon Sep 17 00:00:00 2001 From: hnil Date: Wed, 26 Jul 2023 11:07:26 +0200 Subject: [PATCH] -- moved fully implict related updates to FIblackoil -- changed spesicic nldd calls to use subDomain instead of gridview (-- clang formated FIBlackoil) --- ebos/FIBlackOilModel.hpp | 124 ++++++++++++++---- opm/simulators/flow/BlackoilModelEbosNldd.hpp | 8 +- 2 files changed, 106 insertions(+), 26 deletions(-) diff --git a/ebos/FIBlackOilModel.hpp b/ebos/FIBlackOilModel.hpp index 70ccade84..631a26f00 100644 --- a/ebos/FIBlackOilModel.hpp +++ b/ebos/FIBlackOilModel.hpp @@ -35,28 +35,108 @@ #include -namespace Opm{ - template - class FIBlackOilModel: public BlackOilModel{ - using Parent = BlackOilModel; - using Simulator = GetPropType; - using IntensiveQuantities = GetPropType; - public: - FIBlackOilModel(Simulator& simulator): BlackOilModel(simulator){ - } - - // standard flow - const IntensiveQuantities& intensiveQuantities(unsigned globalIdx, unsigned timeIdx) const{ - if (!this->enableIntensiveQuantityCache_){ - OPM_THROW(std::logic_error, "Run without intensive quantites not enabled: Use --enable-intensive-quantity=true"); - } - const auto* intquant = this->cachedIntensiveQuantities(globalIdx, timeIdx); - if(!intquant){ - OPM_THROW(std::logic_error, "Intensive quantites need to be updated in code"); - } - return *intquant; - } - +namespace Opm +{ +template +class FIBlackOilModel : public BlackOilModel +{ + using ParentType = BlackOilModel; + using Simulator = GetPropType; + using IntensiveQuantities = GetPropType; + using ElementContext = GetPropType; + using ThreadManager = GetPropType; + using GridView = GetPropType; + using Element = typename GridView::template Codim<0>::Entity; + using ElementIterator = typename GridView::template Codim<0>::Iterator; + enum { + numEq = getPropValue(), + historySize = getPropValue(), }; + +public: + FIBlackOilModel(Simulator& simulator) + : BlackOilModel(simulator) + { + } + void invalidateAndUpdateIntensiveQuantities(unsigned timeIdx) const + { + this->invalidateIntensiveQuantitiesCache(timeIdx); + + // loop over all elements... + ThreadedEntityIterator threadedElemIt(this->gridView_); +#ifdef _OPENMP +#pragma omp parallel +#endif + { + ElementContext elemCtx(this->simulator_); + ElementIterator elemIt = threadedElemIt.beginParallel(); + for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) { + const Element& elem = *elemIt; + elemCtx.updatePrimaryStencil(elem); + elemCtx.updatePrimaryIntensiveQuantities(timeIdx); + } + } + } + + template + void invalidateAndUpdateIntensiveQuantities(unsigned timeIdx, const GridSubDomain& gridSubDomain) const + { + // loop over all elements... + using GridViewType = decltype(gridSubDomain.view); + ThreadedEntityIterator threadedElemIt(gridSubDomain.view); +#ifdef _OPENMP +#pragma omp parallel +#endif + { + + ElementContext elemCtx(this->simulator_); + auto elemIt = threadedElemIt.beginParallel(); + for (; !threadedElemIt.isFinished(elemIt); elemIt = threadedElemIt.increment()) { + if (elemIt->partitionType() != Dune::InteriorEntity) { + continue; + } + const Element& elem = *elemIt; + elemCtx.updatePrimaryStencil(elem); + // Mark cache for this element as invalid. + const std::size_t numPrimaryDof = elemCtx.numPrimaryDof(timeIdx); + for (unsigned dofIdx = 0; dofIdx < numPrimaryDof; ++dofIdx) { + const unsigned globalIndex = elemCtx.globalSpaceIndex(dofIdx, timeIdx); + this->setIntensiveQuantitiesCacheEntryValidity(globalIndex, timeIdx, false); + } + // Update for this element. + elemCtx.updatePrimaryIntensiveQuantities(/*timeIdx=*/0); + } + } + } + + /*! + * \brief Called by the update() method if it was + * unsuccessful. This is primary a hook which the actual + * model can overload. + */ + void updateFailed() + { + // Reset the current solution to the one of the + // previous time step so that we can start the next + // update at a physically meaningful solution. + // this->solution(/*timeIdx=*/0) = this->solution(/*timeIdx=*/1); + ParentType::updateFailed(); + invalidateAndUpdateIntensiveQuantities(/*timeIdx=*/0); + } + + // standard flow + const IntensiveQuantities& intensiveQuantities(unsigned globalIdx, unsigned timeIdx) const + { + if (!this->enableIntensiveQuantityCache_) { + OPM_THROW(std::logic_error, + "Run without intensive quantites not enabled: Use --enable-intensive-quantity=true"); + } + const auto* intquant = this->cachedIntensiveQuantities(globalIdx, timeIdx); + if (!intquant) { + OPM_THROW(std::logic_error, "Intensive quantites need to be updated in code"); + } + return *intquant; + } +}; } // namespace Opm #endif // FI_BLACK_OIL_MODEL_HPP diff --git a/opm/simulators/flow/BlackoilModelEbosNldd.hpp b/opm/simulators/flow/BlackoilModelEbosNldd.hpp index dbf24025c..7c4c412f7 100644 --- a/opm/simulators/flow/BlackoilModelEbosNldd.hpp +++ b/opm/simulators/flow/BlackoilModelEbosNldd.hpp @@ -442,7 +442,7 @@ private: // residual // if the solution is updated, the intensive quantities need to be recalculated - ebosSimulator.model().invalidateAndUpdateIntensiveQuantities(/*timeIdx=*/0, domain.view); + ebosSimulator.model().invalidateAndUpdateIntensiveQuantities(/*timeIdx=*/0, domain); } //! \brief Get reservoir quantities on this process needed for convergence calculations. @@ -715,11 +715,11 @@ private: auto local_solution = Details::extractVector(solution, domain.cells); Details::setGlobal(local_solution, domain.cells, locally_solved); Details::setGlobal(initial_local_solution, domain.cells, solution); - model_.ebosSimulator().model().invalidateAndUpdateIntensiveQuantities(/*timeIdx=*/0, domain.view); + model_.ebosSimulator().model().invalidateAndUpdateIntensiveQuantities(/*timeIdx=*/0, domain); } else { model_.wellModel().setPrimaryVarsDomain(domain, initial_local_well_primary_vars); Details::setGlobal(initial_local_solution, domain.cells, solution); - model_.ebosSimulator().model().invalidateAndUpdateIntensiveQuantities(/*timeIdx=*/0, domain.view); + model_.ebosSimulator().model().invalidateAndUpdateIntensiveQuantities(/*timeIdx=*/0, domain); } } @@ -766,7 +766,7 @@ private: } else { model_.wellModel().setPrimaryVarsDomain(domain, initial_local_well_primary_vars); Details::setGlobal(initial_local_solution, domain.cells, solution); - model_.ebosSimulator().model().invalidateAndUpdateIntensiveQuantities(/*timeIdx=*/0, domain.view); + model_.ebosSimulator().model().invalidateAndUpdateIntensiveQuantities(/*timeIdx=*/0, domain); } }