64 using typename FlowProblemType::Scalar;
65 using typename FlowProblemType::Simulator;
66 using typename FlowProblemType::GridView;
67 using typename FlowProblemType::FluidSystem;
68 using typename FlowProblemType::Vanguard;
71 using FlowProblemType::dim;
72 using FlowProblemType::dimWorld;
74 using FlowProblemType::numPhases;
75 using FlowProblemType::numComponents;
77 using FlowProblemType::gasPhaseIdx;
78 using FlowProblemType::oilPhaseIdx;
79 using FlowProblemType::waterPhaseIdx;
81 using typename FlowProblemType::Indices;
82 using typename FlowProblemType::PrimaryVariables;
84 using typename FlowProblemType::Evaluation;
85 using typename FlowProblemType::MaterialLaw;
86 using typename FlowProblemType::RateVector;
102 EclWriterType::registerParameters();
105 Parameters::SetDefault<Parameters::NewtonTolerance<Scalar>>(1
e-7);
108 Opm::CompositionalConfig::EOSType getEosType()
const
110 auto& simulator = this->simulator();
111 const auto& eclState = simulator.vanguard().eclState();
112 return eclState.compositionalConfig().eosType(0);
120 , thresholdPressures_(simulator)
122 eclWriter_ = std::make_unique<EclWriterType>(simulator);
123 enableEclOutput_ = Parameters::Get<Parameters::EnableEclOutput>();
134 FlowProblemType::finishInit();
136 auto& simulator = this->simulator();
142 this->transmissibilities_.finishInit(
143 [&
vg = this->simulator().vanguard()](
const unsigned int it) {
return vg.gridIdxToEquilGridIdx(it); });
150 if (enableEclOutput_) {
151 eclWriter_->setTransmissibilities(&simulator.problem().eclTransmissibilities());
152 std::function<
unsigned int(
unsigned int)>
equilGridToGrid = [&simulator](
unsigned int i) {
153 return simulator.vanguard().gridEquilIdxToGridIdx(i);
158 const auto& eclState = simulator.vanguard().eclState();
159 const auto& schedule = simulator.vanguard().schedule();
162 simulator.setStartTime(schedule.getStartTime());
163 simulator.setEndTime(schedule.simTime(schedule.size() - 1));
169 simulator.setEpisodeIndex(-1);
170 simulator.setEpisodeLength(0.0);
175 this->gravity_ = 0.0;
176 if (Parameters::Get<Parameters::EnableGravity>())
177 this->gravity_[dim - 1] = 9.80665;
178 if (!eclState.getInitConfig().hasGravity())
179 this->gravity_[dim - 1] = 0.0;
181 if (this->enableTuning_) {
184 const auto&
tuning = schedule[0].tuning();
185 this->initialTimeStepSize_ =
tuning.TSINIT.has_value() ?
tuning.TSINIT.value() : -1.0;
186 this->maxTimeStepAfterWellEvent_ =
tuning.TMAXWC;
189 this->initFluidSystem_();
191 if (FluidSystem::phaseIsActive(FluidSystem::oilPhaseIdx)
192 && FluidSystem::phaseIsActive(FluidSystem::gasPhaseIdx)) {
193 this->maxOilSaturation_.resize(this->model().numGridDof(), 0.0);
196 this->readRockParameters_(simulator.vanguard().cellCenterDepths(), [&simulator](
const unsigned idx) {
197 std::array<int, dim> coords;
198 simulator.vanguard().cartesianCoordinate(idx, coords);
199 std::transform(coords.begin(), coords.end(), coords.begin(),
200 [](const auto c) { return c + 1; });
203 FlowProblemType::readMaterialParameters_();
204 FlowProblemType::readThermalParameters_();
207 if (enableEclOutput_) {
208 eclWriter_->writeInit();
211 const auto&
initconfig = eclState.getInitConfig();
213 readEclRestartSolution_();
215 this->readInitialCondition_();
217 FlowProblemType::updatePffDofData_();
220 const auto& vanguard = this->simulator().vanguard();
221 const auto& gridView = vanguard.gridView();
223 this->polymer_.maxAdsorption.resize(
numElements, 0.0);
237 if (this->enableVtkOutput_() && eclState.getIOConfig().initOnly()) {
238 simulator.setTimeStepSize(0.0);
246 simulator.startNextEpisode(schedule.seconds(1));
247 simulator.setEpisodeIndex(0);
248 simulator.setTimeStepIndex(0);
257 FlowProblemType::endTimeStep();
260 this->eclWriter_->mutableOutputModule().invalidateLocalData();
263 const auto& grid = this->simulator().vanguard().gridView().grid();
265 using GridType = std::remove_cv_t<std::remove_reference_t<
decltype(grid)>>;
266 constexpr bool isCpGrid = std::is_same_v<GridType, Dune::CpGrid>;
267 if (!
isCpGrid || (grid.maxLevel() == 0)) {
268 this->eclWriter_->evalSummaryState(! this->episodeWillBeOver());
273 if (enableEclOutput_){
274 eclWriter_->writeReports(timer);
284 FlowProblemType::writeOutput(
verbose);
286 if (! this->enableEclOutput_) {
290 const auto isSubStep = !this->episodeWillBeOver();
292 if (!
isSubStep || Parameters::Get<Parameters::EnableWriteAllSolutions>()) {
304 template <
class Context>
306 const Context& context,
311 if (!context.intersection(
spaceIdx).boundary())
316 if (this->nonTrivialBoundaryConditions()) {
317 throw std::logic_error(
"boundary condition is not supported by compostional modeling yet");
327 template <
class Context>
330 const unsigned globalDofIdx = context.globalSpaceIndex(
spaceIdx,
timeIdx);
331 const auto&
initial_fs = initialFluidStates_[globalDofIdx];
333 for (
unsigned p = 0;
p < numPhases; ++
p) {
345 if (!zmf_initialization_) {
346 for (
unsigned p = 0;
p < numPhases; ++
p) {
353 const auto&
eos_type = getEosType();
355 paramCache.updatePhase(fs, FluidSystem::oilPhaseIdx);
356 paramCache.updatePhase(fs, FluidSystem::gasPhaseIdx);
357 fs.setDensity(FluidSystem::oilPhaseIdx, FluidSystem::density(fs,
paramCache, FluidSystem::oilPhaseIdx));
358 fs.setDensity(FluidSystem::gasPhaseIdx, FluidSystem::density(fs,
paramCache, FluidSystem::gasPhaseIdx));
361 Dune::FieldVector<Scalar, numComponents>
z(0.0);
364 if (Indices::waterEnabled &&
phaseIdx ==
static_cast<unsigned int>(waterPhaseIdx)){
367 const auto saturation = fs.saturation(
phaseIdx);
370 tmp = max(tmp, 1
e-8);
392 const Scalar&
Ltmp = -1.0;
395 values.assignNaive(fs);
398 void addToSourceDense(RateVector&,
unsigned,
unsigned)
const override
403 const InitialFluidState& initialFluidState(
unsigned globalDofIdx)
const
404 {
return initialFluidStates_[globalDofIdx]; }
406 std::vector<InitialFluidState>& initialFluidStates()
407 {
return initialFluidStates_; }
409 const std::vector<InitialFluidState>& initialFluidStates()
const
410 {
return initialFluidStates_; }
414 assert( !thresholdPressures_.enableThresholdPressure() &&
415 " Threshold Pressures are not supported by compostional simulation ");
416 return thresholdPressures_;
419 const EclWriterType& eclWriter()
const
420 {
return *eclWriter_; }
422 EclWriterType& eclWriter()
423 {
return *eclWriter_; }
426 template<
class Serializer>
429 serializer(
static_cast<FlowProblemType&
>(*
this));
434 void updateExplicitQuantities_(
int ,
int ,
bool )
override
439 void readEquilInitialCondition_()
override
441 throw std::logic_error(
"Equilibration is not supported by compositional modeling yet");
444 void readEclRestartSolution_()
446 throw std::logic_error(
"Restarting is not supported by compositional modeling yet");
449 void readExplicitInitialCondition_()
override
451 readExplicitInitialConditionCompositional_();
454 void readExplicitInitialConditionCompositional_()
456 const auto& simulator = this->simulator();
457 const auto& vanguard = simulator.vanguard();
458 const auto& eclState = vanguard.eclState();
459 const auto&
fp = eclState.fieldProps();
462 throw std::runtime_error(
"The ECL input file requires the presence of the PRESSURE "
463 "keyword if the model is initialized explicitly");
465 const bool has_xmf =
fp.has_double(
"XMF");
466 const bool has_ymf =
fp.has_double(
"YMF");
467 const bool has_zmf =
fp.has_double(
"ZMF");
469 throw std::runtime_error(
"The ECL input file requires the presence of ZMF or XMF and YMF "
470 "keyword if the model is initialized explicitly");
474 throw std::runtime_error(
"The ECL input file can not handle explicit initialization "
475 "with both ZMF and XMF or YMF");
479 throw std::runtime_error(
"The ECL input file needs XMF and YMF combined to do the explicit "
480 "initializtion when using XMF or YMF");
488 std::size_t numDof = this->model().numGridDof();
490 initialFluidStates_.resize(numDof);
498 const bool water_active = FluidSystem::phaseIsActive(waterPhaseIdx);
499 const bool gas_active = FluidSystem::phaseIsActive(gasPhaseIdx);
500 const bool oil_active = FluidSystem::phaseIsActive(oilPhaseIdx);
520 for (std::size_t dofIdx = 0; dofIdx < numDof; ++dofIdx) {
549 const std::array<Scalar, numPhases>
pc = {0};
551 if (!FluidSystem::phaseIsActive(
phaseIdx))
554 if (Indices::oilEnabled)
556 else if (Indices::gasEnabled)
558 else if (Indices::waterEnabled)
564 const auto&
xmfData =
fp.get_double(
"XMF");
565 const auto&
ymfData =
fp.get_double(
"YMF");
577 zmf_initialization_ =
true;
578 const auto&
zmfData =
fp.get_double(
"ZMF");
585 const auto ymf = (
dofFluidState.saturation(FluidSystem::gasPhaseIdx) > 0.) ?
zmf : Scalar{0};
589 const auto xmf = (
dofFluidState.saturation(FluidSystem::oilPhaseIdx) > 0.) ?
zmf : Scalar{0};
599 void handleSolventBC(
const BCProp::BCFace& , RateVector& )
const override
601 throw std::logic_error(
"solvent is disabled for compositional modeling and you're trying to add solvent to BC");
604 void handlePolymerBC(
const BCProp::BCFace& , RateVector& )
const override
606 throw std::logic_error(
"polymer is disabled for compositional modeling and you're trying to add polymer to BC");
609 void handleMicrBC(
const BCProp::BCFace& , RateVector& )
const override
611 throw std::logic_error(
"MICP is disabled for compositional modeling and you're trying to add microbes to BC");
614 void handleOxygBC(
const BCProp::BCFace& , RateVector& )
const override
616 throw std::logic_error(
"MICP is disabled for compositional modeling and you're trying to add oxygen to BC");
619 void handleUreaBC(
const BCProp::BCFace& , RateVector& )
const override
621 throw std::logic_error(
"MICP is disabled for compositional modeling and you're trying to add urea to BC");
626 std::vector<InitialFluidState> initialFluidStates_;
628 bool zmf_initialization_ {
false};
630 bool enableEclOutput_{
false};
631 std::unique_ptr<EclWriterType> eclWriter_;