31#ifndef OPM_FLOW_PROBLEM_BLACK_HPP
32#define OPM_FLOW_PROBLEM_BLACK_HPP
34#include <opm/material/fluidsystems/BlackOilFluidSystem.hpp>
35#include <opm/material/fluidsystems/blackoilpvt/DryGasPvt.hpp>
36#include <opm/material/fluidsystems/blackoilpvt/WetGasPvt.hpp>
37#include <opm/material/fluidsystems/blackoilpvt/LiveOilPvt.hpp>
38#include <opm/material/fluidsystems/blackoilpvt/DeadOilPvt.hpp>
39#include <opm/material/fluidsystems/blackoilpvt/ConstantCompressibilityOilPvt.hpp>
40#include <opm/material/fluidsystems/blackoilpvt/ConstantCompressibilityWaterPvt.hpp>
41#include <opm/material/fluidsystems/blackoilpvt/ConstantRsDeadOilPvt.hpp>
47#include <opm/output/eclipse/EclipseIO.hpp>
49#include <opm/input/eclipse/Units/Units.hpp>
85template <
class TypeTag>
141 static constexpr bool enableDissolvedGas =
142 Indices::compositionSwitchIdx != std::numeric_limits<unsigned>::max();
143 enum { enableVapwat = getPropValue<TypeTag, Properties::EnableVapwat>() };
144 enum { enableDisgasInWater = getPropValue<TypeTag, Properties::EnableDisgasInWater>() };
145 enum { enableGeochemistry = getPropValue<TypeTag, Properties::EnableGeochemistry>() };
146 enum { enableMech = getPropValue<TypeTag, Properties::EnableMech>() };
148 using BioeffectsModule = BlackOilBioeffectsModule<TypeTag, enableBioeffects>;
149 using BrineModule = BlackOilBrineModule<TypeTag, enableBrine>;
150 using ConvectiveMixingModule = BlackOilConvectiveMixingModule<TypeTag, enableConvectiveMixing>;
153 using ExtboModule = BlackOilExtboModule<TypeTag, enableExtbo>;
154 using FoamModule = BlackOilFoamModule<TypeTag, enableFoam>;
155 using PolymerModule = BlackOilPolymerModule<TypeTag, enablePolymer>;
156 using SolventModule = BlackOilSolventModule<TypeTag, enableSolvent>;
158 using EclWriterType = EclWriter<TypeTag, OutputBlackOilModule<TypeTag> >;
159 using IndexTraits =
typename FluidSystem::IndexTraitsType;
161 using HybridNewton = BlackOilHybridNewton<TypeTag>;
162 using ModuleParams = BlackoilModuleParams<ConvectiveMixingModuleParam<Scalar>>;
165 using DamarisWriterType = DamarisWriter<TypeTag>;
181 DamarisWriterType::registerParameters();
194 simulator.vanguard().schedule(),
195 simulator.vanguard().actionState(),
196 simulator.vanguard().summaryState(),
198 simulator.vanguard().grid().comm())
204 const auto& vanguard = simulator.vanguard();
206 if constexpr (enableBrine) {
208 brineParams.template initFromState<enableBrine,
209 enableSaltPrecipitation>(vanguard.eclState());
210 BrineModule::setParams(std::move(brineParams));
213 if constexpr (enableDiffusion) {
214 DiffusionModule::initFromState(vanguard.eclState());
217 if constexpr (enableDispersion) {
218 DispersionModule::initFromState(vanguard.eclState());
221 if constexpr (enableExtbo) {
223 extboParams.template initFromState<enableExtbo>(vanguard.eclState());
224 ExtboModule::setParams(std::move(extboParams));
227 if constexpr (enableFoam) {
229 foamParams.template initFromState<enableFoam>(vanguard.eclState());
230 FoamModule::setParams(std::move(foamParams));
233 if constexpr (enableBioeffects) {
235 bioeffectsParams.template initFromState<enableBioeffects, enableMICP>(vanguard.eclState());
236 BioeffectsModule::setParams(std::move(bioeffectsParams));
239 if constexpr (enablePolymer) {
241 polymerParams.template initFromState<enablePolymer, enablePolymerMolarWeight>(vanguard.eclState());
242 PolymerModule::setParams(std::move(polymerParams));
245 if constexpr (enableSolvent) {
247 solventParams.template initFromState<enableSolvent>(vanguard.eclState(), vanguard.schedule());
248 SolventModule::setParams(std::move(solventParams));
252 eclWriter_ = std::make_unique<EclWriterType>(simulator);
256 if constexpr (!enableGeochemistry) {
257 if (vanguard.eclState().runspec().geochem().enabled()) {
258 throw std::runtime_error(
"GEOCHEM keyword in the deck but geochemistry module "
259 "was disabled at compile time!");
264 if constexpr (!enableMech) {
265 const auto& rspec = vanguard.eclState().runspec();
266 if (rspec.mech() && rspec.mechSolver().tpsa()) {
267 throw std::runtime_error(
"TPSA solver enabled in the deck, but geomechanics "
268 "module was disabled at compile time!");
274 damarisWriter_ = std::make_unique<DamarisWriterType>(simulator);
275 enableDamarisOutput_ = Parameters::Get<Parameters::EnableDamarisOutput>();
286 auto& simulator = this->simulator();
288 const int episodeIdx = simulator.episodeIndex();
289 const auto& schedule = simulator.vanguard().schedule();
294 .evalUDQAssignments(episodeIdx, simulator.vanguard().udqState());
296 if (episodeIdx >= 0) {
297 const auto& oilVap = schedule[episodeIdx].oilvap();
298 if (oilVap.getType() == OilVaporizationProperties::OilVaporization::VAPPARS) {
299 FluidSystem::setVapPars(oilVap.vap1(), oilVap.vap2());
302 FluidSystem::setVapPars(0.0, 0.0);
305 if constexpr (enableConvectiveMixing) {
306 ConvectiveMixingModule::beginEpisode(simulator.vanguard().eclState(), schedule, episodeIdx,
307 this->moduleParams_.convectiveMixingModuleParam);
329 FlowProblemType::finishInit();
331 auto& simulator = this->simulator();
333 auto finishTransmissibilities = [updated =
false,
this]()
mutable
335 if (updated) {
return; }
337 this->
transmissibilities_.finishInit([&vg = this->simulator().vanguard()](
const unsigned int it) {
338 return vg.gridIdxToEquilGridIdx(it);
349 if (simulator.vanguard().grid().comm().size() > 1) {
350 if (simulator.vanguard().grid().comm().rank() == 0)
351 eclWriter_->setTransmissibilities(&simulator.vanguard().globalTransmissibility());
353 finishTransmissibilities();
354 eclWriter_->setTransmissibilities(&simulator.problem().eclTransmissibilities());
357 std::function<
unsigned int(
unsigned int)> equilGridToGrid = [&simulator](
unsigned int i) {
358 return simulator.vanguard().gridEquilIdxToGridIdx(i);
361 this->
eclWriter_->extractOutputTransAndNNC(equilGridToGrid);
363 simulator.vanguard().releaseGlobalTransmissibilities();
365 const auto& eclState = simulator.vanguard().eclState();
366 const auto& schedule = simulator.vanguard().schedule();
369 simulator.setStartTime(schedule.getStartTime());
370 simulator.setEndTime(schedule.simTime(schedule.size() - 1));
376 simulator.setEpisodeIndex(-1);
377 simulator.setEpisodeLength(0.0);
382 this->gravity_ = 0.0;
383 if (Parameters::Get<Parameters::EnableGravity>() &&
384 eclState.getInitConfig().hasGravity())
387 this->gravity_[dim - 1] = unit::gravity;
393 const auto& tuning = schedule[0].tuning();
400 bool isThermal = eclState.getSimulationConfig().isThermal();
401 bool isTemp = eclState.getSimulationConfig().isTemp();
402 bool conserveInnerEnergy = isTemp || (isThermal && Parameters::Get<Parameters::ConserveInnerEnergyThermal>());
403 FluidSystem::setEnergyEqualEnthalpy(conserveInnerEnergy);
405 if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx) &&
406 FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
411 [&simulator](
const unsigned idx)
413 std::array<int,dim> coords;
414 simulator.vanguard().cartesianCoordinate(idx, coords);
415 std::ranges::transform(coords, coords.begin(),
416 [](const auto c) { return c + 1; });
428 finishTransmissibilities();
430 const auto& initconfig = eclState.getInitConfig();
432 if (initconfig.restartRequested()) {
443 if constexpr (getPropValue<TypeTag, Properties::EnablePolymer>()) {
444 const auto& vanguard = this->simulator().vanguard();
445 const auto& gridView = vanguard.gridView();
446 const int numElements = gridView.size(0);
447 this->
polymer_.maxAdsorption.resize(numElements, 0.0);
456 this->
drift_.resize(this->model().numGridDof());
463 if (!initconfig.restartRequested() && !eclState.getIOConfig().initOnly()) {
464 simulator.startNextEpisode(schedule.seconds(1));
465 simulator.setEpisodeIndex(0);
466 simulator.setTimeStepIndex(0);
469 if (Parameters::Get<Parameters::CheckSatfuncConsistency>() &&
479 this->simulator().vanguard().grid().comm().barrier();
481 throw std::domain_error {
482 "Saturation function end-points do not "
483 "meet requisite consistency conditions"
492 eclState.runspec().tabdims().getNumPVTTables());
494 if (this->enableVtkOutput_() && eclState.getIOConfig().initOnly()) {
495 simulator.setTimeStepSize(0.0);
496 simulator.model().applyInitialSolution();
500 if (!eclState.getIOConfig().initOnly()) {
501 if (!this->
enableTuning_ && eclState.getSimulationConfig().anyTUNING()) {
502 OpmLog::info(
"\nThe deck has TUNING in the SCHEDULE section, but "
503 "it is ignored due\nto the flag --enable-tuning=false. "
504 "Set this flag to true to activate it.\n"
505 "Manually tuning the simulator with the TUNING keyword may "
506 "increase run time.\nIt is recommended using the simulator's "
507 "default tuning (--enable-tuning=false).");
517 FlowProblemType::endTimeStep();
518 this->endStepApplyAction();
525 this->eclWriter().mutableOutputModule().invalidateLocalData();
528 const auto& grid = this->simulator().vanguard().gridView().grid();
530 using GridType = std::remove_cv_t<std::remove_reference_t<
decltype(grid)>>;
531 constexpr bool isCpGrid = std::is_same_v<GridType, Dune::CpGrid>;
532 if (!isCpGrid || (grid.maxLevel() == 0)) {
533 this->eclWriter_->evalSummaryState(!this->episodeWillBeOver());
537 OPM_TIMEBLOCK(applyActions);
539 const int episodeIdx = this->episodeIndex();
540 auto& simulator = this->simulator();
544 this->simulator().vanguard().schedule().clearEvents(episodeIdx);
548 .applyActions(episodeIdx, simulator.time() + simulator.timeStepSize(),
549 [
this](
const bool global)
551 using TransUpdateQuantities = typename
552 Vanguard::TransmissibilityType::TransUpdateQuantities;
554 this->transmissibilities_
555 .update(global, TransUpdateQuantities::All,
556 [&vg = this->simulator().vanguard()]
557 (const unsigned int i)
559 return vg.gridIdxToEquilGridIdx(i);
570 OPM_TIMEBLOCK(endEpisode);
583 .evalUDQAssignments(this->episodeIndex(), this->simulator().vanguard().udqState());
585 FlowProblemType::endEpisode();
590 if (this->enableEclOutput_) {
591 this->eclWriter_->writeReports(timer);
602 FlowProblemType::writeOutput(verbose);
604 const auto isSubStep = !this->episodeWillBeOver();
606 auto localCellData = data::Solution {};
611 if (this->enableDamarisOutput_ && (this->damarisWriter_ !=
nullptr)) {
612 this->damarisWriter_->writeOutput(localCellData, isSubStep);
616 if (this->enableEclOutput_ && (this->eclWriter_ !=
nullptr)) {
617 this->eclWriter_->writeOutput(std::move(localCellData), isSubStep,
618 this->simulator().vanguard().schedule()
619 .exitStatus().has_value());
625 OPM_TIMEBLOCK(finalizeOutput);
637 FlowProblemType::initialSolutionApplied();
642 this->thresholdPressures_.finishInit();
645 const auto& grid = this->simulator().vanguard().gridView().grid();
647 using GridType = std::remove_cv_t<std::remove_reference_t<
decltype(grid)>>;
648 constexpr bool isCpGrid = std::is_same_v<GridType, Dune::CpGrid>;
650 if (!isCpGrid || (grid.maxLevel() == 0)) {
651 if (this->simulator().episodeIndex() == 0) {
652 eclWriter_->writeInitialFIPReport();
658 unsigned globalDofIdx,
659 unsigned timeIdx)
const override
661 this->aquiferModel_.addToSource(rate, globalDofIdx, timeIdx);
664 const auto& source = this->simulator().vanguard().schedule()[this->episodeIndex()].source();
665 std::array<int,3> ijk;
666 this->simulator().vanguard().cartesianCoordinate(globalDofIdx, ijk);
668 if (source.hasSource(ijk)) {
669 const int pvtRegionIdx = this->pvtRegionIndex(globalDofIdx);
670 static std::array<SourceComponent, 3> sc_map = {SourceComponent::WATER, SourceComponent::OIL, SourceComponent::GAS};
671 static std::array<int, 3> phidx_map = {FluidSystem::waterPhaseIdx, FluidSystem::oilPhaseIdx, FluidSystem::gasPhaseIdx};
672 static std::array<int, 3> cidx_map = {waterCompIdx, oilCompIdx, gasCompIdx};
674 for (
unsigned i = 0; i < phidx_map.size(); ++i) {
675 const auto phaseIdx = phidx_map[i];
676 const auto sourceComp = sc_map[i];
677 const auto compIdx = cidx_map[i];
678 if (!FluidSystem::phaseIsActive(phaseIdx)) {
681 Scalar mass_rate = source.rate(ijk, sourceComp) / this->model().dofTotalVolume(globalDofIdx);
682 if constexpr (getPropValue<TypeTag, Properties::BlackoilConserveSurfaceVolume>()) {
683 mass_rate /= FluidSystem::referenceDensity(phaseIdx, pvtRegionIdx);
685 rate[FluidSystem::canonicalToActiveCompIdx(compIdx)] += mass_rate;
688 if constexpr (enableSolvent) {
689 Scalar mass_rate = source.rate(ijk, SourceComponent::SOLVENT) / this->model().dofTotalVolume(globalDofIdx);
690 if constexpr (getPropValue<TypeTag, Properties::BlackoilConserveSurfaceVolume>()) {
691 const auto& solventPvt = SolventModule::solventPvt();
692 mass_rate /= solventPvt.referenceDensity(pvtRegionIdx);
694 rate[Indices::contiSolventEqIdx] += mass_rate;
696 if constexpr (enablePolymer) {
697 rate[Indices::polymerConcentrationIdx] += source.rate(ijk, SourceComponent::POLYMER) / this->model().dofTotalVolume(globalDofIdx);
699 if constexpr (enableMICP) {
700 rate[Indices::microbialConcentrationIdx] += source.rate(ijk, SourceComponent::MICR) / this->model().dofTotalVolume(globalDofIdx);
701 rate[Indices::oxygenConcentrationIdx] += source.rate(ijk, SourceComponent::OXYG) / this->model().dofTotalVolume(globalDofIdx);
702 rate[Indices::ureaConcentrationIdx] += source.rate(ijk, SourceComponent::UREA) / (this->model().dofTotalVolume(globalDofIdx));
704 if constexpr (energyModuleType == EnergyModules::FullyImplicitThermal) {
705 for (
unsigned i = 0; i < phidx_map.size(); ++i) {
706 const auto phaseIdx = phidx_map[i];
707 if (!FluidSystem::phaseIsActive(phaseIdx)) {
710 const auto sourceComp = sc_map[i];
711 const auto source_hrate = source.hrate(ijk, sourceComp);
713 rate[Indices::contiEnergyEqIdx] += source_hrate.value() / this->model().dofTotalVolume(globalDofIdx);
715 const auto& intQuants = this->simulator().model().intensiveQuantities(globalDofIdx, 0);
716 auto fs = intQuants.fluidState();
718 const auto source_temp = source.temperature(ijk, sourceComp);
720 Scalar temperature = source_temp.value();
721 fs.setTemperature(temperature);
723 const auto& h = FluidSystem::enthalpy(fs, phaseIdx, pvtRegionIdx);
724 Scalar mass_rate = source.rate(ijk, sourceComp)/ this->model().dofTotalVolume(globalDofIdx);
725 Scalar energy_rate = getValue(h)*mass_rate;
726 rate[Indices::contiEnergyEqIdx] += energy_rate;
734 if (this->enableDriftCompensation_) {
735 const auto& simulator = this->simulator();
736 const auto& model = this->model();
741 Scalar maxCompensation = model.newtonMethod().tolerance()/10;
742 Scalar poro = this->porosity(globalDofIdx, timeIdx);
743 Scalar dt = simulator.timeStepSize();
744 EqVector dofDriftRate = this->drift_[globalDofIdx];
745 dofDriftRate /= dt*model.dofTotalVolume(globalDofIdx);
748 for (
unsigned eqIdx = 0; eqIdx < numEq; ++ eqIdx) {
749 Scalar cnv = std::abs(dofDriftRate[eqIdx])*dt*model.eqWeight(globalDofIdx, eqIdx)/poro;
750 if (cnv > maxCompensation) {
751 dofDriftRate[eqIdx] *= maxCompensation/cnv;
755 for (
unsigned eqIdx = 0; eqIdx < numEq; ++ eqIdx)
756 rate[eqIdx] -= dofDriftRate[eqIdx];
763 template <
class LhsEval,
class Callback>
766 OPM_TIMEBLOCK_LOCAL(permFactTransMultiplier, Subsystem::PvtProps);
767 if constexpr (enableSaltPrecipitation) {
768 const auto& fs = intQuants.fluidState();
769 unsigned tableIdx = this->simulator().problem().satnumRegionIndex(elementIdx);
770 LhsEval porosityFactor = obtain(1. - fs.saltSaturation());
771 porosityFactor = min(porosityFactor, 1.0);
772 const auto& permfactTable = BrineModule::permfactTable(tableIdx);
773 return permfactTable.eval(porosityFactor,
true);
775 else if constexpr (enableBioeffects) {
776 return obtain(intQuants.permFactor());
785 {
return initialFluidStates_[globalDofIdx]; }
788 {
return initialFluidStates_; }
791 {
return initialFluidStates_; }
794 {
return eclWriter_->eclIO(); }
797 {
return eclWriter_->setSubStepReport(report); }
800 {
return eclWriter_->setSimulationReport(report); }
804 OPM_TIMEBLOCK_LOCAL(boundaryFluidState, Subsystem::Assembly);
805 const auto& bcprop = this->simulator().vanguard().schedule()[this->episodeIndex()].bcprop;
806 if (bcprop.size() > 0) {
807 FaceDir::DirEnum dir = FaceDir::FromIntersectionIndex(directionId);
811 if (this->bcindex_(dir)[globalDofIdx] == 0)
812 return initialFluidStates_[globalDofIdx];
814 const auto& bc = bcprop[this->bcindex_(dir)[globalDofIdx]];
815 if (bc.bctype == BCType::DIRICHLET )
817 InitialFluidState fluidState;
818 const int pvtRegionIdx = this->pvtRegionIndex(globalDofIdx);
819 fluidState.setPvtRegionIndex(pvtRegionIdx);
821 switch (bc.component) {
822 case BCComponent::OIL:
823 if (!FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx))
824 throw std::logic_error(
"oil is not active and you're trying to add oil BC");
826 fluidState.setSaturation(FluidSystem::oilPhaseIdx, 1.0);
828 case BCComponent::GAS:
829 if (!FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx))
830 throw std::logic_error(
"gas is not active and you're trying to add gas BC");
832 fluidState.setSaturation(FluidSystem::gasPhaseIdx, 1.0);
834 case BCComponent::WATER:
835 if (!FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx))
836 throw std::logic_error(
"water is not active and you're trying to add water BC");
838 fluidState.setSaturation(FluidSystem::waterPhaseIdx, 1.0);
840 case BCComponent::SOLVENT:
841 case BCComponent::POLYMER:
842 case BCComponent::MICR:
843 case BCComponent::OXYG:
844 case BCComponent::UREA:
846 throw std::logic_error(
"you need to specify a valid component (OIL, WATER or GAS) when DIRICHLET type is set in BC");
848 fluidState.setTotalSaturation(1.0);
849 double pressure = initialFluidStates_[globalDofIdx].pressure(this->refPressurePhaseIdx_());
850 const auto pressure_input = bc.pressure;
851 if (pressure_input) {
852 pressure = *pressure_input;
855 std::array<Scalar, numPhases> pc = {0};
856 const auto& matParams = this->materialLawParams(globalDofIdx);
857 MaterialLaw::capillaryPressures(pc, matParams, fluidState);
858 Valgrind::CheckDefined(pressure);
859 Valgrind::CheckDefined(pc);
860 for (
unsigned activePhaseIdx = 0; activePhaseIdx < FluidSystem::numActivePhases(); ++activePhaseIdx) {
861 const auto phaseIdx = FluidSystem::activeToCanonicalPhaseIdx(activePhaseIdx);
862 if (Indices::oilEnabled)
863 fluidState.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[oilPhaseIdx]));
864 else if (Indices::gasEnabled)
865 fluidState.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[gasPhaseIdx]));
866 else if (Indices::waterEnabled)
868 fluidState.setPressure(phaseIdx, pressure);
870 if constexpr (energyModuleType != EnergyModules::NoTemperature) {
871 double temperature = initialFluidStates_[globalDofIdx].temperature(0);
872 const auto temperature_input = bc.temperature;
873 if(temperature_input)
874 temperature = *temperature_input;
875 fluidState.setTemperature(temperature);
878 if constexpr (enableDissolvedGas) {
879 if (FluidSystem::enableDissolvedGas()) {
880 fluidState.setRs(0.0);
881 fluidState.setRv(0.0);
884 if constexpr (enableDisgasInWater) {
885 if (FluidSystem::enableDissolvedGasInWater()) {
886 fluidState.setRsw(0.0);
889 if constexpr (enableVapwat) {
890 if (FluidSystem::enableVaporizedWater()) {
891 fluidState.setRvw(0.0);
895 for (
unsigned activePhaseIdx = 0; activePhaseIdx < FluidSystem::numActivePhases(); ++activePhaseIdx) {
896 const auto phaseIdx = FluidSystem::activeToCanonicalPhaseIdx(activePhaseIdx);
898 const auto& b = FluidSystem::inverseFormationVolumeFactor(fluidState, phaseIdx, pvtRegionIdx);
899 fluidState.setInvB(phaseIdx, b);
901 const auto& rho = FluidSystem::density(fluidState, phaseIdx, pvtRegionIdx);
902 fluidState.setDensity(phaseIdx, rho);
903 if constexpr (energyModuleType == EnergyModules::FullyImplicitThermal) {
904 const auto& h = FluidSystem::enthalpy(fluidState, phaseIdx, pvtRegionIdx);
905 fluidState.setEnthalpy(phaseIdx, h);
908 fluidState.checkDefined();
912 return initialFluidStates_[globalDofIdx];
917 {
return *eclWriter_; }
920 {
return *eclWriter_; }
928 return this->mixControls_.maxGasDissolutionFactor(timeIdx, globalDofIdx,
929 this->episodeIndex(),
930 this->pvtRegionIndex(globalDofIdx));
939 return this->mixControls_.maxOilVaporizationFactor(timeIdx, globalDofIdx,
940 this->episodeIndex(),
941 this->pvtRegionIndex(globalDofIdx));
957 const auto& rspec = this->simulator().vanguard().eclState().runspec();
958 const bool tpsaActive = rspec.mech() && rspec.mechSolver().tpsa();
963 int episodeIdx = this->episodeIndex();
964 return !this->mixControls_.drsdtActive(episodeIdx) &&
965 !this->mixControls_.drvdtActive(episodeIdx) &&
966 this->rockCompPoroMultWc_.empty() &&
967 this->rockCompPoroMult_.empty();
976 template <
class Context>
979 unsigned globalDofIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
981 values.setPvtRegionIndex(pvtRegionIndex(context, spaceIdx, timeIdx));
982 values.assignNaive(initialFluidStates_[globalDofIdx]);
984 if constexpr (enableSolvent) {
985 SolventModule::assignPrimaryVars(values,
986 this->solventSaturation_[globalDofIdx],
987 this->solventRsw_[globalDofIdx]);
990 if constexpr (enablePolymer) {
991 values[Indices::polymerConcentrationIdx] = this->polymer_.concentration[globalDofIdx];
994 if constexpr (enablePolymerMolarWeight) {
995 values[Indices::polymerMoleWeightIdx]= this->polymer_.moleWeight[globalDofIdx];
998 if constexpr (enableBrine) {
999 if (enableSaltPrecipitation && values.primaryVarsMeaningBrine() == PrimaryVariables::BrineMeaning::Sp) {
1000 values[Indices::saltConcentrationIdx] = initialFluidStates_[globalDofIdx].saltSaturation();
1003 values[Indices::saltConcentrationIdx] = initialFluidStates_[globalDofIdx].saltConcentration();
1007 if constexpr (enableBioeffects) {
1008 values[Indices::microbialConcentrationIdx] = this->bioeffects_.microbialConcentration[globalDofIdx];
1009 values[Indices::biofilmVolumeFractionIdx] = this->bioeffects_.biofilmVolumeFraction[globalDofIdx];
1010 if constexpr (enableMICP) {
1011 values[Indices::oxygenConcentrationIdx] = this->bioeffects_.oxygenConcentration[globalDofIdx];
1012 values[Indices::ureaConcentrationIdx] = this->bioeffects_.ureaConcentration[globalDofIdx];
1013 values[Indices::calciteVolumeFractionIdx] = this->bioeffects_.calciteVolumeFraction[globalDofIdx];
1017 values.checkDefined();
1023 return this->mixControls_.drsdtcon(elemIdx, episodeIdx,
1024 this->pvtRegionIndex(elemIdx));
1029 return this->mixControls_.drsdtConvective(episodeIdx, this->pvtRegionIndex(elemIdx));
1037 template <
class Context>
1039 const Context& context,
1041 unsigned timeIdx)
const
1043 OPM_TIMEBLOCK_LOCAL(eclProblemBoundary, Subsystem::Assembly);
1044 if (!context.intersection(spaceIdx).boundary())
1047 if constexpr (energyModuleType != EnergyModules::FullyImplicitThermal || !enableThermalFluxBoundaries)
1055 unsigned interiorDofIdx = context.interiorScvIndex(spaceIdx, timeIdx);
1056 unsigned globalDofIdx = context.globalSpaceIndex(interiorDofIdx, timeIdx);
1057 values.setThermalFlow(context, spaceIdx, timeIdx, this->initialFluidStates_[globalDofIdx] );
1060 if (this->nonTrivialBoundaryConditions()) {
1061 unsigned indexInInside = context.intersection(spaceIdx).indexInInside();
1062 unsigned interiorDofIdx = context.interiorScvIndex(spaceIdx, timeIdx);
1063 unsigned globalDofIdx = context.globalSpaceIndex(interiorDofIdx, timeIdx);
1064 unsigned pvtRegionIdx = pvtRegionIndex(context, spaceIdx, timeIdx);
1065 const auto [type, massrate] = this->boundaryCondition(globalDofIdx, indexInInside);
1066 if (type == BCType::THERMAL)
1067 values.setThermalFlow(context, spaceIdx, timeIdx, this->boundaryFluidState(globalDofIdx, indexInInside));
1068 else if (type == BCType::FREE || type == BCType::DIRICHLET)
1069 values.setFreeFlow(context, spaceIdx, timeIdx, this->boundaryFluidState(globalDofIdx, indexInInside));
1070 else if (type == BCType::RATE)
1071 values.setMassRate(massrate, pvtRegionIdx);
1081 auto& simulator = this->simulator();
1082 const auto& eclState = simulator.vanguard().eclState();
1084 std::size_t numElems = this->model().numGridDof();
1085 this->initialFluidStates_.resize(numElems);
1086 if constexpr (enableSolvent) {
1087 this->solventSaturation_.resize(numElems, 0.0);
1088 this->solventRsw_.resize(numElems, 0.0);
1091 if constexpr (enablePolymer)
1092 this->polymer_.concentration.resize(numElems, 0.0);
1094 if constexpr (enablePolymerMolarWeight) {
1095 const std::string msg {
"Support of the RESTART for polymer molecular weight "
1096 "is not implemented yet. The polymer weight value will be "
1097 "zero when RESTART begins"};
1098 OpmLog::warning(
"NO_POLYMW_RESTART", msg);
1099 this->polymer_.moleWeight.resize(numElems, 0.0);
1102 if constexpr (enableBioeffects) {
1103 this->bioeffects_.resize(numElems);
1107 this->mixControls_.init(numElems, restart_step, eclState.runspec().tabdims().getNumPVTTables());
1109 if constexpr (enableBioeffects) {
1110 this->bioeffects_ = this->eclWriter_->outputModule().getBioeffects().getSolution();
1113 for (std::size_t elemIdx = 0; elemIdx < numElems; ++elemIdx) {
1114 auto& elemFluidState = this->initialFluidStates_[elemIdx];
1115 elemFluidState.setPvtRegionIndex(pvtRegionIndex(elemIdx));
1116 this->eclWriter_->outputModule().initHysteresisParams(simulator, elemIdx);
1117 this->eclWriter_->outputModule().assignToFluidState(elemFluidState, elemIdx);
1126 auto ssol = enableSolvent
1127 ? this->eclWriter_->outputModule().getSolventSaturation(elemIdx)
1130 this->processRestartSaturations_(elemFluidState, ssol);
1132 if constexpr (enableSolvent) {
1133 this->solventSaturation_[elemIdx] = ssol;
1134 this->solventRsw_[elemIdx] = this->eclWriter_->outputModule().getSolventRsw(elemIdx);
1139 if constexpr (energyModuleType != EnergyModules::NoTemperature) {
1140 bool needTemperature = (eclState.runspec().co2Storage() || eclState.runspec().h2Storage());
1141 if (needTemperature) {
1142 const auto& fp = simulator.vanguard().eclState().fieldProps();
1143 elemFluidState.setTemperature(fp.get_double(
"TEMPI")[elemIdx]);
1147 this->mixControls_.updateLastValues(elemIdx, elemFluidState.Rs(), elemFluidState.Rv());
1149 if constexpr (enablePolymer)
1150 this->polymer_.concentration[elemIdx] = this->eclWriter_->outputModule().getPolymerConcentration(elemIdx);
1154 const int episodeIdx = this->episodeIndex();
1155 this->mixControls_.updateMaxValues(episodeIdx, simulator.timeStepSize());
1160 auto& sol = this->model().solution(0);
1161 const auto& gridView = this->gridView();
1163 for (
const auto& elem : elements(gridView, Dune::Partitions::interior)) {
1164 elemCtx.updatePrimaryStencil(elem);
1165 int elemIdx = elemCtx.globalSpaceIndex(0, 0);
1166 this->initial(sol[elemIdx], elemCtx, 0, 0);
1174 this->model().syncOverlap();
1177 this->updateReferencePorosity_();
1178 this->mixControls_.init(this->model().numGridDof(),
1179 this->episodeIndex(),
1180 eclState.runspec().tabdims().getNumPVTTables());
1188 {
return thresholdPressures_.thresholdPressure(elem1Idx, elem2Idx); }
1191 {
return thresholdPressures_; }
1194 {
return thresholdPressures_; }
1198 return moduleParams_;
1201 template<
class Serializer>
1205 serializer(mixControls_);
1206 serializer(*eclWriter_);
1212 this->updateExplicitQuantities_(first_step_after_restart);
1214 if constexpr (getPropValue<TypeTag, Properties::EnablePolymer>())
1215 updateMaxPolymerAdsorption_();
1217 mixControls_.updateExplicitQuantities(episodeIdx, timeStepSize);
1223 this->updateProperty_(
"FlowProblemBlackoil::updateMaxPolymerAdsorption_() failed:",
1226 this->updateMaxPolymerAdsorption_(compressedDofIdx,iq);
1232 const Scalar pa = scalarValue(iq.polymerAdsorption());
1233 auto& mpa = this->polymer_.maxAdsorption;
1234 if (mpa[compressedDofIdx] < pa) {
1235 mpa[compressedDofIdx] = pa;
1244 std::vector<Scalar> sumInvB(numPhases, 0.0);
1245 const auto& gridView = this->gridView();
1247 for(
const auto& elem: elements(gridView, Dune::Partitions::interior)) {
1248 elemCtx.updatePrimaryStencil(elem);
1249 int elemIdx = elemCtx.globalSpaceIndex(0, 0);
1250 const auto& dofFluidState = this->initialFluidStates_[elemIdx];
1251 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
1252 if (!FluidSystem::phaseIsActive(phaseIdx))
1255 sumInvB[phaseIdx] += dofFluidState.invB(phaseIdx);
1259 std::size_t numDof = this->model().numGridDof();
1260 const auto& comm = this->simulator().vanguard().grid().comm();
1261 comm.sum(sumInvB.data(),sumInvB.size());
1262 Scalar numTotalDof = comm.sum(numDof);
1264 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
1265 if (!FluidSystem::phaseIsActive(phaseIdx))
1268 Scalar avgB = numTotalDof / sumInvB[phaseIdx];
1269 const unsigned solventCompIdx = FluidSystem::solventComponentIndex(phaseIdx);
1270 const unsigned activeSolventCompIdx = FluidSystem::canonicalToActiveCompIdx(solventCompIdx);
1271 this->model().setEqWeight(activeSolventCompIdx, avgB);
1278 OPM_TIMEBLOCK(updateCompositionChangeLimits);
1281 int episodeIdx = this->episodeIndex();
1282 std::array<bool,3> active{this->mixControls_.drsdtConvective(episodeIdx),
1283 this->mixControls_.drsdtActive(episodeIdx),
1284 this->mixControls_.drvdtActive(episodeIdx)};
1285 if (!active[0] && !active[1] && !active[2]) {
1289 this->updateProperty_(
"FlowProblemBlackoil::updateCompositionChangeLimits_()) failed:",
1290 [
this,episodeIdx,active](
unsigned compressedDofIdx,
1293 const DimMatrix& perm = this->intrinsicPermeability(compressedDofIdx);
1294 const Scalar distZ = active[0] ? this->simulator().vanguard().cellThickness(compressedDofIdx) : 0.0;
1295 const int pvtRegionIdx = this->pvtRegionIndex(compressedDofIdx);
1296 this->mixControls_.update(compressedDofIdx,
1299 this->gravity_[
dim - 1],
1312 if(this->simulator().vanguard().grid().maxLevel() > 0) {
1313 throw std::invalid_argument(
"Refined grids are not yet supported for restart ");
1317 auto& simulator = this->simulator();
1318 const auto& schedule = simulator.vanguard().schedule();
1319 const auto& eclState = simulator.vanguard().eclState();
1320 const auto& initconfig = eclState.getInitConfig();
1321 const int restart_step = initconfig.getRestartStep();
1323 simulator.setTime(schedule.seconds(restart_step));
1325 simulator.startNextEpisode(simulator.startTime() + simulator.time(),
1326 schedule.stepLength(restart_step));
1327 simulator.setEpisodeIndex(restart_step);
1329 this->eclWriter_->beginRestart();
1331 Scalar dt = std::min(this->eclWriter_->restartTimeStepSize(), simulator.episodeLength());
1332 simulator.setTimeStepSize(dt);
1334 this->readSolutionFromOutputModule(restart_step,
false);
1336 this->eclWriter_->endRestart();
1341 const auto& simulator = this->simulator();
1346 std::size_t numElems = this->model().numGridDof();
1347 this->initialFluidStates_.resize(numElems);
1348 for (std::size_t elemIdx = 0; elemIdx < numElems; ++elemIdx) {
1349 auto& elemFluidState = this->initialFluidStates_[elemIdx];
1356 const auto& simulator = this->simulator();
1357 const auto& vanguard = simulator.vanguard();
1358 const auto& eclState = vanguard.eclState();
1359 const auto& fp = eclState.fieldProps();
1360 bool has_swat = fp.has_double(
"SWAT");
1361 bool has_sgas = fp.has_double(
"SGAS");
1362 bool has_rs = fp.has_double(
"RS");
1363 bool has_rsw = fp.has_double(
"RSW");
1364 bool has_rv = fp.has_double(
"RV");
1365 bool has_rvw = fp.has_double(
"RVW");
1366 bool has_pressure = fp.has_double(
"PRESSURE");
1367 bool has_salt = fp.has_double(
"SALT");
1368 bool has_saltp = fp.has_double(
"SALTP");
1371 if (Indices::numPhases > 1) {
1372 if (FluidSystem::phaseIsActive(waterPhaseIdx) && !has_swat)
1373 throw std::runtime_error(
"The ECL input file requires the presence of the SWAT keyword if "
1374 "the water phase is active");
1375 if (FluidSystem::phaseIsActive(gasPhaseIdx) && !has_sgas && FluidSystem::phaseIsActive(oilPhaseIdx))
1376 throw std::runtime_error(
"The ECL input file requires the presence of the SGAS keyword if "
1377 "the gas phase is active");
1380 throw std::runtime_error(
"The ECL input file requires the presence of the PRESSURE "
1381 "keyword if the model is initialized explicitly");
1382 if (FluidSystem::enableDissolvedGas() && !has_rs)
1383 throw std::runtime_error(
"The ECL input file requires the RS keyword to be present if"
1384 " dissolved gas is enabled and the model is initialized explicitly");
1385 if (FluidSystem::enableDissolvedGasInWater() && !has_rsw)
1386 OpmLog::warning(
"The model is initialized explicitly and the RSW keyword is not present in the"
1387 " ECL input file. The RSW values are set equal to 0");
1388 if (FluidSystem::enableVaporizedOil() && !has_rv)
1389 throw std::runtime_error(
"The ECL input file requires the RV keyword to be present if"
1390 " vaporized oil is enabled and the model is initialized explicitly");
1391 if (FluidSystem::enableVaporizedWater() && !has_rvw)
1392 throw std::runtime_error(
"The ECL input file requires the RVW keyword to be present if"
1393 " vaporized water is enabled and the model is initialized explicitly");
1394 if (enableBrine && !has_salt)
1395 throw std::runtime_error(
"The ECL input file requires the SALT keyword to be present if"
1396 " brine is enabled and the model is initialized explicitly");
1397 if (enableSaltPrecipitation && !has_saltp)
1398 throw std::runtime_error(
"The ECL input file requires the SALTP keyword to be present if"
1399 " salt precipitation is enabled and the model is initialized explicitly");
1401 std::size_t numDof = this->model().numGridDof();
1403 initialFluidStates_.resize(numDof);
1405 std::vector<double> waterSaturationData;
1406 std::vector<double> gasSaturationData;
1407 std::vector<double> pressureData;
1408 std::vector<double> rsData;
1409 std::vector<double> rswData;
1410 std::vector<double> rvData;
1411 std::vector<double> rvwData;
1412 std::vector<double> tempiData;
1413 std::vector<double> saltData;
1414 std::vector<double> saltpData;
1416 if (FluidSystem::phaseIsActive(waterPhaseIdx) && Indices::numPhases > 1)
1417 waterSaturationData = fp.get_double(
"SWAT");
1419 waterSaturationData.resize(numDof);
1421 if (FluidSystem::phaseIsActive(gasPhaseIdx) && FluidSystem::phaseIsActive(oilPhaseIdx))
1422 gasSaturationData = fp.get_double(
"SGAS");
1424 gasSaturationData.resize(numDof);
1426 pressureData = fp.get_double(
"PRESSURE");
1427 if (FluidSystem::enableDissolvedGas())
1428 rsData = fp.get_double(
"RS");
1430 if (FluidSystem::enableDissolvedGasInWater() && has_rsw)
1431 rswData = fp.get_double(
"RSW");
1433 if (FluidSystem::enableVaporizedOil())
1434 rvData = fp.get_double(
"RV");
1436 if (FluidSystem::enableVaporizedWater())
1437 rvwData = fp.get_double(
"RVW");
1440 tempiData = fp.get_double(
"TEMPI");
1443 if constexpr (enableBrine)
1444 saltData = fp.get_double(
"SALT");
1447 if constexpr (enableSaltPrecipitation)
1448 saltpData = fp.get_double(
"SALTP");
1451 for (std::size_t dofIdx = 0; dofIdx < numDof; ++dofIdx) {
1452 auto& dofFluidState = initialFluidStates_[dofIdx];
1454 dofFluidState.setPvtRegionIndex(pvtRegionIndex(dofIdx));
1459 if constexpr (energyModuleType != EnergyModules::NoTemperature) {
1460 Scalar temperatureLoc = tempiData[dofIdx];
1461 if (!std::isfinite(temperatureLoc) || temperatureLoc <= 0)
1462 temperatureLoc = FluidSystem::surfaceTemperature;
1463 dofFluidState.setTemperature(temperatureLoc);
1469 if constexpr (enableBrine)
1470 dofFluidState.setSaltConcentration(saltData[dofIdx]);
1475 if constexpr (enableSaltPrecipitation)
1476 dofFluidState.setSaltSaturation(saltpData[dofIdx]);
1481 if (FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx))
1482 dofFluidState.setSaturation(FluidSystem::waterPhaseIdx,
1483 waterSaturationData[dofIdx]);
1485 if (FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)){
1486 if (!FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)){
1487 dofFluidState.setSaturation(FluidSystem::gasPhaseIdx,
1489 - waterSaturationData[dofIdx]);
1492 dofFluidState.setSaturation(FluidSystem::gasPhaseIdx,
1493 gasSaturationData[dofIdx]);
1495 if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)) {
1496 const Scalar soil = 1.0 - waterSaturationData[dofIdx] - gasSaturationData[dofIdx];
1497 if (soil < smallSaturationTolerance_) {
1498 dofFluidState.setSaturation(FluidSystem::oilPhaseIdx, 0.0);
1501 dofFluidState.setSaturation(FluidSystem::oilPhaseIdx, soil);
1508 Scalar pressure = pressureData[dofIdx];
1512 std::array<Scalar, numPhases> pc = {0};
1513 const auto& matParams = this->materialLawParams(dofIdx);
1514 MaterialLaw::capillaryPressures(pc, matParams, dofFluidState);
1515 Valgrind::CheckDefined(pressure);
1516 Valgrind::CheckDefined(pc);
1517 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
1518 if (!FluidSystem::phaseIsActive(phaseIdx))
1521 if (Indices::oilEnabled)
1522 dofFluidState.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[oilPhaseIdx]));
1523 else if (Indices::gasEnabled)
1524 dofFluidState.setPressure(phaseIdx, pressure + (pc[phaseIdx] - pc[gasPhaseIdx]));
1525 else if (Indices::waterEnabled)
1527 dofFluidState.setPressure(phaseIdx, pressure);
1530 if constexpr (enableDissolvedGas) {
1531 if (FluidSystem::enableDissolvedGas())
1532 dofFluidState.setRs(rsData[dofIdx]);
1533 else if (Indices::gasEnabled && Indices::oilEnabled)
1534 dofFluidState.setRs(0.0);
1535 if (FluidSystem::enableVaporizedOil())
1536 dofFluidState.setRv(rvData[dofIdx]);
1537 else if (Indices::gasEnabled && Indices::oilEnabled)
1538 dofFluidState.setRv(0.0);
1541 if constexpr (enableDisgasInWater) {
1542 if (FluidSystem::enableDissolvedGasInWater() && has_rsw)
1543 dofFluidState.setRsw(rswData[dofIdx]);
1546 if constexpr (enableVapwat) {
1547 if (FluidSystem::enableVaporizedWater())
1548 dofFluidState.setRvw(rvwData[dofIdx]);
1554 for (
unsigned phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
1555 if (!FluidSystem::phaseIsActive(phaseIdx))
1558 const auto& b = FluidSystem::inverseFormationVolumeFactor(dofFluidState, phaseIdx, pvtRegionIndex(dofIdx));
1559 dofFluidState.setInvB(phaseIdx, b);
1561 const auto& rho = FluidSystem::density(dofFluidState, phaseIdx, pvtRegionIndex(dofIdx));
1562 dofFluidState.setDensity(phaseIdx, rho);
1573 Scalar sumSaturation = 0.0;
1574 for (std::size_t phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
1575 if (FluidSystem::phaseIsActive(phaseIdx)) {
1576 if (elemFluidState.saturation(phaseIdx) < smallSaturationTolerance_)
1577 elemFluidState.setSaturation(phaseIdx, 0.0);
1579 sumSaturation += elemFluidState.saturation(phaseIdx);
1583 if constexpr (enableSolvent) {
1584 if (solventSaturation < smallSaturationTolerance_)
1585 solventSaturation = 0.0;
1587 sumSaturation += solventSaturation;
1590 assert(sumSaturation > 0.0);
1592 for (std::size_t phaseIdx = 0; phaseIdx < numPhases; ++phaseIdx) {
1593 if (FluidSystem::phaseIsActive(phaseIdx)) {
1594 const Scalar saturation = elemFluidState.saturation(phaseIdx) / sumSaturation;
1595 elemFluidState.setSaturation(phaseIdx, saturation);
1598 if constexpr (enableSolvent) {
1599 solventSaturation = solventSaturation / sumSaturation;
1605 FlowProblemType::readInitialCondition_();
1607 if constexpr (enableSolvent || enablePolymer || enablePolymerMolarWeight || enableBioeffects)
1608 this->readBlackoilExtentionsInitialConditions_(this->model().numGridDof(),
1611 enablePolymerMolarWeight,
1619 if constexpr (!enableSolvent)
1620 throw std::logic_error(
"solvent is disabled and you're trying to add solvent to BC");
1622 rate[Indices::solventSaturationIdx] = bc.rate;
1627 if constexpr (!enablePolymer)
1628 throw std::logic_error(
"polymer is disabled and you're trying to add polymer to BC");
1630 rate[Indices::polymerConcentrationIdx] = bc.rate;
1635 if constexpr (!enableMICP)
1636 throw std::logic_error(
"MICP is disabled and you're trying to add microbes to BC");
1638 rate[Indices::microbialConcentrationIdx] = bc.rate;
1643 if constexpr (!enableMICP)
1644 throw std::logic_error(
"MICP is disabled and you're trying to add oxygen to BC");
1646 rate[Indices::oxygenConcentrationIdx] = bc.rate;
1651 if constexpr (!enableMICP)
1652 throw std::logic_error(
"MICP is disabled and you're trying to add urea to BC");
1654 rate[Indices::ureaConcentrationIdx] = bc.rate;
1656 rate[Indices::ureaConcentrationIdx] *= getPropValue<TypeTag, Properties::BlackOilUreaScalingFactor>();
1661 OPM_TIMEBLOCK(updateExplicitQuantities);
1662 const bool invalidateFromMaxWaterSat = this->updateMaxWaterSaturation_();
1663 const bool invalidateFromMinPressure = this->updateMinPressure_();
1666 const bool invalidateFromHyst = this->updateHysteresis_();
1667 const bool invalidateFromMaxOilSat = this->updateMaxOilSaturation_();
1670 const bool invalidateDRDT = !first_step_after_restart && this->updateCompositionChangeLimits_();
1673 const bool invalidateIntensiveQuantities
1674 = invalidateFromMaxWaterSat || invalidateFromMinPressure || invalidateFromHyst || invalidateFromMaxOilSat || invalidateDRDT;
1675 if (invalidateIntensiveQuantities) {
1676 OPM_TIMEBLOCK(beginTimeStepInvalidateIntensiveQuantities);
1677 this->model().invalidateAndUpdateIntensiveQuantities(0);
1680 this->updateRockCompTransMultVal_();
1685 if (
const auto nph = FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)
1686 + FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)
1687 + FluidSystem::phaseIsActive(FluidSystem::waterPhaseIdx);
1696 const auto numSamplePoints =
static_cast<std::size_t
>
1697 (Parameters::Get<Parameters::NumSatfuncConsistencySamplePoints>());
1699 auto sfuncConsistencyChecks =
1701 numSamplePoints, this->simulator().vanguard().eclState(),
1702 [&cmap = this->simulator().vanguard().cartesianIndexMapper()](
const int elemIdx)
1703 {
return cmap.cartesianIndex(elemIdx); }
1706 const auto ioRank = 0;
1707 const auto isIoRank = this->simulator().vanguard()
1708 .grid().comm().rank() == ioRank;
1714 .
run(this->simulator().vanguard().grid().levelGridView(0),
1715 [&vg = this->simulator().vanguard(),
1716 &emap = this->simulator().model().elementMapper()]
1718 {
return vg.gridIdxToEquilGridIdx(emap.index(elem)); });
1720 using ViolationLevel =
typename Satfunc::PhaseChecks::
1721 SatfuncConsistencyCheckManager<Scalar>::ViolationLevel;
1723 auto reportFailures = [&sfuncConsistencyChecks]
1724 (
const ViolationLevel level)
1726 sfuncConsistencyChecks.reportFailures
1727 (level, [](std::string_view record)
1728 { OpmLog::info(std::string { record }); });
1731 if (sfuncConsistencyChecks.anyFailedStandardChecks()) {
1733 OpmLog::warning(
"Saturation Function "
1734 "End-point Consistency Problems");
1736 reportFailures(ViolationLevel::Standard);
1740 if (sfuncConsistencyChecks.anyFailedCriticalChecks()) {
1742 OpmLog::error(
"Saturation Function "
1743 "End-point Consistency Failures");
1745 reportFailures(ViolationLevel::Critical);
1765 const Scalar smallSaturationTolerance_ = 1.e-6;
1767 bool enableDamarisOutput_ = false ;
1768 std::unique_ptr<DamarisWriterType> damarisWriter_;
1789 bool episodeWillBeOver()
const override
1791 const auto currTime = this->simulator().time()
1792 + this->simulator().timeStepSize();
1794 const auto nextReportStep =
1795 this->simulator().vanguard().schedule()
1796 .seconds(this->simulator().episodeIndex() + 1);
1798 const auto isSubStep = (nextReportStep - currTime)
1799 > (2 * std::numeric_limits<float>::epsilon()) * nextReportStep;
Classes required for dynamic convective mixing.
Contains classes extending the black-oil model. \detail This file holds dummy definitions,...
Class handling Action support in simulator.
Definition: ActionHandler.hpp:52
Provides the auxiliary methods required for consideration of the diffusion equation.
Provides the auxiliary methods required for consideration of the dispersion equation.
Hybrid Newton solver extension for the black-oil model.
Definition: HybridNewton.hpp:60
void tryApplyHybridNewton()
Attempt to apply the Hybrid Newton correction at the current timestep.
Definition: HybridNewton.hpp:101
Collects necessary output values and pass it to opm-common's ECL output.
Definition: EclWriter.hpp:119
static void registerParameters()
Definition: EclWriter.hpp:144
Computes the initial condition based on the EQUIL keyword from ECL.
Definition: EquilInitializer.hpp:59
const ScalarFluidState & initialFluidState(unsigned elemIdx) const
Return the initial thermodynamic state which should be used as the initial condition.
Definition: EquilInitializer.hpp:202
BlackOilFluidState< Scalar, FluidSystem, energyModuleType !=EnergyModules::NoTemperature, energyModuleType==EnergyModules::FullyImplicitThermal, enableDissolution, enableVapwat, enableBrine, enableSaltPrecipitation, enableDisgasInWater, enableSolvent, Indices::numPhases > ScalarFluidState
Definition: EquilInitializer.hpp:102
PolymerSolutionContainer< Scalar > polymer_
Definition: FlowGenericProblem.hpp:353
Scalar initialTimeStepSize_
Definition: FlowGenericProblem.hpp:365
bool enableDriftCompensation_
Definition: FlowGenericProblem.hpp:371
bool enableDriftCompensationTemp_
Definition: FlowGenericProblem.hpp:372
bool enableTuning_
Definition: FlowGenericProblem.hpp:364
void readRockParameters_(const std::vector< Scalar > &cellCenterDepths, std::function< std::array< int, 3 >(const unsigned)> ijkIndex)
Definition: FlowGenericProblem_impl.hpp:137
std::vector< Scalar > maxOilSaturation_
Definition: FlowGenericProblem.hpp:354
Scalar maxTimeStepAfterWellEvent_
Definition: FlowGenericProblem.hpp:366
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
Definition: FlowProblemBlackoil.hpp:87
HybridNewton hybridNewton_
Definition: FlowProblemBlackoil.hpp:1776
void updateExplicitQuantities_(int episodeIdx, int timeStepSize, const bool first_step_after_restart) override
Definition: FlowProblemBlackoil.hpp:1210
bool updateMaxPolymerAdsorption_(unsigned compressedDofIdx, const IntensiveQuantities &iq)
Definition: FlowProblemBlackoil.hpp:1230
void handlePolymerBC(const BCProp::BCFace &bc, RateVector &rate) const override
Definition: FlowProblemBlackoil.hpp:1625
void writeOutput(const bool verbose) override
Write the requested quantities of the current solution into the output files.
Definition: FlowProblemBlackoil.hpp:600
void readInitialCondition_() override
Definition: FlowProblemBlackoil.hpp:1603
void handleOxygBC(const BCProp::BCFace &bc, RateVector &rate) const override
Definition: FlowProblemBlackoil.hpp:1641
void readEquilInitialCondition_() override
Definition: FlowProblemBlackoil.hpp:1339
void handleSolventBC(const BCProp::BCFace &bc, RateVector &rate) const override
Definition: FlowProblemBlackoil.hpp:1617
Scalar maxGasDissolutionFactor(unsigned timeIdx, unsigned globalDofIdx) const
Returns the maximum value of the gas dissolution factor at the current time for a given degree of fre...
Definition: FlowProblemBlackoil.hpp:926
const std::vector< InitialFluidState > & initialFluidStates() const
Definition: FlowProblemBlackoil.hpp:790
void processRestartSaturations_(InitialFluidState &elemFluidState, Scalar &solventSaturation)
Definition: FlowProblemBlackoil.hpp:1569
std::vector< InitialFluidState > & initialFluidStates()
Definition: FlowProblemBlackoil.hpp:787
FlowProblemBlackoil(Simulator &simulator)
Definition: FlowProblemBlackoil.hpp:189
bool enableEclOutput_
Definition: FlowProblemBlackoil.hpp:1762
Scalar drsdtcon(unsigned elemIdx, int episodeIdx) const
Definition: FlowProblemBlackoil.hpp:1021
void endStepApplyAction()
Definition: FlowProblemBlackoil.hpp:521
bool drsdtconIsActive(unsigned elemIdx, int episodeIdx) const
Definition: FlowProblemBlackoil.hpp:1027
Scalar maxOilVaporizationFactor(unsigned timeIdx, unsigned globalDofIdx) const
Returns the maximum value of the oil vaporization factor at the current time for a given degree of fr...
Definition: FlowProblemBlackoil.hpp:937
std::vector< InitialFluidState > initialFluidStates_
Definition: FlowProblemBlackoil.hpp:1760
void endTimeStep() override
Called by the simulator after each time integration.
Definition: FlowProblemBlackoil.hpp:515
void updateMaxPolymerAdsorption_()
Definition: FlowProblemBlackoil.hpp:1220
const InitialFluidState & initialFluidState(unsigned globalDofIdx) const
Definition: FlowProblemBlackoil.hpp:784
void endEpisode() override
Called by the simulator after the end of an episode.
Definition: FlowProblemBlackoil.hpp:568
void setSubStepReport(const SimulatorReportSingle &report)
Definition: FlowProblemBlackoil.hpp:796
void initial(PrimaryVariables &values, const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Evaluate the initial value for a control volume.
Definition: FlowProblemBlackoil.hpp:977
void finishInit()
Called by the Opm::Simulator in order to initialize the problem.
Definition: FlowProblemBlackoil.hpp:324
void handleMicrBC(const BCProp::BCFace &bc, RateVector &rate) const override
Definition: FlowProblemBlackoil.hpp:1633
const FlowThresholdPressure< TypeTag > & thresholdPressure() const
Definition: FlowProblemBlackoil.hpp:1190
void finalizeOutput()
Definition: FlowProblemBlackoil.hpp:623
void boundary(BoundaryRateVector &values, const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Evaluate the boundary conditions for a boundary segment.
Definition: FlowProblemBlackoil.hpp:1038
InitialFluidState boundaryFluidState(unsigned globalDofIdx, const int directionId) const
Definition: FlowProblemBlackoil.hpp:802
std::unique_ptr< EclWriterType > eclWriter_
Definition: FlowProblemBlackoil.hpp:1763
void initialSolutionApplied() override
Callback used by the model to indicate that the initial solution has been determined for all degrees ...
Definition: FlowProblemBlackoil.hpp:635
const ModuleParams & moduleParams() const
Definition: FlowProblemBlackoil.hpp:1196
void readEclRestartSolution_()
Definition: FlowProblemBlackoil.hpp:1309
FlowThresholdPressure< TypeTag > & thresholdPressure()
Definition: FlowProblemBlackoil.hpp:1193
FlowThresholdPressure< TypeTag > thresholdPressures_
Definition: FlowProblemBlackoil.hpp:1758
void readExplicitInitialCondition_() override
Definition: FlowProblemBlackoil.hpp:1354
void beginEpisode() override
Called by the simulator before an episode begins.
Definition: FlowProblemBlackoil.hpp:282
bool recycleFirstIterationStorage() const
Return if the storage term of the first iteration is identical to the storage term for the solution o...
Definition: FlowProblemBlackoil.hpp:955
LhsEval permFactTransMultiplier(const IntensiveQuantities &intQuants, unsigned elementIdx, Callback &obtain) const
Calculate the transmissibility multiplier due to porosity reduction.
Definition: FlowProblemBlackoil.hpp:764
void serializeOp(Serializer &serializer)
Definition: FlowProblemBlackoil.hpp:1202
MixingRateControls< FluidSystem > mixControls_
Definition: FlowProblemBlackoil.hpp:1770
void writeReports(const SimulatorTimer &timer)
Definition: FlowProblemBlackoil.hpp:588
ModuleParams moduleParams_
Definition: FlowProblemBlackoil.hpp:1774
const EclWriterType & eclWriter() const
Definition: FlowProblemBlackoil.hpp:916
void setSimulationReport(const SimulatorReport &report)
Definition: FlowProblemBlackoil.hpp:799
void addToSourceDense(RateVector &rate, unsigned globalDofIdx, unsigned timeIdx) const override
Definition: FlowProblemBlackoil.hpp:657
void computeAndSetEqWeights_()
Definition: FlowProblemBlackoil.hpp:1242
void beginTimeStep() override
Called by the simulator before each time integration.
Definition: FlowProblemBlackoil.hpp:315
void updateExplicitQuantities_(const bool first_step_after_restart)
Definition: FlowProblemBlackoil.hpp:1659
static void registerParameters()
Registers all available parameters for the problem and the model.
Definition: FlowProblemBlackoil.hpp:175
ActionHandler< Scalar, IndexTraits > actionHandler_
Definition: FlowProblemBlackoil.hpp:1772
void readSolutionFromOutputModule(const int restart_step, bool fip_init)
Read simulator solution state from the outputmodule (used with restart)
Definition: FlowProblemBlackoil.hpp:1079
const EclipseIO & eclIO() const
Definition: FlowProblemBlackoil.hpp:793
Scalar thresholdPressure(unsigned elem1Idx, unsigned elem2Idx) const
Definition: FlowProblemBlackoil.hpp:1187
void handleUreaBC(const BCProp::BCFace &bc, RateVector &rate) const override
Definition: FlowProblemBlackoil.hpp:1649
EclWriterType & eclWriter()
Definition: FlowProblemBlackoil.hpp:919
bool satfuncConsistencyRequirementsMet() const
Definition: FlowProblemBlackoil.hpp:1683
bool updateCompositionChangeLimits_()
Definition: FlowProblemBlackoil.hpp:1276
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
Definition: FlowProblem.hpp:95
static constexpr bool enableFoam
Definition: FlowProblem.hpp:126
virtual void writeOutput(bool verbose)
Write the requested quantities of the current solution into the output files.
Definition: FlowProblem.hpp:518
unsigned pvtRegionIndex(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Returns the index of the relevant region for thermodynmic properties.
Definition: FlowProblem.hpp:901
Scalar porosity(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:701
GetPropType< TypeTag, Properties::Vanguard > Vanguard
Definition: FlowProblem.hpp:108
GetPropType< TypeTag, Properties::Scalar > Scalar
Definition: FlowProblem.hpp:102
GetPropType< TypeTag, Properties::EqVector > EqVector
Definition: FlowProblem.hpp:107
@ waterCompIdx
Definition: FlowProblem.hpp:146
GetPropType< TypeTag, Properties::ElementContext > ElementContext
Definition: FlowProblem.hpp:152
@ gasCompIdx
Definition: FlowProblem.hpp:144
GlobalEqVector drift_
Definition: FlowProblem.hpp:1832
@ enableSaltPrecipitation
Definition: FlowProblem.hpp:135
GetPropType< TypeTag, Properties::RateVector > RateVector
Definition: FlowProblem.hpp:149
Dune::FieldMatrix< Scalar, dimWorld, dimWorld > DimMatrix
Definition: FlowProblem.hpp:166
@ enableMICP
Definition: FlowProblem.hpp:134
int episodeIndex() const
Definition: FlowProblem.hpp:299
GetPropType< TypeTag, Properties::Indices > Indices
Definition: FlowProblem.hpp:109
@ dim
Definition: FlowProblem.hpp:112
GetPropType< TypeTag, Properties::GlobalEqVector > GlobalEqVector
Definition: FlowProblem.hpp:106
GetPropType< TypeTag, Properties::Simulator > Simulator
Definition: FlowProblem.hpp:150
@ dimWorld
Definition: FlowProblem.hpp:113
static constexpr bool enableDiffusion
Definition: FlowProblem.hpp:123
TracerModel tracerModel_
Definition: FlowProblem.hpp:1838
@ numComponents
Definition: FlowProblem.hpp:118
WellModel wellModel_
Definition: FlowProblem.hpp:1834
virtual void beginEpisode()
Called by the simulator before an episode begins.
Definition: FlowProblem.hpp:307
static constexpr bool enablePolymerMolarWeight
Definition: FlowProblem.hpp:128
virtual void beginTimeStep()
Called by the simulator before each time integration.
Definition: FlowProblem.hpp:366
static constexpr bool enableSolvent
Definition: FlowProblem.hpp:129
@ waterPhaseIdx
Definition: FlowProblem.hpp:140
static constexpr bool enablePolymer
Definition: FlowProblem.hpp:127
void readThermalParameters_()
Definition: FlowProblem.hpp:1477
GetPropType< TypeTag, Properties::IntensiveQuantities > IntensiveQuantities
Definition: FlowProblem.hpp:161
@ oilCompIdx
Definition: FlowProblem.hpp:145
@ numPhases
Definition: FlowProblem.hpp:117
TemperatureModel temperatureModel_
Definition: FlowProblem.hpp:1839
static constexpr bool enableExtbo
Definition: FlowProblem.hpp:125
static constexpr bool enableConvectiveMixing
Definition: FlowProblem.hpp:122
GetPropType< TypeTag, Properties::GridView > GridView
Definition: FlowProblem.hpp:103
@ enableThermalFluxBoundaries
Definition: FlowProblem.hpp:136
static void registerParameters()
Registers all available parameters for the problem and the model.
Definition: FlowProblem.hpp:186
void updatePffDofData_()
Definition: FlowProblem.hpp:1625
static constexpr bool enableDispersion
Definition: FlowProblem.hpp:124
@ enableExperiments
Definition: FlowProblem.hpp:133
GetPropType< TypeTag, Properties::PrimaryVariables > PrimaryVariables
Definition: FlowProblem.hpp:148
void readBoundaryConditions_()
Definition: FlowProblem.hpp:1656
Vanguard::TransmissibilityType transmissibilities_
Definition: FlowProblem.hpp:1827
static constexpr EnergyModules energyModuleType
Definition: FlowProblem.hpp:131
GetPropType< TypeTag, Properties::FluidSystem > FluidSystem
Definition: FlowProblem.hpp:105
GetPropType< TypeTag, Properties::MaterialLaw > MaterialLaw
Definition: FlowProblem.hpp:158
@ oilPhaseIdx
Definition: FlowProblem.hpp:139
static constexpr bool enableBioeffects
Definition: FlowProblem.hpp:120
void readMaterialParameters_()
Definition: FlowProblem.hpp:1437
static constexpr bool enableBrine
Definition: FlowProblem.hpp:121
@ gasPhaseIdx
Definition: FlowProblem.hpp:138
@ numEq
Definition: FlowProblem.hpp:116
This class calculates the threshold pressure for grid faces according to the Eclipse Reference Manual...
Definition: FlowThresholdPressure.hpp:59
Class handling mixing rate controls for a FlowProblemBlackoil.
Definition: MixingRateControls.hpp:46
Definition: SatfuncConsistencyCheckManager.hpp:58
SatfuncConsistencyCheckManager & collectFailuresTo(const int root)
Definition: SatfuncConsistencyCheckManager.hpp:99
void run(const GridView &gv, GetCellIndex &&getCellIndex)
Definition: SatfuncConsistencyCheckManager.hpp:128
Definition: SimulatorTimer.hpp:39
VTK output module for the tracer model's parameters.
Definition: VtkTracerModule.hpp:58
static void registerParameters()
Register all run-time parameters for the tracer VTK output module.
Definition: VtkTracerModule.hpp:84
@ NONE
Definition: DeferredLogger.hpp:46
static constexpr int dim
Definition: structuredgridvanguard.hh:68
Definition: blackoilbioeffectsmodules.hh:45
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
Struct holding the parameters for the BlackOilBioeffectsModule class.
Definition: blackoilbioeffectsparams.hpp:42
Struct holding the parameters for the BlackoilBrineModule class.
Definition: blackoilbrineparams.hpp:42
Struct holding the parameters for the BlackoilExtboModule class.
Definition: blackoilextboparams.hpp:47
Struct holding the parameters for the BlackoilFoamModule class.
Definition: blackoilfoamparams.hpp:44
Struct holding the parameters for the BlackOilPolymerModule class.
Definition: blackoilpolymerparams.hpp:43
Struct holding the parameters for the BlackOilSolventModule class.
Definition: blackoilsolventparams.hpp:47
Definition: SimulatorReport.hpp:122
A struct for returning timing data from a simulator to its caller.
Definition: SimulatorReport.hpp:34