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 enum { enableBioeffects = getPropValue<TypeTag, Properties::EnableBioeffects>() };
121 enum { enableBrine = getPropValue<TypeTag, Properties::EnableBrine>() };
122 enum { enableConvectiveMixing = getPropValue<TypeTag, Properties::EnableConvectiveMixing>() };
123 enum { enableDiffusion = getPropValue<TypeTag, Properties::EnableDiffusion>() };
124 enum { enableDispersion = getPropValue<TypeTag, Properties::EnableDispersion>() };
125 static constexpr EnergyModules energyModuleType = getPropValue<TypeTag, Properties::EnergyModuleType>();
126 enum { enableFullyImplicitThermal = getPropValue<TypeTag, Properties::EnergyModuleType>() == EnergyModules::FullyImplicitThermal };
127 enum { enableExperiments = getPropValue<TypeTag, Properties::EnableExperiments>() };
128 enum { enableExtbo = getPropValue<TypeTag, Properties::EnableExtbo>() };
129 enum { enableFoam = getPropValue<TypeTag, Properties::EnableFoam>() };
130 enum { enableMICP = Indices::enableMICP };
131 enum { enablePolymer = getPropValue<TypeTag, Properties::EnablePolymer>() };
132 enum { enablePolymerMolarWeight = getPropValue<TypeTag, Properties::EnablePolymerMW>() };
133 enum { enableSaltPrecipitation = getPropValue<TypeTag, Properties::EnableSaltPrecipitation>() };
134 enum { enableSolvent = getPropValue<TypeTag, Properties::EnableSolvent>() };
135 enum { enableThermalFluxBoundaries = getPropValue<TypeTag, Properties::EnableThermalFluxBoundaries>() };
137 enum { gasPhaseIdx = FluidSystem::gasPhaseIdx };
138 enum { oilPhaseIdx = FluidSystem::oilPhaseIdx };
139 enum { waterPhaseIdx = FluidSystem::waterPhaseIdx };
143 enum { gasCompIdx = FluidSystem::gasCompIdx };
144 enum { oilCompIdx = FluidSystem::oilCompIdx };
145 enum { waterCompIdx = FluidSystem::waterCompIdx };
150 using Element =
typename GridView::template Codim<0>::Entity;
154 using MaterialLawParams =
typename EclMaterialLawManager::MaterialLawParams;
155 using SolidEnergyLawParams =
typename EclThermalLawManager::SolidEnergyLawParams;
156 using ThermalConductionLawParams =
typename EclThermalLawManager::ThermalConductionLawParams;
164 using Toolbox = MathToolbox<Evaluation>;
165 using DimMatrix = Dune::FieldMatrix<Scalar, dimWorld, dimWorld>;
169 using DirectionalMobilityPtr = Utility::CopyablePtr<DirectionalMobility<TypeTag>>;
187 ParentType::registerParameters();
189 registerFlowProblemParameters<Scalar>();
202 const std::string&)> addKey,
203 std::set<std::string>& seenParams,
204 std::string& errorMsg,
210 return detail::eclPositionalParameter(addKey,
221 : ParentType(simulator)
222 ,
BaseType(simulator.vanguard().eclState(),
223 simulator.vanguard().schedule(),
224 simulator.vanguard().gridView())
225 , transmissibilities_(simulator.vanguard().eclState(),
226 simulator.vanguard().gridView(),
227 simulator.vanguard().cartesianIndexMapper(),
228 simulator.vanguard().grid(),
229 simulator.vanguard().cellCentroids(),
230 (energyModuleType == EnergyModules::FullyImplicitThermal ||
231 energyModuleType == EnergyModules::SequentialImplicitThermal), enableDiffusion,
233 , wellModel_(simulator)
234 , aquiferModel_(simulator)
235 , pffDofData_(simulator.gridView(), this->elementMapper())
236 , tracerModel_(simulator)
237 , temperatureModel_(simulator)
239 if (! Parameters::Get<Parameters::CheckSatfuncConsistency>()) {
244 relpermDiagnostics.
diagnosis(simulator.vanguard().eclState(),
245 simulator.vanguard().levelCartesianIndexMapper());
248 if (energyModuleType == EnergyModules::SequentialImplicitThermal) {
249 this->enableDriftCompensationTemp_ = Parameters::Get<Parameters::EnableDriftCompensationTemp>();
256 void prefetch(
const Element& elem)
const 257 { this->pffDofData_.prefetch(elem); }
270 template <
class Restarter>
277 wellModel_.deserialize(res);
280 aquiferModel_.deserialize(res);
289 template <
class Restarter>
292 wellModel_.serialize(res);
294 aquiferModel_.serialize(res);
297 int episodeIndex()
const 299 return std::max(this->simulator().episodeIndex(), 0);
309 auto& simulator = this->simulator();
310 int episodeIdx = simulator.episodeIndex();
311 auto& eclState = simulator.vanguard().eclState();
312 const auto& schedule = simulator.vanguard().schedule();
313 const auto& events = schedule[episodeIdx].events();
315 if (episodeIdx >= 0 && events.hasEvent(ScheduleEvents::GEO_MODIFIER)) {
322 const auto& miniDeck = schedule[episodeIdx].geo_keywords();
323 const auto& cc = simulator.vanguard().grid().comm();
324 eclState.apply_schedule_keywords( miniDeck );
325 eclBroadcast(cc, eclState.getTransMult() );
328 std::function<unsigned int(unsigned int)> equilGridToGrid = [&simulator](
unsigned int i) {
329 return simulator.vanguard().gridEquilIdxToGridIdx(i);
333 using TransUpdateQuantities =
typename Vanguard::TransmissibilityType::TransUpdateQuantities;
334 transmissibilities_.update(
true, TransUpdateQuantities::All, equilGridToGrid);
335 this->referencePorosity_[1] = this->referencePorosity_[0];
336 updateReferencePorosity_();
337 this->rockFraction_[1] = this->rockFraction_[0];
338 updateRockFraction_();
340 this->model().linearizer().updateDiscretizationParameters();
343 bool tuningEvent = this->beginEpisode_(enableExperiments, this->episodeIndex());
346 wellModel_.beginEpisode();
349 aquiferModel_.beginEpisode();
352 Scalar dt = limitNextTimeStepSize_(simulator.episodeLength());
354 if ( (episodeIdx == 0 || tuningEvent) && this->initialTimeStepSize_ > 0)
357 dt = std::min(dt, this->initialTimeStepSize_);
358 simulator.setTimeStepSize(dt);
367 const int episodeIdx = this->episodeIndex();
368 const int timeStepSize = this->simulator().timeStepSize();
370 this->beginTimeStep_(enableExperiments,
372 this->simulator().timeStepIndex(),
373 this->simulator().startTime(),
374 this->simulator().time(),
376 this->simulator().endTime());
381 this->updateExplicitQuantities_(episodeIdx, timeStepSize, first_step_ && (episodeIdx > 0));
384 if (nonTrivialBoundaryConditions()) {
385 this->model().linearizer().updateBoundaryConditionData();
388 wellModel_.beginTimeStep();
389 aquiferModel_.beginTimeStep();
390 tracerModel_.beginTimeStep();
391 temperatureModel_.beginTimeStep();
401 wellModel_.beginIteration();
402 aquiferModel_.beginIteration();
411 wellModel_.endIteration();
412 aquiferModel_.endIteration();
423 if constexpr (getPropValue<TypeTag, Properties::EnableDebuggingChecks>()) {
429 const int rank = this->simulator().gridView().comm().rank();
431 std::cout <<
"checking conservativeness of solution\n";
434 this->model().checkConservativeness(-1,
true);
436 std::cout <<
"solution is sufficiently conservative\n";
441 auto& simulator = this->simulator();
442 simulator.setTimeStepIndex(simulator.timeStepIndex()+1);
444 this->wellModel_.endTimeStep();
445 this->aquiferModel_.endTimeStep();
446 this->tracerModel_.endTimeStep();
449 this->model().linearizer().updateFlowsInfo();
451 if (this->enableDriftCompensation_ || this->enableDriftCompensationTemp_) {
452 OPM_TIMEBLOCK(driftCompansation);
454 const auto& residual = this->model().linearizer().residual();
456 for (
unsigned globalDofIdx = 0; globalDofIdx < residual.size(); globalDofIdx ++) {
457 int sfcdofIdx = simulator.vanguard().gridEquilIdxToGridIdx(globalDofIdx);
458 this->drift_[sfcdofIdx] = residual[sfcdofIdx] * simulator.timeStepSize();
460 if constexpr (getPropValue<TypeTag, Properties::UseVolumetricResidual>()) {
461 this->drift_[sfcdofIdx] *= this->model().dofTotalVolume(sfcdofIdx);
467 if constexpr(energyModuleType == EnergyModules::SequentialImplicitThermal) {
468 this->temperatureModel_.endTimeStep(wellModel_.wellState());
477 const int episodeIdx = this->episodeIndex();
479 this->wellModel_.endEpisode();
480 this->aquiferModel_.endEpisode();
482 const auto& schedule = this->simulator().vanguard().schedule();
485 if (episodeIdx + 1 >= static_cast<int>(schedule.size()) - 1) {
486 this->simulator().setFinished(
true);
491 this->simulator().startNextEpisode(schedule.stepLength(episodeIdx + 1));
500 OPM_TIMEBLOCK(problemWriteOutput);
502 if (Parameters::Get<Parameters::EnableWriteAllSolutions>() ||
506 ParentType::writeOutput(verbose);
513 template <
class Context>
516 unsigned timeIdx)
const 518 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
519 return transmissibilities_.permeability(globalSpaceIdx);
529 {
return transmissibilities_.permeability(globalElemIdx); }
534 template <
class Context>
536 [[maybe_unused]]
unsigned fromDofLocalIdx,
537 unsigned toDofLocalIdx)
const 539 assert(fromDofLocalIdx == 0);
548 return transmissibilities_.transmissibility(globalCenterElemIdx, globalElemIdx);
554 template <
class Context>
556 [[maybe_unused]]
unsigned fromDofLocalIdx,
557 unsigned toDofLocalIdx)
const 559 assert(fromDofLocalIdx == 0);
560 return *pffDofData_.get(context.element(), toDofLocalIdx).
diffusivity;
566 Scalar
diffusivity(
const unsigned globalCellIn,
const unsigned globalCellOut)
const{
567 return transmissibilities_.diffusivity(globalCellIn, globalCellOut);
573 Scalar
dispersivity(
const unsigned globalCellIn,
const unsigned globalCellOut)
const{
574 return transmissibilities_.dispersivity(globalCellIn, globalCellOut);
581 const unsigned boundaryFaceIdx)
const 583 return transmissibilities_.thermalTransmissibilityBoundary(globalSpaceIdx, boundaryFaceIdx);
592 template <
class Context>
594 unsigned boundaryFaceIdx)
const 596 unsigned elemIdx = elemCtx.globalSpaceIndex(0, 0);
597 return transmissibilities_.transmissibilityBoundary(elemIdx, boundaryFaceIdx);
604 const unsigned boundaryFaceIdx)
const 606 return transmissibilities_.transmissibilityBoundary(globalSpaceIdx, boundaryFaceIdx);
614 const unsigned globalSpaceIdxOut)
const 616 return transmissibilities_.thermalHalfTrans(globalSpaceIdxIn,globalSpaceIdxOut);
622 template <
class Context>
625 unsigned timeIdx)
const 627 const auto& face = context.stencil(timeIdx).interiorFace(faceIdx);
628 unsigned toDofLocalIdx = face.exteriorIndex();
629 return *pffDofData_.get(context.element(), toDofLocalIdx).thermalHalfTransIn;
635 template <
class Context>
638 unsigned timeIdx)
const 640 const auto& face = context.stencil(timeIdx).interiorFace(faceIdx);
641 unsigned toDofLocalIdx = face.exteriorIndex();
642 return *pffDofData_.get(context.element(), toDofLocalIdx).thermalHalfTransOut;
648 template <
class Context>
650 unsigned boundaryFaceIdx)
const 652 unsigned elemIdx = elemCtx.globalSpaceIndex(0, 0);
653 return transmissibilities_.thermalHalfTransBoundary(elemIdx, boundaryFaceIdx);
660 {
return transmissibilities_; }
664 {
return tracerModel_; }
666 TracerModel& tracerModel()
667 {
return tracerModel_; }
669 TemperatureModel& temperatureModel()
670 {
return temperatureModel_; }
680 template <
class Context>
681 Scalar
porosity(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 683 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
684 return this->
porosity(globalSpaceIdx, timeIdx);
693 template <
class Context>
694 Scalar
dofCenterDepth(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 696 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
708 return this->simulator().vanguard().cellCenterDepth(globalSpaceIdx);
714 template <
class Context>
717 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
724 template <
class Context>
725 Scalar
rockBiotComp(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 727 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
734 template <
class Context>
735 Scalar
lame(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 737 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
738 return this->
lame(globalSpaceIdx);
744 template <
class Context>
745 Scalar
biotCoeff(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 747 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
754 template <
class Context>
757 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
766 const auto& rock_config = this->simulator().vanguard().eclState().getSimulationConfig().rock_config();
767 if (rock_config.store()) {
768 return asImp_().initialFluidState(globalSpaceIdx).pressure(refPressurePhaseIdx_());
771 if (this->rockParams_.empty())
774 unsigned tableIdx = 0;
775 if (!this->rockTableIdx_.empty()) {
776 tableIdx = this->rockTableIdx_[globalSpaceIdx];
778 return this->rockParams_[tableIdx].referencePressure;
785 template <
class Context>
787 unsigned spaceIdx,
unsigned timeIdx)
const 789 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
795 return materialLawManager_->materialLawParams(globalDofIdx);
798 const MaterialLawParams&
materialLawParams(
unsigned globalDofIdx, FaceDir::DirEnum facedir)
const 800 return materialLawManager_->materialLawParams(globalDofIdx, facedir);
806 template <
class Context>
807 const SolidEnergyLawParams&
810 unsigned timeIdx)
const 812 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
813 return thermalLawManager_->solidEnergyLawParams(globalSpaceIdx);
819 template <
class Context>
820 const ThermalConductionLawParams &
823 unsigned globalSpaceIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
824 return thermalLawManager_->thermalConductionLawParams(globalSpaceIdx);
834 {
return materialLawManager_; }
836 template <
class FluidState,
class ...Args>
838 std::array<Evaluation,numPhases> &mobility,
839 DirectionalMobilityPtr &dirMob,
840 FluidState &fluidState,
841 unsigned globalSpaceIdx)
const 843 using ContainerT = std::array<Evaluation, numPhases>;
844 OPM_TIMEBLOCK_LOCAL(updateRelperms, Subsystem::SatProps);
849 MaterialLaw::template relativePermeabilities<ContainerT, FluidState, Args...>(mobility, materialParams, fluidState);
850 Valgrind::CheckDefined(mobility);
852 if (materialLawManager_->hasDirectionalRelperms()
853 || materialLawManager_->hasDirectionalImbnum())
855 using Dir = FaceDir::DirEnum;
856 constexpr
int ndim = 3;
857 dirMob = std::make_unique<DirectionalMobility<TypeTag>>();
858 Dir facedirs[ndim] = {Dir::XPlus, Dir::YPlus, Dir::ZPlus};
859 for (
int i = 0; i<ndim; i++) {
861 auto& mob_array = dirMob->getArray(i);
862 MaterialLaw::template relativePermeabilities<ContainerT, FluidState, Args...>(mob_array, materialParams, fluidState);
871 {
return materialLawManager_; }
877 template <
class Context>
878 unsigned pvtRegionIndex(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 879 {
return pvtRegionIndex(context.globalSpaceIndex(spaceIdx, timeIdx)); }
885 template <
class Context>
893 template <
class Context>
901 template <
class Context>
910 template <
class Context>
918 {
return this->simulator().vanguard().caseName(); }
923 template <
class Context>
924 Scalar
temperature(
const Context& context,
unsigned spaceIdx,
unsigned timeIdx)
const 928 unsigned globalDofIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
929 if constexpr (energyModuleType == EnergyModules::SequentialImplicitThermal)
930 return temperatureModel_.temperature(globalDofIdx);
932 return asImp_().initialFluidState(globalDofIdx).temperature(0);
936 Scalar
temperature(
unsigned globalDofIdx,
unsigned )
const 940 if constexpr (energyModuleType == EnergyModules::SequentialImplicitThermal)
941 return temperatureModel_.temperature(globalDofIdx);
943 return asImp_().initialFluidState(globalDofIdx).temperature(0);
946 const SolidEnergyLawParams&
950 return this->thermalLawManager_->solidEnergyLawParams(globalSpaceIdx);
952 const ThermalConductionLawParams &
956 return this->thermalLawManager_->thermalConductionLawParams(globalSpaceIdx);
970 if (!this->vapparsActive(this->episodeIndex()))
973 return this->maxOilSaturation_[globalDofIdx];
987 if (!this->vapparsActive(this->episodeIndex()))
990 this->maxOilSaturation_[globalDofIdx] = value;
999 this->model().invalidateAndUpdateIntensiveQuantities(0);
1005 if (!this->model().enableStorageCache() || !this->recycleFirstIterationStorage()) {
1006 this->model().invalidateAndUpdateIntensiveQuantities(1);
1014 aquiferModel_.initialSolutionApplied();
1016 const bool invalidateFromHyst = updateHysteresis_();
1017 if (invalidateFromHyst) {
1018 OPM_TIMEBLOCK(beginTimeStepInvalidateIntensiveQuantities);
1019 this->model().invalidateAndUpdateIntensiveQuantities(0);
1028 template <
class Context>
1030 const Context& context,
1032 unsigned timeIdx)
const 1034 const unsigned globalDofIdx = context.globalSpaceIndex(spaceIdx, timeIdx);
1035 source(rate, globalDofIdx, timeIdx);
1038 void source(RateVector& rate,
1039 unsigned globalDofIdx,
1040 unsigned timeIdx)
const 1042 OPM_TIMEBLOCK_LOCAL(eclProblemSource, Subsystem::Assembly);
1046 wellModel_.computeTotalRatesForDof(rate, globalDofIdx);
1050 for (
unsigned eqIdx = 0; eqIdx < numEq; ++ eqIdx) {
1051 rate[eqIdx] /= this->model().dofTotalVolume(globalDofIdx);
1053 Valgrind::CheckDefined(rate[eqIdx]);
1054 assert(isfinite(rate[eqIdx]));
1058 addToSourceDense(rate, globalDofIdx, timeIdx);
1061 virtual void addToSourceDense(RateVector& rate,
1062 unsigned globalDofIdx,
1063 unsigned timeIdx)
const = 0;
1071 {
return wellModel_; }
1074 {
return wellModel_; }
1076 const AquiferModel& aquiferModel()
const 1077 {
return aquiferModel_; }
1079 AquiferModel& mutableAquiferModel()
1080 {
return aquiferModel_; }
1082 bool nonTrivialBoundaryConditions()
const 1083 {
return nonTrivialBoundaryConditions_; }
1093 OPM_TIMEBLOCK(nexTimeStepSize);
1095 if (this->nextTimeStepSize_ > 0.0)
1096 return this->nextTimeStepSize_;
1098 const auto& simulator = this->simulator();
1099 int episodeIdx = simulator.episodeIndex();
1103 return this->initialTimeStepSize_;
1108 const auto& newtonMethod = this->model().newtonMethod();
1109 return limitNextTimeStepSize_(newtonMethod.suggestTimeStepSize(simulator.timeStepSize()));
1117 template <
class LhsEval>
1121 if (this->rockCompPoroMult_.empty() && this->rockCompPoroMultWc_.empty())
1124 unsigned tableIdx = 0;
1125 if (!this->rockTableIdx_.empty())
1126 tableIdx = this->rockTableIdx_[elementIdx];
1128 const auto& fs = intQuants.fluidState();
1129 LhsEval effectivePressure = decay<LhsEval>(fs.pressure(refPressurePhaseIdx_()));
1130 const auto& rock_config = this->simulator().vanguard().eclState().getSimulationConfig().rock_config();
1131 if (!this->minRefPressure_.empty())
1134 min(decay<LhsEval>(fs.pressure(refPressurePhaseIdx_())),
1135 this->minRefPressure_[elementIdx]);
1137 if (!this->overburdenPressure_.empty())
1138 effectivePressure -= this->overburdenPressure_[elementIdx];
1140 if (rock_config.store()) {
1141 effectivePressure -= asImp_().initialFluidState(elementIdx).pressure(refPressurePhaseIdx_());
1144 if (!this->rockCompPoroMult_.empty()) {
1145 return this->rockCompPoroMult_[tableIdx].eval(effectivePressure,
true);
1149 assert(!this->rockCompPoroMultWc_.empty());
1150 LhsEval SwMax = max(decay<LhsEval>(fs.saturation(waterPhaseIdx)), this->maxWaterSaturation_[elementIdx]);
1151 LhsEval SwDeltaMax = SwMax - asImp_().initialFluidStates()[elementIdx].saturation(waterPhaseIdx);
1153 return this->rockCompPoroMultWc_[tableIdx].eval(effectivePressure, SwDeltaMax,
true);
1161 template <
class LhsEval>
1164 auto obtain = [](
const auto& value)
1166 if constexpr (std::is_same_v<LhsEval, Scalar>) {
1167 return getValue(value);
1172 return rockCompTransMultiplier<LhsEval>(intQuants, elementIdx, obtain);
1175 template <
class LhsEval,
class Callback>
1176 LhsEval
rockCompTransMultiplier(
const IntensiveQuantities& intQuants,
unsigned elementIdx, Callback& obtain)
const 1178 const bool implicit = !this->explicitRockCompaction_;
1179 return implicit ? this->simulator().problem().template computeRockCompTransMultiplier_<LhsEval>(intQuants, elementIdx, obtain)
1180 : this->simulator().problem().getRockCompTransMultVal(elementIdx);
1183 template <
class LhsEval,
class Callback>
1184 LhsEval wellTransMultiplier(
const IntensiveQuantities& intQuants,
unsigned elementIdx, Callback& obtain)
const 1186 OPM_TIMEBLOCK_LOCAL(wellTransMultiplier, Subsystem::Wells);
1188 const bool implicit = !this->explicitRockCompaction_;
1189 LhsEval trans_mult = implicit ? this->simulator().problem().template computeRockCompTransMultiplier_<LhsEval>(intQuants, elementIdx, obtain)
1190 : this->simulator().problem().getRockCompTransMultVal(elementIdx);
1191 trans_mult *= this->simulator().problem().template permFactTransMultiplier<LhsEval>(intQuants, elementIdx, obtain);
1196 std::pair<BCType, RateVector> boundaryCondition(
const unsigned int globalSpaceIdx,
const int directionId)
const 1198 OPM_TIMEBLOCK_LOCAL(boundaryCondition, Subsystem::Assembly);
1199 if (!nonTrivialBoundaryConditions_) {
1200 return { BCType::NONE, RateVector(0.0) };
1202 FaceDir::DirEnum dir = FaceDir::FromIntersectionIndex(directionId);
1203 const auto& schedule = this->simulator().vanguard().schedule();
1204 if (bcindex_(dir)[globalSpaceIdx] == 0) {
1205 return { BCType::NONE, RateVector(0.0) };
1207 if (schedule[this->episodeIndex()].bcprop.size() == 0) {
1208 return { BCType::NONE, RateVector(0.0) };
1210 const auto& bc = schedule[this->episodeIndex()].bcprop[bcindex_(dir)[globalSpaceIdx]];
1211 if (bc.bctype!=BCType::RATE) {
1212 return { bc.bctype, RateVector(0.0) };
1215 RateVector rate = 0.0;
1216 switch (bc.component) {
1217 case BCComponent::OIL:
1218 rate[FluidSystem::canonicalToActiveCompIdx(oilCompIdx)] = bc.rate;
1220 case BCComponent::GAS:
1221 rate[FluidSystem::canonicalToActiveCompIdx(gasCompIdx)] = bc.rate;
1223 case BCComponent::WATER:
1224 rate[FluidSystem::canonicalToActiveCompIdx(waterCompIdx)] = bc.rate;
1226 case BCComponent::SOLVENT:
1227 this->handleSolventBC(bc, rate);
1229 case BCComponent::POLYMER:
1230 this->handlePolymerBC(bc, rate);
1232 case BCComponent::MICR:
1233 this->handleMicrBC(bc, rate);
1235 case BCComponent::OXYG:
1236 this->handleOxygBC(bc, rate);
1238 case BCComponent::UREA:
1239 this->handleUreaBC(bc, rate);
1241 case BCComponent::NONE:
1242 throw std::logic_error(
"you need to specify the component when RATE type is set in BC");
1246 return {bc.bctype, rate};
1250 template<
class Serializer>
1251 void serializeOp(Serializer& serializer)
1253 serializer(static_cast<BaseType&>(*
this));
1255 serializer(wellModel_);
1256 serializer(aquiferModel_);
1257 serializer(tracerModel_);
1258 serializer(*materialLawManager_);
1261 const GlobalEqVector& drift()
const 1267 Implementation& asImp_()
1268 {
return *
static_cast<Implementation *
>(
this); }
1270 const Implementation& asImp_()
const 1271 {
return *
static_cast<const Implementation *
>(
this); }
1274 template<
class UpdateFunc>
1275 void updateProperty_(
const std::string& failureMsg,
1278 OPM_TIMEBLOCK(updateProperty);
1279 const auto& model = this->simulator().model();
1280 const auto& primaryVars = model.solution(0);
1281 const auto& vanguard = this->simulator().vanguard();
1282 std::size_t numGridDof = primaryVars.size();
1283 OPM_BEGIN_PARALLEL_TRY_CATCH();
1285 #pragma omp parallel for 1287 for (
unsigned dofIdx = 0; dofIdx < numGridDof; ++dofIdx) {
1288 const auto& iq = *model.cachedIntensiveQuantities(dofIdx, 0);
1291 OPM_END_PARALLEL_TRY_CATCH(failureMsg, vanguard.grid().comm());
1294 bool updateMaxOilSaturation_()
1296 OPM_TIMEBLOCK(updateMaxOilSaturation);
1297 int episodeIdx = this->episodeIndex();
1300 if (this->vapparsActive(episodeIdx)) {
1301 this->updateProperty_(
"FlowProblem::updateMaxOilSaturation_() failed:",
1302 [
this](
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1304 this->updateMaxOilSaturation_(compressedDofIdx,iq);
1312 bool updateMaxOilSaturation_(
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1314 OPM_TIMEBLOCK_LOCAL(updateMaxOilSaturation, Subsystem::SatProps);
1315 const auto& fs = iq.fluidState();
1316 const Scalar So = decay<Scalar>(fs.saturation(refPressurePhaseIdx_()));
1317 auto& mos = this->maxOilSaturation_;
1318 if(mos[compressedDofIdx] < So){
1319 mos[compressedDofIdx] = So;
1326 bool updateMaxWaterSaturation_()
1328 OPM_TIMEBLOCK(updateMaxWaterSaturation);
1330 if (this->maxWaterSaturation_.empty())
1333 this->maxWaterSaturation_[1] = this->maxWaterSaturation_[0];
1334 this->updateProperty_(
"FlowProblem::updateMaxWaterSaturation_() failed:",
1335 [
this](
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1337 this->updateMaxWaterSaturation_(compressedDofIdx,iq);
1343 bool updateMaxWaterSaturation_(
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1345 OPM_TIMEBLOCK_LOCAL(updateMaxWaterSaturation, Subsystem::SatProps);
1346 const auto& fs = iq.fluidState();
1347 const Scalar Sw = decay<Scalar>(fs.saturation(waterPhaseIdx));
1348 auto& mow = this->maxWaterSaturation_;
1349 if(mow[compressedDofIdx]< Sw){
1350 mow[compressedDofIdx] = Sw;
1357 bool updateMinPressure_()
1359 OPM_TIMEBLOCK(updateMinPressure);
1361 if (this->minRefPressure_.empty())
1364 this->updateProperty_(
"FlowProblem::updateMinPressure_() failed:",
1365 [
this](
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1367 this->updateMinPressure_(compressedDofIdx,iq);
1372 bool updateMinPressure_(
unsigned compressedDofIdx,
const IntensiveQuantities& iq){
1373 OPM_TIMEBLOCK_LOCAL(updateMinPressure, Subsystem::PvtProps);
1374 const auto& fs = iq.fluidState();
1375 const Scalar min_pressure = getValue(fs.pressure(refPressurePhaseIdx_()));
1376 auto& min_pressures = this->minRefPressure_;
1377 if(min_pressures[compressedDofIdx]> min_pressure){
1378 min_pressures[compressedDofIdx] = min_pressure;
1389 std::function<std::vector<double>(
const FieldPropsManager&,
const std::string&)>
1390 fieldPropDoubleOnLeafAssigner_()
1392 const auto& lookup = this->lookUpData_;
1393 return [&lookup](
const FieldPropsManager& fieldPropManager,
const std::string& propString)
1395 return lookup.assignFieldPropsDoubleOnLeaf(fieldPropManager, propString);
1403 template<
typename IntType>
1404 std::function<std::vector<IntType>(
const FieldPropsManager&,
const std::string&, bool)>
1405 fieldPropIntTypeOnLeafAssigner_()
1407 const auto& lookup = this->lookUpData_;
1408 return [&lookup](
const FieldPropsManager& fieldPropManager,
const std::string& propString,
bool needsTranslation)
1410 return lookup.template assignFieldPropsIntOnLeaf<IntType>(fieldPropManager, propString, needsTranslation);
1414 void readMaterialParameters_()
1416 OPM_TIMEBLOCK(readMaterialParameters);
1417 const auto& simulator = this->simulator();
1418 const auto& vanguard = simulator.vanguard();
1419 const auto& eclState = vanguard.eclState();
1422 OPM_BEGIN_PARALLEL_TRY_CATCH();
1423 this->updatePvtnum_();
1424 this->updateSatnum_();
1427 this->updateMiscnum_();
1429 this->updatePlmixnum_();
1431 OPM_END_PARALLEL_TRY_CATCH(
"Invalid region numbers: ", vanguard.gridView().comm());
1434 updateReferencePorosity_();
1435 this->referencePorosity_[1] = this->referencePorosity_[0];
1440 updateRockFraction_();
1441 this->rockFraction_[1] = this->rockFraction_[0];
1446 materialLawManager_ = std::make_shared<EclMaterialLawManager>();
1447 materialLawManager_->initFromState(eclState);
1448 materialLawManager_->initParamsForElements(eclState, this->model().numGridDof(),
1449 this->
template fieldPropIntTypeOnLeafAssigner_<int>(),
1450 this-> lookupIdxOnLevelZeroAssigner_());
1454 void readThermalParameters_()
1456 if constexpr (energyModuleType == EnergyModules::FullyImplicitThermal ||
1457 energyModuleType == EnergyModules::SequentialImplicitThermal )
1459 const auto& simulator = this->simulator();
1460 const auto& vanguard = simulator.vanguard();
1461 const auto& eclState = vanguard.eclState();
1464 thermalLawManager_ = std::make_shared<EclThermalLawManager>();
1465 thermalLawManager_->initParamsForElements(eclState, this->model().numGridDof(),
1466 this-> fieldPropDoubleOnLeafAssigner_(),
1467 this->
template fieldPropIntTypeOnLeafAssigner_<unsigned int>());
1471 void updateReferencePorosity_()
1473 const auto& simulator = this->simulator();
1474 const auto& vanguard = simulator.vanguard();
1475 const auto& eclState = vanguard.eclState();
1477 std::size_t numDof = this->model().numGridDof();
1479 this->referencePorosity_[0].resize(numDof);
1481 const auto& fp = eclState.fieldProps();
1482 const std::vector<double> porvData =
this -> fieldPropDoubleOnLeafAssigner_()(fp,
"PORV");
1483 for (std::size_t dofIdx = 0; dofIdx < numDof; ++dofIdx) {
1484 int sfcdofIdx = simulator.vanguard().gridEquilIdxToGridIdx(dofIdx);
1485 Scalar poreVolume = porvData[dofIdx];
1490 Scalar dofVolume = simulator.model().dofTotalVolume(sfcdofIdx);
1491 assert(dofVolume > 0.0);
1492 this->referencePorosity_[0][sfcdofIdx] = poreVolume/dofVolume;
1496 void updateRockFraction_() {
1498 const bool solveEnergyEquation = (energyModuleType == EnergyModules::FullyImplicitThermal ||
1499 energyModuleType == EnergyModules::SequentialImplicitThermal);
1500 if (!solveEnergyEquation)
1503 const auto& simulator = this->simulator();
1504 const auto& vanguard = simulator.vanguard();
1505 const auto& eclState = vanguard.eclState();
1507 std::size_t numDof = this->model().numGridDof();
1508 this->rockFraction_[0].resize(numDof);
1517 const auto& fp = eclState.fieldProps();
1518 const std::vector<double> poroData = this->fieldPropDoubleOnLeafAssigner_()(fp,
"PORO");
1519 const std::vector<double> ntgData = this->fieldPropDoubleOnLeafAssigner_()(fp,
"NTG");
1521 for (std::size_t dofIdx = 0; dofIdx < numDof; ++dofIdx) {
1522 const auto ntg = ntgData[dofIdx];
1523 const auto poro_eff = ntg * poroData[dofIdx];
1524 const int sfcdofIdx = simulator.vanguard().gridEquilIdxToGridIdx(dofIdx);
1525 const auto rock_fraction = (1 - poro_eff) * this->referencePorosity_[0][sfcdofIdx] / poro_eff;
1526 this->rockFraction_[0][sfcdofIdx] = rock_fraction;
1530 virtual void readInitialCondition_()
1533 const auto& simulator = this->simulator();
1534 const auto& vanguard = simulator.vanguard();
1535 const auto& eclState = vanguard.eclState();
1537 if (eclState.getInitConfig().hasEquil())
1538 readEquilInitialCondition_();
1540 readExplicitInitialCondition_();
1543 std::size_t numElems = this->model().numGridDof();
1544 for (std::size_t elemIdx = 0; elemIdx < numElems; ++elemIdx) {
1545 const auto& fs = asImp_().initialFluidStates()[elemIdx];
1546 if (!this->maxWaterSaturation_.empty() && waterPhaseIdx > -1)
1547 this->maxWaterSaturation_[elemIdx] = std::max(this->maxWaterSaturation_[elemIdx], fs.saturation(waterPhaseIdx));
1548 if (!this->maxOilSaturation_.empty() && oilPhaseIdx > -1)
1549 this->maxOilSaturation_[elemIdx] = std::max(this->maxOilSaturation_[elemIdx], fs.saturation(oilPhaseIdx));
1550 if (!this->minRefPressure_.empty() && refPressurePhaseIdx_() > -1)
1551 this->minRefPressure_[elemIdx] = std::min(this->minRefPressure_[elemIdx], fs.pressure(refPressurePhaseIdx_()));
1555 virtual void readEquilInitialCondition_() = 0;
1556 virtual void readExplicitInitialCondition_() = 0;
1559 bool updateHysteresis_()
1561 if (!materialLawManager_->enableHysteresis())
1566 this->updateProperty_(
"FlowProblem::updateHysteresis_() failed:",
1567 [
this](
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1569 materialLawManager_->updateHysteresis(iq.fluidState(), compressedDofIdx);
1575 bool updateHysteresis_(
unsigned compressedDofIdx,
const IntensiveQuantities& iq)
1577 OPM_TIMEBLOCK_LOCAL(updateHysteresis_, Subsystem::SatProps);
1578 materialLawManager_->updateHysteresis(iq.fluidState(), compressedDofIdx);
1583 Scalar getRockCompTransMultVal(std::size_t dofIdx)
const 1585 if (this->rockCompTransMultVal_.empty())
1588 return this->rockCompTransMultVal_[dofIdx];
1594 ConditionalStorage<enableFullyImplicitThermal, Scalar> thermalHalfTransIn;
1595 ConditionalStorage<enableFullyImplicitThermal, Scalar> thermalHalfTransOut;
1596 ConditionalStorage<enableDiffusion, Scalar> diffusivity;
1597 ConditionalStorage<enableDispersion, Scalar> dispersivity;
1598 Scalar transmissibility;
1602 void updatePffDofData_()
1604 const auto& distFn =
1606 const Stencil& stencil,
1607 unsigned localDofIdx)
1610 const auto& elementMapper = this->model().elementMapper();
1612 unsigned globalElemIdx = elementMapper.index(stencil.entity(localDofIdx));
1613 if (localDofIdx != 0) {
1614 unsigned globalCenterElemIdx = elementMapper.index(stencil.entity(0));
1615 dofData.transmissibility = transmissibilities_.transmissibility(globalCenterElemIdx, globalElemIdx);
1617 if constexpr (enableFullyImplicitThermal) {
1618 *dofData.thermalHalfTransIn = transmissibilities_.thermalHalfTrans(globalCenterElemIdx, globalElemIdx);
1619 *dofData.thermalHalfTransOut = transmissibilities_.thermalHalfTrans(globalElemIdx, globalCenterElemIdx);
1621 if constexpr (enableDiffusion)
1622 *dofData.diffusivity = transmissibilities_.diffusivity(globalCenterElemIdx, globalElemIdx);
1623 if (enableDispersion)
1624 dofData.dispersivity = transmissibilities_.dispersivity(globalCenterElemIdx, globalElemIdx);
1628 pffDofData_.update(distFn);
1631 virtual void updateExplicitQuantities_(
int episodeIdx,
int timeStepSize,
bool first_step_after_restart) = 0;
1633 void readBoundaryConditions_()
1635 const auto& simulator = this->simulator();
1636 const auto& vanguard = simulator.vanguard();
1637 const auto& bcconfig = vanguard.eclState().getSimulationConfig().bcconfig();
1638 if (bcconfig.size() > 0) {
1639 nonTrivialBoundaryConditions_ =
true;
1641 std::size_t numCartDof = vanguard.cartesianSize();
1642 unsigned numElems = vanguard.gridView().size(0);
1643 std::vector<int> cartesianToCompressedElemIdx(numCartDof, -1);
1645 for (
unsigned elemIdx = 0; elemIdx < numElems; ++elemIdx)
1646 cartesianToCompressedElemIdx[vanguard.cartesianIndex(elemIdx)] = elemIdx;
1648 bcindex_.resize(numElems, 0);
1649 auto loopAndApply = [&cartesianToCompressedElemIdx,
1650 &vanguard](
const auto& bcface,
1653 for (
int i = bcface.i1; i <= bcface.i2; ++i) {
1654 for (
int j = bcface.j1; j <= bcface.j2; ++j) {
1655 for (
int k = bcface.k1; k <= bcface.k2; ++k) {
1656 std::array<int, 3> tmp = {i,j,k};
1657 auto elemIdx = cartesianToCompressedElemIdx[vanguard.cartesianIndex(tmp)];
1664 for (
const auto& bcface : bcconfig) {
1665 std::vector<int>& data = bcindex_(bcface.dir);
1666 const int index = bcface.index;
1667 loopAndApply(bcface,
1668 [&data,index](
int elemIdx)
1669 { data[elemIdx] = index; });
1676 Scalar limitNextTimeStepSize_(Scalar dtNext)
const 1678 if constexpr (enableExperiments) {
1679 const auto& simulator = this->simulator();
1680 const auto& schedule = simulator.vanguard().schedule();
1681 int episodeIdx = simulator.episodeIndex();
1684 Scalar maxTimeStepSize = Parameters::Get<Parameters::SolverMaxTimeStepInDays<Scalar>>() * 24 * 60 * 60;
1685 int reportStepIdx = std::max(episodeIdx, 0);
1686 if (this->enableTuning_) {
1687 const auto& tuning = schedule[reportStepIdx].tuning();
1688 maxTimeStepSize = tuning.TSMAXZ;
1691 dtNext = std::min(dtNext, maxTimeStepSize);
1693 Scalar remainingEpisodeTime =
1694 simulator.episodeStartTime() + simulator.episodeLength()
1695 - (simulator.startTime() + simulator.time());
1696 assert(remainingEpisodeTime >= 0.0);
1700 if (remainingEpisodeTime/2.0 < dtNext && dtNext < remainingEpisodeTime*(1.0 - 1e-5))
1703 dtNext = std::min(maxTimeStepSize, remainingEpisodeTime/2.0);
1705 if (simulator.episodeStarts()) {
1708 const auto& events = simulator.vanguard().schedule()[reportStepIdx].events();
1709 bool wellEventOccured =
1710 events.hasEvent(ScheduleEvents::NEW_WELL)
1711 || events.hasEvent(ScheduleEvents::PRODUCTION_UPDATE)
1712 || events.hasEvent(ScheduleEvents::INJECTION_UPDATE)
1713 || events.hasEvent(ScheduleEvents::WELL_STATUS_CHANGE);
1714 if (episodeIdx >= 0 && wellEventOccured && this->maxTimeStepAfterWellEvent_ > 0)
1715 dtNext = std::min(dtNext, this->maxTimeStepAfterWellEvent_);
1722 int refPressurePhaseIdx_()
const {
1723 if (FluidSystem::phaseIsActive(oilPhaseIdx)) {
1726 else if (FluidSystem::phaseIsActive(gasPhaseIdx)) {
1730 return waterPhaseIdx;
1734 void updateRockCompTransMultVal_()
1736 const auto& model = this->simulator().model();
1737 std::size_t numGridDof = this->model().numGridDof();
1738 this->rockCompTransMultVal_.resize(numGridDof, 1.0);
1739 for (std::size_t elementIdx = 0; elementIdx < numGridDof; ++elementIdx) {
1740 const auto& iq = *model.cachedIntensiveQuantities(elementIdx, 0);
1741 Scalar trans_mult = computeRockCompTransMultiplier_<Scalar>(iq, elementIdx);
1742 this->rockCompTransMultVal_[elementIdx] = trans_mult;
1751 template <
class LhsEval>
1754 auto obtain = [](
const auto& value)
1756 if constexpr (std::is_same_v<LhsEval, Scalar>) {
1757 return getValue(value);
1763 return computeRockCompTransMultiplier_<LhsEval>(intQuants, elementIdx, obtain);
1766 template <
class LhsEval,
class Callback>
1769 OPM_TIMEBLOCK_LOCAL(computeRockCompTransMultiplier, Subsystem::PvtProps);
1770 if (this->rockCompTransMult_.empty() && this->rockCompTransMultWc_.empty())
1773 unsigned tableIdx = 0;
1774 if (!this->rockTableIdx_.empty())
1775 tableIdx = this->rockTableIdx_[elementIdx];
1777 const auto& fs = intQuants.fluidState();
1778 LhsEval effectivePressure = obtain(fs.pressure(refPressurePhaseIdx_()));
1779 const auto& rock_config = this->simulator().vanguard().eclState().getSimulationConfig().rock_config();
1780 if (!this->minRefPressure_.empty())
1783 min(obtain(fs.pressure(refPressurePhaseIdx_())),
1784 this->minRefPressure_[elementIdx]);
1786 if (!this->overburdenPressure_.empty())
1787 effectivePressure -= this->overburdenPressure_[elementIdx];
1789 if (rock_config.store()) {
1790 effectivePressure -= asImp_().initialFluidState(elementIdx).pressure(refPressurePhaseIdx_());
1793 if (!this->rockCompTransMult_.empty())
1794 return this->rockCompTransMult_[tableIdx].eval(effectivePressure,
true);
1797 assert(!this->rockCompTransMultWc_.empty());
1798 LhsEval SwMax = max(obtain(fs.saturation(waterPhaseIdx)), this->maxWaterSaturation_[elementIdx]);
1799 LhsEval SwDeltaMax = SwMax - asImp_().initialFluidStates()[elementIdx].saturation(waterPhaseIdx);
1801 return this->rockCompTransMultWc_[tableIdx].eval(effectivePressure, SwDeltaMax,
true);
1804 typename Vanguard::TransmissibilityType transmissibilities_;
1806 std::shared_ptr<EclMaterialLawManager> materialLawManager_;
1807 std::shared_ptr<EclThermalLawManager> thermalLawManager_;
1809 GlobalEqVector drift_;
1811 WellModel wellModel_;
1812 AquiferModel aquiferModel_;
1814 PffGridVector<GridView, Stencil, PffDofData_, DofMapper> pffDofData_;
1815 TracerModel tracerModel_;
1816 TemperatureModel temperatureModel_;
1821 std::array<std::vector<T>,6> data;
1823 void resize(std::size_t size, T defVal)
1825 for (
auto& d : data)
1826 d.resize(size, defVal);
1829 const std::vector<T>& operator()(FaceDir::DirEnum dir)
const 1831 if (dir == FaceDir::DirEnum::Unknown)
1832 throw std::runtime_error(
"Tried to access BC data for the 'Unknown' direction");
1834 int div =
static_cast<int>(dir);
1835 while ((div /= 2) >= 1)
1837 assert(idx >= 0 && idx <= 5);
1841 std::vector<T>& operator()(FaceDir::DirEnum dir)
1843 return const_cast<std::vector<T>&
>(std::as_const(*
this)(dir));
1847 virtual void handleSolventBC(
const BCProp::BCFace&, RateVector&)
const = 0;
1849 virtual void handlePolymerBC(
const BCProp::BCFace&, RateVector&)
const = 0;
1851 virtual void handleMicrBC(
const BCProp::BCFace&, RateVector&)
const = 0;
1853 virtual void handleOxygBC(
const BCProp::BCFace&, RateVector&)
const = 0;
1855 virtual void handleUreaBC(
const BCProp::BCFace&, RateVector&)
const = 0;
1858 bool nonTrivialBoundaryConditions_ =
false;
1859 bool first_step_ =
true;
1865 return this->simulator().episodeWillBeOver();
1871 #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:271
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:1118
void diagnosis(const EclipseState &eclState, const LevelCartesianIndexMapper &levelCartesianIndexMapper)
This function is used to diagnosis relperm in eclipse data file.
Definition: RelpermDiagnostics.cpp:830
std::shared_ptr< const EclMaterialLawManager > materialLawManager() const
Returns the ECL material law manager.
Definition: FlowProblem.hpp:833
std::shared_ptr< EclMaterialLawManager > materialLawManager()
Definition: FlowProblem.hpp:870
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:528
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:878
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:786
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:808
virtual void beginTimeStep()
Called by the simulator before each time integration.
Definition: FlowProblem.hpp:364
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:1863
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:924
unsigned plmixnumRegionIndex(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Returns the index of the relevant region for thermodynmic properties.
Definition: FlowProblem.hpp:902
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:917
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:603
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:1091
Scalar thermalHalfTransmissibility(const unsigned globalSpaceIdxIn, const unsigned globalSpaceIdxOut) const
Definition: FlowProblem.hpp:613
Scalar thermalHalfTransmissibilityOut(const Context &context, unsigned faceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:636
Scalar thermalHalfTransmissibilityIn(const Context &context, unsigned faceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:623
A class which handles tracers as specified in by ECL.
Definition: TracerModel.hpp:69
This file contains a set of helper functions used by VFPProd / VFPInj.
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:968
Scalar porosity(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:681
const WellModel & wellModel() const
Returns a reference to the ECL well manager used by the problem.
Definition: FlowProblem.hpp:1070
Scalar thermalHalfTransmissibilityBoundary(const Context &elemCtx, unsigned boundaryFaceIdx) const
Definition: FlowProblem.hpp:649
Scalar transmissibilityBoundary(const Context &elemCtx, unsigned boundaryFaceIdx) const
Definition: FlowProblem.hpp:593
Scalar thermalTransmissibilityBoundary(const unsigned globalSpaceIdx, const unsigned boundaryFaceIdx) const
Direct access to a boundary transmissibility.
Definition: FlowProblem.hpp:580
LhsEval rockCompTransMultiplier(const IntensiveQuantities &intQuants, unsigned elementIdx) const
Calculate the transmissibility multiplier due to water induced rock compaction.
Definition: FlowProblem.hpp:1162
Scalar dofCenterDepth(unsigned globalSpaceIdx) const
Direct indexed acces to the depth of an degree of freedom [m].
Definition: FlowProblem.hpp:706
Definition: FlowProblem.hpp:1592
const DimMatrix & intrinsicPermeability(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:514
Scalar biotCoeff(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:745
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:911
virtual void beginEpisode()
Called by the simulator before an episode begins.
Definition: FlowProblem.hpp:305
Scalar transmissibility(unsigned globalCenterElemIdx, unsigned globalElemIdx) const
Direct access to the transmissibility between two elements.
Definition: FlowProblem.hpp:546
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:886
Scalar rockBiotComp(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:725
virtual void endTimeStep()
Called by the simulator after each time integration.
Definition: FlowProblem.hpp:418
const Vanguard::TransmissibilityType & eclTransmissibilities() const
Return a reference to the object that handles the "raw" transmissibilities.
Definition: FlowProblem.hpp:659
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:1029
const ThermalConductionLawParams & thermalConductionLawParams(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:821
void beginIteration()
Called by the simulator before each Newton-Raphson iteration.
Definition: FlowProblem.hpp:398
virtual void endEpisode()
Called by the simulator after the end of an episode.
Definition: FlowProblem.hpp:475
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:755
void serialize(Restarter &res)
This method writes the complete state of the problem and its subobjects to disk.
Definition: FlowProblem.hpp:290
FlowProblem(Simulator &simulator)
Definition: FlowProblem.hpp:220
Definition: FlowProblem.hpp:1819
static void registerParameters()
Registers all available parameters for the problem and the model.
Definition: FlowProblem.hpp:185
Scalar dofCenterDepth(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Returns the depth of an degree of freedom [m].
Definition: FlowProblem.hpp:694
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:985
Scalar transmissibility(const Context &context, [[maybe_unused]] unsigned fromDofLocalIdx, unsigned toDofLocalIdx) const
Definition: FlowProblem.hpp:535
virtual void initialSolutionApplied()
Callback used by the model to indicate that the initial solution has been determined for all degrees ...
Definition: FlowProblem.hpp:996
bool shouldWriteOutput() const
Always returns true.
Definition: FlowGenericProblem.hpp:294
Scalar lame(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Definition: FlowProblem.hpp:735
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:498
A class which handles sequential implicit solution of the energy equation as specified in by TEMP...
LhsEval computeRockCompTransMultiplier_(const IntensiveQuantities &intQuants, unsigned elementIdx) const
Calculate the transmissibility multiplier due to water induced rock compaction.
Definition: FlowProblem.hpp:1752
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:715
Scalar diffusivity(const unsigned globalCellIn, const unsigned globalCellOut) const
give the transmissibility for a face i.e.
Definition: FlowProblem.hpp:566
unsigned miscnumRegionIndex(const Context &context, unsigned spaceIdx, unsigned timeIdx) const
Returns the index of the relevant region for thermodynmic properties.
Definition: FlowProblem.hpp:894
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:201
void endIteration()
Called by the simulator after each Newton-Raphson iteration.
Definition: FlowProblem.hpp:408
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:764
Scalar dispersivity(const unsigned globalCellIn, const unsigned globalCellOut) const
give the dispersivity for a face i.e.
Definition: FlowProblem.hpp:573
Scalar diffusivity(const Context &context, [[maybe_unused]] unsigned fromDofLocalIdx, unsigned toDofLocalIdx) const
Definition: FlowProblem.hpp:555