30 #ifndef OPM_FLOW_PROBLEM_HPP 31 #define OPM_FLOW_PROBLEM_HPP 33 #include <dune/common/version.hh> 34 #include <dune/common/fvector.hh> 35 #include <dune/common/fmatrix.hh> 37 #include <opm/common/utility/TimeService.hpp> 39 #include <opm/input/eclipse/EclipseState/EclipseState.hpp> 40 #include <opm/input/eclipse/Schedule/Schedule.hpp> 41 #include <opm/input/eclipse/Units/Units.hpp> 43 #include <opm/material/common/ConditionalStorage.hpp> 44 #include <opm/material/common/Valgrind.hpp> 45 #include <opm/material/densead/Evaluation.hpp> 46 #include <opm/material/fluidmatrixinteractions/EclMaterialLawManager.hpp> 47 #include <opm/material/thermal/EclThermalLawManager.hpp> 53 #include <opm/output/eclipse/EclipseIO.hpp> 62 #include <opm/simulators/flow/FlowUtils.hpp> 66 #include <opm/simulators/timestepping/AdaptiveTimeStepping.hpp> 67 #include <opm/simulators/timestepping/SimulatorReport.hpp> 69 #include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp> 70 #include <opm/simulators/utils/ParallelSerialization.hpp> 71 #include <opm/simulators/utils/satfunc/RelpermDiagnostics.hpp> 73 #include <opm/utility/CopyablePtr.hpp> 91 template <
class TypeTag>
94 GetPropType<TypeTag, Properties::FluidSystem>>
112 enum { dim = GridView::dimension };
113 enum { dimWorld = GridView::dimensionworld };
116 enum { numEq = getPropValue<TypeTag, Properties::NumEq>() };
117 enum { numPhases = FluidSystem::numPhases };
118 enum { numComponents = FluidSystem::numComponents };
120 static constexpr
bool enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>();
121 static constexpr
bool enableBrine = getPropValue<TypeTag, Properties::EnableBrine>();
122 static constexpr
bool enableConvectiveMixing = getPropValue<TypeTag, Properties::EnableConvectiveMixing>();
123 static constexpr
bool enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>();
124 static constexpr
bool enableDispersion = getPropValue<TypeTag, Properties::EnableDispersion>();
125 static constexpr
bool enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>();
126 static constexpr
bool enableFoam = getPropValue<TypeTag, Properties::EnableFoam>();
127 static constexpr
bool enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>();
128 static constexpr
bool enablePolymerMolarWeight = getPropValue<TypeTag, Properties::EnablePolymerMW>();
129 static constexpr
bool enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>();
131 static constexpr EnergyModules energyModuleType = getPropValue<TypeTag, Properties::EnergyModuleType>();
132 enum { enableFullyImplicitThermal = getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::FullyImplicitThermal };
133 enum { enableExperiments = getPropValue<TypeTag, Properties::EnableExperiments>() };
134 enum { enableMICP = Indices::enableMICP };
135 enum { enableSaltPrecipitation = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>() };
136 enum { enableThermalFluxBoundaries = getPropValue<TypeTag, Properties::EnableThermalFluxBoundaries>() };
138 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
139 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
140 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
144 enum { gasCompIdx = FluidSystem::gasCompIdx };
145 enum { oilCompIdx = FluidSystem::oilCompIdx };
146 enum { waterCompIdx = FluidSystem::waterCompIdx };
151 using Element =
typename GridView::template Codim<0>::Entity;
155 using MaterialLawParams =
typename EclMaterialLawManager::MaterialLawParams;
156 using SolidEnergyLawParams =
typename EclThermalLawManager::SolidEnergyLawParams;
157 using ThermalConductionLawParams =
typename EclThermalLawManager::ThermalConductionLawParams;
165 using Toolbox = MathToolbox<Evaluation>;
166 using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
170 using DirectionalMobilityPtr = Utility::CopyablePtr<DirectionalMobility<TypeTag>>;
188 ParentType::registerParameters();
190 registerFlowProblemParameters<Scalar>();
203 const std::string&)> addKey,
204 std::set<std::string>& seenParams,
205 std::string& errorMsg,
211 return detail::eclPositionalParameter(addKey,
222 : ParentType(simulator)
223 ,
BaseType(simulator.vanguard().eclState(),
224 simulator.vanguard().schedule(),
225 simulator.vanguard().gridView())
226 , transmissibilities_(simulator.vanguard().eclState(),
227 simulator.vanguard().gridView(),
228 simulator.vanguard().cartesianIndexMapper(),
229 simulator.vanguard().grid(),
230 simulator.vanguard().cellCentroids(),
231 (energyModuleType == EnergyModules::FullyImplicitThermal ||
232 energyModuleType == EnergyModules::SequentialImplicitThermal),
235 , wellModel_(simulator, this->iterationContext())
236 , aquiferModel_(simulator)
237 , pffDofData_(simulator.gridView(), this->elementMapper())
238 , tracerModel_(simulator)
239 , temperatureModel_(simulator)
241 if (! Parameters::Get<Parameters::CheckSatfuncConsistency>()) {
246 relpermDiagnostics.
diagnosis(simulator.vanguard().eclState(),
247 simulator.vanguard().levelCartesianIndexMapper());
250 if (energyModuleType == EnergyModules::SequentialImplicitThermal) {
251 this->enableDriftCompensationTemp_ = Parameters::Get<Parameters::EnableDriftCompensationTemp>();
258 void prefetch(
const Element& elem)
const 259 { this->pffDofData_.prefetch(elem); }
272 template <
class Restarter>
279 wellModel_.deserialize(res);
282 aquiferModel_.deserialize(res);
291 template <
class Restarter>
294 wellModel_.serialize(res);
296 aquiferModel_.serialize(res);
299 int episodeIndex()
const 301 return std::max(this->simulator().episodeIndex(), 0);
311 auto& simulator = this->simulator();
312 int episodeIdx = simulator.episodeIndex();
313 auto& eclState = simulator.vanguard().eclState();
314 const auto& schedule = simulator.vanguard().schedule();
315 const auto& events = schedule[episodeIdx].events();
317 if (episodeIdx >= 0 && events.hasEvent(ScheduleEvents::GEO_MODIFIER)) {
324 const auto& miniDeck = schedule[episodeIdx].geo_keywords();
325 const auto& cc = simulator.vanguard().grid().comm();
326 eclState.apply_schedule_keywords( miniDeck );
327 eclBroadcast(cc, eclState.getTransMult() );
330 std::function<unsigned int(unsigned int)> equilGridToGrid = [&simulator](
unsigned int i) {
331 return simulator.vanguard().gridEquilIdxToGridIdx(i);
335 using TransUpdateQuantities =
typename Vanguard::TransmissibilityType::TransUpdateQuantities;
336 transmissibilities_.update(
true, TransUpdateQuantities::All, equilGridToGrid);
337 this->referencePorosity_[1] = this->referencePorosity_[0];
338 updateReferencePorosity_();
339 this->rockFraction_[1] = this->rockFraction_[0];
340 updateRockFraction_();
342 this->model().linearizer().updateDiscretizationParameters();
345 bool tuningEvent = this->beginEpisode_(enableExperiments, this->episodeIndex());
348 wellModel_.beginEpisode();
351 aquiferModel_.beginEpisode();
354 Scalar dt = limitNextTimeStepSize_(simulator.episodeLength());
356 if ( (episodeIdx == 0 || tuningEvent) && this->initialTimeStepSize_ > 0)
359 dt = std::min(dt, this->initialTimeStepSize_);
360 simulator.setTimeStepSize(dt);
369 const int episodeIdx = this->episodeIndex();
370 const int timeStepSize = this->simulator().timeStepSize();
372 this->beginTimeStep_(enableExperiments,
374 this->simulator().timeStepIndex(),
375 this->simulator().startTime(),
376 this->simulator().time(),
378 this->simulator().endTime());
383 this->updateExplicitQuantities_(episodeIdx, timeStepSize, first_step_ && (episodeIdx > 0));
386 if (nonTrivialBoundaryConditions()) {
387 this->model().linearizer().updateBoundaryConditionData();
390 wellModel_.beginTimeStep();
391 aquiferModel_.beginTimeStep();
392 tracerModel_.beginTimeStep();
393 temperatureModel_.beginTimeStep();
403 this->model().updateFailed();
412 this->model().advanceTimeLevel();
421 wellModel_.beginIteration();
422 aquiferModel_.beginIteration();
431 wellModel_.endIteration();
432 aquiferModel_.endIteration();
443 if constexpr (getPropValue<TypeTag, Properties::EnableDebuggingChecks>()) {
449 const int rank = this->simulator().gridView().comm().rank();
451 std::cout <<
"checking conservativeness of solution\n";
454 this->model().checkConservativeness(-1,
true);
456 std::cout <<
"solution is sufficiently conservative\n";
461 auto& simulator = this->simulator();
462 simulator.setTimeStepIndex(simulator.timeStepIndex()+1);
464 this->wellModel_.endTimeStep();
465 this->aquiferModel_.endTimeStep();
466 this->tracerModel_.endTimeStep();
469 this->model().linearizer().updateFlowsInfo();
471 if (this->enableDriftCompensation_ || this->enableDriftCompensationTemp_) {
472 OPM_TIMEBLOCK(driftCompansation);
474 const auto& residual = this->model().linearizer().residual();
476 for (
unsigned globalDofIdx = 0; globalDofIdx < residual.size(); globalDofIdx ++) {
477 int sfcdofIdx = simulator.vanguard().gridEquilIdxToGridIdx(globalDofIdx);
478 this->drift_[sfcdofIdx] = residual[sfcdofIdx] * simulator.timeStepSize();
480 if constexpr (getPropValue<TypeTag, Properties::UseVolumetricResidual>()) {
481 this->drift_[sfcdofIdx] *= this->model().dofTotalVolume(sfcdofIdx);
487 if constexpr(energyModuleType == EnergyModules::SequentialImplicitThermal) {
488 this->temperatureModel_.endTimeStep(wellModel_.wellState());
497 const int episodeIdx = this->episodeIndex();
499 this->wellModel_.endEpisode();
500 this->aquiferModel_.endEpisode();
502 const auto& schedule = this->simulator().vanguard().schedule();
505 if (episodeIdx + 1 >= static_cast<int>(schedule.size()) - 1) {
506 this->simulator().setFinished(
true);
511 this->simulator().startNextEpisode(schedule.stepLength(episodeIdx + 1));
520 OPM_TIMEBLOCK(problemWriteOutput);
522 if (Parameters::Get<Parameters::EnableWriteAllSolutions>() ||
526 ParentType::writeOutput(verbose);
533 template <
class Context>
536 unsigned timeIdx)
const 538 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
539 return transmissibilities_.permeability(globalSpaceIdx);
549 {
return transmissibilities_.permeability(globalElemIdx); }
554 template <
class Context>
556 [[maybe_unused]]
unsigned fromDofLocalIdx,
557 unsigned toDofLocalIdx)
const 559 assert(fromDofLocalIdx == 0);
568 return transmissibilities_.transmissibility(globalCenterElemIdx, globalElemIdx);
574 template <
class Context>
576 [[maybe_unused]]
unsigned fromDofLocalIdx,
577 unsigned toDofLocalIdx)
const 579 assert(fromDofLocalIdx == 0);
580 return *pffDofData_.get(context.element(), toDofLocalIdx).
diffusivity;
586 Scalar
diffusivity(
const unsigned globalCellIn,
const unsigned globalCellOut)
const{
587 return transmissibilities_.diffusivity(globalCellIn, globalCellOut);
593 Scalar
dispersivity(
const unsigned globalCellIn,
const unsigned globalCellOut)
const{
594 return transmissibilities_.dispersivity(globalCellIn, globalCellOut);
601 const unsigned boundaryFaceIdx)
const 603 return transmissibilities_.thermalTransmissibilityBoundary(globalSpaceIdx, boundaryFaceIdx);
612 template <
class Context>
614 unsigned boundaryFaceIdx)
const 616 unsigned elemIdx = elemCtx.globalSpaceIndex(0, 0);
617 return transmissibilities_.transmissibilityBoundary(elemIdx, boundaryFaceIdx);
624 const unsigned boundaryFaceIdx)
const 626 return transmissibilities_.transmissibilityBoundary(globalSpaceIdx, boundaryFaceIdx);
634 const unsigned globalSpaceIdxOut)
const 636 return transmissibilities_.thermalHalfTrans(globalSpaceIdxIn,globalSpaceIdxOut);
642 template <
class Context>
645 unsigned timeIdx)
const 647 const auto& face = context.stencil(timeIdx).interiorFace(faceIdx);
648 unsigned toDofLocalIdx = face.exteriorIndex();
649 return *pffDofData_.get(context.element(), toDofLocalIdx).thermalHalfTransIn;
655 template <
class Context>
658 unsigned timeIdx)
const 660 const auto& face = context.stencil(timeIdx).interiorFace(faceIdx);
661 unsigned toDofLocalIdx = face.exteriorIndex();
662 return *pffDofData_.get(context.element(), toDofLocalIdx).thermalHalfTransOut;
668 template <
class Context>
670 unsigned boundaryFaceIdx)
const 672 unsigned elemIdx = elemCtx.globalSpaceIndex(0, 0);
673 return transmissibilities_.thermalHalfTransBoundary(elemIdx, boundaryFaceIdx);
680 {
return transmissibilities_; }
684 {
return tracerModel_; }
686 TracerModel& tracerModel()
687 {
return tracerModel_; }
689 TemperatureModel& temperatureModel()
690 {
return temperatureModel_; }
700 template <
class Context>
701 Scalar
porosity(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 703 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
704 return this->
porosity(globalSpaceIdx, timeIdx);
713 template <
class Context>
714 Scalar
dofCenterDepth(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 716 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
728 return this->simulator().vanguard().cellCenterDepth(globalSpaceIdx);
734 template <
class Context>
737 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
744 template <
class Context>
745 Scalar
rockBiotComp(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 747 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
754 template <
class Context>
755 Scalar
lame(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 757 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
758 return this->
lame(globalSpaceIdx);
764 template <
class Context>
765 Scalar
biotCoeff(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 767 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
774 template <
class Context>
777 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
786 const auto& rock_config = this->simulator().vanguard().eclState().getSimulationConfig().rock_config();
787 if (rock_config.store()) {
788 return asImp_().initialFluidState(globalSpaceIdx).pressure(refPressurePhaseIdx_());
791 if (this->rockParams_.empty())
794 unsigned tableIdx = 0;
795 if (!this->rockTableIdx_.empty()) {
796 tableIdx = this->rockTableIdx_[globalSpaceIdx];
798 return this->rockParams_[tableIdx].referencePressure;
805 template <
class Context>
807 unsigned spaceIdx,
unsigned timeIdx)
const 809 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
815 return materialLawManager_->materialLawParams(globalDofIdx);
818 const MaterialLawParams&
materialLawParams(
unsigned globalDofIdx, FaceDir::DirEnum facedir)
const 820 return materialLawManager_->materialLawParams(globalDofIdx, facedir);
826 template <
class Context>
827 const SolidEnergyLawParams&
830 unsigned timeIdx)
const 832 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
833 return thermalLawManager_->solidEnergyLawParams(globalSpaceIdx);
839 template <
class Context>
840 const ThermalConductionLawParams &
843 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
844 return thermalLawManager_->thermalConductionLawParams(globalSpaceIdx);
854 {
return materialLawManager_; }
856 std::shared_ptr<const EclThermalLawManager> thermalLawManager()
const 857 {
return thermalLawManager_; }
859 template <
class FluidState,
class ...Args>
861 std::array<Evaluation,numPhases> &mobility,
862 DirectionalMobilityPtr &dirMob,
863 FluidState &fluidState,
864 unsigned globalSpaceIdx)
const 866 using ContainerT = std::array<Evaluation, numPhases>;
867 OPM_TIMEBLOCK_LOCAL(updateRelperms, Subsystem::SatProps);
872 MaterialLaw::template relativePermeabilities<ContainerT, FluidState, Args...>(mobility, materialParams, fluidState);
873 Valgrind::CheckDefined(mobility);
875 if (materialLawManager_->hasDirectionalRelperms()
876 || materialLawManager_->hasDirectionalImbnum())
878 using Dir = FaceDir::DirEnum;
879 constexpr
int ndim = 3;
880 dirMob = std::make_unique<DirectionalMobility<TypeTag>>();
881 Dir facedirs[ndim] = {Dir::XPlus, Dir::YPlus, Dir::ZPlus};
882 for (
int i = 0; i<ndim; i++) {
884 auto& mob_array = dirMob->getArray(i);
885 MaterialLaw::template relativePermeabilities<ContainerT, FluidState, Args...>(mob_array, materialParams, fluidState);
894 {
return materialLawManager_; }
900 template <
class Context>
901 unsigned pvtRegionIndex(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 902 {
return pvtRegionIndex(context.globalSpaceIndex(spaceIdx, timeIdx)); }
908 template <
class Context>
916 template <
class Context>
924 template <
class Context>
933 template <
class Context>
941 {
return this->simulator().vanguard().caseName(); }
946 template <
class Context>
947 Scalar
temperature(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 951 unsigned globalDofIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
952 if constexpr (energyModuleType == EnergyModules::SequentialImplicitThermal)
953 return temperatureModel_.temperature(globalDofIdx);
955 return asImp_().initialFluidState(globalDofIdx).temperature(0);
959 Scalar
temperature(
unsigned globalDofIdx,
unsigned )
const 963 if constexpr (energyModuleType == EnergyModules::SequentialImplicitThermal)
964 return temperatureModel_.temperature(globalDofIdx);
966 return asImp_().initialFluidState(globalDofIdx).temperature(0);
969 const SolidEnergyLawParams&
973 return this->thermalLawManager_->solidEnergyLawParams(globalSpaceIdx);
975 const ThermalConductionLawParams &
979 return this->thermalLawManager_->thermalConductionLawParams(globalSpaceIdx);
993 if (!this->vapparsActive(this->episodeIndex()))
996 return this->maxOilSaturation_[globalDofIdx];
1010 if (!this->vapparsActive(this->episodeIndex()))
1013 this->maxOilSaturation_[globalDofIdx] = value;
1022 this->model().invalidateAndUpdateIntensiveQuantities(0);
1028 if (!this->model().enableStorageCache() || !this->recycleFirstIterationStorage()) {
1029 this->model().invalidateAndUpdateIntensiveQuantities(1);
1037 aquiferModel_.initialSolutionApplied();
1039 const bool invalidateFromHyst = updateHysteresis_();
1040 if (invalidateFromHyst) {
1041 OPM_TIMEBLOCK(beginTimeStepInvalidateIntensiveQuantities);
1042 this->model().invalidateAndUpdateIntensiveQuantities(0);
1051 template <
class Context>
1053 const Context& context,
1055 unsigned timeIdx)
const 1057 const unsigned globalDofIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
1058 source(rate, globalDofIdx, timeIdx);
1061 void source(RateVector& rate,
1062 unsigned globalDofIdx,
1063 unsigned timeIdx)
const 1065 OPM_TIMEBLOCK_LOCAL(eclProblemSource, Subsystem::Assembly);
1069 wellModel_.computeTotalRatesForDof(rate, globalDofIdx);
1073 for (
unsigned eqIdx = 0; eqIdx < numEq; ++ eqIdx) {
1074 rate[eqIdx] /= this->model().dofTotalVolume(globalDofIdx);
1076 Valgrind::CheckDefined(rate[eqIdx]);
1077 assert(isfinite(rate[eqIdx]));
1081 addToSourceDense(rate, globalDofIdx, timeIdx);
1084 virtual void addToSourceDense(RateVector& rate,
1085 unsigned globalDofIdx,
1086 unsigned timeIdx)
const = 0;
1094 {
return wellModel_; }
1097 {
return wellModel_; }
1099 const AquiferModel& aquiferModel()
const 1100 {
return aquiferModel_; }
1102 AquiferModel& mutableAquiferModel()
1103 {
return aquiferModel_; }
1105 bool nonTrivialBoundaryConditions()
const 1106 {
return nonTrivialBoundaryConditions_; }
1116 OPM_TIMEBLOCK(nexTimeStepSize);
1118 if (this->nextTimeStepSize_ > 0.0)
1119 return this->nextTimeStepSize_;
1121 const auto& simulator = this->simulator();
1122 int episodeIdx = simulator.episodeIndex();
1126 return this->initialTimeStepSize_;
1131 const auto& newtonMethod = this->model().newtonMethod();
1132 return limitNextTimeStepSize_(newtonMethod.suggestTimeStepSize(simulator.timeStepSize()));
1140 template <
class LhsEval>
1144 if (this->rockCompPoroMult_.empty() && this->rockCompPoroMultWc_.empty())
1147 unsigned tableIdx = 0;
1148 if (!this->rockTableIdx_.empty())
1149 tableIdx = this->rockTableIdx_[elementIdx];
1151 const auto& fs = intQuants.fluidState();
1152 LhsEval effectivePressure = decay<LhsEval>(fs.pressure(refPressurePhaseIdx_()));
1153 const auto& rock_config = this->simulator().vanguard().eclState().getSimulationConfig().rock_config();
1154 if (!this->minRefPressure_.empty())
1157 min(decay<LhsEval>(fs.pressure(refPressurePhaseIdx_())),
1158 this->minRefPressure_[elementIdx]);
1160 if (!this->overburdenPressure_.empty())
1161 effectivePressure -= this->overburdenPressure_[elementIdx];
1163 if (rock_config.store()) {
1164 effectivePressure -= asImp_().initialFluidState(elementIdx).pressure(refPressurePhaseIdx_());
1167 if (!this->rockCompPoroMult_.empty()) {
1168 return this->rockCompPoroMult_[tableIdx].eval(effectivePressure,
true);
1172 assert(!this->rockCompPoroMultWc_.empty());
1173 LhsEval SwMax = max(decay<LhsEval>(fs.saturation(waterPhaseIdx)), this->maxWaterSaturation_[elementIdx]);
1174 LhsEval SwDeltaMax = SwMax - asImp_().initialFluidStates()[elementIdx].saturation(waterPhaseIdx);
1176 return this->rockCompPoroMultWc_[tableIdx].eval(effectivePressure, SwDeltaMax,
true);
1184 template <
class LhsEval>
1187 auto obtain = [](
const auto& value)
1189 if constexpr (std::is_same_v<LhsEval, Scalar>) {
1190 return getValue(value);
1195 return rockCompTransMultiplier<LhsEval>(intQuants, elementIdx, obtain);
1198 template <
class LhsEval,
class Callback>
1199 LhsEval
rockCompTransMultiplier(
const IntensiveQuantities& intQuants,
unsigned elementIdx, Callback& obtain)
const 1201 const bool implicit = !this->explicitRockCompaction_;
1202 return implicit ? this->simulator().problem().template computeRockCompTransMultiplier_<LhsEval>(intQuants, elementIdx, obtain)
1203 : this->simulator().problem().getRockCompTransMultVal(elementIdx);
1206 template <
class LhsEval,
class Callback>
1207 LhsEval wellTransMultiplier(
const IntensiveQuantities& intQuants,
unsigned elementIdx, Callback& obtain)
const 1209 OPM_TIMEBLOCK_LOCAL(wellTransMultiplier, Subsystem::Wells);
1211 const bool implicit = !this->explicitRockCompaction_;
1212 LhsEval trans_mult = implicit ? this->simulator().problem().template computeRockCompTransMultiplier_<LhsEval>(intQuants, elementIdx, obtain)
1213 : this->simulator().problem().getRockCompTransMultVal(elementIdx);
1214 trans_mult *= this->simulator().problem().template permFactTransMultiplier<LhsEval>(intQuants, elementIdx, obtain);
1219 std::pair<BCType, RateVector> boundaryCondition(
const unsigned int globalSpaceIdx,
const int directionId)
const 1221 OPM_TIMEBLOCK_LOCAL(boundaryCondition, Subsystem::Assembly);
1222 if (!nonTrivialBoundaryConditions_) {
1223 return { BCType::NONE, RateVector(0.0) };
1225 FaceDir::DirEnum dir = FaceDir::FromIntersectionIndex(directionId);
1226 const auto& schedule = this->simulator().vanguard().schedule();
1227 if (bcindex_(dir)[globalSpaceIdx] == 0) {
1228 return { BCType::NONE, RateVector(0.0) };
1230 if (schedule[this->episodeIndex()].bcprop.size() == 0) {
1231 return { BCType::NONE, RateVector(0.0) };
1233 const auto& bc = schedule[this->episodeIndex()].bcprop[bcindex_(dir)[globalSpaceIdx]];
1234 if (bc.bctype!=BCType::RATE) {
1235 return { bc.bctype, RateVector(0.0) };
1238 RateVector rate = 0.0;
1239 switch (bc.component) {
1240 case BCComponent::OIL:
1241 rate[FluidSystem::canonicalToActiveCompIdx(oilCompIdx)] = bc.rate;
1243 case BCComponent::GAS:
1244 rate[FluidSystem::canonicalToActiveCompIdx(gasCompIdx)] = bc.rate;
1246 case BCComponent::WATER:
1247 rate[FluidSystem::canonicalToActiveCompIdx(waterCompIdx)] = bc.rate;
1249 case BCComponent::SOLVENT:
1250 this->handleSolventBC(bc, rate);
1252 case BCComponent::POLYMER:
1253 this->handlePolymerBC(bc, rate);
1255 case BCComponent::MICR:
1256 this->handleMicrBC(bc, rate);
1258 case BCComponent::OXYG:
1259 this->handleOxygBC(bc, rate);
1261 case BCComponent::UREA:
1262 this->handleUreaBC(bc, rate);
1264 case BCComponent::NONE:
1265 throw std::logic_error(
"you need to specify the component when RATE type is set in BC");
1269 return {bc.bctype, rate};
1273 template<
class Serializer>
1274 void serializeOp(Serializer& serializer)
1276 serializer(static_cast<BaseType&>(*
this));
1278 serializer(wellModel_);
1279 serializer(aquiferModel_);
1280 serializer(tracerModel_);
1281 serializer(*materialLawManager_);
1284 const GlobalEqVector& drift()
const 1290 Implementation& asImp_()
1291 {
return *
static_cast<Implementation *
>(
this); }
1293 const Implementation& asImp_()
const 1294 {
return *
static_cast<const Implementation *
>(
this); }
1297 template<
class UpdateFunc>
1298 void updateProperty_(
const std::string& failureMsg,
1301 OPM_TIMEBLOCK(updateProperty);
1302 const auto& model = this->simulator().model();
1303 const auto& primaryVars = model.solution(0);
1304 const auto& vanguard = this->simulator().vanguard();
1305 std::size_t numGridDof = primaryVars.size();
1306 OPM_BEGIN_PARALLEL_TRY_CATCH();
1308 #pragma omp parallel for 1310 for (
unsigned dofIdx = 0; dofIdx < numGridDof; ++dofIdx) {
1311 const auto& iq = *model.cachedIntensiveQuantities(dofIdx, 0);
1314 OPM_END_PARALLEL_TRY_CATCH(failureMsg, vanguard.grid().comm());
1317 bool updateMaxOilSaturation_()
1319 OPM_TIMEBLOCK(updateMaxOilSaturation);
1320 int episodeIdx = this->episodeIndex();
1323 if (this->vapparsActive(episodeIdx)) {
1324 this->updateProperty_(
"FlowProblem::updateMaxOilSaturation_() failed:",
1325 [
this](
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1327 this->updateMaxOilSaturation_(compressedDofIdx,iq);
1335 bool updateMaxOilSaturation_(
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1337 OPM_TIMEBLOCK_LOCAL(updateMaxOilSaturation, Subsystem::SatProps);
1338 const auto& fs = iq.fluidState();
1339 const Scalar So = decay<Scalar>(fs.saturation(refPressurePhaseIdx_()));
1340 auto& mos = this->maxOilSaturation_;
1341 if(mos[compressedDofIdx] < So){
1342 mos[compressedDofIdx] = So;
1349 bool updateMaxWaterSaturation_()
1351 OPM_TIMEBLOCK(updateMaxWaterSaturation);
1353 if (this->maxWaterSaturation_.empty())
1356 this->maxWaterSaturation_[1] = this->maxWaterSaturation_[0];
1357 this->updateProperty_(
"FlowProblem::updateMaxWaterSaturation_() failed:",
1358 [
this](
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1360 this->updateMaxWaterSaturation_(compressedDofIdx,iq);
1366 bool updateMaxWaterSaturation_(
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1368 OPM_TIMEBLOCK_LOCAL(updateMaxWaterSaturation, Subsystem::SatProps);
1369 const auto& fs = iq.fluidState();
1370 const Scalar Sw = decay<Scalar>(fs.saturation(waterPhaseIdx));
1371 auto& mow = this->maxWaterSaturation_;
1372 if(mow[compressedDofIdx]< Sw){
1373 mow[compressedDofIdx] = Sw;
1380 bool updateMinPressure_()
1382 OPM_TIMEBLOCK(updateMinPressure);
1384 if (this->minRefPressure_.empty())
1387 this->updateProperty_(
"FlowProblem::updateMinPressure_() failed:",
1388 [
this](
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1390 this->updateMinPressure_(compressedDofIdx,iq);
1395 bool updateMinPressure_(
unsigned compressedDofIdx,
const IntensiveQuantities& iq){
1396 OPM_TIMEBLOCK_LOCAL(updateMinPressure, Subsystem::PvtProps);
1397 const auto& fs = iq.fluidState();
1398 const Scalar min_pressure = getValue(fs.pressure(refPressurePhaseIdx_()));
1399 auto& min_pressures = this->minRefPressure_;
1400 if(min_pressures[compressedDofIdx]> min_pressure){
1401 min_pressures[compressedDofIdx] = min_pressure;
1412 std::function<std::vector<double>(
const FieldPropsManager&,
const std::string&)>
1413 fieldPropDoubleOnLeafAssigner_()
1415 const auto& lookup = this->lookUpData_;
1416 return [&lookup](
const FieldPropsManager& fieldPropManager,
const std::string& propString)
1418 return lookup.assignFieldPropsDoubleOnLeaf(fieldPropManager, propString);
1426 template<
typename IntType>
1427 std::function<std::vector<IntType>(
const FieldPropsManager&,
const std::string&, bool)>
1428 fieldPropIntTypeOnLeafAssigner_()
1430 const auto& lookup = this->lookUpData_;
1431 return [&lookup](
const FieldPropsManager& fieldPropManager,
const std::string& propString,
bool needsTranslation)
1433 return lookup.template assignFieldPropsIntOnLeaf<IntType>(fieldPropManager, propString, needsTranslation);
1437 void readMaterialParameters_()
1439 OPM_TIMEBLOCK(readMaterialParameters);
1440 const auto& simulator = this->simulator();
1441 const auto& vanguard = simulator.vanguard();
1442 const auto& eclState = vanguard.eclState();
1445 OPM_BEGIN_PARALLEL_TRY_CATCH();
1446 this->updatePvtnum_();
1447 this->updateSatnum_();
1450 this->updateMiscnum_();
1452 this->updatePlmixnum_();
1454 OPM_END_PARALLEL_TRY_CATCH(
"Invalid region numbers: ", vanguard.gridView().comm());
1457 updateReferencePorosity_();
1458 this->referencePorosity_[1] = this->referencePorosity_[0];
1463 updateRockFraction_();
1464 this->rockFraction_[1] = this->rockFraction_[0];
1469 materialLawManager_ = std::make_shared<EclMaterialLawManager>();
1470 materialLawManager_->initFromState(eclState);
1471 materialLawManager_->initParamsForElements(eclState, this->model().numGridDof(),
1472 this->
template fieldPropIntTypeOnLeafAssigner_<int>(),
1473 this-> lookupIdxOnLevelZeroAssigner_());
1477 void readThermalParameters_()
1479 if constexpr (energyModuleType == EnergyModules::FullyImplicitThermal ||
1480 energyModuleType == EnergyModules::SequentialImplicitThermal )
1482 const auto& simulator = this->simulator();
1483 const auto& vanguard = simulator.vanguard();
1484 const auto& eclState = vanguard.eclState();
1487 thermalLawManager_ = std::make_shared<EclThermalLawManager>();
1488 thermalLawManager_->initParamsForElements(eclState, this->model().numGridDof(),
1489 this-> fieldPropDoubleOnLeafAssigner_(),
1490 this->
template fieldPropIntTypeOnLeafAssigner_<unsigned int>());
1494 void updateReferencePorosity_()
1496 const auto& simulator = this->simulator();
1497 const auto& vanguard = simulator.vanguard();
1498 const auto& eclState = vanguard.eclState();
1500 std::size_t numDof = this->model().numGridDof();
1502 this->referencePorosity_[0].resize(numDof);
1504 const auto& fp = eclState.fieldProps();
1505 const std::vector<double> porvData =
this -> fieldPropDoubleOnLeafAssigner_()(fp,
"PORV");
1506 for (std::size_t dofIdx = 0; dofIdx < numDof; ++dofIdx) {
1507 int sfcdofIdx = simulator.vanguard().gridEquilIdxToGridIdx(dofIdx);
1508 Scalar poreVolume = porvData[dofIdx];
1513 Scalar dofVolume = simulator.model().dofTotalVolume(sfcdofIdx);
1514 assert(dofVolume > 0.0);
1515 this->referencePorosity_[0][sfcdofIdx] = poreVolume/dofVolume;
1519 void updateRockFraction_() {
1521 const bool solveEnergyEquation = (energyModuleType == EnergyModules::FullyImplicitThermal ||
1522 energyModuleType == EnergyModules::SequentialImplicitThermal);
1523 if (!solveEnergyEquation)
1526 const auto& simulator = this->simulator();
1527 const auto& vanguard = simulator.vanguard();
1528 const auto& eclState = vanguard.eclState();
1530 std::size_t numDof = this->model().numGridDof();
1531 this->rockFraction_[0].resize(numDof);
1540 const auto& fp = eclState.fieldProps();
1541 const std::vector<double> poroData = this->fieldPropDoubleOnLeafAssigner_()(fp,
"PORO");
1542 const std::vector<double> ntgData = this->fieldPropDoubleOnLeafAssigner_()(fp,
"NTG");
1544 for (std::size_t dofIdx = 0; dofIdx < numDof; ++dofIdx) {
1545 const auto ntg = ntgData[dofIdx];
1546 const auto poro_eff = ntg * poroData[dofIdx];
1547 const int sfcdofIdx = simulator.vanguard().gridEquilIdxToGridIdx(dofIdx);
1548 const auto rock_fraction = (1 - poro_eff) * this->referencePorosity_[0][sfcdofIdx] / poro_eff;
1549 this->rockFraction_[0][sfcdofIdx] = rock_fraction;
1553 virtual void readInitialCondition_()
1556 const auto& simulator = this->simulator();
1557 const auto& vanguard = simulator.vanguard();
1558 const auto& eclState = vanguard.eclState();
1560 if (eclState.getInitConfig().hasEquil())
1561 readEquilInitialCondition_();
1563 readExplicitInitialCondition_();
1566 std::size_t numElems = this->model().numGridDof();
1567 for (std::size_t elemIdx = 0; elemIdx < numElems; ++elemIdx) {
1568 const auto& fs = asImp_().initialFluidStates()[elemIdx];
1569 if (!this->maxWaterSaturation_.empty() && waterPhaseIdx > -1)
1570 this->maxWaterSaturation_[elemIdx] = std::max(this->maxWaterSaturation_[elemIdx], fs.saturation(waterPhaseIdx));
1571 if (!this->maxOilSaturation_.empty() && oilPhaseIdx > -1)
1572 this->maxOilSaturation_[elemIdx] = std::max(this->maxOilSaturation_[elemIdx], fs.saturation(oilPhaseIdx));
1573 if (!this->minRefPressure_.empty() && refPressurePhaseIdx_() > -1)
1574 this->minRefPressure_[elemIdx] = std::min(this->minRefPressure_[elemIdx], fs.pressure(refPressurePhaseIdx_()));
1578 virtual void readEquilInitialCondition_() = 0;
1579 virtual void readExplicitInitialCondition_() = 0;
1582 bool updateHysteresis_()
1584 if (!materialLawManager_->enableHysteresis())
1589 this->updateProperty_(
"FlowProblem::updateHysteresis_() failed:",
1590 [
this](
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1592 materialLawManager_->updateHysteresis(iq.fluidState(), compressedDofIdx);
1598 bool updateHysteresis_(
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1600 OPM_TIMEBLOCK_LOCAL(updateHysteresis_, Subsystem::SatProps);
1601 materialLawManager_->updateHysteresis(iq.fluidState(), compressedDofIdx);
1606 Scalar getRockCompTransMultVal(std::size_t dofIdx)
const 1608 if (this->rockCompTransMultVal_.empty())
1611 return this->rockCompTransMultVal_[dofIdx];
1617 ConditionalStorage<enableFullyImplicitThermal, Scalar> thermalHalfTransIn;
1618 ConditionalStorage<enableFullyImplicitThermal, Scalar> thermalHalfTransOut;
1619 ConditionalStorage<enableDiffusion, Scalar> diffusivity;
1620 ConditionalStorage<enableDispersion, Scalar> dispersivity;
1621 Scalar transmissibility;
1625 void updatePffDofData_()
1627 const auto& distFn =
1629 const Stencil& stencil,
1630 unsigned localDofIdx)
1633 const auto& elementMapper = this->model().elementMapper();
1635 unsigned globalElemIdx = elementMapper.index(stencil.entity(localDofIdx));
1636 if (localDofIdx != 0) {
1637 unsigned globalCenterElemIdx = elementMapper.index(stencil.entity(0));
1638 dofData.transmissibility = transmissibilities_.transmissibility(globalCenterElemIdx, globalElemIdx);
1640 if constexpr (enableFullyImplicitThermal) {
1641 *dofData.thermalHalfTransIn = transmissibilities_.thermalHalfTrans(globalCenterElemIdx, globalElemIdx);
1642 *dofData.thermalHalfTransOut = transmissibilities_.thermalHalfTrans(globalElemIdx, globalCenterElemIdx);
1644 if constexpr (enableDiffusion)
1645 *dofData.diffusivity = transmissibilities_.diffusivity(globalCenterElemIdx, globalElemIdx);
1646 if (enableDispersion)
1647 dofData.dispersivity = transmissibilities_.dispersivity(globalCenterElemIdx, globalElemIdx);
1651 pffDofData_.update(distFn);
1654 virtual void updateExplicitQuantities_(
int episodeIdx,
int timeStepSize,
bool first_step_after_restart) = 0;
1656 void readBoundaryConditions_()
1658 const auto& simulator = this->simulator();
1659 const auto& vanguard = simulator.vanguard();
1660 const auto& bcconfig = vanguard.eclState().getSimulationConfig().bcconfig();
1661 if (bcconfig.size() > 0) {
1662 nonTrivialBoundaryConditions_ =
true;
1664 std::size_t numCartDof = vanguard.cartesianSize();
1665 unsigned numElems = vanguard.gridView().size(0);
1666 std::vector<int> cartesianToCompressedElemIdx(numCartDof, -1);
1668 for (
unsigned elemIdx = 0; elemIdx < numElems; ++elemIdx)
1669 cartesianToCompressedElemIdx[vanguard.cartesianIndex(elemIdx)] = elemIdx;
1671 bcindex_.resize(numElems, 0);
1672 auto loopAndApply = [&cartesianToCompressedElemIdx,
1673 &vanguard](
const auto& bcface,
1676 for (
int i = bcface.i1; i <= bcface.i2; ++i) {
1677 for (
int j = bcface.j1; j <= bcface.j2; ++j) {
1678 for (
int k = bcface.k1; k <= bcface.k2; ++k) {
1679 std::array<int, 3> tmp = {i,j,k};
1680 auto elemIdx = cartesianToCompressedElemIdx[vanguard.cartesianIndex(tmp)];
1687 for (
const auto& bcface : bcconfig) {
1688 std::vector<int>& data = bcindex_(bcface.dir);
1689 const int index = bcface.index;
1690 loopAndApply(bcface,
1691 [&data,index](
int elemIdx)
1692 { data[elemIdx] = index; });
1699 Scalar limitNextTimeStepSize_(Scalar dtNext)
const 1701 if constexpr (enableExperiments) {
1702 const auto& simulator = this->simulator();
1703 const auto& schedule = simulator.vanguard().schedule();
1704 int episodeIdx = simulator.episodeIndex();
1707 Scalar maxTimeStepSize = Parameters::Get<Parameters::SolverMaxTimeStepInDays<Scalar>>() * 24 * 60 * 60;
1708 int reportStepIdx = std::max(episodeIdx, 0);
1709 if (this->enableTuning_) {
1710 const auto& tuning = schedule[reportStepIdx].tuning();
1711 maxTimeStepSize = tuning.TSMAXZ;
1714 dtNext = std::min(dtNext, maxTimeStepSize);
1716 Scalar remainingEpisodeTime =
1717 simulator.episodeStartTime() + simulator.episodeLength()
1718 - (simulator.startTime() + simulator.time());
1719 assert(remainingEpisodeTime >= 0.0);
1723 if (remainingEpisodeTime/2.0 < dtNext && dtNext < remainingEpisodeTime*(1.0 - 1e-5))
1726 dtNext = std::min(maxTimeStepSize, remainingEpisodeTime/2.0);
1728 if (simulator.episodeStarts()) {
1731 const auto& events = simulator.vanguard().schedule()[reportStepIdx].events();
1732 bool wellEventOccured =
1733 events.hasEvent(ScheduleEvents::NEW_WELL)
1734 || events.hasEvent(ScheduleEvents::PRODUCTION_UPDATE)
1735 || events.hasEvent(ScheduleEvents::INJECTION_UPDATE)
1736 || events.hasEvent(ScheduleEvents::WELL_STATUS_CHANGE);
1737 if (episodeIdx >= 0 && wellEventOccured && this->maxTimeStepAfterWellEvent_ > 0)
1738 dtNext = std::min(dtNext, this->maxTimeStepAfterWellEvent_);
1745 int refPressurePhaseIdx_()
const {
1746 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1749 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1753 return waterPhaseIdx;
1757 void updateRockCompTransMultVal_()
1759 const auto& model = this->simulator().model();
1760 std::size_t numGridDof = this->model().numGridDof();
1761 this->rockCompTransMultVal_.resize(numGridDof, 1.0);
1762 for (std::size_t elementIdx = 0; elementIdx < numGridDof; ++elementIdx) {
1763 const auto& iq = *model.cachedIntensiveQuantities(elementIdx, 0);
1764 Scalar trans_mult = computeRockCompTransMultiplier_<Scalar>(iq, elementIdx);
1765 this->rockCompTransMultVal_[elementIdx] = trans_mult;
1774 template <
class LhsEval>
1777 auto obtain = [](
const auto& value)
1779 if constexpr (std::is_same_v<LhsEval, Scalar>) {
1780 return getValue(value);
1786 return computeRockCompTransMultiplier_<LhsEval>(intQuants, elementIdx, obtain);
1789 template <
class LhsEval,
class Callback>
1792 OPM_TIMEBLOCK_LOCAL(computeRockCompTransMultiplier, Subsystem::PvtProps);
1793 if (this->rockCompTransMult_.empty() && this->rockCompTransMultWc_.empty())
1796 unsigned tableIdx = 0;
1797 if (!this->rockTableIdx_.empty())
1798 tableIdx = this->rockTableIdx_[elementIdx];
1800 const auto& fs = intQuants.fluidState();
1801 LhsEval effectivePressure = obtain(fs.pressure(refPressurePhaseIdx_()));
1802 const auto& rock_config = this->simulator().vanguard().eclState().getSimulationConfig().rock_config();
1803 if (!this->minRefPressure_.empty())
1806 min(obtain(fs.pressure(refPressurePhaseIdx_())),
1807 this->minRefPressure_[elementIdx]);
1809 if (!this->overburdenPressure_.empty())
1810 effectivePressure -= this->overburdenPressure_[elementIdx];
1812 if (rock_config.store()) {
1813 effectivePressure -= asImp_().initialFluidState(elementIdx).pressure(refPressurePhaseIdx_());
1816 if (!this->rockCompTransMult_.empty())
1817 return this->rockCompTransMult_[tableIdx].eval(effectivePressure,
true);
1820 assert(!this->rockCompTransMultWc_.empty());
1821 LhsEval SwMax = max(obtain(fs.saturation(waterPhaseIdx)), this->maxWaterSaturation_[elementIdx]);
1822 LhsEval SwDeltaMax = SwMax - asImp_().initialFluidStates()[elementIdx].saturation(waterPhaseIdx);
1824 return this->rockCompTransMultWc_[tableIdx].eval(effectivePressure, SwDeltaMax,
true);
1827 typename Vanguard::TransmissibilityType transmissibilities_;
1829 std::shared_ptr<EclMaterialLawManager> materialLawManager_;
1830 std::shared_ptr<EclThermalLawManager> thermalLawManager_;
1832 GlobalEqVector drift_;
1834 WellModel wellModel_;
1835 AquiferModel aquiferModel_;
1837 PffGridVector<GridView, Stencil, PffDofData_, DofMapper> pffDofData_;
1838 TracerModel tracerModel_;
1839 TemperatureModel temperatureModel_;
1844 std::array<std::vector<T>,6> data;
1846 void resize(std::size_t size, T defVal)
1848 for (
auto& d : data)
1849 d.resize(size, defVal);
1852 const std::vector<T>& operator()(FaceDir::DirEnum dir)
const 1854 if (dir == FaceDir::DirEnum::Unknown)
1855 throw std::runtime_error(
"Tried to access BC data for the 'Unknown' direction");
1857 int div =
static_cast<int>(dir);
1858 while ((div /= 2) >= 1)
1860 assert(idx >= 0 && idx <= 5);
1864 std::vector<T>& operator()(FaceDir::DirEnum dir)
1866 return const_cast<std::vector<T>&
>(std::as_const(*
this)(dir));
1870 virtual void handleSolventBC(
const BCProp::BCFace&, RateVector&)
const = 0;
1872 virtual void handlePolymerBC(
const BCProp::BCFace&, RateVector&)
const = 0;
1874 virtual void handleMicrBC(
const BCProp::BCFace&, RateVector&)
const = 0;
1876 virtual void handleOxygBC(
const BCProp::BCFace&, RateVector&)
const = 0;
1878 virtual void handleUreaBC(
const BCProp::BCFace&, RateVector&)
const = 0;
1881 bool nonTrivialBoundaryConditions_ =
false;
1882 bool first_step_ =
true;
1888 return this->simulator().episodeWillBeOver();
1894 #endif // OPM_FLOW_PROBLEM_HPP void deserialize(Restarter &res)
This method restores the complete state of the problem and its sub-objects from disk.
Definition: FlowProblem.hpp:273
Scalar rockCompressibility(unsigned globalSpaceIdx) const
Direct access to rock compressibility.
Definition: FlowGenericProblem_impl.hpp:323
LhsEval rockCompPoroMultiplier(const IntensiveQuantities &intQuants, unsigned elementIdx) const
Calculate the porosity multiplier due to water induced rock compaction.
Definition: FlowProblem.hpp:1141
void diagnosis(const EclipseState &eclState, const LevelCartesianIndexMapper &levelCartesianIndexMapper)
This function is used to diagnosis relperm in eclipse data file.
Definition: RelpermDiagnostics.cpp:907
std::shared_ptr< const EclMaterialLawManager > materialLawManager() const
Returns the ECL material law manager.
Definition: FlowProblem.hpp:853
std::shared_ptr< EclMaterialLawManager > materialLawManager()
Definition: FlowProblem.hpp:893
A class which handles tracers as specified in by ECL.
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
const DimMatrix & intrinsicPermeability(unsigned globalElemIdx) const
This method returns the intrinsic permeability tensor given a global element index.
Definition: FlowProblem.hpp:548
Scalar maxPolymerAdsorption(unsigned elemIdx) const
Returns the max polymer adsorption value.
Definition: FlowGenericProblem_impl.hpp:797
typename Properties::Detail::GetPropImpl< TypeTag, Property >::type GetProp
get the type of a property (equivalent to old macro GET_PROP(...))
Definition: propertysystem.hh:224
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
Definition: FlowProblem.hpp:92
unsigned pvtRegionIndex(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Returns the index of the relevant region for thermodynmic properties.
Definition: FlowProblem.hpp:901
Collects necessary output values and pass it to opm-common's ECL output.
static std::string helpPreamble(int, const char **argv)
Definition: FlowGenericProblem_impl.hpp:115
const MaterialLawParams & materialLawParams(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:806
const SolidEnergyLawParams & solidEnergyLawParams(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Return the parameters for the energy storage law of the rock.
Definition: FlowProblem.hpp:828
virtual void beginTimeStep()
Called by the simulator before each time integration.
Definition: FlowProblem.hpp:366
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
virtual bool episodeWillBeOver() const
Whether or not the current episode will end at the end of the current time step.
Definition: FlowProblem.hpp:1886
unsigned pvtRegionIndex(unsigned elemIdx) const
Returns the index the relevant PVT region given a cell index.
Definition: FlowGenericProblem_impl.hpp:756
Scalar temperature(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:947
unsigned plmixnumRegionIndex(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Returns the index of the relevant region for thermodynmic properties.
Definition: FlowProblem.hpp:925
Scalar lame(unsigned elementIdx) const
Direct access to Lame's second parameter in an element.
Definition: FlowGenericProblem_impl.hpp:357
std::string name() const
The problem name.
Definition: FlowProblem.hpp:940
The base class for the element-centered finite-volume discretization scheme.
unsigned miscnumRegionIndex(unsigned elemIdx) const
Returns the index the relevant MISC region given a cell index.
Definition: FlowGenericProblem_impl.hpp:776
Scalar transmissibilityBoundary(const unsigned globalSpaceIdx, const unsigned boundaryFaceIdx) const
Direct access to a boundary transmissibility.
Definition: FlowProblem.hpp:623
This is a "dummy" gradient calculator which does not do anything.
Scalar nextTimeStepSize() const
Propose the size of the next time step to the simulator.
Definition: FlowProblem.hpp:1114
Scalar thermalHalfTransmissibility(const unsigned globalSpaceIdxIn, const unsigned globalSpaceIdxOut) const
Definition: FlowProblem.hpp:633
Scalar thermalHalfTransmissibilityOut(const Context &context, unsigned faceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:656
Scalar thermalHalfTransmissibilityIn(const Context &context, unsigned faceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:643
A class which handles tracers as specified in by ECL.
Definition: TracerModel.hpp:70
Structs needed for tpfalinearizer and its gpuparams struct extracted to be defined in one place that ...
Definition: blackoilbioeffectsmodules.hh:45
Scalar maxOilSaturation(unsigned globalDofIdx) const
Returns an element's historic maximum oil phase saturation that was observed during the simulation...
Definition: FlowProblem.hpp:991
Scalar porosity(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:701
const WellModel & wellModel() const
Returns a reference to the ECL well manager used by the problem.
Definition: FlowProblem.hpp:1093
Scalar thermalHalfTransmissibilityBoundary(const Context &elemCtx, unsigned boundaryFaceIdx) const
Definition: FlowProblem.hpp:669
Scalar transmissibilityBoundary(const Context &elemCtx, unsigned boundaryFaceIdx) const
Definition: FlowProblem.hpp:613
Scalar thermalTransmissibilityBoundary(const unsigned globalSpaceIdx, const unsigned boundaryFaceIdx) const
Direct access to a boundary transmissibility.
Definition: FlowProblem.hpp:600
LhsEval rockCompTransMultiplier(const IntensiveQuantities &intQuants, unsigned elementIdx) const
Calculate the transmissibility multiplier due to water induced rock compaction.
Definition: FlowProblem.hpp:1185
Scalar dofCenterDepth(unsigned globalSpaceIdx) const
Direct indexed acces to the depth of an degree of freedom [m].
Definition: FlowProblem.hpp:726
Definition: FlowProblem.hpp:1615
const DimMatrix & intrinsicPermeability(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:534
Scalar biotCoeff(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:765
Helper class for grid instantiation of ECL file-format using problems.
Scalar rockBiotComp(unsigned elementIdx) const
Returns the rock compressibility of an element due to poroelasticity.
Definition: FlowGenericProblem_impl.hpp:346
Scalar maxPolymerAdsorption(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Returns the max polymer adsorption value.
Definition: FlowProblem.hpp:934
virtual void beginEpisode()
Called by the simulator before an episode begins.
Definition: FlowProblem.hpp:307
Scalar transmissibility(unsigned globalCenterElemIdx, unsigned globalElemIdx) const
Direct access to the transmissibility between two elements.
Definition: FlowProblem.hpp:566
Scalar biotCoeff(unsigned elementIdx) const
Direct access to Biot coefficient in an element.
Definition: FlowGenericProblem_impl.hpp:388
unsigned satnumRegionIndex(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Returns the index of the relevant region for thermodynmic properties.
Definition: FlowProblem.hpp:909
Scalar rockBiotComp(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:745
virtual void endTimeStep()
Called by the simulator after each time integration.
Definition: FlowProblem.hpp:438
const Vanguard::TransmissibilityType & eclTransmissibilities() const
Return a reference to the object that handles the "raw" transmissibilities.
Definition: FlowProblem.hpp:679
void source(RateVector &rate, const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Evaluate the source term for all phases within a given sub-control-volume.
Definition: FlowProblem.hpp:1052
const ThermalConductionLawParams & thermalConductionLawParams(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:841
void advanceTimeLevel()
Called by the simulator to accept the current state as the new time level after a successful timestep...
Definition: FlowProblem.hpp:410
void beginIteration()
Called by the simulator before each Newton-Raphson iteration.
Definition: FlowProblem.hpp:418
virtual void endEpisode()
Called by the simulator after the end of an episode.
Definition: FlowProblem.hpp:495
unsigned satnumRegionIndex(unsigned elemIdx) const
Returns the index the relevant saturation function region given a cell index.
Definition: FlowGenericProblem_impl.hpp:766
Scalar rockReferencePressure(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:775
void serialize(Restarter &res)
This method writes the complete state of the problem and its subobjects to disk.
Definition: FlowProblem.hpp:292
FlowProblem(Simulator &simulator)
Definition: FlowProblem.hpp:221
Definition: FlowProblem.hpp:1842
static void registerParameters()
Registers all available parameters for the problem and the model.
Definition: FlowProblem.hpp:186
Scalar dofCenterDepth(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Returns the depth of an degree of freedom [m].
Definition: FlowProblem.hpp:714
Scalar porosity(unsigned globalSpaceIdx, unsigned timeIdx) const
Direct indexed access to the porosity.
Definition: FlowGenericProblem_impl.hpp:338
void setMaxOilSaturation(unsigned globalDofIdx, Scalar value)
Sets an element's maximum oil phase saturation observed during the simulation.
Definition: FlowProblem.hpp:1008
Scalar transmissibility(const Context &context, [[maybe_unused]] unsigned fromDofLocalIdx, unsigned toDofLocalIdx) const
Definition: FlowProblem.hpp:555
virtual void initialSolutionApplied()
Callback used by the model to indicate that the initial solution has been determined for all degrees ...
Definition: FlowProblem.hpp:1019
bool shouldWriteOutput() const
Always returns true.
Definition: FlowGenericProblem.hpp:294
Scalar lame(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:755
This file contains definitions related to directional mobilities.
unsigned plmixnumRegionIndex(unsigned elemIdx) const
Returns the index the relevant PLMIXNUM (for polymer module) region given a cell index.
Definition: FlowGenericProblem_impl.hpp:786
virtual void writeOutput(bool verbose)
Write the requested quantities of the current solution into the output files.
Definition: FlowProblem.hpp:518
A class which handles sequential implicit solution of the energy equation as specified in by TEMP...
void updateFailed()
Called by the simulator to restore the state captured at the beginning of the timestep after a failed...
Definition: FlowProblem.hpp:401
LhsEval computeRockCompTransMultiplier_(const IntensiveQuantities &intQuants, unsigned elementIdx) const
Calculate the transmissibility multiplier due to water induced rock compaction.
Definition: FlowProblem.hpp:1775
This class is intend to be a relperm diagnostics, to detect wrong input of relperm table and endpoint...
Definition: RelpermDiagnostics.hpp:50
static std::string briefDescription()
Definition: FlowGenericProblem_impl.hpp:130
Scalar rockCompressibility(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:735
Scalar diffusivity(const unsigned globalCellIn, const unsigned globalCellOut) const
give the transmissibility for a face i.e.
Definition: FlowProblem.hpp:586
unsigned miscnumRegionIndex(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Returns the index of the relevant region for thermodynmic properties.
Definition: FlowProblem.hpp:917
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
Definition: FlowGenericProblem.hpp:60
static int handlePositionalParameter(std::function< void(const std::string &, const std::string &)> addKey, std::set< std::string > &seenParams, std::string &errorMsg, int, const char **argv, int paramIdx, int)
Handles positional command line parameters.
Definition: FlowProblem.hpp:202
void endIteration()
Called by the simulator after each Newton-Raphson iteration.
Definition: FlowProblem.hpp:428
bool shouldWriteRestartFile() const
Returns true if an eWoms restart file should be written to disk.
Definition: FlowGenericProblem.hpp:303
Computes the initial condition based on the EQUIL keyword from ECL.
Scalar rockReferencePressure(unsigned globalSpaceIdx) const
Definition: FlowProblem.hpp:784
Scalar dispersivity(const unsigned globalCellIn, const unsigned globalCellOut) const
give the dispersivity for a face i.e.
Definition: FlowProblem.hpp:593
Scalar diffusivity(const Context &context, [[maybe_unused]] unsigned fromDofLocalIdx, unsigned toDofLocalIdx) const
Definition: FlowProblem.hpp:575