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>
44#include <unordered_map>
45#include <unordered_set>
53class NumericalAquifers;
102inline bool isFipxxx(
const std::string& keyword) {
105 if (keyword.size() < 4 || keyword ==
"FIPOWG") {
108 return keyword[0] ==
'F' && keyword[1] ==
'I' && keyword[2] ==
'P';
127 static const std::unordered_map<std::string, std::string> aliased_keywords = {{
"PERMR",
"PERMX"},
128 {
"PERMTHT",
"PERMY"}};
133static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"MULTPV", keyword_info<double>{}.init(1.0)},
134 {
"NTG", keyword_info<double>{}.init(1.0)},
135 {
"PORO", keyword_info<double>{}.distribute_top(
true)},
136 {
"PERMX", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
137 {
"PERMY", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
138 {
"PERMZ", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
139 {
"PERMR", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
140 {
"PERMTHT", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
141 {
"TEMPI", keyword_info<double>{}.unit_string(
"Temperature")},
142 {
"THCONR", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
143 {
"THCONSF", keyword_info<double>{}},
144 {
"HEATCR", keyword_info<double>{}.unit_string(
"Energy/ReservoirVolume*AbsoluteTemperature")},
145 {
"HEATCRT", keyword_info<double>{}.unit_string(
"Energy/ReservoirVolume*AbsoluteTemperature*AbsoluteTemperature")},
146 {
"THCROCK", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
147 {
"THCOIL", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
148 {
"THCGAS", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
149 {
"THCWATER",keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
150 {
"YMODULE", keyword_info<double>{}.unit_string(
"Giga*Pascal")},
151 {
"PRATIO", keyword_info<double>{}.unit_string(
"1")},
152 {
"BIOTCOEF", keyword_info<double>{}.unit_string(
"1")},
153 {
"POELCOEF", keyword_info<double>{}.unit_string(
"1")},
154 {
"THERMEXR", keyword_info<double>{}.unit_string(
"1/AbsoluteTemperature")},
155 {
"THELCOEF", keyword_info<double>{}.unit_string(
"Pressure/AbsoluteTemperature")},
156 {
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
157 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
158 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
159 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
160 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
161 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
163static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ACTNUM", keyword_info<int>{}.init(1)},
164 {
"FLUXNUM", keyword_info<int>{}},
165 {
"ISOLNUM", keyword_info<int>{}.init(1)},
166 {
"MULTNUM", keyword_info<int>{}.init(1)},
167 {
"OPERNUM", keyword_info<int>{}},
168 {
"ROCKNUM", keyword_info<int>{}}};
181static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"MULTPV", keyword_info<double>{}.init(1.0)},
182 {
"PORV", keyword_info<double>{}.unit_string(
"ReservoirVolume")},
183 {
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
184 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
185 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
186 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
187 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
188 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
190static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
194static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"SWATINIT", keyword_info<double>{}},
195 {
"PCG", keyword_info<double>{}.unit_string(
"Pressure")},
196 {
"IPCG", keyword_info<double>{}.unit_string(
"Pressure")},
197 {
"PCW", keyword_info<double>{}.unit_string(
"Pressure")},
198 {
"IPCW", keyword_info<double>{}.unit_string(
"Pressure")}};
199static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
201#define dirfunc(base) base, base "X", base "X-", base "Y", base "Y-", base "Z", base "Z-"
203static const std::set<std::string> satfunc = {
"SWLPC",
"ISWLPC",
"SGLPC",
"ISGLPC",
240static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ENDNUM", keyword_info<int>{}.init(1)},
241 {
"EQLNUM", keyword_info<int>{}.init(1)},
242 {
"FIPNUM", keyword_info<int>{}.init(1)},
243 {
"IMBNUM", keyword_info<int>{}.init(1)},
244 {
"OPERNUM", keyword_info<int>{}},
245 {
"STRESSEQUILNUM", keyword_info<int>{}.init(1)},
246 {
"MISCNUM", keyword_info<int>{}},
247 {
"MISCNUM", keyword_info<int>{}},
248 {
"PVTNUM", keyword_info<int>{}.init(1)},
249 {
"SATNUM", keyword_info<int>{}.init(1)},
250 {
"LWSLTNUM", keyword_info<int>{}},
251 {
"ROCKNUM", keyword_info<int>{}},
252 {
"KRNUMX", keyword_info<int>{}},
253 {
"KRNUMY", keyword_info<int>{}},
254 {
"KRNUMZ", keyword_info<int>{}},
255 {
"IMBNUMX", keyword_info<int>{}},
256 {
"IMBNUMY", keyword_info<int>{}},
257 {
"IMBNUMZ", keyword_info<int>{}},
263static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"PRESSURE", keyword_info<double>{}.unit_string(
"Pressure")},
264 {
"SPOLY", keyword_info<double>{}.unit_string(
"Density")},
265 {
"SPOLYMW", keyword_info<double>{}},
266 {
"SSOL", keyword_info<double>{}},
267 {
"SWAT", keyword_info<double>{}},
268 {
"SGAS", keyword_info<double>{}},
269 {
"SMICR", keyword_info<double>{}.unit_string(
"Density")},
270 {
"SOXYG", keyword_info<double>{}.unit_string(
"Density")},
271 {
"SUREA", keyword_info<double>{}.unit_string(
"Density")},
272 {
"SBIOF", keyword_info<double>{}},
273 {
"SCALC", keyword_info<double>{}},
274 {
"SALTP", keyword_info<double>{}},
275 {
"SALT", keyword_info<double>{}.unit_string(
"Salinity")},
276 {
"TEMPI", keyword_info<double>{}.unit_string(
"Temperature")},
277 {
"RS", keyword_info<double>{}.unit_string(
"GasDissolutionFactor")},
278 {
"RV", keyword_info<double>{}.unit_string(
"OilDissolutionFactor")},
279 {
"RVW", keyword_info<double>{}.unit_string(
"OilDissolutionFactor")}
286static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
287 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
288 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
289 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
290 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
291 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
293static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ROCKNUM", keyword_info<int>{}}};
298keyword_info<T> global_kw_info(
const std::string& name,
bool allow_unsupported =
false);
300bool is_oper_keyword(
const std::string& name);
308 using ScalarOperation = Fieldprops::ScalarOperation;
313 std::string region_name;
324 return this->region_value == other.region_value &&
325 this->multiplier == other.multiplier &&
326 this->region_name == other.region_name;
330 enum class GetStatus {
334 NOT_SUPPPORTED_KEYWORD = 4
339 const std::string& keyword;
342 const Data * data_ptr;
351 void verify_status()
const {
353 case FieldProps::GetStatus::OK:
355 case FieldProps::GetStatus::INVALID_DATA:
356 throw std::runtime_error(
"The keyword: " + keyword +
" has not been fully initialized");
357 case FieldProps::GetStatus::MISSING_KEYWORD:
358 throw std::out_of_range(
"No such keyword in deck: " + keyword);
359 case FieldProps::GetStatus::NOT_SUPPPORTED_KEYWORD:
360 throw std::logic_error(
"The keyword " + keyword +
" is not supported");
364 const std::vector<T>* ptr()
const {
366 return std::addressof(this->data_ptr->data);
371 const std::vector<T>& data()
const {
372 this->verify_status();
373 return this->data_ptr->data;
376 const Data& field_data()
const {
377 this->verify_status();
378 return *this->data_ptr;
382 return (this->status == GetStatus::OK);
393 void reset_actnum(
const std::vector<int>& actnum);
397 const std::string& default_region()
const;
399 std::vector<int> actnum();
400 const std::vector<int>& actnumRaw()
const;
402 template <
typename T>
403 static bool supported(
const std::string& keyword);
405 template <
typename T>
406 bool has(
const std::string& keyword)
const;
408 template <
typename T>
409 std::vector<std::string> keys()
const;
411 template <
typename T>
413 try_get(
const std::string& keyword,
const bool allow_unsupported =
false)
415 if (!allow_unsupported && !FieldProps::template supported<T>(keyword)) {
416 return { keyword, GetStatus::NOT_SUPPPORTED_KEYWORD,
nullptr };
419 const auto has0 = this->
template has<T>(keyword);
421 const auto& field_data =
422 this->
template init_get<T>(keyword, std::is_same<T,double>::value && allow_unsupported);
424 if (field_data.valid() || allow_unsupported) {
427 return { keyword, GetStatus::OK, &field_data };
431 this->
template erase<T>(keyword);
433 return { keyword, GetStatus::MISSING_KEYWORD,
nullptr };
436 return { keyword, GetStatus::INVALID_DATA,
nullptr };
439 template <
typename T>
440 const std::vector<T>& get(
const std::string& keyword)
442 return this->
template try_get<T>(keyword).data();
445 template <
typename T>
446 std::vector<T> get_global(
const std::string& keyword)
448 const auto managed_field_data = this->
template try_get<T>(keyword);
449 const auto& field_data = managed_field_data.field_data();
451 const auto& kw_info = Fieldprops::keywords::
452 template global_kw_info<T>(keyword);
454 return kw_info.global
455 ? *field_data.global_data
456 : this->global_copy(field_data.data, kw_info.scalar_init);
459 template <
typename T>
460 std::vector<T> get_copy(
const std::string& keyword,
bool global)
462 const auto has0 = this->
template has<T>(keyword);
472 const auto& field_data = this->
template try_get<T>(keyword).field_data();
475 return this->get_copy(field_data.data, field_data.kw_info.scalar_init, global);
478 const auto initial_value = Fieldprops::keywords::
479 template global_kw_info<T>(keyword).scalar_init;
481 return this->get_copy(this->
template extract<T>(keyword), initial_value, global);
484 template <
typename T>
485 std::vector<bool> defaulted(
const std::string& keyword)
487 const auto& field = this->
template init_get<T>(keyword);
488 std::vector<bool> def(field.size());
490 for (std::size_t i = 0; i < def.size(); ++i) {
491 def[i] = value::defaulted(field.value_status[i]);
497 template <
typename T>
498 std::vector<T> global_copy(
const std::vector<T>& data,
499 const std::optional<T>& default_value)
const
501 const T fill_value = default_value.has_value() ? *default_value : 0;
503 std::vector<T> global_data(this->global_size, fill_value);
506 for (std::size_t g = 0; g < this->global_size; g++) {
507 if (this->m_actnum[g]) {
508 global_data[g] = data[i];
516 std::size_t active_size;
517 std::size_t global_size;
519 std::size_t num_int()
const
521 return this->int_data.size();
524 std::size_t num_double()
const
526 return this->double_data.size();
529 void handle_schedule_keywords(
const std::vector<DeckKeyword>& keywords);
530 bool tran_active(
const std::string& keyword)
const;
531 void apply_tran(
const std::string& keyword, std::vector<double>& data);
532 bool operator==(
const FieldProps& other)
const;
533 static bool rst_cmp(
const FieldProps& full_arg,
const FieldProps& rst_arg);
535 const std::unordered_map<std::string,Fieldprops::TranCalculator>& getTran()
const
541 void scanGRIDSection(
const GRIDSection& grid_section);
542 void scanGRIDSectionOnlyACTNUM(
const GRIDSection& grid_section);
543 void scanEDITSection(
const EDITSection& edit_section);
544 void scanPROPSSection(
const PROPSSection& props_section);
545 void scanREGIONSSection(
const REGIONSSection& regions_section);
546 void scanSOLUTIONSection(
const SOLUTIONSection& solution_section);
547 double getSIValue(
const std::string& keyword,
double raw_value)
const;
548 double getSIValue(ScalarOperation op,
const std::string& keyword,
double raw_value)
const;
549 template <
typename T>
550 void erase(
const std::string& keyword);
552 template <
typename T>
553 std::vector<T> extract(
const std::string& keyword);
555 template <
typename T>
556 std::vector<T> get_copy(
const std::vector<T>& x,
557 const std::optional<T>& initial_value,
558 const bool global)
const
560 return (! global) ? x : this->global_copy(x, initial_value);
563 template <
typename T>
564 std::vector<T> get_copy(std::vector<T>&& x,
565 const std::optional<T>& initial_value,
566 const bool global)
const
568 return (! global) ? std::move(x) : this->global_copy(x, initial_value);
571 template <
typename T>
572 void operate(
const DeckRecord& record, Fieldprops::FieldData<T>& target_data,
const Fieldprops::FieldData<T>& src_data,
const std::vector<Box::cell_index>& index_list);
574 template <
typename T>
575 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);
577 template <
typename T>
578 Fieldprops::FieldData<T>& init_get(
const std::string& keyword,
bool allow_unsupported =
false);
580 template <
typename T>
581 Fieldprops::FieldData<T>& init_get(
const std::string& keyword,
const Fieldprops::keywords::keyword_info<T>& kw_info);
583 std::string region_name(
const DeckItem& region_item);
584 std::vector<Box::cell_index> region_index(
const std::string& region_name,
int region_value );
585 void handle_OPERATE(
const DeckKeyword& keyword, Box box);
586 void handle_operation(
const DeckKeyword& keyword, Box box);
587 void handle_region_operation(
const DeckKeyword& keyword);
588 void handle_COPY(
const DeckKeyword& keyword, Box box,
bool region);
589 void distribute_toplayer(Fieldprops::FieldData<double>& field_data,
const std::vector<double>& deck_data,
const Box& box);
590 double get_beta(
const std::string& func_name,
const std::string& target_array,
double raw_beta);
591 double get_alpha(
const std::string& func_name,
const std::string& target_array,
double raw_alpha);
593 void handle_keyword(
const DeckKeyword& keyword, Box& box);
594 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);
595 void handle_double_keyword(Section section,
const Fieldprops::keywords::keyword_info<double>& kw_info,
const DeckKeyword& keyword,
const Box& box);
596 void handle_int_keyword(
const Fieldprops::keywords::keyword_info<int>& kw_info,
const DeckKeyword& keyword,
const Box& box);
597 void init_satfunc(
const std::string& keyword, Fieldprops::FieldData<double>& satfunc);
598 void init_porv(Fieldprops::FieldData<double>& porv);
599 void init_tempi(Fieldprops::FieldData<double>& tempi);
600 std::string canonical_fipreg_name(
const std::string& fipreg);
601 const std::string& canonical_fipreg_name(
const std::string& fipreg)
const;
603 const UnitSystem unit_system;
604 std::size_t nx,ny,nz;
606 SatFuncControls m_satfuncctrl;
607 std::vector<int> m_actnum;
608 std::vector<double> cell_volume;
609 std::vector<double> cell_depth;
610 const std::string m_default_region;
611 const EclipseGrid * grid_ptr;
613 std::optional<satfunc::RawTableEndPoints> m_rtep;
614 std::vector<MultregpRecord> multregp;
615 std::unordered_map<std::string, Fieldprops::FieldData<int>> int_data;
616 std::unordered_map<std::string, Fieldprops::FieldData<double>> double_data;
617 std::unordered_map<std::string, std::string> fipreg_shortname_translation{};
619 std::unordered_map<std::string,Fieldprops::TranCalculator> tran;
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:305
FieldProps(const Deck &deck, const EclipseGrid &grid)
Special case constructor used to process ACTNUM only.
FieldProps(const Deck &deck, const Phases &phases, const EclipseGrid &grid, const TableManager &table_arg)
Normal constructor for FieldProps.
Definition NumericalAquifers.hpp:38
Definition Runspec.hpp:36
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:338
Definition FieldProps.hpp:310
Definition FieldData.hpp:55