FlowGenericProblem_impl.hpp
Go to the documentation of this file.
1// -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2// vi: set et ts=4 sw=4 sts=4:
3/*
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18
19 Consult the COPYING file in the top-level source directory of this
20 module for the precise wording of the license and the list of
21 copyright holders.
22*/
23#ifndef OPM_FLOW_GENERIC_PROBLEM_IMPL_HPP
24#define OPM_FLOW_GENERIC_PROBLEM_IMPL_HPP
25
26#include <dune/common/parametertree.hh>
27
28#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
29#include <opm/input/eclipse/EclipseState/Tables/OverburdTable.hpp>
30#include <opm/input/eclipse/EclipseState/Tables/RockwnodTable.hpp>
31#include <opm/input/eclipse/Schedule/Schedule.hpp>
32#include <opm/input/eclipse/Units/Units.hpp>
33
36
37#include <boost/date_time.hpp>
38
39#include <fmt/format.h>
40#include <fmt/ranges.h>
41
42#include <algorithm>
43#include <iostream>
44#include <stdexcept>
45
46namespace Opm {
47
48int eclPositionalParameter(Dune::ParameterTree& tree,
49 std::set<std::string>& seenParams,
50 std::string& errorMsg,
51 const char** argv,
52 int paramIdx)
53{
54 std::string param = argv[paramIdx];
55 std::size_t i = param.find('=');
56 if (i != std::string::npos) {
57 std::string oldParamName = param.substr(0, i);
58 std::string oldParamValue = param.substr(i+1);
59 std::string newParamName = "--" + oldParamName;
60 std::replace(newParamName.begin(),
61 newParamName.end(), '_' , '-');
62 errorMsg =
63 "The old syntax to specify parameters on the command line is no longer supported: "
64 "Try replacing '" + oldParamName + "=" + oldParamValue + "' with "+
65 "'" + newParamName + "=" + oldParamValue + "'!";
66 return 0;
67 }
68
69 if (seenParams.count("EclDeckFileName") > 0) {
70 errorMsg =
71 "Parameter 'EclDeckFileName' specified multiple times"
72 " as a command line parameter";
73 return 0;
74 }
75
76 tree["EclDeckFileName"] = argv[paramIdx];
77 seenParams.insert("EclDeckFileName");
78 return 1;
79}
80
81template<class GridView, class FluidSystem>
83FlowGenericProblem(const EclipseState& eclState,
84 const Schedule& schedule,
85 const GridView& gridView)
86 : eclState_(eclState)
87 , schedule_(schedule)
88 , gridView_(gridView)
89 , mixControls_(schedule)
90 , lookUpData_(gridView)
91{
92}
94template<class GridView, class FluidSystem>
97serializationTestObject(const EclipseState& eclState,
98 const Schedule& schedule,
99 const GridView& gridView)
100{
101 FlowGenericProblem result(eclState, schedule, gridView);
102 result.maxOilSaturation_ = {1.0, 2.0};
103 result.maxWaterSaturation_ = {6.0};
104 result.minRefPressure_ = {7.0, 8.0, 9.0, 10.0};
105 result.overburdenPressure_ = {11.0};
106 result.solventSaturation_ = {15.0};
107 result.solventRsw_ = {18.0};
111
112 return result;
113}
114
115template<class GridView, class FluidSystem>
116std::string
119 const char **argv)
120{
121 std::string desc = FlowGenericProblem::briefDescription();
122 if (!desc.empty())
123 desc = desc + "\n";
124
125 return
126 "Usage: "+std::string(argv[0]) + " [OPTIONS] [ECL_DECK_FILENAME]\n"
127 + desc;
128}
130template<class GridView, class FluidSystem>
131std::string
134{
135 return briefDescription_;
137
138template<class GridView, class FluidSystem>
140readRockParameters_(const std::vector<Scalar>& cellCenterDepths,
141 std::function<std::array<int,3>(const unsigned)> ijkIndex)
142{
143 const auto& rock_config = eclState_.getSimulationConfig().rock_config();
144
145 // read the rock compressibility parameters
146 {
147 const auto& comp = rock_config.comp();
148 rockParams_.clear();
149 for (const auto& c : comp)
150 rockParams_.push_back( { c.pref, c.compressibility } );
151 }
152
153 // read the parameters for water-induced rock compaction
154 readRockCompactionParameters_();
155
156 unsigned numElem = gridView_.size(0);
157 if (eclState_.fieldProps().has_int(rock_config.rocknum_property())) {
158 // Auxiliary function to check rockTableIdx_ values belong to the right range. Otherwise, throws.
159 std::function<void(int, int)> valueCheck = [&ijkIndex,&rock_config,this](int fieldPropValue, int coarseElemIdx)
160 {
161 auto fmtError = [fieldPropValue, coarseElemIdx,&ijkIndex,&rock_config](const char* type, std::size_t size)
162 {
163 return fmt::format("{} table index {} for elem {} read from {}"
164 " is out of bounds for number of tables {}",
165 type, fieldPropValue,
166 ijkIndex(coarseElemIdx),
167 rock_config.rocknum_property(), size);
168 };
169 if (!rockCompPoroMult_.empty() &&
170 fieldPropValue > static_cast<int>(rockCompPoroMult_.size())) {
171 throw std::runtime_error(fmtError("Rock compaction",
172 rockCompPoroMult_.size()));
173 }
174 if (!rockCompPoroMultWc_.empty() &&
175 fieldPropValue > static_cast<int>(rockCompPoroMultWc_.size())) {
176 throw std::runtime_error(fmtError("Rock water compaction",
177 rockCompPoroMultWc_.size()));
178 }
179 };
181 rockTableIdx_ = this->lookUpData_.template assignFieldPropsIntOnLeaf<short unsigned int>(eclState_.fieldProps(),
182 rock_config.rocknum_property(),
183 true /*needsTranslation*/,
184 valueCheck);
186
187 // Store overburden pressure pr element
188 const auto& overburdTables = eclState_.getTableManager().getOverburdTables();
189 if (!overburdTables.empty()) {
190 overburdenPressure_.resize(numElem,0.0);
191 std::size_t numRocktabTables = rock_config.num_rock_tables();
192
193 if (overburdTables.size() != numRocktabTables)
194 throw std::runtime_error(std::to_string(numRocktabTables) +" OVERBURD tables is expected, but " + std::to_string(overburdTables.size()) +" is provided");
195
196 std::vector<Tabulated1DFunction<Scalar>> overburdenTables(numRocktabTables);
197 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
198 const OverburdTable& overburdTable = overburdTables.template getTable<OverburdTable>(regionIdx);
199 overburdenTables[regionIdx].setXYContainers(overburdTable.getDepthColumn(),overburdTable.getOverburdenPressureColumn());
200 }
202 for (std::size_t elemIdx = 0; elemIdx < numElem; ++ elemIdx) {
203 unsigned tableIdx = 0;
204 if (!rockTableIdx_.empty()) {
205 tableIdx = rockTableIdx_[elemIdx];
207 overburdenPressure_[elemIdx] =
208 overburdenTables[tableIdx].eval(cellCenterDepths[elemIdx], /*extrapolation=*/true);
209 }
210 }
212
213template<class GridView, class FluidSystem>
217 const auto& rock_config = eclState_.getSimulationConfig().rock_config();
218
219 if (!rock_config.active())
220 return; // deck does not enable rock compaction
222 unsigned numElem = gridView_.size(0);
223 switch (rock_config.hysteresis_mode()) {
224 case RockConfig::Hysteresis::REVERS:
225 break;
226 case RockConfig::Hysteresis::IRREVERS:
227 // interpolate the porv volume multiplier using the minimum pressure in the cell
228 // i.e. don't allow re-inflation.
229 minRefPressure_.resize(numElem, 1e99);
230 break;
231 default:
232 throw std::runtime_error("Not support ROCKOMP hysteresis option ");
233 }
235 std::size_t numRocktabTables = rock_config.num_rock_tables();
236 bool waterCompaction = rock_config.water_compaction();
237
238 if (!waterCompaction) {
239 const auto& rocktabTables = eclState_.getTableManager().getRocktabTables();
240 if (rocktabTables.size() != numRocktabTables)
241 throw std::runtime_error("ROCKCOMP is activated." + std::to_string(numRocktabTables)
242 +" ROCKTAB tables is expected, but " + std::to_string(rocktabTables.size()) +" is provided");
243
244 rockCompPoroMult_.resize(numRocktabTables);
245 rockCompTransMult_.resize(numRocktabTables);
246 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
247 const auto& rocktabTable = rocktabTables.template getTable<RocktabTable>(regionIdx);
248 const auto& pressureColumn = rocktabTable.getPressureColumn();
249 const auto& poroColumn = rocktabTable.getPoreVolumeMultiplierColumn();
250 const auto& transColumn = rocktabTable.getTransmissibilityMultiplierColumn();
251 rockCompPoroMult_[regionIdx].setXYContainers(pressureColumn, poroColumn);
252 rockCompTransMult_[regionIdx].setXYContainers(pressureColumn, transColumn);
254 } else {
255 const auto& rock2dTables = eclState_.getTableManager().getRock2dTables();
256 const auto& rock2dtrTables = eclState_.getTableManager().getRock2dtrTables();
257 const auto& rockwnodTables = eclState_.getTableManager().getRockwnodTables();
258 maxWaterSaturation_.resize(numElem, 0.0);
259
260 if (rock2dTables.size() != numRocktabTables)
261 throw std::runtime_error("Water compation option is selected in ROCKCOMP." + std::to_string(numRocktabTables)
262 +" ROCK2D tables is expected, but " + std::to_string(rock2dTables.size()) +" is provided");
263
264 if (rockwnodTables.size() != numRocktabTables)
265 throw std::runtime_error("Water compation option is selected in ROCKCOMP." + std::to_string(numRocktabTables)
266 +" ROCKWNOD tables is expected, but " + std::to_string(rockwnodTables.size()) +" is provided");
267 //TODO check size match
268 rockCompPoroMultWc_.resize(numRocktabTables, TabulatedTwoDFunction(TabulatedTwoDFunction::InterpolationPolicy::Vertical));
269 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
270 const RockwnodTable& rockwnodTable = rockwnodTables.template getTable<RockwnodTable>(regionIdx);
271 const auto& rock2dTable = rock2dTables[regionIdx];
273 if (rockwnodTable.getSaturationColumn().size() != rock2dTable.sizeMultValues())
274 throw std::runtime_error("Number of entries in ROCKWNOD and ROCK2D needs to match.");
275
276 for (std::size_t xIdx = 0; xIdx < rock2dTable.size(); ++xIdx) {
277 rockCompPoroMultWc_[regionIdx].appendXPos(rock2dTable.getPressureValue(xIdx));
278 for (std::size_t yIdx = 0; yIdx < rockwnodTable.getSaturationColumn().size(); ++yIdx)
279 rockCompPoroMultWc_[regionIdx].appendSamplePoint(xIdx,
280 rockwnodTable.getSaturationColumn()[yIdx],
281 rock2dTable.getPvmultValue(xIdx, yIdx));
282 }
283 }
284
285 if (!rock2dtrTables.empty()) {
286 rockCompTransMultWc_.resize(numRocktabTables, TabulatedTwoDFunction(TabulatedTwoDFunction::InterpolationPolicy::Vertical));
287 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
288 const RockwnodTable& rockwnodTable = rockwnodTables.template getTable<RockwnodTable>(regionIdx);
289 const auto& rock2dtrTable = rock2dtrTables[regionIdx];
290
291 if (rockwnodTable.getSaturationColumn().size() != rock2dtrTable.sizeMultValues())
292 throw std::runtime_error("Number of entries in ROCKWNOD and ROCK2DTR needs to match.");
293
294 for (std::size_t xIdx = 0; xIdx < rock2dtrTable.size(); ++xIdx) {
295 rockCompTransMultWc_[regionIdx].appendXPos(rock2dtrTable.getPressureValue(xIdx));
296 for (std::size_t yIdx = 0; yIdx < rockwnodTable.getSaturationColumn().size(); ++yIdx)
297 rockCompTransMultWc_[regionIdx].appendSamplePoint(xIdx,
298 rockwnodTable.getSaturationColumn()[yIdx],
299 rock2dtrTable.getTransMultValue(xIdx, yIdx));
300 }
301 }
302 }
303 }
304}
305
306template<class GridView, class FluidSystem>
309rockCompressibility(unsigned globalSpaceIdx) const
310{
311 if (this->rockParams_.empty())
312 return 0.0;
314 unsigned tableIdx = 0;
315 if (!this->rockTableIdx_.empty()) {
316 tableIdx = this->rockTableIdx_[globalSpaceIdx];
317 }
318 return this->rockParams_[tableIdx].compressibility;
319}
320
321template<class GridView, class FluidSystem>
324rockReferencePressure(unsigned globalSpaceIdx) const
326 if (this->rockParams_.empty())
327 return 1e5;
328
329 unsigned tableIdx = 0;
330 if (!this->rockTableIdx_.empty()) {
331 tableIdx = this->rockTableIdx_[globalSpaceIdx];
332 }
333 return this->rockParams_[tableIdx].referencePressure;
336template<class GridView, class FluidSystem>
339porosity(unsigned globalSpaceIdx, unsigned timeIdx) const
340{
341 return this->referencePorosity_[timeIdx][globalSpaceIdx];
342}
343
344template<class GridView, class FluidSystem>
347rockFraction(unsigned elementIdx, unsigned timeIdx) const
348{
349 // the reference porosity is defined as the accumulated pore volume divided by the
350 // geometric volume of the element. Note that it can
351 // be larger than 1.0 if porevolume multipliers are used
352 // to for instance implement larger boundary cells
353 auto porosity = this->lookUpData_.fieldPropDouble(eclState_.fieldProps(), "PORO", elementIdx);
354 return referencePorosity(elementIdx, timeIdx) / porosity * (1 - porosity);
355}
356
357template<class GridView, class FluidSystem>
358template<class T>
360updateNum(const std::string& name, std::vector<T>& numbers, std::size_t num_regions)
361{
362 if (!eclState_.fieldProps().has_int(name))
363 return;
364
365 std::function<void(T, int)> valueCheck = [num_regions,name](T fieldPropValue, [[maybe_unused]] int fieldPropIdx) {
366 if ( fieldPropValue > (int)num_regions) {
367 throw std::runtime_error("Values larger than maximum number of regions "
368 + std::to_string(num_regions) + " provided in " + name);
369 }
370 if ( fieldPropValue <= 0) {
371 throw std::runtime_error("zero or negative values provided for region array: " + name);
372 }
373 };
374
375 numbers = this->lookUpData_.template assignFieldPropsIntOnLeaf<T>(eclState_.fieldProps(), name,
376 true /*needsTranslation*/, valueCheck);
377}
378
379template<class GridView, class FluidSystem>
382{
383 const auto num_regions = eclState_.getTableManager().getTabdims().getNumPVTTables();
384 updateNum("PVTNUM", pvtnum_, num_regions);
385}
386
387template<class GridView, class FluidSystem>
390{
391 const auto num_regions = eclState_.getTableManager().getTabdims().getNumSatTables();
392 updateNum("SATNUM", satnum_, num_regions);
393}
394
395template<class GridView, class FluidSystem>
398{
399 const auto num_regions = 1; // we only support single region
400 updateNum("MISCNUM", miscnum_, num_regions);
401}
402
403template<class GridView, class FluidSystem>
406{
407 const auto num_regions = 1; // we only support single region
408 updateNum("PLMIXNUM", plmixnum_, num_regions);
409}
410
411template<class GridView, class FluidSystem>
414{
415 const auto num_regions = eclState_.getTableManager().getTabdims().getNumSatTables();
416 updateNum("KRNUMX", krnumx_, num_regions);
417 updateNum("KRNUMY", krnumy_, num_regions);
418 updateNum("KRNUMZ", krnumz_, num_regions);
419}
420
421template<class GridView, class FluidSystem>
424{
425 const auto num_regions = eclState_.getTableManager().getTabdims().getNumSatTables();
426 updateNum("IMBNUMX", imbnumx_, num_regions);
427 updateNum("IMBNUMY", imbnumy_, num_regions);
428 updateNum("IMBNUMZ", imbnumz_, num_regions);
429}
430
431template<class GridView, class FluidSystem>
433vapparsActive(int episodeIdx) const
434{
435 const auto& oilVaporizationControl = schedule_[episodeIdx].oilvap();
436 return (oilVaporizationControl.getType() == OilVaporizationProperties::OilVaporization::VAPPARS);
437}
438
439template<class GridView, class FluidSystem>
441beginEpisode_(bool enableExperiments,
442 int episodeIdx)
443{
444 if (enableExperiments && gridView_.comm().rank() == 0 && episodeIdx >= 0) {
445 // print some useful information in experimental mode. (the production
446 // simulator does this externally.)
447 std::ostringstream ss;
448 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
449 boost::posix_time::ptime curDateTime =
450 boost::posix_time::from_time_t(schedule_.simTime(episodeIdx));
451 ss.imbue(std::locale(std::locale::classic(), facet));
452 ss << "Report step " << episodeIdx + 1
453 << "/" << schedule_.size() - 1
454 << " at day " << schedule_.seconds(episodeIdx)/(24*3600)
455 << "/" << schedule_.seconds(schedule_.size() - 1)/(24*3600)
456 << ", date = " << curDateTime.date()
457 << "\n ";
458 OpmLog::info(ss.str());
459 }
460
461 const auto& events = schedule_[episodeIdx].events();
462
463 // react to TUNING changes
464 if (episodeIdx > 0 && enableTuning_ && events.hasEvent(ScheduleEvents::TUNING_CHANGE))
465 {
466 const auto& sched_state = schedule_[episodeIdx];
467 const auto& tuning = sched_state.tuning();
468 initialTimeStepSize_ = sched_state.max_next_tstep(enableTuning_);
469 maxTimeStepAfterWellEvent_ = tuning.TMAXWC;
470 return true;
471 }
472
473 return false;
474}
475
476template<class GridView, class FluidSystem>
478beginTimeStep_(bool enableExperiments,
479 int episodeIdx,
480 int timeStepIndex,
481 Scalar startTime,
482 Scalar time,
483 Scalar timeStepSize,
484 Scalar endTime)
485{
486 if (enableExperiments && gridView_.comm().rank() == 0 && episodeIdx >= 0) {
487 std::ostringstream ss;
488 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
489 boost::posix_time::ptime date = boost::posix_time::from_time_t(startTime) + boost::posix_time::milliseconds(static_cast<long long>(time / prefix::milli));
490 ss.imbue(std::locale(std::locale::classic(), facet));
491 ss <<"\nTime step " << timeStepIndex << ", stepsize "
492 << unit::convert::to(timeStepSize, unit::day) << " days,"
493 << " at day " << (double)unit::convert::to(time, unit::day)
494 << "/" << (double)unit::convert::to(endTime, unit::day)
495 << ", date = " << date;
496 OpmLog::info(ss.str());
497 }
498
499 // update explicit quantities between timesteps.
500 this->mixControls_.updateExplicitQuantities(episodeIdx, timeStepSize);
501}
502
503template<class GridView, class FluidSystem>
506{
507 FluidSystem::initFromState(eclState_, schedule_);
508}
509
510template<class GridView, class FluidSystem>
513 bool enableSolvent,
514 bool enablePolymer,
515 bool enablePolymerMolarWeight,
516 bool enableMICP)
517{
518 if (enableSolvent) {
519 if (eclState_.fieldProps().has_double("SSOL"))
520 solventSaturation_ = eclState_.fieldProps().get_double("SSOL");
521 else
522 solventSaturation_.resize(numDof, 0.0);
523
524 //if (eclState_.fieldProps().has_double("SSOL"))
525 // solventRsw_ = eclState_.fieldProps().get_double("SSOL");
526 //else
527 solventRsw_.resize(numDof, 0.0);
528 }
529
530 if (enablePolymer) {
531 if (eclState_.fieldProps().has_double("SPOLY")) {
532 polymer_.concentration = eclState_.fieldProps().get_double("SPOLY");
533 } else {
534 polymer_.concentration.resize(numDof, 0.0);
535 }
536 }
537
538 if (enablePolymerMolarWeight) {
539 if (eclState_.fieldProps().has_double("SPOLYMW")) {
540 polymer_.moleWeight = eclState_.fieldProps().get_double("SPOLYMW");
541 } else {
542 polymer_.moleWeight.resize(numDof, 0.0);
543 }
544 }
545
546 if (enableMICP) {
547 if (eclState_.fieldProps().has_double("SMICR")) {
548 micp_.microbialConcentration = eclState_.fieldProps().get_double("SMICR");
549 } else {
550 micp_.microbialConcentration.resize(numDof, 0.0);
551 }
552 if (eclState_.fieldProps().has_double("SOXYG")) {
553 micp_.oxygenConcentration = eclState_.fieldProps().get_double("SOXYG");
554 } else {
555 micp_.oxygenConcentration.resize(numDof, 0.0);
556 }
557 if (eclState_.fieldProps().has_double("SUREA")) {
558 micp_.ureaConcentration = eclState_.fieldProps().get_double("SUREA");
559 } else {
560 micp_.ureaConcentration.resize(numDof, 0.0);
561 }
562 if (eclState_.fieldProps().has_double("SBIOF")) {
563 micp_.biofilmConcentration = eclState_.fieldProps().get_double("SBIOF");
564 } else {
565 micp_.biofilmConcentration.resize(numDof, 0.0);
566 }
567 if (eclState_.fieldProps().has_double("SCALC")) {
568 micp_.calciteConcentration = eclState_.fieldProps().get_double("SCALC");
569 } else {
570 micp_.calciteConcentration.resize(numDof, 0.0);
571 }
572 }
573}
574
575template<class GridView, class FluidSystem>
578maxWaterSaturation(unsigned globalDofIdx) const
579{
580 if (maxWaterSaturation_.empty())
581 return 0.0;
582
583 return maxWaterSaturation_[globalDofIdx];
584}
585
586template<class GridView, class FluidSystem>
589minOilPressure(unsigned globalDofIdx) const
590{
591 if (minRefPressure_.empty())
592 return 0.0;
593
594 return minRefPressure_[globalDofIdx];
595}
596
597template<class GridView, class FluidSystem>
600overburdenPressure(unsigned elementIdx) const
601{
602 if (overburdenPressure_.empty())
603 return 0.0;
604
605 return overburdenPressure_[elementIdx];
606}
607
608template<class GridView, class FluidSystem>
611solventSaturation(unsigned elemIdx) const
612{
613 if (solventSaturation_.empty())
614 return 0;
615
616 return solventSaturation_[elemIdx];
617}
618
619template<class GridView, class FluidSystem>
622solventRsw(unsigned elemIdx) const
623{
624 if (solventRsw_.empty())
625 return 0;
626
627 return solventRsw_[elemIdx];
628}
629
630template<class GridView, class FluidSystem>
633drsdtcon(unsigned elemIdx, int episodeIdx) const
634{
635 return this->mixControls_.drsdtcon(elemIdx, episodeIdx,
636 this->pvtRegionIndex(elemIdx));
637}
638
639template<class GridView, class FluidSystem>
642polymerConcentration(unsigned elemIdx) const
643{
644 if (polymer_.concentration.empty()) {
645 return 0;
646 }
647
648 return polymer_.concentration[elemIdx];
649}
650
651template<class GridView, class FluidSystem>
654polymerMolecularWeight(const unsigned elemIdx) const
655{
656 if (polymer_.moleWeight.empty()) {
657 return 0.0;
658 }
659
660 return polymer_.moleWeight[elemIdx];
661}
662
663template<class GridView, class FluidSystem>
666microbialConcentration(unsigned elemIdx) const
667{
668 if (micp_.microbialConcentration.empty()) {
669 return 0;
670 }
671
672 return micp_.microbialConcentration[elemIdx];
673}
674
675template<class GridView, class FluidSystem>
678oxygenConcentration(unsigned elemIdx) const
679{
680 if (micp_.oxygenConcentration.empty()) {
681 return 0;
682 }
683
684 return micp_.oxygenConcentration[elemIdx];
685}
686
687template<class GridView, class FluidSystem>
690ureaConcentration(unsigned elemIdx) const
691{
692 if (micp_.ureaConcentration.empty()) {
693 return 0;
694 }
695
696 return micp_.ureaConcentration[elemIdx];
697}
698
699template<class GridView, class FluidSystem>
702biofilmConcentration(unsigned elemIdx) const
703{
704 if (micp_.biofilmConcentration.empty()) {
705 return 0;
706 }
707
708 return micp_.biofilmConcentration[elemIdx];
709}
710
711template<class GridView, class FluidSystem>
714calciteConcentration(unsigned elemIdx) const
715{
716 if (micp_.calciteConcentration.empty()) {
717 return 0;
718 }
719
720 return micp_.calciteConcentration[elemIdx];
721}
722
723template<class GridView, class FluidSystem>
725pvtRegionIndex(unsigned elemIdx) const
726{
727 if (pvtnum_.empty())
728 return 0;
729
730 return pvtnum_[elemIdx];
731}
732
733template<class GridView, class FluidSystem>
735satnumRegionIndex(unsigned elemIdx) const
736{
737 if (satnum_.empty())
738 return 0;
739
740 return satnum_[elemIdx];
741}
742
743template<class GridView, class FluidSystem>
745miscnumRegionIndex(unsigned elemIdx) const
746{
747 if (miscnum_.empty())
748 return 0;
749
750 return miscnum_[elemIdx];
751}
752
753template<class GridView, class FluidSystem>
755plmixnumRegionIndex(unsigned elemIdx) const
756{
757 if (plmixnum_.empty())
758 return 0;
759
760 return plmixnum_[elemIdx];
761}
762
763template<class GridView, class FluidSystem>
766maxPolymerAdsorption(unsigned elemIdx) const
767{
768 if (polymer_.maxAdsorption.empty()) {
769 return 0;
770 }
771
772 return polymer_.maxAdsorption[elemIdx];
773}
774
775template<class GridView, class FluidSystem>
777operator==(const FlowGenericProblem& rhs) const
778{
779 return this->maxWaterSaturation_ == rhs.maxWaterSaturation_ &&
780 this->minRefPressure_ == rhs.minRefPressure_ &&
781 this->overburdenPressure_ == rhs.overburdenPressure_ &&
782 this->solventSaturation_ == rhs.solventSaturation_ &&
783 this->solventRsw_ == rhs.solventRsw_ &&
784 this->polymer_ == rhs.polymer_ &&
785 this->micp_ == rhs.micp_ &&
786 this->mixControls_ == rhs.mixControls_;
787}
788
789} // namespace Opm
790
791#endif // OPM_FLOW_GENERIC_PROBLEM_IMPL_HPP
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
Definition: FlowGenericProblem.hpp:70
UniformXTabulated2DFunction< Scalar > TabulatedTwoDFunction
Definition: FlowGenericProblem.hpp:73
Scalar maxPolymerAdsorption(unsigned elemIdx) const
Returns the max polymer adsorption value.
Definition: FlowGenericProblem_impl.hpp:766
unsigned pvtRegionIndex(unsigned elemIdx) const
Returns the index the relevant PVT region given a cell index.
Definition: FlowGenericProblem_impl.hpp:725
Scalar oxygenConcentration(unsigned elemIdx) const
Returns the initial oxygen concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:678
Scalar microbialConcentration(unsigned elemIdx) const
Returns the initial microbial concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:666
PolymerSolutionContainer< Scalar > polymer_
Definition: FlowGenericProblem.hpp:366
Scalar rockReferencePressure(unsigned globalSpaceIdx) const
Definition: FlowGenericProblem_impl.hpp:324
static std::string briefDescription()
Definition: FlowGenericProblem_impl.hpp:133
Scalar solventRsw(unsigned elemIdx) const
Returns the initial solvent dissolved in water for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:622
Scalar overburdenPressure(unsigned elementIdx) const
Get the pressure of the overburden.
Definition: FlowGenericProblem_impl.hpp:600
void updateMiscnum_()
Definition: FlowGenericProblem_impl.hpp:397
Scalar porosity(unsigned globalSpaceIdx, unsigned timeIdx) const
Direct indexed access to the porosity.
Definition: FlowGenericProblem_impl.hpp:339
Scalar rockCompressibility(unsigned globalSpaceIdx) const
Definition: FlowGenericProblem_impl.hpp:309
unsigned miscnumRegionIndex(unsigned elemIdx) const
Returns the index the relevant MISC region given a cell index.
Definition: FlowGenericProblem_impl.hpp:745
bool vapparsActive(int episodeIdx) const
Definition: FlowGenericProblem_impl.hpp:433
void updateImbnum_()
Definition: FlowGenericProblem_impl.hpp:423
unsigned satnumRegionIndex(unsigned elemIdx) const
Returns the index the relevant saturation function region given a cell index.
Definition: FlowGenericProblem_impl.hpp:735
Scalar rockFraction(unsigned elementIdx, unsigned timeIdx) const
Returns the rockFraction of an element.
Definition: FlowGenericProblem_impl.hpp:347
Scalar maxWaterSaturation(unsigned globalDofIdx) const
Returns an element's historic maximum water phase saturation that was observed during the simulation.
Definition: FlowGenericProblem_impl.hpp:578
std::vector< Scalar > solventSaturation_
Definition: FlowGenericProblem.hpp:371
void readRockCompactionParameters_()
Definition: FlowGenericProblem_impl.hpp:215
void updateSatnum_()
Definition: FlowGenericProblem_impl.hpp:389
void updatePvtnum_()
Definition: FlowGenericProblem_impl.hpp:381
static FlowGenericProblem serializationTestObject(const EclipseState &eclState, const Schedule &schedule, const GridView &gridView)
Definition: FlowGenericProblem_impl.hpp:97
void beginTimeStep_(bool enableExperiments, int episodeIdx, int timeStepIndex, Scalar startTime, Scalar time, Scalar timeStepSize, Scalar endTime)
Definition: FlowGenericProblem_impl.hpp:478
unsigned plmixnumRegionIndex(unsigned elemIdx) const
Returns the index the relevant PLMIXNUM (for polymer module) region given a cell index.
Definition: FlowGenericProblem_impl.hpp:755
FlowGenericProblem(const EclipseState &eclState, const Schedule &schedule, const GridView &gridView)
Definition: FlowGenericProblem_impl.hpp:83
Scalar solventSaturation(unsigned elemIdx) const
Returns the initial solvent saturation for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:611
Scalar polymerMolecularWeight(const unsigned elemIdx) const
Returns the polymer molecule weight for a given cell index.
Definition: FlowGenericProblem_impl.hpp:654
Scalar biofilmConcentration(unsigned elemIdx) const
Returns the initial biofilm concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:702
MICPSolutionContainer< Scalar > micp_
Definition: FlowGenericProblem.hpp:373
MixingRateControls< FluidSystem > mixControls_
Definition: FlowGenericProblem.hpp:375
void readRockParameters_(const std::vector< Scalar > &cellCenterDepths, std::function< std::array< int, 3 >(const unsigned)> ijkIndex)
Definition: FlowGenericProblem_impl.hpp:140
std::vector< Scalar > maxOilSaturation_
Definition: FlowGenericProblem.hpp:367
void readBlackoilExtentionsInitialConditions_(std::size_t numDof, bool enableSolvent, bool enablePolymer, bool enablePolymerMolarWeight, bool enableMICP)
Definition: FlowGenericProblem_impl.hpp:512
Scalar minOilPressure(unsigned globalDofIdx) const
Returns an element's historic minimum pressure of the oil phase that was observed during the simulati...
Definition: FlowGenericProblem_impl.hpp:589
std::vector< Scalar > maxWaterSaturation_
Definition: FlowGenericProblem.hpp:368
void initFluidSystem_()
Definition: FlowGenericProblem_impl.hpp:505
bool operator==(const FlowGenericProblem &rhs) const
Definition: FlowGenericProblem_impl.hpp:777
Scalar calciteConcentration(unsigned elemIdx) const
Returns the initial calcite concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:714
Scalar ureaConcentration(unsigned elemIdx) const
Returns the initial urea concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:690
std::vector< Scalar > minRefPressure_
Definition: FlowGenericProblem.hpp:369
bool beginEpisode_(bool enableExperiments, int episodeIdx)
Definition: FlowGenericProblem_impl.hpp:441
std::vector< Scalar > solventRsw_
Definition: FlowGenericProblem.hpp:372
static std::string helpPreamble(int, const char **argv)
Definition: FlowGenericProblem_impl.hpp:118
std::vector< Scalar > overburdenPressure_
Definition: FlowGenericProblem.hpp:370
void updatePlmixnum_()
Definition: FlowGenericProblem_impl.hpp:405
typename FluidSystem::Scalar Scalar
Definition: FlowGenericProblem.hpp:72
Scalar drsdtcon(unsigned elemIdx, int episodeIdx) const
Returns the dynamic drsdt convective mixing value.
Definition: FlowGenericProblem_impl.hpp:633
void updateKrnum_()
Definition: FlowGenericProblem_impl.hpp:413
Scalar polymerConcentration(unsigned elemIdx) const
Returns the initial polymer concentration for a given a cell index.
Definition: FlowGenericProblem_impl.hpp:642
static MixingRateControls serializationTestObject(const Schedule &schedule)
Definition: BlackoilPhases.hpp:27
std::string to_string(const ConvergenceReport::ReservoirFailure::Type t)
int eclPositionalParameter(Dune::ParameterTree &tree, std::set< std::string > &seenParams, std::string &errorMsg, const char **argv, int paramIdx)
Definition: FlowGenericProblem_impl.hpp:48
static MICPSolutionContainer serializationTestObject()
static PolymerSolutionContainer serializationTestObject()