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  {"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)}};
198 
199 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
200 }
201 
202 namespace PROPS {
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 = {};
209 
210 #define dirfunc(base) base, base "X", base "X-", base "Y", base "Y-", base "Z", base "Z-"
211 
212 static const std::set<std::string> satfunc = {"SWLPC", "ISWLPC", "SGLPC", "ISGLPC",
213  dirfunc("SGL"),
214  dirfunc("ISGL"),
215  dirfunc("SGU"),
216  dirfunc("ISGU"),
217  dirfunc("SWL"),
218  dirfunc("ISWL"),
219  dirfunc("SWU"),
220  dirfunc("ISWU"),
221  dirfunc("SGCR"),
222  dirfunc("ISGCR"),
223  dirfunc("SOWCR"),
224  dirfunc("ISOWCR"),
225  dirfunc("SOGCR"),
226  dirfunc("ISOGCR"),
227  dirfunc("SWCR"),
228  dirfunc("ISWCR"),
229  dirfunc("KRW"),
230  dirfunc("IKRW"),
231  dirfunc("KRWR"),
232  dirfunc("IKRWR"),
233  dirfunc("KRO"),
234  dirfunc("IKRO"),
235  dirfunc("KRORW"),
236  dirfunc("IKRORW"),
237  dirfunc("KRORG"),
238  dirfunc("IKRORG"),
239  dirfunc("KRG"),
240  dirfunc("IKRG"),
241  dirfunc("KRGR"),
242  dirfunc("IKRGR")};
243 
244 #undef dirfunc
245 }
246 
247 namespace REGIONS {
248 
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>{}},
268  };
269 }
270 
271 namespace SOLUTION {
272 
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")}
291  };
292 
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>{}},
296  };
297 }
298 
299 namespace SCHEDULE {
300 
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)}};
307 
308 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{"ROCKNUM", keyword_info<int>{}}};
309 
310 }
311 
312 template <typename T>
313 keyword_info<T> global_kw_info(const std::string& name, bool allow_unsupported = false);
314 
315 bool is_oper_keyword(const std::string& name);
316 } // end namespace keywords
317 
318 } // end namespace Fieldprops
319 
320 class FieldProps {
321 public:
322 
323  using ScalarOperation = Fieldprops::ScalarOperation;
324 
325  struct MultregpRecord {
326  int region_value;
327  double multiplier;
328  std::string region_name;
329 
330 
331  MultregpRecord(int rv, double m, const std::string& rn) :
332  region_value(rv),
333  multiplier(m),
334  region_name(rn)
335  {}
336 
337 
338  bool operator==(const MultregpRecord& other) const {
339  return this->region_value == other.region_value &&
340  this->multiplier == other.multiplier &&
341  this->region_name == other.region_name;
342  }
343  };
344 
346  enum class GetStatus {
348  OK = 1,
349 
357  INVALID_DATA = 2,
358 
363  MISSING_KEYWORD = 3,
364 
375  };
376 
380  template<typename T>
382  {
384  const std::string& keyword;
385 
388 
391 
397  FieldDataManager(const std::string& k, GetStatus s, const Fieldprops::FieldData<T>* d)
398  : keyword(k)
399  , status(s)
400  , data_ptr(d)
401  {}
402 
416  const std::string& descr,
417  const std::string& operation) const
418  {
419  switch (this->status) {
421  return;
422 
424  throw OpmInputError {
425  descr + " " + this->keyword +
426  " is not fully initialised for " + operation,
427  loc
428  };
429 
431  throw OpmInputError {
432  descr + " " + this->keyword +
433  " does not exist in input deck for " + operation,
434  loc
435  };
436 
438  throw OpmInputError {
439  descr + " " + this->keyword +
440  " is not supported for " + operation,
441  loc
442  };
443  }
444  }
445 
451  void verify_status() const
452  {
453  switch (status) {
455  return;
456 
458  throw std::runtime_error("The keyword: " + keyword + " has not been fully initialized");
459 
461  throw std::out_of_range("No such keyword in deck: " + keyword);
462 
464  throw std::logic_error("The keyword " + keyword + " is not supported");
465  }
466  }
467 
471  const std::vector<T>* ptr() const
472  {
473  return (this->data_ptr != nullptr)
474  ? &this->data_ptr->data
475  : nullptr;
476  }
477 
482  const std::vector<T>& data() const
483  {
484  this->verify_status();
485  return this->data_ptr->data;
486  }
487 
493  {
494  this->verify_status();
495  return *this->data_ptr;
496  }
497 
502  bool valid() const
503  {
504  return this->status == GetStatus::OK;
505  }
506  };
507 
519  enum TryGetFlags : unsigned int {
522  AllowUnsupported = (1u << 0),
523 
525  MustExist = (1u << 1),
526  };
527 
529  FieldProps(const Deck& deck,
530  const Phases& phases,
531  EclipseGrid& grid,
532  const TableManager& table_arg,
533  const std::size_t ncomps);
534 
536  FieldProps(const Deck& deck, const EclipseGrid& grid);
537 
538  void reset_actnum(const std::vector<int>& actnum);
539 
540  void prune_global_for_schedule_run();
541 
542  void apply_numerical_aquifers(const NumericalAquifers& numerical_aquifers);
543 
544  const std::string& default_region() const;
545 
546  std::vector<int> actnum();
547  const std::vector<int>& actnumRaw() const;
548 
549  template <typename T>
550  static bool supported(const std::string& keyword);
551 
552  template <typename T>
553  bool has(const std::string& keyword) const;
554 
555  template <typename T>
556  std::vector<std::string> keys() const;
557 
570  template <typename T>
571  FieldDataManager<T>
572  try_get(const std::string& keyword, const unsigned int flags = 0u)
573  {
574  const auto allow_unsupported =
575  (flags & TryGetFlags::AllowUnsupported) != 0u;
576 
577  if (!allow_unsupported && !FieldProps::template supported<T>(keyword)) {
578  return { keyword, GetStatus::NOT_SUPPPORTED_KEYWORD, nullptr };
579  }
580 
581  const auto has0 = this->template has<T>(keyword);
582  if (!has0 && ((flags & TryGetFlags::MustExist) != 0)) {
583  // Client requested a property which must exist, e.g., as a
584  // source array for a COPY operation, but the property has not
585  // (yet) been defined in the run's input.
586  return { keyword, GetStatus::MISSING_KEYWORD, nullptr };
587  }
588 
589  const auto& field_data = this->template
590  init_get<T>(keyword, std::is_same_v<T, double> && allow_unsupported);
591 
592  if (field_data.valid() || allow_unsupported) {
593  // Note: FieldDataManager depends on init_get<>() producing a
594  // long-lived FieldData instance.
595  return { keyword, GetStatus::OK, &field_data };
596  }
597 
598  if (! has0) {
599  // Client requested a property which did not exist and which
600  // could not be created from a default description.
601  this->template erase<T>(keyword);
602 
603  return { keyword, GetStatus::MISSING_KEYWORD, nullptr };
604  }
605 
606  // If we get here then the property exists but has not been fully
607  // defined yet.
608  return { keyword, GetStatus::INVALID_DATA, nullptr };
609  }
610 
611  template <typename T>
612  const std::vector<T>& get(const std::string& keyword)
613  {
614  return this->template try_get<T>(keyword).data();
615  }
616 
617  template <typename T>
618  std::vector<T> get_global(const std::string& keyword)
619  {
620  const auto managed_field_data = this->template try_get<T>(keyword);
621  const auto& field_data = managed_field_data.field_data();
622 
623  const auto& kw_info = Fieldprops::keywords::
624  template global_kw_info<T>(keyword);
625 
626  return kw_info.global
627  ? *field_data.global_data
628  : this->global_copy(field_data.data, kw_info.scalar_init);
629  }
630 
631  template <typename T>
632  std::vector<T> get_copy(const std::string& keyword, bool global)
633  {
634  const auto has0 = this->template has<T>(keyword);
635 
636  // Recall: FieldDataManager::field_data() will throw various
637  // exception types if the 'status' is anything other than 'OK'.
638  //
639  // Get_copy() depends on this behaviour to not proceed to extracting
640  // values in such cases. In other words, get_copy() uses exceptions
641  // for control flow, and we cannot move this try_get() call into the
642  // 'has0' branch even though the actual 'field_data' object returned
643  // from try_get() is only needed/used there.
644  const auto& field_data = this->template try_get<T>(keyword).field_data();
645 
646  if (has0) {
647  return this->get_copy(field_data.data, field_data.kw_info.scalar_init, global);
648  }
649 
650  const auto initial_value = Fieldprops::keywords::
651  template global_kw_info<T>(keyword).scalar_init;
652 
653  return this->get_copy(this->template extract<T>(keyword), initial_value, global);
654  }
655 
656  template <typename T>
657  std::vector<bool> defaulted(const std::string& keyword)
658  {
659  const auto& field = this->template init_get<T>(keyword);
660  std::vector<bool> def(field.numCells());
661 
662  for (std::size_t i = 0; i < def.size(); ++i) {
663  def[i] = value::defaulted(field.value_status[i]);
664  }
665 
666  return def;
667  }
668 
669  template <typename T>
670  std::vector<T> global_copy(const std::vector<T>& data,
671  const std::optional<T>& default_value) const
672  {
673  const T fill_value = default_value.has_value() ? *default_value : 0;
674 
675  std::vector<T> global_data(this->global_size, fill_value);
676 
677  std::size_t i = 0;
678  for (std::size_t g = 0; g < this->global_size; g++) {
679  if (this->m_actnum[g]) {
680  global_data[g] = data[i];
681  ++i;
682  }
683  }
684 
685  return global_data;
686  }
687 
688  std::size_t active_size;
689  std::size_t global_size;
690 
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;
696  static bool rst_cmp(const FieldProps& full_arg, const FieldProps& rst_arg);
697 
698  const std::unordered_map<std::string,Fieldprops::TranCalculator>& getTran() const
699  {
700  return tran;
701  }
702 
703  std::vector<std::string> fip_regions() const;
704 
705  void deleteMINPVV();
706 
707  bool depth_edited() const
708  {
709  return this->depth_edited_;
710  }
711 
712  void set_active_indices(const std::vector<int>& indices);
713 
714 private:
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;
725 
726  template <typename T>
727  void erase(const std::string& keyword);
728 
729  template <typename T>
730  std::vector<T> extract(const std::string& keyword);
731 
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
736  {
737  return (! global) ? x : this->global_copy(x, initial_value);
738  }
739 
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
744  {
745  return (! global) ? std::move(x) : this->global_copy(x, initial_value);
746  }
747 
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);
754 
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);
760 
761  template <typename T>
762  Fieldprops::FieldData<T>&
763  init_get(const std::string& keyword, bool allow_unsupported = false);
764 
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);
770 
771  std::string region_name(const DeckItem& region_item) const;
772 
773  std::pair<std::vector<Box::cell_index>,bool>
774  region_index(const std::string& region_name, int region_value);
775 
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,
783  const Box& box);
784 
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,
790  const Box& box);
791 
792  void handle_double_keyword(Section section,
793  const Fieldprops::keywords::keyword_info<double>& kw_info,
794  const DeckKeyword& keyword,
795  const Box& box);
796 
797  void handle_int_keyword(const Fieldprops::keywords::keyword_info<int>& kw_info,
798  const DeckKeyword& keyword,
799  const Box& box);
800 
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);
804 
805  std::string canonical_fipreg_name(const std::string& fipreg);
806  const std::string& canonical_fipreg_name(const std::string& fipreg) const;
807 
813  void apply_multipliers();
814 
815  static constexpr std::string_view getMultiplierPrefix()
816  {
817  using namespace std::literals;
818  return "__MULT__"sv;
819  }
820 
821  void resetWorkArrays();
822 
823  const UnitSystem unit_system;
824  std::size_t nx,ny,nz;
825  Phases m_phases;
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; // A bit undecided whether to properly use the grid or not ...
832  TableManager tables;
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{};
838 
842  std::unordered_map<std::string, Fieldprops::FieldData<double>> work_arrays{};
843 
844  std::unordered_map<std::string,Fieldprops::TranCalculator> tran;
845 
846  bool depth_edited_ = false;
847 
853  std::unordered_map<std::string,Fieldprops::keywords::keyword_info<double>> multiplier_kw_infos_;
854 };
855 
856 }
857 #endif
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: OpmInputError.hpp:48
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
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:572
Definition: NumericalAquifers.hpp:36
const std::string & keyword
Property name.
Definition: FieldProps.hpp:384
Definition: Runspec.hpp:45