19 #ifndef FIELDPROPS_HPP 20 #define FIELDPROPS_HPP 22 #include <opm/common/utility/OpmInputError.hpp> 24 #include <opm/input/eclipse/EclipseState/Grid/Box.hpp> 25 #include <opm/input/eclipse/EclipseState/Grid/FieldData.hpp> 26 #include <opm/input/eclipse/EclipseState/Grid/Keywords.hpp> 27 #include <opm/input/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp> 28 #include <opm/input/eclipse/EclipseState/Grid/TranCalculator.hpp> 29 #include <opm/input/eclipse/EclipseState/Runspec.hpp> 30 #include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp> 32 #include <opm/input/eclipse/Units/UnitSystem.hpp> 34 #include <opm/input/eclipse/Deck/DeckSection.hpp> 35 #include <opm/input/eclipse/Deck/value_status.hpp> 45 #include <string_view> 46 #include <type_traits> 47 #include <unordered_map> 48 #include <unordered_set> 56 class NumericalAquifers;
105 inline bool isFipxxx(
const std::string& keyword) {
108 if (keyword.size() < 4 || keyword ==
"FIPOWG") {
111 return keyword[0] ==
'F' && keyword[1] ==
'I' && keyword[2] ==
'P';
130 static const std::unordered_map<std::string, std::string> aliased_keywords = {{
"PERMR",
"PERMX"},
131 {
"PERMTHT",
"PERMY"}};
136 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"DISPERC",keyword_info<double>{}.unit_string(
"Length")},
137 {
"MINPVV", keyword_info<double>{}.init(0.0).unit_string(
"ReservoirVolume").global_kw(
true)},
138 {
"MULTPV", keyword_info<double>{}.init(1.0).mult(
true)},
139 {
"NTG", keyword_info<double>{}.init(1.0)},
140 {
"PORO", keyword_info<double>{}.distribute_top(
true)},
141 {
"PERMX", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true).global_kw_until_edit()},
142 {
"PERMY", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true).global_kw_until_edit()},
143 {
"PERMZ", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true).global_kw_until_edit()},
144 {
"PERMR", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true).global_kw_until_edit()},
145 {
"PERMTHT", keyword_info<double>{}.unit_string(
"Permeability").distribute_top(
true).global_kw_until_edit()},
146 {
"TEMPI", keyword_info<double>{}.unit_string(
"Temperature")},
147 {
"THCONR", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
148 {
"THCONSF", keyword_info<double>{}},
149 {
"HEATCR", keyword_info<double>{}.unit_string(
"Energy/ReservoirVolume*AbsoluteTemperature")},
150 {
"HEATCRT", keyword_info<double>{}.unit_string(
"Energy/ReservoirVolume*AbsoluteTemperature*AbsoluteTemperature")},
151 {
"THCROCK", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
152 {
"THCOIL", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
153 {
"THCGAS", keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
154 {
"THCWATER",keyword_info<double>{}.unit_string(
"Energy/AbsoluteTemperature*Length*Time")},
155 {
"YMODULE", keyword_info<double>{}.unit_string(
"Ymodule")},
156 {
"SMODULUS",keyword_info<double>{}.unit_string(
"Ymodule")},
157 {
"LAME", keyword_info<double>{}.unit_string(
"Ymodule")},
158 {
"CSTRESS", keyword_info<double>{}.unit_string(
"1")},
159 {
"PRATIO", keyword_info<double>{}.unit_string(
"1")},
160 {
"BIOTCOEF", keyword_info<double>{}.unit_string(
"1")},
161 {
"POELCOEF", keyword_info<double>{}.unit_string(
"1")},
162 {
"THERMEXR", keyword_info<double>{}.unit_string(
"1/AbsoluteTemperature")},
163 {
"THELCOEF", keyword_info<double>{}.unit_string(
"Pressure/AbsoluteTemperature")},
164 {
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
165 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
166 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
167 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
168 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
169 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
171 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ACTNUM", keyword_info<int>{}.init(1)},
172 {
"FLUXNUM", keyword_info<int>{}},
173 {
"ISOLNUM", keyword_info<int>{}.init(1)},
174 {
"MULTNUM", keyword_info<int>{}.init(1)},
175 {
"OPERNUM", keyword_info<int>{}},
176 {
"ROCKNUM", keyword_info<int>{}}};
189 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"MULTPV", keyword_info<double>{}.init(1.0).mult(
true)},
190 {
"DEPTH", keyword_info<double>{}.unit_string(
"Length")},
191 {
"PORV", keyword_info<double>{}.unit_string(
"ReservoirVolume")},
192 {
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
193 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
194 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
195 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
196 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
197 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
199 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
203 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"SWATINIT", keyword_info<double>{}},
204 {
"PCG", keyword_info<double>{}.unit_string(
"Pressure")},
205 {
"IPCG", keyword_info<double>{}.unit_string(
"Pressure")},
206 {
"PCW", keyword_info<double>{}.unit_string(
"Pressure")},
207 {
"IPCW", keyword_info<double>{}.unit_string(
"Pressure")}};
208 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
210 #define dirfunc(base) base, base "X", base "X-", base "Y", base "Y-", base "Z", base "Z-" 212 static const std::set<std::string> satfunc = {
"SWLPC",
"ISWLPC",
"SGLPC",
"ISGLPC",
249 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ENDNUM", keyword_info<int>{}.init(1)},
250 {
"EOSNUM", keyword_info<int>{}.init(1)},
251 {
"EQLNUM", keyword_info<int>{}.init(1)},
252 {
"FIPNUM", keyword_info<int>{}.init(1)},
253 {
"IMBNUM", keyword_info<int>{}.init(1)},
254 {
"OPERNUM", keyword_info<int>{}},
255 {
"STRESSEQUILNUM", keyword_info<int>{}.init(1)},
256 {
"MISCNUM", keyword_info<int>{}},
257 {
"MISCNUM", keyword_info<int>{}},
258 {
"PVTNUM", keyword_info<int>{}.init(1)},
259 {
"SATNUM", keyword_info<int>{}.init(1)},
260 {
"LWSLTNUM", keyword_info<int>{}},
261 {
"ROCKNUM", keyword_info<int>{}},
262 {
"KRNUMX", keyword_info<int>{}},
263 {
"KRNUMY", keyword_info<int>{}},
264 {
"KRNUMZ", keyword_info<int>{}},
265 {
"IMBNUMX", keyword_info<int>{}},
266 {
"IMBNUMY", keyword_info<int>{}},
267 {
"IMBNUMZ", keyword_info<int>{}},
273 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"PRESSURE", keyword_info<double>{}.unit_string(
"Pressure")},
274 {
"SPOLY", keyword_info<double>{}.unit_string(
"Concentration")},
275 {
"SPOLYMW", keyword_info<double>{}},
276 {
"SSOL", keyword_info<double>{}},
277 {
"SWAT", keyword_info<double>{}},
278 {
"SGAS", keyword_info<double>{}},
279 {
"SMICR", keyword_info<double>{}.unit_string(
"Concentration")},
280 {
"SOXYG", keyword_info<double>{}.unit_string(
"Concentration")},
281 {
"SUREA", keyword_info<double>{}.unit_string(
"Concentration")},
282 {
"SBIOF", keyword_info<double>{}},
283 {
"SCALC", keyword_info<double>{}},
284 {
"SALTP", keyword_info<double>{}},
285 {
"SALT", keyword_info<double>{}.unit_string(
"Concentration")},
286 {
"TEMPI", keyword_info<double>{}.unit_string(
"Temperature")},
287 {
"RS", keyword_info<double>{}.unit_string(
"GasDissolutionFactor")},
288 {
"RSW", keyword_info<double>{}.unit_string(
"GasDissolutionFactor")},
289 {
"RV", keyword_info<double>{}.unit_string(
"OilDissolutionFactor")},
290 {
"RVW", keyword_info<double>{}.unit_string(
"OilDissolutionFactor")}
293 static const std::unordered_map<std::string, keyword_info<double>> composition_keywords = {{
"XMF", keyword_info<double>{}},
294 {
"YMF", keyword_info<double>{}},
295 {
"ZMF", keyword_info<double>{}},
301 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{
"MULTX", keyword_info<double>{}.init(1.0).mult(
true)},
302 {
"MULTX-", keyword_info<double>{}.init(1.0).mult(
true)},
303 {
"MULTY", keyword_info<double>{}.init(1.0).mult(
true)},
304 {
"MULTY-", keyword_info<double>{}.init(1.0).mult(
true)},
305 {
"MULTZ", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)},
306 {
"MULTZ-", keyword_info<double>{}.init(1.0).mult(
true).global_kw(
true)}};
308 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{
"ROCKNUM", keyword_info<int>{}}};
312 template <
typename T>
313 keyword_info<T> global_kw_info(
const std::string& name,
bool allow_unsupported =
false);
315 bool is_oper_keyword(
const std::string& name);
323 using ScalarOperation = Fieldprops::ScalarOperation;
328 std::string region_name;
339 return this->region_value == other.region_value &&
340 this->multiplier == other.multiplier &&
341 this->region_name == other.region_name;
416 const std::string& descr,
417 const std::string& operation)
const 419 switch (this->status) {
425 descr +
" " + this->keyword +
426 " is not fully initialised for " + operation,
432 descr +
" " + this->keyword +
433 " does not exist in input deck for " + operation,
439 descr +
" " + this->keyword +
440 " is not supported for " + operation,
458 throw std::runtime_error(
"The keyword: " +
keyword +
" has not been fully initialized");
461 throw std::out_of_range(
"No such keyword in deck: " +
keyword);
464 throw std::logic_error(
"The keyword " +
keyword +
" is not supported");
471 const std::vector<T>*
ptr()
const 473 return (this->data_ptr !=
nullptr)
474 ? &this->data_ptr->data
482 const std::vector<T>&
data()
const 485 return this->data_ptr->data;
533 const std::size_t ncomps);
538 void reset_actnum(
const std::vector<int>& actnum);
540 void prune_global_for_schedule_run();
544 const std::string& default_region()
const;
546 std::vector<int> actnum();
547 const std::vector<int>& actnumRaw()
const;
549 template <
typename T>
550 static bool supported(
const std::string& keyword);
552 template <
typename T>
553 bool has(
const std::string& keyword)
const;
555 template <
typename T>
556 std::vector<std::string> keys()
const;
570 template <
typename T>
572 try_get(
const std::string& keyword,
const unsigned int flags = 0u)
574 const auto allow_unsupported =
575 (flags & TryGetFlags::AllowUnsupported) != 0u;
577 if (!allow_unsupported && !FieldProps::template supported<T>(keyword)) {
581 const auto has0 = this->
template has<T>(keyword);
582 if (!has0 && ((flags & TryGetFlags::MustExist) != 0)) {
589 const auto& field_data = this->
template 590 init_get<T>(keyword, std::is_same_v<T, double> && allow_unsupported);
592 if (field_data.valid() || allow_unsupported) {
601 this->
template erase<T>(keyword);
611 template <
typename T>
612 const std::vector<T>&
get(
const std::string& keyword)
614 return this->
template try_get<T>(keyword).data();
617 template <
typename T>
618 std::vector<T> get_global(
const std::string& keyword)
620 const auto managed_field_data = this->
template try_get<T>(keyword);
621 const auto& field_data = managed_field_data.field_data();
623 const auto& kw_info = Fieldprops::keywords::
624 template global_kw_info<T>(keyword);
626 return kw_info.global
627 ? *field_data.global_data
628 : this->global_copy(field_data.data, kw_info.scalar_init);
631 template <
typename T>
632 std::vector<T> get_copy(
const std::string& keyword,
bool global)
634 const auto has0 = this->
template has<T>(keyword);
644 const auto& field_data = this->
template try_get<T>(keyword).field_data();
647 return this->get_copy(field_data.data, field_data.kw_info.scalar_init, global);
650 const auto initial_value = Fieldprops::keywords::
651 template global_kw_info<T>(keyword).scalar_init;
653 return this->get_copy(this->
template extract<T>(keyword), initial_value, global);
656 template <
typename T>
657 std::vector<bool> defaulted(
const std::string& keyword)
659 const auto& field = this->
template init_get<T>(keyword);
660 std::vector<bool> def(field.numCells());
662 for (std::size_t i = 0; i < def.size(); ++i) {
663 def[i] = value::defaulted(field.value_status[i]);
669 template <
typename T>
670 std::vector<T> global_copy(
const std::vector<T>& data,
671 const std::optional<T>& default_value)
const 673 const T fill_value = default_value.has_value() ? *default_value : 0;
675 std::vector<T> global_data(this->global_size, fill_value);
678 for (std::size_t g = 0; g < this->global_size; g++) {
679 if (this->m_actnum[g]) {
680 global_data[g] = data[i];
688 std::size_t active_size;
689 std::size_t global_size;
691 void handle_schedule_keywords(
const std::vector<DeckKeyword>& keywords);
692 bool tran_active(
const std::string& keyword)
const;
693 void apply_tran(
const std::string& keyword, std::vector<double>& data);
694 void apply_tranz_global(
const std::vector<std::size_t>& indices, std::vector<double>& data)
const;
695 bool operator==(
const FieldProps& other)
const;
698 const std::unordered_map<std::string,Fieldprops::TranCalculator>& getTran()
const 703 std::vector<std::string> fip_regions()
const;
707 bool depth_edited()
const 709 return this->depth_edited_;
712 void set_active_indices(
const std::vector<int>& indices);
715 void processMULTREGP(
const Deck& deck);
716 void scanGRIDSection(
const GRIDSection& grid_section);
717 void scanGRIDSectionOnlyACTNUM(
const GRIDSection& grid_section);
718 void initialize_depth_from_grid();
719 void scanEDITSection(
const EDITSection& edit_section);
720 void scanPROPSSection(
const PROPSSection& props_section);
721 void scanREGIONSSection(
const REGIONSSection& regions_section);
722 void scanSOLUTIONSection(
const SOLUTIONSection& solution_section,
const std::size_t ncomps);
723 double getSIValue(
const std::string& keyword,
double raw_value)
const;
724 double getSIValue(ScalarOperation op,
const std::string& keyword,
double raw_value)
const;
726 template <
typename T>
727 void erase(
const std::string& keyword);
729 template <
typename T>
730 std::vector<T> extract(
const std::string& keyword);
732 template <
typename T>
733 std::vector<T> get_copy(
const std::vector<T>& x,
734 const std::optional<T>& initial_value,
735 const bool global)
const 737 return (! global) ? x : this->global_copy(x, initial_value);
740 template <
typename T>
741 std::vector<T> get_copy(std::vector<T>&& x,
742 const std::optional<T>& initial_value,
743 const bool global)
const 745 return (! global) ? std::move(x) : this->global_copy(x, initial_value);
748 template <
typename T>
749 void operate(
const DeckRecord& record,
750 Fieldprops::FieldData<T>& target_data,
751 const Fieldprops::FieldData<T>& src_data,
752 const std::vector<Box::cell_index>& index_list,
753 const bool global =
false);
755 void operate_int_target(
const DeckRecord& record,
756 Fieldprops::FieldData<int>& target_data,
757 const std::string& src_kw,
758 const std::vector<Box::cell_index>& index_list,
759 const bool global =
false);
761 template <
typename T>
762 Fieldprops::FieldData<T>&
763 init_get(
const std::string& keyword,
bool allow_unsupported =
false);
765 template <
typename T>
766 Fieldprops::FieldData<T>&
767 init_get(
const std::string& keyword,
768 const Fieldprops::keywords::keyword_info<T>& kw_info,
769 const bool multiplier_in_edit =
false);
771 std::string region_name(
const DeckItem& region_item)
const;
773 std::pair<std::vector<Box::cell_index>,
bool>
774 region_index(
const std::string& region_name,
int region_value);
776 void handle_OPERATE(Section section,
const DeckKeyword& keyword, Box box);
777 void handle_operation(Section section,
const DeckKeyword& keyword, Box box);
778 void handle_operateR(Section section,
const DeckKeyword& keyword);
779 void handle_region_operation(Section section,
const DeckKeyword& keyword);
780 void handle_COPY(Section section,
const DeckKeyword& keyword, Box box,
bool region);
781 void distribute_toplayer(Fieldprops::FieldData<double>& field_data,
782 const std::vector<double>& deck_data,
785 void handle_keyword(Section section,
const DeckKeyword& keyword, Box& box);
786 void handle_double_keyword(Section section,
787 const Fieldprops::keywords::keyword_info<double>& kw_info,
788 const DeckKeyword& keyword,
789 const std::string& keyword_name,
792 void handle_double_keyword(Section section,
793 const Fieldprops::keywords::keyword_info<double>& kw_info,
794 const DeckKeyword& keyword,
797 void handle_int_keyword(
const Fieldprops::keywords::keyword_info<int>& kw_info,
798 const DeckKeyword& keyword,
801 void init_satfunc(
const std::string& keyword, Fieldprops::FieldData<double>& satfunc);
802 void init_porv(Fieldprops::FieldData<double>& porv);
803 void init_tempi(Fieldprops::FieldData<double>& tempi);
805 std::string canonical_fipreg_name(
const std::string& fipreg);
806 const std::string& canonical_fipreg_name(
const std::string& fipreg)
const;
813 void apply_multipliers();
815 static constexpr std::string_view getMultiplierPrefix()
817 using namespace std::literals;
821 void resetWorkArrays();
823 const UnitSystem unit_system;
824 std::size_t nx,ny,nz;
826 SatFuncControls m_satfuncctrl;
827 std::vector<int> m_actnum;
828 std::unordered_map<int,int> m_active_index;
829 std::vector<double> cell_volume;
830 const std::string m_default_region;
831 const EclipseGrid * grid_ptr;
833 std::optional<satfunc::RawTableEndPoints> m_rtep;
834 std::vector<MultregpRecord> multregp;
835 std::unordered_map<std::string, Fieldprops::FieldData<int>> int_data;
836 std::unordered_map<std::string, Fieldprops::FieldData<double>> double_data;
837 std::unordered_map<std::string, std::string> fipreg_shortname_translation{};
842 std::unordered_map<std::string, Fieldprops::FieldData<double>> work_arrays{};
844 std::unordered_map<std::string,Fieldprops::TranCalculator> tran;
846 bool depth_edited_ =
false;
853 std::unordered_map<std::string,Fieldprops::keywords::keyword_info<double>> multiplier_kw_infos_;
void verify_status() const
Validate result of.
Definition: FieldProps.hpp:451
Named property is not known to the internal handling mechanism.
bool valid() const
Property validity predicate.
Definition: FieldProps.hpp:502
Definition: KeywordLocation.hpp:27
GetStatus
Property array existence status.
Definition: FieldProps.hpp:346
Property has not yet been defined in the input file.
Property array has not been fully initialised.
About cell information and dimension: The actual grid information is held in a pointer to an ERT ecl_...
Definition: EclipseGrid.hpp:63
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:30
Wrapper type for field properties.
Definition: FieldProps.hpp:381
const std::vector< T > & data() const
Access underlying property data elements.
Definition: FieldProps.hpp:482
const Fieldprops::FieldData< T > & field_data() const
Read-only access to contained FieldData object.
Definition: FieldProps.hpp:492
Whether or not to permit looking up property names of unmatching types.
Definition: FieldProps.hpp:522
Whether or not the property must already exist.
Definition: FieldProps.hpp:525
GetStatus status
Request status.
Definition: FieldProps.hpp:387
FieldDataManager(const std::string &k, GetStatus s, const Fieldprops::FieldData< T > *d)
Constructor.
Definition: FieldProps.hpp:397
FieldProps(const Deck &deck, const Phases &phases, EclipseGrid &grid, const TableManager &table_arg, const std::size_t ncomps)
Normal constructor for FieldProps.
Definition: FieldProps.cpp:853
Definition: TableManager.hpp:71
const std::vector< T > * ptr() const
Access underlying property data elements.
Definition: FieldProps.hpp:471
Definition: FieldProps.hpp:320
Definition: FieldData.hpp:71
TryGetFlags
Options to restrict or relax a try_get() request.
Definition: FieldProps.hpp:519
void verify_status(const KeywordLocation &loc, const std::string &descr, const std::string &operation) const
Validate result of.
Definition: FieldProps.hpp:415
Property exists and its property data is fully defined.
Definition: FieldProps.hpp:325
const Fieldprops::FieldData< T > * data_ptr
Property data.
Definition: FieldProps.hpp:390
FieldDataManager< T > try_get(const std::string &keyword, const unsigned int flags=0u)
Request read-only property array from internal cache.
Definition: FieldProps.hpp:572
Definition: NumericalAquifers.hpp:36
const std::string & keyword
Property name.
Definition: FieldProps.hpp:384
Definition: Runspec.hpp:45