opm-common
FieldProps.hpp
1 /*
2  Copyright 2019 Equinor ASA.
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 it under the terms
7  of the GNU General Public License as published by the Free Software
8  Foundation, either version 3 of the License, or (at your option) any later
9  version.
10 
11  OPM is distributed in the hope that it will be useful, but WITHOUT ANY
12  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
13  A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License along with
16  OPM. If not, see <http://www.gnu.org/licenses/>.
17 */
18 
19 #ifndef FIELDPROPS_HPP
20 #define FIELDPROPS_HPP
21 
22 #include <opm/common/utility/OpmInputError.hpp>
23 
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>
31 
32 #include <opm/input/eclipse/Units/UnitSystem.hpp>
33 
34 #include <opm/input/eclipse/Deck/DeckSection.hpp>
35 #include <opm/input/eclipse/Deck/value_status.hpp>
36 
37 #include <cstddef>
38 #include <limits>
39 #include <map>
40 #include <memory>
41 #include <optional>
42 #include <set>
43 #include <stdexcept>
44 #include <string>
45 #include <string_view>
46 #include <type_traits>
47 #include <unordered_map>
48 #include <unordered_set>
49 #include <utility>
50 #include <vector>
51 
52 namespace Opm {
53 
54 class Deck;
55 class EclipseGrid;
56 class NumericalAquifers;
57 
58 namespace Fieldprops
59 {
60 
61 namespace keywords {
62 
63 /*
64  Regarding global keywords
65  =========================
66 
67  It turns out that when the option 'ALL' is used for the PINCH keyword we
68  require the MULTZ keyword specified for all cells, also the inactive cells.
69  The premise for the FieldProps implementation has all the way been that only
70  the active cells should be stored.
71 
72  In order to support the ALL option of the PINCH keyword we have bolted on a
73  limited support for global storage. By setting .global = true in the
74  keyword_info describing the keyword you get:
75 
76  1. Normal deck assignment like
77 
78  MULTZ
79  ..... /
80 
81  2. Scalar operations like EQUALS and MULTIPLY.
82 
83  These operations also support the full details of the BOX behavior.
84 
85  The following operations do not work
86  ------------------------------------
87 
88  1. Operations involving multiple keywords like
89 
90  COPY
91  MULTX MULTZ /
92  /
93 
94  this also includes the OPERATE which involves multiple keywords for some
95  of its operations.
96 
97  2. All region operatins like EQUALREG and MULTREG.
98 
99  The operations which are not properly implemented will be intercepted and a
100  std::logic_error() exception will be thrown.
101 */
102 
103 
104 
105 inline bool isFipxxx(const std::string& keyword) {
106  // FIPxxxx can be any keyword, e.g. FIPREG or FIPXYZ that has the pattern "FIP.+"
107  // However, it can not be FIPOWG as that is an actual keyword.
108  if (keyword.size() < 4 || keyword == "FIPOWG") {
109  return false;
110  }
111  return keyword[0] == 'F' && keyword[1] == 'I' && keyword[2] == 'P';
112 }
113 
114 
115 /*
116  The aliased_keywords map defines aliases for other keywords. The FieldProps
117  objects will translate those keywords before further processing. The aliases
118  will also be exposed by the FieldPropsManager object.
119 
120  However, the following methods of FieldProps do not fully support aliases:
121  - FieldProps::keys() does not return the aliases.
122  - FieldProps::erase() and FieldProps::extract() do not support aliases. Using
123  them with an aliased keyword will also remove the alias.
124 
125  Note that the aliases are also added to GRID::double_keywords.
126 
127  The PERMR and PERMTHT keywords are aliases for PERMX and PERMY, respectively.
128 */
129 namespace ALIAS {
130  static const std::unordered_map<std::string, std::string> aliased_keywords = {{"PERMR", "PERMX"},
131  {"PERMTHT", "PERMY"}};
132 }
133 
134 
135 namespace GRID {
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)}};
170 
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>{}}};
177 
178 }
179 
180 namespace EDIT {
181 
182 /*
183  The TRANX, TRANY and TRANZ properties are handled very differently from the
184  other properties. It is important that these fields are not entered into the
185  double_keywords list of the EDIT section, that way we risk silent failures
186  due to the special treatment of the TRAN fields.
187 */
188 
189 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"MULTPV", keyword_info<double>{}.init(1.0).mult(true)},
190  {"PORV", keyword_info<double>{}.unit_string("ReservoirVolume")},
191  {"MULTX", keyword_info<double>{}.init(1.0).mult(true)},
192  {"MULTX-", keyword_info<double>{}.init(1.0).mult(true)},
193  {"MULTY", keyword_info<double>{}.init(1.0).mult(true)},
194  {"MULTY-", keyword_info<double>{}.init(1.0).mult(true)},
195  {"MULTZ", keyword_info<double>{}.init(1.0).mult(true).global_kw(true)},
196  {"MULTZ-", keyword_info<double>{}.init(1.0).mult(true).global_kw(true)}};
197 
198 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
199 }
200 
201 namespace PROPS {
202 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"SWATINIT", keyword_info<double>{}},
203  {"PCG", keyword_info<double>{}.unit_string("Pressure")},
204  {"IPCG", keyword_info<double>{}.unit_string("Pressure")},
205  {"PCW", keyword_info<double>{}.unit_string("Pressure")},
206  {"IPCW", keyword_info<double>{}.unit_string("Pressure")}};
207 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
208 
209 #define dirfunc(base) base, base "X", base "X-", base "Y", base "Y-", base "Z", base "Z-"
210 
211 static const std::set<std::string> satfunc = {"SWLPC", "ISWLPC", "SGLPC", "ISGLPC",
212  dirfunc("SGL"),
213  dirfunc("ISGL"),
214  dirfunc("SGU"),
215  dirfunc("ISGU"),
216  dirfunc("SWL"),
217  dirfunc("ISWL"),
218  dirfunc("SWU"),
219  dirfunc("ISWU"),
220  dirfunc("SGCR"),
221  dirfunc("ISGCR"),
222  dirfunc("SOWCR"),
223  dirfunc("ISOWCR"),
224  dirfunc("SOGCR"),
225  dirfunc("ISOGCR"),
226  dirfunc("SWCR"),
227  dirfunc("ISWCR"),
228  dirfunc("KRW"),
229  dirfunc("IKRW"),
230  dirfunc("KRWR"),
231  dirfunc("IKRWR"),
232  dirfunc("KRO"),
233  dirfunc("IKRO"),
234  dirfunc("KRORW"),
235  dirfunc("IKRORW"),
236  dirfunc("KRORG"),
237  dirfunc("IKRORG"),
238  dirfunc("KRG"),
239  dirfunc("IKRG"),
240  dirfunc("KRGR"),
241  dirfunc("IKRGR")};
242 
243 #undef dirfunc
244 }
245 
246 namespace REGIONS {
247 
248 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{"ENDNUM", keyword_info<int>{}.init(1)},
249  {"EOSNUM", keyword_info<int>{}.init(1)},
250  {"EQLNUM", keyword_info<int>{}.init(1)},
251  {"FIPNUM", keyword_info<int>{}.init(1)},
252  {"IMBNUM", keyword_info<int>{}.init(1)},
253  {"OPERNUM", keyword_info<int>{}},
254  {"STRESSEQUILNUM", keyword_info<int>{}.init(1)},
255  {"MISCNUM", keyword_info<int>{}},
256  {"MISCNUM", keyword_info<int>{}},
257  {"PVTNUM", keyword_info<int>{}.init(1)},
258  {"SATNUM", keyword_info<int>{}.init(1)},
259  {"LWSLTNUM", keyword_info<int>{}},
260  {"ROCKNUM", keyword_info<int>{}},
261  {"KRNUMX", keyword_info<int>{}},
262  {"KRNUMY", keyword_info<int>{}},
263  {"KRNUMZ", keyword_info<int>{}},
264  {"IMBNUMX", keyword_info<int>{}},
265  {"IMBNUMY", keyword_info<int>{}},
266  {"IMBNUMZ", keyword_info<int>{}},
267  };
268 }
269 
270 namespace SOLUTION {
271 
272 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"PRESSURE", keyword_info<double>{}.unit_string("Pressure")},
273  {"SPOLY", keyword_info<double>{}.unit_string("Concentration")},
274  {"SPOLYMW", keyword_info<double>{}},
275  {"SSOL", keyword_info<double>{}},
276  {"SWAT", keyword_info<double>{}},
277  {"SGAS", keyword_info<double>{}},
278  {"SMICR", keyword_info<double>{}.unit_string("Concentration")},
279  {"SOXYG", keyword_info<double>{}.unit_string("Concentration")},
280  {"SUREA", keyword_info<double>{}.unit_string("Concentration")},
281  {"SBIOF", keyword_info<double>{}},
282  {"SCALC", keyword_info<double>{}},
283  {"SALTP", keyword_info<double>{}},
284  {"SALT", keyword_info<double>{}.unit_string("Concentration")},
285  {"TEMPI", keyword_info<double>{}.unit_string("Temperature")},
286  {"RS", keyword_info<double>{}.unit_string("GasDissolutionFactor")},
287  {"RSW", keyword_info<double>{}.unit_string("GasDissolutionFactor")},
288  {"RV", keyword_info<double>{}.unit_string("OilDissolutionFactor")},
289  {"RVW", keyword_info<double>{}.unit_string("OilDissolutionFactor")}
290  };
291 
292 static const std::unordered_map<std::string, keyword_info<double>> composition_keywords = {{"XMF", keyword_info<double>{}},
293  {"YMF", keyword_info<double>{}},
294  {"ZMF", keyword_info<double>{}},
295  };
296 }
297 
298 namespace SCHEDULE {
299 
300 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"MULTX", keyword_info<double>{}.init(1.0).mult(true)},
301  {"MULTX-", keyword_info<double>{}.init(1.0).mult(true)},
302  {"MULTY", keyword_info<double>{}.init(1.0).mult(true)},
303  {"MULTY-", keyword_info<double>{}.init(1.0).mult(true)},
304  {"MULTZ", keyword_info<double>{}.init(1.0).mult(true).global_kw(true)},
305  {"MULTZ-", keyword_info<double>{}.init(1.0).mult(true).global_kw(true)}};
306 
307 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{"ROCKNUM", keyword_info<int>{}}};
308 
309 }
310 
311 template <typename T>
312 keyword_info<T> global_kw_info(const std::string& name, bool allow_unsupported = false);
313 
314 bool is_oper_keyword(const std::string& name);
315 } // end namespace keywords
316 
317 } // end namespace Fieldprops
318 
319 class FieldProps {
320 public:
321 
322  using ScalarOperation = Fieldprops::ScalarOperation;
323 
324  struct MultregpRecord {
325  int region_value;
326  double multiplier;
327  std::string region_name;
328 
329 
330  MultregpRecord(int rv, double m, const std::string& rn) :
331  region_value(rv),
332  multiplier(m),
333  region_name(rn)
334  {}
335 
336 
337  bool operator==(const MultregpRecord& other) const {
338  return this->region_value == other.region_value &&
339  this->multiplier == other.multiplier &&
340  this->region_name == other.region_name;
341  }
342  };
343 
345  enum class GetStatus {
347  OK = 1,
348 
356  INVALID_DATA = 2,
357 
362  MISSING_KEYWORD = 3,
363 
374  };
375 
379  template<typename T>
381  {
383  const std::string& keyword;
384 
387 
390 
396  FieldDataManager(const std::string& k, GetStatus s, const Fieldprops::FieldData<T>* d)
397  : keyword(k)
398  , status(s)
399  , data_ptr(d)
400  {}
401 
415  const std::string& descr,
416  const std::string& operation) const
417  {
418  switch (this->status) {
420  return;
421 
423  throw OpmInputError {
424  descr + " " + this->keyword +
425  " is not fully initialised for " + operation,
426  loc
427  };
428 
430  throw OpmInputError {
431  descr + " " + this->keyword +
432  " does not exist in input deck for " + operation,
433  loc
434  };
435 
437  throw OpmInputError {
438  descr + " " + this->keyword +
439  " is not supported for " + operation,
440  loc
441  };
442  }
443  }
444 
450  void verify_status() const
451  {
452  switch (status) {
454  return;
455 
457  throw std::runtime_error("The keyword: " + keyword + " has not been fully initialized");
458 
460  throw std::out_of_range("No such keyword in deck: " + keyword);
461 
463  throw std::logic_error("The keyword " + keyword + " is not supported");
464  }
465  }
466 
470  const std::vector<T>* ptr() const
471  {
472  return (this->data_ptr != nullptr)
473  ? &this->data_ptr->data
474  : nullptr;
475  }
476 
481  const std::vector<T>& data() const
482  {
483  this->verify_status();
484  return this->data_ptr->data;
485  }
486 
492  {
493  this->verify_status();
494  return *this->data_ptr;
495  }
496 
501  bool valid() const
502  {
503  return this->status == GetStatus::OK;
504  }
505  };
506 
518  enum TryGetFlags : unsigned int {
521  AllowUnsupported = (1u << 0),
522 
524  MustExist = (1u << 1),
525  };
526 
528  FieldProps(const Deck& deck,
529  const Phases& phases,
530  EclipseGrid& grid,
531  const TableManager& table_arg,
532  const std::size_t ncomps);
533 
535  FieldProps(const Deck& deck, const EclipseGrid& grid);
536 
537  void reset_actnum(const std::vector<int>& actnum);
538 
539  void prune_global_for_schedule_run();
540 
541  void apply_numerical_aquifers(const NumericalAquifers& numerical_aquifers);
542 
543  const std::string& default_region() const;
544 
545  std::vector<int> actnum();
546  const std::vector<int>& actnumRaw() const;
547 
548  template <typename T>
549  static bool supported(const std::string& keyword);
550 
551  template <typename T>
552  bool has(const std::string& keyword) const;
553 
554  template <typename T>
555  std::vector<std::string> keys() const;
556 
569  template <typename T>
570  FieldDataManager<T>
571  try_get(const std::string& keyword, const unsigned int flags = 0u)
572  {
573  const auto allow_unsupported =
574  (flags & TryGetFlags::AllowUnsupported) != 0u;
575 
576  if (!allow_unsupported && !FieldProps::template supported<T>(keyword)) {
577  return { keyword, GetStatus::NOT_SUPPPORTED_KEYWORD, nullptr };
578  }
579 
580  const auto has0 = this->template has<T>(keyword);
581  if (!has0 && ((flags & TryGetFlags::MustExist) != 0)) {
582  // Client requested a property which must exist, e.g., as a
583  // source array for a COPY operation, but the property has not
584  // (yet) been defined in the run's input.
585  return { keyword, GetStatus::MISSING_KEYWORD, nullptr };
586  }
587 
588  const auto& field_data = this->template
589  init_get<T>(keyword, std::is_same_v<T, double> && allow_unsupported);
590 
591  if (field_data.valid() || allow_unsupported) {
592  // Note: FieldDataManager depends on init_get<>() producing a
593  // long-lived FieldData instance.
594  return { keyword, GetStatus::OK, &field_data };
595  }
596 
597  if (! has0) {
598  // Client requested a property which did not exist and which
599  // could not be created from a default description.
600  this->template erase<T>(keyword);
601 
602  return { keyword, GetStatus::MISSING_KEYWORD, nullptr };
603  }
604 
605  // If we get here then the property exists but has not been fully
606  // defined yet.
607  return { keyword, GetStatus::INVALID_DATA, nullptr };
608  }
609 
610  template <typename T>
611  const std::vector<T>& get(const std::string& keyword)
612  {
613  return this->template try_get<T>(keyword).data();
614  }
615 
616  template <typename T>
617  std::vector<T> get_global(const std::string& keyword)
618  {
619  const auto managed_field_data = this->template try_get<T>(keyword);
620  const auto& field_data = managed_field_data.field_data();
621 
622  const auto& kw_info = Fieldprops::keywords::
623  template global_kw_info<T>(keyword);
624 
625  return kw_info.global
626  ? *field_data.global_data
627  : this->global_copy(field_data.data, kw_info.scalar_init);
628  }
629 
630  template <typename T>
631  std::vector<T> get_copy(const std::string& keyword, bool global)
632  {
633  const auto has0 = this->template has<T>(keyword);
634 
635  // Recall: FieldDataManager::field_data() will throw various
636  // exception types if the 'status' is anything other than 'OK'.
637  //
638  // Get_copy() depends on this behaviour to not proceed to extracting
639  // values in such cases. In other words, get_copy() uses exceptions
640  // for control flow, and we cannot move this try_get() call into the
641  // 'has0' branch even though the actual 'field_data' object returned
642  // from try_get() is only needed/used there.
643  const auto& field_data = this->template try_get<T>(keyword).field_data();
644 
645  if (has0) {
646  return this->get_copy(field_data.data, field_data.kw_info.scalar_init, global);
647  }
648 
649  const auto initial_value = Fieldprops::keywords::
650  template global_kw_info<T>(keyword).scalar_init;
651 
652  return this->get_copy(this->template extract<T>(keyword), initial_value, global);
653  }
654 
655  template <typename T>
656  std::vector<bool> defaulted(const std::string& keyword)
657  {
658  const auto& field = this->template init_get<T>(keyword);
659  std::vector<bool> def(field.numCells());
660 
661  for (std::size_t i = 0; i < def.size(); ++i) {
662  def[i] = value::defaulted(field.value_status[i]);
663  }
664 
665  return def;
666  }
667 
668  template <typename T>
669  std::vector<T> global_copy(const std::vector<T>& data,
670  const std::optional<T>& default_value) const
671  {
672  const T fill_value = default_value.has_value() ? *default_value : 0;
673 
674  std::vector<T> global_data(this->global_size, fill_value);
675 
676  std::size_t i = 0;
677  for (std::size_t g = 0; g < this->global_size; g++) {
678  if (this->m_actnum[g]) {
679  global_data[g] = data[i];
680  ++i;
681  }
682  }
683 
684  return global_data;
685  }
686 
687  std::size_t active_size;
688  std::size_t global_size;
689 
690  void handle_schedule_keywords(const std::vector<DeckKeyword>& keywords);
691  bool tran_active(const std::string& keyword) const;
692  void apply_tran(const std::string& keyword, std::vector<double>& data);
693  void apply_tranz_global(const std::vector<size_t>& indices, std::vector<double>& data) const;
694  bool operator==(const FieldProps& other) const;
695  static bool rst_cmp(const FieldProps& full_arg, const FieldProps& rst_arg);
696 
697  const std::unordered_map<std::string,Fieldprops::TranCalculator>& getTran() const
698  {
699  return tran;
700  }
701 
702  std::vector<std::string> fip_regions() const;
703 
704  void deleteMINPVV();
705 
706  void set_active_indices(const std::vector<int>& indices);
707 
708 private:
709  void processMULTREGP(const Deck& deck);
710  void scanGRIDSection(const GRIDSection& grid_section);
711  void scanGRIDSectionOnlyACTNUM(const GRIDSection& grid_section);
712  void scanEDITSection(const EDITSection& edit_section);
713  void scanPROPSSection(const PROPSSection& props_section);
714  void scanREGIONSSection(const REGIONSSection& regions_section);
715  void scanSOLUTIONSection(const SOLUTIONSection& solution_section, const std::size_t ncomps);
716  double getSIValue(const std::string& keyword, double raw_value) const;
717  double getSIValue(ScalarOperation op, const std::string& keyword, double raw_value) const;
718 
719  template <typename T>
720  void erase(const std::string& keyword);
721 
722  template <typename T>
723  std::vector<T> extract(const std::string& keyword);
724 
725  template <typename T>
726  std::vector<T> get_copy(const std::vector<T>& x,
727  const std::optional<T>& initial_value,
728  const bool global) const
729  {
730  return (! global) ? x : this->global_copy(x, initial_value);
731  }
732 
733  template <typename T>
734  std::vector<T> get_copy(std::vector<T>&& x,
735  const std::optional<T>& initial_value,
736  const bool global) const
737  {
738  return (! global) ? std::move(x) : this->global_copy(x, initial_value);
739  }
740 
741  template <typename T>
742  void operate(const DeckRecord& record,
743  Fieldprops::FieldData<T>& target_data,
744  const Fieldprops::FieldData<T>& src_data,
745  const std::vector<Box::cell_index>& index_list,
746  const bool global = false);
747 
748  template <typename T>
749  Fieldprops::FieldData<T>&
750  init_get(const std::string& keyword, bool allow_unsupported = false);
751 
752  template <typename T>
753  Fieldprops::FieldData<T>&
754  init_get(const std::string& keyword,
755  const Fieldprops::keywords::keyword_info<T>& kw_info,
756  const bool multiplier_in_edit = false);
757 
758  std::string region_name(const DeckItem& region_item) const;
759 
760  std::pair<std::vector<Box::cell_index>,bool>
761  region_index(const std::string& region_name, int region_value);
762 
763  void handle_OPERATE(const DeckKeyword& keyword, Box box);
764  void handle_operation(Section section, const DeckKeyword& keyword, Box box);
765  void handle_operateR(const DeckKeyword& keyword);
766  void handle_region_operation(const DeckKeyword& keyword);
767  void handle_COPY(const DeckKeyword& keyword, Box box, bool region);
768  void distribute_toplayer(Fieldprops::FieldData<double>& field_data,
769  const std::vector<double>& deck_data,
770  const Box& box);
771 
772  void handle_keyword(Section section, const DeckKeyword& keyword, Box& box);
773  void handle_double_keyword(Section section,
774  const Fieldprops::keywords::keyword_info<double>& kw_info,
775  const DeckKeyword& keyword,
776  const std::string& keyword_name,
777  const Box& box);
778 
779  void handle_double_keyword(Section section,
780  const Fieldprops::keywords::keyword_info<double>& kw_info,
781  const DeckKeyword& keyword,
782  const Box& box);
783 
784  void handle_int_keyword(const Fieldprops::keywords::keyword_info<int>& kw_info,
785  const DeckKeyword& keyword,
786  const Box& box);
787 
788  void init_satfunc(const std::string& keyword, Fieldprops::FieldData<double>& satfunc);
789  void init_porv(Fieldprops::FieldData<double>& porv);
790  void init_tempi(Fieldprops::FieldData<double>& tempi);
791 
792  std::string canonical_fipreg_name(const std::string& fipreg);
793  const std::string& canonical_fipreg_name(const std::string& fipreg) const;
794 
800  void apply_multipliers();
801 
802  static constexpr std::string_view getMultiplierPrefix()
803  {
804  using namespace std::literals;
805  return "__MULT__"sv;
806  }
807 
808  void resetWorkArrays();
809 
810  const UnitSystem unit_system;
811  std::size_t nx,ny,nz;
812  Phases m_phases;
813  SatFuncControls m_satfuncctrl;
814  std::vector<int> m_actnum;
815  std::unordered_map<int,int> m_active_index;
816  std::vector<double> cell_volume;
817  std::vector<double> cell_depth;
818  const std::string m_default_region;
819  const EclipseGrid * grid_ptr; // A bit undecided whether to properly use the grid or not ...
820  TableManager tables;
821  std::optional<satfunc::RawTableEndPoints> m_rtep;
822  std::vector<MultregpRecord> multregp;
823  std::unordered_map<std::string, Fieldprops::FieldData<int>> int_data;
824  std::unordered_map<std::string, Fieldprops::FieldData<double>> double_data;
825  std::unordered_map<std::string, std::string> fipreg_shortname_translation{};
826 
830  std::unordered_map<std::string, Fieldprops::FieldData<double>> work_arrays{};
831 
832  std::unordered_map<std::string,Fieldprops::TranCalculator> tran;
833 
839  std::unordered_map<std::string,Fieldprops::keywords::keyword_info<double>> multiplier_kw_infos_;
840 };
841 
842 }
843 #endif
void verify_status() const
Validate result of.
Definition: FieldProps.hpp:450
Named property is not known to the internal handling mechanism.
bool valid() const
Property validity predicate.
Definition: FieldProps.hpp:501
Definition: KeywordLocation.hpp:27
GetStatus
Property array existence status.
Definition: FieldProps.hpp:345
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:62
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:380
const std::vector< T > & data() const
Access underlying property data elements.
Definition: FieldProps.hpp:481
const Fieldprops::FieldData< T > & field_data() const
Read-only access to contained FieldData object.
Definition: FieldProps.hpp:491
Whether or not to permit looking up property names of unmatching types.
Definition: FieldProps.hpp:521
Whether or not the property must already exist.
Definition: FieldProps.hpp:524
GetStatus status
Request status.
Definition: FieldProps.hpp:386
FieldDataManager(const std::string &k, GetStatus s, const Fieldprops::FieldData< T > *d)
Constructor.
Definition: FieldProps.hpp:396
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:855
Definition: TableManager.hpp:66
const std::vector< T > * ptr() const
Access underlying property data elements.
Definition: FieldProps.hpp:470
Definition: FieldProps.hpp:319
Definition: OpmInputError.hpp:48
Definition: FieldData.hpp:71
TryGetFlags
Options to restrict or relax a try_get() request.
Definition: FieldProps.hpp:518
void verify_status(const KeywordLocation &loc, const std::string &descr, const std::string &operation) const
Validate result of.
Definition: FieldProps.hpp:414
Property exists and its property data is fully defined.
Definition: FieldProps.hpp:324
const Fieldprops::FieldData< T > * data_ptr
Property data.
Definition: FieldProps.hpp:389
Definition: Deck.hpp:46
FieldDataManager< T > try_get(const std::string &keyword, const unsigned int flags=0u)
Request read-only property array from internal cache.
Definition: FieldProps.hpp:571
Definition: NumericalAquifers.hpp:38
const std::string & keyword
Property name.
Definition: FieldProps.hpp:383
Definition: Runspec.hpp:45