27#ifndef OPM_OUTPUT_BLACK_OIL_MODULE_HPP
28#define OPM_OUTPUT_BLACK_OIL_MODULE_HPP
30#include <dune/common/fvector.hh>
32#include <opm/grid/CpGrid.hpp>
33#include <opm/grid/LookUpData.hh>
37#include <opm/common/Exceptions.hpp>
38#include <opm/common/TimingMacros.hpp>
39#include <opm/common/OpmLog/OpmLog.hpp>
40#include <opm/common/utility/Visitor.hpp>
42#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
44#include <opm/material/common/Valgrind.hpp>
45#include <opm/material/fluidmatrixinteractions/EclEpsScalingPoints.hpp>
46#include <opm/material/fluidstates/BlackOilFluidState.hpp>
47#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
54#include <opm/output/data/Cells.hpp>
55#include <opm/output/data/RegionVariableMapping.hpp>
57#include <opm/output/eclipse/EclipseIO.hpp>
58#include <opm/output/eclipse/Inplace.hpp>
59#include <opm/output/eclipse/RegionVariableCollection.hpp>
84template <
class TypeTag>
85class EcfvDiscretization;
89 template <
typename... T>
99template <
class TypeTag>
111 using FluidState =
typename IntensiveQuantities::FluidState;
113 using Element =
typename GridView::template Codim<0>::Entity;
114 using ElementIterator =
typename GridView::template Codim<0>::Iterator;
117 using Dir = FaceDir::DirEnum;
124 static constexpr int conti0EqIdx = Indices::conti0EqIdx;
125 static constexpr int numPhases = FluidSystem::numPhases;
126 static constexpr int oilPhaseIdx = FluidSystem::oilPhaseIdx;
127 static constexpr int gasPhaseIdx = FluidSystem::gasPhaseIdx;
128 static constexpr int waterPhaseIdx = FluidSystem::waterPhaseIdx;
129 static constexpr int gasCompIdx = FluidSystem::gasCompIdx;
130 static constexpr int oilCompIdx = FluidSystem::oilCompIdx;
131 static constexpr int waterCompIdx = FluidSystem::waterCompIdx;
132 static constexpr EnergyModules energyModuleType = getPropValue<TypeTag, Properties::EnergyModuleType>();
133 static constexpr bool enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
134 static constexpr bool enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>();
135 static constexpr bool enableFoam = getPropValue<TypeTag, Properties::EnableFoam>();
136 static constexpr bool enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>();
137 static constexpr bool enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>();
138 enum { enableMICP = Indices::enableMICP };
139 enum { enableVapwat = getPropValue<TypeTag, Properties::EnableVapwat>() };
140 enum { enableDisgasInWater = getPropValue<TypeTag, Properties::EnableDisgasInWater>() };
141 static constexpr bool enableDissolvedGas =
142 Indices::compositionSwitchIdx != std::numeric_limits<unsigned>::max();
144 template<
class VectorType>
145 static Scalar value_or_zero(
int idx,
const VectorType& v)
150 return v.empty() ? 0.0 : v[idx];
155 const SummaryConfig& smryCfg,
157 :
BaseType(simulator.vanguard().eclState(),
158 simulator.vanguard().schedule(),
160 simulator.vanguard().summaryState(),
162 [this](const int idx)
163 {
return simulator_.problem().eclWriter().collectOnIORank().localIdxToGlobalIdx(idx); },
164 [&collectOnIORank](
const int idx)
165 {
return collectOnIORank.isCartIdxOnThisRank(idx); },
166 simulator.vanguard().grid().comm(),
167 energyModuleType == EnergyModules::FullyImplicitThermal ||
168 energyModuleType == EnergyModules::SequentialImplicitThermal,
169 energyModuleType == EnergyModules::ConstantTemperature,
170 getPropValue<TypeTag, Properties::EnableMech>(),
171 getPropValue<TypeTag, Properties::EnableSolvent>(),
172 getPropValue<TypeTag, Properties::EnablePolymer>(),
173 getPropValue<TypeTag, Properties::EnableFoam>(),
174 getPropValue<TypeTag, Properties::EnableBrine>(),
175 getPropValue<TypeTag, Properties::EnableSaltPrecipitation>(),
176 getPropValue<TypeTag, Properties::EnableExtbo>(),
177 getPropValue<TypeTag, Properties::EnableBioeffects>(),
178 getPropValue<TypeTag, Properties::EnableGeochemistry>())
179 , simulator_(simulator)
180 , collectOnIORank_(collectOnIORank)
186 this->mapRegionsOntoLeaf_();
188 for (
auto& region_pair : this->
regions_) {
189 this->createLocalRegion_(region_pair.second);
192 auto isCartIdxOnThisRank = [&collectOnIORank](
const int idx) {
193 return collectOnIORank.isCartIdxOnThisRank(idx);
205 std::set<std::pair<int, int>> ownedLgrCells;
206 std::map<std::string, int> lgrNameToLevel;
207 if constexpr (std::is_same_v<Grid, Dune::CpGrid>) {
210 lgrNameToLevel = simulator.vanguard().grid().getLgrNameToLevel();
211 for (
const auto& element : elements(simulator.gridView())) {
212 const int level = element.level();
213 if (level > 0 && element.partitionType() == Dune::InteriorEntity) {
214 const int levelCompressed = element.getLevelElem().index();
215 const int levelCart = simulator.vanguard()
216 .levelCartesianIndexMapper()
217 .cartesianIndex(levelCompressed, level);
218 ownedLgrCells.emplace(level, levelCart);
224 [&ownedLgrCells](
const int level,
const int levelCart) {
225 return ownedLgrCells.count(std::make_pair(level, levelCart)) > 0;
228 if (! Parameters::Get<Parameters::OwnerCellsFirst>()) {
229 const std::string msg =
"The output code does not support --owner-cells-first=false.";
230 if (collectOnIORank.isIORank()) {
233 OPM_THROW_NOLOG(std::runtime_error, msg);
236 if (smryCfg.match(
"[FB]PP[OGW]") || smryCfg.match(
"RPP[OGW]*")) {
237 auto rset = this->
eclState_.fieldProps().fip_regions();
238 rset.push_back(
"PVTNUM");
246 const LookUpData<Grid, GridView> lookUpData(this->simulator_.gridView());
247 auto pvtnum = lookUpData.template assignFieldPropsIntOnLeaf<int>(
248 this->
eclState_.fieldProps(),
"PVTNUM",
false);
251 .emplace(this->simulator_.gridView().comm(),
252 FluidSystem::numPhases, rset,
253 [®ions = std::as_const(this->regions_),
254 pvtnum = std::move(pvtnum)]
255 (
const std::string& rsetName) ->
decltype(
auto)
257 return (rsetName ==
"PVTNUM")
258 ? static_cast<const std::vector<int>&>(pvtnum)
259 : static_cast<const std::vector<int>&>(regions.at(rsetName));
270 const unsigned reportStepNum,
273 const bool forceRestartFieldAllocation)
279 const auto& problem = this->simulator_.problem();
285 forceRestartFieldAllocation,
286 &problem.materialLawManager()->hysteresisConfig(),
287 problem.eclWriter().getOutputNnc().front().size());
292 const int reportStepNum)
294 this->setupElementExtractors_();
295 this->setupBlockExtractors_(isSubStep, reportStepNum);
301 this->extractors_.clear();
302 this->blockExtractors_.clear();
303 this->extraBlockExtractors_.clear();
304 this->lgrBlockExtractors_.clear();
315 using M = UnitSystem::measure;
316 this->
assignBuffer(sol,
"1OVERBO", M::oil_inverse_formation_volume_factor,
317 this->invB_[oilPhaseIdx], oilPhaseIdx);
318 this->
assignBuffer(sol,
"1OVERBG", M::gas_inverse_formation_volume_factor,
319 this->invB_[gasPhaseIdx], gasPhaseIdx);
321 this->relativePermeability_[oilPhaseIdx], oilPhaseIdx);
323 this->relativePermeability_[gasPhaseIdx], gasPhaseIdx);
324 this->
assignBuffer(sol,
"PBUB", M::pressure, this->bubblePointPressure_);
325 this->
assignBuffer(sol,
"PDEW", M::pressure, this->dewPointPressure_);
326 this->
assignBuffer(sol,
"RS", M::gas_oil_ratio, this->rs_);
327 this->
assignBuffer(sol,
"RV", M::oil_gas_ratio, this->rv_);
330 if constexpr (numPhases > 2) {
331 this->
assignBuffer(sol,
"1OVERBW", M::water_inverse_formation_volume_factor,
332 this->invB_[waterPhaseIdx], waterPhaseIdx);
334 this->relativePermeability_[waterPhaseIdx], waterPhaseIdx);
341 .gasDensity =
"GAS_DEN",
342 .waterDensity =
"WAT_DEN",
343 .oilViscosity =
"OIL_VISC",
344 .gasViscosity =
"GAS_VISC",
345 .waterViscosity =
"WAT_VISC",
360 if (this->extractors_.empty()) {
364 const auto& matLawManager = simulator_.problem().materialLawManager();
366 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
367 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
368 const auto& fs = intQuants.fluidState();
369 const auto globalDofIdx = elemCtx.globalSpaceIndex(dofIdx, 0);
372 if (matLawManager->enableHysteresis()) {
373 if (FluidSystem::phaseIsActive(oilPhaseIdx) && FluidSystem::phaseIsActive(waterPhaseIdx)) {
374 matLawManager->oilWaterHysteresisParams(hysterParams.
somax,
379 if (FluidSystem::phaseIsActive(oilPhaseIdx) && FluidSystem::phaseIsActive(gasPhaseIdx)) {
380 matLawManager->gasOilHysteresisParams(hysterParams.
sgmax,
389 elemCtx.primaryVars(dofIdx, 0).pvtRegionIndex(),
407 if (this->blockExtractors_.empty() &&
408 this->extraBlockExtractors_.empty() &&
409 this->lgrBlockExtractors_.empty())
420 const auto& element = elemCtx.element();
421 const int level = element.level();
423 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
424 const auto globalDofIdx = elemCtx.globalSpaceIndex(dofIdx, 0);
426 const std::vector<typename BlockExtractor::Exec>* be_extractors =
nullptr;
427 const std::vector<typename BlockExtractor::Exec>* bee_extractors =
nullptr;
428 const std::vector<typename BlockExtractor::Exec>* lgr_extractors =
nullptr;
431 const auto cartesianIdx = elemCtx.simulator().vanguard().cartesianIndex(globalDofIdx);
432 const auto be_it = this->blockExtractors_.find(cartesianIdx);
433 const auto bee_it = this->extraBlockExtractors_.find(cartesianIdx);
434 if (be_it != this->blockExtractors_.end()) { be_extractors = &be_it->second; }
435 if (bee_it != this->extraBlockExtractors_.end()) { bee_extractors = &bee_it->second; }
437 else if constexpr (std::is_same_v<Grid, Dune::CpGrid>) {
449 const auto level_it = this->lgrBlockExtractors_.find(level);
450 if (level_it != this->lgrBlockExtractors_.end() &&
451 element.partitionType() == Dune::InteriorEntity)
453 const int levelCompressed = element.getLevelElem().index();
454 const int levelCart = elemCtx.simulator().vanguard()
455 .levelCartesianIndexMapper()
456 .cartesianIndex(levelCompressed, level);
457 const auto cell_it = level_it->second.find(levelCart);
458 if (cell_it != level_it->second.end()) {
459 lgr_extractors = &cell_it->second;
464 if (be_extractors ==
nullptr &&
465 bee_extractors ==
nullptr &&
466 lgr_extractors ==
nullptr)
471 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
472 const auto& fs = intQuants.fluidState();
489 const std::size_t reportStepNum,
491 boost::posix_time::ptime currentDate,
496 if (comm.rank() != 0) {
501 std::unique_ptr<FIPConfig> fipSched;
502 if (reportStepNum > 0) {
503 const auto& rpt = this->
schedule_[reportStepNum-1].rpt_config.get();
504 fipSched = std::make_unique<FIPConfig>(rpt);
506 const FIPConfig& fipc = reportStepNum == 0 ? this->
eclState_.getEclipseConfig().fip()
511 this->
logOutput_.timeStamp(
"BALANCE", elapsed, reportStepNum, currentDate);
514 this->
logOutput_.fip(inplace, initial_inplace,
"");
516 if (fipc.output(FIPConfig::OutputField::FIPNUM)) {
517 this->
logOutput_.fip(inplace, initial_inplace,
"FIPNUM");
519 if (fipc.output(FIPConfig::OutputField::RESV))
523 if (fipc.output(FIPConfig::OutputField::FIP)) {
524 for (
const auto& reg : this->regions_) {
525 if (reg.first !=
"FIPNUM") {
526 std::ostringstream ss;
527 ss <<
"BAL" << reg.first.substr(3);
528 this->
logOutput_.timeStamp(ss.str(), elapsed, reportStepNum, currentDate);
529 this->
logOutput_.fip(inplace, initial_inplace, reg.first);
531 if (fipc.output(FIPConfig::OutputField::RESV))
543 if (comm.rank() != 0) {
547 if ((reportStepNum == 0) && (!substep) &&
548 (this->
schedule_.initialReportConfiguration().has_value()) &&
549 (this->schedule_.initialReportConfiguration()->contains(
"CSVFIP"))) {
551 std::ostringstream csv_stream;
557 this->
logOutput_.fip_csv(csv_stream, initial_inplace,
"FIPNUM");
559 for (
const auto& reg : this->regions_) {
560 if (reg.first !=
"FIPNUM") {
561 this->
logOutput_.fip_csv(csv_stream, initial_inplace, reg.first);
565 const IOConfig& io = this->
eclState_.getIOConfig();
566 auto csv_fname = io.getOutputDir() +
"/" + io.getBaseName() +
".CSV";
568 std::ofstream outputFile(csv_fname);
570 outputFile << csv_stream.str();
604 template <
class ActiveIndex,
class CartesianIndex>
606 ActiveIndex&& activeIndex,
607 CartesianIndex&& cartesianIndex)
610 const auto identifyCell = [&activeIndex, &cartesianIndex](
const Element& elem)
613 const auto cellIndex = activeIndex(elem);
616 static_cast<int>(cellIndex),
617 cartesianIndex(cellIndex),
618 elem.partitionType() == Dune::InteriorEntity
622 const auto timeIdx = 0u;
623 const auto& stencil = elemCtx.stencil(timeIdx);
624 const auto numInteriorFaces = elemCtx.numInteriorFaces(timeIdx);
626 for (
auto scvfIdx = 0 * numInteriorFaces; scvfIdx < numInteriorFaces; ++scvfIdx) {
627 const auto& face = stencil.interiorFace(scvfIdx);
628 const auto left = identifyCell(stencil.element(face.interiorIndex()));
629 const auto right = identifyCell(stencil.element(face.exteriorIndex()));
631 const auto rates = this->
632 getComponentSurfaceRates(elemCtx, face.area(), scvfIdx, timeIdx);
665 template <
class Flu
idState>
668 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
672 fs.setSaturation(phaseIdx, this->
saturation_[phaseIdx][elemIdx]);
678 std::array<Scalar, numPhases> pc = {0};
679 const MaterialLawParams& matParams = simulator_.problem().materialLawParams(elemIdx);
680 MaterialLaw::capillaryPressures(pc, matParams, fs);
682 Valgrind::CheckDefined(pc);
684 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
685 if (!FluidSystem::phaseIsActive(phaseIdx))
688 if (Indices::oilEnabled)
689 fs.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[oilPhaseIdx]));
690 else if (Indices::gasEnabled)
691 fs.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[gasPhaseIdx]));
692 else if (Indices::waterEnabled)
694 fs.setPressure(phaseIdx, pressure);
698 if constexpr (energyModuleType != EnergyModules::NoTemperature) {
700 fs.setTemperature(this->temperature_[elemIdx]);
702 if constexpr (enableDissolvedGas) {
703 if (!this->rs_.empty())
704 fs.setRs(this->rs_[elemIdx]);
705 if (!this->rv_.empty())
706 fs.setRv(this->rv_[elemIdx]);
708 if constexpr (enableDisgasInWater) {
709 if (!this->
rsw_.empty())
710 fs.setRsw(this->rsw_[elemIdx]);
712 if constexpr (enableVapwat) {
713 if (!this->
rvw_.empty())
714 fs.setRvw(this->rvw_[elemIdx]);
720 if (!this->
soMax_.empty())
721 simulator.problem().setMaxOilSaturation(elemIdx, this->
soMax_[elemIdx]);
723 if (simulator.problem().materialLawManager()->enableHysteresis()) {
724 auto matLawManager = simulator.problem().materialLawManager();
726 if (FluidSystem::phaseIsActive(oilPhaseIdx)
727 && FluidSystem::phaseIsActive(waterPhaseIdx)) {
732 if (matLawManager->enableNonWettingHysteresis()) {
733 if (!this->
soMax_.empty()) {
734 somax = this->
soMax_[elemIdx];
737 if (matLawManager->enableWettingHysteresis()) {
738 if (!this->
swMax_.empty()) {
739 swmax = this->
swMax_[elemIdx];
742 if (matLawManager->enablePCHysteresis()) {
743 if (!this->
swmin_.empty()) {
744 swmin = this->
swmin_[elemIdx];
747 matLawManager->setOilWaterHysteresisParams(
748 somax, swmax, swmin, elemIdx);
750 if (FluidSystem::phaseIsActive(oilPhaseIdx)
751 && FluidSystem::phaseIsActive(gasPhaseIdx)) {
756 if (matLawManager->enableNonWettingHysteresis()) {
757 if (!this->
sgmax_.empty()) {
758 sgmax = this->
sgmax_[elemIdx];
761 if (matLawManager->enableWettingHysteresis()) {
762 if (!this->
shmax_.empty()) {
763 shmax = this->
shmax_[elemIdx];
766 if (matLawManager->enablePCHysteresis()) {
767 if (!this->
somin_.empty()) {
768 somin = this->
somin_[elemIdx];
771 matLawManager->setGasOilHysteresisParams(
772 sgmax, shmax, somin, elemIdx);
777 if (simulator_.vanguard().eclState().fieldProps().has_double(
"SWATINIT")) {
778 simulator.problem().materialLawManager()
779 ->applyRestartSwatInit(elemIdx, this->
ppcw_[elemIdx]);
785 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
786 updateFluidInPlace_(elemCtx, dofIdx);
791 const IntensiveQuantities& intQuants,
792 const double totVolume)
794 this->updateFluidInPlace_(globalDofIdx, intQuants, totVolume);
799 const unsigned elemIdx,
800 const unsigned globalDofIndex)
override
804 auto assign = [&sol, elemIdx, globalDofIndex](
const std::string& name,
807 if (!data.empty() && sol.has(name)) {
808 data[elemIdx] = sol.data<
double>(name)[globalDofIndex];
820 const unsigned bufferSize)
override
825 FluidSystem::enableDissolvedGas(),
true);
827 FluidSystem::enableVaporizedOil(),
true);
831 bubblePointPressure_,
"PBPD",
true)) {
832 dewPointPressure_.resize(bufferSize, 0.0);
836 constexpr auto phaseChar = std::string_view{
"WOG"};
837 for (
unsigned phase = 0; phase < numPhases; ++phase) {
838 if (!FluidSystem::phaseIsActive(phase)) {
844 std::string(
"B") + phaseChar[phase],
true);
846 std::string(
"KR") + phaseChar[phase],
true);
856 ScalarBuffer bubblePointPressure_;
857 ScalarBuffer dewPointPressure_;
858 std::array<ScalarBuffer, numPhases> invB_;
859 std::array<ScalarBuffer, numPhases> relativePermeability_;
860 template <
typename T>
861 using RemoveCVR = std::remove_cv_t<std::remove_reference_t<T>>;
863 template <
typename,
class =
void>
864 struct HasGeoMech :
public std::false_type {};
866 template <
typename Problem>
868 Problem, std::void_t<decltype(std::declval<Problem>().geoMechModel())>
869 > :
public std::true_type {};
871 template <
typename,
class =
void>
872 struct HasGeochemistry :
public std::false_type {};
874 template <
typename Problem>
875 struct HasGeochemistry<
876 Problem, std::void_t<decltype(std::declval<Problem>().geochemistryModel())>
877 > :
public std::true_type {};
879 bool isDefunctParallelWell(
const std::string& wname)
const override
881 if (simulator_.gridView().comm().size() == 1)
883 const auto& parallelWells = simulator_.vanguard().parallelWells();
884 std::pair<std::string, bool> value {wname,
true};
885 auto candidate = std::lower_bound(parallelWells.begin(), parallelWells.end(), value);
886 return candidate == parallelWells.end() || *candidate != value;
889 bool isOwnedByCurrentRank(
const std::string& wname)
const override
891 return this->simulator_.problem().wellModel().isOwner(wname);
894 bool isOnCurrentRank(
const std::string& wname)
const override
896 return this->simulator_.problem().wellModel().hasLocalCells(wname);
899 void updateFluidInPlace_(
const ElementContext& elemCtx,
const unsigned dofIdx)
901 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
902 const unsigned globalDofIdx = elemCtx.globalSpaceIndex(dofIdx, 0);
903 const auto totVolume = elemCtx.simulator().model().dofTotalVolume(globalDofIdx);
905 this->updateFluidInPlace_(globalDofIdx, intQuants, totVolume);
908 void updateFluidInPlace_(
const unsigned globalDofIdx,
909 const IntensiveQuantities& intQuants,
910 const double totVolume)
917 intQuants.referencePorosity());
920 this->updatePhaseInplaceVolumes_(globalDofIdx, intQuants, totVolume);
928 void mapRegionsOntoLeaf_()
930 const LookUpData<Grid, GridView> lookUpData(simulator_.gridView());
931 const auto numLeaf = simulator_.gridView().size(0);
933 std::vector<int> onLeaf(numLeaf, 0);
934 for (
auto& [name, region] : this->regions_) {
935 std::size_t elemIdx = 0;
936 for (
const auto& elem : elements(simulator_.gridView())) {
937 onLeaf[elemIdx++] = lookUpData(elem, region);
944 void createLocalRegion_(std::vector<int>& region)
946 std::size_t elemIdx = 0;
947 for (
const auto& elem : elements(simulator_.gridView())) {
948 if (elem.partitionType() != Dune::InteriorEntity) {
956 template <
typename Flu
idState>
957 void aggregateAverageDensityContributions_(
const FluidState& fs,
958 const unsigned int globalDofIdx,
961 auto pvCellValue = RegionPhasePoreVolAverage::CellValue{};
962 pvCellValue.porv = porv;
964 for (
auto phaseIdx = 0*FluidSystem::numPhases;
965 phaseIdx < FluidSystem::numPhases; ++phaseIdx)
967 if (! FluidSystem::phaseIsActive(phaseIdx)) {
971 pvCellValue.value = getValue(fs.density(phaseIdx));
972 pvCellValue.sat = getValue(fs.saturation(phaseIdx));
975 ->addCell(globalDofIdx,
996 data::InterRegFlowMap::FlowRates
997 getComponentSurfaceRates(
const ElementContext& elemCtx,
998 const Scalar faceArea,
999 const std::size_t scvfIdx,
1000 const std::size_t timeIdx)
const
1002 using Component = data::InterRegFlowMap::Component;
1004 auto rates = data::InterRegFlowMap::FlowRates {};
1006 const auto& extQuant = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
1008 const auto alpha = getValue(extQuant.extrusionFactor()) * faceArea;
1010 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1011 const auto& up = elemCtx
1012 .intensiveQuantities(extQuant.upstreamIndex(oilPhaseIdx), timeIdx);
1014 const auto pvtReg = up.pvtRegionIndex();
1016 const auto bO = getValue(getInvB_<FluidSystem, FluidState, Scalar>
1017 (up.fluidState(), oilPhaseIdx, pvtReg));
1019 const auto qO = alpha * bO * getValue(extQuant.volumeFlux(oilPhaseIdx));
1021 rates[Component::Oil] += qO;
1023 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1024 const auto Rs = getValue(
1025 BlackOil::getRs_<FluidSystem, FluidState, Scalar>
1026 (up.fluidState(), pvtReg));
1028 rates[Component::Gas] += qO *
Rs;
1029 rates[Component::Disgas] += qO *
Rs;
1033 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1034 const auto& up = elemCtx
1035 .intensiveQuantities(extQuant.upstreamIndex(gasPhaseIdx), timeIdx);
1037 const auto pvtReg = up.pvtRegionIndex();
1039 const auto bG = getValue(getInvB_<FluidSystem, FluidState, Scalar>
1040 (up.fluidState(), gasPhaseIdx, pvtReg));
1042 const auto qG = alpha * bG * getValue(extQuant.volumeFlux(gasPhaseIdx));
1044 rates[Component::Gas] += qG;
1046 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1047 const auto Rv = getValue(
1048 BlackOil::getRv_<FluidSystem, FluidState, Scalar>
1049 (up.fluidState(), pvtReg));
1051 rates[Component::Oil] += qG *
Rv;
1052 rates[Component::Vapoil] += qG *
Rv;
1056 if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
1057 const auto& up = elemCtx
1058 .intensiveQuantities(extQuant.upstreamIndex(waterPhaseIdx), timeIdx);
1060 const auto pvtReg = up.pvtRegionIndex();
1062 const auto bW = getValue(getInvB_<FluidSystem, FluidState, Scalar>
1063 (up.fluidState(), waterPhaseIdx, pvtReg));
1065 rates[Component::Water] +=
1066 alpha * bW * getValue(extQuant.volumeFlux(waterPhaseIdx));
1072 void updatePhaseInplaceVolumes_(
const unsigned globalDofIdx,
1073 const IntensiveQuantities& intQuants,
1074 const double totVolume)
1076 std::array<Scalar, FluidSystem::numPhases> fip {};
1077 std::array<Scalar, FluidSystem::numPhases> fipr{};
1079 const auto& fs = intQuants.fluidState();
1080 const auto pv = totVolume * intQuants.porosity().value();
1082 for (
unsigned phaseIdx = 0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) {
1083 if (!FluidSystem::phaseIsActive(phaseIdx)) {
1087 const auto b = getValue(fs.invB(phaseIdx));
1088 const auto s = getValue(fs.saturation(phaseIdx));
1090 fipr[phaseIdx] = s * pv;
1091 fip [phaseIdx] = b * fipr[phaseIdx];
1096 fs.saltConcentration().value(),
1099 if (FluidSystem::phaseIsActive(oilPhaseIdx) &&
1100 FluidSystem::phaseIsActive(gasPhaseIdx))
1102 this->updateOilGasDistribution(globalDofIdx, fs, fip);
1105 if (FluidSystem::phaseIsActive(waterPhaseIdx) &&
1106 FluidSystem::phaseIsActive(gasPhaseIdx))
1108 this->updateGasWaterDistribution(globalDofIdx, fs, fip);
1111 if (FluidSystem::phaseIsActive(gasPhaseIdx) &&
1114 this->updateCO2InGas(globalDofIdx, pv, intQuants);
1118 (FluidSystem::phaseIsActive(waterPhaseIdx) ||
1119 FluidSystem::phaseIsActive(oilPhaseIdx)))
1121 this->updateCO2InWater(globalDofIdx, pv, fs);
1124 if constexpr(enableBioeffects) {
1125 const auto surfVolWat = pv * getValue(fs.saturation(waterPhaseIdx)) *
1126 getValue(fs.invB(waterPhaseIdx));
1128 this->updateMicrobialMass(globalDofIdx, intQuants, surfVolWat);
1131 this->updateBiofilmMass(globalDofIdx, intQuants, totVolume);
1133 if constexpr(enableMICP) {
1135 this->updateOxygenMass(globalDofIdx, intQuants, surfVolWat);
1138 this->updateUreaMass(globalDofIdx, intQuants, surfVolWat);
1141 this->updateCalciteMass(globalDofIdx, intQuants, totVolume);
1148 this->updateWaterMass(globalDofIdx, fs, fip);
1152 template <
typename Flu
idState,
typename FIPArray>
1153 void updateOilGasDistribution(
const unsigned globalDofIdx,
1154 const FluidState& fs,
1155 const FIPArray& fip)
1158 const auto gasInPlaceLiquid = getValue(fs.Rs()) * fip[oilPhaseIdx];
1159 const auto oilInPlaceGas = getValue(fs.Rv()) * fip[gasPhaseIdx];
1164 template <
typename Flu
idState,
typename FIPArray>
1165 void updateGasWaterDistribution(
const unsigned globalDofIdx,
1166 const FluidState& fs,
1167 const FIPArray& fip)
1170 const auto gasInPlaceWater = getValue(fs.Rsw()) * fip[waterPhaseIdx];
1171 const auto waterInPlaceGas = getValue(fs.Rvw()) * fip[gasPhaseIdx];
1176 template <
typename IntensiveQuantities>
1177 void updateCO2InGas(
const unsigned globalDofIdx,
1179 const IntensiveQuantities& intQuants)
1181 const auto& scaledDrainageInfo = this->simulator_.problem().materialLawManager()
1182 ->oilWaterScaledEpsInfoDrainage(globalDofIdx);
1184 const auto& fs = intQuants.fluidState();
1185 Scalar sgcr = scaledDrainageInfo.Sgcr;
1186 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1187 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1188 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
1191 Scalar trappedGasSaturation = scaledDrainageInfo.Sgcr;
1192 if (this->
fipC_.
has(Inplace::Phase::CO2MassInGasPhaseMaximumTrapped) ||
1193 this->fipC_.has(Inplace::Phase::CO2MassInGasPhaseMaximumUnTrapped))
1195 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1196 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1198 trappedGasSaturation = MaterialLaw::trappedGasSaturation(matParams,
true);
1202 const Scalar sg = getValue(fs.saturation(gasPhaseIdx));
1203 Scalar strandedGasSaturation = scaledDrainageInfo.Sgcr;
1204 if (this->
fipC_.
has(Inplace::Phase::CO2MassInGasPhaseEffectiveTrapped) ||
1205 this->fipC_.has(Inplace::Phase::CO2MassInGasPhaseEffectiveUnTrapped))
1207 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1208 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1209 const double krg = getValue(intQuants.relativePermeability(gasPhaseIdx));
1210 strandedGasSaturation = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
1214 const typename FIPContainer<FluidSystem>::Co2InGasInput v{
1218 getValue(fs.density(gasPhaseIdx)),
1219 FluidSystem::phaseIsActive(waterPhaseIdx)
1220 ? FluidSystem::convertRvwToXgW(getValue(fs.Rvw()), fs.pvtRegionIndex())
1221 : FluidSystem::convertRvToXgO(getValue(fs.
Rv()), fs.pvtRegionIndex()),
1222 FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex()),
1223 trappedGasSaturation,
1224 strandedGasSaturation,
1230 template <
typename Flu
idState>
1231 void updateCO2InWater(
const unsigned globalDofIdx,
1233 const FluidState& fs)
1235 const auto co2InWater = FluidSystem::phaseIsActive(oilPhaseIdx)
1236 ? this->co2InWaterFromOil(fs, pv)
1237 : this->co2InWaterFromWater(fs, pv);
1239 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1244 template <
typename Flu
idState>
1245 Scalar co2InWaterFromWater(
const FluidState& fs,
const double pv)
const
1247 const double rhow = getValue(fs.density(waterPhaseIdx));
1248 const double sw = getValue(fs.saturation(waterPhaseIdx));
1249 const double xwG = FluidSystem::convertRswToXwG(getValue(fs.Rsw()), fs.pvtRegionIndex());
1251 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1253 return xwG * pv * rhow * sw / mM;
1256 template <
typename Flu
idState>
1257 Scalar co2InWaterFromOil(
const FluidState& fs,
const double pv)
const
1259 const double rhoo = getValue(fs.density(oilPhaseIdx));
1260 const double so = getValue(fs.saturation(oilPhaseIdx));
1261 const double xoG = FluidSystem::convertRsToXoG(getValue(fs.Rs()), fs.pvtRegionIndex());
1263 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1265 return xoG * pv * rhoo * so / mM;
1268 template <
typename Flu
idState,
typename FIPArray>
1269 void updateWaterMass(
const unsigned globalDofIdx,
1270 const FluidState& fs,
1274 const Scalar rhoW = FluidSystem::referenceDensity(waterPhaseIdx, fs.pvtRegionIndex());
1279 template <
typename IntensiveQuantities>
1280 void updateMicrobialMass(
const unsigned globalDofIdx,
1281 const IntensiveQuantities& intQuants,
1282 const double surfVolWat)
1284 const Scalar mass = surfVolWat * intQuants.microbialConcentration().value();
1289 template <
typename IntensiveQuantities>
1290 void updateOxygenMass(
const unsigned globalDofIdx,
1291 const IntensiveQuantities& intQuants,
1292 const double surfVolWat)
1294 const Scalar mass = surfVolWat * intQuants.oxygenConcentration().value();
1299 template <
typename IntensiveQuantities>
1300 void updateUreaMass(
const unsigned globalDofIdx,
1301 const IntensiveQuantities& intQuants,
1302 const double surfVolWat)
1304 const Scalar mass = surfVolWat * intQuants.ureaConcentration().value();
1309 template <
typename IntensiveQuantities>
1310 void updateBiofilmMass(
const unsigned globalDofIdx,
1311 const IntensiveQuantities& intQuants,
1312 const double totVolume)
1314 const Scalar mass = totVolume * intQuants.biofilmMass().value();
1319 template <
typename IntensiveQuantities>
1320 void updateCalciteMass(
const unsigned globalDofIdx,
1321 const IntensiveQuantities& intQuants,
1322 const double totVolume)
1324 const Scalar mass = totVolume * intQuants.calciteMass().value();
1330 void setupElementExtractors_()
1332 using Entry =
typename Extractor::Entry;
1333 using Context =
typename Extractor::Context;
1334 using ScalarEntry =
typename Extractor::ScalarEntry;
1335 using PhaseEntry =
typename Extractor::PhaseEntry;
1337 const bool hasResidual = simulator_.model().linearizer().residual().size() > 0;
1338 const auto& hysteresisConfig = simulator_.problem().materialLawManager()->hysteresisConfig();
1340 auto extractors = std::array{
1342 [](
const unsigned phase,
const Context& ectx)
1343 {
return getValue(ectx.fs.saturation(phase)); }
1346 Entry{PhaseEntry{&this->invB_,
1347 [](
const unsigned phase,
const Context& ectx)
1348 {
return getValue(ectx.fs.invB(phase)); }
1352 [](
const unsigned phase,
const Context& ectx)
1353 {
return getValue(ectx.fs.density(phase)); }
1356 Entry{PhaseEntry{&this->relativePermeability_,
1357 [](
const unsigned phase,
const Context& ectx)
1358 {
return getValue(ectx.intQuants.relativePermeability(phase)); }
1362 [
this](
const unsigned phaseIdx,
const Context& ectx)
1365 if constexpr (enableExtbo) {
1366 if (this->
extboC_.allocated() && phaseIdx == oilPhaseIdx) {
1367 return getValue(ectx.intQuants.oilViscosity());
1369 else if (this->
extboC_.allocated() && phaseIdx == gasPhaseIdx) {
1370 return getValue(ectx.intQuants.gasViscosity());
1373 return getValue(ectx.fs.viscosity(phaseIdx));
1378 [&modelResid = this->simulator_.model().linearizer().residual()]
1379 (
const unsigned phaseIdx,
const Context& ectx)
1381 const unsigned sIdx = FluidSystem::solventComponentIndex(phaseIdx);
1382 const unsigned activeCompIdx = FluidSystem::canonicalToActiveCompIdx(sIdx);
1383 return modelResid[ectx.globalDofIdx][activeCompIdx];
1389 [&problem = this->simulator_.problem()](
const Context& ectx)
1391 return problem.template
1392 rockCompPoroMultiplier<Scalar>(ectx.intQuants,
1398 [&problem = this->simulator_.problem()](
const Context& ectx)
1401 template rockCompTransMultiplier<Scalar>(ectx.intQuants,
1406 [&problem = this->simulator_.problem()](
const Context& ectx)
1408 return std::min(getValue(ectx.fs.pressure(oilPhaseIdx)),
1409 problem.minOilPressure(ectx.globalDofIdx));
1413 Entry{ScalarEntry{&this->bubblePointPressure_,
1415 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1419 FluidSystem::bubblePointPressure(ectx.fs,
1420 ectx.intQuants.pvtRegionIndex())
1422 }
catch (
const NumericalProblem&) {
1423 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1424 failedCells.push_back(cartesianIdx);
1430 Entry{ScalarEntry{&this->dewPointPressure_,
1432 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1436 FluidSystem::dewPointPressure(ectx.fs,
1437 ectx.intQuants.pvtRegionIndex())
1439 }
catch (
const NumericalProblem&) {
1440 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1441 failedCells.push_back(cartesianIdx);
1448 [&problem = simulator_.problem()](
const Context& ectx)
1449 {
return problem.overburdenPressure(ectx.globalDofIdx); }
1453 [](
const Context& ectx)
1454 {
return getValue(ectx.fs.temperature(oilPhaseIdx)); }
1457 Entry{ScalarEntry{&this->
sSol_,
1458 [](
const Context& ectx)
1460 if constexpr (enableSolvent) {
1461 return getValue(ectx.intQuants.solventSaturation());
1469 Entry{ScalarEntry{&this->
rswSol_,
1470 [](
const Context& ectx)
1472 if constexpr (enableSolvent) {
1473 return getValue(ectx.intQuants.rsSolw());
1482 [](
const Context& ectx)
1484 if constexpr (enablePolymer) {
1485 return getValue(ectx.intQuants.polymerConcentration());
1493 Entry{ScalarEntry{&this->
cFoam_,
1494 [](
const Context& ectx)
1496 if constexpr (enableFoam) {
1497 return getValue(ectx.intQuants.foamConcentration());
1505 Entry{ScalarEntry{&this->
cSalt_,
1506 [](
const Context& ectx)
1507 {
return getValue(ectx.fs.saltConcentration()); }
1510 Entry{ScalarEntry{&this->
pSalt_,
1511 [](
const Context& ectx)
1512 {
return getValue(ectx.fs.saltSaturation()); }
1516 [](
const Context& ectx)
1517 {
return getValue(ectx.intQuants.permFactor()); }
1520 Entry{ScalarEntry{&this->
rPorV_,
1521 [&model = this->simulator_.model()](
const Context& ectx)
1523 const auto totVolume = model.dofTotalVolume(ectx.globalDofIdx);
1524 return totVolume * getValue(ectx.intQuants.porosity());
1528 Entry{ScalarEntry{&this->rs_,
1529 [](
const Context& ectx)
1530 {
return getValue(ectx.fs.Rs()); }
1533 Entry{ScalarEntry{&this->rv_,
1534 [](
const Context& ectx)
1535 {
return getValue(ectx.fs.Rv()); }
1538 Entry{ScalarEntry{&this->
rsw_,
1539 [](
const Context& ectx)
1540 {
return getValue(ectx.fs.Rsw()); }
1543 Entry{ScalarEntry{&this->
rvw_,
1544 [](
const Context& ectx)
1545 {
return getValue(ectx.fs.Rvw()); }
1548 Entry{ScalarEntry{&this->
ppcw_,
1549 [&matLawManager = *this->simulator_.problem().materialLawManager()]
1550 (
const Context& ectx)
1552 return matLawManager.
1553 oilWaterScaledEpsInfoDrainage(ectx.globalDofIdx).maxPcow;
1558 [&problem = this->simulator_.problem()](
const Context& ectx)
1560 return problem.drsdtcon(ectx.globalDofIdx,
1565 Entry{ScalarEntry{&this->
pcgw_,
1566 [](
const Context& ectx)
1568 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1569 getValue(ectx.fs.pressure(waterPhaseIdx));
1573 Entry{ScalarEntry{&this->
pcow_,
1574 [](
const Context& ectx)
1576 return getValue(ectx.fs.pressure(oilPhaseIdx)) -
1577 getValue(ectx.fs.pressure(waterPhaseIdx));
1581 Entry{ScalarEntry{&this->
pcog_,
1582 [](
const Context& ectx)
1584 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1585 getValue(ectx.fs.pressure(oilPhaseIdx));
1590 [](
const Context& ectx)
1592 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1594 return getValue(ectx.fs.pressure(oilPhaseIdx));
1596 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1598 return getValue(ectx.fs.pressure(gasPhaseIdx));
1602 return getValue(ectx.fs.pressure(waterPhaseIdx));
1608 [&problem = this->simulator_.problem()](
const Context& ectx)
1610 const Scalar SoMax = problem.maxOilSaturation(ectx.globalDofIdx);
1611 return FluidSystem::template
1612 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1620 [&problem = this->simulator_.problem()](
const Context& ectx)
1622 const Scalar SoMax = problem.maxOilSaturation(ectx.globalDofIdx);
1623 return FluidSystem::template
1624 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1632 [&problem = this->simulator_.problem()](
const Context& ectx)
1634 const Scalar SwMax = problem.maxWaterSaturation(ectx.globalDofIdx);
1635 return FluidSystem::template
1636 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1644 [](
const Context& ectx)
1646 return FluidSystem::template
1647 saturatedVaporizationFactor<FluidState, Scalar>(ectx.fs,
1654 [](
const Context& ectx)
1656 return 1.0 / FluidSystem::template
1657 inverseFormationVolumeFactor<FluidState, Scalar>(ectx.fs,
1664 [](
const Context& ectx)
1666 return 1.0 / FluidSystem::template
1667 saturatedInverseFormationVolumeFactor<FluidState, Scalar>(ectx.fs,
1674 [](
const Context& ectx)
1676 return FluidSystem::template
1677 saturationPressure<FluidState, Scalar>(ectx.fs,
1683 Entry{ScalarEntry{&this->
soMax_,
1684 [&problem = this->simulator_.problem()](
const Context& ectx)
1686 return std::max(getValue(ectx.fs.saturation(oilPhaseIdx)),
1687 problem.maxOilSaturation(ectx.globalDofIdx));
1690 !hysteresisConfig.enableHysteresis()
1692 Entry{ScalarEntry{&this->
swMax_,
1693 [&problem = this->simulator_.problem()](
const Context& ectx)
1695 return std::max(getValue(ectx.fs.saturation(waterPhaseIdx)),
1696 problem.maxWaterSaturation(ectx.globalDofIdx));
1699 !hysteresisConfig.enableHysteresis()
1701 Entry{ScalarEntry{&this->
soMax_,
1702 [](
const Context& ectx)
1703 {
return ectx.hParams.somax; }
1705 hysteresisConfig.enableHysteresis() &&
1706 hysteresisConfig.enableNonWettingHysteresis() &&
1707 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1708 FluidSystem::phaseIsActive(waterPhaseIdx)
1710 Entry{ScalarEntry{&this->
swMax_,
1711 [](
const Context& ectx)
1712 {
return ectx.hParams.swmax; }
1714 hysteresisConfig.enableHysteresis() &&
1715 hysteresisConfig.enableWettingHysteresis() &&
1716 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1717 FluidSystem::phaseIsActive(waterPhaseIdx)
1719 Entry{ScalarEntry{&this->
swmin_,
1720 [](
const Context& ectx)
1721 {
return ectx.hParams.swmin; }
1723 hysteresisConfig.enableHysteresis() &&
1724 hysteresisConfig.enablePCHysteresis() &&
1725 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1726 FluidSystem::phaseIsActive(waterPhaseIdx)
1728 Entry{ScalarEntry{&this->
sgmax_,
1729 [](
const Context& ectx)
1730 {
return ectx.hParams.sgmax; }
1732 hysteresisConfig.enableHysteresis() &&
1733 hysteresisConfig.enableNonWettingHysteresis() &&
1734 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1735 FluidSystem::phaseIsActive(gasPhaseIdx)
1737 Entry{ScalarEntry{&this->
shmax_,
1738 [](
const Context& ectx)
1739 {
return ectx.hParams.shmax; }
1741 hysteresisConfig.enableHysteresis() &&
1742 hysteresisConfig.enableWettingHysteresis() &&
1743 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1744 FluidSystem::phaseIsActive(gasPhaseIdx)
1746 Entry{ScalarEntry{&this->
somin_,
1747 [](
const Context& ectx)
1748 {
return ectx.hParams.somin; }
1750 hysteresisConfig.enableHysteresis() &&
1751 hysteresisConfig.enablePCHysteresis() &&
1752 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1753 FluidSystem::phaseIsActive(gasPhaseIdx)
1755 Entry{[&model = this->simulator_.model(),
this](
const Context& ectx)
1759 const auto porv = ectx.intQuants.referencePorosity()
1760 * model.dofTotalVolume(ectx.globalDofIdx);
1762 this->aggregateAverageDensityContributions_(ectx.fs, ectx.globalDofIdx,
1763 static_cast<double>(porv));
1766 Entry{[&extboC = this->
extboC_](
const Context& ectx)
1769 if constexpr (enableExtbo) {
1770 extboC.assignVolumes(ectx.globalDofIdx,
1771 ectx.intQuants.xVolume().value(),
1772 ectx.intQuants.yVolume().value());
1773 extboC.assignZFraction(ectx.globalDofIdx,
1774 ectx.intQuants.zFraction().value());
1776 const Scalar stdVolOil = getValue(ectx.fs.saturation(oilPhaseIdx)) *
1777 getValue(ectx.fs.invB(oilPhaseIdx)) +
1778 getValue(ectx.fs.saturation(gasPhaseIdx)) *
1779 getValue(ectx.fs.invB(gasPhaseIdx)) *
1780 getValue(ectx.fs.Rv());
1781 const Scalar stdVolGas = getValue(ectx.fs.saturation(gasPhaseIdx)) *
1782 getValue(ectx.fs.invB(gasPhaseIdx)) *
1783 (1.0 - ectx.intQuants.yVolume().value()) +
1784 getValue(ectx.fs.saturation(oilPhaseIdx)) *
1785 getValue(ectx.fs.invB(oilPhaseIdx)) *
1786 getValue(ectx.fs.Rs()) *
1787 (1.0 - ectx.intQuants.xVolume().value());
1788 const Scalar stdVolCo2 = getValue(ectx.fs.saturation(gasPhaseIdx)) *
1789 getValue(ectx.fs.invB(gasPhaseIdx)) *
1790 ectx.intQuants.yVolume().value() +
1791 getValue(ectx.fs.saturation(oilPhaseIdx)) *
1792 getValue(ectx.fs.invB(oilPhaseIdx)) *
1793 getValue(ectx.fs.Rs()) *
1794 ectx.intQuants.xVolume().value();
1795 const Scalar rhoO = FluidSystem::referenceDensity(oilPhaseIdx, ectx.pvtRegionIdx);
1796 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx, ectx.pvtRegionIdx);
1797 const Scalar rhoCO2 = ectx.intQuants.zRefDensity();
1798 const Scalar stdMassTotal = 1.0e-10 + stdVolOil * rhoO + stdVolGas * rhoG + stdVolCo2 * rhoCO2;
1799 extboC.assignMassFractions(ectx.globalDofIdx,
1800 stdVolGas * rhoG / stdMassTotal,
1801 stdVolOil * rhoO / stdMassTotal,
1802 stdVolCo2 * rhoCO2 / stdMassTotal);
1806 Entry{[&bioeffectsC = this->
bioeffectsC_](
const Context& ectx)
1809 if constexpr (enableBioeffects) {
1810 bioeffectsC.assign(ectx.globalDofIdx,
1811 ectx.intQuants.microbialConcentration().value(),
1812 ectx.intQuants.biofilmVolumeFraction().value());
1813 if (Indices::enableMICP) {
1814 bioeffectsC.assign(ectx.globalDofIdx,
1815 ectx.intQuants.oxygenConcentration().value(),
1816 ectx.intQuants.ureaConcentration().value(),
1817 ectx.intQuants.calciteVolumeFraction().value());
1822 Entry{[&runspec = this->
eclState_.runspec(),
1823 &CO2H2C = this->
CO2H2C_](
const Context& ectx)
1825 const auto xwg = FluidSystem::convertRswToXwG(getValue(ectx.fs.Rsw()), ectx.pvtRegionIdx);
1826 const auto xgw = FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.pvtRegionIdx);
1827 CO2H2C.assign(ectx.globalDofIdx,
1828 FluidSystem::convertXwGToxwG(xwg, ectx.pvtRegionIdx),
1829 FluidSystem::convertXgWToxgW(xgw, ectx.pvtRegionIdx),
1830 runspec.co2Storage());
1833 Entry{[&rftC = this->
rftC_,
1834 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1836 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1837 rftC.assign(cartesianIdx,
1838 [&fs = ectx.fs]() {
return getValue(fs.pressure(oilPhaseIdx)); },
1839 [&fs = ectx.fs]() {
return getValue(fs.saturation(waterPhaseIdx)); },
1840 [&fs = ectx.fs]() {
return getValue(fs.saturation(gasPhaseIdx)); });
1844 &tM = this->simulator_.problem().tracerModel()](
const Context& ectx)
1846 tC.assignFreeConcentrations(ectx.globalDofIdx,
1847 [gIdx = ectx.globalDofIdx, &tM](
const unsigned tracerIdx)
1848 {
return tM.freeTracerConcentration(tracerIdx, gIdx); });
1849 tC.assignSolConcentrations(ectx.globalDofIdx,
1850 [gIdx = ectx.globalDofIdx, &tM](
const unsigned tracerIdx)
1851 {
return tM.solTracerConcentration(tracerIdx, gIdx); });
1854 Entry{[&flowsInf = this->simulator_.problem().model().linearizer().getFlowsInfo(),
1856 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1858 const auto gas_idx = Indices::gasEnabled ?
1859 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(gasCompIdx) : -1;
1860 const auto oil_idx = Indices::oilEnabled ?
1861 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(oilCompIdx) : -1;
1862 const auto water_idx = Indices::waterEnabled ?
1863 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(waterCompIdx) : -1;
1864 const auto& flowsInfos = flowsInf[ectx.globalDofIdx];
1865 if (!flowsC.blockFlows().empty()) {
1866 const std::vector<int>& blockIdxs = flowsC.blockFlows();
1867 const unsigned cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1868 if (std::ranges::binary_search(blockIdxs, cartesianIdx)) {
1869 const auto compIdxs = std::array{ gasCompIdx, oilCompIdx, waterCompIdx };
1870 const auto compEnabled = std::array{ Indices::gasEnabled, Indices::oilEnabled, Indices::waterEnabled };
1871 for (
const auto& flowsInfo : flowsInfos) {
1872 if (flowsInfo.faceId < 0) {
1875 for (
unsigned ii = 0; ii < compIdxs.size(); ++ii) {
1876 if (!compEnabled[ii]) {
1879 if (flowsC.hasBlockFlowValue(cartesianIdx, flowsInfo.faceId, compIdxs[ii])) {
1880 flowsC.assignBlockFlows(flowsC.blockFlowsIds(cartesianIdx, flowsInfo.faceId, compIdxs[ii]),
1883 flowsInfo.flow[conti0EqIdx
1884 + FluidSystem::canonicalToActiveCompIdx(compIdxs[ii])]);
1891 for (
const auto& flowsInfo : flowsInfos) {
1892 flowsC.assignFlows(ectx.globalDofIdx,
1895 value_or_zero(gas_idx, flowsInfo.flow),
1896 value_or_zero(oil_idx, flowsInfo.flow),
1897 value_or_zero(water_idx, flowsInfo.flow));
1900 }, !this->simulator_.problem().model().linearizer().getFlowsInfo().empty()
1902 Entry{[&floresInf = this->simulator_.problem().model().linearizer().getFloresInfo(),
1903 &flowsC = this->
flowsC_](
const Context& ectx)
1905 const auto gas_idx = Indices::gasEnabled ?
1906 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(gasCompIdx) : -1;
1907 const auto oil_idx = Indices::oilEnabled ?
1908 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(oilCompIdx) : -1;
1909 const auto water_idx = Indices::waterEnabled ?
1910 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(waterCompIdx) : -1;
1911 const auto& floresInfos = floresInf[ectx.globalDofIdx];
1912 for (
const auto& floresInfo : floresInfos) {
1913 flowsC.assignFlores(ectx.globalDofIdx,
1916 value_or_zero(gas_idx, floresInfo.flow),
1917 value_or_zero(oil_idx, floresInfo.flow),
1918 value_or_zero(water_idx, floresInfo.flow));
1920 }, !this->simulator_.problem().model().linearizer().getFloresInfo().empty()
1922 Entry{[&velocityInf = this->simulator_.problem().model().linearizer().getVelocityInfo(),
1924 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1926 const auto& velocityInfos = velocityInf[ectx.globalDofIdx];
1927 const std::vector<int>& blockIdxs = flowsC.blockVelocity();
1928 const unsigned cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1929 if (std::ranges::binary_search(blockIdxs, cartesianIdx)) {
1930 const auto compIdxs = std::array{ gasCompIdx, oilCompIdx, waterCompIdx };
1931 const auto compEnabled = std::array{ Indices::gasEnabled, Indices::oilEnabled, Indices::waterEnabled };
1932 for (
const auto& velocityInfo : velocityInfos) {
1933 if (velocityInfo.faceId < 0) {
1936 for (
unsigned ii = 0; ii < compIdxs.size(); ++ii) {
1937 if (!compEnabled[ii]) {
1940 if (flowsC.hasBlockVelocityValue(cartesianIdx, velocityInfo.faceId, compIdxs[ii])) {
1941 flowsC.assignBlockVelocity(flowsC.blockVelocityIds(cartesianIdx, velocityInfo.faceId, compIdxs[ii]),
1942 velocityInfo.faceId,
1944 velocityInfo.velocity[conti0EqIdx
1945 + FluidSystem::canonicalToActiveCompIdx(compIdxs[ii])]);
1951 !this->simulator_.problem().model().linearizer().getVelocityInfo().empty()
1958 Entry{ScalarEntry{&this->rv_,
1959 [&problem = this->simulator_.problem()](
const Context& ectx)
1960 {
return problem.initialFluidState(ectx.globalDofIdx).Rv(); }
1962 simulator_.episodeIndex() < 0 &&
1963 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1964 FluidSystem::phaseIsActive(gasPhaseIdx)
1966 Entry{ScalarEntry{&this->rs_,
1967 [&problem = this->simulator_.problem()](
const Context& ectx)
1968 {
return problem.initialFluidState(ectx.globalDofIdx).Rs(); }
1970 simulator_.episodeIndex() < 0 &&
1971 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1972 FluidSystem::phaseIsActive(gasPhaseIdx)
1974 Entry{ScalarEntry{&this->
rsw_,
1975 [&problem = this->simulator_.problem()](
const Context& ectx)
1976 {
return problem.initialFluidState(ectx.globalDofIdx).Rsw(); }
1978 simulator_.episodeIndex() < 0 &&
1979 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1980 FluidSystem::phaseIsActive(gasPhaseIdx)
1982 Entry{ScalarEntry{&this->
rvw_,
1983 [&problem = this->simulator_.problem()](
const Context& ectx)
1984 {
return problem.initialFluidState(ectx.globalDofIdx).Rvw(); }
1986 simulator_.episodeIndex() < 0 &&
1987 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1988 FluidSystem::phaseIsActive(gasPhaseIdx)
1992 [&problem = this->simulator_.problem()](
const unsigned phase,
1993 const Context& ectx)
1995 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
1996 return FluidSystem::density(fsInitial,
1998 ectx.intQuants.pvtRegionIndex());
2001 simulator_.episodeIndex() < 0 &&
2002 FluidSystem::phaseIsActive(oilPhaseIdx) &&
2003 FluidSystem::phaseIsActive(gasPhaseIdx)
2005 Entry{PhaseEntry{&this->invB_,
2006 [&problem = this->simulator_.problem()](
const unsigned phase,
2007 const Context& ectx)
2009 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
2010 return FluidSystem::inverseFormationVolumeFactor(fsInitial,
2012 ectx.intQuants.pvtRegionIndex());
2015 simulator_.episodeIndex() < 0 &&
2016 FluidSystem::phaseIsActive(oilPhaseIdx) &&
2017 FluidSystem::phaseIsActive(gasPhaseIdx)
2020 [&problem = this->simulator_.problem()](
const unsigned phase,
2021 const Context& ectx)
2023 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
2024 return FluidSystem::viscosity(fsInitial,
2026 ectx.intQuants.pvtRegionIndex());
2029 simulator_.episodeIndex() < 0 &&
2030 FluidSystem::phaseIsActive(oilPhaseIdx) &&
2031 FluidSystem::phaseIsActive(gasPhaseIdx)
2039 if constexpr (getPropValue<TypeTag, Properties::EnableGeochemistry>()) {
2041 this->extractors_.emplace_back(
2043 &gM = this->simulator_.problem().geochemistryModel()](
const Context& ectx)
2045 gC.assignSpeciesConcentrations(
2047 [gIdx = ectx.globalDofIdx, &gM](
const unsigned speciesIdx)
2048 {
return gM.speciesConcentration(speciesIdx, gIdx); }
2050 gC.assignMineralConcentrations(
2052 [gIdx = ectx.globalDofIdx, &gM](
const unsigned mineralIdx)
2053 {
return gM.mineralConcentration(mineralIdx, gIdx); }
2055 gC.assignPH(ectx.globalDofIdx, gM.PH(ectx.globalDofIdx));
2063 if constexpr (getPropValue<TypeTag, Properties::EnableMech>()) {
2064 if (this->
mech_.allocated()) {
2065 this->extractors_.emplace_back(
2066 [&mech = this->
mech_,
2067 &model = simulator_.problem().geoMechModel()](
const Context& ectx)
2069 mech.assignDelStress(ectx.globalDofIdx,
2070 model.delstress(ectx.globalDofIdx));
2072 mech.assignDisplacement(ectx.globalDofIdx,
2073 model.disp(ectx.globalDofIdx,
true));
2076 mech.assignFracStress(ectx.globalDofIdx,
2077 model.fractureStress(ectx.globalDofIdx));
2079 mech.assignLinStress(ectx.globalDofIdx,
2080 model.linstress(ectx.globalDofIdx));
2082 mech.assignPotentialForces(ectx.globalDofIdx,
2083 model.mechPotentialForce(ectx.globalDofIdx),
2084 model.mechPotentialPressForce(ectx.globalDofIdx),
2085 model.mechPotentialTempForce(ectx.globalDofIdx));
2087 mech.assignStrain(ectx.globalDofIdx,
2088 model.strain(ectx.globalDofIdx,
true));
2091 mech.assignStress(ectx.globalDofIdx,
2092 model.stress(ectx.globalDofIdx,
true));
2097 if (this->
tpsaC_.allocated()) {
2098 this->extractors_.emplace_back(
2100 &model = simulator_.problem().geoMechModel()](
const Context& ectx) {
2101 tpsaC.assignRotation(ectx.globalDofIdx,
2102 model.rotation(ectx.globalDofIdx));
2104 tpsaC.assignSolidPressure(ectx.globalDofIdx,
2105 model.solidPressure(ectx.globalDofIdx));
2114 void setupBlockExtractors_(
const bool isSubStep,
2115 const int reportStepNum)
2118 using Context =
typename BlockExtractor::Context;
2119 using PhaseEntry =
typename BlockExtractor::PhaseEntry;
2120 using ScalarEntry =
typename BlockExtractor::ScalarEntry;
2121 using TensorEntry =
typename BlockExtractor::TensorEntry;
2123 using namespace std::string_view_literals;
2125 const auto pressure_handler =
2126 Entry{ScalarEntry{std::vector{
"BPR"sv,
"BPRESSUR"sv},
2127 [](
const Context& ectx)
2129 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2130 return getValue(ectx.fs.pressure(oilPhaseIdx));
2132 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
2133 return getValue(ectx.fs.pressure(gasPhaseIdx));
2136 return getValue(ectx.fs.pressure(waterPhaseIdx));
2142 const auto handlers = std::array{
2144 Entry{PhaseEntry{std::array{
2145 std::array{
"BWSAT"sv,
"BOSAT"sv,
"BGSAT"sv},
2146 std::array{
"BSWAT"sv,
"BSOIL"sv,
"BSGAS"sv}
2148 [](
const unsigned phaseIdx,
const Context& ectx)
2150 return getValue(ectx.fs.saturation(phaseIdx));
2154 Entry{ScalarEntry{
"BNSAT",
2155 [](
const Context& ectx)
2157 if constexpr (enableSolvent) {
2158 return ectx.intQuants.solventSaturation().value();
2166 Entry{ScalarEntry{std::vector{
"BTCNFHEA"sv,
"BTEMP"sv},
2167 [](
const Context& ectx)
2169 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2170 return getValue(ectx.fs.temperature(oilPhaseIdx));
2172 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
2173 return getValue(ectx.fs.temperature(gasPhaseIdx));
2176 return getValue(ectx.fs.temperature(waterPhaseIdx));
2181 Entry{PhaseEntry{std::array{
2182 std::array{
"BWKR"sv,
"BOKR"sv,
"BGKR"sv},
2183 std::array{
"BKRW"sv,
"BKRO"sv,
"BKRG"sv}
2185 [](
const unsigned phaseIdx,
const Context& ectx)
2187 return getValue(ectx.intQuants.relativePermeability(phaseIdx));
2191 Entry{ScalarEntry{
"BKROG",
2192 [&problem = this->simulator_.problem()](
const Context& ectx)
2194 const auto& materialParams =
2195 problem.materialLawParams(ectx.elemCtx,
2198 return getValue(MaterialLaw::template
2199 relpermOilInOilGasSystem<Evaluation>(materialParams,
2204 Entry{ScalarEntry{
"BKROW",
2205 [&problem = this->simulator_.problem()](
const Context& ectx)
2207 const auto& materialParams = problem.materialLawParams(ectx.elemCtx,
2210 return getValue(MaterialLaw::template
2211 relpermOilInOilWaterSystem<Evaluation>(materialParams,
2216 Entry{ScalarEntry{
"BWPC",
2217 [](
const Context& ectx)
2219 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2220 return getValue(ectx.fs.pressure(oilPhaseIdx)) -
2221 getValue(ectx.fs.pressure(waterPhaseIdx));
2223 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
2224 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
2225 getValue(ectx.fs.pressure(waterPhaseIdx));
2233 Entry{ScalarEntry{
"BGPC",
2234 [](
const Context& ectx)
2236 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2237 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
2238 getValue(ectx.fs.pressure(oilPhaseIdx));
2240 else if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
2241 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
2242 getValue(ectx.fs.pressure(waterPhaseIdx));
2250 Entry{ScalarEntry{
"BWPR",
2251 [](
const Context& ectx)
2253 return getValue(ectx.fs.pressure(waterPhaseIdx));
2257 Entry{ScalarEntry{
"BGPR",
2258 [](
const Context& ectx)
2260 return getValue(ectx.fs.pressure(gasPhaseIdx));
2264 Entry{PhaseEntry{std::array{
2265 std::array{
"BVWAT"sv,
"BVOIL"sv,
"BVGAS"sv},
2266 std::array{
"BWVIS"sv,
"BOVIS"sv,
"BGVIS"sv}
2268 [](
const unsigned phaseIdx,
const Context& ectx)
2270 return getValue(ectx.fs.viscosity(phaseIdx));
2274 Entry{PhaseEntry{std::array{
2275 std::array{
"BWDEN"sv,
"BODEN"sv,
"BGDEN"sv},
2276 std::array{
"BDENW"sv,
"BDENO"sv,
"BDENG"sv}
2278 [](
const unsigned phaseIdx,
const Context& ectx)
2280 return getValue(ectx.fs.density(phaseIdx));
2284 Entry{ScalarEntry{
"BFLOGI",
2286 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2288 const unsigned index = !flowsC.blockFlows().empty() ?
2289 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2290 FaceDir::ToIntersectionIndex(Dir::XPlus), gasCompIdx) : ectx.globalDofIdx;
2291 return flowsC.getFlow(index, Dir::XPlus, gasCompIdx);
2295 Entry{ScalarEntry{
"BFLOGI-",
2297 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2299 const unsigned index = !flowsC.blockFlows().empty() ?
2300 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2301 FaceDir::ToIntersectionIndex(Dir::XMinus), gasCompIdx) : ectx.globalDofIdx;
2302 return flowsC.getFlow(index, Dir::XMinus, gasCompIdx);
2306 Entry{ScalarEntry{
"BFLOGJ",
2308 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2310 const unsigned index = !flowsC.blockFlows().empty() ?
2311 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2312 FaceDir::ToIntersectionIndex(Dir::YPlus), gasCompIdx) : ectx.globalDofIdx;
2313 return flowsC.getFlow(index, Dir::YPlus, gasCompIdx);
2317 Entry{ScalarEntry{
"BFLOGJ-",
2319 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2321 const unsigned index = !flowsC.blockFlows().empty() ?
2322 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2323 FaceDir::ToIntersectionIndex(Dir::YMinus), gasCompIdx) : ectx.globalDofIdx;
2324 return flowsC.getFlow(index, Dir::YMinus, gasCompIdx);
2328 Entry{ScalarEntry{
"BFLOGK",
2330 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2332 const unsigned index = !flowsC.blockFlows().empty() ?
2333 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2334 FaceDir::ToIntersectionIndex(Dir::ZPlus), gasCompIdx) : ectx.globalDofIdx;
2335 return flowsC.getFlow(index, Dir::ZPlus, gasCompIdx);
2339 Entry{ScalarEntry{
"BFLOGK-",
2341 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2343 const unsigned index = !flowsC.blockFlows().empty() ?
2344 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2345 FaceDir::ToIntersectionIndex(Dir::ZMinus), gasCompIdx) : ectx.globalDofIdx;
2346 return flowsC.getFlow(index, Dir::ZMinus, gasCompIdx);
2350 Entry{ScalarEntry{
"BFLOOI",
2352 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2354 const unsigned index = !flowsC.blockFlows().empty() ?
2355 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2356 FaceDir::ToIntersectionIndex(Dir::XPlus), oilCompIdx) : ectx.globalDofIdx;
2357 return flowsC.getFlow(index, Dir::XPlus, oilCompIdx);
2361 Entry{ScalarEntry{
"BFLOOI-",
2363 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2365 const unsigned index = !flowsC.blockFlows().empty() ?
2366 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2367 FaceDir::ToIntersectionIndex(Dir::XMinus), oilCompIdx) : ectx.globalDofIdx;
2368 return flowsC.getFlow(index, Dir::XMinus, oilCompIdx);
2372 Entry{ScalarEntry{
"BFLOOJ",
2374 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2376 const unsigned index = !flowsC.blockFlows().empty() ?
2377 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2378 FaceDir::ToIntersectionIndex(Dir::YPlus), oilCompIdx) : ectx.globalDofIdx;
2379 return flowsC.getFlow(index, Dir::YPlus, oilCompIdx);
2383 Entry{ScalarEntry{
"BFLOOJ-",
2385 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2387 const unsigned index = !flowsC.blockFlows().empty() ?
2388 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2389 FaceDir::ToIntersectionIndex(Dir::YMinus), oilCompIdx) : ectx.globalDofIdx;
2390 return flowsC.getFlow(index, Dir::YMinus, oilCompIdx);
2394 Entry{ScalarEntry{
"BFLOOK",
2396 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2398 const unsigned index = !flowsC.blockFlows().empty() ?
2399 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2400 FaceDir::ToIntersectionIndex(Dir::ZPlus), oilCompIdx) : ectx.globalDofIdx;
2401 return flowsC.getFlow(index, Dir::ZPlus, oilCompIdx);
2405 Entry{ScalarEntry{
"BFLOOK-",
2407 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2409 const unsigned index = !flowsC.blockFlows().empty() ?
2410 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2411 FaceDir::ToIntersectionIndex(Dir::ZMinus), oilCompIdx) : ectx.globalDofIdx;
2412 return flowsC.getFlow(index, Dir::ZMinus, oilCompIdx);
2416 Entry{ScalarEntry{
"BFLOWI",
2418 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2420 const unsigned index = !flowsC.blockFlows().empty() ?
2421 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2422 FaceDir::ToIntersectionIndex(Dir::XPlus), waterCompIdx) : ectx.globalDofIdx;
2423 return flowsC.getFlow(index, Dir::XPlus, waterCompIdx);
2427 Entry{ScalarEntry{
"BFLOWI-",
2429 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2431 const unsigned index = !flowsC.blockFlows().empty() ?
2432 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2433 FaceDir::ToIntersectionIndex(Dir::XMinus), waterCompIdx) : ectx.globalDofIdx;
2434 return flowsC.getFlow(index, Dir::XMinus, waterCompIdx);
2438 Entry{ScalarEntry{
"BFLOWJ",
2440 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2442 const unsigned index = !flowsC.blockFlows().empty() ?
2443 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2444 FaceDir::ToIntersectionIndex(Dir::YPlus), waterCompIdx) : ectx.globalDofIdx;
2445 return flowsC.getFlow(index, Dir::YPlus, waterCompIdx);
2449 Entry{ScalarEntry{
"BFLOWJ-",
2451 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2453 const unsigned index = !flowsC.blockFlows().empty() ?
2454 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2455 FaceDir::ToIntersectionIndex(Dir::YMinus), waterCompIdx) : ectx.globalDofIdx;
2456 return flowsC.getFlow(index, Dir::YMinus, waterCompIdx);
2460 Entry{ScalarEntry{
"BFLOWK",
2462 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2464 const unsigned index = !flowsC.blockFlows().empty() ?
2465 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2466 FaceDir::ToIntersectionIndex(Dir::ZPlus), waterCompIdx) : ectx.globalDofIdx;
2467 return flowsC.getFlow(index, Dir::ZPlus, waterCompIdx);
2471 Entry{ScalarEntry{
"BFLOWK-",
2473 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2475 const unsigned index = !flowsC.blockFlows().empty() ?
2476 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2477 FaceDir::ToIntersectionIndex(Dir::ZMinus), waterCompIdx) : ectx.globalDofIdx;
2478 return flowsC.getFlow(index, Dir::ZMinus, waterCompIdx);
2482 Entry{ScalarEntry{
"BVELGI",
2484 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2486 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2487 FaceDir::ToIntersectionIndex(Dir::XPlus), gasCompIdx);
2488 return flowsC.getVelocity(index, Dir::XPlus, gasCompIdx);
2492 Entry{ScalarEntry{
"BVELGI-",
2494 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2496 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2497 FaceDir::ToIntersectionIndex(Dir::XMinus), gasCompIdx);
2498 return flowsC.getVelocity(index, Dir::XMinus, gasCompIdx);
2502 Entry{ScalarEntry{
"BVELGJ",
2504 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2506 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2507 FaceDir::ToIntersectionIndex(Dir::YPlus), gasCompIdx);
2508 return flowsC.getVelocity(index, Dir::YPlus, gasCompIdx);
2512 Entry{ScalarEntry{
"BVELGJ-",
2514 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2516 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2517 FaceDir::ToIntersectionIndex(Dir::YMinus), gasCompIdx);
2518 return flowsC.getVelocity(index, Dir::YMinus, gasCompIdx);
2522 Entry{ScalarEntry{
"BVELGK",
2524 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2526 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2527 FaceDir::ToIntersectionIndex(Dir::ZPlus), gasCompIdx);
2528 return flowsC.getVelocity(index, Dir::ZPlus, gasCompIdx);
2532 Entry{ScalarEntry{
"BVELGK-",
2534 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2536 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2537 FaceDir::ToIntersectionIndex(Dir::ZMinus), gasCompIdx);
2538 return flowsC.getVelocity(index, Dir::ZMinus, gasCompIdx);
2542 Entry{ScalarEntry{
"BVELOI",
2544 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2546 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2547 FaceDir::ToIntersectionIndex(Dir::XPlus), oilCompIdx);
2548 return flowsC.getVelocity(index, Dir::XPlus, oilCompIdx);
2552 Entry{ScalarEntry{
"BVELOI-",
2554 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2556 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2557 FaceDir::ToIntersectionIndex(Dir::XMinus), oilCompIdx);
2558 return flowsC.getVelocity(index, Dir::XMinus, oilCompIdx);
2562 Entry{ScalarEntry{
"BVELOJ",
2564 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2566 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2567 FaceDir::ToIntersectionIndex(Dir::YPlus), oilCompIdx);
2568 return flowsC.getVelocity(index, Dir::YPlus, oilCompIdx);
2572 Entry{ScalarEntry{
"BVELOJ-",
2574 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2576 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2577 FaceDir::ToIntersectionIndex(Dir::YMinus), oilCompIdx);
2578 return flowsC.getVelocity(index, Dir::YMinus, oilCompIdx);
2582 Entry{ScalarEntry{
"BVELOK",
2584 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2586 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2587 FaceDir::ToIntersectionIndex(Dir::ZPlus), oilCompIdx);
2588 return flowsC.getVelocity(index, Dir::ZPlus, oilCompIdx);
2592 Entry{ScalarEntry{
"BVELOK-",
2594 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2596 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2597 FaceDir::ToIntersectionIndex(Dir::ZMinus), oilCompIdx);
2598 return flowsC.getVelocity(index, Dir::ZMinus, oilCompIdx);
2602 Entry{ScalarEntry{
"BVELWI",
2604 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2606 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2607 FaceDir::ToIntersectionIndex(Dir::XPlus), waterCompIdx);
2608 return flowsC.getVelocity(index, Dir::XPlus, waterCompIdx);
2612 Entry{ScalarEntry{
"BVELWI-",
2614 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2616 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2617 FaceDir::ToIntersectionIndex(Dir::XMinus), waterCompIdx);
2618 return flowsC.getVelocity(index, Dir::XMinus, waterCompIdx);
2622 Entry{ScalarEntry{
"BVELWJ",
2624 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2626 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2627 FaceDir::ToIntersectionIndex(Dir::YPlus), waterCompIdx);
2628 return flowsC.getVelocity(index, Dir::YPlus, waterCompIdx);
2632 Entry{ScalarEntry{
"BVELWJ-",
2634 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2636 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2637 FaceDir::ToIntersectionIndex(Dir::YMinus), waterCompIdx);
2638 return flowsC.getVelocity(index, Dir::YMinus, waterCompIdx);
2642 Entry{ScalarEntry{
"BVELWK",
2644 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2646 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2647 FaceDir::ToIntersectionIndex(Dir::ZPlus), waterCompIdx);
2648 return flowsC.getVelocity(index, Dir::ZPlus, waterCompIdx);
2652 Entry{ScalarEntry{
"BVELWK-",
2654 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2656 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2657 FaceDir::ToIntersectionIndex(Dir::ZMinus), waterCompIdx);
2658 return flowsC.getVelocity(index, Dir::ZMinus, waterCompIdx);
2662 Entry{ScalarEntry{
"BRPV",
2663 [&model = this->simulator_.model()](
const Context& ectx)
2665 return getValue(ectx.intQuants.porosity()) *
2666 model.dofTotalVolume(ectx.globalDofIdx);
2670 Entry{PhaseEntry{std::array{
"BWPV"sv,
"BOPV"sv,
"BGPV"sv},
2671 [&model = this->simulator_.model()](
const unsigned phaseIdx,
2672 const Context& ectx)
2674 return getValue(ectx.fs.saturation(phaseIdx)) *
2675 getValue(ectx.intQuants.porosity()) *
2676 model.dofTotalVolume(ectx.globalDofIdx);
2680 Entry{ScalarEntry{
"BRS",
2681 [](
const Context& ectx)
2683 return getValue(ectx.fs.Rs());
2687 Entry{ScalarEntry{
"BRV",
2688 [](
const Context& ectx)
2690 return getValue(ectx.fs.Rv());
2694 Entry{ScalarEntry{
"BOIP",
2695 [&model = this->simulator_.model()](
const Context& ectx)
2697 return (getValue(ectx.fs.invB(oilPhaseIdx)) *
2698 getValue(ectx.fs.saturation(oilPhaseIdx)) +
2699 getValue(ectx.fs.Rv()) *
2700 getValue(ectx.fs.invB(gasPhaseIdx)) *
2701 getValue(ectx.fs.saturation(gasPhaseIdx))) *
2702 model.dofTotalVolume(ectx.globalDofIdx) *
2703 getValue(ectx.intQuants.porosity());
2707 Entry{ScalarEntry{
"BGIP",
2708 [&model = this->simulator_.model()](
const Context& ectx)
2710 Scalar result = getValue(ectx.fs.invB(gasPhaseIdx)) *
2711 getValue(ectx.fs.saturation(gasPhaseIdx));
2713 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2714 result += getValue(ectx.fs.Rs()) *
2715 getValue(ectx.fs.invB(oilPhaseIdx)) *
2716 getValue(ectx.fs.saturation(oilPhaseIdx));
2719 result += getValue(ectx.fs.Rsw()) *
2720 getValue(ectx.fs.invB(waterPhaseIdx)) *
2721 getValue(ectx.fs.saturation(waterPhaseIdx));
2725 model.dofTotalVolume(ectx.globalDofIdx) *
2726 getValue(ectx.intQuants.porosity());
2730 Entry{ScalarEntry{
"BWIP",
2731 [&model = this->simulator_.model()](
const Context& ectx)
2733 return getValue(ectx.fs.invB(waterPhaseIdx)) *
2734 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2735 model.dofTotalVolume(ectx.globalDofIdx) *
2736 getValue(ectx.intQuants.porosity());
2740 Entry{ScalarEntry{
"BOIPL",
2741 [&model = this->simulator_.model()](
const Context& ectx)
2743 return getValue(ectx.fs.invB(oilPhaseIdx)) *
2744 getValue(ectx.fs.saturation(oilPhaseIdx)) *
2745 model.dofTotalVolume(ectx.globalDofIdx) *
2746 getValue(ectx.intQuants.porosity());
2750 Entry{ScalarEntry{
"BGIPL",
2751 [&model = this->simulator_.model()](
const Context& ectx)
2754 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2755 result = getValue(ectx.fs.Rs()) *
2756 getValue(ectx.fs.invB(oilPhaseIdx)) *
2757 getValue(ectx.fs.saturation(oilPhaseIdx));
2760 result = getValue(ectx.fs.Rsw()) *
2761 getValue(ectx.fs.invB(waterPhaseIdx)) *
2762 getValue(ectx.fs.saturation(waterPhaseIdx));
2765 model.dofTotalVolume(ectx.globalDofIdx) *
2766 getValue(ectx.intQuants.porosity());
2770 Entry{ScalarEntry{
"BGIPG",
2771 [&model = this->simulator_.model()](
const Context& ectx)
2773 return getValue(ectx.fs.invB(gasPhaseIdx)) *
2774 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2775 model.dofTotalVolume(ectx.globalDofIdx) *
2776 getValue(ectx.intQuants.porosity());
2780 Entry{ScalarEntry{
"BOIPG",
2781 [&model = this->simulator_.model()](
const Context& ectx)
2783 return getValue(ectx.fs.Rv()) *
2784 getValue(ectx.fs.invB(gasPhaseIdx)) *
2785 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2786 model.dofTotalVolume(ectx.globalDofIdx) *
2787 getValue(ectx.intQuants.porosity());
2791 Entry{PhaseEntry{std::array{
"BPPW"sv,
"BPPO"sv,
"BPPG"sv},
2792 [&simConfig = this->
eclState_.getSimulationConfig(),
2793 &grav = this->simulator_.problem().gravity(),
2795 &problem = this->simulator_.problem(),
2796 ®ions = this->
regions_](
const unsigned phaseIdx,
const Context& ectx)
2799 phase.ix = phaseIdx;
2808 const auto datum = simConfig.datumDepths()(regions[
"FIPNUM"][ectx.dofIdx] - 1);
2811 const auto region = RegionPhasePoreVolAverage::Region {
2812 ectx.elemCtx.primaryVars(ectx.dofIdx, 0).pvtRegionIndex() + 1
2815 const auto density = regionAvgDensity->value(
"PVTNUM", phase, region);
2817 const auto press = getValue(ectx.fs.pressure(phase.ix));
2818 const auto dz = problem.dofCenterDepth(ectx.globalDofIdx) - datum;
2819 return press - density*dz*grav[GridView::dimensionworld - 1];
2823 Entry{ScalarEntry{
"BAMIP",
2824 [&model = this->simulator_.model()](
const Context& ectx)
2826 const Scalar rhoW = FluidSystem::referenceDensity(waterPhaseIdx,
2827 ectx.intQuants.pvtRegionIndex());
2828 return getValue(ectx.fs.invB(waterPhaseIdx)) *
2829 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2831 model.dofTotalVolume(ectx.globalDofIdx) *
2832 getValue(ectx.intQuants.porosity());
2836 Entry{ScalarEntry{
"BMMIP",
2837 [&model = this->simulator_.model()](
const Context& ectx)
2839 if constexpr (enableBioeffects) {
2840 return getValue(ectx.intQuants.microbialConcentration()) *
2841 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2842 getValue(ectx.intQuants.porosity()) *
2843 model.dofTotalVolume(ectx.globalDofIdx);
2851 Entry{ScalarEntry{
"BMOIP",
2852 [&model = this->simulator_.model()](
const Context& ectx)
2854 if constexpr (enableBioeffects) {
2855 return getValue(ectx.intQuants.oxygenConcentration()) *
2856 getValue(ectx.intQuants.porosity()) *
2857 model.dofTotalVolume(ectx.globalDofIdx);
2865 Entry{ScalarEntry{
"BMUIP",
2866 [&model = this->simulator_.model()](
const Context& ectx)
2868 if constexpr (enableBioeffects) {
2869 return getValue(ectx.intQuants.ureaConcentration()) *
2870 getValue(ectx.intQuants.porosity()) *
2871 model.dofTotalVolume(ectx.globalDofIdx);
2879 Entry{ScalarEntry{
"BMBIP",
2880 [&model = this->simulator_.model()](
const Context& ectx)
2882 if constexpr (enableBioeffects) {
2883 return model.dofTotalVolume(ectx.globalDofIdx) *
2884 getValue(ectx.intQuants.biofilmMass());
2892 Entry{ScalarEntry{
"BMCIP",
2893 [&model = this->simulator_.model()](
const Context& ectx)
2895 if constexpr (enableBioeffects) {
2896 return model.dofTotalVolume(ectx.globalDofIdx) *
2897 getValue(ectx.intQuants.calciteMass());
2905 Entry{ScalarEntry{
"BGMIP",
2906 [&model = this->simulator_.model()](
const Context& ectx)
2908 Scalar result = getValue(ectx.fs.invB(gasPhaseIdx)) *
2909 getValue(ectx.fs.saturation(gasPhaseIdx));
2911 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2912 result += getValue(ectx.fs.Rs()) *
2913 getValue(ectx.fs.invB(oilPhaseIdx)) *
2914 getValue(ectx.fs.saturation(oilPhaseIdx));
2917 result += getValue(ectx.fs.Rsw()) *
2918 getValue(ectx.fs.invB(waterPhaseIdx)) *
2919 getValue(ectx.fs.saturation(waterPhaseIdx));
2921 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2922 ectx.intQuants.pvtRegionIndex());
2924 model.dofTotalVolume(ectx.globalDofIdx) *
2925 getValue(ectx.intQuants.porosity()) *
2930 Entry{ScalarEntry{
"BGMGP",
2931 [&model = this->simulator_.model()](
const Context& ectx)
2933 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2934 ectx.intQuants.pvtRegionIndex());
2935 return getValue(ectx.fs.invB(gasPhaseIdx)) *
2936 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2937 model.dofTotalVolume(ectx.globalDofIdx) *
2938 getValue(ectx.intQuants.porosity()) *
2943 Entry{ScalarEntry{
"BGMDS",
2944 [&model = this->simulator_.model()](
const Context& ectx)
2947 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2948 result = getValue(ectx.fs.Rs()) *
2949 getValue(ectx.fs.invB(oilPhaseIdx)) *
2950 getValue(ectx.fs.saturation(oilPhaseIdx));
2953 result = getValue(ectx.fs.Rsw()) *
2954 getValue(ectx.fs.invB(waterPhaseIdx)) *
2955 getValue(ectx.fs.saturation(waterPhaseIdx));
2957 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2958 ectx.intQuants.pvtRegionIndex());
2960 model.dofTotalVolume(ectx.globalDofIdx) *
2961 getValue(ectx.intQuants.porosity()) *
2966 Entry{ScalarEntry{
"BGMST",
2967 [&model = this->simulator_.model(),
2968 &problem = this->simulator_.problem()](
const Context& ectx)
2970 const auto& scaledDrainageInfo = problem.materialLawManager()
2971 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2972 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2973 Scalar strandedGas = scaledDrainageInfo.Sgcr;
2974 if (problem.materialLawManager()->enableHysteresis()) {
2975 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2976 const Scalar krg = getValue(ectx.intQuants.relativePermeability(gasPhaseIdx));
2977 strandedGas = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
2979 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2980 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2981 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2982 return (1.0 - xgW) *
2983 model.dofTotalVolume(ectx.globalDofIdx) *
2984 getValue(ectx.intQuants.porosity()) *
2985 getValue(ectx.fs.density(gasPhaseIdx)) *
2986 std::min(strandedGas, sg);
2990 Entry{ScalarEntry{
"BGMUS",
2991 [&model = this->simulator_.model(),
2992 &problem = this->simulator_.problem()](
const Context& ectx)
2994 const auto& scaledDrainageInfo = problem.materialLawManager()
2995 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2996 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2997 Scalar strandedGas = scaledDrainageInfo.Sgcr;
2998 if (problem.materialLawManager()->enableHysteresis()) {
2999 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3000 const Scalar krg = getValue(ectx.intQuants.relativePermeability(gasPhaseIdx));
3001 strandedGas = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
3003 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3004 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3005 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3006 return (1.0 - xgW) *
3007 model.dofTotalVolume(ectx.globalDofIdx) *
3008 getValue(ectx.intQuants.porosity()) *
3009 getValue(ectx.fs.density(gasPhaseIdx)) *
3010 std::max(Scalar{0.0}, sg - strandedGas);
3014 Entry{ScalarEntry{
"BGMTR",
3015 [&model = this->simulator_.model(),
3016 &problem = this->simulator_.problem()](
const Context& ectx)
3018 const auto& scaledDrainageInfo = problem.materialLawManager()
3019 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3020 Scalar trappedGas = scaledDrainageInfo.Sgcr;
3021 if (problem.materialLawManager()->enableHysteresis()) {
3022 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3023 trappedGas = MaterialLaw::trappedGasSaturation(matParams,
true);
3025 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3026 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3027 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3028 return (1.0 - xgW) *
3029 model.dofTotalVolume(ectx.globalDofIdx) *
3030 getValue(ectx.intQuants.porosity()) *
3031 getValue(ectx.fs.density(gasPhaseIdx)) *
3032 std::min(trappedGas, getValue(ectx.fs.saturation(gasPhaseIdx)));
3036 Entry{ScalarEntry{
"BGMMO",
3037 [&model = this->simulator_.model(),
3038 &problem = this->simulator_.problem()](
const Context& ectx)
3040 const auto& scaledDrainageInfo = problem.materialLawManager()
3041 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3042 Scalar trappedGas = scaledDrainageInfo.Sgcr;
3043 if (problem.materialLawManager()->enableHysteresis()) {
3044 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3045 trappedGas = MaterialLaw::trappedGasSaturation(matParams,
true);
3047 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3048 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3049 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3050 return (1.0 - xgW) *
3051 model.dofTotalVolume(ectx.globalDofIdx) *
3052 getValue(ectx.intQuants.porosity()) *
3053 getValue(ectx.fs.density(gasPhaseIdx)) *
3054 std::max(Scalar{0.0}, getValue(ectx.fs.saturation(gasPhaseIdx)) - trappedGas);
3058 Entry{ScalarEntry{
"BGKTR",
3059 [&model = this->simulator_.model(),
3060 &problem = this->simulator_.problem()](
const Context& ectx)
3062 const auto& scaledDrainageInfo = problem.materialLawManager()
3063 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3064 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
3065 Scalar sgcr = scaledDrainageInfo.Sgcr;
3066 if (problem.materialLawManager()->enableHysteresis()) {
3067 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3068 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3074 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3075 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3076 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3077 return (1.0 - xgW) *
3078 model.dofTotalVolume(ectx.globalDofIdx) *
3079 getValue(ectx.intQuants.porosity()) *
3080 getValue(ectx.fs.density(gasPhaseIdx)) *
3081 getValue(ectx.fs.saturation(gasPhaseIdx));
3086 Entry{ScalarEntry{
"BGKMO",
3087 [&model = this->simulator_.model(),
3088 &problem = this->simulator_.problem()](
const Context& ectx)
3090 const auto& scaledDrainageInfo = problem.materialLawManager()
3091 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3092 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
3093 Scalar sgcr = scaledDrainageInfo.Sgcr;
3094 if (problem.materialLawManager()->enableHysteresis()) {
3095 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3096 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3102 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3103 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3104 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3105 return (1.0 - xgW) *
3106 model.dofTotalVolume(ectx.globalDofIdx) *
3107 getValue(ectx.intQuants.porosity()) *
3108 getValue(ectx.fs.density(gasPhaseIdx)) *
3109 getValue(ectx.fs.saturation(gasPhaseIdx));
3114 Entry{ScalarEntry{
"BGCDI",
3115 [&model = this->simulator_.model(),
3116 &problem = this->simulator_.problem()](
const Context& ectx)
3118 const auto& scaledDrainageInfo = problem.materialLawManager()
3119 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3120 Scalar sgcr = scaledDrainageInfo.Sgcr;
3121 if (problem.materialLawManager()->enableHysteresis()) {
3122 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3123 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3125 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3126 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3127 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3128 return (1.0 - xgW) *
3129 model.dofTotalVolume(ectx.globalDofIdx) *
3130 getValue(ectx.intQuants.porosity()) *
3131 getValue(ectx.fs.density(gasPhaseIdx)) *
3132 std::min(sgcr, getValue(ectx.fs.saturation(gasPhaseIdx))) /
3133 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
3137 Entry{ScalarEntry{
"BGCDM",
3138 [&model = this->simulator_.model(),
3139 &problem = this->simulator_.problem()](
const Context& ectx)
3141 const auto& scaledDrainageInfo = problem.materialLawManager()
3142 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3143 Scalar sgcr = scaledDrainageInfo.Sgcr;
3144 if (problem.materialLawManager()->enableHysteresis()) {
3145 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3146 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3148 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3149 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3150 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3151 return (1.0 - xgW) *
3152 model.dofTotalVolume(ectx.globalDofIdx) *
3153 getValue(ectx.intQuants.porosity()) *
3154 getValue(ectx.fs.density(gasPhaseIdx)) *
3155 std::max(Scalar{0.0}, getValue(ectx.fs.saturation(gasPhaseIdx)) - sgcr) /
3156 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
3160 Entry{ScalarEntry{
"BGKDI",
3161 [&model = this->simulator_.model(),
3162 &problem = this->simulator_.problem()](
const Context& ectx)
3164 const auto& scaledDrainageInfo = problem.materialLawManager()
3165 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3166 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
3167 Scalar sgcr = scaledDrainageInfo.Sgcr;
3168 if (problem.materialLawManager()->enableHysteresis()) {
3169 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3170 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3176 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3177 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3178 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3179 return (1.0 - xgW) *
3180 model.dofTotalVolume(ectx.globalDofIdx) *
3181 getValue(ectx.intQuants.porosity()) *
3182 getValue(ectx.fs.density(gasPhaseIdx)) *
3183 getValue(ectx.fs.saturation(gasPhaseIdx)) /
3184 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
3189 Entry{ScalarEntry{
"BGKDM",
3190 [&model = this->simulator_.model(),
3191 &problem = this->simulator_.problem()](
const Context& ectx)
3193 const auto& scaledDrainageInfo = problem.materialLawManager()
3194 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3195 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
3196 Scalar sgcr = scaledDrainageInfo.Sgcr;
3197 if (problem.materialLawManager()->enableHysteresis()) {
3198 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3199 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3205 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3206 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3207 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3208 return (1.0 - xgW) *
3209 model.dofTotalVolume(ectx.globalDofIdx) *
3210 getValue(ectx.intQuants.porosity()) *
3211 getValue(ectx.fs.density(gasPhaseIdx)) *
3212 getValue(ectx.fs.saturation(gasPhaseIdx)) /
3213 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
3218 Entry{ScalarEntry{
"BWCD",
3219 [&model = this->simulator_.model()](
const Context& ectx)
3222 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
3223 result = getValue(ectx.fs.Rs()) *
3224 getValue(ectx.fs.invB(oilPhaseIdx)) *
3225 getValue(ectx.fs.saturation(oilPhaseIdx));
3228 result = getValue(ectx.fs.Rsw()) *
3229 getValue(ectx.fs.invB(waterPhaseIdx)) *
3230 getValue(ectx.fs.saturation(waterPhaseIdx));
3232 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
3233 ectx.intQuants.pvtRegionIndex());
3235 model.dofTotalVolume(ectx.globalDofIdx) *
3236 getValue(ectx.intQuants.porosity()) *
3238 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
3242 Entry{ScalarEntry{
"BWIPG",
3243 [&model = this->simulator_.model()](
const Context& ectx)
3245 Scalar result = 0.0;
3246 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
3247 result = getValue(ectx.fs.Rvw()) *
3248 getValue(ectx.fs.invB(gasPhaseIdx)) *
3249 getValue(ectx.fs.saturation(gasPhaseIdx));
3252 model.dofTotalVolume(ectx.globalDofIdx) *
3253 getValue(ectx.intQuants.porosity());
3257 Entry{ScalarEntry{
"BWIPL",
3258 [&model = this->simulator_.model()](
const Context& ectx)
3260 return getValue(ectx.fs.invB(waterPhaseIdx)) *
3261 getValue(ectx.fs.saturation(waterPhaseIdx)) *
3262 model.dofTotalVolume(ectx.globalDofIdx) *
3263 getValue(ectx.intQuants.porosity());
3269 auto blockHandlers = std::span<const Entry>{handlers};
3270 auto mechHandlers = std::vector<Entry>{};
3271 if constexpr (getPropValue<TypeTag, Properties::EnableMech>()) {
3272 if (this->
mech_.allocated()) {
3273 mechHandlers.assign(handlers.begin(), handlers.end());
3274 mechHandlers.push_back(
3275 Entry{TensorEntry{
"BSTRSS",
3276 [&model = this->simulator_.problem().geoMechModel()]
3277 (
const VoigtIndex index,
const Context& ectx)
3279 return model.stress(ectx.globalDofIdx,
true)[index];
3283 blockHandlers = mechHandlers;
3292 this->lgrBlockExtractors_ =
3296 if (reportStepNum > 0 && !isSubStep) {
3298 const auto& rpt = this->
schedule_[reportStepNum - 1].rpt_config.get();
3299 if (rpt.contains(
"WELLS") && rpt.at(
"WELLS") > 1) {
3301 [&c = this->collectOnIORank_](
const int idx)
3302 {
return c.isCartIdxOnThisRank(idx); });
3304 const auto extraHandlers = std::array{
3313 const Simulator& simulator_;
3314 const CollectDataOnIORankType& collectOnIORank_;
3315 std::vector<typename Extractor::Entry> extractors_;
Common output functionality shared by simulator formulations.
Declares the properties required by the black oil model.
Definition: CollectDataOnIORank.hpp:57
The base class for the element-centered finite-volume discretization scheme.
Definition: ecfvdiscretization.hh:160
void assignMicrobialMass(const unsigned globalDofIdx, const Scalar microbialMass)
void assignCalciteMass(const unsigned globalDofIdx, const Scalar calciteMass)
void assignCo2InWater(const unsigned globalDofIdx, const Scalar co2InWater, const Scalar mM)
void assignVolumesSurface(const unsigned globalDofIdx, const std::array< Scalar, numPhases > &fip)
bool has(const Inplace::Phase phase) const
bool hasMicrobialMass() const
void assignWaterMass(const unsigned globalDofIdx, const std::array< Scalar, numPhases > &fip, const Scalar rhoW)
void assignCo2InGas(const unsigned globalDofIdx, const Co2InGasInput &v)
bool hasOxygenMass() const
void assignVolumesReservoir(const unsigned globalDofIdx, const Scalar saltConcentration, const std::array< Scalar, numPhases > &fipr)
void assignOxygenMass(const unsigned globalDofIdx, const Scalar oxygenMass)
void assignOilGasDistribution(const unsigned globalDofIdx, const Scalar gasInPlaceLiquid, const Scalar oilInPlaceGas)
void assignBiofilmMass(const unsigned globalDofIdx, const Scalar biofilmMass)
bool hasWaterMass() const
bool hasCo2InWater() const
void assignUreaMass(const unsigned globalDofIdx, const Scalar ureaMass)
bool hasCalciteMass() const
bool hasBiofilmMass() const
void assignGasWater(const unsigned globalDofIdx, const std::array< Scalar, numPhases > &fip, const Scalar gasInPlaceWater, const Scalar waterInPlaceGas)
const std::vector< int > blockVelocity() const
Definition: FlowsContainer.hpp:103
Definition: GenericOutputModule.hpp:91
const Schedule & schedule_
Definition: GenericOutputModule.hpp:536
ScalarBuffer oilVaporizationFactor_
Definition: GenericOutputModule.hpp:613
bool forceDisableFipOutput_
Definition: GenericOutputModule.hpp:557
RFTContainer< GetPropType< TypeTag, Properties::FluidSystem > > rftC_
Definition: GenericOutputModule.hpp:642
ScalarBuffer saturatedOilFormationVolumeFactor_
Definition: GenericOutputModule.hpp:618
GeochemistryContainer< Scalar > geochemC_
Definition: GenericOutputModule.hpp:634
ScalarBuffer rockCompPorvMultiplier_
Definition: GenericOutputModule.hpp:616
TracerContainer< GetPropType< TypeTag, Properties::FluidSystem > > tracerC_
Definition: GenericOutputModule.hpp:636
void doAllocBuffers(unsigned bufferSize, unsigned reportStepNum, const bool substep, const bool log, const bool forceRestartFieldAllocation, const EclHysteresisConfig *hysteresisConfig, unsigned numOutputNnc=0, std::map< std::string, int > rstKeywords={})
CO2H2Container< Scalar > CO2H2C_
Definition: GenericOutputModule.hpp:621
std::array< ScalarBuffer, numPhases > residual_
Definition: GenericOutputModule.hpp:638
ScalarBuffer sSol_
Definition: GenericOutputModule.hpp:597
std::map< std::tuple< std::string, int, int >, double > lgrBlockData_
Definition: GenericOutputModule.hpp:655
void setupExtraBlockData(const std::size_t reportStepNum, std::function< bool(int)> isCartIdxOnThisRank)
std::vector< int > failedCellsPd_
Definition: GenericOutputModule.hpp:583
ScalarBuffer shmax_
Definition: GenericOutputModule.hpp:608
ScalarBuffer sgmax_
Definition: GenericOutputModule.hpp:607
ScalarBuffer rockCompTransMultiplier_
Definition: GenericOutputModule.hpp:619
void setupBlockData(std::function< bool(int)> isCartIdxOnThisRank)
ScalarBuffer minimumOilPressure_
Definition: GenericOutputModule.hpp:617
ScalarBuffer temperature_
Definition: GenericOutputModule.hpp:591
ScalarBuffer pcow_
Definition: GenericOutputModule.hpp:623
ScalarBuffer drsdtcon_
Definition: GenericOutputModule.hpp:596
bool computeFip_
Definition: GenericOutputModule.hpp:559
std::optional< RegionPhasePoreVolAverage > regionAvgDensity_
Definition: GenericOutputModule.hpp:660
ScalarBuffer permFact_
Definition: GenericOutputModule.hpp:603
ScalarBuffer overburdenPressure_
Definition: GenericOutputModule.hpp:594
TpsaContainer< Scalar > tpsaC_
Definition: GenericOutputModule.hpp:628
ScalarBuffer rPorV_
Definition: GenericOutputModule.hpp:589
std::array< ScalarBuffer, numPhases > viscosity_
Definition: GenericOutputModule.hpp:632
void setupLgrBlockData(const std::map< std::string, int > &lgrNameToLevel, const std::function< bool(int, int)> &isLgrCellOnThisRank)
ScalarBuffer rvw_
Definition: GenericOutputModule.hpp:593
FIPContainer< GetPropType< TypeTag, Properties::FluidSystem > > fipC_
Definition: GenericOutputModule.hpp:570
ScalarBuffer cPolymer_
Definition: GenericOutputModule.hpp:599
void assignBuffer(data::Solution &sol, std::string_view name, UnitSystem::measure measure, std::vector< Scalar > &buffer)
static bool allocBufferIfRequested(std::map< std::string, int > &rstKeywords, unsigned bufferSize, std::vector< Scalar > &buffer, std::string_view kw, bool supported, bool required=false)
std::unordered_map< std::string, std::vector< int > > regions_
Definition: GenericOutputModule.hpp:571
ScalarBuffer swmin_
Definition: GenericOutputModule.hpp:610
FlowsContainer< GetPropType< TypeTag, Properties::FluidSystem > > flowsC_
Definition: GenericOutputModule.hpp:640
std::map< std::pair< std::string, int >, double > blockData_
Definition: GenericOutputModule.hpp:645
ScalarBuffer gasDissolutionFactor_
Definition: GenericOutputModule.hpp:612
MechContainer< Scalar > mech_
Definition: GenericOutputModule.hpp:627
BioeffectsContainer< Scalar > bioeffectsC_
Definition: GenericOutputModule.hpp:620
ExtboContainer< Scalar > extboC_
Definition: GenericOutputModule.hpp:604
ScalarBuffer gasDissolutionFactorInWater_
Definition: GenericOutputModule.hpp:614
ScalarBuffer pcgw_
Definition: GenericOutputModule.hpp:622
LogOutputHelper< Scalar > logOutput_
Definition: GenericOutputModule.hpp:542
void assignPhaseProperties(data::Solution &sol, const PhasePropertyNames &names)
Move the phase density and viscosity buffers to sol under names.
std::vector< Scalar > ScalarBuffer
Definition: GenericOutputModule.hpp:325
ScalarBuffer somin_
Definition: GenericOutputModule.hpp:609
void updateTotalVolumesAndPressures_(const unsigned globalDofIdx, const IntensiveQuantities &intQuants, const double totVolume, const Scalar referencePorosity)
Definition: GenericOutputModule.hpp:362
InterRegFlowMap interRegionFlows_
Definition: GenericOutputModule.hpp:541
ScalarBuffer soMax_
Definition: GenericOutputModule.hpp:605
std::array< ScalarBuffer, numPhases > density_
Definition: GenericOutputModule.hpp:631
ScalarBuffer cFoam_
Definition: GenericOutputModule.hpp:600
ScalarBuffer waterVaporizationFactor_
Definition: GenericOutputModule.hpp:615
std::array< ScalarBuffer, numPhases > saturation_
Definition: GenericOutputModule.hpp:630
ScalarBuffer rsw_
Definition: GenericOutputModule.hpp:592
ScalarBuffer oilSaturationPressure_
Definition: GenericOutputModule.hpp:595
const EclipseState & eclState_
Definition: GenericOutputModule.hpp:535
ScalarBuffer ppcw_
Definition: GenericOutputModule.hpp:611
virtual void assignToSolution(data::Solution &sol)
Move all buffers to data::Solution.
ScalarBuffer cSalt_
Definition: GenericOutputModule.hpp:601
ScalarBuffer pcog_
Definition: GenericOutputModule.hpp:624
const Inplace * initialInplace() const
Definition: GenericOutputModule.hpp:274
ScalarBuffer swMax_
Definition: GenericOutputModule.hpp:606
ScalarBuffer rswSol_
Definition: GenericOutputModule.hpp:598
std::map< std::pair< std::string, int >, double > extraBlockData_
Definition: GenericOutputModule.hpp:648
ScalarBuffer fluidPressure_
Definition: GenericOutputModule.hpp:590
ScalarBuffer gasFormationVolumeFactor_
Definition: GenericOutputModule.hpp:585
virtual void setRestart(const data::Solution &sol, unsigned elemIdx, unsigned globalDofIndex)
std::vector< int > failedCellsPb_
Definition: GenericOutputModule.hpp:582
ScalarBuffer pSalt_
Definition: GenericOutputModule.hpp:602
Inter-region flow accumulation maps for all region definition arrays.
Definition: InterRegFlows.hpp:179
void addConnection(const Cell &source, const Cell &destination, const data::InterRegFlowMap::FlowRates &rates)
void clear()
Clear all internal buffers, but preserve allocated capacity.
Output module for the results black oil model writing in ECL binary format.
Definition: OutputBlackoilModule.hpp:101
void processElement(const ElementContext &elemCtx)
Modify the internal buffers according to the intensive quanties relevant for an element.
Definition: OutputBlackoilModule.hpp:353
void initializeFluxData()
Prepare for capturing connection fluxes, particularly to account for inter-region flows.
Definition: OutputBlackoilModule.hpp:642
void setupExtractors(const bool isSubStep, const int reportStepNum)
Setup list of active element-level data extractors.
Definition: OutputBlackoilModule.hpp:291
void processFluxes(const ElementContext &elemCtx, ActiveIndex &&activeIndex, CartesianIndex &&cartesianIndex)
Capture connection fluxes, particularly to account for inter-region flows.
Definition: OutputBlackoilModule.hpp:605
void setRestart(const data::Solution &sol, const unsigned elemIdx, const unsigned globalDofIndex) override
Restore the buffers this module owns from a restart file.
Definition: OutputBlackoilModule.hpp:798
void clearExtractors()
Clear list of active element-level data extractors.
Definition: OutputBlackoilModule.hpp:299
void allocBuffers(const unsigned bufferSize, const unsigned reportStepNum, const bool substep, const bool log, const bool forceRestartFieldAllocation)
Allocate memory for the scalar fields we would like to write to ECL output files.
Definition: OutputBlackoilModule.hpp:269
void outputFipAndResvLogToCSV(const std::size_t reportStepNum, const bool substep, const Parallel::Communication &comm)
Definition: OutputBlackoilModule.hpp:539
void allocFormulationBuffers(std::map< std::string, int > &rstKeywords, const unsigned bufferSize) override
Allocate the buffers of the quantities only the black-oil formulation produces, keyed on their restar...
Definition: OutputBlackoilModule.hpp:819
void assignToFluidState(FluidState &fs, unsigned elemIdx) const
Definition: OutputBlackoilModule.hpp:666
void assignToSolution(data::Solution &sol) override
Move all buffers to data::Solution.
Definition: OutputBlackoilModule.hpp:310
void initHysteresisParams(Simulator &simulator, unsigned elemIdx) const
Definition: OutputBlackoilModule.hpp:718
void updateFluidInPlace(const ElementContext &elemCtx)
Definition: OutputBlackoilModule.hpp:783
OutputBlackOilModule(const Simulator &simulator, const SummaryConfig &smryCfg, const CollectDataOnIORankType &collectOnIORank)
Definition: OutputBlackoilModule.hpp:154
void outputFipAndResvLog(const Inplace &inplace, const std::size_t reportStepNum, double elapsed, boost::posix_time::ptime currentDate, const bool substep, const Parallel::Communication &comm)
Definition: OutputBlackoilModule.hpp:488
const InterRegFlowMap & getInterRegFlows() const
Get read-only access to collection of inter-region flows.
Definition: OutputBlackoilModule.hpp:660
void processElementBlockData(const ElementContext &elemCtx)
Definition: OutputBlackoilModule.hpp:400
void finalizeFluxData()
Finalize capturing connection fluxes.
Definition: OutputBlackoilModule.hpp:652
void updateFluidInPlace(const unsigned globalDofIdx, const IntensiveQuantities &intQuants, const double totVolume)
Definition: OutputBlackoilModule.hpp:790
Declare the properties used by the infrastructure code of the finite volume discretizations.
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
Phase
Phase indices for reservoir coupling, we currently only support black-oil phases (oil,...
Definition: ReservoirCoupling.hpp:183
constexpr void ignoreUnused(T &&...) noexcept
Utility to silence "unused variable" warnings in lambdas.
Definition: OutputBlackoilModule.hpp:90
Definition: blackoilbioeffectsmodules.hh:45
std::string moduleVersionName()
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
This file provides the infrastructure to retrieve run-time parameters.
The Opm property system, traits with inheritance.
Definition: GenericOutputModule.hpp:410
std::string_view oilDensity
Definition: GenericOutputModule.hpp:411
Minimal characteristics of a cell from a simulation grid.
Definition: InterRegFlows.hpp:50