25#include <unordered_set>
28#include <opm/input/eclipse/Deck/value_status.hpp>
29#include <opm/input/eclipse/Deck/DeckSection.hpp>
30#include <opm/input/eclipse/Units/UnitSystem.hpp>
31#include <opm/input/eclipse/EclipseState/Grid/Box.hpp>
32#include <opm/input/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp>
33#include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp>
34#include <opm/input/eclipse/EclipseState/Runspec.hpp>
35#include <opm/input/eclipse/EclipseState/Grid/Keywords.hpp>
36#include <opm/input/eclipse/EclipseState/Grid/TranCalculator.hpp>
37#include <opm/input/eclipse/EclipseState/Grid/FieldData.hpp>
43class NumericalAquifers;
92inline bool isFipxxx(
const std::string& keyword) {
95 if (keyword.size() < 4 || keyword ==
"FIPOWG") {
98 return keyword[0] ==
'F' && keyword[1] ==
'I' && keyword[2] ==
'P';
117 static const std::unordered_map<std::string, std::string> aliased_keywords = {{
"PERMR",
"PERMX"},
118 {
"PERMTHT",
"PERMY"}};
123static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"MULTPV", keyword_info<double>{}.init(1.0)},
124 {
"NTG", keyword_info<double>{}.init(1.0)},
125 {
"PORO", keyword_info<double>{}.distribute_top(
true)},
126 {
"PERMX", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
127 {
"PERMY", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
128 {
"PERMZ", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
129 {
"PERMR", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
130 {
"PERMTHT", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true)},
131 {
"TEMPI", keyword_info<double>{}.unit_string(
"Temperature")},
132 {
"THCONR", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
133 {
"THCONSF", keyword_info<double>{}},
134 {
"HEATCR", keyword_info<double>{}.unit_string(
"Energy/ReservoirVolume*AbsoluteTemperature")},
135 {
"HEATCRT", keyword_info<double>{}.unit_string(
"Energy/ReservoirVolume*AbsoluteTemperature*AbsoluteTemperature")},
136 {
"THCROCK", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
137 {
"THCOIL", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
138 {
"THCGAS", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
139 {
"THCWATER",keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
140 {
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
141 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
142 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
143 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
144 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
145 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
147static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ACTNUM", keyword_info<int>{}.init(1)},
148 {
"FLUXNUM", keyword_info<int>{}},
149 {
"ISOLNUM", keyword_info<int>{}.init(1)},
150 {
"MULTNUM", keyword_info<int>{}.init(1)},
151 {
"OPERNUM", keyword_info<int>{}},
152 {
"ROCKNUM", keyword_info<int>{}}};
165static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"MULTPV", keyword_info<double>{}.init(1.0)},
166 {
"PORV", keyword_info<double>{}.unit_string(
"ReservoirVolume")},
167 {
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
168 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
169 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
170 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
171 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
172 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
174static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
178static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"SWATINIT", keyword_info<double>{}}};
179static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
181#define dirfunc(base) base, base "X", base "X-", base "Y", base "Y-", base "Z", base "Z-"
183static const std::set<std::string> satfunc = {
"SWLPC",
"ISWLPC",
"SGLPC",
"ISGLPC",
219static const std::map<std::string,std::string> sogcr_shift = {{
"SOGCR",
"SWL"},
221 {
"SOGCRX-",
"SWLX-"},
223 {
"SOGCRY-",
"SWLY-"},
225 {
"SOGCRZ-",
"SWLZ-"},
227 {
"ISOGCRX",
"ISWLX"},
228 {
"ISOGCRX-",
"ISWLX-"},
229 {
"ISOGCRY",
"ISWLY"},
230 {
"ISOGCRY-",
"ISWLY-"},
231 {
"ISOGCRZ",
"ISWLZ"},
232 {
"ISOGCRZ-",
"ISWLZ-"}};
238static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ENDNUM", keyword_info<int>{}.init(1)},
239 {
"EQLNUM", keyword_info<int>{}.init(1)},
240 {
"FIPNUM", keyword_info<int>{}.init(1)},
241 {
"IMBNUM", keyword_info<int>{}.init(1)},
242 {
"OPERNUM", keyword_info<int>{}},
243 {
"MISCNUM", keyword_info<int>{}},
244 {
"MISCNUM", keyword_info<int>{}},
245 {
"PVTNUM", keyword_info<int>{}.init(1)},
246 {
"SATNUM", keyword_info<int>{}.init(1)},
247 {
"LWSLTNUM", keyword_info<int>{}},
248 {
"ROCKNUM", keyword_info<int>{}},
249 {
"KRNUMX", keyword_info<int>{}},
250 {
"KRNUMY", keyword_info<int>{}},
251 {
"KRNUMZ", keyword_info<int>{}},
252 {
"IMBNUMX", keyword_info<int>{}},
253 {
"IMBNUMY", keyword_info<int>{}},
254 {
"IMBNUMZ", keyword_info<int>{}},
260static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"PRESSURE", keyword_info<double>{}.unit_string(
"Pressure")},
261 {
"SPOLY", keyword_info<double>{}.unit_string(
"Density")},
262 {
"SPOLYMW", keyword_info<double>{}},
263 {
"SSOL", keyword_info<double>{}},
264 {
"SWAT", keyword_info<double>{}},
265 {
"SGAS", keyword_info<double>{}},
266 {
"SMICR", keyword_info<double>{}.unit_string(
"Density")},
267 {
"SOXYG", keyword_info<double>{}.unit_string(
"Density")},
268 {
"SUREA", keyword_info<double>{}.unit_string(
"Density")},
269 {
"SBIOF", keyword_info<double>{}},
270 {
"SCALC", keyword_info<double>{}},
271 {
"SALTP", keyword_info<double>{}},
272 {
"SALT", keyword_info<double>{}.unit_string(
"Salinity")},
273 {
"TEMPI", keyword_info<double>{}.unit_string(
"Temperature")},
274 {
"RS", keyword_info<double>{}.unit_string(
"GasDissolutionFactor")},
275 {
"RV", keyword_info<double>{}.unit_string(
"OilDissolutionFactor")},
276 {
"RVW", keyword_info<double>{}.unit_string(
"OilDissolutionFactor")}
283static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
284 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
285 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
286 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
287 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
288 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
290static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ROCKNUM", keyword_info<int>{}}};
295keyword_info<T> global_kw_info(
const std::string& name,
bool allow_unsupported =
false);
304 using ScalarOperation = Fieldprops::ScalarOperation;
309 std::string region_name;
320 return this->region_value == other.region_value &&
321 this->multiplier == other.multiplier &&
322 this->region_name == other.region_name;
328 enum class GetStatus {
332 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);
394 void reset_actnum(
const std::vector<int>& actnum);
398 const std::string& default_region()
const;
400 std::vector<int> actnum();
401 const std::vector<int>& actnumRaw()
const;
403 template <
typename T>
404 static bool supported(
const std::string& keyword);
406 template <
typename T>
407 bool has(
const std::string& keyword)
const;
409 template <
typename T>
410 std::vector<std::string> keys()
const;
413 template <
typename T>
415 bool allow_unsupported=
false) {
416 if (!allow_unsupported && !FieldProps::supported<T>(keyword))
420 bool has0 = this->has<T>(keyword);
422 field_data = std::addressof(this->init_get<T>(keyword,
423 std::is_same<T,double>::value && allow_unsupported));
424 if (field_data->valid() || allow_unsupported)
428 this->erase<T>(keyword);
432 return FieldDataManager<T>(keyword, GetStatus::INVALID_DATA,
nullptr);
436 template <
typename T>
437 const std::vector<T>& get(
const std::string& keyword) {
438 const auto& data = this->try_get<T>(keyword);
442 template <
typename T>
443 std::vector<T> get_global(
const std::string& keyword) {
444 const auto& managed_field_data = this->try_get<T>(keyword);
445 const auto& field_data = managed_field_data.field_data();
446 const auto& kw_info = Fieldprops::keywords::global_kw_info<T>(keyword);
448 return *field_data.global_data;
450 return this->global_copy(field_data.data, kw_info.scalar_init);
454 template <
typename T>
455 std::vector<T> get_copy(
const std::string& keyword,
bool global) {
456 bool has0 = this->has<T>(keyword);
457 const auto& field_data = this->try_get<T>(keyword).field_data();
461 return this->global_copy(field_data.data, field_data.kw_info.scalar_init);
463 return field_data.data;
466 const auto& kw_info = Fieldprops::keywords::global_kw_info<T>(keyword);
467 return this->global_copy(this->extract<T>(keyword), kw_info.scalar_init);
469 return this->extract<T>(keyword);
474 template <
typename T>
475 std::vector<bool> defaulted(
const std::string& keyword) {
476 const auto& field = this->init_get<T>(keyword);
477 std::vector<bool> def(field.size());
479 for (std::size_t i=0; i < def.size(); i++)
480 def[i] = value::defaulted( field.value_status[i]);
486 template <
typename T>
487 std::vector<T> global_copy(
const std::vector<T>& data,
const std::optional<T>& default_value)
const {
488 T fill_value = default_value.has_value() ? *default_value : 0;
489 std::vector<T> global_data(this->global_size, fill_value);
491 for (std::size_t g = 0; g < this->global_size; g++) {
492 if (this->m_actnum[g]) {
493 global_data[g] = data[i];
500 std::size_t active_size;
501 std::size_t global_size;
503 std::size_t num_int()
const {
504 return this->int_data.size();
507 std::size_t num_double()
const {
508 return this->double_data.size();
511 void handle_schedule_keywords(
const std::vector<DeckKeyword>& keywords);
512 bool tran_active(
const std::string& keyword)
const;
513 void apply_tran(
const std::string& keyword, std::vector<double>& data);
514 bool operator==(
const FieldProps& other)
const;
517 const std::unordered_map<std::string,Fieldprops::TranCalculator>& getTran()
const
523 void scanGRIDSection(
const GRIDSection& grid_section);
524 void scanGRIDSectionOnlyACTNUM(
const GRIDSection& grid_section);
525 void scanEDITSection(
const EDITSection& edit_section);
526 void scanPROPSSection(
const PROPSSection& props_section);
527 void scanREGIONSSection(
const REGIONSSection& regions_section);
528 void scanSOLUTIONSection(
const SOLUTIONSection& solution_section);
529 double getSIValue(
const std::string& keyword,
double raw_value)
const;
530 double getSIValue(ScalarOperation op,
const std::string& keyword,
double raw_value)
const;
531 template <
typename T>
532 void erase(
const std::string& keyword);
534 template <
typename T>
535 std::vector<T> extract(
const std::string& keyword);
537 template <
typename T>
538 void operate(
const DeckRecord& record, Fieldprops::FieldData<T>& target_data,
const Fieldprops::FieldData<T>& src_data,
const std::vector<Box::cell_index>& index_list);
540 template <
typename T>
541 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);
543 template <
typename T>
544 Fieldprops::FieldData<T>& init_get(
const std::string& keyword,
bool allow_unsupported =
false);
546 template <
typename T>
547 Fieldprops::FieldData<T>& init_get(
const std::string& keyword,
const Fieldprops::keywords::keyword_info<T>& kw_info);
549 std::string region_name(
const DeckItem& region_item);
550 std::vector<Box::cell_index> region_index(
const std::string& region_name,
int region_value );
551 void handle_OPERATE(
const DeckKeyword& keyword, Box box);
552 void handle_operation(
const DeckKeyword& keyword, Box box);
553 void handle_region_operation(
const DeckKeyword& keyword);
554 void handle_COPY(
const DeckKeyword& keyword, Box box,
bool region);
555 void distribute_toplayer(Fieldprops::FieldData<double>& field_data,
const std::vector<double>& deck_data,
const Box& box);
556 double get_beta(
const std::string& func_name,
const std::string& target_array,
double raw_beta);
557 double get_alpha(
const std::string& func_name,
const std::string& target_array,
double raw_alpha);
559 void handle_keyword(
const DeckKeyword& keyword, Box& box);
560 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);
561 void handle_double_keyword(Section section,
const Fieldprops::keywords::keyword_info<double>& kw_info,
const DeckKeyword& keyword,
const Box& box);
562 void handle_int_keyword(
const Fieldprops::keywords::keyword_info<int>& kw_info,
const DeckKeyword& keyword,
const Box& box);
563 void init_satfunc(
const std::string& keyword, Fieldprops::FieldData<double>& satfunc);
564 void init_porv(Fieldprops::FieldData<double>& porv);
565 void init_tempi(Fieldprops::FieldData<double>& tempi);
567 const UnitSystem unit_system;
568 std::size_t nx,ny,nz;
570 SatFuncControls m_satfuncctrl;
571 std::vector<int> m_actnum;
572 std::vector<double> cell_volume;
573 std::vector<double> cell_depth;
574 const std::string m_default_region;
575 const EclipseGrid * grid_ptr;
577 std::optional<satfunc::RawTableEndPoints> m_rtep;
578 std::vector<MultregpRecord> multregp;
579 std::unordered_map<std::string, Fieldprops::FieldData<int>> int_data;
580 std::unordered_map<std::string, Fieldprops::FieldData<double>> double_data;
582 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:54
Definition: FieldProps.hpp:301
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:36
Definition: Runspec.hpp:37
Definition: TableManager.hpp:65
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:306
Definition: FieldData.hpp:55