22#include <opm/input/eclipse/EclipseState/Grid/Box.hpp>
23#include <opm/input/eclipse/EclipseState/Grid/FieldData.hpp>
24#include <opm/input/eclipse/EclipseState/Grid/Keywords.hpp>
25#include <opm/input/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp>
26#include <opm/input/eclipse/EclipseState/Grid/TranCalculator.hpp>
27#include <opm/input/eclipse/EclipseState/Runspec.hpp>
28#include <opm/input/eclipse/EclipseState/Util/OrderedMap.hpp>
29#include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp>
31#include <opm/input/eclipse/Units/UnitSystem.hpp>
33#include <opm/input/eclipse/Deck/DeckSection.hpp>
34#include <opm/input/eclipse/Deck/value_status.hpp>
45#include <unordered_map>
46#include <unordered_set>
54class NumericalAquifers;
103inline bool isFipxxx(
const std::string& keyword) {
106 if (keyword.size() < 4 || keyword ==
"FIPOWG") {
109 return keyword[0] ==
'F' && keyword[1] ==
'I' && keyword[2] ==
'P';
128 static const std::unordered_map<std::string, std::string> aliased_keywords = {{
"PERMR",
"PERMX"},
129 {
"PERMTHT",
"PERMY"}};
134static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"DISPERC",keyword_info<double>{}.unit_string(
"Length")},
135 {
"MINPVV", keyword_info<double>{}.unit_string(
"ReservoirVolume").global_kw(
true)},
136 {
"MULTPV", keyword_info<double>{}.init(1.0)},
137 {
"NTG", keyword_info<double>{}.init(1.0)},
138 {
"PORO", keyword_info<double>{}.distribute_top(
true)},
139 {
"PERMX", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
140 {
"PERMY", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
141 {
"PERMZ", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
142 {
"PERMR", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
143 {
"PERMTHT", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
144 {
"TEMPI", keyword_info<double>{}.unit_string(
"Temperature")},
145 {
"THCONR", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
146 {
"THCONSF", keyword_info<double>{}},
147 {
"HEATCR", keyword_info<double>{}.unit_string(
"Energy/ReservoirVolume*AbsoluteTemperature")},
148 {
"HEATCRT", keyword_info<double>{}.unit_string(
"Energy/ReservoirVolume*AbsoluteTemperature*AbsoluteTemperature")},
149 {
"THCROCK", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
150 {
"THCOIL", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
151 {
"THCGAS", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
152 {
"THCWATER",keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
153 {
"YMODULE", keyword_info<double>{}.unit_string(
"Giga*Pascal")},
154 {
"PRATIO", keyword_info<double>{}.unit_string(
"1")},
155 {
"BIOTCOEF", keyword_info<double>{}.unit_string(
"1")},
156 {
"POELCOEF", keyword_info<double>{}.unit_string(
"1")},
157 {
"THERMEXR", keyword_info<double>{}.unit_string(
"1/AbsoluteTemperature")},
158 {
"THELCOEF", keyword_info<double>{}.unit_string(
"Pressure/AbsoluteTemperature")},
159 {
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
160 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
161 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
162 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
163 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
164 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
166static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ACTNUM", keyword_info<int>{}.init(1)},
167 {
"FLUXNUM", keyword_info<int>{}},
168 {
"ISOLNUM", keyword_info<int>{}.init(1)},
169 {
"MULTNUM", keyword_info<int>{}.init(1)},
170 {
"OPERNUM", keyword_info<int>{}},
171 {
"ROCKNUM", keyword_info<int>{}}};
184static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"MULTPV", keyword_info<double>{}.init(1.0)},
185 {
"PORV", keyword_info<double>{}.unit_string(
"ReservoirVolume")},
186 {
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
187 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
188 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
189 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
190 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
191 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
193static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
197static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"SWATINIT", keyword_info<double>{}},
198 {
"PCG", keyword_info<double>{}.unit_string(
"Pressure")},
199 {
"IPCG", keyword_info<double>{}.unit_string(
"Pressure")},
200 {
"PCW", keyword_info<double>{}.unit_string(
"Pressure")},
201 {
"IPCW", keyword_info<double>{}.unit_string(
"Pressure")}};
202static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
204#define dirfunc(base) base, base "X", base "X-", base "Y", base "Y-", base "Z", base "Z-"
206static const std::set<std::string> satfunc = {
"SWLPC",
"ISWLPC",
"SGLPC",
"ISGLPC",
243static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ENDNUM", keyword_info<int>{}.init(1)},
244 {
"EOSNUM", keyword_info<int>{}.init(1)},
245 {
"EQLNUM", keyword_info<int>{}.init(1)},
246 {
"FIPNUM", keyword_info<int>{}.init(1)},
247 {
"IMBNUM", keyword_info<int>{}.init(1)},
248 {
"OPERNUM", keyword_info<int>{}},
249 {
"STRESSEQUILNUM", keyword_info<int>{}.init(1)},
250 {
"MISCNUM", keyword_info<int>{}},
251 {
"MISCNUM", keyword_info<int>{}},
252 {
"PVTNUM", keyword_info<int>{}.init(1)},
253 {
"SATNUM", keyword_info<int>{}.init(1)},
254 {
"LWSLTNUM", keyword_info<int>{}},
255 {
"ROCKNUM", keyword_info<int>{}},
256 {
"KRNUMX", keyword_info<int>{}},
257 {
"KRNUMY", keyword_info<int>{}},
258 {
"KRNUMZ", keyword_info<int>{}},
259 {
"IMBNUMX", keyword_info<int>{}},
260 {
"IMBNUMY", keyword_info<int>{}},
261 {
"IMBNUMZ", keyword_info<int>{}},
267static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"PRESSURE", keyword_info<double>{}.unit_string(
"Pressure")},
268 {
"SPOLY", keyword_info<double>{}.unit_string(
"Density")},
269 {
"SPOLYMW", keyword_info<double>{}},
270 {
"SSOL", keyword_info<double>{}},
271 {
"SWAT", keyword_info<double>{}},
272 {
"SGAS", keyword_info<double>{}},
273 {
"SMICR", keyword_info<double>{}.unit_string(
"Density")},
274 {
"SOXYG", keyword_info<double>{}.unit_string(
"Density")},
275 {
"SUREA", keyword_info<double>{}.unit_string(
"Density")},
276 {
"SBIOF", keyword_info<double>{}},
277 {
"SCALC", keyword_info<double>{}},
278 {
"SALTP", keyword_info<double>{}},
279 {
"SALT", keyword_info<double>{}.unit_string(
"Salinity")},
280 {
"TEMPI", keyword_info<double>{}.unit_string(
"Temperature")},
281 {
"RS", keyword_info<double>{}.unit_string(
"GasDissolutionFactor")},
282 {
"RV", keyword_info<double>{}.unit_string(
"OilDissolutionFactor")},
283 {
"RVW", keyword_info<double>{}.unit_string(
"OilDissolutionFactor")}
290static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
291 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
292 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
293 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
294 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
295 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
297static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ROCKNUM", keyword_info<int>{}}};
302keyword_info<T> global_kw_info(
const std::string& name,
bool allow_unsupported =
false);
304bool is_oper_keyword(
const std::string& name);
312 using ScalarOperation = Fieldprops::ScalarOperation;
317 std::string region_name;
328 return this->region_value == other.region_value &&
329 this->multiplier == other.multiplier &&
330 this->region_name == other.region_name;
334 enum class GetStatus {
338 NOT_SUPPPORTED_KEYWORD = 4
343 const std::string& keyword;
346 const Data * data_ptr;
355 void verify_status()
const {
357 case FieldProps::GetStatus::OK:
359 case FieldProps::GetStatus::INVALID_DATA:
360 throw std::runtime_error(
"The keyword: " + keyword +
" has not been fully initialized");
361 case FieldProps::GetStatus::MISSING_KEYWORD:
362 throw std::out_of_range(
"No such keyword in deck: " + keyword);
363 case FieldProps::GetStatus::NOT_SUPPPORTED_KEYWORD:
364 throw std::logic_error(
"The keyword " + keyword +
" is not supported");
368 const std::vector<T>* ptr()
const {
370 return std::addressof(this->data_ptr->data);
375 const std::vector<T>& data()
const {
376 this->verify_status();
377 return this->data_ptr->data;
380 const Data& field_data()
const {
381 this->verify_status();
382 return *this->data_ptr;
386 return (this->status == GetStatus::OK);
397 void reset_actnum(
const std::vector<int>& actnum);
401 const std::string& default_region()
const;
403 std::vector<int> actnum();
404 const std::vector<int>& actnumRaw()
const;
406 template <
typename T>
407 static bool supported(
const std::string& keyword);
409 template <
typename T>
410 bool has(
const std::string& keyword)
const;
412 template <
typename T>
413 std::vector<std::string> keys()
const;
415 template <
typename T>
417 try_get(
const std::string& keyword,
const bool allow_unsupported =
false)
419 if (!allow_unsupported && !FieldProps::template supported<T>(keyword)) {
420 return { keyword, GetStatus::NOT_SUPPPORTED_KEYWORD,
nullptr };
423 const auto has0 = this->
template has<T>(keyword);
425 const auto& field_data =
426 this->
template init_get<T>(keyword, std::is_same<T,double>::value && allow_unsupported);
428 if (field_data.valid() || allow_unsupported) {
431 return { keyword, GetStatus::OK, &field_data };
435 this->
template erase<T>(keyword);
437 return { keyword, GetStatus::MISSING_KEYWORD,
nullptr };
440 return { keyword, GetStatus::INVALID_DATA,
nullptr };
443 template <
typename T>
444 const std::vector<T>& get(
const std::string& keyword)
446 return this->
template try_get<T>(keyword).data();
449 template <
typename T>
450 std::vector<T> get_global(
const std::string& keyword)
452 const auto managed_field_data = this->
template try_get<T>(keyword);
453 const auto& field_data = managed_field_data.field_data();
455 const auto& kw_info = Fieldprops::keywords::
456 template global_kw_info<T>(keyword);
458 return kw_info.global
459 ? *field_data.global_data
460 : this->global_copy(field_data.data, kw_info.scalar_init);
463 template <
typename T>
464 std::vector<T> get_copy(
const std::string& keyword,
bool global)
466 const auto has0 = this->
template has<T>(keyword);
476 const auto& field_data = this->
template try_get<T>(keyword).field_data();
479 return this->get_copy(field_data.data, field_data.kw_info.scalar_init, global);
482 const auto initial_value = Fieldprops::keywords::
483 template global_kw_info<T>(keyword).scalar_init;
485 return this->get_copy(this->
template extract<T>(keyword), initial_value, global);
488 template <
typename T>
489 std::vector<bool> defaulted(
const std::string& keyword)
491 const auto& field = this->
template init_get<T>(keyword);
492 std::vector<bool> def(field.size());
494 for (std::size_t i = 0; i < def.size(); ++i) {
495 def[i] = value::defaulted(field.value_status[i]);
501 template <
typename T>
502 std::vector<T> global_copy(
const std::vector<T>& data,
503 const std::optional<T>& default_value)
const
505 const T fill_value = default_value.has_value() ? *default_value : 0;
507 std::vector<T> global_data(this->global_size, fill_value);
510 for (std::size_t g = 0; g < this->global_size; g++) {
511 if (this->m_actnum[g]) {
512 global_data[g] = data[i];
520 std::size_t active_size;
521 std::size_t global_size;
523 std::size_t num_int()
const
525 return this->int_data.size();
528 std::size_t num_double()
const
530 return this->double_data.size();
533 void handle_schedule_keywords(
const std::vector<DeckKeyword>& keywords);
534 bool tran_active(
const std::string& keyword)
const;
535 void apply_tran(
const std::string& keyword, std::vector<double>& data);
536 bool operator==(
const FieldProps& other)
const;
537 static bool rst_cmp(
const FieldProps& full_arg,
const FieldProps& rst_arg);
539 const std::unordered_map<std::string,Fieldprops::TranCalculator>& getTran()
const
544 std::vector<std::string> fip_regions()
const;
549 void scanGRIDSection(
const GRIDSection& grid_section);
550 void scanGRIDSectionOnlyACTNUM(
const GRIDSection& grid_section);
551 void scanEDITSection(
const EDITSection& edit_section);
552 void scanPROPSSection(
const PROPSSection& props_section);
553 void scanREGIONSSection(
const REGIONSSection& regions_section);
554 void scanSOLUTIONSection(
const SOLUTIONSection& solution_section);
555 double getSIValue(
const std::string& keyword,
double raw_value)
const;
556 double getSIValue(ScalarOperation op,
const std::string& keyword,
double raw_value)
const;
557 template <
typename T>
558 void erase(
const std::string& keyword);
560 template <
typename T>
561 std::vector<T> extract(
const std::string& keyword);
563 template <
typename T>
564 std::vector<T> get_copy(
const std::vector<T>& x,
565 const std::optional<T>& initial_value,
566 const bool global)
const
568 return (! global) ? x : this->global_copy(x, initial_value);
571 template <
typename T>
572 std::vector<T> get_copy(std::vector<T>&& x,
573 const std::optional<T>& initial_value,
574 const bool global)
const
576 return (! global) ? std::move(x) : this->global_copy(x, initial_value);
579 template <
typename T>
580 void operate(
const DeckRecord& record, Fieldprops::FieldData<T>& target_data,
const Fieldprops::FieldData<T>& src_data,
const std::vector<Box::cell_index>& index_list);
582 template <
typename T>
583 static void apply(ScalarOperation op, std::vector<T>& data, std::vector<value::status>& value_status, T scalar_value,
const std::vector<Box::cell_index>& index_list);
585 template <
typename T>
586 Fieldprops::FieldData<T>& init_get(
const std::string& keyword,
bool allow_unsupported =
false);
588 template <
typename T>
589 Fieldprops::FieldData<T>& init_get(
const std::string& keyword,
const Fieldprops::keywords::keyword_info<T>& kw_info,
bool multiplier_in_edit =
false);
591 std::string region_name(
const DeckItem& region_item);
592 std::vector<Box::cell_index> region_index(
const std::string& region_name,
int region_value );
593 void handle_OPERATE(
const DeckKeyword& keyword, Box box);
594 void handle_operation(Section section,
const DeckKeyword& keyword, Box box);
595 void handle_region_operation(
const DeckKeyword& keyword);
596 void handle_COPY(
const DeckKeyword& keyword, Box box,
bool region);
597 void distribute_toplayer(Fieldprops::FieldData<double>& field_data,
const std::vector<double>& deck_data,
const Box& box);
598 double get_beta(
const std::string& func_name,
const std::string& target_array,
double raw_beta);
599 double get_alpha(
const std::string& func_name,
const std::string& target_array,
double raw_alpha);
601 void handle_keyword(Section section,
const DeckKeyword& keyword, Box& box);
602 void handle_double_keyword(Section section,
const Fieldprops::keywords::keyword_info<double>& kw_info,
const DeckKeyword& keyword,
const std::string& keyword_name,
const Box& box);
603 void handle_double_keyword(Section section,
const Fieldprops::keywords::keyword_info<double>& kw_info,
const DeckKeyword& keyword,
const Box& box);
604 void handle_int_keyword(
const Fieldprops::keywords::keyword_info<int>& kw_info,
const DeckKeyword& keyword,
const Box& box);
605 void init_satfunc(
const std::string& keyword, Fieldprops::FieldData<double>& satfunc);
606 void init_porv(Fieldprops::FieldData<double>& porv);
607 void init_tempi(Fieldprops::FieldData<double>& tempi);
608 std::string canonical_fipreg_name(
const std::string& fipreg);
609 const std::string& canonical_fipreg_name(
const std::string& fipreg)
const;
616 void apply_multipliers();
618 static constexpr std::string_view getMultiplierPrefix()
620 using namespace std::literals;
624 const UnitSystem unit_system;
625 std::size_t nx,ny,nz;
627 SatFuncControls m_satfuncctrl;
628 std::vector<int> m_actnum;
629 std::vector<double> cell_volume;
630 std::vector<double> cell_depth;
631 const std::string m_default_region;
632 const EclipseGrid * grid_ptr;
634 std::optional<satfunc::RawTableEndPoints> m_rtep;
635 std::vector<MultregpRecord> multregp;
636 std::unordered_map<std::string, Fieldprops::FieldData<int>> int_data;
637 std::unordered_map<std::string, Fieldprops::FieldData<double>> double_data;
638 std::unordered_map<std::string, std::string> fipreg_shortname_translation{};
640 std::unordered_map<std::string,Fieldprops::TranCalculator> tran;
647 std::unordered_map<std::string,Fieldprops::keywords::keyword_info<double>> multiplier_kw_infos_;
About cell information and dimension: The actual grid information is held in a pointer to an ERT ecl_...
Definition EclipseGrid.hpp:55
Definition FieldProps.hpp:309
Definition NumericalAquifers.hpp:38
Definition Runspec.hpp:46
Definition TableManager.hpp:66
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition Exceptions.hpp:30
Definition FieldProps.hpp:342
Definition FieldProps.hpp:314
Definition FieldData.hpp:55