My Project
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 <limits>
23 #include <optional>
24 #include <string>
25 #include <unordered_set>
26 #include <vector>
27 
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>
38 
39 namespace Opm {
40 
41 class Deck;
42 class EclipseGrid;
43 class NumericalAquifers;
44 
45 namespace Fieldprops
46 {
47 
48 namespace keywords {
49 
50 /*
51  Regarding global keywords
52  =========================
53 
54  It turns out that when the option 'ALL' is used for the PINCH keyword we
55  require the MULTZ keyword specified for all cells, also the inactive cells.
56  The premise for the FieldProps implementation has all the way been that only
57  the active cells should be stored.
58 
59  In order to support the ALL option of the PINCH keyword we have bolted on a
60  limited support for global storage. By setting .global = true in the
61  keyword_info describing the keyword you get:
62 
63  1. Normal deck assignment like
64 
65  MULTZ
66  ..... /
67 
68  2. Scalar operations like EQUALS and MULTIPLY.
69 
70  These operations also support the full details of the BOX behavior.
71 
72  The following operations do not work
73  ------------------------------------
74 
75  1. Operations involving multiple keywords like
76 
77  COPY
78  MULTX MULTZ /
79  /
80 
81  this also includes the OPERATE which involves multiple keywords for some
82  of its operations.
83 
84  2. All region operatins like EQUALREG and MULTREG.
85 
86  The operations which are not properly implemented will be intercepted and a
87  std::logic_error() exception will be thrown.
88 */
89 
90 
91 
92 inline bool isFipxxx(const std::string& keyword) {
93  // FIPxxxx can be any keyword, e.g. FIPREG or FIPXYZ that has the pattern "FIP.+"
94  // However, it can not be FIPOWG as that is an actual keyword.
95  if (keyword.size() < 4 || keyword == "FIPOWG") {
96  return false;
97  }
98  return keyword[0] == 'F' && keyword[1] == 'I' && keyword[2] == 'P';
99 }
100 
101 
102 /*
103  The aliased_keywords map defines aliases for other keywords. The FieldProps
104  objects will translate those keywords before further processing. The aliases
105  will also be exposed by the FieldPropsManager object.
106 
107  However, the following methods of FieldProps do not fully support aliases:
108  - FieldProps::keys() does not return the aliases.
109  - FieldProps::erase() and FieldProps::extract() do not support aliases. Using
110  them with an aliased keyword will also remove the alias.
111 
112  Note that the aliases are also added to GRID::double_keywords.
113 
114  The PERMR and PERMTHT keywords are aliases for PERMX and PERMY, respectively.
115 */
116 namespace ALIAS {
117  static const std::unordered_map<std::string, std::string> aliased_keywords = {{"PERMR", "PERMX"},
118  {"PERMTHT", "PERMY"}};
119 }
120 
121 
122 namespace GRID {
123 static 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  {"THCROCK", keyword_info<double>{}.unit_string("Energy/AbsoluteTemperature*Length*Time")},
135  {"THCOIL", keyword_info<double>{}.unit_string("Energy/AbsoluteTemperature*Length*Time")},
136  {"THCGAS", keyword_info<double>{}.unit_string("Energy/AbsoluteTemperature*Length*Time")},
137  {"THCWATER",keyword_info<double>{}.unit_string("Energy/AbsoluteTemperature*Length*Time")},
138  {"MULTX", keyword_info<double>{}.init(1.0).mult(true)},
139  {"MULTX-", keyword_info<double>{}.init(1.0).mult(true)},
140  {"MULTY", keyword_info<double>{}.init(1.0).mult(true)},
141  {"MULTY-", keyword_info<double>{}.init(1.0).mult(true)},
142  {"MULTZ", keyword_info<double>{}.init(1.0).mult(true).global_kw(true)},
143  {"MULTZ-", keyword_info<double>{}.init(1.0).mult(true)}};
144 
145 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{"ACTNUM", keyword_info<int>{}.init(1)},
146  {"FLUXNUM", keyword_info<int>{}},
147  {"ISOLNUM", keyword_info<int>{}.init(1)},
148  {"MULTNUM", keyword_info<int>{}.init(1)},
149  {"OPERNUM", keyword_info<int>{}},
150  {"ROCKNUM", keyword_info<int>{}}};
151 
152 }
153 
154 namespace EDIT {
155 
156 /*
157  The TRANX, TRANY and TRANZ properties are handled very differently from the
158  other properties. It is important that these fields are not entered into the
159  double_keywords list of the EDIT section, that way we risk silent failures
160  due to the special treatment of the TRAN fields.
161 */
162 
163 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"MULTPV", keyword_info<double>{}.init(1.0)},
164  {"PORV", keyword_info<double>{}.unit_string("ReservoirVolume")},
165  {"MULTX", keyword_info<double>{}.init(1.0).mult(true)},
166  {"MULTX-", keyword_info<double>{}.init(1.0).mult(true)},
167  {"MULTY", keyword_info<double>{}.init(1.0).mult(true)},
168  {"MULTY-", keyword_info<double>{}.init(1.0).mult(true)},
169  {"MULTZ", keyword_info<double>{}.init(1.0).mult(true).global_kw(true)},
170  {"MULTZ-", keyword_info<double>{}.init(1.0).mult(true)}};
171 
172 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
173 }
174 
175 namespace PROPS {
176 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"SWATINIT", keyword_info<double>{}}};
177 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {};
178 
179 #define dirfunc(base) base, base "X", base "X-", base "Y", base "Y-", base "Z", base "Z-"
180 
181 static const std::set<std::string> satfunc = {"SWLPC", "ISWLPC", "SGLPC", "ISGLPC",
182  dirfunc("SGL"),
183  dirfunc("ISGL"),
184  dirfunc("SGU"),
185  dirfunc("ISGU"),
186  dirfunc("SWL"),
187  dirfunc("ISWL"),
188  dirfunc("SWU"),
189  dirfunc("ISWU"),
190  dirfunc("SGCR"),
191  dirfunc("ISGCR"),
192  dirfunc("SOWCR"),
193  dirfunc("ISOWCR"),
194  dirfunc("SOGCR"),
195  dirfunc("ISOGCR"),
196  dirfunc("SWCR"),
197  dirfunc("ISWCR"),
198  dirfunc("PCW"),
199  dirfunc("IPCW"),
200  dirfunc("PCG"),
201  dirfunc("IPCG"),
202  dirfunc("KRW"),
203  dirfunc("IKRW"),
204  dirfunc("KRWR"),
205  dirfunc("IKRWR"),
206  dirfunc("KRO"),
207  dirfunc("IKRO"),
208  dirfunc("KRORW"),
209  dirfunc("IKRORW"),
210  dirfunc("KRORG"),
211  dirfunc("IKRORG"),
212  dirfunc("KRG"),
213  dirfunc("IKRG"),
214  dirfunc("KRGR"),
215  dirfunc("IKRGR")};
216 
217 static const std::map<std::string,std::string> sogcr_shift = {{"SOGCR", "SWL"},
218  {"SOGCRX", "SWLX"},
219  {"SOGCRX-", "SWLX-"},
220  {"SOGCRY", "SWLY"},
221  {"SOGCRY-", "SWLY-"},
222  {"SOGCRZ", "SWLZ"},
223  {"SOGCRZ-", "SWLZ-"},
224  {"ISOGCR", "ISWL"},
225  {"ISOGCRX", "ISWLX"},
226  {"ISOGCRX-", "ISWLX-"},
227  {"ISOGCRY", "ISWLY"},
228  {"ISOGCRY-", "ISWLY-"},
229  {"ISOGCRZ", "ISWLZ"},
230  {"ISOGCRZ-", "ISWLZ-"}};
231 
232 }
233 
234 namespace REGIONS {
235 
236 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{"ENDNUM", keyword_info<int>{}.init(1)},
237  {"EQLNUM", keyword_info<int>{}.init(1)},
238  {"FIPNUM", keyword_info<int>{}.init(1)},
239  {"IMBNUM", keyword_info<int>{}.init(1)},
240  {"OPERNUM", keyword_info<int>{}},
241  {"MISCNUM", keyword_info<int>{}},
242  {"MISCNUM", keyword_info<int>{}},
243  {"PVTNUM", keyword_info<int>{}.init(1)},
244  {"SATNUM", keyword_info<int>{}.init(1)},
245  {"LWSLTNUM", keyword_info<int>{}},
246  {"ROCKNUM", keyword_info<int>{}},
247  {"KRNUMX", keyword_info<int>{}},
248  {"KRNUMY", keyword_info<int>{}},
249  {"KRNUMZ", keyword_info<int>{}},
250  };
251 }
252 
253 namespace SOLUTION {
254 
255 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"PRESSURE", keyword_info<double>{}.unit_string("Pressure")},
256  {"SPOLY", keyword_info<double>{}.unit_string("Density")},
257  {"SPOLYMW", keyword_info<double>{}},
258  {"SSOL", keyword_info<double>{}},
259  {"SWAT", keyword_info<double>{}},
260  {"SGAS", keyword_info<double>{}},
261  {"SMICR", keyword_info<double>{}.unit_string("Density")},
262  {"SOXYG", keyword_info<double>{}.unit_string("Density")},
263  {"SUREA", keyword_info<double>{}.unit_string("Density")},
264  {"SBIOF", keyword_info<double>{}},
265  {"SCALC", keyword_info<double>{}},
266  {"SALTP", keyword_info<double>{}},
267  {"SALT", keyword_info<double>{}.unit_string("Salinity")},
268  {"TEMPI", keyword_info<double>{}.unit_string("Temperature")},
269  {"RS", keyword_info<double>{}.unit_string("GasDissolutionFactor")},
270  {"RV", keyword_info<double>{}.unit_string("OilDissolutionFactor")},
271  {"RVW", keyword_info<double>{}.unit_string("OilDissolutionFactor")}
272  };
273 
274 }
275 
276 namespace SCHEDULE {
277 
278 static const std::unordered_map<std::string, keyword_info<double>> double_keywords = {{"MULTX", keyword_info<double>{}.init(1.0).mult(true)},
279  {"MULTX-", keyword_info<double>{}.init(1.0).mult(true)},
280  {"MULTY", keyword_info<double>{}.init(1.0).mult(true)},
281  {"MULTY-", keyword_info<double>{}.init(1.0).mult(true)},
282  {"MULTZ", keyword_info<double>{}.init(1.0).mult(true).global_kw(true)},
283  {"MULTZ-", keyword_info<double>{}.init(1.0).mult(true)}};
284 
285 static const std::unordered_map<std::string, keyword_info<int>> int_keywords = {{"ROCKNUM", keyword_info<int>{}}};
286 
287 }
288 
289 template <typename T>
290 keyword_info<T> global_kw_info(const std::string& name, bool allow_unsupported = false);
291 
292 } // end namespace keywords
293 
294 } // end namespace FieldProps
295 
296 class FieldProps {
297 public:
298 
299  using ScalarOperation = Fieldprops::ScalarOperation;
300 
301  struct MultregpRecord {
302  int region_value;
303  double multiplier;
304  std::string region_name;
305 
306 
307  MultregpRecord(int rv, double m, const std::string& rn) :
308  region_value(rv),
309  multiplier(m),
310  region_name(rn)
311  {}
312 
313 
314  bool operator==(const MultregpRecord& other) const {
315  return this->region_value == other.region_value &&
316  this->multiplier == other.multiplier &&
317  this->region_name == other.region_name;
318  }
319  };
320 
321 
322 
323  enum class GetStatus {
324  OK = 1,
325  INVALID_DATA = 2, // std::runtime_error
326  MISSING_KEYWORD = 3, // std::out_of_range
327  NOT_SUPPPORTED_KEYWORD = 4 // std::logic_error
328  };
329 
330 
331 
332  template<typename T>
334  const std::string& keyword;
335  GetStatus status;
337  const Data * data_ptr;
338 
339  FieldDataManager(const std::string& k, GetStatus s, const Data * d) :
340  keyword(k),
341  status(s),
342  data_ptr(d)
343  { }
344 
345 
346  void verify_status() const {
347  switch (status) {
348  case FieldProps::GetStatus::OK:
349  return;
350  case FieldProps::GetStatus::INVALID_DATA:
351  throw std::runtime_error("The keyword: " + keyword + " has not been fully initialized");
352  case FieldProps::GetStatus::MISSING_KEYWORD:
353  throw std::out_of_range("No such keyword in deck: " + keyword);
354  case FieldProps::GetStatus::NOT_SUPPPORTED_KEYWORD:
355  throw std::logic_error("The keyword " + keyword + " is not supported");
356  }
357  }
358 
359  const std::vector<T>* ptr() const {
360  if (this->data_ptr)
361  return std::addressof(this->data_ptr->data);
362  else
363  return nullptr;
364  }
365 
366  const std::vector<T>& data() const {
367  this->verify_status();
368  return this->data_ptr->data;
369  }
370 
371  const Data& field_data() const {
372  this->verify_status();
373  return *this->data_ptr;
374  }
375 
376  bool valid() const {
377  return (this->status == GetStatus::OK);
378  }
379 
380  };
381 
382 
383 
385  FieldProps(const Deck& deck, const Phases& phases, const EclipseGrid& grid, const TableManager& table_arg);
387  FieldProps(const Deck& deck, const EclipseGrid& grid);
388 
389  void reset_actnum(const std::vector<int>& actnum);
390 
391  void apply_numerical_aquifers(const NumericalAquifers& numerical_aquifers);
392 
393  const std::string& default_region() const;
394 
395  std::vector<int> actnum();
396  const std::vector<int>& actnumRaw() const;
397 
398  template <typename T>
399  static bool supported(const std::string& keyword);
400 
401  template <typename T>
402  bool has(const std::string& keyword) const;
403 
404  template <typename T>
405  std::vector<std::string> keys() const;
406 
407 
408  template <typename T>
409  FieldDataManager<T> try_get(const std::string& keyword,
410  bool allow_unsupported=false) {
411  if (!allow_unsupported && !FieldProps::supported<T>(keyword))
412  return FieldDataManager<T>(keyword, GetStatus::NOT_SUPPPORTED_KEYWORD, nullptr);
413 
414  const Fieldprops::FieldData<T> * field_data;
415  bool has0 = this->has<T>(keyword);
416 
417  field_data = std::addressof(this->init_get<T>(keyword,
418  std::is_same<T,double>::value && allow_unsupported));
419  if (field_data->valid() || allow_unsupported)
420  return FieldDataManager<T>(keyword, GetStatus::OK, field_data);
421 
422  if (!has0) {
423  this->erase<T>(keyword);
424  return FieldDataManager<T>(keyword, GetStatus::MISSING_KEYWORD, nullptr);
425  }
426 
427  return FieldDataManager<T>(keyword, GetStatus::INVALID_DATA, nullptr);
428  }
429 
430 
431  template <typename T>
432  const std::vector<T>& get(const std::string& keyword) {
433  const auto& data = this->try_get<T>(keyword);
434  return data.data();
435  }
436 
437  template <typename T>
438  std::vector<T> get_global(const std::string& keyword) {
439  const auto& managed_field_data = this->try_get<T>(keyword);
440  const auto& field_data = managed_field_data.field_data();
441  const auto& kw_info = Fieldprops::keywords::global_kw_info<T>(keyword);
442  if (kw_info.global)
443  return *field_data.global_data;
444  else
445  return this->global_copy(field_data.data, kw_info.scalar_init);
446  }
447 
448 
449  template <typename T>
450  std::vector<T> get_copy(const std::string& keyword, bool global) {
451  bool has0 = this->has<T>(keyword);
452  const auto& field_data = this->try_get<T>(keyword).field_data();
453 
454  if (has0) {
455  if (global)
456  return this->global_copy(field_data.data, field_data.kw_info.scalar_init);
457  else
458  return field_data.data;
459  } else {
460  if (global) {
461  const auto& kw_info = Fieldprops::keywords::global_kw_info<T>(keyword);
462  return this->global_copy(this->extract<T>(keyword), kw_info.scalar_init);
463  } else
464  return this->extract<T>(keyword);
465  }
466  }
467 
468 
469  template <typename T>
470  std::vector<bool> defaulted(const std::string& keyword) {
471  const auto& field = this->init_get<T>(keyword);
472  std::vector<bool> def(field.size());
473 
474  for (std::size_t i=0; i < def.size(); i++)
475  def[i] = value::defaulted( field.value_status[i]);
476 
477  return def;
478  }
479 
480 
481  template <typename T>
482  std::vector<T> global_copy(const std::vector<T>& data, const std::optional<T>& default_value) const {
483  T fill_value = default_value.has_value() ? *default_value : 0;
484  std::vector<T> global_data(this->global_size, fill_value);
485  std::size_t i = 0;
486  for (std::size_t g = 0; g < this->global_size; g++) {
487  if (this->m_actnum[g]) {
488  global_data[g] = data[i];
489  i++;
490  }
491  }
492  return global_data;
493  }
494 
495  std::size_t active_size;
496  std::size_t global_size;
497 
498  std::size_t num_int() const {
499  return this->int_data.size();
500  }
501 
502  std::size_t num_double() const {
503  return this->double_data.size();
504  }
505 
506  void handle_schedule_keywords(const std::vector<DeckKeyword>& keywords);
507  bool tran_active(const std::string& keyword) const;
508  void apply_tran(const std::string& keyword, std::vector<double>& data);
509  bool operator==(const FieldProps& other) const;
510  static bool rst_cmp(const FieldProps& full_arg, const FieldProps& rst_arg);
511 
512  const Fieldprops::TranMap& getTran() const
513  {
514  return tran;
515  }
516 
517 private:
518  void scanGRIDSection(const GRIDSection& grid_section);
519  void scanGRIDSectionOnlyACTNUM(const GRIDSection& grid_section);
520  void scanEDITSection(const EDITSection& edit_section);
521  void scanPROPSSection(const PROPSSection& props_section);
522  void scanREGIONSSection(const REGIONSSection& regions_section);
523  void scanSOLUTIONSection(const SOLUTIONSection& solution_section);
524  double getSIValue(const std::string& keyword, double raw_value) const;
525  double getSIValue(ScalarOperation op, const std::string& keyword, double raw_value) const;
526  template <typename T>
527  void erase(const std::string& keyword);
528 
529  template <typename T>
530  std::vector<T> extract(const std::string& keyword);
531 
532  template <typename T>
533  void operate(const DeckRecord& record, Fieldprops::FieldData<T>& target_data, const Fieldprops::FieldData<T>& src_data, const std::vector<Box::cell_index>& index_list);
534 
535  template <typename T>
536  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);
537 
538  template <typename T>
539  Fieldprops::FieldData<T>& init_get(const std::string& keyword, bool allow_unsupported = false);
540 
541  template <typename T>
542  Fieldprops::FieldData<T>& init_get(const std::string& keyword, const Fieldprops::keywords::keyword_info<T>& kw_info);
543 
544  std::string region_name(const DeckItem& region_item);
545  std::vector<Box::cell_index> region_index( const std::string& region_name, int region_value );
546  void handle_OPERATE(const DeckKeyword& keyword, Box box);
547  void handle_operation(const DeckKeyword& keyword, Box box);
548  void handle_region_operation(const DeckKeyword& keyword);
549  void handle_COPY(const DeckKeyword& keyword, Box box, bool region);
550  void distribute_toplayer(Fieldprops::FieldData<double>& field_data, const std::vector<double>& deck_data, const Box& box);
551  double get_beta(const std::string& func_name, const std::string& target_array, double raw_beta);
552  double get_alpha(const std::string& func_name, const std::string& target_array, double raw_alpha);
553 
554  void handle_keyword(const DeckKeyword& keyword, Box& box);
555  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);
556  void handle_double_keyword(Section section, const Fieldprops::keywords::keyword_info<double>& kw_info, const DeckKeyword& keyword, const Box& box);
557  void handle_int_keyword(const Fieldprops::keywords::keyword_info<int>& kw_info, const DeckKeyword& keyword, const Box& box);
558  void init_satfunc(const std::string& keyword, Fieldprops::FieldData<double>& satfunc);
559  void init_porv(Fieldprops::FieldData<double>& porv);
560  void init_tempi(Fieldprops::FieldData<double>& tempi);
561 
562  const UnitSystem unit_system;
563  std::size_t nx,ny,nz;
564  Phases m_phases;
565  SatFuncControls m_satfuncctrl;
566  std::vector<int> m_actnum;
567  std::vector<double> cell_volume;
568  std::vector<double> cell_depth;
569  const std::string m_default_region;
570  const EclipseGrid * grid_ptr; // A bit undecided whether to properly use the grid or not ...
571  TableManager tables;
572  std::optional<satfunc::RawTableEndPoints> m_rtep;
573  std::vector<MultregpRecord> multregp;
574  std::unordered_map<std::string, Fieldprops::FieldData<int>> int_data;
575  std::unordered_map<std::string, Fieldprops::FieldData<double>> double_data;
576 
577  Fieldprops::TranMap tran;
578 };
579 
580 }
581 #endif
Definition: Deck.hpp:63
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:296
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:57
Definition: TableManager.hpp:65
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29
Definition: FieldProps.hpp:333
Definition: FieldProps.hpp:301
Definition: FieldData.hpp:55