27#ifndef OPM_OUTPUT_BLACK_OIL_MODULE_HPP
28#define OPM_OUTPUT_BLACK_OIL_MODULE_HPP
30#include <dune/common/fvector.hh>
32#include <opm/grid/CpGrid.hpp>
33#include <opm/grid/LookUpData.hh>
37#include <opm/common/Exceptions.hpp>
38#include <opm/common/TimingMacros.hpp>
39#include <opm/common/OpmLog/OpmLog.hpp>
40#include <opm/common/utility/Visitor.hpp>
42#include <opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.hpp>
44#include <opm/material/common/Valgrind.hpp>
45#include <opm/material/fluidmatrixinteractions/EclEpsScalingPoints.hpp>
46#include <opm/material/fluidstates/BlackOilFluidState.hpp>
47#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
54#include <opm/output/data/Cells.hpp>
55#include <opm/output/data/RegionVariableMapping.hpp>
57#include <opm/output/eclipse/EclipseIO.hpp>
58#include <opm/output/eclipse/Inplace.hpp>
59#include <opm/output/eclipse/RegionVariableCollection.hpp>
83template <
class TypeTag>
84class EcfvDiscretization;
88 template <
typename... T>
98template <
class TypeTag>
110 using FluidState =
typename IntensiveQuantities::FluidState;
112 using Element =
typename GridView::template Codim<0>::Entity;
113 using ElementIterator =
typename GridView::template Codim<0>::Iterator;
116 using Dir = FaceDir::DirEnum;
123 static constexpr int conti0EqIdx = Indices::conti0EqIdx;
124 static constexpr int numPhases = FluidSystem::numPhases;
125 static constexpr int oilPhaseIdx = FluidSystem::oilPhaseIdx;
126 static constexpr int gasPhaseIdx = FluidSystem::gasPhaseIdx;
127 static constexpr int waterPhaseIdx = FluidSystem::waterPhaseIdx;
128 static constexpr int gasCompIdx = FluidSystem::gasCompIdx;
129 static constexpr int oilCompIdx = FluidSystem::oilCompIdx;
130 static constexpr int waterCompIdx = FluidSystem::waterCompIdx;
131 static constexpr EnergyModules energyModuleType = getPropValue<TypeTag, Properties::EnergyModuleType>();
132 static constexpr bool enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
133 static constexpr bool enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>();
134 static constexpr bool enableFoam = getPropValue<TypeTag, Properties::EnableFoam>();
135 static constexpr bool enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>();
136 static constexpr bool enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>();
137 enum { enableMICP = Indices::enableMICP };
138 enum { enableVapwat = getPropValue<TypeTag, Properties::EnableVapwat>() };
139 enum { enableDisgasInWater = getPropValue<TypeTag, Properties::EnableDisgasInWater>() };
140 static constexpr bool enableDissolvedGas =
141 Indices::compositionSwitchIdx != std::numeric_limits<unsigned>::max();
143 template<
class VectorType>
144 static Scalar value_or_zero(
int idx,
const VectorType& v)
149 return v.empty() ? 0.0 : v[idx];
154 const SummaryConfig& smryCfg,
156 :
BaseType(simulator.vanguard().eclState(),
157 simulator.vanguard().schedule(),
159 simulator.vanguard().summaryState(),
161 [this](const int idx)
162 {
return simulator_.problem().eclWriter().collectOnIORank().localIdxToGlobalIdx(idx); },
163 [&collectOnIORank](
const int idx)
164 {
return collectOnIORank.isCartIdxOnThisRank(idx); },
165 simulator.vanguard().grid().comm(),
166 energyModuleType == EnergyModules::FullyImplicitThermal ||
167 energyModuleType == EnergyModules::SequentialImplicitThermal,
168 energyModuleType == EnergyModules::ConstantTemperature,
169 getPropValue<TypeTag, Properties::EnableMech>(),
170 getPropValue<TypeTag, Properties::EnableSolvent>(),
171 getPropValue<TypeTag, Properties::EnablePolymer>(),
172 getPropValue<TypeTag, Properties::EnableFoam>(),
173 getPropValue<TypeTag, Properties::EnableBrine>(),
174 getPropValue<TypeTag, Properties::EnableSaltPrecipitation>(),
175 getPropValue<TypeTag, Properties::EnableExtbo>(),
176 getPropValue<TypeTag, Properties::EnableBioeffects>(),
177 getPropValue<TypeTag, Properties::EnableGeochemistry>())
178 , simulator_(simulator)
179 , collectOnIORank_(collectOnIORank)
185 this->mapRegionsOntoLeaf_();
187 for (
auto& region_pair : this->
regions_) {
188 this->createLocalRegion_(region_pair.second);
191 auto isCartIdxOnThisRank = [&collectOnIORank](
const int idx) {
192 return collectOnIORank.isCartIdxOnThisRank(idx);
204 std::set<std::pair<int, int>> ownedLgrCells;
205 std::map<std::string, int> lgrNameToLevel;
206 if constexpr (std::is_same_v<Grid, Dune::CpGrid>) {
209 lgrNameToLevel = simulator.vanguard().grid().getLgrNameToLevel();
210 for (
const auto& element : elements(simulator.gridView())) {
211 const int level = element.level();
212 if (level > 0 && element.partitionType() == Dune::InteriorEntity) {
213 const int levelCompressed = element.getLevelElem().index();
214 const int levelCart = simulator.vanguard()
215 .levelCartesianIndexMapper()
216 .cartesianIndex(levelCompressed, level);
217 ownedLgrCells.emplace(level, levelCart);
223 [&ownedLgrCells](
const int level,
const int levelCart) {
224 return ownedLgrCells.count(std::make_pair(level, levelCart)) > 0;
227 if (! Parameters::Get<Parameters::OwnerCellsFirst>()) {
228 const std::string msg =
"The output code does not support --owner-cells-first=false.";
229 if (collectOnIORank.isIORank()) {
232 OPM_THROW_NOLOG(std::runtime_error, msg);
235 if (smryCfg.match(
"[FB]PP[OGW]") || smryCfg.match(
"RPP[OGW]*")) {
236 auto rset = this->
eclState_.fieldProps().fip_regions();
237 rset.push_back(
"PVTNUM");
245 const LookUpData<Grid, GridView> lookUpData(this->simulator_.gridView());
246 auto pvtnum = lookUpData.template assignFieldPropsIntOnLeaf<int>(
247 this->
eclState_.fieldProps(),
"PVTNUM",
false);
250 .emplace(this->simulator_.gridView().comm(),
251 FluidSystem::numPhases, rset,
252 [®ions = std::as_const(this->regions_),
253 pvtnum = std::move(pvtnum)]
254 (
const std::string& rsetName) ->
decltype(
auto)
256 return (rsetName ==
"PVTNUM")
257 ? static_cast<const std::vector<int>&>(pvtnum)
258 : static_cast<const std::vector<int>&>(regions.at(rsetName));
269 const unsigned reportStepNum,
272 const bool forceRestartFieldAllocation)
278 const auto& problem = this->simulator_.problem();
284 forceRestartFieldAllocation,
285 &problem.materialLawManager()->hysteresisConfig(),
286 problem.eclWriter().getOutputNnc().front().size());
291 const int reportStepNum)
293 this->setupElementExtractors_();
294 this->setupBlockExtractors_(isSubStep, reportStepNum);
300 this->extractors_.clear();
301 this->blockExtractors_.clear();
302 this->extraBlockExtractors_.clear();
303 this->lgrBlockExtractors_.clear();
314 using M = UnitSystem::measure;
315 this->
assignBuffer(sol,
"1OVERBO", M::oil_inverse_formation_volume_factor,
316 this->invB_[oilPhaseIdx], oilPhaseIdx);
317 this->
assignBuffer(sol,
"1OVERBG", M::gas_inverse_formation_volume_factor,
318 this->invB_[gasPhaseIdx], gasPhaseIdx);
320 this->relativePermeability_[oilPhaseIdx], oilPhaseIdx);
322 this->relativePermeability_[gasPhaseIdx], gasPhaseIdx);
323 this->
assignBuffer(sol,
"PBUB", M::pressure, this->bubblePointPressure_);
324 this->
assignBuffer(sol,
"PDEW", M::pressure, this->dewPointPressure_);
325 this->
assignBuffer(sol,
"RS", M::gas_oil_ratio, this->rs_);
326 this->
assignBuffer(sol,
"RV", M::oil_gas_ratio, this->rv_);
329 if constexpr (numPhases > 2) {
330 this->
assignBuffer(sol,
"1OVERBW", M::water_inverse_formation_volume_factor,
331 this->invB_[waterPhaseIdx], waterPhaseIdx);
333 this->relativePermeability_[waterPhaseIdx], waterPhaseIdx);
340 .gasDensity =
"GAS_DEN",
341 .waterDensity =
"WAT_DEN",
342 .oilViscosity =
"OIL_VISC",
343 .gasViscosity =
"GAS_VISC",
344 .waterViscosity =
"WAT_VISC",
359 if (this->extractors_.empty()) {
363 const auto& matLawManager = simulator_.problem().materialLawManager();
366 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
367 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
368 const auto& fs = intQuants.fluidState();
371 elemCtx.globalSpaceIndex(dofIdx, 0),
372 elemCtx.primaryVars(dofIdx, 0).pvtRegionIndex(),
379 if (matLawManager->enableHysteresis()) {
380 if (FluidSystem::phaseIsActive(oilPhaseIdx) && FluidSystem::phaseIsActive(waterPhaseIdx)) {
381 matLawManager->oilWaterHysteresisParams(hysterParams.
somax,
386 if (FluidSystem::phaseIsActive(oilPhaseIdx) && FluidSystem::phaseIsActive(gasPhaseIdx)) {
387 matLawManager->gasOilHysteresisParams(hysterParams.
sgmax,
405 if (this->blockExtractors_.empty() &&
406 this->extraBlockExtractors_.empty() &&
407 this->lgrBlockExtractors_.empty())
418 const auto& element = elemCtx.element();
419 const int level = element.level();
421 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
422 const auto globalDofIdx = elemCtx.globalSpaceIndex(dofIdx, 0);
424 const std::vector<typename BlockExtractor::Exec>* be_extractors =
nullptr;
425 const std::vector<typename BlockExtractor::Exec>* bee_extractors =
nullptr;
426 const std::vector<typename BlockExtractor::Exec>* lgr_extractors =
nullptr;
429 const auto cartesianIdx = elemCtx.simulator().vanguard().cartesianIndex(globalDofIdx);
430 const auto be_it = this->blockExtractors_.find(cartesianIdx);
431 const auto bee_it = this->extraBlockExtractors_.find(cartesianIdx);
432 if (be_it != this->blockExtractors_.end()) { be_extractors = &be_it->second; }
433 if (bee_it != this->extraBlockExtractors_.end()) { bee_extractors = &bee_it->second; }
435 else if constexpr (std::is_same_v<Grid, Dune::CpGrid>) {
447 const auto level_it = this->lgrBlockExtractors_.find(level);
448 if (level_it != this->lgrBlockExtractors_.end() &&
449 element.partitionType() == Dune::InteriorEntity)
451 const int levelCompressed = element.getLevelElem().index();
452 const int levelCart = elemCtx.simulator().vanguard()
453 .levelCartesianIndexMapper()
454 .cartesianIndex(levelCompressed, level);
455 const auto cell_it = level_it->second.find(levelCart);
456 if (cell_it != level_it->second.end()) {
457 lgr_extractors = &cell_it->second;
462 if (be_extractors ==
nullptr &&
463 bee_extractors ==
nullptr &&
464 lgr_extractors ==
nullptr)
469 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
470 const auto& fs = intQuants.fluidState();
487 const std::size_t reportStepNum,
489 boost::posix_time::ptime currentDate,
494 if (comm.rank() != 0) {
499 std::unique_ptr<FIPConfig> fipSched;
500 if (reportStepNum > 0) {
501 const auto& rpt = this->
schedule_[reportStepNum-1].rpt_config.get();
502 fipSched = std::make_unique<FIPConfig>(rpt);
504 const FIPConfig& fipc = reportStepNum == 0 ? this->
eclState_.getEclipseConfig().fip()
509 this->
logOutput_.timeStamp(
"BALANCE", elapsed, reportStepNum, currentDate);
512 this->
logOutput_.fip(inplace, initial_inplace,
"");
514 if (fipc.output(FIPConfig::OutputField::FIPNUM)) {
515 this->
logOutput_.fip(inplace, initial_inplace,
"FIPNUM");
517 if (fipc.output(FIPConfig::OutputField::RESV))
521 if (fipc.output(FIPConfig::OutputField::FIP)) {
522 for (
const auto& reg : this->regions_) {
523 if (reg.first !=
"FIPNUM") {
524 std::ostringstream ss;
525 ss <<
"BAL" << reg.first.substr(3);
526 this->
logOutput_.timeStamp(ss.str(), elapsed, reportStepNum, currentDate);
527 this->
logOutput_.fip(inplace, initial_inplace, reg.first);
529 if (fipc.output(FIPConfig::OutputField::RESV))
541 if (comm.rank() != 0) {
545 if ((reportStepNum == 0) && (!substep) &&
546 (this->
schedule_.initialReportConfiguration().has_value()) &&
547 (this->schedule_.initialReportConfiguration()->contains(
"CSVFIP"))) {
549 std::ostringstream csv_stream;
555 this->
logOutput_.fip_csv(csv_stream, initial_inplace,
"FIPNUM");
557 for (
const auto& reg : this->regions_) {
558 if (reg.first !=
"FIPNUM") {
559 this->
logOutput_.fip_csv(csv_stream, initial_inplace, reg.first);
563 const IOConfig& io = this->
eclState_.getIOConfig();
564 auto csv_fname = io.getOutputDir() +
"/" + io.getBaseName() +
".CSV";
566 std::ofstream outputFile(csv_fname);
568 outputFile << csv_stream.str();
602 template <
class ActiveIndex,
class CartesianIndex>
604 ActiveIndex&& activeIndex,
605 CartesianIndex&& cartesianIndex)
608 const auto identifyCell = [&activeIndex, &cartesianIndex](
const Element& elem)
611 const auto cellIndex = activeIndex(elem);
614 static_cast<int>(cellIndex),
615 cartesianIndex(cellIndex),
616 elem.partitionType() == Dune::InteriorEntity
620 const auto timeIdx = 0u;
621 const auto& stencil = elemCtx.stencil(timeIdx);
622 const auto numInteriorFaces = elemCtx.numInteriorFaces(timeIdx);
624 for (
auto scvfIdx = 0 * numInteriorFaces; scvfIdx < numInteriorFaces; ++scvfIdx) {
625 const auto& face = stencil.interiorFace(scvfIdx);
626 const auto left = identifyCell(stencil.element(face.interiorIndex()));
627 const auto right = identifyCell(stencil.element(face.exteriorIndex()));
629 const auto rates = this->
630 getComponentSurfaceRates(elemCtx, face.area(), scvfIdx, timeIdx);
663 template <
class Flu
idState>
666 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
670 fs.setSaturation(phaseIdx, this->
saturation_[phaseIdx][elemIdx]);
676 std::array<Scalar, numPhases> pc = {0};
677 const MaterialLawParams& matParams = simulator_.problem().materialLawParams(elemIdx);
678 MaterialLaw::capillaryPressures(pc, matParams, fs);
680 Valgrind::CheckDefined(pc);
682 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
683 if (!FluidSystem::phaseIsActive(phaseIdx))
686 if (Indices::oilEnabled)
687 fs.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[oilPhaseIdx]));
688 else if (Indices::gasEnabled)
689 fs.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[gasPhaseIdx]));
690 else if (Indices::waterEnabled)
692 fs.setPressure(phaseIdx, pressure);
696 if constexpr (energyModuleType != EnergyModules::NoTemperature) {
698 fs.setTemperature(this->temperature_[elemIdx]);
700 if constexpr (enableDissolvedGas) {
701 if (!this->rs_.empty())
702 fs.setRs(this->rs_[elemIdx]);
703 if (!this->rv_.empty())
704 fs.setRv(this->rv_[elemIdx]);
706 if constexpr (enableDisgasInWater) {
707 if (!this->
rsw_.empty())
708 fs.setRsw(this->rsw_[elemIdx]);
710 if constexpr (enableVapwat) {
711 if (!this->
rvw_.empty())
712 fs.setRvw(this->rvw_[elemIdx]);
718 if (!this->
soMax_.empty())
719 simulator.problem().setMaxOilSaturation(elemIdx, this->
soMax_[elemIdx]);
721 if (simulator.problem().materialLawManager()->enableHysteresis()) {
722 auto matLawManager = simulator.problem().materialLawManager();
724 if (FluidSystem::phaseIsActive(oilPhaseIdx)
725 && FluidSystem::phaseIsActive(waterPhaseIdx)) {
730 if (matLawManager->enableNonWettingHysteresis()) {
731 if (!this->
soMax_.empty()) {
732 somax = this->
soMax_[elemIdx];
735 if (matLawManager->enableWettingHysteresis()) {
736 if (!this->
swMax_.empty()) {
737 swmax = this->
swMax_[elemIdx];
740 if (matLawManager->enablePCHysteresis()) {
741 if (!this->
swmin_.empty()) {
742 swmin = this->
swmin_[elemIdx];
745 matLawManager->setOilWaterHysteresisParams(
746 somax, swmax, swmin, elemIdx);
748 if (FluidSystem::phaseIsActive(oilPhaseIdx)
749 && FluidSystem::phaseIsActive(gasPhaseIdx)) {
754 if (matLawManager->enableNonWettingHysteresis()) {
755 if (!this->
sgmax_.empty()) {
756 sgmax = this->
sgmax_[elemIdx];
759 if (matLawManager->enableWettingHysteresis()) {
760 if (!this->
shmax_.empty()) {
761 shmax = this->
shmax_[elemIdx];
764 if (matLawManager->enablePCHysteresis()) {
765 if (!this->
somin_.empty()) {
766 somin = this->
somin_[elemIdx];
769 matLawManager->setGasOilHysteresisParams(
770 sgmax, shmax, somin, elemIdx);
775 if (simulator_.vanguard().eclState().fieldProps().has_double(
"SWATINIT")) {
776 simulator.problem().materialLawManager()
777 ->applyRestartSwatInit(elemIdx, this->
ppcw_[elemIdx]);
783 for (
unsigned dofIdx = 0; dofIdx < elemCtx.numPrimaryDof(0); ++dofIdx) {
784 updateFluidInPlace_(elemCtx, dofIdx);
789 const IntensiveQuantities& intQuants,
790 const double totVolume)
792 this->updateFluidInPlace_(globalDofIdx, intQuants, totVolume);
797 const unsigned elemIdx,
798 const unsigned globalDofIndex)
override
802 auto assign = [&sol, elemIdx, globalDofIndex](
const std::string& name,
805 if (!data.empty() && sol.has(name)) {
806 data[elemIdx] = sol.data<
double>(name)[globalDofIndex];
818 const unsigned bufferSize)
override
823 FluidSystem::enableDissolvedGas(),
true);
825 FluidSystem::enableVaporizedOil(),
true);
829 bubblePointPressure_,
"PBPD",
true)) {
830 dewPointPressure_.resize(bufferSize, 0.0);
834 constexpr auto phaseChar = std::string_view{
"WOG"};
835 for (
unsigned phase = 0; phase < numPhases; ++phase) {
836 if (!FluidSystem::phaseIsActive(phase)) {
842 std::string(
"B") + phaseChar[phase],
true);
844 std::string(
"KR") + phaseChar[phase],
true);
854 ScalarBuffer bubblePointPressure_;
855 ScalarBuffer dewPointPressure_;
856 std::array<ScalarBuffer, numPhases> invB_;
857 std::array<ScalarBuffer, numPhases> relativePermeability_;
858 template <
typename T>
859 using RemoveCVR = std::remove_cv_t<std::remove_reference_t<T>>;
861 template <
typename,
class =
void>
862 struct HasGeoMech :
public std::false_type {};
864 template <
typename Problem>
866 Problem, std::void_t<decltype(std::declval<Problem>().geoMechModel())>
867 > :
public std::true_type {};
869 template <
typename,
class =
void>
870 struct HasGeochemistry :
public std::false_type {};
872 template <
typename Problem>
873 struct HasGeochemistry<
874 Problem, std::void_t<decltype(std::declval<Problem>().geochemistryModel())>
875 > :
public std::true_type {};
877 bool isDefunctParallelWell(
const std::string& wname)
const override
879 if (simulator_.gridView().comm().size() == 1)
881 const auto& parallelWells = simulator_.vanguard().parallelWells();
882 std::pair<std::string, bool> value {wname,
true};
883 auto candidate = std::lower_bound(parallelWells.begin(), parallelWells.end(), value);
884 return candidate == parallelWells.end() || *candidate != value;
887 bool isOwnedByCurrentRank(
const std::string& wname)
const override
889 return this->simulator_.problem().wellModel().isOwner(wname);
892 bool isOnCurrentRank(
const std::string& wname)
const override
894 return this->simulator_.problem().wellModel().hasLocalCells(wname);
897 void updateFluidInPlace_(
const ElementContext& elemCtx,
const unsigned dofIdx)
899 const auto& intQuants = elemCtx.intensiveQuantities(dofIdx, 0);
900 const unsigned globalDofIdx = elemCtx.globalSpaceIndex(dofIdx, 0);
901 const auto totVolume = elemCtx.simulator().model().dofTotalVolume(globalDofIdx);
903 this->updateFluidInPlace_(globalDofIdx, intQuants, totVolume);
906 void updateFluidInPlace_(
const unsigned globalDofIdx,
907 const IntensiveQuantities& intQuants,
908 const double totVolume)
915 intQuants.referencePorosity());
918 this->updatePhaseInplaceVolumes_(globalDofIdx, intQuants, totVolume);
926 void mapRegionsOntoLeaf_()
928 const LookUpData<Grid, GridView> lookUpData(simulator_.gridView());
929 const auto numLeaf = simulator_.gridView().size(0);
931 std::vector<int> onLeaf(numLeaf, 0);
932 for (
auto& [name, region] : this->regions_) {
933 std::size_t elemIdx = 0;
934 for (
const auto& elem : elements(simulator_.gridView())) {
935 onLeaf[elemIdx++] = lookUpData(elem, region);
942 void createLocalRegion_(std::vector<int>& region)
944 std::size_t elemIdx = 0;
945 for (
const auto& elem : elements(simulator_.gridView())) {
946 if (elem.partitionType() != Dune::InteriorEntity) {
954 template <
typename Flu
idState>
955 void aggregateAverageDensityContributions_(
const FluidState& fs,
956 const unsigned int globalDofIdx,
959 auto pvCellValue = RegionPhasePoreVolAverage::CellValue{};
960 pvCellValue.porv = porv;
962 for (
auto phaseIdx = 0*FluidSystem::numPhases;
963 phaseIdx < FluidSystem::numPhases; ++phaseIdx)
965 if (! FluidSystem::phaseIsActive(phaseIdx)) {
969 pvCellValue.value = getValue(fs.density(phaseIdx));
970 pvCellValue.sat = getValue(fs.saturation(phaseIdx));
973 ->addCell(globalDofIdx,
994 data::InterRegFlowMap::FlowRates
995 getComponentSurfaceRates(
const ElementContext& elemCtx,
996 const Scalar faceArea,
997 const std::size_t scvfIdx,
998 const std::size_t timeIdx)
const
1000 using Component = data::InterRegFlowMap::Component;
1002 auto rates = data::InterRegFlowMap::FlowRates {};
1004 const auto& extQuant = elemCtx.extensiveQuantities(scvfIdx, timeIdx);
1006 const auto alpha = getValue(extQuant.extrusionFactor()) * faceArea;
1008 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1009 const auto& up = elemCtx
1010 .intensiveQuantities(extQuant.upstreamIndex(oilPhaseIdx), timeIdx);
1012 const auto pvtReg = up.pvtRegionIndex();
1014 const auto bO = getValue(getInvB_<FluidSystem, FluidState, Scalar>
1015 (up.fluidState(), oilPhaseIdx, pvtReg));
1017 const auto qO = alpha * bO * getValue(extQuant.volumeFlux(oilPhaseIdx));
1019 rates[Component::Oil] += qO;
1021 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1022 const auto Rs = getValue(
1023 BlackOil::getRs_<FluidSystem, FluidState, Scalar>
1024 (up.fluidState(), pvtReg));
1026 rates[Component::Gas] += qO *
Rs;
1027 rates[Component::Disgas] += qO *
Rs;
1031 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1032 const auto& up = elemCtx
1033 .intensiveQuantities(extQuant.upstreamIndex(gasPhaseIdx), timeIdx);
1035 const auto pvtReg = up.pvtRegionIndex();
1037 const auto bG = getValue(getInvB_<FluidSystem, FluidState, Scalar>
1038 (up.fluidState(), gasPhaseIdx, pvtReg));
1040 const auto qG = alpha * bG * getValue(extQuant.volumeFlux(gasPhaseIdx));
1042 rates[Component::Gas] += qG;
1044 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1045 const auto Rv = getValue(
1046 BlackOil::getRv_<FluidSystem, FluidState, Scalar>
1047 (up.fluidState(), pvtReg));
1049 rates[Component::Oil] += qG *
Rv;
1050 rates[Component::Vapoil] += qG *
Rv;
1054 if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
1055 const auto& up = elemCtx
1056 .intensiveQuantities(extQuant.upstreamIndex(waterPhaseIdx), timeIdx);
1058 const auto pvtReg = up.pvtRegionIndex();
1060 const auto bW = getValue(getInvB_<FluidSystem, FluidState, Scalar>
1061 (up.fluidState(), waterPhaseIdx, pvtReg));
1063 rates[Component::Water] +=
1064 alpha * bW * getValue(extQuant.volumeFlux(waterPhaseIdx));
1070 void updatePhaseInplaceVolumes_(
const unsigned globalDofIdx,
1071 const IntensiveQuantities& intQuants,
1072 const double totVolume)
1074 std::array<Scalar, FluidSystem::numPhases> fip {};
1075 std::array<Scalar, FluidSystem::numPhases> fipr{};
1077 const auto& fs = intQuants.fluidState();
1078 const auto pv = totVolume * intQuants.porosity().value();
1080 for (
unsigned phaseIdx = 0; phaseIdx < FluidSystem::numPhases; ++phaseIdx) {
1081 if (!FluidSystem::phaseIsActive(phaseIdx)) {
1085 const auto b = getValue(fs.invB(phaseIdx));
1086 const auto s = getValue(fs.saturation(phaseIdx));
1088 fipr[phaseIdx] = s * pv;
1089 fip [phaseIdx] = b * fipr[phaseIdx];
1094 fs.saltConcentration().value(),
1097 if (FluidSystem::phaseIsActive(oilPhaseIdx) &&
1098 FluidSystem::phaseIsActive(gasPhaseIdx))
1100 this->updateOilGasDistribution(globalDofIdx, fs, fip);
1103 if (FluidSystem::phaseIsActive(waterPhaseIdx) &&
1104 FluidSystem::phaseIsActive(gasPhaseIdx))
1106 this->updateGasWaterDistribution(globalDofIdx, fs, fip);
1109 if (FluidSystem::phaseIsActive(gasPhaseIdx) &&
1112 this->updateCO2InGas(globalDofIdx, pv, intQuants);
1116 (FluidSystem::phaseIsActive(waterPhaseIdx) ||
1117 FluidSystem::phaseIsActive(oilPhaseIdx)))
1119 this->updateCO2InWater(globalDofIdx, pv, fs);
1122 if constexpr(enableBioeffects) {
1123 const auto surfVolWat = pv * getValue(fs.saturation(waterPhaseIdx)) *
1124 getValue(fs.invB(waterPhaseIdx));
1126 this->updateMicrobialMass(globalDofIdx, intQuants, surfVolWat);
1129 this->updateBiofilmMass(globalDofIdx, intQuants, totVolume);
1131 if constexpr(enableMICP) {
1133 this->updateOxygenMass(globalDofIdx, intQuants, surfVolWat);
1136 this->updateUreaMass(globalDofIdx, intQuants, surfVolWat);
1139 this->updateCalciteMass(globalDofIdx, intQuants, totVolume);
1146 this->updateWaterMass(globalDofIdx, fs, fip);
1150 template <
typename Flu
idState,
typename FIPArray>
1151 void updateOilGasDistribution(
const unsigned globalDofIdx,
1152 const FluidState& fs,
1153 const FIPArray& fip)
1156 const auto gasInPlaceLiquid = getValue(fs.Rs()) * fip[oilPhaseIdx];
1157 const auto oilInPlaceGas = getValue(fs.Rv()) * fip[gasPhaseIdx];
1162 template <
typename Flu
idState,
typename FIPArray>
1163 void updateGasWaterDistribution(
const unsigned globalDofIdx,
1164 const FluidState& fs,
1165 const FIPArray& fip)
1168 const auto gasInPlaceWater = getValue(fs.Rsw()) * fip[waterPhaseIdx];
1169 const auto waterInPlaceGas = getValue(fs.Rvw()) * fip[gasPhaseIdx];
1174 template <
typename IntensiveQuantities>
1175 void updateCO2InGas(
const unsigned globalDofIdx,
1177 const IntensiveQuantities& intQuants)
1179 const auto& scaledDrainageInfo = this->simulator_.problem().materialLawManager()
1180 ->oilWaterScaledEpsInfoDrainage(globalDofIdx);
1182 const auto& fs = intQuants.fluidState();
1183 Scalar sgcr = scaledDrainageInfo.Sgcr;
1184 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1185 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1186 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
1189 Scalar trappedGasSaturation = scaledDrainageInfo.Sgcr;
1190 if (this->
fipC_.
has(Inplace::Phase::CO2MassInGasPhaseMaximumTrapped) ||
1191 this->fipC_.has(Inplace::Phase::CO2MassInGasPhaseMaximumUnTrapped))
1193 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1194 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1196 trappedGasSaturation = MaterialLaw::trappedGasSaturation(matParams,
true);
1200 const Scalar sg = getValue(fs.saturation(gasPhaseIdx));
1201 Scalar strandedGasSaturation = scaledDrainageInfo.Sgcr;
1202 if (this->
fipC_.
has(Inplace::Phase::CO2MassInGasPhaseEffectiveTrapped) ||
1203 this->fipC_.has(Inplace::Phase::CO2MassInGasPhaseEffectiveUnTrapped))
1205 if (this->simulator_.problem().materialLawManager()->enableHysteresis()) {
1206 const auto& matParams = simulator_.problem().materialLawParams(globalDofIdx);
1207 const double krg = getValue(intQuants.relativePermeability(gasPhaseIdx));
1208 strandedGasSaturation = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
1212 const typename FIPContainer<FluidSystem>::Co2InGasInput v{
1216 getValue(fs.density(gasPhaseIdx)),
1217 FluidSystem::phaseIsActive(waterPhaseIdx)
1218 ? FluidSystem::convertRvwToXgW(getValue(fs.Rvw()), fs.pvtRegionIndex())
1219 : FluidSystem::convertRvToXgO(getValue(fs.
Rv()), fs.pvtRegionIndex()),
1220 FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex()),
1221 trappedGasSaturation,
1222 strandedGasSaturation,
1228 template <
typename Flu
idState>
1229 void updateCO2InWater(
const unsigned globalDofIdx,
1231 const FluidState& fs)
1233 const auto co2InWater = FluidSystem::phaseIsActive(oilPhaseIdx)
1234 ? this->co2InWaterFromOil(fs, pv)
1235 : this->co2InWaterFromWater(fs, pv);
1237 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1242 template <
typename Flu
idState>
1243 Scalar co2InWaterFromWater(
const FluidState& fs,
const double pv)
const
1245 const double rhow = getValue(fs.density(waterPhaseIdx));
1246 const double sw = getValue(fs.saturation(waterPhaseIdx));
1247 const double xwG = FluidSystem::convertRswToXwG(getValue(fs.Rsw()), fs.pvtRegionIndex());
1249 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1251 return xwG * pv * rhow * sw / mM;
1254 template <
typename Flu
idState>
1255 Scalar co2InWaterFromOil(
const FluidState& fs,
const double pv)
const
1257 const double rhoo = getValue(fs.density(oilPhaseIdx));
1258 const double so = getValue(fs.saturation(oilPhaseIdx));
1259 const double xoG = FluidSystem::convertRsToXoG(getValue(fs.Rs()), fs.pvtRegionIndex());
1261 const Scalar mM = FluidSystem::molarMass(gasCompIdx, fs.pvtRegionIndex());
1263 return xoG * pv * rhoo * so / mM;
1266 template <
typename Flu
idState,
typename FIPArray>
1267 void updateWaterMass(
const unsigned globalDofIdx,
1268 const FluidState& fs,
1272 const Scalar rhoW = FluidSystem::referenceDensity(waterPhaseIdx, fs.pvtRegionIndex());
1277 template <
typename IntensiveQuantities>
1278 void updateMicrobialMass(
const unsigned globalDofIdx,
1279 const IntensiveQuantities& intQuants,
1280 const double surfVolWat)
1282 const Scalar mass = surfVolWat * intQuants.microbialConcentration().value();
1287 template <
typename IntensiveQuantities>
1288 void updateOxygenMass(
const unsigned globalDofIdx,
1289 const IntensiveQuantities& intQuants,
1290 const double surfVolWat)
1292 const Scalar mass = surfVolWat * intQuants.oxygenConcentration().value();
1297 template <
typename IntensiveQuantities>
1298 void updateUreaMass(
const unsigned globalDofIdx,
1299 const IntensiveQuantities& intQuants,
1300 const double surfVolWat)
1302 const Scalar mass = surfVolWat * intQuants.ureaConcentration().value();
1307 template <
typename IntensiveQuantities>
1308 void updateBiofilmMass(
const unsigned globalDofIdx,
1309 const IntensiveQuantities& intQuants,
1310 const double totVolume)
1312 const Scalar mass = totVolume * intQuants.biofilmMass().value();
1317 template <
typename IntensiveQuantities>
1318 void updateCalciteMass(
const unsigned globalDofIdx,
1319 const IntensiveQuantities& intQuants,
1320 const double totVolume)
1322 const Scalar mass = totVolume * intQuants.calciteMass().value();
1328 void setupElementExtractors_()
1330 using Entry =
typename Extractor::Entry;
1331 using Context =
typename Extractor::Context;
1332 using ScalarEntry =
typename Extractor::ScalarEntry;
1333 using PhaseEntry =
typename Extractor::PhaseEntry;
1335 const bool hasResidual = simulator_.model().linearizer().residual().size() > 0;
1336 const auto& hysteresisConfig = simulator_.problem().materialLawManager()->hysteresisConfig();
1338 auto extractors = std::array{
1340 [](
const unsigned phase,
const Context& ectx)
1341 {
return getValue(ectx.fs.saturation(phase)); }
1344 Entry{PhaseEntry{&this->invB_,
1345 [](
const unsigned phase,
const Context& ectx)
1346 {
return getValue(ectx.fs.invB(phase)); }
1350 [](
const unsigned phase,
const Context& ectx)
1351 {
return getValue(ectx.fs.density(phase)); }
1354 Entry{PhaseEntry{&this->relativePermeability_,
1355 [](
const unsigned phase,
const Context& ectx)
1356 {
return getValue(ectx.intQuants.relativePermeability(phase)); }
1360 [
this](
const unsigned phaseIdx,
const Context& ectx)
1363 if constexpr (enableExtbo) {
1364 if (this->
extboC_.allocated() && phaseIdx == oilPhaseIdx) {
1365 return getValue(ectx.intQuants.oilViscosity());
1367 else if (this->
extboC_.allocated() && phaseIdx == gasPhaseIdx) {
1368 return getValue(ectx.intQuants.gasViscosity());
1371 return getValue(ectx.fs.viscosity(phaseIdx));
1376 [&modelResid = this->simulator_.model().linearizer().residual()]
1377 (
const unsigned phaseIdx,
const Context& ectx)
1379 const unsigned sIdx = FluidSystem::solventComponentIndex(phaseIdx);
1380 const unsigned activeCompIdx = FluidSystem::canonicalToActiveCompIdx(sIdx);
1381 return modelResid[ectx.globalDofIdx][activeCompIdx];
1387 [&problem = this->simulator_.problem()](
const Context& ectx)
1389 return problem.template
1390 rockCompPoroMultiplier<Scalar>(ectx.intQuants,
1396 [&problem = this->simulator_.problem()](
const Context& ectx)
1399 template rockCompTransMultiplier<Scalar>(ectx.intQuants,
1404 [&problem = this->simulator_.problem()](
const Context& ectx)
1406 return std::min(getValue(ectx.fs.pressure(oilPhaseIdx)),
1407 problem.minOilPressure(ectx.globalDofIdx));
1411 Entry{ScalarEntry{&this->bubblePointPressure_,
1413 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1417 FluidSystem::bubblePointPressure(ectx.fs,
1418 ectx.intQuants.pvtRegionIndex())
1420 }
catch (
const NumericalProblem&) {
1421 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1422 failedCells.push_back(cartesianIdx);
1428 Entry{ScalarEntry{&this->dewPointPressure_,
1430 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1434 FluidSystem::dewPointPressure(ectx.fs,
1435 ectx.intQuants.pvtRegionIndex())
1437 }
catch (
const NumericalProblem&) {
1438 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1439 failedCells.push_back(cartesianIdx);
1446 [&problem = simulator_.problem()](
const Context& ectx)
1447 {
return problem.overburdenPressure(ectx.globalDofIdx); }
1451 [](
const Context& ectx)
1452 {
return getValue(ectx.fs.temperature(oilPhaseIdx)); }
1455 Entry{ScalarEntry{&this->
sSol_,
1456 [](
const Context& ectx)
1458 if constexpr (enableSolvent) {
1459 return getValue(ectx.intQuants.solventSaturation());
1467 Entry{ScalarEntry{&this->
rswSol_,
1468 [](
const Context& ectx)
1470 if constexpr (enableSolvent) {
1471 return getValue(ectx.intQuants.rsSolw());
1480 [](
const Context& ectx)
1482 if constexpr (enablePolymer) {
1483 return getValue(ectx.intQuants.polymerConcentration());
1491 Entry{ScalarEntry{&this->
cFoam_,
1492 [](
const Context& ectx)
1494 if constexpr (enableFoam) {
1495 return getValue(ectx.intQuants.foamConcentration());
1503 Entry{ScalarEntry{&this->
cSalt_,
1504 [](
const Context& ectx)
1505 {
return getValue(ectx.fs.saltConcentration()); }
1508 Entry{ScalarEntry{&this->
pSalt_,
1509 [](
const Context& ectx)
1510 {
return getValue(ectx.fs.saltSaturation()); }
1514 [](
const Context& ectx)
1515 {
return getValue(ectx.intQuants.permFactor()); }
1518 Entry{ScalarEntry{&this->
rPorV_,
1519 [&model = this->simulator_.model()](
const Context& ectx)
1521 const auto totVolume = model.dofTotalVolume(ectx.globalDofIdx);
1522 return totVolume * getValue(ectx.intQuants.porosity());
1526 Entry{ScalarEntry{&this->rs_,
1527 [](
const Context& ectx)
1528 {
return getValue(ectx.fs.Rs()); }
1531 Entry{ScalarEntry{&this->rv_,
1532 [](
const Context& ectx)
1533 {
return getValue(ectx.fs.Rv()); }
1536 Entry{ScalarEntry{&this->
rsw_,
1537 [](
const Context& ectx)
1538 {
return getValue(ectx.fs.Rsw()); }
1541 Entry{ScalarEntry{&this->
rvw_,
1542 [](
const Context& ectx)
1543 {
return getValue(ectx.fs.Rvw()); }
1546 Entry{ScalarEntry{&this->
ppcw_,
1547 [&matLawManager = *this->simulator_.problem().materialLawManager()]
1548 (
const Context& ectx)
1550 return matLawManager.
1551 oilWaterScaledEpsInfoDrainage(ectx.globalDofIdx).maxPcow;
1556 [&problem = this->simulator_.problem()](
const Context& ectx)
1558 return problem.drsdtcon(ectx.globalDofIdx,
1563 Entry{ScalarEntry{&this->
pcgw_,
1564 [](
const Context& ectx)
1566 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1567 getValue(ectx.fs.pressure(waterPhaseIdx));
1571 Entry{ScalarEntry{&this->
pcow_,
1572 [](
const Context& ectx)
1574 return getValue(ectx.fs.pressure(oilPhaseIdx)) -
1575 getValue(ectx.fs.pressure(waterPhaseIdx));
1579 Entry{ScalarEntry{&this->
pcog_,
1580 [](
const Context& ectx)
1582 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
1583 getValue(ectx.fs.pressure(oilPhaseIdx));
1588 [](
const Context& ectx)
1590 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1592 return getValue(ectx.fs.pressure(oilPhaseIdx));
1594 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1596 return getValue(ectx.fs.pressure(gasPhaseIdx));
1600 return getValue(ectx.fs.pressure(waterPhaseIdx));
1606 [&problem = this->simulator_.problem()](
const Context& ectx)
1608 const Scalar SoMax = problem.maxOilSaturation(ectx.globalDofIdx);
1609 return FluidSystem::template
1610 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1618 [&problem = this->simulator_.problem()](
const Context& ectx)
1620 const Scalar SoMax = problem.maxOilSaturation(ectx.globalDofIdx);
1621 return FluidSystem::template
1622 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1630 [&problem = this->simulator_.problem()](
const Context& ectx)
1632 const Scalar SwMax = problem.maxWaterSaturation(ectx.globalDofIdx);
1633 return FluidSystem::template
1634 saturatedDissolutionFactor<FluidState, Scalar>(ectx.fs,
1642 [](
const Context& ectx)
1644 return FluidSystem::template
1645 saturatedVaporizationFactor<FluidState, Scalar>(ectx.fs,
1652 [](
const Context& ectx)
1654 return 1.0 / FluidSystem::template
1655 inverseFormationVolumeFactor<FluidState, Scalar>(ectx.fs,
1662 [](
const Context& ectx)
1664 return 1.0 / FluidSystem::template
1665 saturatedInverseFormationVolumeFactor<FluidState, Scalar>(ectx.fs,
1672 [](
const Context& ectx)
1674 return FluidSystem::template
1675 saturationPressure<FluidState, Scalar>(ectx.fs,
1681 Entry{ScalarEntry{&this->
soMax_,
1682 [&problem = this->simulator_.problem()](
const Context& ectx)
1684 return std::max(getValue(ectx.fs.saturation(oilPhaseIdx)),
1685 problem.maxOilSaturation(ectx.globalDofIdx));
1688 !hysteresisConfig.enableHysteresis()
1690 Entry{ScalarEntry{&this->
swMax_,
1691 [&problem = this->simulator_.problem()](
const Context& ectx)
1693 return std::max(getValue(ectx.fs.saturation(waterPhaseIdx)),
1694 problem.maxWaterSaturation(ectx.globalDofIdx));
1697 !hysteresisConfig.enableHysteresis()
1699 Entry{ScalarEntry{&this->
soMax_,
1700 [](
const Context& ectx)
1701 {
return ectx.hParams.somax; }
1703 hysteresisConfig.enableHysteresis() &&
1704 hysteresisConfig.enableNonWettingHysteresis() &&
1705 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1706 FluidSystem::phaseIsActive(waterPhaseIdx)
1708 Entry{ScalarEntry{&this->
swMax_,
1709 [](
const Context& ectx)
1710 {
return ectx.hParams.swmax; }
1712 hysteresisConfig.enableHysteresis() &&
1713 hysteresisConfig.enableWettingHysteresis() &&
1714 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1715 FluidSystem::phaseIsActive(waterPhaseIdx)
1717 Entry{ScalarEntry{&this->
swmin_,
1718 [](
const Context& ectx)
1719 {
return ectx.hParams.swmin; }
1721 hysteresisConfig.enableHysteresis() &&
1722 hysteresisConfig.enablePCHysteresis() &&
1723 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1724 FluidSystem::phaseIsActive(waterPhaseIdx)
1726 Entry{ScalarEntry{&this->
sgmax_,
1727 [](
const Context& ectx)
1728 {
return ectx.hParams.sgmax; }
1730 hysteresisConfig.enableHysteresis() &&
1731 hysteresisConfig.enableNonWettingHysteresis() &&
1732 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1733 FluidSystem::phaseIsActive(gasPhaseIdx)
1735 Entry{ScalarEntry{&this->
shmax_,
1736 [](
const Context& ectx)
1737 {
return ectx.hParams.shmax; }
1739 hysteresisConfig.enableHysteresis() &&
1740 hysteresisConfig.enableWettingHysteresis() &&
1741 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1742 FluidSystem::phaseIsActive(gasPhaseIdx)
1744 Entry{ScalarEntry{&this->
somin_,
1745 [](
const Context& ectx)
1746 {
return ectx.hParams.somin; }
1748 hysteresisConfig.enableHysteresis() &&
1749 hysteresisConfig.enablePCHysteresis() &&
1750 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1751 FluidSystem::phaseIsActive(gasPhaseIdx)
1753 Entry{[&model = this->simulator_.model(),
this](
const Context& ectx)
1757 const auto porv = ectx.intQuants.referencePorosity()
1758 * model.dofTotalVolume(ectx.globalDofIdx);
1760 this->aggregateAverageDensityContributions_(ectx.fs, ectx.globalDofIdx,
1761 static_cast<double>(porv));
1764 Entry{[&extboC = this->
extboC_](
const Context& ectx)
1767 if constexpr (enableExtbo) {
1768 extboC.assignVolumes(ectx.globalDofIdx,
1769 ectx.intQuants.xVolume().value(),
1770 ectx.intQuants.yVolume().value());
1771 extboC.assignZFraction(ectx.globalDofIdx,
1772 ectx.intQuants.zFraction().value());
1774 const Scalar stdVolOil = getValue(ectx.fs.saturation(oilPhaseIdx)) *
1775 getValue(ectx.fs.invB(oilPhaseIdx)) +
1776 getValue(ectx.fs.saturation(gasPhaseIdx)) *
1777 getValue(ectx.fs.invB(gasPhaseIdx)) *
1778 getValue(ectx.fs.Rv());
1779 const Scalar stdVolGas = getValue(ectx.fs.saturation(gasPhaseIdx)) *
1780 getValue(ectx.fs.invB(gasPhaseIdx)) *
1781 (1.0 - ectx.intQuants.yVolume().value()) +
1782 getValue(ectx.fs.saturation(oilPhaseIdx)) *
1783 getValue(ectx.fs.invB(oilPhaseIdx)) *
1784 getValue(ectx.fs.Rs()) *
1785 (1.0 - ectx.intQuants.xVolume().value());
1786 const Scalar stdVolCo2 = getValue(ectx.fs.saturation(gasPhaseIdx)) *
1787 getValue(ectx.fs.invB(gasPhaseIdx)) *
1788 ectx.intQuants.yVolume().value() +
1789 getValue(ectx.fs.saturation(oilPhaseIdx)) *
1790 getValue(ectx.fs.invB(oilPhaseIdx)) *
1791 getValue(ectx.fs.Rs()) *
1792 ectx.intQuants.xVolume().value();
1793 const Scalar rhoO = FluidSystem::referenceDensity(oilPhaseIdx, ectx.pvtRegionIdx);
1794 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx, ectx.pvtRegionIdx);
1795 const Scalar rhoCO2 = ectx.intQuants.zRefDensity();
1796 const Scalar stdMassTotal = 1.0e-10 + stdVolOil * rhoO + stdVolGas * rhoG + stdVolCo2 * rhoCO2;
1797 extboC.assignMassFractions(ectx.globalDofIdx,
1798 stdVolGas * rhoG / stdMassTotal,
1799 stdVolOil * rhoO / stdMassTotal,
1800 stdVolCo2 * rhoCO2 / stdMassTotal);
1804 Entry{[&bioeffectsC = this->
bioeffectsC_](
const Context& ectx)
1807 if constexpr (enableBioeffects) {
1808 bioeffectsC.assign(ectx.globalDofIdx,
1809 ectx.intQuants.microbialConcentration().value(),
1810 ectx.intQuants.biofilmVolumeFraction().value());
1811 if (Indices::enableMICP) {
1812 bioeffectsC.assign(ectx.globalDofIdx,
1813 ectx.intQuants.oxygenConcentration().value(),
1814 ectx.intQuants.ureaConcentration().value(),
1815 ectx.intQuants.calciteVolumeFraction().value());
1820 Entry{[&runspec = this->
eclState_.runspec(),
1821 &CO2H2C = this->
CO2H2C_](
const Context& ectx)
1823 const auto xwg = FluidSystem::convertRswToXwG(getValue(ectx.fs.Rsw()), ectx.pvtRegionIdx);
1824 const auto xgw = FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.pvtRegionIdx);
1825 CO2H2C.assign(ectx.globalDofIdx,
1826 FluidSystem::convertXwGToxwG(xwg, ectx.pvtRegionIdx),
1827 FluidSystem::convertXgWToxgW(xgw, ectx.pvtRegionIdx),
1828 runspec.co2Storage());
1831 Entry{[&rftC = this->
rftC_,
1832 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1834 const auto cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1835 rftC.assign(cartesianIdx,
1836 [&fs = ectx.fs]() {
return getValue(fs.pressure(oilPhaseIdx)); },
1837 [&fs = ectx.fs]() {
return getValue(fs.saturation(waterPhaseIdx)); },
1838 [&fs = ectx.fs]() {
return getValue(fs.saturation(gasPhaseIdx)); });
1842 &tM = this->simulator_.problem().tracerModel()](
const Context& ectx)
1844 tC.assignFreeConcentrations(ectx.globalDofIdx,
1845 [gIdx = ectx.globalDofIdx, &tM](
const unsigned tracerIdx)
1846 {
return tM.freeTracerConcentration(tracerIdx, gIdx); });
1847 tC.assignSolConcentrations(ectx.globalDofIdx,
1848 [gIdx = ectx.globalDofIdx, &tM](
const unsigned tracerIdx)
1849 {
return tM.solTracerConcentration(tracerIdx, gIdx); });
1852 Entry{[&flowsInf = this->simulator_.problem().model().linearizer().getFlowsInfo(),
1854 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1856 const auto gas_idx = Indices::gasEnabled ?
1857 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(gasCompIdx) : -1;
1858 const auto oil_idx = Indices::oilEnabled ?
1859 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(oilCompIdx) : -1;
1860 const auto water_idx = Indices::waterEnabled ?
1861 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(waterCompIdx) : -1;
1862 const auto& flowsInfos = flowsInf[ectx.globalDofIdx];
1863 if (!flowsC.blockFlows().empty()) {
1864 const std::vector<int>& blockIdxs = flowsC.blockFlows();
1865 const unsigned cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1866 if (std::ranges::binary_search(blockIdxs, cartesianIdx)) {
1867 const auto compIdxs = std::array{ gasCompIdx, oilCompIdx, waterCompIdx };
1868 const auto compEnabled = std::array{ Indices::gasEnabled, Indices::oilEnabled, Indices::waterEnabled };
1869 for (
const auto& flowsInfo : flowsInfos) {
1870 if (flowsInfo.faceId < 0) {
1873 for (
unsigned ii = 0; ii < compIdxs.size(); ++ii) {
1874 if (!compEnabled[ii]) {
1877 if (flowsC.hasBlockFlowValue(cartesianIdx, flowsInfo.faceId, compIdxs[ii])) {
1878 flowsC.assignBlockFlows(flowsC.blockFlowsIds(cartesianIdx, flowsInfo.faceId, compIdxs[ii]),
1881 flowsInfo.flow[conti0EqIdx
1882 + FluidSystem::canonicalToActiveCompIdx(compIdxs[ii])]);
1889 for (
const auto& flowsInfo : flowsInfos) {
1890 flowsC.assignFlows(ectx.globalDofIdx,
1893 value_or_zero(gas_idx, flowsInfo.flow),
1894 value_or_zero(oil_idx, flowsInfo.flow),
1895 value_or_zero(water_idx, flowsInfo.flow));
1898 }, !this->simulator_.problem().model().linearizer().getFlowsInfo().empty()
1900 Entry{[&floresInf = this->simulator_.problem().model().linearizer().getFloresInfo(),
1901 &flowsC = this->
flowsC_](
const Context& ectx)
1903 const auto gas_idx = Indices::gasEnabled ?
1904 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(gasCompIdx) : -1;
1905 const auto oil_idx = Indices::oilEnabled ?
1906 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(oilCompIdx) : -1;
1907 const auto water_idx = Indices::waterEnabled ?
1908 conti0EqIdx + FluidSystem::canonicalToActiveCompIdx(waterCompIdx) : -1;
1909 const auto& floresInfos = floresInf[ectx.globalDofIdx];
1910 for (
const auto& floresInfo : floresInfos) {
1911 flowsC.assignFlores(ectx.globalDofIdx,
1914 value_or_zero(gas_idx, floresInfo.flow),
1915 value_or_zero(oil_idx, floresInfo.flow),
1916 value_or_zero(water_idx, floresInfo.flow));
1918 }, !this->simulator_.problem().model().linearizer().getFloresInfo().empty()
1920 Entry{[&velocityInf = this->simulator_.problem().model().linearizer().getVelocityInfo(),
1922 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
1924 const auto& velocityInfos = velocityInf[ectx.globalDofIdx];
1925 const std::vector<int>& blockIdxs = flowsC.blockVelocity();
1926 const unsigned cartesianIdx = vanguard.cartesianIndex(ectx.globalDofIdx);
1927 if (std::ranges::binary_search(blockIdxs, cartesianIdx)) {
1928 const auto compIdxs = std::array{ gasCompIdx, oilCompIdx, waterCompIdx };
1929 const auto compEnabled = std::array{ Indices::gasEnabled, Indices::oilEnabled, Indices::waterEnabled };
1930 for (
const auto& velocityInfo : velocityInfos) {
1931 if (velocityInfo.faceId < 0) {
1934 for (
unsigned ii = 0; ii < compIdxs.size(); ++ii) {
1935 if (!compEnabled[ii]) {
1938 if (flowsC.hasBlockVelocityValue(cartesianIdx, velocityInfo.faceId, compIdxs[ii])) {
1939 flowsC.assignBlockVelocity(flowsC.blockVelocityIds(cartesianIdx, velocityInfo.faceId, compIdxs[ii]),
1940 velocityInfo.faceId,
1942 velocityInfo.velocity[conti0EqIdx
1943 + FluidSystem::canonicalToActiveCompIdx(compIdxs[ii])]);
1949 !this->simulator_.problem().model().linearizer().getVelocityInfo().empty()
1956 Entry{ScalarEntry{&this->rv_,
1957 [&problem = this->simulator_.problem()](
const Context& ectx)
1958 {
return problem.initialFluidState(ectx.globalDofIdx).Rv(); }
1960 simulator_.episodeIndex() < 0 &&
1961 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1962 FluidSystem::phaseIsActive(gasPhaseIdx)
1964 Entry{ScalarEntry{&this->rs_,
1965 [&problem = this->simulator_.problem()](
const Context& ectx)
1966 {
return problem.initialFluidState(ectx.globalDofIdx).Rs(); }
1968 simulator_.episodeIndex() < 0 &&
1969 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1970 FluidSystem::phaseIsActive(gasPhaseIdx)
1972 Entry{ScalarEntry{&this->
rsw_,
1973 [&problem = this->simulator_.problem()](
const Context& ectx)
1974 {
return problem.initialFluidState(ectx.globalDofIdx).Rsw(); }
1976 simulator_.episodeIndex() < 0 &&
1977 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1978 FluidSystem::phaseIsActive(gasPhaseIdx)
1980 Entry{ScalarEntry{&this->
rvw_,
1981 [&problem = this->simulator_.problem()](
const Context& ectx)
1982 {
return problem.initialFluidState(ectx.globalDofIdx).Rvw(); }
1984 simulator_.episodeIndex() < 0 &&
1985 FluidSystem::phaseIsActive(oilPhaseIdx) &&
1986 FluidSystem::phaseIsActive(gasPhaseIdx)
1990 [&problem = this->simulator_.problem()](
const unsigned phase,
1991 const Context& ectx)
1993 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
1994 return FluidSystem::density(fsInitial,
1996 ectx.intQuants.pvtRegionIndex());
1999 simulator_.episodeIndex() < 0 &&
2000 FluidSystem::phaseIsActive(oilPhaseIdx) &&
2001 FluidSystem::phaseIsActive(gasPhaseIdx)
2003 Entry{PhaseEntry{&this->invB_,
2004 [&problem = this->simulator_.problem()](
const unsigned phase,
2005 const Context& ectx)
2007 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
2008 return FluidSystem::inverseFormationVolumeFactor(fsInitial,
2010 ectx.intQuants.pvtRegionIndex());
2013 simulator_.episodeIndex() < 0 &&
2014 FluidSystem::phaseIsActive(oilPhaseIdx) &&
2015 FluidSystem::phaseIsActive(gasPhaseIdx)
2018 [&problem = this->simulator_.problem()](
const unsigned phase,
2019 const Context& ectx)
2021 const auto& fsInitial = problem.initialFluidState(ectx.globalDofIdx);
2022 return FluidSystem::viscosity(fsInitial,
2024 ectx.intQuants.pvtRegionIndex());
2027 simulator_.episodeIndex() < 0 &&
2028 FluidSystem::phaseIsActive(oilPhaseIdx) &&
2029 FluidSystem::phaseIsActive(gasPhaseIdx)
2037 if constexpr (getPropValue<TypeTag, Properties::EnableGeochemistry>()) {
2039 this->extractors_.emplace_back(
2041 &gM = this->simulator_.problem().geochemistryModel()](
const Context& ectx)
2043 gC.assignSpeciesConcentrations(
2045 [gIdx = ectx.globalDofIdx, &gM](
const unsigned speciesIdx)
2046 {
return gM.speciesConcentration(speciesIdx, gIdx); }
2048 gC.assignMineralConcentrations(
2050 [gIdx = ectx.globalDofIdx, &gM](
const unsigned mineralIdx)
2051 {
return gM.mineralConcentration(mineralIdx, gIdx); }
2053 gC.assignPH(ectx.globalDofIdx, gM.PH(ectx.globalDofIdx));
2061 if constexpr (getPropValue<TypeTag, Properties::EnableMech>()) {
2062 if (this->
mech_.allocated()) {
2063 this->extractors_.emplace_back(
2064 [&mech = this->
mech_,
2065 &model = simulator_.problem().geoMechModel()](
const Context& ectx)
2067 mech.assignDelStress(ectx.globalDofIdx,
2068 model.delstress(ectx.globalDofIdx));
2070 mech.assignDisplacement(ectx.globalDofIdx,
2071 model.disp(ectx.globalDofIdx,
true));
2074 mech.assignFracStress(ectx.globalDofIdx,
2075 model.fractureStress(ectx.globalDofIdx));
2077 mech.assignLinStress(ectx.globalDofIdx,
2078 model.linstress(ectx.globalDofIdx));
2080 mech.assignPotentialForces(ectx.globalDofIdx,
2081 model.mechPotentialForce(ectx.globalDofIdx),
2082 model.mechPotentialPressForce(ectx.globalDofIdx),
2083 model.mechPotentialTempForce(ectx.globalDofIdx));
2085 mech.assignStrain(ectx.globalDofIdx,
2086 model.strain(ectx.globalDofIdx,
true));
2089 mech.assignStress(ectx.globalDofIdx,
2090 model.stress(ectx.globalDofIdx,
true));
2095 if (this->
tpsaC_.allocated()) {
2096 this->extractors_.emplace_back(
2098 &model = simulator_.problem().geoMechModel()](
const Context& ectx) {
2099 tpsaC.assignRotation(ectx.globalDofIdx,
2100 model.rotation(ectx.globalDofIdx));
2102 tpsaC.assignSolidPressure(ectx.globalDofIdx,
2103 model.solidPressure(ectx.globalDofIdx));
2112 void setupBlockExtractors_(
const bool isSubStep,
2113 const int reportStepNum)
2116 using Context =
typename BlockExtractor::Context;
2117 using PhaseEntry =
typename BlockExtractor::PhaseEntry;
2118 using ScalarEntry =
typename BlockExtractor::ScalarEntry;
2120 using namespace std::string_view_literals;
2122 const auto pressure_handler =
2123 Entry{ScalarEntry{std::vector{
"BPR"sv,
"BPRESSUR"sv},
2124 [](
const Context& ectx)
2126 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2127 return getValue(ectx.fs.pressure(oilPhaseIdx));
2129 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
2130 return getValue(ectx.fs.pressure(gasPhaseIdx));
2133 return getValue(ectx.fs.pressure(waterPhaseIdx));
2139 const auto handlers = std::array{
2141 Entry{PhaseEntry{std::array{
2142 std::array{
"BWSAT"sv,
"BOSAT"sv,
"BGSAT"sv},
2143 std::array{
"BSWAT"sv,
"BSOIL"sv,
"BSGAS"sv}
2145 [](
const unsigned phaseIdx,
const Context& ectx)
2147 return getValue(ectx.fs.saturation(phaseIdx));
2151 Entry{ScalarEntry{
"BNSAT",
2152 [](
const Context& ectx)
2154 if constexpr (enableSolvent) {
2155 return ectx.intQuants.solventSaturation().value();
2163 Entry{ScalarEntry{std::vector{
"BTCNFHEA"sv,
"BTEMP"sv},
2164 [](
const Context& ectx)
2166 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2167 return getValue(ectx.fs.temperature(oilPhaseIdx));
2169 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
2170 return getValue(ectx.fs.temperature(gasPhaseIdx));
2173 return getValue(ectx.fs.temperature(waterPhaseIdx));
2178 Entry{PhaseEntry{std::array{
2179 std::array{
"BWKR"sv,
"BOKR"sv,
"BGKR"sv},
2180 std::array{
"BKRW"sv,
"BKRO"sv,
"BKRG"sv}
2182 [](
const unsigned phaseIdx,
const Context& ectx)
2184 return getValue(ectx.intQuants.relativePermeability(phaseIdx));
2188 Entry{ScalarEntry{
"BKROG",
2189 [&problem = this->simulator_.problem()](
const Context& ectx)
2191 const auto& materialParams =
2192 problem.materialLawParams(ectx.elemCtx,
2195 return getValue(MaterialLaw::template
2196 relpermOilInOilGasSystem<Evaluation>(materialParams,
2201 Entry{ScalarEntry{
"BKROW",
2202 [&problem = this->simulator_.problem()](
const Context& ectx)
2204 const auto& materialParams = problem.materialLawParams(ectx.elemCtx,
2207 return getValue(MaterialLaw::template
2208 relpermOilInOilWaterSystem<Evaluation>(materialParams,
2213 Entry{ScalarEntry{
"BWPC",
2214 [](
const Context& ectx)
2216 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2217 return getValue(ectx.fs.pressure(oilPhaseIdx)) -
2218 getValue(ectx.fs.pressure(waterPhaseIdx));
2220 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
2221 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
2222 getValue(ectx.fs.pressure(waterPhaseIdx));
2230 Entry{ScalarEntry{
"BGPC",
2231 [](
const Context& ectx)
2233 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2234 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
2235 getValue(ectx.fs.pressure(oilPhaseIdx));
2237 else if (FluidSystem::phaseIsActive(waterPhaseIdx)) {
2238 return getValue(ectx.fs.pressure(gasPhaseIdx)) -
2239 getValue(ectx.fs.pressure(waterPhaseIdx));
2247 Entry{ScalarEntry{
"BWPR",
2248 [](
const Context& ectx)
2250 return getValue(ectx.fs.pressure(waterPhaseIdx));
2254 Entry{ScalarEntry{
"BGPR",
2255 [](
const Context& ectx)
2257 return getValue(ectx.fs.pressure(gasPhaseIdx));
2261 Entry{PhaseEntry{std::array{
2262 std::array{
"BVWAT"sv,
"BVOIL"sv,
"BVGAS"sv},
2263 std::array{
"BWVIS"sv,
"BOVIS"sv,
"BGVIS"sv}
2265 [](
const unsigned phaseIdx,
const Context& ectx)
2267 return getValue(ectx.fs.viscosity(phaseIdx));
2271 Entry{PhaseEntry{std::array{
2272 std::array{
"BWDEN"sv,
"BODEN"sv,
"BGDEN"sv},
2273 std::array{
"BDENW"sv,
"BDENO"sv,
"BDENG"sv}
2275 [](
const unsigned phaseIdx,
const Context& ectx)
2277 return getValue(ectx.fs.density(phaseIdx));
2281 Entry{ScalarEntry{
"BFLOGI",
2283 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2285 const unsigned index = !flowsC.blockFlows().empty() ?
2286 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2287 FaceDir::ToIntersectionIndex(Dir::XPlus), gasCompIdx) : ectx.globalDofIdx;
2288 return flowsC.getFlow(index, Dir::XPlus, gasCompIdx);
2292 Entry{ScalarEntry{
"BFLOGI-",
2294 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2296 const unsigned index = !flowsC.blockFlows().empty() ?
2297 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2298 FaceDir::ToIntersectionIndex(Dir::XMinus), gasCompIdx) : ectx.globalDofIdx;
2299 return flowsC.getFlow(index, Dir::XMinus, gasCompIdx);
2303 Entry{ScalarEntry{
"BFLOGJ",
2305 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2307 const unsigned index = !flowsC.blockFlows().empty() ?
2308 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2309 FaceDir::ToIntersectionIndex(Dir::YPlus), gasCompIdx) : ectx.globalDofIdx;
2310 return flowsC.getFlow(index, Dir::YPlus, gasCompIdx);
2314 Entry{ScalarEntry{
"BFLOGJ-",
2316 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2318 const unsigned index = !flowsC.blockFlows().empty() ?
2319 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2320 FaceDir::ToIntersectionIndex(Dir::YMinus), gasCompIdx) : ectx.globalDofIdx;
2321 return flowsC.getFlow(index, Dir::YMinus, gasCompIdx);
2325 Entry{ScalarEntry{
"BFLOGK",
2327 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2329 const unsigned index = !flowsC.blockFlows().empty() ?
2330 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2331 FaceDir::ToIntersectionIndex(Dir::ZPlus), gasCompIdx) : ectx.globalDofIdx;
2332 return flowsC.getFlow(index, Dir::ZPlus, gasCompIdx);
2336 Entry{ScalarEntry{
"BFLOGK-",
2338 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2340 const unsigned index = !flowsC.blockFlows().empty() ?
2341 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2342 FaceDir::ToIntersectionIndex(Dir::ZMinus), gasCompIdx) : ectx.globalDofIdx;
2343 return flowsC.getFlow(index, Dir::ZMinus, gasCompIdx);
2347 Entry{ScalarEntry{
"BFLOOI",
2349 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2351 const unsigned index = !flowsC.blockFlows().empty() ?
2352 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2353 FaceDir::ToIntersectionIndex(Dir::XPlus), oilCompIdx) : ectx.globalDofIdx;
2354 return flowsC.getFlow(index, Dir::XPlus, oilCompIdx);
2358 Entry{ScalarEntry{
"BFLOOI-",
2360 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2362 const unsigned index = !flowsC.blockFlows().empty() ?
2363 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2364 FaceDir::ToIntersectionIndex(Dir::XMinus), oilCompIdx) : ectx.globalDofIdx;
2365 return flowsC.getFlow(index, Dir::XMinus, oilCompIdx);
2369 Entry{ScalarEntry{
"BFLOOJ",
2371 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2373 const unsigned index = !flowsC.blockFlows().empty() ?
2374 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2375 FaceDir::ToIntersectionIndex(Dir::YPlus), oilCompIdx) : ectx.globalDofIdx;
2376 return flowsC.getFlow(index, Dir::YPlus, oilCompIdx);
2380 Entry{ScalarEntry{
"BFLOOJ-",
2382 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2384 const unsigned index = !flowsC.blockFlows().empty() ?
2385 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2386 FaceDir::ToIntersectionIndex(Dir::YMinus), oilCompIdx) : ectx.globalDofIdx;
2387 return flowsC.getFlow(index, Dir::YMinus, oilCompIdx);
2391 Entry{ScalarEntry{
"BFLOOK",
2393 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2395 const unsigned index = !flowsC.blockFlows().empty() ?
2396 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2397 FaceDir::ToIntersectionIndex(Dir::ZPlus), oilCompIdx) : ectx.globalDofIdx;
2398 return flowsC.getFlow(index, Dir::ZPlus, oilCompIdx);
2402 Entry{ScalarEntry{
"BFLOOK-",
2404 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2406 const unsigned index = !flowsC.blockFlows().empty() ?
2407 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2408 FaceDir::ToIntersectionIndex(Dir::ZMinus), oilCompIdx) : ectx.globalDofIdx;
2409 return flowsC.getFlow(index, Dir::ZMinus, oilCompIdx);
2413 Entry{ScalarEntry{
"BFLOWI",
2415 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2417 const unsigned index = !flowsC.blockFlows().empty() ?
2418 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2419 FaceDir::ToIntersectionIndex(Dir::XPlus), waterCompIdx) : ectx.globalDofIdx;
2420 return flowsC.getFlow(index, Dir::XPlus, waterCompIdx);
2424 Entry{ScalarEntry{
"BFLOWI-",
2426 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2428 const unsigned index = !flowsC.blockFlows().empty() ?
2429 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2430 FaceDir::ToIntersectionIndex(Dir::XMinus), waterCompIdx) : ectx.globalDofIdx;
2431 return flowsC.getFlow(index, Dir::XMinus, waterCompIdx);
2435 Entry{ScalarEntry{
"BFLOWJ",
2437 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2439 const unsigned index = !flowsC.blockFlows().empty() ?
2440 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2441 FaceDir::ToIntersectionIndex(Dir::YPlus), waterCompIdx) : ectx.globalDofIdx;
2442 return flowsC.getFlow(index, Dir::YPlus, waterCompIdx);
2446 Entry{ScalarEntry{
"BFLOWJ-",
2448 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2450 const unsigned index = !flowsC.blockFlows().empty() ?
2451 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2452 FaceDir::ToIntersectionIndex(Dir::YMinus), waterCompIdx) : ectx.globalDofIdx;
2453 return flowsC.getFlow(index, Dir::YMinus, waterCompIdx);
2457 Entry{ScalarEntry{
"BFLOWK",
2459 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2461 const unsigned index = !flowsC.blockFlows().empty() ?
2462 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2463 FaceDir::ToIntersectionIndex(Dir::ZPlus), waterCompIdx) : ectx.globalDofIdx;
2464 return flowsC.getFlow(index, Dir::ZPlus, waterCompIdx);
2468 Entry{ScalarEntry{
"BFLOWK-",
2470 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2472 const unsigned index = !flowsC.blockFlows().empty() ?
2473 flowsC.blockFlowsIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2474 FaceDir::ToIntersectionIndex(Dir::ZMinus), waterCompIdx) : ectx.globalDofIdx;
2475 return flowsC.getFlow(index, Dir::ZMinus, waterCompIdx);
2479 Entry{ScalarEntry{
"BVELGI",
2481 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2483 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2484 FaceDir::ToIntersectionIndex(Dir::XPlus), gasCompIdx);
2485 return flowsC.getVelocity(index, Dir::XPlus, gasCompIdx);
2489 Entry{ScalarEntry{
"BVELGI-",
2491 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2493 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2494 FaceDir::ToIntersectionIndex(Dir::XMinus), gasCompIdx);
2495 return flowsC.getVelocity(index, Dir::XMinus, gasCompIdx);
2499 Entry{ScalarEntry{
"BVELGJ",
2501 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2503 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2504 FaceDir::ToIntersectionIndex(Dir::YPlus), gasCompIdx);
2505 return flowsC.getVelocity(index, Dir::YPlus, gasCompIdx);
2509 Entry{ScalarEntry{
"BVELGJ-",
2511 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2513 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2514 FaceDir::ToIntersectionIndex(Dir::YMinus), gasCompIdx);
2515 return flowsC.getVelocity(index, Dir::YMinus, gasCompIdx);
2519 Entry{ScalarEntry{
"BVELGK",
2521 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2523 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2524 FaceDir::ToIntersectionIndex(Dir::ZPlus), gasCompIdx);
2525 return flowsC.getVelocity(index, Dir::ZPlus, gasCompIdx);
2529 Entry{ScalarEntry{
"BVELGK-",
2531 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2533 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2534 FaceDir::ToIntersectionIndex(Dir::ZMinus), gasCompIdx);
2535 return flowsC.getVelocity(index, Dir::ZMinus, gasCompIdx);
2539 Entry{ScalarEntry{
"BVELOI",
2541 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2543 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2544 FaceDir::ToIntersectionIndex(Dir::XPlus), oilCompIdx);
2545 return flowsC.getVelocity(index, Dir::XPlus, oilCompIdx);
2549 Entry{ScalarEntry{
"BVELOI-",
2551 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2553 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2554 FaceDir::ToIntersectionIndex(Dir::XMinus), oilCompIdx);
2555 return flowsC.getVelocity(index, Dir::XMinus, oilCompIdx);
2559 Entry{ScalarEntry{
"BVELOJ",
2561 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2563 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2564 FaceDir::ToIntersectionIndex(Dir::YPlus), oilCompIdx);
2565 return flowsC.getVelocity(index, Dir::YPlus, oilCompIdx);
2569 Entry{ScalarEntry{
"BVELOJ-",
2571 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2573 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2574 FaceDir::ToIntersectionIndex(Dir::YMinus), oilCompIdx);
2575 return flowsC.getVelocity(index, Dir::YMinus, oilCompIdx);
2579 Entry{ScalarEntry{
"BVELOK",
2581 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2583 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2584 FaceDir::ToIntersectionIndex(Dir::ZPlus), oilCompIdx);
2585 return flowsC.getVelocity(index, Dir::ZPlus, oilCompIdx);
2589 Entry{ScalarEntry{
"BVELOK-",
2591 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2593 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2594 FaceDir::ToIntersectionIndex(Dir::ZMinus), oilCompIdx);
2595 return flowsC.getVelocity(index, Dir::ZMinus, oilCompIdx);
2599 Entry{ScalarEntry{
"BVELWI",
2601 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2603 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2604 FaceDir::ToIntersectionIndex(Dir::XPlus), waterCompIdx);
2605 return flowsC.getVelocity(index, Dir::XPlus, waterCompIdx);
2609 Entry{ScalarEntry{
"BVELWI-",
2611 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2613 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2614 FaceDir::ToIntersectionIndex(Dir::XMinus), waterCompIdx);
2615 return flowsC.getVelocity(index, Dir::XMinus, waterCompIdx);
2619 Entry{ScalarEntry{
"BVELWJ",
2621 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2623 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2624 FaceDir::ToIntersectionIndex(Dir::YPlus), waterCompIdx);
2625 return flowsC.getVelocity(index, Dir::YPlus, waterCompIdx);
2629 Entry{ScalarEntry{
"BVELWJ-",
2631 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2633 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2634 FaceDir::ToIntersectionIndex(Dir::YMinus), waterCompIdx);
2635 return flowsC.getVelocity(index, Dir::YMinus, waterCompIdx);
2639 Entry{ScalarEntry{
"BVELWK",
2641 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2643 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2644 FaceDir::ToIntersectionIndex(Dir::ZPlus), waterCompIdx);
2645 return flowsC.getVelocity(index, Dir::ZPlus, waterCompIdx);
2649 Entry{ScalarEntry{
"BVELWK-",
2651 &vanguard = this->simulator_.vanguard()](
const Context& ectx)
2653 const unsigned index = flowsC.blockVelocityIds(vanguard.cartesianIndex(ectx.globalDofIdx),
2654 FaceDir::ToIntersectionIndex(Dir::ZMinus), waterCompIdx);
2655 return flowsC.getVelocity(index, Dir::ZMinus, waterCompIdx);
2659 Entry{ScalarEntry{
"BRPV",
2660 [&model = this->simulator_.model()](
const Context& ectx)
2662 return getValue(ectx.intQuants.porosity()) *
2663 model.dofTotalVolume(ectx.globalDofIdx);
2667 Entry{PhaseEntry{std::array{
"BWPV"sv,
"BOPV"sv,
"BGPV"sv},
2668 [&model = this->simulator_.model()](
const unsigned phaseIdx,
2669 const Context& ectx)
2671 return getValue(ectx.fs.saturation(phaseIdx)) *
2672 getValue(ectx.intQuants.porosity()) *
2673 model.dofTotalVolume(ectx.globalDofIdx);
2677 Entry{ScalarEntry{
"BRS",
2678 [](
const Context& ectx)
2680 return getValue(ectx.fs.Rs());
2684 Entry{ScalarEntry{
"BRV",
2685 [](
const Context& ectx)
2687 return getValue(ectx.fs.Rv());
2691 Entry{ScalarEntry{
"BOIP",
2692 [&model = this->simulator_.model()](
const Context& ectx)
2694 return (getValue(ectx.fs.invB(oilPhaseIdx)) *
2695 getValue(ectx.fs.saturation(oilPhaseIdx)) +
2696 getValue(ectx.fs.Rv()) *
2697 getValue(ectx.fs.invB(gasPhaseIdx)) *
2698 getValue(ectx.fs.saturation(gasPhaseIdx))) *
2699 model.dofTotalVolume(ectx.globalDofIdx) *
2700 getValue(ectx.intQuants.porosity());
2704 Entry{ScalarEntry{
"BGIP",
2705 [&model = this->simulator_.model()](
const Context& ectx)
2707 Scalar result = getValue(ectx.fs.invB(gasPhaseIdx)) *
2708 getValue(ectx.fs.saturation(gasPhaseIdx));
2710 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2711 result += getValue(ectx.fs.Rs()) *
2712 getValue(ectx.fs.invB(oilPhaseIdx)) *
2713 getValue(ectx.fs.saturation(oilPhaseIdx));
2716 result += getValue(ectx.fs.Rsw()) *
2717 getValue(ectx.fs.invB(waterPhaseIdx)) *
2718 getValue(ectx.fs.saturation(waterPhaseIdx));
2722 model.dofTotalVolume(ectx.globalDofIdx) *
2723 getValue(ectx.intQuants.porosity());
2727 Entry{ScalarEntry{
"BWIP",
2728 [&model = this->simulator_.model()](
const Context& ectx)
2730 return getValue(ectx.fs.invB(waterPhaseIdx)) *
2731 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2732 model.dofTotalVolume(ectx.globalDofIdx) *
2733 getValue(ectx.intQuants.porosity());
2737 Entry{ScalarEntry{
"BOIPL",
2738 [&model = this->simulator_.model()](
const Context& ectx)
2740 return getValue(ectx.fs.invB(oilPhaseIdx)) *
2741 getValue(ectx.fs.saturation(oilPhaseIdx)) *
2742 model.dofTotalVolume(ectx.globalDofIdx) *
2743 getValue(ectx.intQuants.porosity());
2747 Entry{ScalarEntry{
"BGIPL",
2748 [&model = this->simulator_.model()](
const Context& ectx)
2751 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2752 result = getValue(ectx.fs.Rs()) *
2753 getValue(ectx.fs.invB(oilPhaseIdx)) *
2754 getValue(ectx.fs.saturation(oilPhaseIdx));
2757 result = getValue(ectx.fs.Rsw()) *
2758 getValue(ectx.fs.invB(waterPhaseIdx)) *
2759 getValue(ectx.fs.saturation(waterPhaseIdx));
2762 model.dofTotalVolume(ectx.globalDofIdx) *
2763 getValue(ectx.intQuants.porosity());
2767 Entry{ScalarEntry{
"BGIPG",
2768 [&model = this->simulator_.model()](
const Context& ectx)
2770 return getValue(ectx.fs.invB(gasPhaseIdx)) *
2771 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2772 model.dofTotalVolume(ectx.globalDofIdx) *
2773 getValue(ectx.intQuants.porosity());
2777 Entry{ScalarEntry{
"BOIPG",
2778 [&model = this->simulator_.model()](
const Context& ectx)
2780 return getValue(ectx.fs.Rv()) *
2781 getValue(ectx.fs.invB(gasPhaseIdx)) *
2782 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2783 model.dofTotalVolume(ectx.globalDofIdx) *
2784 getValue(ectx.intQuants.porosity());
2788 Entry{PhaseEntry{std::array{
"BPPW"sv,
"BPPO"sv,
"BPPG"sv},
2789 [&simConfig = this->
eclState_.getSimulationConfig(),
2790 &grav = this->simulator_.problem().gravity(),
2792 &problem = this->simulator_.problem(),
2793 ®ions = this->
regions_](
const unsigned phaseIdx,
const Context& ectx)
2796 phase.ix = phaseIdx;
2805 const auto datum = simConfig.datumDepths()(regions[
"FIPNUM"][ectx.dofIdx] - 1);
2808 const auto region = RegionPhasePoreVolAverage::Region {
2809 ectx.elemCtx.primaryVars(ectx.dofIdx, 0).pvtRegionIndex() + 1
2812 const auto density = regionAvgDensity->value(
"PVTNUM", phase, region);
2814 const auto press = getValue(ectx.fs.pressure(phase.ix));
2815 const auto dz = problem.dofCenterDepth(ectx.globalDofIdx) - datum;
2816 return press - density*dz*grav[GridView::dimensionworld - 1];
2820 Entry{ScalarEntry{
"BAMIP",
2821 [&model = this->simulator_.model()](
const Context& ectx)
2823 const Scalar rhoW = FluidSystem::referenceDensity(waterPhaseIdx,
2824 ectx.intQuants.pvtRegionIndex());
2825 return getValue(ectx.fs.invB(waterPhaseIdx)) *
2826 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2828 model.dofTotalVolume(ectx.globalDofIdx) *
2829 getValue(ectx.intQuants.porosity());
2833 Entry{ScalarEntry{
"BMMIP",
2834 [&model = this->simulator_.model()](
const Context& ectx)
2836 if constexpr (enableBioeffects) {
2837 return getValue(ectx.intQuants.microbialConcentration()) *
2838 getValue(ectx.fs.saturation(waterPhaseIdx)) *
2839 getValue(ectx.intQuants.porosity()) *
2840 model.dofTotalVolume(ectx.globalDofIdx);
2848 Entry{ScalarEntry{
"BMOIP",
2849 [&model = this->simulator_.model()](
const Context& ectx)
2851 if constexpr (enableBioeffects) {
2852 return getValue(ectx.intQuants.oxygenConcentration()) *
2853 getValue(ectx.intQuants.porosity()) *
2854 model.dofTotalVolume(ectx.globalDofIdx);
2862 Entry{ScalarEntry{
"BMUIP",
2863 [&model = this->simulator_.model()](
const Context& ectx)
2865 if constexpr (enableBioeffects) {
2866 return getValue(ectx.intQuants.ureaConcentration()) *
2867 getValue(ectx.intQuants.porosity()) *
2868 model.dofTotalVolume(ectx.globalDofIdx);
2876 Entry{ScalarEntry{
"BMBIP",
2877 [&model = this->simulator_.model()](
const Context& ectx)
2879 if constexpr (enableBioeffects) {
2880 return model.dofTotalVolume(ectx.globalDofIdx) *
2881 getValue(ectx.intQuants.biofilmMass());
2889 Entry{ScalarEntry{
"BMCIP",
2890 [&model = this->simulator_.model()](
const Context& ectx)
2892 if constexpr (enableBioeffects) {
2893 return model.dofTotalVolume(ectx.globalDofIdx) *
2894 getValue(ectx.intQuants.calciteMass());
2902 Entry{ScalarEntry{
"BGMIP",
2903 [&model = this->simulator_.model()](
const Context& ectx)
2905 Scalar result = getValue(ectx.fs.invB(gasPhaseIdx)) *
2906 getValue(ectx.fs.saturation(gasPhaseIdx));
2908 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2909 result += getValue(ectx.fs.Rs()) *
2910 getValue(ectx.fs.invB(oilPhaseIdx)) *
2911 getValue(ectx.fs.saturation(oilPhaseIdx));
2914 result += getValue(ectx.fs.Rsw()) *
2915 getValue(ectx.fs.invB(waterPhaseIdx)) *
2916 getValue(ectx.fs.saturation(waterPhaseIdx));
2918 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2919 ectx.intQuants.pvtRegionIndex());
2921 model.dofTotalVolume(ectx.globalDofIdx) *
2922 getValue(ectx.intQuants.porosity()) *
2927 Entry{ScalarEntry{
"BGMGP",
2928 [&model = this->simulator_.model()](
const Context& ectx)
2930 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2931 ectx.intQuants.pvtRegionIndex());
2932 return getValue(ectx.fs.invB(gasPhaseIdx)) *
2933 getValue(ectx.fs.saturation(gasPhaseIdx)) *
2934 model.dofTotalVolume(ectx.globalDofIdx) *
2935 getValue(ectx.intQuants.porosity()) *
2940 Entry{ScalarEntry{
"BGMDS",
2941 [&model = this->simulator_.model()](
const Context& ectx)
2944 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
2945 result = getValue(ectx.fs.Rs()) *
2946 getValue(ectx.fs.invB(oilPhaseIdx)) *
2947 getValue(ectx.fs.saturation(oilPhaseIdx));
2950 result = getValue(ectx.fs.Rsw()) *
2951 getValue(ectx.fs.invB(waterPhaseIdx)) *
2952 getValue(ectx.fs.saturation(waterPhaseIdx));
2954 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
2955 ectx.intQuants.pvtRegionIndex());
2957 model.dofTotalVolume(ectx.globalDofIdx) *
2958 getValue(ectx.intQuants.porosity()) *
2963 Entry{ScalarEntry{
"BGMST",
2964 [&model = this->simulator_.model(),
2965 &problem = this->simulator_.problem()](
const Context& ectx)
2967 const auto& scaledDrainageInfo = problem.materialLawManager()
2968 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2969 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2970 Scalar strandedGas = scaledDrainageInfo.Sgcr;
2971 if (problem.materialLawManager()->enableHysteresis()) {
2972 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2973 const Scalar krg = getValue(ectx.intQuants.relativePermeability(gasPhaseIdx));
2974 strandedGas = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
2976 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
2977 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
2978 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
2979 return (1.0 - xgW) *
2980 model.dofTotalVolume(ectx.globalDofIdx) *
2981 getValue(ectx.intQuants.porosity()) *
2982 getValue(ectx.fs.density(gasPhaseIdx)) *
2983 std::min(strandedGas, sg);
2987 Entry{ScalarEntry{
"BGMUS",
2988 [&model = this->simulator_.model(),
2989 &problem = this->simulator_.problem()](
const Context& ectx)
2991 const auto& scaledDrainageInfo = problem.materialLawManager()
2992 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
2993 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
2994 Scalar strandedGas = scaledDrainageInfo.Sgcr;
2995 if (problem.materialLawManager()->enableHysteresis()) {
2996 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
2997 const Scalar krg = getValue(ectx.intQuants.relativePermeability(gasPhaseIdx));
2998 strandedGas = MaterialLaw::strandedGasSaturation(matParams, sg, krg);
3000 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3001 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3002 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3003 return (1.0 - xgW) *
3004 model.dofTotalVolume(ectx.globalDofIdx) *
3005 getValue(ectx.intQuants.porosity()) *
3006 getValue(ectx.fs.density(gasPhaseIdx)) *
3007 std::max(Scalar{0.0}, sg - strandedGas);
3011 Entry{ScalarEntry{
"BGMTR",
3012 [&model = this->simulator_.model(),
3013 &problem = this->simulator_.problem()](
const Context& ectx)
3015 const auto& scaledDrainageInfo = problem.materialLawManager()
3016 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3017 Scalar trappedGas = scaledDrainageInfo.Sgcr;
3018 if (problem.materialLawManager()->enableHysteresis()) {
3019 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3020 trappedGas = MaterialLaw::trappedGasSaturation(matParams,
true);
3022 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3023 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3024 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3025 return (1.0 - xgW) *
3026 model.dofTotalVolume(ectx.globalDofIdx) *
3027 getValue(ectx.intQuants.porosity()) *
3028 getValue(ectx.fs.density(gasPhaseIdx)) *
3029 std::min(trappedGas, getValue(ectx.fs.saturation(gasPhaseIdx)));
3033 Entry{ScalarEntry{
"BGMMO",
3034 [&model = this->simulator_.model(),
3035 &problem = this->simulator_.problem()](
const Context& ectx)
3037 const auto& scaledDrainageInfo = problem.materialLawManager()
3038 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3039 Scalar trappedGas = scaledDrainageInfo.Sgcr;
3040 if (problem.materialLawManager()->enableHysteresis()) {
3041 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3042 trappedGas = MaterialLaw::trappedGasSaturation(matParams,
true);
3044 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3045 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3046 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3047 return (1.0 - xgW) *
3048 model.dofTotalVolume(ectx.globalDofIdx) *
3049 getValue(ectx.intQuants.porosity()) *
3050 getValue(ectx.fs.density(gasPhaseIdx)) *
3051 std::max(Scalar{0.0}, getValue(ectx.fs.saturation(gasPhaseIdx)) - trappedGas);
3055 Entry{ScalarEntry{
"BGKTR",
3056 [&model = this->simulator_.model(),
3057 &problem = this->simulator_.problem()](
const Context& ectx)
3059 const auto& scaledDrainageInfo = problem.materialLawManager()
3060 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3061 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
3062 Scalar sgcr = scaledDrainageInfo.Sgcr;
3063 if (problem.materialLawManager()->enableHysteresis()) {
3064 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3065 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3071 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3072 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3073 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3074 return (1.0 - xgW) *
3075 model.dofTotalVolume(ectx.globalDofIdx) *
3076 getValue(ectx.intQuants.porosity()) *
3077 getValue(ectx.fs.density(gasPhaseIdx)) *
3078 getValue(ectx.fs.saturation(gasPhaseIdx));
3083 Entry{ScalarEntry{
"BGKMO",
3084 [&model = this->simulator_.model(),
3085 &problem = this->simulator_.problem()](
const Context& ectx)
3087 const auto& scaledDrainageInfo = problem.materialLawManager()
3088 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3089 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
3090 Scalar sgcr = scaledDrainageInfo.Sgcr;
3091 if (problem.materialLawManager()->enableHysteresis()) {
3092 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3093 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3099 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3100 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3101 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3102 return (1.0 - xgW) *
3103 model.dofTotalVolume(ectx.globalDofIdx) *
3104 getValue(ectx.intQuants.porosity()) *
3105 getValue(ectx.fs.density(gasPhaseIdx)) *
3106 getValue(ectx.fs.saturation(gasPhaseIdx));
3111 Entry{ScalarEntry{
"BGCDI",
3112 [&model = this->simulator_.model(),
3113 &problem = this->simulator_.problem()](
const Context& ectx)
3115 const auto& scaledDrainageInfo = problem.materialLawManager()
3116 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3117 Scalar sgcr = scaledDrainageInfo.Sgcr;
3118 if (problem.materialLawManager()->enableHysteresis()) {
3119 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3120 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3122 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3123 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3124 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3125 return (1.0 - xgW) *
3126 model.dofTotalVolume(ectx.globalDofIdx) *
3127 getValue(ectx.intQuants.porosity()) *
3128 getValue(ectx.fs.density(gasPhaseIdx)) *
3129 std::min(sgcr, getValue(ectx.fs.saturation(gasPhaseIdx))) /
3130 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
3134 Entry{ScalarEntry{
"BGCDM",
3135 [&model = this->simulator_.model(),
3136 &problem = this->simulator_.problem()](
const Context& ectx)
3138 const auto& scaledDrainageInfo = problem.materialLawManager()
3139 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3140 Scalar sgcr = scaledDrainageInfo.Sgcr;
3141 if (problem.materialLawManager()->enableHysteresis()) {
3142 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3143 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3145 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3146 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3147 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3148 return (1.0 - xgW) *
3149 model.dofTotalVolume(ectx.globalDofIdx) *
3150 getValue(ectx.intQuants.porosity()) *
3151 getValue(ectx.fs.density(gasPhaseIdx)) *
3152 std::max(Scalar{0.0}, getValue(ectx.fs.saturation(gasPhaseIdx)) - sgcr) /
3153 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
3157 Entry{ScalarEntry{
"BGKDI",
3158 [&model = this->simulator_.model(),
3159 &problem = this->simulator_.problem()](
const Context& ectx)
3161 const auto& scaledDrainageInfo = problem.materialLawManager()
3162 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3163 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
3164 Scalar sgcr = scaledDrainageInfo.Sgcr;
3165 if (problem.materialLawManager()->enableHysteresis()) {
3166 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3167 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3173 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3174 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3175 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3176 return (1.0 - xgW) *
3177 model.dofTotalVolume(ectx.globalDofIdx) *
3178 getValue(ectx.intQuants.porosity()) *
3179 getValue(ectx.fs.density(gasPhaseIdx)) *
3180 getValue(ectx.fs.saturation(gasPhaseIdx)) /
3181 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
3186 Entry{ScalarEntry{
"BGKDM",
3187 [&model = this->simulator_.model(),
3188 &problem = this->simulator_.problem()](
const Context& ectx)
3190 const auto& scaledDrainageInfo = problem.materialLawManager()
3191 ->oilWaterScaledEpsInfoDrainage(ectx.dofIdx);
3192 const Scalar sg = getValue(ectx.fs.saturation(gasPhaseIdx));
3193 Scalar sgcr = scaledDrainageInfo.Sgcr;
3194 if (problem.materialLawManager()->enableHysteresis()) {
3195 const auto& matParams = problem.materialLawParams(ectx.dofIdx);
3196 sgcr = MaterialLaw::trappedGasSaturation(matParams,
false);
3202 const Scalar xgW = FluidSystem::phaseIsActive(waterPhaseIdx) ?
3203 FluidSystem::convertRvwToXgW(getValue(ectx.fs.Rvw()), ectx.intQuants.pvtRegionIndex())
3204 : FluidSystem::convertRvToXgO(getValue(ectx.fs.
Rv()), ectx.intQuants.pvtRegionIndex());
3205 return (1.0 - xgW) *
3206 model.dofTotalVolume(ectx.globalDofIdx) *
3207 getValue(ectx.intQuants.porosity()) *
3208 getValue(ectx.fs.density(gasPhaseIdx)) *
3209 getValue(ectx.fs.saturation(gasPhaseIdx)) /
3210 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
3215 Entry{ScalarEntry{
"BWCD",
3216 [&model = this->simulator_.model()](
const Context& ectx)
3219 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
3220 result = getValue(ectx.fs.Rs()) *
3221 getValue(ectx.fs.invB(oilPhaseIdx)) *
3222 getValue(ectx.fs.saturation(oilPhaseIdx));
3225 result = getValue(ectx.fs.Rsw()) *
3226 getValue(ectx.fs.invB(waterPhaseIdx)) *
3227 getValue(ectx.fs.saturation(waterPhaseIdx));
3229 const Scalar rhoG = FluidSystem::referenceDensity(gasPhaseIdx,
3230 ectx.intQuants.pvtRegionIndex());
3232 model.dofTotalVolume(ectx.globalDofIdx) *
3233 getValue(ectx.intQuants.porosity()) *
3235 FluidSystem::molarMass(gasCompIdx, ectx.intQuants.pvtRegionIndex());
3239 Entry{ScalarEntry{
"BWIPG",
3240 [&model = this->simulator_.model()](
const Context& ectx)
3242 Scalar result = 0.0;
3243 if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
3244 result = getValue(ectx.fs.Rvw()) *
3245 getValue(ectx.fs.invB(gasPhaseIdx)) *
3246 getValue(ectx.fs.saturation(gasPhaseIdx));
3249 model.dofTotalVolume(ectx.globalDofIdx) *
3250 getValue(ectx.intQuants.porosity());
3254 Entry{ScalarEntry{
"BWIPL",
3255 [&model = this->simulator_.model()](
const Context& ectx)
3257 return getValue(ectx.fs.invB(waterPhaseIdx)) *
3258 getValue(ectx.fs.saturation(waterPhaseIdx)) *
3259 model.dofTotalVolume(ectx.globalDofIdx) *
3260 getValue(ectx.intQuants.porosity());
3271 this->lgrBlockExtractors_ =
3275 if (reportStepNum > 0 && !isSubStep) {
3277 const auto& rpt = this->
schedule_[reportStepNum - 1].rpt_config.get();
3278 if (rpt.contains(
"WELLS") && rpt.at(
"WELLS") > 1) {
3280 [&c = this->collectOnIORank_](
const int idx)
3281 {
return c.isCartIdxOnThisRank(idx); });
3283 const auto extraHandlers = std::array{
3292 const Simulator& simulator_;
3293 const CollectDataOnIORankType& collectOnIORank_;
3294 std::vector<typename Extractor::Entry> extractors_;
Common output functionality shared by simulator formulations.
Declares the properties required by the black oil model.
Definition: CollectDataOnIORank.hpp:57
The base class for the element-centered finite-volume discretization scheme.
Definition: ecfvdiscretization.hh:160
void assignMicrobialMass(const unsigned globalDofIdx, const Scalar microbialMass)
void assignCalciteMass(const unsigned globalDofIdx, const Scalar calciteMass)
void assignCo2InWater(const unsigned globalDofIdx, const Scalar co2InWater, const Scalar mM)
void assignVolumesSurface(const unsigned globalDofIdx, const std::array< Scalar, numPhases > &fip)
bool has(const Inplace::Phase phase) const
bool hasMicrobialMass() const
void assignWaterMass(const unsigned globalDofIdx, const std::array< Scalar, numPhases > &fip, const Scalar rhoW)
void assignCo2InGas(const unsigned globalDofIdx, const Co2InGasInput &v)
bool hasOxygenMass() const
void assignVolumesReservoir(const unsigned globalDofIdx, const Scalar saltConcentration, const std::array< Scalar, numPhases > &fipr)
void assignOxygenMass(const unsigned globalDofIdx, const Scalar oxygenMass)
void assignOilGasDistribution(const unsigned globalDofIdx, const Scalar gasInPlaceLiquid, const Scalar oilInPlaceGas)
void assignBiofilmMass(const unsigned globalDofIdx, const Scalar biofilmMass)
bool hasWaterMass() const
bool hasCo2InWater() const
void assignUreaMass(const unsigned globalDofIdx, const Scalar ureaMass)
bool hasCalciteMass() const
bool hasBiofilmMass() const
void assignGasWater(const unsigned globalDofIdx, const std::array< Scalar, numPhases > &fip, const Scalar gasInPlaceWater, const Scalar waterInPlaceGas)
const std::vector< int > blockVelocity() const
Definition: FlowsContainer.hpp:103
Definition: GenericOutputModule.hpp:91
const Schedule & schedule_
Definition: GenericOutputModule.hpp:536
ScalarBuffer oilVaporizationFactor_
Definition: GenericOutputModule.hpp:613
bool forceDisableFipOutput_
Definition: GenericOutputModule.hpp:557
RFTContainer< GetPropType< TypeTag, Properties::FluidSystem > > rftC_
Definition: GenericOutputModule.hpp:642
ScalarBuffer saturatedOilFormationVolumeFactor_
Definition: GenericOutputModule.hpp:618
GeochemistryContainer< Scalar > geochemC_
Definition: GenericOutputModule.hpp:634
ScalarBuffer rockCompPorvMultiplier_
Definition: GenericOutputModule.hpp:616
TracerContainer< GetPropType< TypeTag, Properties::FluidSystem > > tracerC_
Definition: GenericOutputModule.hpp:636
void doAllocBuffers(unsigned bufferSize, unsigned reportStepNum, const bool substep, const bool log, const bool forceRestartFieldAllocation, const EclHysteresisConfig *hysteresisConfig, unsigned numOutputNnc=0, std::map< std::string, int > rstKeywords={})
CO2H2Container< Scalar > CO2H2C_
Definition: GenericOutputModule.hpp:621
std::array< ScalarBuffer, numPhases > residual_
Definition: GenericOutputModule.hpp:638
ScalarBuffer sSol_
Definition: GenericOutputModule.hpp:597
std::map< std::tuple< std::string, int, int >, double > lgrBlockData_
Definition: GenericOutputModule.hpp:655
void setupExtraBlockData(const std::size_t reportStepNum, std::function< bool(int)> isCartIdxOnThisRank)
std::vector< int > failedCellsPd_
Definition: GenericOutputModule.hpp:583
ScalarBuffer shmax_
Definition: GenericOutputModule.hpp:608
ScalarBuffer sgmax_
Definition: GenericOutputModule.hpp:607
ScalarBuffer rockCompTransMultiplier_
Definition: GenericOutputModule.hpp:619
void setupBlockData(std::function< bool(int)> isCartIdxOnThisRank)
ScalarBuffer minimumOilPressure_
Definition: GenericOutputModule.hpp:617
ScalarBuffer temperature_
Definition: GenericOutputModule.hpp:591
ScalarBuffer pcow_
Definition: GenericOutputModule.hpp:623
ScalarBuffer drsdtcon_
Definition: GenericOutputModule.hpp:596
bool computeFip_
Definition: GenericOutputModule.hpp:559
std::optional< RegionPhasePoreVolAverage > regionAvgDensity_
Definition: GenericOutputModule.hpp:660
ScalarBuffer permFact_
Definition: GenericOutputModule.hpp:603
ScalarBuffer overburdenPressure_
Definition: GenericOutputModule.hpp:594
TpsaContainer< Scalar > tpsaC_
Definition: GenericOutputModule.hpp:628
ScalarBuffer rPorV_
Definition: GenericOutputModule.hpp:589
std::array< ScalarBuffer, numPhases > viscosity_
Definition: GenericOutputModule.hpp:632
void setupLgrBlockData(const std::map< std::string, int > &lgrNameToLevel, const std::function< bool(int, int)> &isLgrCellOnThisRank)
ScalarBuffer rvw_
Definition: GenericOutputModule.hpp:593
FIPContainer< GetPropType< TypeTag, Properties::FluidSystem > > fipC_
Definition: GenericOutputModule.hpp:570
ScalarBuffer cPolymer_
Definition: GenericOutputModule.hpp:599
void assignBuffer(data::Solution &sol, std::string_view name, UnitSystem::measure measure, std::vector< Scalar > &buffer)
static bool allocBufferIfRequested(std::map< std::string, int > &rstKeywords, unsigned bufferSize, std::vector< Scalar > &buffer, std::string_view kw, bool supported, bool required=false)
std::unordered_map< std::string, std::vector< int > > regions_
Definition: GenericOutputModule.hpp:571
ScalarBuffer swmin_
Definition: GenericOutputModule.hpp:610
FlowsContainer< GetPropType< TypeTag, Properties::FluidSystem > > flowsC_
Definition: GenericOutputModule.hpp:640
std::map< std::pair< std::string, int >, double > blockData_
Definition: GenericOutputModule.hpp:645
ScalarBuffer gasDissolutionFactor_
Definition: GenericOutputModule.hpp:612
MechContainer< Scalar > mech_
Definition: GenericOutputModule.hpp:627
BioeffectsContainer< Scalar > bioeffectsC_
Definition: GenericOutputModule.hpp:620
ExtboContainer< Scalar > extboC_
Definition: GenericOutputModule.hpp:604
ScalarBuffer gasDissolutionFactorInWater_
Definition: GenericOutputModule.hpp:614
ScalarBuffer pcgw_
Definition: GenericOutputModule.hpp:622
LogOutputHelper< Scalar > logOutput_
Definition: GenericOutputModule.hpp:542
void assignPhaseProperties(data::Solution &sol, const PhasePropertyNames &names)
Move the phase density and viscosity buffers to sol under names.
std::vector< Scalar > ScalarBuffer
Definition: GenericOutputModule.hpp:325
ScalarBuffer somin_
Definition: GenericOutputModule.hpp:609
void updateTotalVolumesAndPressures_(const unsigned globalDofIdx, const IntensiveQuantities &intQuants, const double totVolume, const Scalar referencePorosity)
Definition: GenericOutputModule.hpp:362
InterRegFlowMap interRegionFlows_
Definition: GenericOutputModule.hpp:541
ScalarBuffer soMax_
Definition: GenericOutputModule.hpp:605
std::array< ScalarBuffer, numPhases > density_
Definition: GenericOutputModule.hpp:631
ScalarBuffer cFoam_
Definition: GenericOutputModule.hpp:600
ScalarBuffer waterVaporizationFactor_
Definition: GenericOutputModule.hpp:615
std::array< ScalarBuffer, numPhases > saturation_
Definition: GenericOutputModule.hpp:630
ScalarBuffer rsw_
Definition: GenericOutputModule.hpp:592
ScalarBuffer oilSaturationPressure_
Definition: GenericOutputModule.hpp:595
const EclipseState & eclState_
Definition: GenericOutputModule.hpp:535
ScalarBuffer ppcw_
Definition: GenericOutputModule.hpp:611
virtual void assignToSolution(data::Solution &sol)
Move all buffers to data::Solution.
ScalarBuffer cSalt_
Definition: GenericOutputModule.hpp:601
ScalarBuffer pcog_
Definition: GenericOutputModule.hpp:624
const Inplace * initialInplace() const
Definition: GenericOutputModule.hpp:274
ScalarBuffer swMax_
Definition: GenericOutputModule.hpp:606
ScalarBuffer rswSol_
Definition: GenericOutputModule.hpp:598
std::map< std::pair< std::string, int >, double > extraBlockData_
Definition: GenericOutputModule.hpp:648
ScalarBuffer fluidPressure_
Definition: GenericOutputModule.hpp:590
ScalarBuffer gasFormationVolumeFactor_
Definition: GenericOutputModule.hpp:585
virtual void setRestart(const data::Solution &sol, unsigned elemIdx, unsigned globalDofIndex)
std::vector< int > failedCellsPb_
Definition: GenericOutputModule.hpp:582
ScalarBuffer pSalt_
Definition: GenericOutputModule.hpp:602
Inter-region flow accumulation maps for all region definition arrays.
Definition: InterRegFlows.hpp:179
void addConnection(const Cell &source, const Cell &destination, const data::InterRegFlowMap::FlowRates &rates)
void clear()
Clear all internal buffers, but preserve allocated capacity.
Output module for the results black oil model writing in ECL binary format.
Definition: OutputBlackoilModule.hpp:100
void processElement(const ElementContext &elemCtx)
Modify the internal buffers according to the intensive quanties relevant for an element.
Definition: OutputBlackoilModule.hpp:352
void initializeFluxData()
Prepare for capturing connection fluxes, particularly to account for inter-region flows.
Definition: OutputBlackoilModule.hpp:640
void setupExtractors(const bool isSubStep, const int reportStepNum)
Setup list of active element-level data extractors.
Definition: OutputBlackoilModule.hpp:290
void processFluxes(const ElementContext &elemCtx, ActiveIndex &&activeIndex, CartesianIndex &&cartesianIndex)
Capture connection fluxes, particularly to account for inter-region flows.
Definition: OutputBlackoilModule.hpp:603
void setRestart(const data::Solution &sol, const unsigned elemIdx, const unsigned globalDofIndex) override
Restore the buffers this module owns from a restart file.
Definition: OutputBlackoilModule.hpp:796
void clearExtractors()
Clear list of active element-level data extractors.
Definition: OutputBlackoilModule.hpp:298
void allocBuffers(const unsigned bufferSize, const unsigned reportStepNum, const bool substep, const bool log, const bool forceRestartFieldAllocation)
Allocate memory for the scalar fields we would like to write to ECL output files.
Definition: OutputBlackoilModule.hpp:268
void outputFipAndResvLogToCSV(const std::size_t reportStepNum, const bool substep, const Parallel::Communication &comm)
Definition: OutputBlackoilModule.hpp:537
void allocFormulationBuffers(std::map< std::string, int > &rstKeywords, const unsigned bufferSize) override
Allocate the buffers of the quantities only the black-oil formulation produces, keyed on their restar...
Definition: OutputBlackoilModule.hpp:817
void assignToFluidState(FluidState &fs, unsigned elemIdx) const
Definition: OutputBlackoilModule.hpp:664
void assignToSolution(data::Solution &sol) override
Move all buffers to data::Solution.
Definition: OutputBlackoilModule.hpp:309
void initHysteresisParams(Simulator &simulator, unsigned elemIdx) const
Definition: OutputBlackoilModule.hpp:716
void updateFluidInPlace(const ElementContext &elemCtx)
Definition: OutputBlackoilModule.hpp:781
OutputBlackOilModule(const Simulator &simulator, const SummaryConfig &smryCfg, const CollectDataOnIORankType &collectOnIORank)
Definition: OutputBlackoilModule.hpp:153
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:486
const InterRegFlowMap & getInterRegFlows() const
Get read-only access to collection of inter-region flows.
Definition: OutputBlackoilModule.hpp:658
void processElementBlockData(const ElementContext &elemCtx)
Definition: OutputBlackoilModule.hpp:398
void finalizeFluxData()
Finalize capturing connection fluxes.
Definition: OutputBlackoilModule.hpp:650
void updateFluidInPlace(const unsigned globalDofIdx, const IntensiveQuantities &intQuants, const double totVolume)
Definition: OutputBlackoilModule.hpp:788
Declare the properties used by the infrastructure code of the finite volume discretizations.
Dune::Communication< MPIComm > Communication
Definition: ParallelCommunication.hpp:30
Phase
Phase indices for reservoir coupling, we currently only support black-oil phases (oil,...
Definition: ReservoirCoupling.hpp:183
constexpr void ignoreUnused(T &&...) noexcept
Utility to silence "unused variable" warnings in lambdas.
Definition: OutputBlackoilModule.hpp:89
Definition: blackoilbioeffectsmodules.hh:45
std::string moduleVersionName()
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type::type GetPropType
get the type alias defined in the property (equivalent to old macro GET_PROP_TYPE(....
Definition: propertysystem.hh:233
This file provides the infrastructure to retrieve run-time parameters.
The Opm property system, traits with inheritance.
Definition: GenericOutputModule.hpp:410
std::string_view oilDensity
Definition: GenericOutputModule.hpp:411
Minimal characteristics of a cell from a simulation grid.
Definition: InterRegFlows.hpp:50