opm-simulators
Loading...
Searching...
No Matches
FlowGenericProblem_impl.hpp
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#ifndef OPM_FLOW_GENERIC_PROBLEM_HPP
27#include <config.h>
29#endif
30
31#include <dune/common/parametertree.hh>
32
33#include <opm/input/eclipse/EclipseState/EclipseState.hpp>
34#include <opm/input/eclipse/EclipseState/Tables/OverburdTable.hpp>
35#include <opm/input/eclipse/EclipseState/Tables/RockwnodTable.hpp>
36#include <opm/input/eclipse/Schedule/Schedule.hpp>
37#include <opm/input/eclipse/Units/Units.hpp>
38
42
45
46#include <opm/simulators/timestepping/EclTimeSteppingParams.hpp>
47
48#include <boost/date_time.hpp>
49
50#include <fmt/format.h>
51#include <fmt/ranges.h>
52
53#include <iostream>
54#include <stdexcept>
55
56namespace Opm {
57
58template<class GridView, class FluidSystem>
60FlowGenericProblem(const EclipseState& eclState,
61 const Schedule& schedule,
62 const GridView& gridView)
63 : eclState_(eclState)
64 , schedule_(schedule)
65 , gridView_(gridView)
66 , lookUpData_(gridView)
67{
68 // we need to update the FluidSystem based on EclipseState before it is passed around
69 this->initFluidSystem_();
70
71 enableTuning_ = Parameters::Get<Parameters::EnableTuning>();
72 enableDriftCompensation_ = Parameters::Get<Parameters::EnableDriftCompensation>();
73 initialTimeStepSize_ = Parameters::Get<Parameters::InitialTimeStepSize<Scalar>>();
74 maxTimeStepAfterWellEvent_ = unit::convert::from
75 (Parameters::Get<Parameters::TimeStepAfterEventInDays<Scalar>>(), unit::day);
76
77 // The value N for this parameter is defined in the following order of precedence:
78 //
79 // 1. Command line value (--num-pressure-points-equil=N)
80 //
81 // 2. EQLDIMS item 2. Default value from
82 // opm-common/opm/input/eclipse/share/keywords/000_Eclipse100/E/EQLDIMS
83
84 numPressurePointsEquil_ = Parameters::IsSet<Parameters::NumPressurePointsEquil>()
85 ? Parameters::Get<Parameters::NumPressurePointsEquil>()
86 : eclState.getTableManager().getEqldims().getNumDepthNodesP();
87
88 explicitRockCompaction_ = Parameters::Get<Parameters::ExplicitRockCompaction>();
89}
90
91template<class GridView, class FluidSystem>
92FlowGenericProblem<GridView,FluidSystem>
93FlowGenericProblem<GridView,FluidSystem>::
94serializationTestObject(const EclipseState& eclState,
95 const Schedule& schedule,
96 const GridView& gridView)
97{
98 FlowGenericProblem result(eclState, schedule, gridView);
99 result.maxOilSaturation_ = {1.0, 2.0};
100 result.maxWaterSaturation_ = {6.0};
101 result.minRefPressure_ = {7.0, 8.0, 9.0, 10.0};
102 result.overburdenPressure_ = {11.0};
103 result.solventSaturation_ = {15.0};
104 result.solventRsw_ = {18.0};
105 result.polymer_ = PolymerSolutionContainer<Scalar>::serializationTestObject();
106 result.bioeffects_ = BioeffectsSolutionContainer<Scalar>::serializationTestObject();
107 result.CO2H2_ = CO2H2SolutionContainer<Scalar>::serializationTestObject();
108
109 return result;
110}
111
112template<class GridView, class FluidSystem>
113std::string
114FlowGenericProblem<GridView,FluidSystem>::
115helpPreamble(int,
116 const char **argv)
117{
118 std::string desc = FlowGenericProblem::briefDescription();
119 if (!desc.empty())
120 desc = desc + "\n";
121
122 return
123 "Usage: "+std::string(argv[0]) + " [OPTIONS] [ECL_DECK_FILENAME]\n"
124 + desc;
125}
126
127template<class GridView, class FluidSystem>
128std::string
129FlowGenericProblem<GridView,FluidSystem>::
130briefDescription()
131{
132 return briefDescription_;
133}
134
135template<class GridView, class FluidSystem>
137readRockParameters_(const std::vector<Scalar>& cellCenterDepths,
138 std::function<std::array<int,3>(const unsigned)> ijkIndex)
139{
140 const auto& rock_config = eclState_.getSimulationConfig().rock_config();
141
142 // read the rock compressibility parameters
143 {
144 const auto& comp = rock_config.comp();
145 rockParams_.clear();
146 std::ranges::transform(comp, std::back_inserter(rockParams_),
147 [](const auto& c)
148 {
149 return RockParams{
150 static_cast<Scalar>(c.pref),
151 static_cast<Scalar>(c.compressibility)
152 };
153 });
154 }
155
156 // Warn that ROCK and ROCKOPTS item 2 = STORE is used together
157 if (rock_config.store()) {
158 OpmLog::warning("ROCKOPTS item 2 set to STORE, ROCK item 1 replaced with initial (equilibrated) pressures");
159 }
160
161 // read the parameters for water-induced rock compaction
162 readRockCompactionParameters_();
163
164 unsigned numElem = gridView_.size(0);
165 if (eclState_.fieldProps().has_int(rock_config.rocknum_property())) {
166 // Auxiliary function to check rockTableIdx_ values belong to the right range. Otherwise, throws.
167 std::function<void(int, int)> valueCheck = [&ijkIndex,&rock_config,this](int fieldPropValue, int coarseElemIdx)
168 {
169 auto fmtError = [fieldPropValue, coarseElemIdx,&ijkIndex,&rock_config](const char* type, std::size_t size)
170 {
171 return fmt::format("{} table index {} for elem {} read from {}"
172 " is out of bounds for number of tables {}",
173 type, fieldPropValue,
174 ijkIndex(coarseElemIdx),
175 rock_config.rocknum_property(), size);
176 };
177 if (!rockCompPoroMult_.empty() &&
178 fieldPropValue > static_cast<int>(rockCompPoroMult_.size())) {
179 throw std::runtime_error(fmtError("Rock compaction",
180 rockCompPoroMult_.size()));
181 }
182 if (!rockCompPoroMultWc_.empty() &&
183 fieldPropValue > static_cast<int>(rockCompPoroMultWc_.size())) {
184 throw std::runtime_error(fmtError("Rock water compaction",
185 rockCompPoroMultWc_.size()));
186 }
187 };
188
189 rockTableIdx_ = this->lookUpData_.template assignFieldPropsIntOnLeaf<short unsigned int>(eclState_.fieldProps(),
190 rock_config.rocknum_property(),
191 true /*needsTranslation*/,
192 valueCheck);
193 }
194
195 // Store overburden pressure pr element
196 const auto& overburdTables = eclState_.getTableManager().getOverburdTables();
197 if (!overburdTables.empty() && !rock_config.store()) {
198 overburdenPressure_.resize(numElem,0.0);
199 std::size_t numRocktabTables = rock_config.num_rock_tables();
200
201 if (overburdTables.size() != numRocktabTables)
202 throw std::runtime_error(fmt::format("{} OVERBURD tables is expected, but {} is provided",
203 numRocktabTables, overburdTables.size()));
204
205 std::vector<Tabulated1DFunction<Scalar>> overburdenTables(numRocktabTables);
206 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
207 const OverburdTable& overburdTable = overburdTables.template getTable<OverburdTable>(regionIdx);
208 overburdenTables[regionIdx].setXYContainers(overburdTable.getDepthColumn(),overburdTable.getOverburdenPressureColumn());
209 }
210
211 for (std::size_t elemIdx = 0; elemIdx < numElem; ++ elemIdx) {
212 unsigned tableIdx = 0;
213 if (!rockTableIdx_.empty()) {
214 tableIdx = rockTableIdx_[elemIdx];
215 }
216 overburdenPressure_[elemIdx] =
217 overburdenTables[tableIdx].eval(cellCenterDepths[elemIdx], /*extrapolation=*/true);
218 }
219 }
220 else if (!overburdTables.empty() && rock_config.store()) {
221 OpmLog::warning("ROCKOPTS item 2 set to STORE, OVERBURD ignored!");
222 }
223}
224
225template<class GridView, class FluidSystem>
226void FlowGenericProblem<GridView,FluidSystem>::
227readRockCompactionParameters_()
228{
229 const auto& rock_config = eclState_.getSimulationConfig().rock_config();
230
231 if (!rock_config.active())
232 return; // deck does not enable rock compaction
233
234 unsigned numElem = gridView_.size(0);
235 switch (rock_config.hysteresis_mode()) {
236 case RockConfig::Hysteresis::REVERS:
237 break;
238 case RockConfig::Hysteresis::IRREVERS:
239 // interpolate the porv volume multiplier using the minimum pressure in the cell
240 // i.e. don't allow re-inflation.
241 minRefPressure_.resize(numElem, 1e99);
242 break;
243 default:
244 throw std::runtime_error("Not support ROCKOMP hysteresis option ");
245 }
246
247 std::size_t numRocktabTables = rock_config.num_rock_tables();
248 bool waterCompaction = rock_config.water_compaction();
249
250 if (!waterCompaction) {
251 const auto& rocktabTables = eclState_.getTableManager().getRocktabTables();
252 if (rocktabTables.size() != numRocktabTables)
253 throw std::runtime_error("ROCKCOMP is activated." + std::to_string(numRocktabTables)
254 +" ROCKTAB tables is expected, but " + std::to_string(rocktabTables.size()) +" is provided");
255
256 rockCompPoroMult_.resize(numRocktabTables);
257 rockCompTransMult_.resize(numRocktabTables);
258 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
259 const auto& rocktabTable = rocktabTables.template getTable<RocktabTable>(regionIdx);
260 const auto& pressureColumn = rocktabTable.getPressureColumn();
261 const auto& poroColumn = rocktabTable.getPoreVolumeMultiplierColumn();
262 const auto& transColumn = rocktabTable.getTransmissibilityMultiplierColumn();
263 rockCompPoroMult_[regionIdx].setXYContainers(pressureColumn, poroColumn);
264 rockCompTransMult_[regionIdx].setXYContainers(pressureColumn, transColumn);
265 }
266 } else {
267 const auto& rock2dTables = eclState_.getTableManager().getRock2dTables();
268 const auto& rock2dtrTables = eclState_.getTableManager().getRock2dtrTables();
269 const auto& rockwnodTables = eclState_.getTableManager().getRockwnodTables();
270 maxWaterSaturation_.resize(numElem, 0.0);
271
272 if (rock2dTables.size() != numRocktabTables)
273 throw std::runtime_error(fmt::format("Water compation option is selected in ROCKCOMP."
274 " {} ROCK2D tables is expected, but {} is provided",
275 numRocktabTables, rock2dTables.size()));
276
277 if (rockwnodTables.size() != numRocktabTables)
278 throw std::runtime_error(fmt::format("Water compation option is selected in ROCKCOMP."
279 " {} ROCKWNOD tables is expected, but {} is provided",
280 numRocktabTables, rockwnodTables.size()));
281 //TODO check size match
282 rockCompPoroMultWc_.resize(numRocktabTables, TabulatedTwoDFunction(TabulatedTwoDFunction::InterpolationPolicy::Vertical));
283 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
284 const RockwnodTable& rockwnodTable = rockwnodTables.template getTable<RockwnodTable>(regionIdx);
285 const auto& rock2dTable = rock2dTables[regionIdx];
286
287 if (rockwnodTable.getSaturationColumn().size() != rock2dTable.sizeMultValues())
288 throw std::runtime_error("Number of entries in ROCKWNOD and ROCK2D needs to match.");
289
290 for (std::size_t xIdx = 0; xIdx < rock2dTable.size(); ++xIdx) {
291 rockCompPoroMultWc_[regionIdx].appendXPos(rock2dTable.getPressureValue(xIdx));
292 for (std::size_t yIdx = 0; yIdx < rockwnodTable.getSaturationColumn().size(); ++yIdx)
293 rockCompPoroMultWc_[regionIdx].appendSamplePoint(xIdx,
294 rockwnodTable.getSaturationColumn()[yIdx],
295 rock2dTable.getPvmultValue(xIdx, yIdx));
296 }
297 }
298
299 if (!rock2dtrTables.empty()) {
300 rockCompTransMultWc_.resize(numRocktabTables, TabulatedTwoDFunction(TabulatedTwoDFunction::InterpolationPolicy::Vertical));
301 for (std::size_t regionIdx = 0; regionIdx < numRocktabTables; ++regionIdx) {
302 const RockwnodTable& rockwnodTable = rockwnodTables.template getTable<RockwnodTable>(regionIdx);
303 const auto& rock2dtrTable = rock2dtrTables[regionIdx];
304
305 if (rockwnodTable.getSaturationColumn().size() != rock2dtrTable.sizeMultValues())
306 throw std::runtime_error("Number of entries in ROCKWNOD and ROCK2DTR needs to match.");
307
308 for (std::size_t xIdx = 0; xIdx < rock2dtrTable.size(); ++xIdx) {
309 rockCompTransMultWc_[regionIdx].appendXPos(rock2dtrTable.getPressureValue(xIdx));
310 for (std::size_t yIdx = 0; yIdx < rockwnodTable.getSaturationColumn().size(); ++yIdx)
311 rockCompTransMultWc_[regionIdx].appendSamplePoint(xIdx,
312 rockwnodTable.getSaturationColumn()[yIdx],
313 rock2dtrTable.getTransMultValue(xIdx, yIdx));
314 }
315 }
316 }
317 }
318}
319
320template<class GridView, class FluidSystem>
321typename FlowGenericProblem<GridView,FluidSystem>::Scalar
322FlowGenericProblem<GridView,FluidSystem>::
323rockCompressibility(unsigned globalSpaceIdx) const
324{
325 if (this->rockParams_.empty())
326 return 0.0;
327
328 unsigned tableIdx = 0;
329 if (!this->rockTableIdx_.empty()) {
330 tableIdx = this->rockTableIdx_[globalSpaceIdx];
331 }
332 return this->rockParams_[tableIdx].compressibility;
333}
334
335template<class GridView, class FluidSystem>
336typename FlowGenericProblem<GridView,FluidSystem>::Scalar
337FlowGenericProblem<GridView,FluidSystem>::
338porosity(unsigned globalSpaceIdx, unsigned timeIdx) const
339{
340 return this->referencePorosity_[timeIdx][globalSpaceIdx];
341}
342
343template<class GridView, class FluidSystem>
344template<class T>
346updateNum(const std::string& name, std::vector<T>& numbers, std::size_t num_regions)
347{
348 if (!eclState_.fieldProps().has_int(name))
349 return;
350
351 std::function<void(T, int)> valueCheck = [num_regions,name](T fieldPropValue, [[maybe_unused]] int fieldPropIdx) {
352 if (fieldPropValue > static_cast<int>(num_regions)) {
353 throw std::runtime_error(fmt::format("Values larger than maximum number of regions {} provided in {}",
354 num_regions, name));
355 }
356 if (fieldPropValue <= 0) {
357 throw std::runtime_error("zero or negative values provided for region array: " + name);
358 }
359 };
360
361 numbers = this->lookUpData_.template assignFieldPropsIntOnLeaf<T>(eclState_.fieldProps(), name,
362 true /*needsTranslation*/, valueCheck);
363}
364
365template<class GridView, class FluidSystem>
366void FlowGenericProblem<GridView,FluidSystem>::
367updatePvtnum_()
368{
369 const auto num_regions = eclState_.getTableManager().getTabdims().getNumPVTTables();
370 updateNum("PVTNUM", pvtnum_, num_regions);
371}
372
373template<class GridView, class FluidSystem>
374void FlowGenericProblem<GridView,FluidSystem>::
375updateSatnum_()
376{
377 const auto num_regions = eclState_.getTableManager().getTabdims().getNumSatTables();
378 updateNum("SATNUM", satnum_, num_regions);
379}
380
381template<class GridView, class FluidSystem>
382void FlowGenericProblem<GridView,FluidSystem>::
383updateMiscnum_()
384{
385 const auto num_regions = 1; // we only support single region
386 updateNum("MISCNUM", miscnum_, num_regions);
387}
388
389template<class GridView, class FluidSystem>
390void FlowGenericProblem<GridView,FluidSystem>::
391updatePlmixnum_()
392{
393 const auto num_regions = 1; // we only support single region
394 updateNum("PLMIXNUM", plmixnum_, num_regions);
395}
396
397template<class GridView, class FluidSystem>
398bool FlowGenericProblem<GridView,FluidSystem>::
399vapparsActive(int episodeIdx) const
400{
401 const auto& oilVaporizationControl = schedule_[episodeIdx].oilvap();
402 return (oilVaporizationControl.getType() == OilVaporizationProperties::OilVaporization::VAPPARS);
403}
404
405template<class GridView, class FluidSystem>
406bool FlowGenericProblem<GridView,FluidSystem>::
407beginEpisode_(bool enableExperiments,
408 int episodeIdx)
409{
410 if (enableExperiments && gridView_.comm().rank() == 0 && episodeIdx >= 0) {
411 // print some useful information in experimental mode. (the production
412 // simulator does this externally.)
413 std::ostringstream ss;
414 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
415 boost::posix_time::ptime curDateTime =
416 boost::posix_time::from_time_t(schedule_.simTime(episodeIdx));
417 ss.imbue(std::locale(std::locale::classic(), facet));
418 ss << "Report step " << episodeIdx + 1
419 << "/" << schedule_.size() - 1
420 << " at day " << schedule_.seconds(episodeIdx)/(24*3600)
421 << "/" << schedule_.seconds(schedule_.size() - 1)/(24*3600)
422 << ", date = " << curDateTime.date()
423 << "\n ";
424 OpmLog::info(ss.str());
425 }
426
427 const auto& events = schedule_[episodeIdx].events();
428
429 // react to TUNING changes
430 if (episodeIdx > 0 && enableTuning_ && events.hasEvent(ScheduleEvents::TUNING_CHANGE))
431 {
432 const auto& sched_state = schedule_[episodeIdx];
433 const auto& tuning = sched_state.tuning();
434 initialTimeStepSize_ = sched_state.max_next_tstep(enableTuning_);
435 maxTimeStepAfterWellEvent_ = tuning.TMAXWC;
436 return true;
437 }
438
439 return false;
440}
441
442template<class GridView, class FluidSystem>
443void FlowGenericProblem<GridView,FluidSystem>::
444beginTimeStep_(bool enableExperiments,
445 int episodeIdx,
446 int timeStepIndex,
447 Scalar startTime,
448 Scalar time,
449 Scalar timeStepSize,
450 Scalar endTime)
451{
452 if (enableExperiments && gridView_.comm().rank() == 0 && episodeIdx >= 0) {
453 std::ostringstream ss;
454 boost::posix_time::time_facet* facet = new boost::posix_time::time_facet("%d-%b-%Y");
455 boost::posix_time::ptime date = boost::posix_time::from_time_t(startTime) +
456 boost::posix_time::milliseconds(static_cast<long long>(time / prefix::milli));
457 ss.imbue(std::locale(std::locale::classic(), facet));
458 ss <<"\nTime step " << timeStepIndex << ", stepsize "
459 << unit::convert::to(timeStepSize, unit::day) << " days,"
460 << " at day " << (double)unit::convert::to(time, unit::day)
461 << "/" << (double)unit::convert::to(endTime, unit::day)
462 << ", date = " << date;
463 OpmLog::info(ss.str());
464 }
465}
466
467template<class GridView, class FluidSystem>
468void FlowGenericProblem<GridView,FluidSystem>::
469initFluidSystem_()
470{
471 FluidSystem::initFromState(eclState_, schedule_);
472}
473
474template<class GridView, class FluidSystem>
475void FlowGenericProblem<GridView,FluidSystem>::
476readBlackoilExtentionsInitialConditions_(std::size_t numDof,
477 bool enableSolvent,
478 bool enablePolymer,
479 bool enablePolymerMolarWeight,
480 bool enableBioeffects,
481 bool enableMICP)
482{
483 auto getArray = [](const std::vector<double>& input)
484 {
485 if constexpr (std::is_same_v<Scalar,double>) {
486 return input;
487 } else {
488 return std::vector<Scalar>{input.begin(), input.end()};
489 }
490 };
491
492 if (enableSolvent) {
493 if (eclState_.fieldProps().has_double("SSOL")) {
494 solventSaturation_ = getArray(eclState_.fieldProps().get_double("SSOL"));
495 } else {
496 solventSaturation_.resize(numDof, 0.0);
497 }
498
499 solventRsw_.resize(numDof, 0.0);
500 }
501
502 if (enablePolymer) {
503 if (eclState_.fieldProps().has_double("SPOLY")) {
504 polymer_.concentration = getArray(eclState_.fieldProps().get_double("SPOLY"));
505 } else {
506 polymer_.concentration.resize(numDof, 0.0);
507 }
508 }
509
510 if (enablePolymerMolarWeight) {
511 if (eclState_.fieldProps().has_double("SPOLYMW")) {
512 polymer_.moleWeight = getArray(eclState_.fieldProps().get_double("SPOLYMW"));
513 } else {
514 polymer_.moleWeight.resize(numDof, 0.0);
515 }
516 }
517
518 if (enableBioeffects) {
519 if (eclState_.fieldProps().has_double("SMICR")) {
520 bioeffects_.microbialConcentration = getArray(eclState_.fieldProps().get_double("SMICR"));
521 } else {
522 bioeffects_.microbialConcentration.resize(numDof, 0.0);
523 }
524 if (eclState_.fieldProps().has_double("SBIOF")) {
525 bioeffects_.biofilmVolumeFraction = getArray(eclState_.fieldProps().get_double("SBIOF"));
526 } else {
527 bioeffects_.biofilmVolumeFraction.resize(numDof, 0.0);
528 }
529 if (enableMICP) {
530 if (eclState_.fieldProps().has_double("SOXYG")) {
531 bioeffects_.oxygenConcentration = getArray(eclState_.fieldProps().get_double("SOXYG"));
532 } else {
533 bioeffects_.oxygenConcentration.resize(numDof, 0.0);
534 }
535 if (eclState_.fieldProps().has_double("SUREA")) {
536 bioeffects_.ureaConcentration = getArray(eclState_.fieldProps().get_double("SUREA"));
537 } else {
538 bioeffects_.ureaConcentration.resize(numDof, 0.0);
539 }
540 if (eclState_.fieldProps().has_double("SCALC")) {
541 bioeffects_.calciteVolumeFraction = getArray(eclState_.fieldProps().get_double("SCALC"));
542 } else {
543 bioeffects_.calciteVolumeFraction.resize(numDof, 0.0);
544 }
545 }
546 }
547}
548
549template<class GridView, class FluidSystem>
550typename FlowGenericProblem<GridView,FluidSystem>::Scalar
551FlowGenericProblem<GridView,FluidSystem>::
552maxWaterSaturation(unsigned globalDofIdx) const
553{
554 if (maxWaterSaturation_.empty())
555 return 0.0;
556
557 return maxWaterSaturation_[globalDofIdx];
558}
559
560template<class GridView, class FluidSystem>
561typename FlowGenericProblem<GridView,FluidSystem>::Scalar
562FlowGenericProblem<GridView,FluidSystem>::
563minOilPressure(unsigned globalDofIdx) const
564{
565 if (minRefPressure_.empty())
566 return 0.0;
567
568 return minRefPressure_[globalDofIdx];
569}
570
571template<class GridView, class FluidSystem>
572typename FlowGenericProblem<GridView,FluidSystem>::Scalar
573FlowGenericProblem<GridView,FluidSystem>::
574overburdenPressure(unsigned elementIdx) const
575{
576 if (overburdenPressure_.empty())
577 return 0.0;
578
579 return overburdenPressure_[elementIdx];
580}
581
582template<class GridView, class FluidSystem>
583typename FlowGenericProblem<GridView,FluidSystem>::Scalar
584FlowGenericProblem<GridView,FluidSystem>::
585solventSaturation(unsigned elemIdx) const
586{
587 if (solventSaturation_.empty())
588 return 0;
589
590 return solventSaturation_[elemIdx];
591}
592
593template<class GridView, class FluidSystem>
594typename FlowGenericProblem<GridView,FluidSystem>::Scalar
595FlowGenericProblem<GridView,FluidSystem>::
596solventRsw(unsigned elemIdx) const
597{
598 if (solventRsw_.empty())
599 return 0;
600
601 return solventRsw_[elemIdx];
602}
603
604
605
606template<class GridView, class FluidSystem>
607typename FlowGenericProblem<GridView,FluidSystem>::Scalar
608FlowGenericProblem<GridView,FluidSystem>::
609polymerConcentration(unsigned elemIdx) const
610{
611 if (polymer_.concentration.empty()) {
612 return 0;
613 }
614
615 return polymer_.concentration[elemIdx];
616}
617
618template<class GridView, class FluidSystem>
619typename FlowGenericProblem<GridView,FluidSystem>::Scalar
620FlowGenericProblem<GridView,FluidSystem>::
621polymerMolecularWeight(const unsigned elemIdx) const
622{
623 if (polymer_.moleWeight.empty()) {
624 return 0.0;
625 }
626
627 return polymer_.moleWeight[elemIdx];
628}
629
630template<class GridView, class FluidSystem>
631typename FlowGenericProblem<GridView,FluidSystem>::Scalar
632FlowGenericProblem<GridView,FluidSystem>::
633microbialConcentration(unsigned elemIdx) const
634{
635 if (bioeffects_.microbialConcentration.empty()) {
636 return 0;
637 }
638
639 return bioeffects_.microbialConcentration[elemIdx];
640}
641
642template<class GridView, class FluidSystem>
643typename FlowGenericProblem<GridView,FluidSystem>::Scalar
644FlowGenericProblem<GridView,FluidSystem>::
645oxygenConcentration(unsigned elemIdx) const
646{
647 if (bioeffects_.oxygenConcentration.empty()) {
648 return 0;
649 }
650
651 return bioeffects_.oxygenConcentration[elemIdx];
652}
653
654template<class GridView, class FluidSystem>
655typename FlowGenericProblem<GridView,FluidSystem>::Scalar
656FlowGenericProblem<GridView,FluidSystem>::
657ureaConcentration(unsigned elemIdx) const
658{
659 if (bioeffects_.ureaConcentration.empty()) {
660 return 0;
661 }
662
663 return bioeffects_.ureaConcentration[elemIdx];
664}
665
666template<class GridView, class FluidSystem>
667typename FlowGenericProblem<GridView,FluidSystem>::Scalar
668FlowGenericProblem<GridView,FluidSystem>::
669biofilmVolumeFraction(unsigned elemIdx) const
670{
671 if (bioeffects_.biofilmVolumeFraction.empty()) {
672 return 0;
673 }
674
675 return bioeffects_.biofilmVolumeFraction[elemIdx];
676}
677
678template<class GridView, class FluidSystem>
679typename FlowGenericProblem<GridView,FluidSystem>::Scalar
680FlowGenericProblem<GridView,FluidSystem>::
681calciteVolumeFraction(unsigned elemIdx) const
682{
683 if (bioeffects_.calciteVolumeFraction.empty()) {
684 return 0;
685 }
686
687 return bioeffects_.calciteVolumeFraction[elemIdx];
688}
689
690template<class GridView, class FluidSystem>
691unsigned FlowGenericProblem<GridView,FluidSystem>::
692pvtRegionIndex(unsigned elemIdx) const
693{
694 if (pvtnum_.empty())
695 return 0;
696
697 return pvtnum_[elemIdx];
698}
699
700template<class GridView, class FluidSystem>
701unsigned FlowGenericProblem<GridView,FluidSystem>::
702satnumRegionIndex(unsigned elemIdx) const
703{
704 if (satnum_.empty())
705 return 0;
706
707 return satnum_[elemIdx];
708}
709
710template<class GridView, class FluidSystem>
711unsigned FlowGenericProblem<GridView,FluidSystem>::
712miscnumRegionIndex(unsigned elemIdx) const
713{
714 if (miscnum_.empty())
715 return 0;
716
717 return miscnum_[elemIdx];
718}
719
720template<class GridView, class FluidSystem>
721unsigned FlowGenericProblem<GridView,FluidSystem>::
722plmixnumRegionIndex(unsigned elemIdx) const
723{
724 if (plmixnum_.empty())
725 return 0;
726
727 return plmixnum_[elemIdx];
728}
729
730template<class GridView, class FluidSystem>
731typename FlowGenericProblem<GridView,FluidSystem>::Scalar
732FlowGenericProblem<GridView,FluidSystem>::
733maxPolymerAdsorption(unsigned elemIdx) const
734{
735 if (polymer_.maxAdsorption.empty()) {
736 return 0;
737 }
738
739 return polymer_.maxAdsorption[elemIdx];
740}
741
742template<class GridView, class FluidSystem>
744operator==(const FlowGenericProblem& rhs) const
745{
746 return this->maxWaterSaturation_ == rhs.maxWaterSaturation_ &&
747 this->minRefPressure_ == rhs.minRefPressure_ &&
748 this->overburdenPressure_ == rhs.overburdenPressure_ &&
749 this->solventSaturation_ == rhs.solventSaturation_ &&
750 this->solventRsw_ == rhs.solventRsw_ &&
751 this->polymer_ == rhs.polymer_ &&
752 this->bioeffects_ == rhs.bioeffects_;
753}
754
755} // namespace Opm
756
757#endif // OPM_FLOW_GENERIC_PROBLEM_IMPL_HPP
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
Defines some fundamental parameters for all models.
This problem simulates an input file given in the data format used by the commercial ECLiPSE simulato...
Definition FlowGenericProblem.hpp:61
static std::string briefDescription()
Returns a human readable description of the problem for the help message.
Definition FlowGenericProblem_impl.hpp:130
Declare the properties used by the infrastructure code of the finite volume discretizations.
This file contains a set of helper functions used by VFPProd / VFPInj.
Definition blackoilbioeffectsmodules.hh:45
This file provides the infrastructure to retrieve run-time parameters.