27#ifndef OPM_OUTPUT_BLACK_OIL_MODULE_HPP
28#define OPM_OUTPUT_BLACK_OIL_MODULE_HPP
30#include <dune/common/fvector.hh>
34#include <opm/common/Exceptions.hpp>
35#include <opm/common/TimingMacros.hpp>
36#include <opm/common/OpmLog/OpmLog.hpp>
37#include <opm/common/utility/Visitor.hpp>
39#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
41#include <opm/material/common/Valgrind.hpp>
42#include <opm/material/fluidmatrixinteractions/EclEpsScalingPoints.hpp>
43#include <opm/material/fluidstates/BlackOilFluidState.hpp>
44#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
52#include <opm/output/data/Cells.hpp>
53#include <opm/output/eclipse/EclipseIO.hpp>
54#include <opm/output/eclipse/Inplace.hpp>
75template <
class TypeTag>
76class EcfvDiscretization;
84template <
class TypeTag>
96 using FluidState =
typename IntensiveQuantities::FluidState;
98 using Element =
typename GridView::template Codim<0>::Entity;
99 using ElementIterator =
typename GridView::template Codim<0>::Iterator;
102 using Dir = FaceDir::DirEnum;
109 static constexpr int conti0EqIdx = Indices::conti0EqIdx;
110 static constexpr int numPhases = FluidSystem::numPhases;
111 static constexpr int oilPhaseIdx = FluidSystem::oilPhaseIdx;
112 static constexpr int gasPhaseIdx = FluidSystem::gasPhaseIdx;
113 static constexpr int waterPhaseIdx = FluidSystem::waterPhaseIdx;
114 static constexpr int gasCompIdx = FluidSystem::gasCompIdx;
115 static constexpr int oilCompIdx = FluidSystem::oilCompIdx;
116 static constexpr int waterCompIdx = FluidSystem::waterCompIdx;
117 static constexpr EnergyModules energyModuleType = getPropValue<TypeTag, Properties::EnergyModuleType>();
118 enum { enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>() };
119 enum { enableMICP = Indices::enableMICP };
120 enum { enableVapwat = getPropValue<TypeTag, Properties::EnableVapwat>() };
121 enum { enableDisgasInWater = getPropValue<TypeTag, Properties::EnableDisgasInWater>() };
122 enum { enableDissolvedGas = Indices::compositionSwitchIdx >= 0 };
124 template<
class VectorType>
125 static Scalar value_or_zero(
int idx,
const VectorType& v)
130 return v.empty() ? 0.0 : v[idx];
135 const SummaryConfig& smryCfg,
137 :
BaseType(simulator.vanguard().eclState(),
138 simulator.vanguard().schedule(),
140 simulator.vanguard().summaryState(),
142 [this](const int idx)
143 {
return simulator_.problem().eclWriter().collectOnIORank().localIdxToGlobalIdx(idx); },
144 [&collectOnIORank](
const int idx)
145 {
return collectOnIORank.isCartIdxOnThisRank(idx); },
146 simulator.vanguard().grid().comm(),
147 energyModuleType == EnergyModules::FullyImplicitThermal ||
148 energyModuleType == EnergyModules::SequentialImplicitThermal,
149 energyModuleType == EnergyModules::ConstantTemperature,
150 getPropValue<TypeTag, Properties::EnableMech>(),
151 getPropValue<TypeTag, Properties::EnableSolvent>(),
152 getPropValue<TypeTag, Properties::EnablePolymer>(),
153 getPropValue<TypeTag, Properties::EnableFoam>(),
154 getPropValue<TypeTag, Properties::EnableBrine>(),
155 getPropValue<TypeTag, Properties::EnableSaltPrecipitation>(),
156 getPropValue<TypeTag, Properties::EnableExtbo>(),
157 getPropValue<TypeTag, Properties::EnableBioeffects>())
158 , simulator_(simulator)
159 , collectOnIORank_(collectOnIORank)
161 for (
auto& region_pair : this->
regions_) {
162 this->createLocalRegion_(region_pair.second);
165 auto isCartIdxOnThisRank = [&collectOnIORank](
const int idx) {
166 return collectOnIORank.isCartIdxOnThisRank(idx);
171 if (! Parameters::Get<Parameters::OwnerCellsFirst>()) {
172 const std::string msg =
"The output code does not support --owner-cells-first=false.";
173 if (collectOnIORank.isIORank()) {
176 OPM_THROW_NOLOG(std::runtime_error, msg);
179 if (smryCfg.match(
"[FB]PP[OGW]") || smryCfg.match(
"RPP[OGW]*")) {
180 auto rset = this->
eclState_.fieldProps().fip_regions();
181 rset.push_back(
"PVTNUM");
187 .emplace(this->simulator_.gridView().comm(),
188 FluidSystem::numPhases, rset,
189 [fp = std::cref(this->eclState_.fieldProps())]
190 (
const std::string& rsetName) ->
decltype(
auto)
191 { return fp.get().get_int(rsetName); });
201 const unsigned reportStepNum,
204 const bool isRestart)
210 const auto& problem = this->simulator_.problem();
217 &problem.materialLawManager()->hysteresisConfig(),
218 problem.eclWriter().getOutputNnc().front().size());
223 const int reportStepNum)
225 this->setupElementExtractors_();
226 this->setupBlockExtractors_(isSubStep, reportStepNum);
232 this->extractors_.clear();
233 this->blockExtractors_.clear();
234 this->extraBlockExtractors_.clear();
248 if (this->extractors_.empty()) {
252 const auto& matLawManager = simulator_.problem().materialLawManager();
255 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
256 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
257 const auto& fs = intQuants.fluidState();
260 elemCtx.globalSpaceIndex(dofIdx, 0),
261 elemCtx.primaryVars(dofIdx, 0).pvtRegionIndex(),
268 if (matLawManager->enableHysteresis()) {
269 if (FluidSystem::phaseIsActive(oilPhaseIdx) && FluidSystem::phaseIsActive(waterPhaseIdx)) {
270 matLawManager->oilWaterHysteresisParams(hysterParams.
somax,
275 if (FluidSystem::phaseIsActive(oilPhaseIdx) && FluidSystem::phaseIsActive(gasPhaseIdx)) {
276 matLawManager->gasOilHysteresisParams(hysterParams.
sgmax,
294 if (this->blockExtractors_.empty() && this->extraBlockExtractors_.empty()) {
298 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
300 const auto globalDofIdx = elemCtx.globalSpaceIndex(dofIdx, 0);
301 const auto cartesianIdx = elemCtx.simulator().vanguard().cartesianIndex(globalDofIdx);
303 const auto be_it = this->blockExtractors_.find(cartesianIdx);
304 const auto bee_it = this->extraBlockExtractors_.find(cartesianIdx);
305 if (be_it == this->blockExtractors_.end() &&
306 bee_it == this->extraBlockExtractors_.end())
311 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
312 const auto& fs = intQuants.fluidState();
322 if (be_it != this->blockExtractors_.end()) {
325 if (bee_it != this->extraBlockExtractors_.end()) {
332 const std::size_t reportStepNum,
334 boost::posix_time::ptime currentDate,
339 if (comm.rank() != 0) {
344 std::unique_ptr<FIPConfig> fipSched;
345 if (reportStepNum > 0) {
346 const auto& rpt = this->
schedule_[reportStepNum-1].rpt_config.get();
347 fipSched = std::make_unique<FIPConfig>(rpt);
349 const FIPConfig& fipc = reportStepNum == 0 ? this->
eclState_.getEclipseConfig().fip()
354 this->
logOutput_.timeStamp(
"BALANCE", elapsed, reportStepNum, currentDate);
357 this->
logOutput_.fip(inplace, initial_inplace,
"");
359 if (fipc.output(FIPConfig::OutputField::FIPNUM)) {
360 this->
logOutput_.fip(inplace, initial_inplace,
"FIPNUM");
362 if (fipc.output(FIPConfig::OutputField::RESV))
366 if (fipc.output(FIPConfig::OutputField::FIP)) {
367 for (
const auto& reg : this->regions_) {
368 if (reg.first !=
"FIPNUM") {
369 std::ostringstream ss;
370 ss <<
"BAL" << reg.first.substr(3);
371 this->
logOutput_.timeStamp(ss.str(), elapsed, reportStepNum, currentDate);
372 this->
logOutput_.fip(inplace, initial_inplace, reg.first);
374 if (fipc.output(FIPConfig::OutputField::RESV))
386 if (comm.rank() != 0) {
390 if ((reportStepNum == 0) && (!substep) &&
391 (this->
schedule_.initialReportConfiguration().has_value()) &&
392 (this->schedule_.initialReportConfiguration()->contains(
"CSVFIP"))) {
394 std::ostringstream csv_stream;
400 this->
logOutput_.fip_csv(csv_stream, initial_inplace,
"FIPNUM");
402 for (
const auto& reg : this->regions_) {
403 if (reg.first !=
"FIPNUM") {
404 this->
logOutput_.fip_csv(csv_stream, initial_inplace, reg.first);
408 const IOConfig& io = this->
eclState_.getIOConfig();
409 auto csv_fname = io.getOutputDir() +
"/" + io.getBaseName() +
".CSV";
411 std::ofstream outputFile(csv_fname);
413 outputFile << csv_stream.str();
447 template <
class ActiveIndex,
class CartesianIndex>
449 ActiveIndex&& activeIndex,
450 CartesianIndex&& cartesianIndex)
453 const auto identifyCell = [&activeIndex, &cartesianIndex](
const Element& elem)
456 const auto cellIndex = activeIndex(elem);
459 static_cast<int>(cellIndex),
460 cartesianIndex(cellIndex),
461 elem.partitionType() == Dune::InteriorEntity
465 const auto timeIdx = 0u;
466 const auto& stencil = elemCtx.stencil(timeIdx);
467 const auto numInteriorFaces = elemCtx.numInteriorFaces(timeIdx);
469 for (
auto scvfIdx = 0 * numInteriorFaces; scvfIdx < numInteriorFaces; ++scvfIdx) {
470 const auto& face = stencil.interiorFace(scvfIdx);
471 const auto left = identifyCell(stencil.element(face.interiorIndex()));
472 const auto right = identifyCell(stencil.element(face.exteriorIndex()));
474 const auto rates = this->
475 getComponentSurfaceRates(elemCtx, face.area(), scvfIdx, timeIdx);
508 template <
class Flu
idState>
511 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
515 fs.setSaturation(phaseIdx, this->
saturation_[phaseIdx][elemIdx]);
521 std::array<Scalar, numPhases> pc = {0};
522 const MaterialLawParams& matParams = simulator_.problem().materialLawParams(elemIdx);
523 MaterialLaw::capillaryPressures(pc, matParams, fs);
525 Valgrind::CheckDefined(pc);
527 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
528 if (!FluidSystem::phaseIsActive(phaseIdx))
531 if (Indices::oilEnabled)
532 fs.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[oilPhaseIdx]));
533 else if (Indices::gasEnabled)
534 fs.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[gasPhaseIdx]));
535 else if (Indices::waterEnabled)
537 fs.setPressure(phaseIdx, pressure);
541 if constexpr (energyModuleType != EnergyModules::NoTemperature) {
543 fs.setTemperature(this->temperature_[elemIdx]);
545 if constexpr (enableDissolvedGas) {
546 if (!this->
rs_.empty())
547 fs.setRs(this->rs_[elemIdx]);
548 if (!this->
rv_.empty())
549 fs.setRv(this->rv_[elemIdx]);
551 if constexpr (enableDisgasInWater) {
552 if (!this->
rsw_.empty())
553 fs.setRsw(this->rsw_[elemIdx]);
555 if constexpr (enableVapwat) {
556 if (!this->
rvw_.empty())
557 fs.setRvw(this->rvw_[elemIdx]);
563 if (!this->
soMax_.empty())
564 simulator.problem().setMaxOilSaturation(elemIdx, this->
soMax_[elemIdx]);
566 if (simulator.problem().materialLawManager()->enableHysteresis()) {
567 auto matLawManager = simulator.problem().materialLawManager();
569 if (FluidSystem::phaseIsActive(oilPhaseIdx)
570 && FluidSystem::phaseIsActive(waterPhaseIdx)) {
575 if (matLawManager->enableNonWettingHysteresis()) {
576 if (!this->
soMax_.empty()) {
577 somax = this->
soMax_[elemIdx];
580 if (matLawManager->enableWettingHysteresis()) {
581 if (!this->
swMax_.empty()) {
582 swmax = this->
swMax_[elemIdx];
585 if (matLawManager->enablePCHysteresis()) {
586 if (!this->
swmin_.empty()) {
587 swmin = this->
swmin_[elemIdx];
590 matLawManager->setOilWaterHysteresisParams(
591 somax, swmax, swmin, elemIdx);
593 if (FluidSystem::phaseIsActive(oilPhaseIdx)
594 && FluidSystem::phaseIsActive(gasPhaseIdx)) {
599 if (matLawManager->enableNonWettingHysteresis()) {
600 if (!this->
sgmax_.empty()) {
601 sgmax = this->
sgmax_[elemIdx];
604 if (matLawManager->enableWettingHysteresis()) {
605 if (!this->
shmax_.empty()) {
606 shmax = this->
shmax_[elemIdx];
609 if (matLawManager->enablePCHysteresis()) {
610 if (!this->
somin_.empty()) {
611 somin = this->
somin_[elemIdx];
614 matLawManager->setGasOilHysteresisParams(
615 sgmax, shmax, somin, elemIdx);
620 if (simulator_.vanguard().eclState().fieldProps().has_double(
"SWATINIT")) {
621 simulator.problem().materialLawManager()
622 ->applyRestartSwatInit(elemIdx, this->
ppcw_[elemIdx]);
628 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
629 updateFluidInPlace_(elemCtx, dofIdx);
634 const IntensiveQuantities& intQuants,
635 const double totVolume)
637 this->updateFluidInPlace_(globalDofIdx, intQuants, totVolume);
641 template <
typename T>
642 using RemoveCVR = std::remove_cv_t<std::remove_reference_t<T>>;
644 template <
typename,
class =
void>
645 struct HasGeoMech :
public std::false_type {};
647 template <
typename Problem>
649 Problem, std::void_t<decltype(std::declval<Problem>().geoMechModel())>
650 > :
public std::true_type {};
652 bool isDefunctParallelWell(
const std::string& wname)
const override
654 if (simulator_.gridView().comm().size() == 1)
656 const auto& parallelWells = simulator_.vanguard().parallelWells();
657 std::pair<std::string, bool> value {wname,
true};
658 auto candidate = std::lower_bound(parallelWells.begin(), parallelWells.end(), value);
659 return candidate == parallelWells.end() || *candidate != value;
662 bool isOwnedByCurrentRank(
const std::string& wname)
const override
664 return this->simulator_.problem().wellModel().isOwner(wname);
667 bool isOnCurrentRank(
const std::string& wname)
const override
669 return this->simulator_.problem().wellModel().hasLocalCells(wname);
672 void updateFluidInPlace_(
const ElementContext& elemCtx,
const unsigned dofIdx)
674 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
675 const unsigned globalDofIdx = elemCtx.globalSpaceIndex(dofIdx, 0);
676 const auto totVolume = elemCtx.simulator().model().dofTotalVolume(globalDofIdx);
678 this->updateFluidInPlace_(globalDofIdx, intQuants, totVolume);
681 void updateFluidInPlace_(
const unsigned globalDofIdx,
682 const IntensiveQuantities& intQuants,
683 const double totVolume)
687 this->updateTotalVolumesAndPressures_(globalDofIdx, intQuants, totVolume);
690 this->updatePhaseInplaceVolumes_(globalDofIdx, intQuants, totVolume);
694 void createLocalRegion_(std::vector<int>& region)
700 region.resize(simulator_.gridView().size(0));
701 std::size_t elemIdx = 0;
702 for (
const auto& elem : elements(simulator_.gridView())) {
703 if (elem.partitionType() != Dune::InteriorEntity) {
711 template <
typename Flu
idState>
712 void aggregateAverageDensityContributions_(
const FluidState& fs,
713 const unsigned int globalDofIdx,
716 auto pvCellValue = RegionPhasePoreVolAverage::CellValue{};
717 pvCellValue.porv = porv;
719 for (
auto phaseIdx = 0*FluidSystem::numPhases;
720 phaseIdx < FluidSystem::numPhases; ++phaseIdx)
722 if (! FluidSystem::phaseIsActive(phaseIdx)) {
726 pvCellValue.value = getValue(fs.density(phaseIdx));
727 pvCellValue.sat = getValue(fs.saturation(phaseIdx));
730 ->addCell(globalDofIdx,
751 data::InterRegFlowMap::FlowRates
752 getComponentSurfaceRates(
const ElementContext& elemCtx,
753 const Scalar faceArea,
754 const std::size_t scvfIdx,
755 const std::size_t timeIdx)
const
757 using Component = data::InterRegFlowMap::Component;
759 auto rates = data::InterRegFlowMap::FlowRates {};
761 const auto& extQuant = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
763 const auto alpha = getValue(extQuant.extrusionFactor()) * faceArea;
765 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
766 const auto& up = elemCtx
767 .intensiveQuantities(extQuant.upstreamIndex(oilPhaseIdx), timeIdx);
769 const auto pvtReg = up.pvtRegionIndex();
771 const auto bO = getValue(getInvB_<FluidSystem, FluidState, Scalar>
772 (up.fluidState(), oilPhaseIdx, pvtReg));
774 const auto qO = alpha * bO * getValue(extQuant.volumeFlux(oilPhaseIdx));
776 rates[Component::Oil] += qO;
778 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
779 const auto Rs = getValue(
780 BlackOil::getRs_<FluidSystem, FluidState, Scalar>
781 (up.fluidState(), pvtReg));
783 rates[Component::Gas] += qO *
Rs;
784 rates[Component::Disgas] += qO *
Rs;
788 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
789 const auto& up = elemCtx
790 .intensiveQuantities(extQuant.upstreamIndex(gasPhaseIdx), timeIdx);
792 const auto pvtReg = up.pvtRegionIndex();
794 const auto bG = getValue(getInvB_<FluidSystem, FluidState, Scalar>
795 (up.fluidState(), gasPhaseIdx, pvtReg));
797 const auto qG = alpha * bG * getValue(extQuant.volumeFlux(gasPhaseIdx));
799 rates[Component::Gas] += qG;
801 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
802 const auto Rv = getValue(
803 BlackOil::getRv_<FluidSystem, FluidState, Scalar>
804 (up.fluidState(), pvtReg));
806 rates[Component::Oil] += qG *
Rv;
807 rates[Component::Vapoil] += qG *
Rv;
811 if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
812 const auto& up = elemCtx
813 .intensiveQuantities(extQuant.upstreamIndex(waterPhaseIdx), timeIdx);
815 const auto pvtReg = up.pvtRegionIndex();
817 const auto bW = getValue(getInvB_<FluidSystem, FluidState, Scalar>
818 (up.fluidState(), waterPhaseIdx, pvtReg));
820 rates[Component::Water] +=
821 alpha * bW * getValue(extQuant.volumeFlux(waterPhaseIdx));
827 template <
typename Flu
idState>
828 Scalar hydroCarbonFraction(
const FluidState& fs)
const
830 if (this->
eclState_.runspec().co2Storage()) {
837 auto hydrocarbon = Scalar {0};
838 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
839 hydrocarbon += getValue(fs.saturation(oilPhaseIdx));
842 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
843 hydrocarbon += getValue(fs.saturation(gasPhaseIdx));
849 void updateTotalVolumesAndPressures_(
const unsigned globalDofIdx,
850 const IntensiveQuantities& intQuants,
851 const double totVolume)
853 const auto& fs = intQuants.fluidState();
855 const double pv = totVolume * intQuants.porosity().value();
856 const auto hydrocarbon = this->hydroCarbonFraction(fs);
860 totVolume * intQuants.referencePorosity());
867 !this->pressureTimesPoreVolume_.empty())
870 assert(this->
fipC_.
get(Inplace::Phase::PoreVolume).size() == this->pressureTimesPoreVolume_.size());
872 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
874 getValue(fs.pressure(oilPhaseIdx)) * pv;
879 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
881 getValue(fs.pressure(gasPhaseIdx)) * pv;
886 else if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
888 getValue(fs.pressure(waterPhaseIdx)) * pv;
893 void updatePhaseInplaceVolumes_(
const unsigned globalDofIdx,
894 const IntensiveQuantities& intQuants,
895 const double totVolume)
897 std::array<Scalar, FluidSystem::numPhases> fip {};
898 std::array<Scalar, FluidSystem::numPhases> fipr{};
900 const auto& fs = intQuants.fluidState();
901 const auto pv = totVolume * intQuants.porosity().value();
903 for (
unsigned phaseIdx = 0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) {
904 if (!FluidSystem::phaseIsActive(phaseIdx)) {
908 const auto b = getValue(fs.invB(phaseIdx));
909 const auto s = getValue(fs.saturation(phaseIdx));
911 fipr[phaseIdx] = s * pv;
912 fip [phaseIdx] = b * fipr[phaseIdx];
917 fs.saltConcentration().value(),
920 if (FluidSystem::phaseIsActive(oilPhaseIdx) &&
921 FluidSystem::phaseIsActive(gasPhaseIdx))
923 this->updateOilGasDistribution(globalDofIdx, fs, fip);
926 if (FluidSystem::phaseIsActive(waterPhaseIdx) &&
927 FluidSystem::phaseIsActive(gasPhaseIdx))
929 this->updateGasWaterDistribution(globalDofIdx, fs, fip);
932 if (FluidSystem::phaseIsActive(gasPhaseIdx) &&
935 this->updateCO2InGas(globalDofIdx, pv, intQuants);
939 (FluidSystem::phaseIsActive(waterPhaseIdx) ||
940 FluidSystem::phaseIsActive(oilPhaseIdx)))
942 this->updateCO2InWater(globalDofIdx, pv, fs);
945 if constexpr(enableBioeffects) {
946 const auto surfVolWat = pv * getValue(fs.saturation(waterPhaseIdx)) *
947 getValue(fs.invB(waterPhaseIdx));
949 this->updateMicrobialMass(globalDofIdx, intQuants, surfVolWat);
952 this->updateBiofilmMass(globalDofIdx, intQuants, totVolume);
954 if constexpr(enableMICP) {
956 this->updateOxygenMass(globalDofIdx, intQuants, surfVolWat);
959 this->updateUreaMass(globalDofIdx, intQuants, surfVolWat);
962 this->updateCalciteMass(globalDofIdx, intQuants, totVolume);
969 this->updateWaterMass(globalDofIdx, fs, fip);
973 template <
typename Flu
idState,
typename FIPArray>
974 void updateOilGasDistribution(
const unsigned globalDofIdx,
975 const FluidState& fs,
979 const auto gasInPlaceLiquid = getValue(fs.Rs()) * fip[oilPhaseIdx];
980 const auto oilInPlaceGas = getValue(fs.Rv()) * fip[gasPhaseIdx];
985 template <
typename Flu
idState,
typename FIPArray>
986 void updateGasWaterDistribution(
const unsigned globalDofIdx,
987 const FluidState& fs,
991 const auto gasInPlaceWater = getValue(fs.Rsw()) * fip[waterPhaseIdx];
992 const auto waterInPlaceGas = getValue(fs.Rvw()) * fip[gasPhaseIdx];
997 template <
typename IntensiveQuantities>
998 void updateCO2InGas(
const unsigned globalDofIdx,
1000 const IntensiveQuantities& intQuants)
1002 const auto& scaledDrainageInfo = this->simulator_.problem().materialLawManager()
1003 ->oilWaterScaledEpsInfoDrainage(globalDofIdx);
1005 const auto& fs = intQuants.fluidState();
1006 Scalar sgcr = scaledDrainageInfo.Sgcr;
1007 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1008 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1009 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
1012 Scalar trappedGasSaturation = scaledDrainageInfo.Sgcr;
1013 if (this->
fipC_.
has(Inplace::Phase::CO2MassInGasPhaseMaximumTrapped) ||
1014 this->fipC_.has(Inplace::Phase::CO2MassInGasPhaseMaximumUnTrapped))
1016 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1017 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1019 trappedGasSaturation = MaterialLaw::trappedGasSaturation(matParams,
true);
1023 const Scalar sg = getValue(fs.saturation(gasPhaseIdx));
1024 Scalar strandedGasSaturation = scaledDrainageInfo.Sgcr;
1025 if (this->
fipC_.
has(Inplace::Phase::CO2MassInGasPhaseEffectiveTrapped) ||
1026 this->fipC_.has(Inplace::Phase::CO2MassInGasPhaseEffectiveUnTrapped))
1028 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1029 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1030 const double krg = getValue(intQuants.relativePermeability(gasPhaseIdx));
1031 strandedGasSaturation = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
1035 const typename FIPContainer<FluidSystem>::Co2InGasInput v{
1039 getValue(fs.density(gasPhaseIdx)),
1040 FluidSystem::phaseIsActive(waterPhaseIdx)
1041 ? FluidSystem::convertRvwToXgW(getValue(fs.Rvw()), fs.pvtRegionIndex())
1042 : FluidSystem::convertRvToXgO(getValue(fs.
Rv()), fs.pvtRegionIndex()),
1043 FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex()),
1044 trappedGasSaturation,
1045 strandedGasSaturation,
1051 template <
typename Flu
idState>
1052 void updateCO2InWater(
const unsigned globalDofIdx,
1054 const FluidState& fs)
1056 const auto co2InWater = FluidSystem::phaseIsActive(oilPhaseIdx)
1057 ? this->co2InWaterFromOil(fs, pv)
1058 : this->co2InWaterFromWater(fs, pv);
1060 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1065 template <
typename Flu
idState>
1066 Scalar co2InWaterFromWater(
const FluidState& fs,
const double pv)
const
1068 const double rhow = getValue(fs.density(waterPhaseIdx));
1069 const double sw = getValue(fs.saturation(waterPhaseIdx));
1070 const double xwG = FluidSystem::convertRswToXwG(getValue(fs.Rsw()), fs.pvtRegionIndex());
1072 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1074 return xwG * pv * rhow * sw / mM;
1077 template <
typename Flu
idState>
1078 Scalar co2InWaterFromOil(
const FluidState& fs,
const double pv)
const
1080 const double rhoo = getValue(fs.density(oilPhaseIdx));
1081 const double so = getValue(fs.saturation(oilPhaseIdx));
1082 const double xoG = FluidSystem::convertRsToXoG(getValue(fs.Rs()), fs.pvtRegionIndex());
1084 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1086 return xoG * pv * rhoo * so / mM;
1089 template <
typename Flu
idState,
typename FIPArray>
1090 void updateWaterMass(
const unsigned globalDofIdx,
1091 const FluidState& fs,
1095 const Scalar rhoW = FluidSystem::referenceDensity(waterPhaseIdx, fs.pvtRegionIndex());
1100 template <
typename IntensiveQuantities>
1101 void updateMicrobialMass(
const unsigned globalDofIdx,
1102 const IntensiveQuantities& intQuants,
1103 const double surfVolWat)
1105 const Scalar mass = surfVolWat * intQuants.microbialConcentration().value();
1110 template <
typename IntensiveQuantities>
1111 void updateOxygenMass(
const unsigned globalDofIdx,
1112 const IntensiveQuantities& intQuants,
1113 const double surfVolWat)
1115 const Scalar mass = surfVolWat * intQuants.oxygenConcentration().value();
1120 template <
typename IntensiveQuantities>
1121 void updateUreaMass(
const unsigned globalDofIdx,
1122 const IntensiveQuantities& intQuants,
1123 const double surfVolWat)
1125 const Scalar mass = surfVolWat * intQuants.ureaConcentration().value();
1130 template <
typename IntensiveQuantities>
1131 void updateBiofilmMass(
const unsigned globalDofIdx,
1132 const IntensiveQuantities& intQuants,
1133 const double totVolume)
1135 const Scalar mass = totVolume * intQuants.biofilmMass().value();
1140 template <
typename IntensiveQuantities>
1141 void updateCalciteMass(
const unsigned globalDofIdx,
1142 const IntensiveQuantities& intQuants,
1143 const double totVolume)
1145 const Scalar mass = totVolume * intQuants.calciteMass().value();
1151 void setupElementExtractors_()
1153 using Entry =
typename Extractor::Entry;
1154 using Context =
typename Extractor::Context;
1155 using ScalarEntry =
typename Extractor::ScalarEntry;
1156 using PhaseEntry =
typename Extractor::PhaseEntry;
1158 const bool hasResidual = simulator_.model().linearizer().residual().size() > 0;
1159 const auto& hysteresisConfig = simulator_.problem().materialLawManager()->hysteresisConfig();
1161 auto extractors = std::array{
1163 [](
const unsigned phase,
const Context& ectx)
1164 {
return getValue(ectx.fs.saturation(phase)); }
1167 Entry{PhaseEntry{&this->
invB_,
1168 [](
const unsigned phase,
const Context& ectx)
1169 {
return getValue(ectx.fs.invB(phase)); }
1173 [](
const unsigned phase,
const Context& ectx)
1174 {
return getValue(ectx.fs.density(phase)); }
1178 [](
const unsigned phase,
const Context& ectx)
1179 {
return getValue(ectx.intQuants.relativePermeability(phase)); }
1183 [
this](
const unsigned phaseIdx,
const Context& ectx)
1185 if (this->
extboC_.allocated() && phaseIdx == oilPhaseIdx) {
1186 return getValue(ectx.intQuants.oilViscosity());
1188 else if (this->
extboC_.allocated() && phaseIdx == gasPhaseIdx) {
1189 return getValue(ectx.intQuants.gasViscosity());
1192 return getValue(ectx.fs.viscosity(phaseIdx));
1198 [&modelResid = this->simulator_.model().linearizer().residual()]
1199 (
const unsigned phaseIdx,
const Context& ectx)
1201 const unsigned sIdx = FluidSystem::solventComponentIndex(phaseIdx);
1202 const unsigned activeCompIdx = FluidSystem::canonicalToActiveCompIdx(sIdx);
1203 return modelResid[ectx.globalDofIdx][activeCompIdx];
1209 [&problem = this->simulator_.problem()](
const Context& ectx)
1211 return problem.template
1212 rockCompPoroMultiplier<Scalar>(ectx.intQuants,
1218 [&problem = this->simulator_.problem()](
const Context& ectx)
1221 template rockCompTransMultiplier<Scalar>(ectx.intQuants,
1226 [&problem = this->simulator_.problem()](
const Context& ectx)
1228 return std::min(getValue(ectx.fs.pressure(oilPhaseIdx)),
1229 problem.minOilPressure(ectx.globalDofIdx));
1235 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1239 FluidSystem::bubblePointPressure(ectx.fs,
1240 ectx.intQuants.pvtRegionIndex())
1242 }
catch (
const NumericalProblem&) {
1243 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1244 failedCells.push_back(cartesianIdx);
1252 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1256 FluidSystem::dewPointPressure(ectx.fs,
1257 ectx.intQuants.pvtRegionIndex())
1259 }
catch (
const NumericalProblem&) {
1260 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1261 failedCells.push_back(cartesianIdx);
1268 [&problem = simulator_.problem()](
const Context& ectx)
1269 {
return problem.overburdenPressure(ectx.globalDofIdx); }
1273 [](
const Context& ectx)
1274 {
return getValue(ectx.fs.temperature(oilPhaseIdx)); }
1277 Entry{ScalarEntry{&this->
sSol_,
1278 [](
const Context& ectx)
1279 {
return getValue(ectx.intQuants.solventSaturation()); }
1282 Entry{ScalarEntry{&this->
rswSol_,
1283 [](
const Context& ectx)
1284 {
return getValue(ectx.intQuants.rsSolw()); }
1288 [](
const Context& ectx)
1289 {
return getValue(ectx.intQuants.polymerConcentration()); }
1292 Entry{ScalarEntry{&this->
cFoam_,
1293 [](
const Context& ectx)
1294 {
return getValue(ectx.intQuants.foamConcentration()); }
1297 Entry{ScalarEntry{&this->
cSalt_,
1298 [](
const Context& ectx)
1299 {
return getValue(ectx.fs.saltConcentration()); }
1302 Entry{ScalarEntry{&this->
pSalt_,
1303 [](
const Context& ectx)
1304 {
return getValue(ectx.fs.saltSaturation()); }
1308 [](
const Context& ectx)
1309 {
return getValue(ectx.intQuants.permFactor()); }
1312 Entry{ScalarEntry{&this->
rPorV_,
1313 [&model = this->simulator_.model()](
const Context& ectx)
1315 const auto totVolume = model.dofTotalVolume(ectx.globalDofIdx);
1316 return totVolume * getValue(ectx.intQuants.porosity());
1320 Entry{ScalarEntry{&this->
rs_,
1321 [](
const Context& ectx)
1322 {
return getValue(ectx.fs.Rs()); }
1325 Entry{ScalarEntry{&this->
rv_,
1326 [](
const Context& ectx)
1327 {
return getValue(ectx.fs.Rv()); }
1330 Entry{ScalarEntry{&this->
rsw_,
1331 [](
const Context& ectx)
1332 {
return getValue(ectx.fs.Rsw()); }
1335 Entry{ScalarEntry{&this->
rvw_,
1336 [](
const Context& ectx)
1337 {
return getValue(ectx.fs.Rvw()); }
1340 Entry{ScalarEntry{&this->
ppcw_,
1341 [&matLawManager = *this->simulator_.problem().materialLawManager()]
1342 (
const Context& ectx)
1344 return matLawManager.
1345 oilWaterScaledEpsInfoDrainage(ectx.globalDofIdx).maxPcow;
1350 [&problem = this->simulator_.problem()](
const Context& ectx)
1352 return problem.drsdtcon(ectx.globalDofIdx,
1357 Entry{ScalarEntry{&this->
pcgw_,
1358 [](
const Context& ectx)
1360 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1361 getValue(ectx.fs.pressure(waterPhaseIdx));
1365 Entry{ScalarEntry{&this->
pcow_,
1366 [](
const Context& ectx)
1368 return getValue(ectx.fs.pressure(oilPhaseIdx)) -
1369 getValue(ectx.fs.pressure(waterPhaseIdx));
1373 Entry{ScalarEntry{&this->
pcog_,
1374 [](
const Context& ectx)
1376 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1377 getValue(ectx.fs.pressure(oilPhaseIdx));
1382 [](
const Context& ectx)
1384 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1386 return getValue(ectx.fs.pressure(oilPhaseIdx));
1388 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1390 return getValue(ectx.fs.pressure(gasPhaseIdx));
1394 return getValue(ectx.fs.pressure(waterPhaseIdx));
1400 [&problem = this->simulator_.problem()](
const Context& ectx)
1402 const Scalar SoMax = problem.maxOilSaturation(ectx.globalDofIdx);
1403 return FluidSystem::template
1404 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1412 [&problem = this->simulator_.problem()](
const Context& ectx)
1414 const Scalar SoMax = problem.maxOilSaturation(ectx.globalDofIdx);
1415 return FluidSystem::template
1416 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1424 [&problem = this->simulator_.problem()](
const Context& ectx)
1426 const Scalar SwMax = problem.maxWaterSaturation(ectx.globalDofIdx);
1427 return FluidSystem::template
1428 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1436 [](
const Context& ectx)
1438 return FluidSystem::template
1439 saturatedVaporizationFactor<FluidState, Scalar>(ectx.fs,
1446 [](
const Context& ectx)
1448 return 1.0 / FluidSystem::template
1449 inverseFormationVolumeFactor<FluidState, Scalar>(ectx.fs,
1456 [](
const Context& ectx)
1458 return 1.0 / FluidSystem::template
1459 saturatedInverseFormationVolumeFactor<FluidState, Scalar>(ectx.fs,
1466 [](
const Context& ectx)
1468 return FluidSystem::template
1469 saturationPressure<FluidState, Scalar>(ectx.fs,
1475 Entry{ScalarEntry{&this->
soMax_,
1476 [&problem = this->simulator_.problem()](
const Context& ectx)
1478 return std::max(getValue(ectx.fs.saturation(oilPhaseIdx)),
1479 problem.maxOilSaturation(ectx.globalDofIdx));
1482 !hysteresisConfig.enableHysteresis()
1484 Entry{ScalarEntry{&this->
swMax_,
1485 [&problem = this->simulator_.problem()](
const Context& ectx)
1487 return std::max(getValue(ectx.fs.saturation(waterPhaseIdx)),
1488 problem.maxWaterSaturation(ectx.globalDofIdx));
1491 !hysteresisConfig.enableHysteresis()
1493 Entry{ScalarEntry{&this->
soMax_,
1494 [](
const Context& ectx)
1495 {
return ectx.hParams.somax; }
1497 hysteresisConfig.enableHysteresis() &&
1498 hysteresisConfig.enableNonWettingHysteresis() &&
1499 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1500 FluidSystem::phaseIsActive(waterPhaseIdx)
1502 Entry{ScalarEntry{&this->
swMax_,
1503 [](
const Context& ectx)
1504 {
return ectx.hParams.swmax; }
1506 hysteresisConfig.enableHysteresis() &&
1507 hysteresisConfig.enableWettingHysteresis() &&
1508 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1509 FluidSystem::phaseIsActive(waterPhaseIdx)
1511 Entry{ScalarEntry{&this->
swmin_,
1512 [](
const Context& ectx)
1513 {
return ectx.hParams.swmin; }
1515 hysteresisConfig.enableHysteresis() &&
1516 hysteresisConfig.enablePCHysteresis() &&
1517 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1518 FluidSystem::phaseIsActive(waterPhaseIdx)
1520 Entry{ScalarEntry{&this->
sgmax_,
1521 [](
const Context& ectx)
1522 {
return ectx.hParams.sgmax; }
1524 hysteresisConfig.enableHysteresis() &&
1525 hysteresisConfig.enableNonWettingHysteresis() &&
1526 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1527 FluidSystem::phaseIsActive(gasPhaseIdx)
1529 Entry{ScalarEntry{&this->
shmax_,
1530 [](
const Context& ectx)
1531 {
return ectx.hParams.shmax; }
1533 hysteresisConfig.enableHysteresis() &&
1534 hysteresisConfig.enableWettingHysteresis() &&
1535 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1536 FluidSystem::phaseIsActive(gasPhaseIdx)
1538 Entry{ScalarEntry{&this->
somin_,
1539 [](
const Context& ectx)
1540 {
return ectx.hParams.somin; }
1542 hysteresisConfig.enableHysteresis() &&
1543 hysteresisConfig.enablePCHysteresis() &&
1544 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1545 FluidSystem::phaseIsActive(gasPhaseIdx)
1547 Entry{[&model = this->simulator_.model(),
this](
const Context& ectx)
1551 const auto porv = ectx.intQuants.referencePorosity()
1552 * model.dofTotalVolume(ectx.globalDofIdx);
1554 this->aggregateAverageDensityContributions_(ectx.fs, ectx.globalDofIdx,
1555 static_cast<double>(porv));
1558 Entry{[&extboC = this->
extboC_](
const Context& ectx)
1560 extboC.assignVolumes(ectx.globalDofIdx,
1561 ectx.intQuants.xVolume().value(),
1562 ectx.intQuants.yVolume().value());
1563 extboC.assignZFraction(ectx.globalDofIdx,
1564 ectx.intQuants.zFraction().value());
1566 const Scalar stdVolOil = getValue(ectx.fs.saturation(oilPhaseIdx)) *
1567 getValue(ectx.fs.invB(oilPhaseIdx)) +
1568 getValue(ectx.fs.saturation(gasPhaseIdx)) *
1569 getValue(ectx.fs.invB(gasPhaseIdx)) *
1570 getValue(ectx.fs.Rv());
1571 const Scalar stdVolGas = getValue(ectx.fs.saturation(gasPhaseIdx)) *
1572 getValue(ectx.fs.invB(gasPhaseIdx)) *
1573 (1.0 - ectx.intQuants.yVolume().value()) +
1574 getValue(ectx.fs.saturation(oilPhaseIdx)) *
1575 getValue(ectx.fs.invB(oilPhaseIdx)) *
1576 getValue(ectx.fs.Rs()) *
1577 (1.0 - ectx.intQuants.xVolume().value());
1578 const Scalar stdVolCo2 = getValue(ectx.fs.saturation(gasPhaseIdx)) *
1579 getValue(ectx.fs.invB(gasPhaseIdx)) *
1580 ectx.intQuants.yVolume().value() +
1581 getValue(ectx.fs.saturation(oilPhaseIdx)) *
1582 getValue(ectx.fs.invB(oilPhaseIdx)) *
1583 getValue(ectx.fs.Rs()) *
1584 ectx.intQuants.xVolume().value();
1585 const Scalar rhoO = FluidSystem::referenceDensity(gasPhaseIdx, ectx.pvtRegionIdx);
1586 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx, ectx.pvtRegionIdx);
1587 const Scalar rhoCO2 = ectx.intQuants.zRefDensity();
1588 const Scalar stdMassTotal = 1.0e-10 + stdVolOil * rhoO + stdVolGas * rhoG + stdVolCo2 * rhoCO2;
1589 extboC.assignMassFractions(ectx.globalDofIdx,
1590 stdVolGas * rhoG / stdMassTotal,
1591 stdVolOil * rhoO / stdMassTotal,
1592 stdVolCo2 * rhoCO2 / stdMassTotal);
1595 Entry{[&bioeffectsC = this->
bioeffectsC_](
const Context& ectx)
1597 bioeffectsC.assign(ectx.globalDofIdx,
1598 ectx.intQuants.microbialConcentration().value(),
1599 ectx.intQuants.biofilmVolumeFraction().value());
1600 if (Indices::enableMICP) {
1601 bioeffectsC.assign(ectx.globalDofIdx,
1602 ectx.intQuants.oxygenConcentration().value(),
1603 ectx.intQuants.ureaConcentration().value(),
1604 ectx.intQuants.calciteVolumeFraction().value());
1608 Entry{[&runspec = this->
eclState_.runspec(),
1609 &CO2H2C = this->
CO2H2C_](
const Context& ectx)
1611 const auto xwg = FluidSystem::convertRswToXwG(getValue(ectx.fs.Rsw()), ectx.pvtRegionIdx);
1612 const auto xgw = FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.pvtRegionIdx);
1613 CO2H2C.assign(ectx.globalDofIdx,
1614 FluidSystem::convertXwGToxwG(xwg, ectx.pvtRegionIdx),
1615 FluidSystem::convertXgWToxgW(xgw, ectx.pvtRegionIdx),
1616 runspec.co2Storage());
1619 Entry{[&rftC = this->
rftC_,
1620 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1622 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1623 rftC.assign(cartesianIdx,
1624 [&fs = ectx.fs]() {
return getValue(fs.pressure(oilPhaseIdx)); },
1625 [&fs = ectx.fs]() {
return getValue(fs.saturation(waterPhaseIdx)); },
1626 [&fs = ectx.fs]() {
return getValue(fs.saturation(gasPhaseIdx)); });
1630 &tM = this->simulator_.problem().tracerModel()](
const Context& ectx)
1632 tC.assignFreeConcentrations(ectx.globalDofIdx,
1633 [gIdx = ectx.globalDofIdx, &tM](
const unsigned tracerIdx)
1634 {
return tM.freeTracerConcentration(tracerIdx, gIdx); });
1635 tC.assignSolConcentrations(ectx.globalDofIdx,
1636 [gIdx = ectx.globalDofIdx, &tM](
const unsigned tracerIdx)
1637 {
return tM.solTracerConcentration(tracerIdx, gIdx); });
1640 Entry{[&flowsInf = this->simulator_.problem().model().linearizer().getFlowsInfo(),
1642 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1644 const auto gas_idx = Indices::gasEnabled ?
1645 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(gasCompIdx) : -1;
1646 const auto oil_idx = Indices::oilEnabled ?
1647 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(oilCompIdx) : -1;
1648 const auto water_idx = Indices::waterEnabled ?
1649 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(waterCompIdx) : -1;
1650 const auto& flowsInfos = flowsInf[ectx.globalDofIdx];
1651 if (!flowsC.blockFlows().empty()) {
1652 const std::vector<int>& blockIdxs = flowsC.blockFlows();
1653 const unsigned cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1654 if (std::ranges::binary_search(blockIdxs, cartesianIdx)) {
1655 const auto compIdxs = std::array{ gasCompIdx, oilCompIdx, waterCompIdx };
1656 const auto compEnabled = std::array{ Indices::gasEnabled, Indices::oilEnabled, Indices::waterEnabled };
1657 for (
const auto& flowsInfo : flowsInfos) {
1658 if (flowsInfo.faceId < 0) {
1661 for (
unsigned ii = 0; ii < compIdxs.size(); ++ii) {
1662 if (!compEnabled[ii]) {
1665 if (flowsC.hasBlockFlowValue(cartesianIdx, flowsInfo.faceId, compIdxs[ii])) {
1666 flowsC.assignBlockFlows(flowsC.blockFlowsIds(cartesianIdx, flowsInfo.faceId, compIdxs[ii]),
1669 flowsInfo.flow[conti0EqIdx
1670 + FluidSystem::canonicalToActiveCompIdx(compIdxs[ii])]);
1677 for (
const auto& flowsInfo : flowsInfos) {
1678 flowsC.assignFlows(ectx.globalDofIdx,
1681 value_or_zero(gas_idx, flowsInfo.flow),
1682 value_or_zero(oil_idx, flowsInfo.flow),
1683 value_or_zero(water_idx, flowsInfo.flow));
1686 }, !this->simulator_.problem().model().linearizer().getFlowsInfo().empty()
1688 Entry{[&floresInf = this->simulator_.problem().model().linearizer().getFloresInfo(),
1689 &flowsC = this->
flowsC_](
const Context& ectx)
1691 const auto gas_idx = Indices::gasEnabled ?
1692 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(gasCompIdx) : -1;
1693 const auto oil_idx = Indices::oilEnabled ?
1694 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(oilCompIdx) : -1;
1695 const auto water_idx = Indices::waterEnabled ?
1696 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(waterCompIdx) : -1;
1697 const auto& floresInfos = floresInf[ectx.globalDofIdx];
1698 for (
const auto& floresInfo : floresInfos) {
1699 flowsC.assignFlores(ectx.globalDofIdx,
1702 value_or_zero(gas_idx, floresInfo.flow),
1703 value_or_zero(oil_idx, floresInfo.flow),
1704 value_or_zero(water_idx, floresInfo.flow));
1706 }, !this->simulator_.problem().model().linearizer().getFloresInfo().empty()
1708 Entry{[&velocityInf = this->simulator_.problem().model().linearizer().getVelocityInfo(),
1710 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1712 const auto& velocityInfos = velocityInf[ectx.globalDofIdx];
1713 const std::vector<int>& blockIdxs = flowsC.blockVelocity();
1714 const unsigned cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1715 if (std::ranges::binary_search(blockIdxs, cartesianIdx)) {
1716 const auto compIdxs = std::array{ gasCompIdx, oilCompIdx, waterCompIdx };
1717 const auto compEnabled = std::array{ Indices::gasEnabled, Indices::oilEnabled, Indices::waterEnabled };
1718 for (
const auto& velocityInfo : velocityInfos) {
1719 if (velocityInfo.faceId < 0) {
1722 for (
unsigned ii = 0; ii < compIdxs.size(); ++ii) {
1723 if (!compEnabled[ii]) {
1726 if (flowsC.hasBlockVelocityValue(cartesianIdx, velocityInfo.faceId, compIdxs[ii])) {
1727 flowsC.assignBlockVelocity(flowsC.blockVelocityIds(cartesianIdx, velocityInfo.faceId, compIdxs[ii]),
1728 velocityInfo.faceId,
1730 velocityInfo.velocity[conti0EqIdx
1731 + FluidSystem::canonicalToActiveCompIdx(compIdxs[ii])]);
1737 !this->simulator_.problem().model().linearizer().getVelocityInfo().empty()
1744 Entry{ScalarEntry{&this->
rv_,
1745 [&problem = this->simulator_.problem()](
const Context& ectx)
1746 {
return problem.initialFluidState(ectx.globalDofIdx).Rv(); }
1748 simulator_.episodeIndex() < 0 &&
1749 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1750 FluidSystem::phaseIsActive(gasPhaseIdx)
1752 Entry{ScalarEntry{&this->
rs_,
1753 [&problem = this->simulator_.problem()](
const Context& ectx)
1754 {
return problem.initialFluidState(ectx.globalDofIdx).Rs(); }
1756 simulator_.episodeIndex() < 0 &&
1757 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1758 FluidSystem::phaseIsActive(gasPhaseIdx)
1760 Entry{ScalarEntry{&this->
rsw_,
1761 [&problem = this->simulator_.problem()](
const Context& ectx)
1762 {
return problem.initialFluidState(ectx.globalDofIdx).Rsw(); }
1764 simulator_.episodeIndex() < 0 &&
1765 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1766 FluidSystem::phaseIsActive(gasPhaseIdx)
1768 Entry{ScalarEntry{&this->
rvw_,
1769 [&problem = this->simulator_.problem()](
const Context& ectx)
1770 {
return problem.initialFluidState(ectx.globalDofIdx).Rvw(); }
1772 simulator_.episodeIndex() < 0 &&
1773 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1774 FluidSystem::phaseIsActive(gasPhaseIdx)
1778 [&problem = this->simulator_.problem()](
const unsigned phase,
1779 const Context& ectx)
1781 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
1782 return FluidSystem::density(fsInitial,
1784 ectx.intQuants.pvtRegionIndex());
1787 simulator_.episodeIndex() < 0 &&
1788 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1789 FluidSystem::phaseIsActive(gasPhaseIdx)
1791 Entry{PhaseEntry{&this->
invB_,
1792 [&problem = this->simulator_.problem()](
const unsigned phase,
1793 const Context& ectx)
1795 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
1796 return FluidSystem::inverseFormationVolumeFactor(fsInitial,
1798 ectx.intQuants.pvtRegionIndex());
1801 simulator_.episodeIndex() < 0 &&
1802 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1803 FluidSystem::phaseIsActive(gasPhaseIdx)
1806 [&problem = this->simulator_.problem()](
const unsigned phase,
1807 const Context& ectx)
1809 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
1810 return FluidSystem::viscosity(fsInitial,
1812 ectx.intQuants.pvtRegionIndex());
1815 simulator_.episodeIndex() < 0 &&
1816 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1817 FluidSystem::phaseIsActive(gasPhaseIdx)
1824 if constexpr (getPropValue<TypeTag, Properties::EnableMech>()) {
1825 if (this->
mech_.allocated()) {
1826 this->extractors_.push_back(
1827 Entry{[&mech = this->
mech_,
1828 &model = simulator_.problem().geoMechModel()](
const Context& ectx)
1830 mech.assignDelStress(ectx.globalDofIdx,
1831 model.delstress(ectx.globalDofIdx));
1833 mech.assignDisplacement(ectx.globalDofIdx,
1834 model.disp(ectx.globalDofIdx,
true));
1837 mech.assignFracStress(ectx.globalDofIdx,
1838 model.fractureStress(ectx.globalDofIdx));
1840 mech.assignLinStress(ectx.globalDofIdx,
1841 model.linstress(ectx.globalDofIdx));
1843 mech.assignPotentialForces(ectx.globalDofIdx,
1844 model.mechPotentialForce(ectx.globalDofIdx),
1845 model.mechPotentialPressForce(ectx.globalDofIdx),
1846 model.mechPotentialTempForce(ectx.globalDofIdx));
1848 mech.assignStrain(ectx.globalDofIdx,
1849 model.strain(ectx.globalDofIdx,
true));
1852 mech.assignStress(ectx.globalDofIdx,
1853 model.stress(ectx.globalDofIdx,
true));
1862 void setupBlockExtractors_(
const bool isSubStep,
1863 const int reportStepNum)
1866 using Context =
typename BlockExtractor::Context;
1867 using PhaseEntry =
typename BlockExtractor::PhaseEntry;
1868 using ScalarEntry =
typename BlockExtractor::ScalarEntry;
1870 using namespace std::string_view_literals;
1872 const auto pressure_handler =
1873 Entry{ScalarEntry{std::vector{
"BPR"sv,
"BPRESSUR"sv},
1874 [](
const Context& ectx)
1876 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1877 return getValue(ectx.fs.pressure(oilPhaseIdx));
1879 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1880 return getValue(ectx.fs.pressure(gasPhaseIdx));
1883 return getValue(ectx.fs.pressure(waterPhaseIdx));
1889 const auto handlers = std::array{
1891 Entry{PhaseEntry{std::array{
1892 std::array{
"BWSAT"sv,
"BOSAT"sv,
"BGSAT"sv},
1893 std::array{
"BSWAT"sv,
"BSOIL"sv,
"BSGAS"sv}
1895 [](
const unsigned phaseIdx,
const Context& ectx)
1897 return getValue(ectx.fs.saturation(phaseIdx));
1901 Entry{ScalarEntry{
"BNSAT",
1902 [](
const Context& ectx)
1904 return ectx.intQuants.solventSaturation().value();
1908 Entry{ScalarEntry{std::vector{
"BTCNFHEA"sv,
"BTEMP"sv},
1909 [](
const Context& ectx)
1911 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1912 return getValue(ectx.fs.temperature(oilPhaseIdx));
1914 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1915 return getValue(ectx.fs.temperature(gasPhaseIdx));
1918 return getValue(ectx.fs.temperature(waterPhaseIdx));
1923 Entry{PhaseEntry{std::array{
1924 std::array{
"BWKR"sv,
"BOKR"sv,
"BGKR"sv},
1925 std::array{
"BKRW"sv,
"BKRO"sv,
"BKRG"sv}
1927 [](
const unsigned phaseIdx,
const Context& ectx)
1929 return getValue(ectx.intQuants.relativePermeability(phaseIdx));
1933 Entry{ScalarEntry{
"BKROG",
1934 [&problem = this->simulator_.problem()](
const Context& ectx)
1936 const auto& materialParams =
1937 problem.materialLawParams(ectx.elemCtx,
1940 return getValue(MaterialLaw::template
1941 relpermOilInOilGasSystem<Evaluation>(materialParams,
1946 Entry{ScalarEntry{
"BKROW",
1947 [&problem = this->simulator_.problem()](
const Context& ectx)
1949 const auto& materialParams = problem.materialLawParams(ectx.elemCtx,
1952 return getValue(MaterialLaw::template
1953 relpermOilInOilWaterSystem<Evaluation>(materialParams,
1958 Entry{ScalarEntry{
"BWPC",
1959 [](
const Context& ectx)
1961 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1962 return getValue(ectx.fs.pressure(oilPhaseIdx)) -
1963 getValue(ectx.fs.pressure(waterPhaseIdx));
1965 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1966 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1967 getValue(ectx.fs.pressure(waterPhaseIdx));
1975 Entry{ScalarEntry{
"BGPC",
1976 [](
const Context& ectx)
1978 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1979 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1980 getValue(ectx.fs.pressure(oilPhaseIdx));
1982 else if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
1983 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1984 getValue(ectx.fs.pressure(waterPhaseIdx));
1992 Entry{ScalarEntry{
"BWPR",
1993 [](
const Context& ectx)
1995 return getValue(ectx.fs.pressure(waterPhaseIdx));
1999 Entry{ScalarEntry{
"BGPR",
2000 [](
const Context& ectx)
2002 return getValue(ectx.fs.pressure(gasPhaseIdx));
2006 Entry{PhaseEntry{std::array{
2007 std::array{
"BVWAT"sv,
"BVOIL"sv,
"BVGAS"sv},
2008 std::array{
"BWVIS"sv,
"BOVIS"sv,
"BGVIS"sv}
2010 [](
const unsigned phaseIdx,
const Context& ectx)
2012 return getValue(ectx.fs.viscosity(phaseIdx));
2016 Entry{PhaseEntry{std::array{
2017 std::array{
"BWDEN"sv,
"BODEN"sv,
"BGDEN"sv},
2018 std::array{
"BDENW"sv,
"BDENO"sv,
"BDENG"sv}
2020 [](
const unsigned phaseIdx,
const Context& ectx)
2022 return getValue(ectx.fs.density(phaseIdx));
2026 Entry{ScalarEntry{
"BFLOGI",
2028 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2030 const unsigned index = !flowsC.blockFlows().empty() ?
2031 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2032 FaceDir::ToIntersectionIndex(Dir::XPlus), gasCompIdx) : ectx.globalDofIdx;
2033 return flowsC.getFlow(index, Dir::XPlus, gasCompIdx);
2037 Entry{ScalarEntry{
"BFLOGI-",
2039 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2041 const unsigned index = !flowsC.blockFlows().empty() ?
2042 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2043 FaceDir::ToIntersectionIndex(Dir::XMinus), gasCompIdx) : ectx.globalDofIdx;
2044 return flowsC.getFlow(index, Dir::XMinus, gasCompIdx);
2048 Entry{ScalarEntry{
"BFLOGJ",
2050 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2052 const unsigned index = !flowsC.blockFlows().empty() ?
2053 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2054 FaceDir::ToIntersectionIndex(Dir::YPlus), gasCompIdx) : ectx.globalDofIdx;
2055 return flowsC.getFlow(index, Dir::YPlus, gasCompIdx);
2059 Entry{ScalarEntry{
"BFLOGJ-",
2061 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2063 const unsigned index = !flowsC.blockFlows().empty() ?
2064 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2065 FaceDir::ToIntersectionIndex(Dir::YMinus), gasCompIdx) : ectx.globalDofIdx;
2066 return flowsC.getFlow(index, Dir::YMinus, gasCompIdx);
2070 Entry{ScalarEntry{
"BFLOGK",
2072 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2074 const unsigned index = !flowsC.blockFlows().empty() ?
2075 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2076 FaceDir::ToIntersectionIndex(Dir::ZPlus), gasCompIdx) : ectx.globalDofIdx;
2077 return flowsC.getFlow(index, Dir::ZPlus, gasCompIdx);
2081 Entry{ScalarEntry{
"BFLOGK-",
2083 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2085 const unsigned index = !flowsC.blockFlows().empty() ?
2086 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2087 FaceDir::ToIntersectionIndex(Dir::ZMinus), gasCompIdx) : ectx.globalDofIdx;
2088 return flowsC.getFlow(index, Dir::ZMinus, gasCompIdx);
2092 Entry{ScalarEntry{
"BFLOOI",
2094 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2096 const unsigned index = !flowsC.blockFlows().empty() ?
2097 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2098 FaceDir::ToIntersectionIndex(Dir::XPlus), oilCompIdx) : ectx.globalDofIdx;
2099 return flowsC.getFlow(index, Dir::XPlus, oilCompIdx);
2103 Entry{ScalarEntry{
"BFLOOI-",
2105 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2107 const unsigned index = !flowsC.blockFlows().empty() ?
2108 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2109 FaceDir::ToIntersectionIndex(Dir::XMinus), oilCompIdx) : ectx.globalDofIdx;
2110 return flowsC.getFlow(index, Dir::XMinus, oilCompIdx);
2114 Entry{ScalarEntry{
"BFLOOJ",
2116 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2118 const unsigned index = !flowsC.blockFlows().empty() ?
2119 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2120 FaceDir::ToIntersectionIndex(Dir::YPlus), oilCompIdx) : ectx.globalDofIdx;
2121 return flowsC.getFlow(index, Dir::YPlus, oilCompIdx);
2125 Entry{ScalarEntry{
"BFLOOJ-",
2127 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2129 const unsigned index = !flowsC.blockFlows().empty() ?
2130 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2131 FaceDir::ToIntersectionIndex(Dir::YMinus), oilCompIdx) : ectx.globalDofIdx;
2132 return flowsC.getFlow(index, Dir::YMinus, oilCompIdx);
2136 Entry{ScalarEntry{
"BFLOOK",
2138 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2140 const unsigned index = !flowsC.blockFlows().empty() ?
2141 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2142 FaceDir::ToIntersectionIndex(Dir::ZPlus), oilCompIdx) : ectx.globalDofIdx;
2143 return flowsC.getFlow(index, Dir::ZPlus, oilCompIdx);
2147 Entry{ScalarEntry{
"BFLOOK-",
2149 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2151 const unsigned index = !flowsC.blockFlows().empty() ?
2152 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2153 FaceDir::ToIntersectionIndex(Dir::ZMinus), oilCompIdx) : ectx.globalDofIdx;
2154 return flowsC.getFlow(index, Dir::ZMinus, oilCompIdx);
2158 Entry{ScalarEntry{
"BFLOWI",
2160 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2162 const unsigned index = !flowsC.blockFlows().empty() ?
2163 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2164 FaceDir::ToIntersectionIndex(Dir::XPlus), waterCompIdx) : ectx.globalDofIdx;
2165 return flowsC.getFlow(index, Dir::XPlus, waterCompIdx);
2169 Entry{ScalarEntry{
"BFLOWI-",
2171 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2173 const unsigned index = !flowsC.blockFlows().empty() ?
2174 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2175 FaceDir::ToIntersectionIndex(Dir::XMinus), waterCompIdx) : ectx.globalDofIdx;
2176 return flowsC.getFlow(index, Dir::XMinus, waterCompIdx);
2180 Entry{ScalarEntry{
"BFLOWJ",
2182 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2184 const unsigned index = !flowsC.blockFlows().empty() ?
2185 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2186 FaceDir::ToIntersectionIndex(Dir::YPlus), waterCompIdx) : ectx.globalDofIdx;
2187 return flowsC.getFlow(index, Dir::YPlus, waterCompIdx);
2191 Entry{ScalarEntry{
"BFLOWJ-",
2193 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2195 const unsigned index = !flowsC.blockFlows().empty() ?
2196 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2197 FaceDir::ToIntersectionIndex(Dir::YMinus), waterCompIdx) : ectx.globalDofIdx;
2198 return flowsC.getFlow(index, Dir::YMinus, waterCompIdx);
2202 Entry{ScalarEntry{
"BFLOWK",
2204 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2206 const unsigned index = !flowsC.blockFlows().empty() ?
2207 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2208 FaceDir::ToIntersectionIndex(Dir::ZPlus), waterCompIdx) : ectx.globalDofIdx;
2209 return flowsC.getFlow(index, Dir::ZPlus, waterCompIdx);
2213 Entry{ScalarEntry{
"BFLOWK-",
2215 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2217 const unsigned index = !flowsC.blockFlows().empty() ?
2218 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2219 FaceDir::ToIntersectionIndex(Dir::ZMinus), waterCompIdx) : ectx.globalDofIdx;
2220 return flowsC.getFlow(index, Dir::ZMinus, waterCompIdx);
2224 Entry{ScalarEntry{
"BVELGI",
2226 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2228 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2229 FaceDir::ToIntersectionIndex(Dir::XPlus), gasCompIdx);
2230 return flowsC.getVelocity(index, Dir::XPlus, gasCompIdx);
2234 Entry{ScalarEntry{
"BVELGI-",
2236 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2238 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2239 FaceDir::ToIntersectionIndex(Dir::XMinus), gasCompIdx);
2240 return flowsC.getVelocity(index, Dir::XMinus, gasCompIdx);
2244 Entry{ScalarEntry{
"BVELGJ",
2246 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2248 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2249 FaceDir::ToIntersectionIndex(Dir::YPlus), gasCompIdx);
2250 return flowsC.getVelocity(index, Dir::YPlus, gasCompIdx);
2254 Entry{ScalarEntry{
"BVELGJ-",
2256 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2258 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2259 FaceDir::ToIntersectionIndex(Dir::YMinus), gasCompIdx);
2260 return flowsC.getVelocity(index, Dir::YMinus, gasCompIdx);
2264 Entry{ScalarEntry{
"BVELGK",
2266 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2268 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2269 FaceDir::ToIntersectionIndex(Dir::ZPlus), gasCompIdx);
2270 return flowsC.getVelocity(index, Dir::ZPlus, gasCompIdx);
2274 Entry{ScalarEntry{
"BVELGK-",
2276 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2278 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2279 FaceDir::ToIntersectionIndex(Dir::ZMinus), gasCompIdx);
2280 return flowsC.getVelocity(index, Dir::ZMinus, gasCompIdx);
2284 Entry{ScalarEntry{
"BVELOI",
2286 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2288 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2289 FaceDir::ToIntersectionIndex(Dir::XPlus), oilCompIdx);
2290 return flowsC.getVelocity(index, Dir::XPlus, oilCompIdx);
2294 Entry{ScalarEntry{
"BVELOI-",
2296 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2298 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2299 FaceDir::ToIntersectionIndex(Dir::XMinus), oilCompIdx);
2300 return flowsC.getVelocity(index, Dir::XMinus, oilCompIdx);
2304 Entry{ScalarEntry{
"BVELOJ",
2306 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2308 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2309 FaceDir::ToIntersectionIndex(Dir::YPlus), oilCompIdx);
2310 return flowsC.getVelocity(index, Dir::YPlus, oilCompIdx);
2314 Entry{ScalarEntry{
"BVELOJ-",
2316 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2318 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2319 FaceDir::ToIntersectionIndex(Dir::YMinus), oilCompIdx);
2320 return flowsC.getVelocity(index, Dir::YMinus, oilCompIdx);
2324 Entry{ScalarEntry{
"BVELOK",
2326 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2328 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2329 FaceDir::ToIntersectionIndex(Dir::ZPlus), oilCompIdx);
2330 return flowsC.getVelocity(index, Dir::ZPlus, oilCompIdx);
2334 Entry{ScalarEntry{
"BVELOK-",
2336 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2338 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2339 FaceDir::ToIntersectionIndex(Dir::ZMinus), oilCompIdx);
2340 return flowsC.getVelocity(index, Dir::ZMinus, oilCompIdx);
2344 Entry{ScalarEntry{
"BVELWI",
2346 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2348 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2349 FaceDir::ToIntersectionIndex(Dir::XPlus), waterCompIdx);
2350 return flowsC.getVelocity(index, Dir::XPlus, waterCompIdx);
2354 Entry{ScalarEntry{
"BVELWI-",
2356 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2358 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2359 FaceDir::ToIntersectionIndex(Dir::XMinus), waterCompIdx);
2360 return flowsC.getVelocity(index, Dir::XMinus, waterCompIdx);
2364 Entry{ScalarEntry{
"BVELWJ",
2366 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2368 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2369 FaceDir::ToIntersectionIndex(Dir::YPlus), waterCompIdx);
2370 return flowsC.getVelocity(index, Dir::YPlus, waterCompIdx);
2374 Entry{ScalarEntry{
"BVELWJ-",
2376 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2378 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2379 FaceDir::ToIntersectionIndex(Dir::YMinus), waterCompIdx);
2380 return flowsC.getVelocity(index, Dir::YMinus, waterCompIdx);
2384 Entry{ScalarEntry{
"BVELWK",
2386 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2388 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2389 FaceDir::ToIntersectionIndex(Dir::ZPlus), waterCompIdx);
2390 return flowsC.getVelocity(index, Dir::ZPlus, waterCompIdx);
2394 Entry{ScalarEntry{
"BVELWK-",
2396 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2398 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2399 FaceDir::ToIntersectionIndex(Dir::ZMinus), waterCompIdx);
2400 return flowsC.getVelocity(index, Dir::ZMinus, waterCompIdx);
2404 Entry{ScalarEntry{
"BRPV",
2405 [&model = this->simulator_.model()](
const Context& ectx)
2407 return getValue(ectx.intQuants.porosity()) *
2408 model.dofTotalVolume(ectx.globalDofIdx);
2412 Entry{PhaseEntry{std::array{
"BWPV"sv,
"BOPV"sv,
"BGPV"sv},
2413 [&model = this->simulator_.model()](
const unsigned phaseIdx,
2414 const Context& ectx)
2416 return getValue(ectx.fs.saturation(phaseIdx)) *
2417 getValue(ectx.intQuants.porosity()) *
2418 model.dofTotalVolume(ectx.globalDofIdx);
2422 Entry{ScalarEntry{
"BRS",
2423 [](
const Context& ectx)
2425 return getValue(ectx.fs.Rs());
2429 Entry{ScalarEntry{
"BRV",
2430 [](
const Context& ectx)
2432 return getValue(ectx.fs.Rv());
2436 Entry{ScalarEntry{
"BOIP",
2437 [&model = this->simulator_.model()](
const Context& ectx)
2439 return (getValue(ectx.fs.invB(oilPhaseIdx)) *
2440 getValue(ectx.fs.saturation(oilPhaseIdx)) +
2441 getValue(ectx.fs.Rv()) *
2442 getValue(ectx.fs.invB(gasPhaseIdx)) *
2443 getValue(ectx.fs.saturation(gasPhaseIdx))) *
2444 model.dofTotalVolume(ectx.globalDofIdx) *
2445 getValue(ectx.intQuants.porosity());
2449 Entry{ScalarEntry{
"BGIP",
2450 [&model = this->simulator_.model()](
const Context& ectx)
2452 Scalar result = getValue(ectx.fs.invB(gasPhaseIdx)) *
2453 getValue(ectx.fs.saturation(gasPhaseIdx));
2455 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2456 result += getValue(ectx.fs.Rs()) *
2457 getValue(ectx.fs.invB(oilPhaseIdx)) *
2458 getValue(ectx.fs.saturation(oilPhaseIdx));
2461 result += getValue(ectx.fs.Rsw()) *
2462 getValue(ectx.fs.invB(waterPhaseIdx)) *
2463 getValue(ectx.fs.saturation(waterPhaseIdx));
2467 model.dofTotalVolume(ectx.globalDofIdx) *
2468 getValue(ectx.intQuants.porosity());
2472 Entry{ScalarEntry{
"BWIP",
2473 [&model = this->simulator_.model()](
const Context& ectx)
2475 return getValue(ectx.fs.invB(waterPhaseIdx)) *
2476 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2477 model.dofTotalVolume(ectx.globalDofIdx) *
2478 getValue(ectx.intQuants.porosity());
2482 Entry{ScalarEntry{
"BOIPL",
2483 [&model = this->simulator_.model()](
const Context& ectx)
2485 return getValue(ectx.fs.invB(oilPhaseIdx)) *
2486 getValue(ectx.fs.saturation(oilPhaseIdx)) *
2487 model.dofTotalVolume(ectx.globalDofIdx) *
2488 getValue(ectx.intQuants.porosity());
2492 Entry{ScalarEntry{
"BGIPL",
2493 [&model = this->simulator_.model()](
const Context& ectx)
2496 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2497 result = getValue(ectx.fs.Rs()) *
2498 getValue(ectx.fs.invB(oilPhaseIdx)) *
2499 getValue(ectx.fs.saturation(oilPhaseIdx));
2502 result = getValue(ectx.fs.Rsw()) *
2503 getValue(ectx.fs.invB(waterPhaseIdx)) *
2504 getValue(ectx.fs.saturation(waterPhaseIdx));
2507 model.dofTotalVolume(ectx.globalDofIdx) *
2508 getValue(ectx.intQuants.porosity());
2512 Entry{ScalarEntry{
"BGIPG",
2513 [&model = this->simulator_.model()](
const Context& ectx)
2515 return getValue(ectx.fs.invB(gasPhaseIdx)) *
2516 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2517 model.dofTotalVolume(ectx.globalDofIdx) *
2518 getValue(ectx.intQuants.porosity());
2522 Entry{ScalarEntry{
"BOIPG",
2523 [&model = this->simulator_.model()](
const Context& ectx)
2525 return getValue(ectx.fs.Rv()) *
2526 getValue(ectx.fs.invB(gasPhaseIdx)) *
2527 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2528 model.dofTotalVolume(ectx.globalDofIdx) *
2529 getValue(ectx.intQuants.porosity());
2533 Entry{PhaseEntry{std::array{
"BPPW"sv,
"BPPO"sv,
"BPPG"sv},
2534 [&simConfig = this->
eclState_.getSimulationConfig(),
2535 &grav = this->simulator_.problem().gravity(),
2537 &problem = this->simulator_.problem(),
2538 ®ions = this->
regions_](
const unsigned phaseIdx,
const Context& ectx)
2541 phase.ix = phaseIdx;
2550 const auto datum = simConfig.datumDepths()(regions[
"FIPNUM"][ectx.dofIdx] - 1);
2553 const auto region = RegionPhasePoreVolAverage::Region {
2554 ectx.elemCtx.primaryVars(ectx.dofIdx, 0).pvtRegionIndex() + 1
2557 const auto density = regionAvgDensity->value(
"PVTNUM", phase, region);
2559 const auto press = getValue(ectx.fs.pressure(phase.ix));
2560 const auto dz = problem.dofCenterDepth(ectx.globalDofIdx) - datum;
2561 return press - density*dz*grav[GridView::dimensionworld - 1];
2565 Entry{ScalarEntry{
"BAMIP",
2566 [&model = this->simulator_.model()](
const Context& ectx)
2568 const Scalar rhoW = FluidSystem::referenceDensity(waterPhaseIdx,
2569 ectx.intQuants.pvtRegionIndex());
2570 return getValue(ectx.fs.invB(waterPhaseIdx)) *
2571 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2573 model.dofTotalVolume(ectx.globalDofIdx) *
2574 getValue(ectx.intQuants.porosity());
2578 Entry{ScalarEntry{
"BMMIP",
2579 [&model = this->simulator_.model()](
const Context& ectx)
2581 return getValue(ectx.intQuants.microbialConcentration()) *
2582 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2583 getValue(ectx.intQuants.porosity()) *
2584 model.dofTotalVolume(ectx.globalDofIdx);
2588 Entry{ScalarEntry{
"BMOIP",
2589 [&model = this->simulator_.model()](
const Context& ectx)
2591 return getValue(ectx.intQuants.oxygenConcentration()) *
2592 getValue(ectx.intQuants.porosity()) *
2593 model.dofTotalVolume(ectx.globalDofIdx);
2597 Entry{ScalarEntry{
"BMUIP",
2598 [&model = this->simulator_.model()](
const Context& ectx)
2600 return getValue(ectx.intQuants.ureaConcentration()) *
2601 getValue(ectx.intQuants.porosity()) *
2602 model.dofTotalVolume(ectx.globalDofIdx) * 1;
2606 Entry{ScalarEntry{
"BMBIP",
2607 [&model = this->simulator_.model()](
const Context& ectx)
2609 return model.dofTotalVolume(ectx.globalDofIdx) *
2610 getValue(ectx.intQuants.biofilmMass());
2614 Entry{ScalarEntry{
"BMCIP",
2615 [&model = this->simulator_.model()](
const Context& ectx)
2617 return model.dofTotalVolume(ectx.globalDofIdx) *
2618 getValue(ectx.intQuants.calciteMass());
2622 Entry{ScalarEntry{
"BGMIP",
2623 [&model = this->simulator_.model()](
const Context& ectx)
2625 Scalar result = getValue(ectx.fs.invB(gasPhaseIdx)) *
2626 getValue(ectx.fs.saturation(gasPhaseIdx));
2628 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2629 result += getValue(ectx.fs.Rs()) *
2630 getValue(ectx.fs.invB(oilPhaseIdx)) *
2631 getValue(ectx.fs.saturation(oilPhaseIdx));
2634 result += getValue(ectx.fs.Rsw()) *
2635 getValue(ectx.fs.invB(waterPhaseIdx)) *
2636 getValue(ectx.fs.saturation(waterPhaseIdx));
2638 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2639 ectx.intQuants.pvtRegionIndex());
2641 model.dofTotalVolume(ectx.globalDofIdx) *
2642 getValue(ectx.intQuants.porosity()) *
2647 Entry{ScalarEntry{
"BGMGP",
2648 [&model = this->simulator_.model()](
const Context& ectx)
2650 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2651 ectx.intQuants.pvtRegionIndex());
2652 return getValue(ectx.fs.invB(gasPhaseIdx)) *
2653 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2654 model.dofTotalVolume(ectx.globalDofIdx) *
2655 getValue(ectx.intQuants.porosity()) *
2660 Entry{ScalarEntry{
"BGMDS",
2661 [&model = this->simulator_.model()](
const Context& ectx)
2664 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2665 result = getValue(ectx.fs.Rs()) *
2666 getValue(ectx.fs.invB(oilPhaseIdx)) *
2667 getValue(ectx.fs.saturation(oilPhaseIdx));
2670 result = getValue(ectx.fs.Rsw()) *
2671 getValue(ectx.fs.invB(waterPhaseIdx)) *
2672 getValue(ectx.fs.saturation(waterPhaseIdx));
2674 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2675 ectx.intQuants.pvtRegionIndex());
2677 model.dofTotalVolume(ectx.globalDofIdx) *
2678 getValue(ectx.intQuants.porosity()) *
2683 Entry{ScalarEntry{
"BGMST",
2684 [&model = this->simulator_.model(),
2685 &problem = this->simulator_.problem()](
const Context& ectx)
2687 const auto& scaledDrainageInfo = problem.materialLawManager()
2688 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2689 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2690 Scalar strandedGas = scaledDrainageInfo.Sgcr;
2691 if (problem.materialLawManager()->enableHysteresis()) {
2692 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2693 const Scalar krg = getValue(ectx.intQuants.relativePermeability(gasPhaseIdx));
2694 strandedGas = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
2696 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2697 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2698 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2699 return (1.0 - xgW) *
2700 model.dofTotalVolume(ectx.globalDofIdx) *
2701 getValue(ectx.intQuants.porosity()) *
2702 getValue(ectx.fs.density(gasPhaseIdx)) *
2703 std::min(strandedGas, sg);
2707 Entry{ScalarEntry{
"BGMUS",
2708 [&model = this->simulator_.model(),
2709 &problem = this->simulator_.problem()](
const Context& ectx)
2711 const auto& scaledDrainageInfo = problem.materialLawManager()
2712 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2713 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2714 Scalar strandedGas = scaledDrainageInfo.Sgcr;
2715 if (problem.materialLawManager()->enableHysteresis()) {
2716 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2717 const Scalar krg = getValue(ectx.intQuants.relativePermeability(gasPhaseIdx));
2718 strandedGas = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
2720 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2721 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2722 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2723 return (1.0 - xgW) *
2724 model.dofTotalVolume(ectx.globalDofIdx) *
2725 getValue(ectx.intQuants.porosity()) *
2726 getValue(ectx.fs.density(gasPhaseIdx)) *
2727 std::max(Scalar{0.0}, sg - strandedGas);
2731 Entry{ScalarEntry{
"BGMTR",
2732 [&model = this->simulator_.model(),
2733 &problem = this->simulator_.problem()](
const Context& ectx)
2735 const auto& scaledDrainageInfo = problem.materialLawManager()
2736 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2737 Scalar trappedGas = scaledDrainageInfo.Sgcr;
2738 if (problem.materialLawManager()->enableHysteresis()) {
2739 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2740 trappedGas = MaterialLaw::trappedGasSaturation(matParams,
true);
2742 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2743 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2744 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2745 return (1.0 - xgW) *
2746 model.dofTotalVolume(ectx.globalDofIdx) *
2747 getValue(ectx.intQuants.porosity()) *
2748 getValue(ectx.fs.density(gasPhaseIdx)) *
2749 std::min(trappedGas, getValue(ectx.fs.saturation(gasPhaseIdx)));
2753 Entry{ScalarEntry{
"BGMMO",
2754 [&model = this->simulator_.model(),
2755 &problem = this->simulator_.problem()](
const Context& ectx)
2757 const auto& scaledDrainageInfo = problem.materialLawManager()
2758 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2759 Scalar trappedGas = scaledDrainageInfo.Sgcr;
2760 if (problem.materialLawManager()->enableHysteresis()) {
2761 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2762 trappedGas = MaterialLaw::trappedGasSaturation(matParams,
true);
2764 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2765 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2766 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2767 return (1.0 - xgW) *
2768 model.dofTotalVolume(ectx.globalDofIdx) *
2769 getValue(ectx.intQuants.porosity()) *
2770 getValue(ectx.fs.density(gasPhaseIdx)) *
2771 std::max(Scalar{0.0}, getValue(ectx.fs.saturation(gasPhaseIdx)) - trappedGas);
2775 Entry{ScalarEntry{
"BGKTR",
2776 [&model = this->simulator_.model(),
2777 &problem = this->simulator_.problem()](
const Context& ectx)
2779 const auto& scaledDrainageInfo = problem.materialLawManager()
2780 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2781 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2782 Scalar sgcr = scaledDrainageInfo.Sgcr;
2783 if (problem.materialLawManager()->enableHysteresis()) {
2784 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2785 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2791 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2792 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2793 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2794 return (1.0 - xgW) *
2795 model.dofTotalVolume(ectx.globalDofIdx) *
2796 getValue(ectx.intQuants.porosity()) *
2797 getValue(ectx.fs.density(gasPhaseIdx)) *
2798 getValue(ectx.fs.saturation(gasPhaseIdx));
2803 Entry{ScalarEntry{
"BGKMO",
2804 [&model = this->simulator_.model(),
2805 &problem = this->simulator_.problem()](
const Context& ectx)
2807 const auto& scaledDrainageInfo = problem.materialLawManager()
2808 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2809 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2810 Scalar sgcr = scaledDrainageInfo.Sgcr;
2811 if (problem.materialLawManager()->enableHysteresis()) {
2812 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2813 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2819 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2820 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2821 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2822 return (1.0 - xgW) *
2823 model.dofTotalVolume(ectx.globalDofIdx) *
2824 getValue(ectx.intQuants.porosity()) *
2825 getValue(ectx.fs.density(gasPhaseIdx)) *
2826 getValue(ectx.fs.saturation(gasPhaseIdx));
2831 Entry{ScalarEntry{
"BGCDI",
2832 [&model = this->simulator_.model(),
2833 &problem = this->simulator_.problem()](
const Context& ectx)
2835 const auto& scaledDrainageInfo = problem.materialLawManager()
2836 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2837 Scalar sgcr = scaledDrainageInfo.Sgcr;
2838 if (problem.materialLawManager()->enableHysteresis()) {
2839 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2840 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2842 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2843 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2844 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2845 return (1.0 - xgW) *
2846 model.dofTotalVolume(ectx.globalDofIdx) *
2847 getValue(ectx.intQuants.porosity()) *
2848 getValue(ectx.fs.density(gasPhaseIdx)) *
2849 std::min(sgcr, getValue(ectx.fs.saturation(gasPhaseIdx))) /
2850 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
2854 Entry{ScalarEntry{
"BGCDM",
2855 [&model = this->simulator_.model(),
2856 &problem = this->simulator_.problem()](
const Context& ectx)
2858 const auto& scaledDrainageInfo = problem.materialLawManager()
2859 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2860 Scalar sgcr = scaledDrainageInfo.Sgcr;
2861 if (problem.materialLawManager()->enableHysteresis()) {
2862 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2863 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2865 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2866 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2867 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2868 return (1.0 - xgW) *
2869 model.dofTotalVolume(ectx.globalDofIdx) *
2870 getValue(ectx.intQuants.porosity()) *
2871 getValue(ectx.fs.density(gasPhaseIdx)) *
2872 std::max(Scalar{0.0}, getValue(ectx.fs.saturation(gasPhaseIdx)) - sgcr) /
2873 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
2877 Entry{ScalarEntry{
"BGKDI",
2878 [&model = this->simulator_.model(),
2879 &problem = this->simulator_.problem()](
const Context& ectx)
2881 const auto& scaledDrainageInfo = problem.materialLawManager()
2882 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2883 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2884 Scalar sgcr = scaledDrainageInfo.Sgcr;
2885 if (problem.materialLawManager()->enableHysteresis()) {
2886 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2887 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2893 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2894 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2895 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2896 return (1.0 - xgW) *
2897 model.dofTotalVolume(ectx.globalDofIdx) *
2898 getValue(ectx.intQuants.porosity()) *
2899 getValue(ectx.fs.density(gasPhaseIdx)) *
2900 getValue(ectx.fs.saturation(gasPhaseIdx)) /
2901 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
2906 Entry{ScalarEntry{
"BGKDM",
2907 [&model = this->simulator_.model(),
2908 &problem = this->simulator_.problem()](
const Context& ectx)
2910 const auto& scaledDrainageInfo = problem.materialLawManager()
2911 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2912 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2913 Scalar sgcr = scaledDrainageInfo.Sgcr;
2914 if (problem.materialLawManager()->enableHysteresis()) {
2915 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2916 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2922 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2923 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2924 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2925 return (1.0 - xgW) *
2926 model.dofTotalVolume(ectx.globalDofIdx) *
2927 getValue(ectx.intQuants.porosity()) *
2928 getValue(ectx.fs.density(gasPhaseIdx)) *
2929 getValue(ectx.fs.saturation(gasPhaseIdx)) /
2930 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
2935 Entry{ScalarEntry{
"BWCD",
2936 [&model = this->simulator_.model()](
const Context& ectx)
2939 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2940 result = getValue(ectx.fs.Rs()) *
2941 getValue(ectx.fs.invB(oilPhaseIdx)) *
2942 getValue(ectx.fs.saturation(oilPhaseIdx));
2945 result = getValue(ectx.fs.Rsw()) *
2946 getValue(ectx.fs.invB(waterPhaseIdx)) *
2947 getValue(ectx.fs.saturation(waterPhaseIdx));
2949 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2950 ectx.intQuants.pvtRegionIndex());
2952 model.dofTotalVolume(ectx.globalDofIdx) *
2953 getValue(ectx.intQuants.porosity()) *
2955 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
2959 Entry{ScalarEntry{
"BWIPG",
2960 [&model = this->simulator_.model()](
const Context& ectx)
2962 Scalar result = 0.0;
2963 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
2964 result = getValue(ectx.fs.Rvw()) *
2965 getValue(ectx.fs.invB(gasPhaseIdx)) *
2966 getValue(ectx.fs.saturation(gasPhaseIdx));
2969 model.dofTotalVolume(ectx.globalDofIdx) *
2970 getValue(ectx.intQuants.porosity());
2974 Entry{ScalarEntry{
"BWIPL",
2975 [&model = this->simulator_.model()](
const Context& ectx)
2977 return getValue(ectx.fs.invB(waterPhaseIdx)) *
2978 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2979 model.dofTotalVolume(ectx.globalDofIdx) *
2980 getValue(ectx.intQuants.porosity());
2989 if (reportStepNum > 0 && !isSubStep) {
2991 const auto& rpt = this->
schedule_[reportStepNum - 1].rpt_config.get();
2992 if (rpt.contains(
"WELLS") && rpt.at(
"WELLS") > 1) {
2994 [&c = this->collectOnIORank_](
const int idx)
2995 {
return c.isCartIdxOnThisRank(idx); });
2997 const auto extraHandlers = std::array{
3006 const Simulator& simulator_;
3007 const CollectDataOnIORankType& collectOnIORank_;
3008 std::vector<typename Extractor::Entry> extractors_;
Contains the classes required to extend the black-oil model by energy.
Declares the properties required by the black oil model.
Definition: CollectDataOnIORank.hpp:56
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 assignPoreVolume(const unsigned globalDofIdx, const Scalar value)
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
const std::vector< Scalar > & get(const Inplace::Phase phase) 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: GenericOutputBlackoilModule.hpp:77
std::map< std::pair< std::string, int >, double > blockData_
Definition: GenericOutputBlackoilModule.hpp:464
std::array< ScalarBuffer, numPhases > relativePermeability_
Definition: GenericOutputBlackoilModule.hpp:453
const Inplace * initialInplace() const
Definition: GenericOutputBlackoilModule.hpp:250
ScalarBuffer fluidPressure_
Definition: GenericOutputBlackoilModule.hpp:406
std::array< ScalarBuffer, numPhases > density_
Definition: GenericOutputBlackoilModule.hpp:451
ScalarBuffer saturatedOilFormationVolumeFactor_
Definition: GenericOutputBlackoilModule.hpp:438
ScalarBuffer overburdenPressure_
Definition: GenericOutputBlackoilModule.hpp:412
ScalarBuffer gasDissolutionFactorInWater_
Definition: GenericOutputBlackoilModule.hpp:432
const EclipseState & eclState_
Definition: GenericOutputBlackoilModule.hpp:365
ScalarBuffer swmin_
Definition: GenericOutputBlackoilModule.hpp:428
ScalarBuffer rockCompPorvMultiplier_
Definition: GenericOutputBlackoilModule.hpp:436
RFTContainer< GetPropType< TypeTag, Properties::FluidSystem > > rftC_
Definition: GenericOutputBlackoilModule.hpp:461
bool computeFip_
Definition: GenericOutputBlackoilModule.hpp:388
ScalarBuffer dewPointPressure_
Definition: GenericOutputBlackoilModule.hpp:435
LogOutputHelper< Scalar > logOutput_
Definition: GenericOutputBlackoilModule.hpp:372
std::vector< int > failedCellsPb_
Definition: GenericOutputBlackoilModule.hpp:397
ScalarBuffer permFact_
Definition: GenericOutputBlackoilModule.hpp:421
ScalarBuffer rsw_
Definition: GenericOutputBlackoilModule.hpp:409
ScalarBuffer pcog_
Definition: GenericOutputBlackoilModule.hpp:444
std::optional< RegionPhasePoreVolAverage > regionAvgDensity_
Definition: GenericOutputBlackoilModule.hpp:472
std::array< ScalarBuffer, numPhases > invB_
Definition: GenericOutputBlackoilModule.hpp:450
ScalarBuffer pSalt_
Definition: GenericOutputBlackoilModule.hpp:420
ScalarBuffer cFoam_
Definition: GenericOutputBlackoilModule.hpp:418
ScalarBuffer bubblePointPressure_
Definition: GenericOutputBlackoilModule.hpp:434
ScalarBuffer temperature_
Definition: GenericOutputBlackoilModule.hpp:407
ScalarBuffer ppcw_
Definition: GenericOutputBlackoilModule.hpp:429
FIPContainer< GetPropType< TypeTag, Properties::FluidSystem > > fipC_
Definition: GenericOutputBlackoilModule.hpp:390
ScalarBuffer rockCompTransMultiplier_
Definition: GenericOutputBlackoilModule.hpp:439
MechContainer< Scalar > mech_
Definition: GenericOutputBlackoilModule.hpp:447
ScalarBuffer dynamicPoreVolume_
Definition: GenericOutputBlackoilModule.hpp:404
ScalarBuffer minimumOilPressure_
Definition: GenericOutputBlackoilModule.hpp:437
ScalarBuffer gasFormationVolumeFactor_
Definition: GenericOutputBlackoilModule.hpp:400
std::array< ScalarBuffer, numPhases > residual_
Definition: GenericOutputBlackoilModule.hpp:457
void doAllocBuffers(unsigned bufferSize, unsigned reportStepNum, const bool substep, const bool log, const bool isRestart, const EclHysteresisConfig *hysteresisConfig, unsigned numOutputNnc=0, std::map< std::string, int > rstKeywords={})
ScalarBuffer shmax_
Definition: GenericOutputBlackoilModule.hpp:426
BioeffectsContainer< Scalar > bioeffectsC_
Definition: GenericOutputBlackoilModule.hpp:440
const Schedule & schedule_
Definition: GenericOutputBlackoilModule.hpp:366
FlowsContainer< GetPropType< TypeTag, Properties::FluidSystem > > flowsC_
Definition: GenericOutputBlackoilModule.hpp:459
ExtboContainer< Scalar > extboC_
Definition: GenericOutputBlackoilModule.hpp:422
void setupExtraBlockData(const std::size_t reportStepNum, std::function< bool(int)> isCartIdxOnThisRank)
ScalarBuffer oilSaturationPressure_
Definition: GenericOutputBlackoilModule.hpp:413
InterRegFlowMap interRegionFlows_
Definition: GenericOutputBlackoilModule.hpp:371
ScalarBuffer pcgw_
Definition: GenericOutputBlackoilModule.hpp:442
ScalarBuffer cPolymer_
Definition: GenericOutputBlackoilModule.hpp:417
void setupBlockData(std::function< bool(int)> isCartIdxOnThisRank)
ScalarBuffer rvw_
Definition: GenericOutputBlackoilModule.hpp:411
std::array< ScalarBuffer, numPhases > saturation_
Definition: GenericOutputBlackoilModule.hpp:449
std::unordered_map< std::string, std::vector< int > > regions_
Definition: GenericOutputBlackoilModule.hpp:391
ScalarBuffer rPorV_
Definition: GenericOutputBlackoilModule.hpp:405
ScalarBuffer oilVaporizationFactor_
Definition: GenericOutputBlackoilModule.hpp:431
std::vector< int > failedCellsPd_
Definition: GenericOutputBlackoilModule.hpp:398
ScalarBuffer rs_
Definition: GenericOutputBlackoilModule.hpp:408
ScalarBuffer drsdtcon_
Definition: GenericOutputBlackoilModule.hpp:414
ScalarBuffer sSol_
Definition: GenericOutputBlackoilModule.hpp:415
std::map< std::pair< std::string, int >, double > extraBlockData_
Definition: GenericOutputBlackoilModule.hpp:467
ScalarBuffer pressureTimesPoreVolume_
Definition: GenericOutputBlackoilModule.hpp:402
ScalarBuffer gasDissolutionFactor_
Definition: GenericOutputBlackoilModule.hpp:430
std::array< ScalarBuffer, numPhases > viscosity_
Definition: GenericOutputBlackoilModule.hpp:452
bool forceDisableFipOutput_
Definition: GenericOutputBlackoilModule.hpp:386
ScalarBuffer soMax_
Definition: GenericOutputBlackoilModule.hpp:423
ScalarBuffer sgmax_
Definition: GenericOutputBlackoilModule.hpp:425
ScalarBuffer somin_
Definition: GenericOutputBlackoilModule.hpp:427
ScalarBuffer hydrocarbonPoreVolume_
Definition: GenericOutputBlackoilModule.hpp:401
ScalarBuffer waterVaporizationFactor_
Definition: GenericOutputBlackoilModule.hpp:433
ScalarBuffer cSalt_
Definition: GenericOutputBlackoilModule.hpp:419
TracerContainer< GetPropType< TypeTag, Properties::FluidSystem > > tracerC_
Definition: GenericOutputBlackoilModule.hpp:455
ScalarBuffer rv_
Definition: GenericOutputBlackoilModule.hpp:410
ScalarBuffer pcow_
Definition: GenericOutputBlackoilModule.hpp:443
ScalarBuffer swMax_
Definition: GenericOutputBlackoilModule.hpp:424
CO2H2Container< Scalar > CO2H2C_
Definition: GenericOutputBlackoilModule.hpp:441
ScalarBuffer pressureTimesHydrocarbonVolume_
Definition: GenericOutputBlackoilModule.hpp:403
ScalarBuffer rswSol_
Definition: GenericOutputBlackoilModule.hpp:416
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:86
void processElement(const ElementContext &elemCtx)
Modify the internal buffers according to the intensive quanties relevant for an element.
Definition: OutputBlackoilModule.hpp:241
void initializeFluxData()
Prepare for capturing connection fluxes, particularly to account for inter-region flows.
Definition: OutputBlackoilModule.hpp:485
void setupExtractors(const bool isSubStep, const int reportStepNum)
Setup list of active element-level data extractors.
Definition: OutputBlackoilModule.hpp:222
void allocBuffers(const unsigned bufferSize, const unsigned reportStepNum, const bool substep, const bool log, const bool isRestart)
Allocate memory for the scalar fields we would like to write to ECL output files.
Definition: OutputBlackoilModule.hpp:200
void processFluxes(const ElementContext &elemCtx, ActiveIndex &&activeIndex, CartesianIndex &&cartesianIndex)
Capture connection fluxes, particularly to account for inter-region flows.
Definition: OutputBlackoilModule.hpp:448
void clearExtractors()
Clear list of active element-level data extractors.
Definition: OutputBlackoilModule.hpp:230
void outputFipAndResvLogToCSV(const std::size_t reportStepNum, const bool substep, const Parallel::Communication &comm)
Definition: OutputBlackoilModule.hpp:382
void assignToFluidState(FluidState &fs, unsigned elemIdx) const
Definition: OutputBlackoilModule.hpp:509
void initHysteresisParams(Simulator &simulator, unsigned elemIdx) const
Definition: OutputBlackoilModule.hpp:561
void updateFluidInPlace(const ElementContext &elemCtx)
Definition: OutputBlackoilModule.hpp:626
OutputBlackOilModule(const Simulator &simulator, const SummaryConfig &smryCfg, const CollectDataOnIORankType &collectOnIORank)
Definition: OutputBlackoilModule.hpp:134
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:331
const InterRegFlowMap & getInterRegFlows() const
Get read-only access to collection of inter-region flows.
Definition: OutputBlackoilModule.hpp:503
void processElementBlockData(const ElementContext &elemCtx)
Definition: OutputBlackoilModule.hpp:287
void finalizeFluxData()
Finalize capturing connection fluxes.
Definition: OutputBlackoilModule.hpp:495
void updateFluidInPlace(const unsigned globalDofIdx, const IntensiveQuantities &intQuants, const double totVolume)
Definition: OutputBlackoilModule.hpp:633
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:156
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.
Minimal characteristics of a cell from a simulation grid.
Definition: InterRegFlows.hpp:50