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 enum { enableEnergy = getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::FullyImplicitThermal };
118 enum { enableTemperature = getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::ConstantTemperature };
120 enum { enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>() };
121 enum { enableMICP = Indices::enableMICP };
122 enum { enableVapwat = getPropValue<TypeTag, Properties::EnableVapwat>() };
123 enum { enableDisgasInWater = getPropValue<TypeTag, Properties::EnableDisgasInWater>() };
124 enum { enableDissolvedGas = Indices::compositionSwitchIdx >= 0 };
126 template<
class VectorType>
127 static Scalar value_or_zero(
int idx,
const VectorType& v)
132 return v.empty() ? 0.0 : v[idx];
137 const SummaryConfig& smryCfg,
139 :
BaseType(simulator.vanguard().eclState(),
140 simulator.vanguard().schedule(),
142 simulator.vanguard().summaryState(),
144 [this](const int idx)
145 {
return simulator_.problem().eclWriter().collectOnIORank().localIdxToGlobalIdx(idx); },
146 simulator.vanguard().grid().comm(),
147 getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::FullyImplicitThermal,
148 getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::ConstantTemperature,
149 getPropValue<TypeTag, Properties::EnableMech>(),
150 getPropValue<TypeTag, Properties::EnableSolvent>(),
151 getPropValue<TypeTag, Properties::EnablePolymer>(),
152 getPropValue<TypeTag, Properties::EnableFoam>(),
153 getPropValue<TypeTag, Properties::EnableBrine>(),
154 getPropValue<TypeTag, Properties::EnableSaltPrecipitation>(),
155 getPropValue<TypeTag, Properties::EnableExtbo>(),
156 getPropValue<TypeTag, Properties::EnableBioeffects>())
157 , simulator_(simulator)
158 , collectOnIORank_(collectOnIORank)
160 for (
auto& region_pair : this->
regions_) {
161 this->createLocalRegion_(region_pair.second);
164 auto isCartIdxOnThisRank = [&collectOnIORank](
const int idx) {
165 return collectOnIORank.isCartIdxOnThisRank(idx);
170 if (! Parameters::Get<Parameters::OwnerCellsFirst>()) {
171 const std::string msg =
"The output code does not support --owner-cells-first=false.";
172 if (collectOnIORank.isIORank()) {
175 OPM_THROW_NOLOG(std::runtime_error, msg);
178 if (smryCfg.match(
"[FB]PP[OGW]") || smryCfg.match(
"RPP[OGW]*")) {
179 auto rset = this->
eclState_.fieldProps().fip_regions();
180 rset.push_back(
"PVTNUM");
186 .emplace(this->simulator_.gridView().comm(),
187 FluidSystem::numPhases, rset,
188 [fp = std::cref(this->eclState_.fieldProps())]
189 (
const std::string& rsetName) ->
decltype(
auto)
190 { return fp.get().get_int(rsetName); });
200 const unsigned reportStepNum,
203 const bool isRestart)
209 const auto& problem = this->simulator_.problem();
216 &problem.materialLawManager()->hysteresisConfig(),
217 problem.eclWriter().getOutputNnc().size());
222 const int reportStepNum)
224 this->setupElementExtractors_();
225 this->setupBlockExtractors_(isSubStep, reportStepNum);
231 this->extractors_.clear();
232 this->blockExtractors_.clear();
233 this->extraBlockExtractors_.clear();
247 if (this->extractors_.empty()) {
251 const auto& matLawManager = simulator_.problem().materialLawManager();
254 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
255 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
256 const auto& fs = intQuants.fluidState();
259 elemCtx.globalSpaceIndex(dofIdx, 0),
260 elemCtx.primaryVars(dofIdx, 0).pvtRegionIndex(),
267 if (matLawManager->enableHysteresis()) {
268 if (FluidSystem::phaseIsActive(oilPhaseIdx) && FluidSystem::phaseIsActive(waterPhaseIdx)) {
269 matLawManager->oilWaterHysteresisParams(hysterParams.
somax,
274 if (FluidSystem::phaseIsActive(oilPhaseIdx) && FluidSystem::phaseIsActive(gasPhaseIdx)) {
275 matLawManager->gasOilHysteresisParams(hysterParams.
sgmax,
293 if (this->blockExtractors_.empty() && this->extraBlockExtractors_.empty()) {
297 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
299 const auto globalDofIdx = elemCtx.globalSpaceIndex(dofIdx, 0);
300 const auto cartesianIdx = elemCtx.simulator().vanguard().cartesianIndex(globalDofIdx);
302 const auto be_it = this->blockExtractors_.find(cartesianIdx);
303 const auto bee_it = this->extraBlockExtractors_.find(cartesianIdx);
304 if (be_it == this->blockExtractors_.end() &&
305 bee_it == this->extraBlockExtractors_.end())
310 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
311 const auto& fs = intQuants.fluidState();
321 if (be_it != this->blockExtractors_.end()) {
324 if (bee_it != this->extraBlockExtractors_.end()) {
331 const std::size_t reportStepNum,
333 boost::posix_time::ptime currentDate,
338 if (comm.rank() != 0) {
343 std::unique_ptr<FIPConfig> fipSched;
344 if (reportStepNum > 0) {
345 const auto& rpt = this->
schedule_[reportStepNum-1].rpt_config.get();
346 fipSched = std::make_unique<FIPConfig>(rpt);
348 const FIPConfig& fipc = reportStepNum == 0 ? this->
eclState_.getEclipseConfig().fip()
353 this->
logOutput_.timeStamp(
"BALANCE", elapsed, reportStepNum, currentDate);
356 this->
logOutput_.fip(inplace, initial_inplace,
"");
358 if (fipc.output(FIPConfig::OutputField::FIPNUM)) {
359 this->
logOutput_.fip(inplace, initial_inplace,
"FIPNUM");
361 if (fipc.output(FIPConfig::OutputField::RESV))
365 if (fipc.output(FIPConfig::OutputField::FIP)) {
366 for (
const auto& reg : this->regions_) {
367 if (reg.first !=
"FIPNUM") {
368 std::ostringstream ss;
369 ss <<
"BAL" << reg.first.substr(3);
370 this->
logOutput_.timeStamp(ss.str(), elapsed, reportStepNum, currentDate);
371 this->
logOutput_.fip(inplace, initial_inplace, reg.first);
373 if (fipc.output(FIPConfig::OutputField::RESV))
385 if (comm.rank() != 0) {
389 if ((reportStepNum == 0) && (!substep) &&
390 (this->
schedule_.initialReportConfiguration().has_value()) &&
391 (this->schedule_.initialReportConfiguration()->contains(
"CSVFIP"))) {
393 std::ostringstream csv_stream;
399 this->
logOutput_.fip_csv(csv_stream, initial_inplace,
"FIPNUM");
401 for (
const auto& reg : this->regions_) {
402 if (reg.first !=
"FIPNUM") {
403 this->
logOutput_.fip_csv(csv_stream, initial_inplace, reg.first);
407 const IOConfig& io = this->
eclState_.getIOConfig();
408 auto csv_fname = io.getOutputDir() +
"/" + io.getBaseName() +
".CSV";
410 std::ofstream outputFile(csv_fname);
412 outputFile << csv_stream.str();
446 template <
class ActiveIndex,
class CartesianIndex>
448 ActiveIndex&& activeIndex,
449 CartesianIndex&& cartesianIndex)
452 const auto identifyCell = [&activeIndex, &cartesianIndex](
const Element& elem)
455 const auto cellIndex = activeIndex(elem);
458 static_cast<int>(cellIndex),
459 cartesianIndex(cellIndex),
460 elem.partitionType() == Dune::InteriorEntity
464 const auto timeIdx = 0u;
465 const auto& stencil = elemCtx.stencil(timeIdx);
466 const auto numInteriorFaces = elemCtx.numInteriorFaces(timeIdx);
468 for (
auto scvfIdx = 0 * numInteriorFaces; scvfIdx < numInteriorFaces; ++scvfIdx) {
469 const auto& face = stencil.interiorFace(scvfIdx);
470 const auto left = identifyCell(stencil.element(face.interiorIndex()));
471 const auto right = identifyCell(stencil.element(face.exteriorIndex()));
473 const auto rates = this->
474 getComponentSurfaceRates(elemCtx, face.area(), scvfIdx, timeIdx);
507 template <
class Flu
idState>
510 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
514 fs.setSaturation(phaseIdx, this->
saturation_[phaseIdx][elemIdx]);
520 std::array<Scalar, numPhases> pc = {0};
521 const MaterialLawParams& matParams = simulator_.problem().materialLawParams(elemIdx);
522 MaterialLaw::capillaryPressures(pc, matParams, fs);
524 Valgrind::CheckDefined(pc);
526 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
527 if (!FluidSystem::phaseIsActive(phaseIdx))
530 if (Indices::oilEnabled)
531 fs.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[oilPhaseIdx]));
532 else if (Indices::gasEnabled)
533 fs.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[gasPhaseIdx]));
534 else if (Indices::waterEnabled)
536 fs.setPressure(phaseIdx, pressure);
540 if constexpr (enableEnergy || enableTemperature) {
542 fs.setTemperature(this->temperature_[elemIdx]);
544 if constexpr (enableDissolvedGas) {
545 if (!this->
rs_.empty())
546 fs.setRs(this->rs_[elemIdx]);
547 if (!this->
rv_.empty())
548 fs.setRv(this->rv_[elemIdx]);
550 if constexpr (enableDisgasInWater) {
551 if (!this->
rsw_.empty())
552 fs.setRsw(this->rsw_[elemIdx]);
554 if constexpr (enableVapwat) {
555 if (!this->
rvw_.empty())
556 fs.setRvw(this->rvw_[elemIdx]);
562 if (!this->
soMax_.empty())
563 simulator.problem().setMaxOilSaturation(elemIdx, this->
soMax_[elemIdx]);
565 if (simulator.problem().materialLawManager()->enableHysteresis()) {
566 auto matLawManager = simulator.problem().materialLawManager();
568 if (FluidSystem::phaseIsActive(oilPhaseIdx)
569 && FluidSystem::phaseIsActive(waterPhaseIdx)) {
574 if (matLawManager->enableNonWettingHysteresis()) {
575 if (!this->
soMax_.empty()) {
576 somax = this->
soMax_[elemIdx];
579 if (matLawManager->enableWettingHysteresis()) {
580 if (!this->
swMax_.empty()) {
581 swmax = this->
swMax_[elemIdx];
584 if (matLawManager->enablePCHysteresis()) {
585 if (!this->
swmin_.empty()) {
586 swmin = this->
swmin_[elemIdx];
589 matLawManager->setOilWaterHysteresisParams(
590 somax, swmax, swmin, elemIdx);
592 if (FluidSystem::phaseIsActive(oilPhaseIdx)
593 && FluidSystem::phaseIsActive(gasPhaseIdx)) {
598 if (matLawManager->enableNonWettingHysteresis()) {
599 if (!this->
sgmax_.empty()) {
600 sgmax = this->
sgmax_[elemIdx];
603 if (matLawManager->enableWettingHysteresis()) {
604 if (!this->
shmax_.empty()) {
605 shmax = this->
shmax_[elemIdx];
608 if (matLawManager->enablePCHysteresis()) {
609 if (!this->
somin_.empty()) {
610 somin = this->
somin_[elemIdx];
613 matLawManager->setGasOilHysteresisParams(
614 sgmax, shmax, somin, elemIdx);
619 if (simulator_.vanguard().eclState().fieldProps().has_double(
"SWATINIT")) {
620 simulator.problem().materialLawManager()
621 ->applyRestartSwatInit(elemIdx, this->
ppcw_[elemIdx]);
627 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
628 updateFluidInPlace_(elemCtx, dofIdx);
633 const IntensiveQuantities& intQuants,
634 const double totVolume)
636 this->updateFluidInPlace_(globalDofIdx, intQuants, totVolume);
640 template <
typename T>
641 using RemoveCVR = std::remove_cv_t<std::remove_reference_t<T>>;
643 template <
typename,
class =
void>
644 struct HasGeoMech :
public std::false_type {};
646 template <
typename Problem>
648 Problem, std::void_t<decltype(std::declval<Problem>().geoMechModel())>
649 > :
public std::true_type {};
651 bool isDefunctParallelWell(
const std::string& wname)
const override
653 if (simulator_.gridView().comm().size() == 1)
655 const auto& parallelWells = simulator_.vanguard().parallelWells();
656 std::pair<std::string, bool> value {wname,
true};
657 auto candidate = std::lower_bound(parallelWells.begin(), parallelWells.end(), value);
658 return candidate == parallelWells.end() || *candidate != value;
661 bool isOwnedByCurrentRank(
const std::string& wname)
const override
663 return this->simulator_.problem().wellModel().isOwner(wname);
666 bool isOnCurrentRank(
const std::string& wname)
const override
668 return this->simulator_.problem().wellModel().hasLocalCells(wname);
671 void updateFluidInPlace_(
const ElementContext& elemCtx,
const unsigned dofIdx)
673 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
674 const unsigned globalDofIdx = elemCtx.globalSpaceIndex(dofIdx, 0);
675 const auto totVolume = elemCtx.simulator().model().dofTotalVolume(globalDofIdx);
677 this->updateFluidInPlace_(globalDofIdx, intQuants, totVolume);
680 void updateFluidInPlace_(
const unsigned globalDofIdx,
681 const IntensiveQuantities& intQuants,
682 const double totVolume)
686 this->updateTotalVolumesAndPressures_(globalDofIdx, intQuants, totVolume);
689 this->updatePhaseInplaceVolumes_(globalDofIdx, intQuants, totVolume);
693 void createLocalRegion_(std::vector<int>& region)
699 region.resize(simulator_.gridView().size(0));
700 std::size_t elemIdx = 0;
701 for (
const auto& elem : elements(simulator_.gridView())) {
702 if (elem.partitionType() != Dune::InteriorEntity) {
710 template <
typename Flu
idState>
711 void aggregateAverageDensityContributions_(
const FluidState& fs,
712 const unsigned int globalDofIdx,
715 auto pvCellValue = RegionPhasePoreVolAverage::CellValue{};
716 pvCellValue.porv = porv;
718 for (
auto phaseIdx = 0*FluidSystem::numPhases;
719 phaseIdx < FluidSystem::numPhases; ++phaseIdx)
721 if (! FluidSystem::phaseIsActive(phaseIdx)) {
725 pvCellValue.value = getValue(fs.density(phaseIdx));
726 pvCellValue.sat = getValue(fs.saturation(phaseIdx));
729 ->addCell(globalDofIdx,
730 RegionPhasePoreVolAverage::Phase { phaseIdx },
750 data::InterRegFlowMap::FlowRates
751 getComponentSurfaceRates(
const ElementContext& elemCtx,
752 const Scalar faceArea,
753 const std::size_t scvfIdx,
754 const std::size_t timeIdx)
const
756 using Component = data::InterRegFlowMap::Component;
758 auto rates = data::InterRegFlowMap::FlowRates {};
760 const auto& extQuant = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
762 const auto alpha = getValue(extQuant.extrusionFactor()) * faceArea;
764 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
765 const auto& up = elemCtx
766 .intensiveQuantities(extQuant.upstreamIndex(oilPhaseIdx), timeIdx);
768 const auto pvtReg = up.pvtRegionIndex();
770 const auto bO = getValue(getInvB_<FluidSystem, FluidState, Scalar>
771 (up.fluidState(), oilPhaseIdx, pvtReg));
773 const auto qO = alpha * bO * getValue(extQuant.volumeFlux(oilPhaseIdx));
775 rates[Component::Oil] += qO;
777 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
778 const auto Rs = getValue(
779 BlackOil::getRs_<FluidSystem, FluidState, Scalar>
780 (up.fluidState(), pvtReg));
782 rates[Component::Gas] += qO *
Rs;
783 rates[Component::Disgas] += qO *
Rs;
787 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
788 const auto& up = elemCtx
789 .intensiveQuantities(extQuant.upstreamIndex(gasPhaseIdx), timeIdx);
791 const auto pvtReg = up.pvtRegionIndex();
793 const auto bG = getValue(getInvB_<FluidSystem, FluidState, Scalar>
794 (up.fluidState(), gasPhaseIdx, pvtReg));
796 const auto qG = alpha * bG * getValue(extQuant.volumeFlux(gasPhaseIdx));
798 rates[Component::Gas] += qG;
800 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
801 const auto Rv = getValue(
802 BlackOil::getRv_<FluidSystem, FluidState, Scalar>
803 (up.fluidState(), pvtReg));
805 rates[Component::Oil] += qG *
Rv;
806 rates[Component::Vapoil] += qG *
Rv;
810 if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
811 const auto& up = elemCtx
812 .intensiveQuantities(extQuant.upstreamIndex(waterPhaseIdx), timeIdx);
814 const auto pvtReg = up.pvtRegionIndex();
816 const auto bW = getValue(getInvB_<FluidSystem, FluidState, Scalar>
817 (up.fluidState(), waterPhaseIdx, pvtReg));
819 rates[Component::Water] +=
820 alpha * bW * getValue(extQuant.volumeFlux(waterPhaseIdx));
826 template <
typename Flu
idState>
827 Scalar hydroCarbonFraction(
const FluidState& fs)
const
829 if (this->
eclState_.runspec().co2Storage()) {
836 auto hydrocarbon = Scalar {0};
837 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
838 hydrocarbon += getValue(fs.saturation(oilPhaseIdx));
841 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
842 hydrocarbon += getValue(fs.saturation(gasPhaseIdx));
848 void updateTotalVolumesAndPressures_(
const unsigned globalDofIdx,
849 const IntensiveQuantities& intQuants,
850 const double totVolume)
852 const auto& fs = intQuants.fluidState();
854 const double pv = totVolume * intQuants.porosity().value();
855 const auto hydrocarbon = this->hydroCarbonFraction(fs);
859 totVolume * intQuants.referencePorosity());
866 !this->pressureTimesPoreVolume_.empty())
869 assert(this->
fipC_.
get(Inplace::Phase::PoreVolume).size() == this->pressureTimesPoreVolume_.size());
871 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
873 getValue(fs.pressure(oilPhaseIdx)) * pv;
878 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
880 getValue(fs.pressure(gasPhaseIdx)) * pv;
885 else if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
887 getValue(fs.pressure(waterPhaseIdx)) * pv;
892 void updatePhaseInplaceVolumes_(
const unsigned globalDofIdx,
893 const IntensiveQuantities& intQuants,
894 const double totVolume)
896 std::array<Scalar, FluidSystem::numPhases> fip {};
897 std::array<Scalar, FluidSystem::numPhases> fipr{};
899 const auto& fs = intQuants.fluidState();
900 const auto pv = totVolume * intQuants.porosity().value();
902 for (
unsigned phaseIdx = 0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) {
903 if (!FluidSystem::phaseIsActive(phaseIdx)) {
907 const auto b = getValue(fs.invB(phaseIdx));
908 const auto s = getValue(fs.saturation(phaseIdx));
910 fipr[phaseIdx] = s * pv;
911 fip [phaseIdx] = b * fipr[phaseIdx];
916 fs.saltConcentration().value(),
919 if (FluidSystem::phaseIsActive(oilPhaseIdx) &&
920 FluidSystem::phaseIsActive(gasPhaseIdx))
922 this->updateOilGasDistribution(globalDofIdx, fs, fip);
925 if (FluidSystem::phaseIsActive(waterPhaseIdx) &&
926 FluidSystem::phaseIsActive(gasPhaseIdx))
928 this->updateGasWaterDistribution(globalDofIdx, fs, fip);
931 if (FluidSystem::phaseIsActive(gasPhaseIdx) &&
934 this->updateCO2InGas(globalDofIdx, pv, intQuants);
938 (FluidSystem::phaseIsActive(waterPhaseIdx) ||
939 FluidSystem::phaseIsActive(oilPhaseIdx)))
941 this->updateCO2InWater(globalDofIdx, pv, fs);
944 if constexpr(enableBioeffects) {
945 const auto surfVolWat = pv * getValue(fs.saturation(waterPhaseIdx)) *
946 getValue(fs.invB(waterPhaseIdx));
948 this->updateMicrobialMass(globalDofIdx, intQuants, surfVolWat);
951 this->updateBiofilmMass(globalDofIdx, intQuants, totVolume);
953 if constexpr(enableMICP) {
955 this->updateOxygenMass(globalDofIdx, intQuants, surfVolWat);
958 this->updateUreaMass(globalDofIdx, intQuants, surfVolWat);
961 this->updateCalciteMass(globalDofIdx, intQuants, totVolume);
968 this->updateWaterMass(globalDofIdx, fs, fip);
972 template <
typename Flu
idState,
typename FIPArray>
973 void updateOilGasDistribution(
const unsigned globalDofIdx,
974 const FluidState& fs,
978 const auto gasInPlaceLiquid = getValue(fs.Rs()) * fip[oilPhaseIdx];
979 const auto oilInPlaceGas = getValue(fs.Rv()) * fip[gasPhaseIdx];
984 template <
typename Flu
idState,
typename FIPArray>
985 void updateGasWaterDistribution(
const unsigned globalDofIdx,
986 const FluidState& fs,
990 const auto gasInPlaceWater = getValue(fs.Rsw()) * fip[waterPhaseIdx];
991 const auto waterInPlaceGas = getValue(fs.Rvw()) * fip[gasPhaseIdx];
996 template <
typename IntensiveQuantities>
997 void updateCO2InGas(
const unsigned globalDofIdx,
999 const IntensiveQuantities& intQuants)
1001 const auto& scaledDrainageInfo = this->simulator_.problem().materialLawManager()
1002 ->oilWaterScaledEpsInfoDrainage(globalDofIdx);
1004 const auto& fs = intQuants.fluidState();
1005 Scalar sgcr = scaledDrainageInfo.Sgcr;
1006 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1007 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1008 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
1011 Scalar trappedGasSaturation = scaledDrainageInfo.Sgcr;
1012 if (this->
fipC_.
has(Inplace::Phase::CO2MassInGasPhaseMaximumTrapped) ||
1013 this->fipC_.has(Inplace::Phase::CO2MassInGasPhaseMaximumUnTrapped))
1015 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1016 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1018 trappedGasSaturation = MaterialLaw::trappedGasSaturation(matParams,
true);
1022 const Scalar sg = getValue(fs.saturation(gasPhaseIdx));
1023 Scalar strandedGasSaturation = scaledDrainageInfo.Sgcr;
1024 if (this->
fipC_.
has(Inplace::Phase::CO2MassInGasPhaseEffectiveTrapped) ||
1025 this->fipC_.has(Inplace::Phase::CO2MassInGasPhaseEffectiveUnTrapped))
1027 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1028 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1029 const double krg = getValue(intQuants.relativePermeability(gasPhaseIdx));
1030 strandedGasSaturation = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
1034 const typename FIPContainer<FluidSystem>::Co2InGasInput v{
1038 getValue(fs.density(gasPhaseIdx)),
1039 FluidSystem::phaseIsActive(waterPhaseIdx)
1040 ? FluidSystem::convertRvwToXgW(getValue(fs.Rvw()), fs.pvtRegionIndex())
1041 : FluidSystem::convertRvToXgO(getValue(fs.
Rv()), fs.pvtRegionIndex()),
1042 FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex()),
1043 trappedGasSaturation,
1044 strandedGasSaturation,
1050 template <
typename Flu
idState>
1051 void updateCO2InWater(
const unsigned globalDofIdx,
1053 const FluidState& fs)
1055 const auto co2InWater = FluidSystem::phaseIsActive(oilPhaseIdx)
1056 ? this->co2InWaterFromOil(fs, pv)
1057 : this->co2InWaterFromWater(fs, pv);
1059 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1064 template <
typename Flu
idState>
1065 Scalar co2InWaterFromWater(
const FluidState& fs,
const double pv)
const
1067 const double rhow = getValue(fs.density(waterPhaseIdx));
1068 const double sw = getValue(fs.saturation(waterPhaseIdx));
1069 const double xwG = FluidSystem::convertRswToXwG(getValue(fs.Rsw()), fs.pvtRegionIndex());
1071 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1073 return xwG * pv * rhow * sw / mM;
1076 template <
typename Flu
idState>
1077 Scalar co2InWaterFromOil(
const FluidState& fs,
const double pv)
const
1079 const double rhoo = getValue(fs.density(oilPhaseIdx));
1080 const double so = getValue(fs.saturation(oilPhaseIdx));
1081 const double xoG = FluidSystem::convertRsToXoG(getValue(fs.Rs()), fs.pvtRegionIndex());
1083 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1085 return xoG * pv * rhoo * so / mM;
1088 template <
typename Flu
idState,
typename FIPArray>
1089 void updateWaterMass(
const unsigned globalDofIdx,
1090 const FluidState& fs,
1094 const Scalar rhoW = FluidSystem::referenceDensity(waterPhaseIdx, fs.pvtRegionIndex());
1099 template <
typename IntensiveQuantities>
1100 void updateMicrobialMass(
const unsigned globalDofIdx,
1101 const IntensiveQuantities& intQuants,
1102 const double surfVolWat)
1104 const Scalar mass = surfVolWat * intQuants.microbialConcentration().value();
1109 template <
typename IntensiveQuantities>
1110 void updateOxygenMass(
const unsigned globalDofIdx,
1111 const IntensiveQuantities& intQuants,
1112 const double surfVolWat)
1114 const Scalar mass = surfVolWat * intQuants.oxygenConcentration().value();
1119 template <
typename IntensiveQuantities>
1120 void updateUreaMass(
const unsigned globalDofIdx,
1121 const IntensiveQuantities& intQuants,
1122 const double surfVolWat)
1124 const Scalar mass = surfVolWat * intQuants.ureaConcentration().value();
1129 template <
typename IntensiveQuantities>
1130 void updateBiofilmMass(
const unsigned globalDofIdx,
1131 const IntensiveQuantities& intQuants,
1132 const double totVolume)
1134 const Scalar mass = totVolume * intQuants.biofilmMass().value();
1139 template <
typename IntensiveQuantities>
1140 void updateCalciteMass(
const unsigned globalDofIdx,
1141 const IntensiveQuantities& intQuants,
1142 const double totVolume)
1144 const Scalar mass = totVolume * intQuants.calciteMass().value();
1150 void setupElementExtractors_()
1152 using Entry =
typename Extractor::Entry;
1153 using Context =
typename Extractor::Context;
1154 using ScalarEntry =
typename Extractor::ScalarEntry;
1155 using PhaseEntry =
typename Extractor::PhaseEntry;
1157 const bool hasResidual = simulator_.model().linearizer().residual().size() > 0;
1158 const auto& hysteresisConfig = simulator_.problem().materialLawManager()->hysteresisConfig();
1160 auto extractors = std::array{
1162 [](
const unsigned phase,
const Context& ectx)
1163 {
return getValue(ectx.fs.saturation(phase)); }
1166 Entry{PhaseEntry{&this->
invB_,
1167 [](
const unsigned phase,
const Context& ectx)
1168 {
return getValue(ectx.fs.invB(phase)); }
1172 [](
const unsigned phase,
const Context& ectx)
1173 {
return getValue(ectx.fs.density(phase)); }
1177 [](
const unsigned phase,
const Context& ectx)
1178 {
return getValue(ectx.intQuants.relativePermeability(phase)); }
1182 [
this](
const unsigned phaseIdx,
const Context& ectx)
1184 if (this->
extboC_.allocated() && phaseIdx == oilPhaseIdx) {
1185 return getValue(ectx.intQuants.oilViscosity());
1187 else if (this->
extboC_.allocated() && phaseIdx == gasPhaseIdx) {
1188 return getValue(ectx.intQuants.gasViscosity());
1191 return getValue(ectx.fs.viscosity(phaseIdx));
1197 [&modelResid = this->simulator_.model().linearizer().residual()]
1198 (
const unsigned phaseIdx,
const Context& ectx)
1200 const unsigned sIdx = FluidSystem::solventComponentIndex(phaseIdx);
1201 const unsigned activeCompIdx = FluidSystem::canonicalToActiveCompIdx(sIdx);
1202 return modelResid[ectx.globalDofIdx][activeCompIdx];
1208 [&problem = this->simulator_.problem()](
const Context& ectx)
1210 return problem.template
1211 rockCompPoroMultiplier<Scalar>(ectx.intQuants,
1217 [&problem = this->simulator_.problem()](
const Context& ectx)
1220 template rockCompTransMultiplier<Scalar>(ectx.intQuants,
1225 [&problem = this->simulator_.problem()](
const Context& ectx)
1227 return std::min(getValue(ectx.fs.pressure(oilPhaseIdx)),
1228 problem.minOilPressure(ectx.globalDofIdx));
1234 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1238 FluidSystem::bubblePointPressure(ectx.fs,
1239 ectx.intQuants.pvtRegionIndex())
1241 }
catch (
const NumericalProblem&) {
1242 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1243 failedCells.push_back(cartesianIdx);
1251 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1255 FluidSystem::dewPointPressure(ectx.fs,
1256 ectx.intQuants.pvtRegionIndex())
1258 }
catch (
const NumericalProblem&) {
1259 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1260 failedCells.push_back(cartesianIdx);
1267 [&problem = simulator_.problem()](
const Context& ectx)
1268 {
return problem.overburdenPressure(ectx.globalDofIdx); }
1272 [](
const Context& ectx)
1273 {
return getValue(ectx.fs.temperature(oilPhaseIdx)); }
1276 Entry{ScalarEntry{&this->
sSol_,
1277 [](
const Context& ectx)
1278 {
return getValue(ectx.intQuants.solventSaturation()); }
1281 Entry{ScalarEntry{&this->
rswSol_,
1282 [](
const Context& ectx)
1283 {
return getValue(ectx.intQuants.rsSolw()); }
1287 [](
const Context& ectx)
1288 {
return getValue(ectx.intQuants.polymerConcentration()); }
1291 Entry{ScalarEntry{&this->
cFoam_,
1292 [](
const Context& ectx)
1293 {
return getValue(ectx.intQuants.foamConcentration()); }
1296 Entry{ScalarEntry{&this->
cSalt_,
1297 [](
const Context& ectx)
1298 {
return getValue(ectx.fs.saltConcentration()); }
1301 Entry{ScalarEntry{&this->
pSalt_,
1302 [](
const Context& ectx)
1303 {
return getValue(ectx.fs.saltSaturation()); }
1307 [](
const Context& ectx)
1308 {
return getValue(ectx.intQuants.permFactor()); }
1311 Entry{ScalarEntry{&this->
rPorV_,
1312 [&model = this->simulator_.model()](
const Context& ectx)
1314 const auto totVolume = model.dofTotalVolume(ectx.globalDofIdx);
1315 return totVolume * getValue(ectx.intQuants.porosity());
1319 Entry{ScalarEntry{&this->
rs_,
1320 [](
const Context& ectx)
1321 {
return getValue(ectx.fs.Rs()); }
1324 Entry{ScalarEntry{&this->
rv_,
1325 [](
const Context& ectx)
1326 {
return getValue(ectx.fs.Rv()); }
1329 Entry{ScalarEntry{&this->
rsw_,
1330 [](
const Context& ectx)
1331 {
return getValue(ectx.fs.Rsw()); }
1334 Entry{ScalarEntry{&this->
rvw_,
1335 [](
const Context& ectx)
1336 {
return getValue(ectx.fs.Rvw()); }
1339 Entry{ScalarEntry{&this->
ppcw_,
1340 [&matLawManager = *this->simulator_.problem().materialLawManager()]
1341 (
const Context& ectx)
1343 return matLawManager.
1344 oilWaterScaledEpsInfoDrainage(ectx.globalDofIdx).maxPcow;
1349 [&problem = this->simulator_.problem()](
const Context& ectx)
1351 return problem.drsdtcon(ectx.globalDofIdx,
1356 Entry{ScalarEntry{&this->
pcgw_,
1357 [](
const Context& ectx)
1359 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1360 getValue(ectx.fs.pressure(waterPhaseIdx));
1364 Entry{ScalarEntry{&this->
pcow_,
1365 [](
const Context& ectx)
1367 return getValue(ectx.fs.pressure(oilPhaseIdx)) -
1368 getValue(ectx.fs.pressure(waterPhaseIdx));
1372 Entry{ScalarEntry{&this->
pcog_,
1373 [](
const Context& ectx)
1375 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1376 getValue(ectx.fs.pressure(oilPhaseIdx));
1381 [](
const Context& ectx)
1383 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1385 return getValue(ectx.fs.pressure(oilPhaseIdx));
1387 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1389 return getValue(ectx.fs.pressure(gasPhaseIdx));
1393 return getValue(ectx.fs.pressure(waterPhaseIdx));
1399 [&problem = this->simulator_.problem()](
const Context& ectx)
1401 const Scalar SoMax = problem.maxOilSaturation(ectx.globalDofIdx);
1402 return FluidSystem::template
1403 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1411 [&problem = this->simulator_.problem()](
const Context& ectx)
1413 const Scalar SoMax = problem.maxOilSaturation(ectx.globalDofIdx);
1414 return FluidSystem::template
1415 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1423 [&problem = this->simulator_.problem()](
const Context& ectx)
1425 const Scalar SwMax = problem.maxWaterSaturation(ectx.globalDofIdx);
1426 return FluidSystem::template
1427 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1435 [](
const Context& ectx)
1437 return FluidSystem::template
1438 saturatedVaporizationFactor<FluidState, Scalar>(ectx.fs,
1445 [](
const Context& ectx)
1447 return 1.0 / FluidSystem::template
1448 inverseFormationVolumeFactor<FluidState, Scalar>(ectx.fs,
1455 [](
const Context& ectx)
1457 return 1.0 / FluidSystem::template
1458 saturatedInverseFormationVolumeFactor<FluidState, Scalar>(ectx.fs,
1465 [](
const Context& ectx)
1467 return FluidSystem::template
1468 saturationPressure<FluidState, Scalar>(ectx.fs,
1474 Entry{ScalarEntry{&this->
soMax_,
1475 [&problem = this->simulator_.problem()](
const Context& ectx)
1477 return std::max(getValue(ectx.fs.saturation(oilPhaseIdx)),
1478 problem.maxOilSaturation(ectx.globalDofIdx));
1481 !hysteresisConfig.enableHysteresis()
1483 Entry{ScalarEntry{&this->
swMax_,
1484 [&problem = this->simulator_.problem()](
const Context& ectx)
1486 return std::max(getValue(ectx.fs.saturation(waterPhaseIdx)),
1487 problem.maxWaterSaturation(ectx.globalDofIdx));
1490 !hysteresisConfig.enableHysteresis()
1492 Entry{ScalarEntry{&this->
soMax_,
1493 [](
const Context& ectx)
1494 {
return ectx.hParams.somax; }
1496 hysteresisConfig.enableHysteresis() &&
1497 hysteresisConfig.enableNonWettingHysteresis() &&
1498 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1499 FluidSystem::phaseIsActive(waterPhaseIdx)
1501 Entry{ScalarEntry{&this->
swMax_,
1502 [](
const Context& ectx)
1503 {
return ectx.hParams.swmax; }
1505 hysteresisConfig.enableHysteresis() &&
1506 hysteresisConfig.enableWettingHysteresis() &&
1507 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1508 FluidSystem::phaseIsActive(waterPhaseIdx)
1510 Entry{ScalarEntry{&this->
swmin_,
1511 [](
const Context& ectx)
1512 {
return ectx.hParams.swmin; }
1514 hysteresisConfig.enableHysteresis() &&
1515 hysteresisConfig.enablePCHysteresis() &&
1516 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1517 FluidSystem::phaseIsActive(waterPhaseIdx)
1519 Entry{ScalarEntry{&this->
sgmax_,
1520 [](
const Context& ectx)
1521 {
return ectx.hParams.sgmax; }
1523 hysteresisConfig.enableHysteresis() &&
1524 hysteresisConfig.enableNonWettingHysteresis() &&
1525 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1526 FluidSystem::phaseIsActive(gasPhaseIdx)
1528 Entry{ScalarEntry{&this->
shmax_,
1529 [](
const Context& ectx)
1530 {
return ectx.hParams.shmax; }
1532 hysteresisConfig.enableHysteresis() &&
1533 hysteresisConfig.enableWettingHysteresis() &&
1534 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1535 FluidSystem::phaseIsActive(gasPhaseIdx)
1537 Entry{ScalarEntry{&this->
somin_,
1538 [](
const Context& ectx)
1539 {
return ectx.hParams.somin; }
1541 hysteresisConfig.enableHysteresis() &&
1542 hysteresisConfig.enablePCHysteresis() &&
1543 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1544 FluidSystem::phaseIsActive(gasPhaseIdx)
1546 Entry{[&model = this->simulator_.model(),
this](
const Context& ectx)
1550 const auto porv = ectx.intQuants.referencePorosity()
1551 * model.dofTotalVolume(ectx.globalDofIdx);
1553 this->aggregateAverageDensityContributions_(ectx.fs, ectx.globalDofIdx,
1554 static_cast<double>(porv));
1557 Entry{[&extboC = this->
extboC_](
const Context& ectx)
1559 extboC.assignVolumes(ectx.globalDofIdx,
1560 ectx.intQuants.xVolume().value(),
1561 ectx.intQuants.yVolume().value());
1562 extboC.assignZFraction(ectx.globalDofIdx,
1563 ectx.intQuants.zFraction().value());
1565 const Scalar stdVolOil = getValue(ectx.fs.saturation(oilPhaseIdx)) *
1566 getValue(ectx.fs.invB(oilPhaseIdx)) +
1567 getValue(ectx.fs.saturation(gasPhaseIdx)) *
1568 getValue(ectx.fs.invB(gasPhaseIdx)) *
1569 getValue(ectx.fs.Rv());
1570 const Scalar stdVolGas = getValue(ectx.fs.saturation(gasPhaseIdx)) *
1571 getValue(ectx.fs.invB(gasPhaseIdx)) *
1572 (1.0 - ectx.intQuants.yVolume().value()) +
1573 getValue(ectx.fs.saturation(oilPhaseIdx)) *
1574 getValue(ectx.fs.invB(oilPhaseIdx)) *
1575 getValue(ectx.fs.Rs()) *
1576 (1.0 - ectx.intQuants.xVolume().value());
1577 const Scalar stdVolCo2 = getValue(ectx.fs.saturation(gasPhaseIdx)) *
1578 getValue(ectx.fs.invB(gasPhaseIdx)) *
1579 ectx.intQuants.yVolume().value() +
1580 getValue(ectx.fs.saturation(oilPhaseIdx)) *
1581 getValue(ectx.fs.invB(oilPhaseIdx)) *
1582 getValue(ectx.fs.Rs()) *
1583 ectx.intQuants.xVolume().value();
1584 const Scalar rhoO = FluidSystem::referenceDensity(gasPhaseIdx, ectx.pvtRegionIdx);
1585 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx, ectx.pvtRegionIdx);
1586 const Scalar rhoCO2 = ectx.intQuants.zRefDensity();
1587 const Scalar stdMassTotal = 1.0e-10 + stdVolOil * rhoO + stdVolGas * rhoG + stdVolCo2 * rhoCO2;
1588 extboC.assignMassFractions(ectx.globalDofIdx,
1589 stdVolGas * rhoG / stdMassTotal,
1590 stdVolOil * rhoO / stdMassTotal,
1591 stdVolCo2 * rhoCO2 / stdMassTotal);
1594 Entry{[&bioeffectsC = this->
bioeffectsC_](
const Context& ectx)
1596 bioeffectsC.assign(ectx.globalDofIdx,
1597 ectx.intQuants.microbialConcentration().value(),
1598 ectx.intQuants.biofilmVolumeFraction().value());
1599 if (Indices::enableMICP) {
1600 bioeffectsC.assign(ectx.globalDofIdx,
1601 ectx.intQuants.oxygenConcentration().value(),
1602 ectx.intQuants.ureaConcentration().value(),
1603 ectx.intQuants.calciteVolumeFraction().value());
1607 Entry{[&rftC = this->
rftC_,
1608 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1610 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1611 rftC.assign(cartesianIdx,
1612 [&fs = ectx.fs]() {
return getValue(fs.pressure(oilPhaseIdx)); },
1613 [&fs = ectx.fs]() {
return getValue(fs.saturation(waterPhaseIdx)); },
1614 [&fs = ectx.fs]() {
return getValue(fs.saturation(gasPhaseIdx)); });
1618 &tM = this->simulator_.problem().tracerModel()](
const Context& ectx)
1620 tC.assignFreeConcentrations(ectx.globalDofIdx,
1621 [gIdx = ectx.globalDofIdx, &tM](
const unsigned tracerIdx)
1622 {
return tM.freeTracerConcentration(tracerIdx, gIdx); });
1623 tC.assignSolConcentrations(ectx.globalDofIdx,
1624 [gIdx = ectx.globalDofIdx, &tM](
const unsigned tracerIdx)
1625 {
return tM.solTracerConcentration(tracerIdx, gIdx); });
1628 Entry{[&flowsInf = this->simulator_.problem().model().linearizer().getFlowsInfo(),
1629 &flowsC = this->
flowsC_](
const Context& ectx)
1631 const auto gas_idx = Indices::gasEnabled ?
1632 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(gasCompIdx) : -1;
1633 const auto oil_idx = Indices::oilEnabled ?
1634 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(oilCompIdx) : -1;
1635 const auto water_idx = Indices::waterEnabled ?
1636 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(waterCompIdx) : -1;
1637 const auto& flowsInfos = flowsInf[ectx.globalDofIdx];
1638 for (
const auto& flowsInfo : flowsInfos) {
1639 flowsC.assignFlows(ectx.globalDofIdx,
1642 value_or_zero(gas_idx, flowsInfo.flow),
1643 value_or_zero(oil_idx, flowsInfo.flow),
1644 value_or_zero(water_idx, flowsInfo.flow));
1646 }, !this->simulator_.problem().model().linearizer().getFlowsInfo().empty()
1648 Entry{[&floresInf = this->simulator_.problem().model().linearizer().getFloresInfo(),
1649 &flowsC = this->
flowsC_](
const Context& ectx)
1651 const auto gas_idx = Indices::gasEnabled ?
1652 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(gasCompIdx) : -1;
1653 const auto oil_idx = Indices::oilEnabled ?
1654 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(oilCompIdx) : -1;
1655 const auto water_idx = Indices::waterEnabled ?
1656 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(waterCompIdx) : -1;
1657 const auto& floresInfos = floresInf[ectx.globalDofIdx];
1658 for (
const auto& floresInfo : floresInfos) {
1659 flowsC.assignFlores(ectx.globalDofIdx,
1662 value_or_zero(gas_idx, floresInfo.flow),
1663 value_or_zero(oil_idx, floresInfo.flow),
1664 value_or_zero(water_idx, floresInfo.flow));
1666 }, !this->simulator_.problem().model().linearizer().getFloresInfo().empty()
1673 Entry{ScalarEntry{&this->
rv_,
1674 [&problem = this->simulator_.problem()](
const Context& ectx)
1675 {
return problem.initialFluidState(ectx.globalDofIdx).Rv(); }
1677 simulator_.episodeIndex() < 0 &&
1678 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1679 FluidSystem::phaseIsActive(gasPhaseIdx)
1681 Entry{ScalarEntry{&this->
rs_,
1682 [&problem = this->simulator_.problem()](
const Context& ectx)
1683 {
return problem.initialFluidState(ectx.globalDofIdx).Rs(); }
1685 simulator_.episodeIndex() < 0 &&
1686 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1687 FluidSystem::phaseIsActive(gasPhaseIdx)
1689 Entry{ScalarEntry{&this->
rsw_,
1690 [&problem = this->simulator_.problem()](
const Context& ectx)
1691 {
return problem.initialFluidState(ectx.globalDofIdx).Rsw(); }
1693 simulator_.episodeIndex() < 0 &&
1694 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1695 FluidSystem::phaseIsActive(gasPhaseIdx)
1697 Entry{ScalarEntry{&this->
rvw_,
1698 [&problem = this->simulator_.problem()](
const Context& ectx)
1699 {
return problem.initialFluidState(ectx.globalDofIdx).Rvw(); }
1701 simulator_.episodeIndex() < 0 &&
1702 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1703 FluidSystem::phaseIsActive(gasPhaseIdx)
1707 [&problem = this->simulator_.problem()](
const unsigned phase,
1708 const Context& ectx)
1710 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
1711 return FluidSystem::density(fsInitial,
1713 ectx.intQuants.pvtRegionIndex());
1716 simulator_.episodeIndex() < 0 &&
1717 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1718 FluidSystem::phaseIsActive(gasPhaseIdx)
1720 Entry{PhaseEntry{&this->
invB_,
1721 [&problem = this->simulator_.problem()](
const unsigned phase,
1722 const Context& ectx)
1724 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
1725 return FluidSystem::inverseFormationVolumeFactor(fsInitial,
1727 ectx.intQuants.pvtRegionIndex());
1730 simulator_.episodeIndex() < 0 &&
1731 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1732 FluidSystem::phaseIsActive(gasPhaseIdx)
1735 [&problem = this->simulator_.problem()](
const unsigned phase,
1736 const Context& ectx)
1738 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
1739 return FluidSystem::viscosity(fsInitial,
1741 ectx.intQuants.pvtRegionIndex());
1744 simulator_.episodeIndex() < 0 &&
1745 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1746 FluidSystem::phaseIsActive(gasPhaseIdx)
1753 if constexpr (getPropValue<TypeTag, Properties::EnableMech>()) {
1754 if (this->
mech_.allocated()) {
1755 this->extractors_.push_back(
1756 Entry{[&mech = this->
mech_,
1757 &model = simulator_.problem().geoMechModel()](
const Context& ectx)
1759 mech.assignDelStress(ectx.globalDofIdx,
1760 model.delstress(ectx.globalDofIdx));
1762 mech.assignDisplacement(ectx.globalDofIdx,
1763 model.disp(ectx.globalDofIdx,
true));
1766 mech.assignFracStress(ectx.globalDofIdx,
1767 model.fractureStress(ectx.globalDofIdx));
1769 mech.assignLinStress(ectx.globalDofIdx,
1770 model.linstress(ectx.globalDofIdx));
1772 mech.assignPotentialForces(ectx.globalDofIdx,
1773 model.mechPotentialForce(ectx.globalDofIdx),
1774 model.mechPotentialPressForce(ectx.globalDofIdx),
1775 model.mechPotentialTempForce(ectx.globalDofIdx));
1777 mech.assignStrain(ectx.globalDofIdx,
1778 model.strain(ectx.globalDofIdx,
true));
1781 mech.assignStress(ectx.globalDofIdx,
1782 model.stress(ectx.globalDofIdx,
true));
1791 void setupBlockExtractors_(
const bool isSubStep,
1792 const int reportStepNum)
1795 using Context =
typename BlockExtractor::Context;
1796 using PhaseEntry =
typename BlockExtractor::PhaseEntry;
1797 using ScalarEntry =
typename BlockExtractor::ScalarEntry;
1799 using namespace std::string_view_literals;
1801 const auto pressure_handler =
1802 Entry{ScalarEntry{std::vector{
"BPR"sv,
"BPRESSUR"sv},
1803 [](
const Context& ectx)
1805 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1806 return getValue(ectx.fs.pressure(oilPhaseIdx));
1808 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1809 return getValue(ectx.fs.pressure(gasPhaseIdx));
1812 return getValue(ectx.fs.pressure(waterPhaseIdx));
1818 const auto handlers = std::array{
1820 Entry{PhaseEntry{std::array{
1821 std::array{
"BWSAT"sv,
"BOSAT"sv,
"BGSAT"sv},
1822 std::array{
"BSWAT"sv,
"BSOIL"sv,
"BSGAS"sv}
1824 [](
const unsigned phaseIdx,
const Context& ectx)
1826 return getValue(ectx.fs.saturation(phaseIdx));
1830 Entry{ScalarEntry{
"BNSAT",
1831 [](
const Context& ectx)
1833 return ectx.intQuants.solventSaturation().value();
1837 Entry{ScalarEntry{std::vector{
"BTCNFHEA"sv,
"BTEMP"sv},
1838 [](
const Context& ectx)
1840 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1841 return getValue(ectx.fs.temperature(oilPhaseIdx));
1843 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1844 return getValue(ectx.fs.temperature(gasPhaseIdx));
1847 return getValue(ectx.fs.temperature(waterPhaseIdx));
1852 Entry{PhaseEntry{std::array{
1853 std::array{
"BWKR"sv,
"BOKR"sv,
"BGKR"sv},
1854 std::array{
"BKRW"sv,
"BKRO"sv,
"BKRG"sv}
1856 [](
const unsigned phaseIdx,
const Context& ectx)
1858 return getValue(ectx.intQuants.relativePermeability(phaseIdx));
1862 Entry{ScalarEntry{
"BKROG",
1863 [&problem = this->simulator_.problem()](
const Context& ectx)
1865 const auto& materialParams =
1866 problem.materialLawParams(ectx.elemCtx,
1869 return getValue(MaterialLaw::template
1870 relpermOilInOilGasSystem<Evaluation>(materialParams,
1875 Entry{ScalarEntry{
"BKROW",
1876 [&problem = this->simulator_.problem()](
const Context& ectx)
1878 const auto& materialParams = problem.materialLawParams(ectx.elemCtx,
1881 return getValue(MaterialLaw::template
1882 relpermOilInOilWaterSystem<Evaluation>(materialParams,
1887 Entry{ScalarEntry{
"BWPC",
1888 [](
const Context& ectx)
1890 return getValue(ectx.fs.pressure(oilPhaseIdx)) -
1891 getValue(ectx.fs.pressure(waterPhaseIdx));
1895 Entry{ScalarEntry{
"BGPC",
1896 [](
const Context& ectx)
1898 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1899 getValue(ectx.fs.pressure(oilPhaseIdx));
1903 Entry{ScalarEntry{
"BWPR",
1904 [](
const Context& ectx)
1906 return getValue(ectx.fs.pressure(waterPhaseIdx));
1910 Entry{ScalarEntry{
"BGPR",
1911 [](
const Context& ectx)
1913 return getValue(ectx.fs.pressure(gasPhaseIdx));
1917 Entry{PhaseEntry{std::array{
1918 std::array{
"BVWAT"sv,
"BVOIL"sv,
"BVGAS"sv},
1919 std::array{
"BWVIS"sv,
"BOVIS"sv,
"BGVIS"sv}
1921 [](
const unsigned phaseIdx,
const Context& ectx)
1923 return getValue(ectx.fs.viscosity(phaseIdx));
1927 Entry{PhaseEntry{std::array{
1928 std::array{
"BWDEN"sv,
"BODEN"sv,
"BGDEN"sv},
1929 std::array{
"BDENW"sv,
"BDENO"sv,
"BDENG"sv}
1931 [](
const unsigned phaseIdx,
const Context& ectx)
1933 return getValue(ectx.fs.density(phaseIdx));
1937 Entry{ScalarEntry{
"BFLOWI",
1938 [&flowsC = this->
flowsC_](
const Context& ectx)
1940 return flowsC.getFlow(ectx.globalDofIdx, Dir::XPlus, waterCompIdx);
1944 Entry{ScalarEntry{
"BFLOWJ",
1945 [&flowsC = this->
flowsC_](
const Context& ectx)
1947 return flowsC.getFlow(ectx.globalDofIdx, Dir::YPlus, waterCompIdx);
1951 Entry{ScalarEntry{
"BFLOWK",
1952 [&flowsC = this->
flowsC_](
const Context& ectx)
1954 return flowsC.getFlow(ectx.globalDofIdx, Dir::ZPlus, waterCompIdx);
1958 Entry{ScalarEntry{
"BRPV",
1959 [&model = this->simulator_.model()](
const Context& ectx)
1961 return getValue(ectx.intQuants.porosity()) *
1962 model.dofTotalVolume(ectx.globalDofIdx);
1966 Entry{PhaseEntry{std::array{
"BWPV"sv,
"BOPV"sv,
"BGPV"sv},
1967 [&model = this->simulator_.model()](
const unsigned phaseIdx,
1968 const Context& ectx)
1970 return getValue(ectx.fs.saturation(phaseIdx)) *
1971 getValue(ectx.intQuants.porosity()) *
1972 model.dofTotalVolume(ectx.globalDofIdx);
1976 Entry{ScalarEntry{
"BRS",
1977 [](
const Context& ectx)
1979 return getValue(ectx.fs.Rs());
1983 Entry{ScalarEntry{
"BRV",
1984 [](
const Context& ectx)
1986 return getValue(ectx.fs.Rv());
1990 Entry{ScalarEntry{
"BOIP",
1991 [&model = this->simulator_.model()](
const Context& ectx)
1993 return (getValue(ectx.fs.invB(oilPhaseIdx)) *
1994 getValue(ectx.fs.saturation(oilPhaseIdx)) +
1995 getValue(ectx.fs.Rv()) *
1996 getValue(ectx.fs.invB(gasPhaseIdx)) *
1997 getValue(ectx.fs.saturation(gasPhaseIdx))) *
1998 model.dofTotalVolume(ectx.globalDofIdx) *
1999 getValue(ectx.intQuants.porosity());
2003 Entry{ScalarEntry{
"BGIP",
2004 [&model = this->simulator_.model()](
const Context& ectx)
2006 Scalar result = getValue(ectx.fs.invB(gasPhaseIdx)) *
2007 getValue(ectx.fs.saturation(gasPhaseIdx));
2009 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2010 result += getValue(ectx.fs.Rs()) *
2011 getValue(ectx.fs.invB(oilPhaseIdx)) *
2012 getValue(ectx.fs.saturation(oilPhaseIdx));
2015 result += getValue(ectx.fs.Rsw()) *
2016 getValue(ectx.fs.invB(waterPhaseIdx)) *
2017 getValue(ectx.fs.saturation(waterPhaseIdx));
2021 model.dofTotalVolume(ectx.globalDofIdx) *
2022 getValue(ectx.intQuants.porosity());
2026 Entry{ScalarEntry{
"BWIP",
2027 [&model = this->simulator_.model()](
const Context& ectx)
2029 return getValue(ectx.fs.invB(waterPhaseIdx)) *
2030 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2031 model.dofTotalVolume(ectx.globalDofIdx) *
2032 getValue(ectx.intQuants.porosity());
2036 Entry{ScalarEntry{
"BOIPL",
2037 [&model = this->simulator_.model()](
const Context& ectx)
2039 return getValue(ectx.fs.invB(oilPhaseIdx)) *
2040 getValue(ectx.fs.saturation(oilPhaseIdx)) *
2041 model.dofTotalVolume(ectx.globalDofIdx) *
2042 getValue(ectx.intQuants.porosity());
2046 Entry{ScalarEntry{
"BGIPL",
2047 [&model = this->simulator_.model()](
const Context& ectx)
2050 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2051 result = getValue(ectx.fs.Rs()) *
2052 getValue(ectx.fs.invB(oilPhaseIdx)) *
2053 getValue(ectx.fs.saturation(oilPhaseIdx));
2056 result = getValue(ectx.fs.Rsw()) *
2057 getValue(ectx.fs.invB(waterPhaseIdx)) *
2058 getValue(ectx.fs.saturation(waterPhaseIdx));
2061 model.dofTotalVolume(ectx.globalDofIdx) *
2062 getValue(ectx.intQuants.porosity());
2066 Entry{ScalarEntry{
"BGIPG",
2067 [&model = this->simulator_.model()](
const Context& ectx)
2069 return getValue(ectx.fs.invB(gasPhaseIdx)) *
2070 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2071 model.dofTotalVolume(ectx.globalDofIdx) *
2072 getValue(ectx.intQuants.porosity());
2076 Entry{ScalarEntry{
"BOIPG",
2077 [&model = this->simulator_.model()](
const Context& ectx)
2079 return getValue(ectx.fs.Rv()) *
2080 getValue(ectx.fs.invB(gasPhaseIdx)) *
2081 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2082 model.dofTotalVolume(ectx.globalDofIdx) *
2083 getValue(ectx.intQuants.porosity());
2087 Entry{PhaseEntry{std::array{
"BPPW"sv,
"BPPO"sv,
"BPPG"sv},
2088 [&simConfig = this->
eclState_.getSimulationConfig(),
2089 &grav = this->simulator_.problem().gravity(),
2091 &problem = this->simulator_.problem(),
2092 ®ions = this->
regions_](
const unsigned phaseIdx,
const Context& ectx)
2094 auto phase = RegionPhasePoreVolAverage::Phase{};
2095 phase.ix = phaseIdx;
2104 const auto datum = simConfig.datumDepths()(regions[
"FIPNUM"][ectx.dofIdx] - 1);
2107 const auto region = RegionPhasePoreVolAverage::Region {
2108 ectx.elemCtx.primaryVars(ectx.dofIdx, 0).pvtRegionIndex() + 1
2111 const auto density = regionAvgDensity->value(
"PVTNUM", phase, region);
2113 const auto press = getValue(ectx.fs.pressure(phase.ix));
2114 const auto dz = problem.dofCenterDepth(ectx.globalDofIdx) - datum;
2115 return press - density*dz*grav[GridView::dimensionworld - 1];
2119 Entry{ScalarEntry{
"BAMIP",
2120 [&model = this->simulator_.model()](
const Context& ectx)
2122 const Scalar rhoW = FluidSystem::referenceDensity(waterPhaseIdx,
2123 ectx.intQuants.pvtRegionIndex());
2124 return getValue(ectx.fs.invB(waterPhaseIdx)) *
2125 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2127 model.dofTotalVolume(ectx.globalDofIdx) *
2128 getValue(ectx.intQuants.porosity());
2132 Entry{ScalarEntry{
"BMMIP",
2133 [&model = this->simulator_.model()](
const Context& ectx)
2135 return getValue(ectx.intQuants.microbialConcentration()) *
2136 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2137 getValue(ectx.intQuants.porosity()) *
2138 model.dofTotalVolume(ectx.globalDofIdx);
2142 Entry{ScalarEntry{
"BMOIP",
2143 [&model = this->simulator_.model()](
const Context& ectx)
2145 return getValue(ectx.intQuants.oxygenConcentration()) *
2146 getValue(ectx.intQuants.porosity()) *
2147 model.dofTotalVolume(ectx.globalDofIdx);
2151 Entry{ScalarEntry{
"BMUIP",
2152 [&model = this->simulator_.model()](
const Context& ectx)
2154 return getValue(ectx.intQuants.ureaConcentration()) *
2155 getValue(ectx.intQuants.porosity()) *
2156 model.dofTotalVolume(ectx.globalDofIdx) * 1;
2160 Entry{ScalarEntry{
"BMBIP",
2161 [&model = this->simulator_.model()](
const Context& ectx)
2163 return model.dofTotalVolume(ectx.globalDofIdx) *
2164 getValue(ectx.intQuants.biofilmMass());
2168 Entry{ScalarEntry{
"BMCIP",
2169 [&model = this->simulator_.model()](
const Context& ectx)
2171 return model.dofTotalVolume(ectx.globalDofIdx) *
2172 getValue(ectx.intQuants.calciteMass());
2176 Entry{ScalarEntry{
"BGMIP",
2177 [&model = this->simulator_.model()](
const Context& ectx)
2179 Scalar result = getValue(ectx.fs.invB(gasPhaseIdx)) *
2180 getValue(ectx.fs.saturation(gasPhaseIdx));
2182 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2183 result += getValue(ectx.fs.Rs()) *
2184 getValue(ectx.fs.invB(oilPhaseIdx)) *
2185 getValue(ectx.fs.saturation(oilPhaseIdx));
2188 result += getValue(ectx.fs.Rsw()) *
2189 getValue(ectx.fs.invB(waterPhaseIdx)) *
2190 getValue(ectx.fs.saturation(waterPhaseIdx));
2192 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2193 ectx.intQuants.pvtRegionIndex());
2195 model.dofTotalVolume(ectx.globalDofIdx) *
2196 getValue(ectx.intQuants.porosity()) *
2201 Entry{ScalarEntry{
"BGMGP",
2202 [&model = this->simulator_.model()](
const Context& ectx)
2204 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2205 ectx.intQuants.pvtRegionIndex());
2206 return getValue(ectx.fs.invB(gasPhaseIdx)) *
2207 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2208 model.dofTotalVolume(ectx.globalDofIdx) *
2209 getValue(ectx.intQuants.porosity()) *
2214 Entry{ScalarEntry{
"BGMDS",
2215 [&model = this->simulator_.model()](
const Context& ectx)
2218 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2219 result = getValue(ectx.fs.Rs()) *
2220 getValue(ectx.fs.invB(oilPhaseIdx)) *
2221 getValue(ectx.fs.saturation(oilPhaseIdx));
2224 result = getValue(ectx.fs.Rsw()) *
2225 getValue(ectx.fs.invB(waterPhaseIdx)) *
2226 getValue(ectx.fs.saturation(waterPhaseIdx));
2228 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2229 ectx.intQuants.pvtRegionIndex());
2231 model.dofTotalVolume(ectx.globalDofIdx) *
2232 getValue(ectx.intQuants.porosity()) *
2237 Entry{ScalarEntry{
"BGMST",
2238 [&model = this->simulator_.model(),
2239 &problem = this->simulator_.problem()](
const Context& ectx)
2241 const auto& scaledDrainageInfo = problem.materialLawManager()
2242 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2243 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2244 Scalar strandedGas = scaledDrainageInfo.Sgcr;
2245 if (problem.materialLawManager()->enableHysteresis()) {
2246 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2247 const Scalar krg = getValue(ectx.intQuants.relativePermeability(gasPhaseIdx));
2248 strandedGas = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
2250 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2251 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2252 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2253 return (1.0 - xgW) *
2254 model.dofTotalVolume(ectx.globalDofIdx) *
2255 getValue(ectx.intQuants.porosity()) *
2256 getValue(ectx.fs.density(gasPhaseIdx)) *
2257 std::min(strandedGas, sg);
2261 Entry{ScalarEntry{
"BGMUS",
2262 [&model = this->simulator_.model(),
2263 &problem = this->simulator_.problem()](
const Context& ectx)
2265 const auto& scaledDrainageInfo = problem.materialLawManager()
2266 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2267 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2268 Scalar strandedGas = scaledDrainageInfo.Sgcr;
2269 if (problem.materialLawManager()->enableHysteresis()) {
2270 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2271 const Scalar krg = getValue(ectx.intQuants.relativePermeability(gasPhaseIdx));
2272 strandedGas = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
2274 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2275 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2276 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2277 return (1.0 - xgW) *
2278 model.dofTotalVolume(ectx.globalDofIdx) *
2279 getValue(ectx.intQuants.porosity()) *
2280 getValue(ectx.fs.density(gasPhaseIdx)) *
2281 std::max(Scalar{0.0}, sg - strandedGas);
2285 Entry{ScalarEntry{
"BGMTR",
2286 [&model = this->simulator_.model(),
2287 &problem = this->simulator_.problem()](
const Context& ectx)
2289 const auto& scaledDrainageInfo = problem.materialLawManager()
2290 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2291 Scalar trappedGas = scaledDrainageInfo.Sgcr;
2292 if (problem.materialLawManager()->enableHysteresis()) {
2293 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2294 trappedGas = MaterialLaw::trappedGasSaturation(matParams,
true);
2296 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2297 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2298 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2299 return (1.0 - xgW) *
2300 model.dofTotalVolume(ectx.globalDofIdx) *
2301 getValue(ectx.intQuants.porosity()) *
2302 getValue(ectx.fs.density(gasPhaseIdx)) *
2303 std::min(trappedGas, getValue(ectx.fs.saturation(gasPhaseIdx)));
2307 Entry{ScalarEntry{
"BGMMO",
2308 [&model = this->simulator_.model(),
2309 &problem = this->simulator_.problem()](
const Context& ectx)
2311 const auto& scaledDrainageInfo = problem.materialLawManager()
2312 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2313 Scalar trappedGas = scaledDrainageInfo.Sgcr;
2314 if (problem.materialLawManager()->enableHysteresis()) {
2315 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2316 trappedGas = MaterialLaw::trappedGasSaturation(matParams,
true);
2318 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2319 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2320 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2321 return (1.0 - xgW) *
2322 model.dofTotalVolume(ectx.globalDofIdx) *
2323 getValue(ectx.intQuants.porosity()) *
2324 getValue(ectx.fs.density(gasPhaseIdx)) *
2325 std::max(Scalar{0.0}, getValue(ectx.fs.saturation(gasPhaseIdx)) - trappedGas);
2329 Entry{ScalarEntry{
"BGKTR",
2330 [&model = this->simulator_.model(),
2331 &problem = this->simulator_.problem()](
const Context& ectx)
2333 const auto& scaledDrainageInfo = problem.materialLawManager()
2334 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2335 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2336 Scalar sgcr = scaledDrainageInfo.Sgcr;
2337 if (problem.materialLawManager()->enableHysteresis()) {
2338 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2339 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2345 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2346 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2347 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2348 return (1.0 - xgW) *
2349 model.dofTotalVolume(ectx.globalDofIdx) *
2350 getValue(ectx.intQuants.porosity()) *
2351 getValue(ectx.fs.density(gasPhaseIdx)) *
2352 getValue(ectx.fs.saturation(gasPhaseIdx));
2357 Entry{ScalarEntry{
"BGKMO",
2358 [&model = this->simulator_.model(),
2359 &problem = this->simulator_.problem()](
const Context& ectx)
2361 const auto& scaledDrainageInfo = problem.materialLawManager()
2362 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2363 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2364 Scalar sgcr = scaledDrainageInfo.Sgcr;
2365 if (problem.materialLawManager()->enableHysteresis()) {
2366 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2367 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2373 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2374 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2375 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2376 return (1.0 - xgW) *
2377 model.dofTotalVolume(ectx.globalDofIdx) *
2378 getValue(ectx.intQuants.porosity()) *
2379 getValue(ectx.fs.density(gasPhaseIdx)) *
2380 getValue(ectx.fs.saturation(gasPhaseIdx));
2385 Entry{ScalarEntry{
"BGCDI",
2386 [&model = this->simulator_.model(),
2387 &problem = this->simulator_.problem()](
const Context& ectx)
2389 const auto& scaledDrainageInfo = problem.materialLawManager()
2390 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2391 Scalar sgcr = scaledDrainageInfo.Sgcr;
2392 if (problem.materialLawManager()->enableHysteresis()) {
2393 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2394 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2396 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2397 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2398 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2399 return (1.0 - xgW) *
2400 model.dofTotalVolume(ectx.globalDofIdx) *
2401 getValue(ectx.intQuants.porosity()) *
2402 getValue(ectx.fs.density(gasPhaseIdx)) *
2403 std::min(sgcr, getValue(ectx.fs.saturation(gasPhaseIdx))) /
2404 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
2408 Entry{ScalarEntry{
"BGCDM",
2409 [&model = this->simulator_.model(),
2410 &problem = this->simulator_.problem()](
const Context& ectx)
2412 const auto& scaledDrainageInfo = problem.materialLawManager()
2413 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2414 Scalar sgcr = scaledDrainageInfo.Sgcr;
2415 if (problem.materialLawManager()->enableHysteresis()) {
2416 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2417 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2419 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2420 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2421 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2422 return (1.0 - xgW) *
2423 model.dofTotalVolume(ectx.globalDofIdx) *
2424 getValue(ectx.intQuants.porosity()) *
2425 getValue(ectx.fs.density(gasPhaseIdx)) *
2426 std::max(Scalar{0.0}, getValue(ectx.fs.saturation(gasPhaseIdx)) - sgcr) /
2427 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
2431 Entry{ScalarEntry{
"BGKDI",
2432 [&model = this->simulator_.model(),
2433 &problem = this->simulator_.problem()](
const Context& ectx)
2435 const auto& scaledDrainageInfo = problem.materialLawManager()
2436 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2437 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2438 Scalar sgcr = scaledDrainageInfo.Sgcr;
2439 if (problem.materialLawManager()->enableHysteresis()) {
2440 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2441 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2447 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2448 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2449 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2450 return (1.0 - xgW) *
2451 model.dofTotalVolume(ectx.globalDofIdx) *
2452 getValue(ectx.intQuants.porosity()) *
2453 getValue(ectx.fs.density(gasPhaseIdx)) *
2454 getValue(ectx.fs.saturation(gasPhaseIdx)) /
2455 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
2460 Entry{ScalarEntry{
"BGKDM",
2461 [&model = this->simulator_.model(),
2462 &problem = this->simulator_.problem()](
const Context& ectx)
2464 const auto& scaledDrainageInfo = problem.materialLawManager()
2465 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2466 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2467 Scalar sgcr = scaledDrainageInfo.Sgcr;
2468 if (problem.materialLawManager()->enableHysteresis()) {
2469 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2470 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
2476 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2477 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2478 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2479 return (1.0 - xgW) *
2480 model.dofTotalVolume(ectx.globalDofIdx) *
2481 getValue(ectx.intQuants.porosity()) *
2482 getValue(ectx.fs.density(gasPhaseIdx)) *
2483 getValue(ectx.fs.saturation(gasPhaseIdx)) /
2484 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
2489 Entry{ScalarEntry{
"BWCD",
2490 [&model = this->simulator_.model()](
const Context& ectx)
2493 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2494 result = getValue(ectx.fs.Rs()) *
2495 getValue(ectx.fs.invB(oilPhaseIdx)) *
2496 getValue(ectx.fs.saturation(oilPhaseIdx));
2499 result = getValue(ectx.fs.Rsw()) *
2500 getValue(ectx.fs.invB(waterPhaseIdx)) *
2501 getValue(ectx.fs.saturation(waterPhaseIdx));
2503 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2504 ectx.intQuants.pvtRegionIndex());
2506 model.dofTotalVolume(ectx.globalDofIdx) *
2507 getValue(ectx.intQuants.porosity()) *
2509 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
2513 Entry{ScalarEntry{
"BWIPG",
2514 [&model = this->simulator_.model()](
const Context& ectx)
2516 Scalar result = 0.0;
2517 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
2518 result = getValue(ectx.fs.Rvw()) *
2519 getValue(ectx.fs.invB(gasPhaseIdx)) *
2520 getValue(ectx.fs.saturation(gasPhaseIdx));
2523 model.dofTotalVolume(ectx.globalDofIdx) *
2524 getValue(ectx.intQuants.porosity());
2528 Entry{ScalarEntry{
"BWIPL",
2529 [&model = this->simulator_.model()](
const Context& ectx)
2531 return getValue(ectx.fs.invB(waterPhaseIdx)) *
2532 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2533 model.dofTotalVolume(ectx.globalDofIdx) *
2534 getValue(ectx.intQuants.porosity());
2543 if (reportStepNum > 0 && !isSubStep) {
2545 const auto& rpt = this->
schedule_[reportStepNum - 1].rpt_config.get();
2546 if (rpt.contains(
"WELLS") && rpt.at(
"WELLS") > 1) {
2548 [&c = this->collectOnIORank_](
const int idx)
2549 {
return c.isCartIdxOnThisRank(idx); });
2551 const auto extraHandlers = std::array{
2560 const Simulator& simulator_;
2561 const CollectDataOnIORankType& collectOnIORank_;
2562 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)
Definition: GenericOutputBlackoilModule.hpp:76
std::map< std::pair< std::string, int >, double > blockData_
Definition: GenericOutputBlackoilModule.hpp:456
std::array< ScalarBuffer, numPhases > relativePermeability_
Definition: GenericOutputBlackoilModule.hpp:445
ScalarBuffer fluidPressure_
Definition: GenericOutputBlackoilModule.hpp:399
std::array< ScalarBuffer, numPhases > density_
Definition: GenericOutputBlackoilModule.hpp:443
ScalarBuffer saturatedOilFormationVolumeFactor_
Definition: GenericOutputBlackoilModule.hpp:431
ScalarBuffer overburdenPressure_
Definition: GenericOutputBlackoilModule.hpp:405
ScalarBuffer gasDissolutionFactorInWater_
Definition: GenericOutputBlackoilModule.hpp:425
const EclipseState & eclState_
Definition: GenericOutputBlackoilModule.hpp:358
ScalarBuffer swmin_
Definition: GenericOutputBlackoilModule.hpp:421
ScalarBuffer rockCompPorvMultiplier_
Definition: GenericOutputBlackoilModule.hpp:429
RFTContainer< GetPropType< TypeTag, Properties::FluidSystem > > rftC_
Definition: GenericOutputBlackoilModule.hpp:453
bool computeFip_
Definition: GenericOutputBlackoilModule.hpp:381
ScalarBuffer dewPointPressure_
Definition: GenericOutputBlackoilModule.hpp:428
LogOutputHelper< Scalar > logOutput_
Definition: GenericOutputBlackoilModule.hpp:365
std::vector< int > failedCellsPb_
Definition: GenericOutputBlackoilModule.hpp:390
ScalarBuffer permFact_
Definition: GenericOutputBlackoilModule.hpp:414
ScalarBuffer rsw_
Definition: GenericOutputBlackoilModule.hpp:402
ScalarBuffer pcog_
Definition: GenericOutputBlackoilModule.hpp:436
std::optional< RegionPhasePoreVolAverage > regionAvgDensity_
Definition: GenericOutputBlackoilModule.hpp:464
std::array< ScalarBuffer, numPhases > invB_
Definition: GenericOutputBlackoilModule.hpp:442
ScalarBuffer pSalt_
Definition: GenericOutputBlackoilModule.hpp:413
ScalarBuffer cFoam_
Definition: GenericOutputBlackoilModule.hpp:411
ScalarBuffer bubblePointPressure_
Definition: GenericOutputBlackoilModule.hpp:427
ScalarBuffer temperature_
Definition: GenericOutputBlackoilModule.hpp:400
ScalarBuffer ppcw_
Definition: GenericOutputBlackoilModule.hpp:422
FIPContainer< GetPropType< TypeTag, Properties::FluidSystem > > fipC_
Definition: GenericOutputBlackoilModule.hpp:383
ScalarBuffer rockCompTransMultiplier_
Definition: GenericOutputBlackoilModule.hpp:432
MechContainer< Scalar > mech_
Definition: GenericOutputBlackoilModule.hpp:439
ScalarBuffer dynamicPoreVolume_
Definition: GenericOutputBlackoilModule.hpp:397
ScalarBuffer minimumOilPressure_
Definition: GenericOutputBlackoilModule.hpp:430
ScalarBuffer gasFormationVolumeFactor_
Definition: GenericOutputBlackoilModule.hpp:393
std::array< ScalarBuffer, numPhases > residual_
Definition: GenericOutputBlackoilModule.hpp:449
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:419
BioeffectsContainer< Scalar > bioeffectsC_
Definition: GenericOutputBlackoilModule.hpp:433
const Schedule & schedule_
Definition: GenericOutputBlackoilModule.hpp:359
FlowsContainer< GetPropType< TypeTag, Properties::FluidSystem > > flowsC_
Definition: GenericOutputBlackoilModule.hpp:451
ExtboContainer< Scalar > extboC_
Definition: GenericOutputBlackoilModule.hpp:415
void setupExtraBlockData(const std::size_t reportStepNum, std::function< bool(int)> isCartIdxOnThisRank)
ScalarBuffer oilSaturationPressure_
Definition: GenericOutputBlackoilModule.hpp:406
InterRegFlowMap interRegionFlows_
Definition: GenericOutputBlackoilModule.hpp:364
ScalarBuffer pcgw_
Definition: GenericOutputBlackoilModule.hpp:434
ScalarBuffer cPolymer_
Definition: GenericOutputBlackoilModule.hpp:410
void setupBlockData(std::function< bool(int)> isCartIdxOnThisRank)
ScalarBuffer rvw_
Definition: GenericOutputBlackoilModule.hpp:404
std::array< ScalarBuffer, numPhases > saturation_
Definition: GenericOutputBlackoilModule.hpp:441
std::unordered_map< std::string, std::vector< int > > regions_
Definition: GenericOutputBlackoilModule.hpp:384
ScalarBuffer rPorV_
Definition: GenericOutputBlackoilModule.hpp:398
ScalarBuffer oilVaporizationFactor_
Definition: GenericOutputBlackoilModule.hpp:424
std::vector< int > failedCellsPd_
Definition: GenericOutputBlackoilModule.hpp:391
ScalarBuffer rs_
Definition: GenericOutputBlackoilModule.hpp:401
ScalarBuffer drsdtcon_
Definition: GenericOutputBlackoilModule.hpp:407
ScalarBuffer sSol_
Definition: GenericOutputBlackoilModule.hpp:408
std::map< std::pair< std::string, int >, double > extraBlockData_
Definition: GenericOutputBlackoilModule.hpp:459
ScalarBuffer pressureTimesPoreVolume_
Definition: GenericOutputBlackoilModule.hpp:395
ScalarBuffer gasDissolutionFactor_
Definition: GenericOutputBlackoilModule.hpp:423
std::array< ScalarBuffer, numPhases > viscosity_
Definition: GenericOutputBlackoilModule.hpp:444
bool forceDisableFipOutput_
Definition: GenericOutputBlackoilModule.hpp:379
ScalarBuffer soMax_
Definition: GenericOutputBlackoilModule.hpp:416
ScalarBuffer sgmax_
Definition: GenericOutputBlackoilModule.hpp:418
ScalarBuffer somin_
Definition: GenericOutputBlackoilModule.hpp:420
ScalarBuffer hydrocarbonPoreVolume_
Definition: GenericOutputBlackoilModule.hpp:394
const std::optional< Inplace > & initialInplace() const
Definition: GenericOutputBlackoilModule.hpp:246
ScalarBuffer waterVaporizationFactor_
Definition: GenericOutputBlackoilModule.hpp:426
ScalarBuffer cSalt_
Definition: GenericOutputBlackoilModule.hpp:412
TracerContainer< GetPropType< TypeTag, Properties::FluidSystem > > tracerC_
Definition: GenericOutputBlackoilModule.hpp:447
ScalarBuffer rv_
Definition: GenericOutputBlackoilModule.hpp:403
ScalarBuffer pcow_
Definition: GenericOutputBlackoilModule.hpp:435
ScalarBuffer swMax_
Definition: GenericOutputBlackoilModule.hpp:417
ScalarBuffer pressureTimesHydrocarbonVolume_
Definition: GenericOutputBlackoilModule.hpp:396
ScalarBuffer rswSol_
Definition: GenericOutputBlackoilModule.hpp:409
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:240
void initializeFluxData()
Prepare for capturing connection fluxes, particularly to account for inter-region flows.
Definition: OutputBlackoilModule.hpp:484
void setupExtractors(const bool isSubStep, const int reportStepNum)
Setup list of active element-level data extractors.
Definition: OutputBlackoilModule.hpp:221
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:199
void processFluxes(const ElementContext &elemCtx, ActiveIndex &&activeIndex, CartesianIndex &&cartesianIndex)
Capture connection fluxes, particularly to account for inter-region flows.
Definition: OutputBlackoilModule.hpp:447
void clearExtractors()
Clear list of active element-level data extractors.
Definition: OutputBlackoilModule.hpp:229
void outputFipAndResvLogToCSV(const std::size_t reportStepNum, const bool substep, const Parallel::Communication &comm)
Definition: OutputBlackoilModule.hpp:381
void assignToFluidState(FluidState &fs, unsigned elemIdx) const
Definition: OutputBlackoilModule.hpp:508
void initHysteresisParams(Simulator &simulator, unsigned elemIdx) const
Definition: OutputBlackoilModule.hpp:560
void updateFluidInPlace(const ElementContext &elemCtx)
Definition: OutputBlackoilModule.hpp:625
OutputBlackOilModule(const Simulator &simulator, const SummaryConfig &smryCfg, const CollectDataOnIORankType &collectOnIORank)
Definition: OutputBlackoilModule.hpp:136
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:330
const InterRegFlowMap & getInterRegFlows() const
Get read-only access to collection of inter-region flows.
Definition: OutputBlackoilModule.hpp:502
void processElementBlockData(const ElementContext &elemCtx)
Definition: OutputBlackoilModule.hpp:286
void finalizeFluxData()
Finalize capturing connection fluxes.
Definition: OutputBlackoilModule.hpp:494
void updateFluidInPlace(const unsigned globalDofIdx, const IntensiveQuantities &intQuants, const double totVolume)
Definition: OutputBlackoilModule.hpp:632
Declare the properties used by the infrastructure code of the finite volume discretizations.
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
Definition: blackoilbioeffectsmodules.hh:43
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