My Project
FieldPropsManager.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_MANAGER_HPP
20 #define FIELDPROPS_MANAGER_HPP
21 
22 #include <memory>
23 #include <vector>
24 #include <unordered_map>
25 #include <opm/parser/eclipse/EclipseState/Grid/TranCalculator.hpp>
26 #include <opm/parser/eclipse/EclipseState/Grid/FieldData.hpp>
27 
28 namespace Opm {
29 
30 class EclipseGrid;
31 class Deck;
32 class FieldProps;
33 class Phases;
34 class TableManager;
35 class NumericalAquifers;
36 
38 
39 
40 public:
41  // The default constructor should be removed when the FieldPropsManager is mandatory
42  // The default constructed fieldProps object is **NOT** usable
43  FieldPropsManager() = default;
44  FieldPropsManager(const Deck& deck, const Phases& ph, const EclipseGrid& grid, const TableManager& tables);
45  virtual void reset_actnum(const std::vector<int>& actnum);
46  const std::string& default_region() const;
47  virtual std::vector<int> actnum() const;
48  virtual std::vector<double> porv(bool global = false) const;
49 
50  /*
51  The number of cells in the fields managed by this FieldPropsManager.
52  Initially this will correspond to the number of active cells in the grid
53  used when constructing the FieldPropsManager, but using the reset_actnum()
54  method it is possible to deactivate additional cells.
55  */
56  std::size_t active_size() const;
57 
58  bool operator==(const FieldPropsManager& other) const;
59  static bool rst_cmp(const FieldPropsManager& full_arg, const FieldPropsManager& rst_arg);
60  /*
61  Because the FieldProps class can autocreate properties the semantics of
62  get() and has() is slightly non intuitve:
63 
64  - The has<T>("KW") method will check if the current FieldProps container
65  has an installed "KW" keyword; if the container has the keyword in
66  question it will check if all elements have been assigned a value - only
67  in that case will it return true. The has<T>("KW") method will *not* try
68  to create a new keyword.
69 
70  - The has<T>("KW") method will *not* consult the supported<T>("KW")
71  method; i.e. if you ask has<T>("UNKNOWN_KEYWORD") you will just get a
72  false.
73 
74  - The get<T>("KW") method will try to create a new keyword if it does not
75  already have the keyword you are asking for. This implies that you can
76  get the following non intuitive sequence of events:
77 
78  FieldPropsManager fpm(deck, grid);
79 
80  fpm.has<int>("SATNUM"); => false
81  auto satnum = fpm.get<int>("SATNUM"); => SATNUM is autocreated
82  fpm.has<int>("SATNUM"); => true
83 
84  - When checking whether the container has the keyword you should rephrase
85  the question slightly:
86 
87  * Does the container have the keyword *right now* => has<T>("KW")
88  * Can the container provide the keyword => ptr = try_get<T>("KW")
89 
90  - It is quite simple to create a deck where the keywords are only partly
91  initialized, all the methods in the FieldPropsManager only consider
92  fully initialized keywords.
93  */
94 
95 
96  /*
97  The get_copy() has exactly the same behaviour as get(), but the important
98  difference is that said keyword is not already in the container it is not
99  installed in the container; if we look at SATNUM which is a keywor which
100  can be automatically instantiated we have the following behavior:
101 
102  get():
103  fp.has<int>("SATNUM") -> false
104  const std::vector<int>& satnum = fp.get<int>("SATNUM")
105  fp.has<int>("SATNUM") -> true;
106 
107 
108  get_copy():
109  fp.has<int>("SATNUM") -> false
110  const std::vector<int>& satnum = fp.get_copy<int>("SATNUM")
111  fp.has<int>("SATNUM") -> false
112  */
113 
114 
115  template <typename T>
116  std::vector<T> get_copy(const std::string& keyword, bool global=false) const;
117 
118  /*
119  Will return a pointer to the keyword data, or nullptr if the container
120  does not have suce a keyword. Observe that container will hold on to an
121  manage the underlying keyword data.
122 
123  The try_get function will return a nullptr if the container does not
124  contain said keyword, or if the keyword has not been fully initialized. If
125  you ask for a totally unknown keyword the method will return nullptr.
126  */
127  template <typename T> const std::vector<T>* try_get(const
128  std::string& keyword) const;
129 
130  /*
131  You can ask whether the elements in the keyword have a default value -
132  which typically is calculated in some way, or if it has been explicitly
133  assigned to in the deck.
134  */
135  template <typename T>
136  std::vector<bool> defaulted(const std::string& keyword) const;
137 
138 
139  /*
140  Check whether the container supports/recognizes a keyword at all:
141 
142  supported<double>("PORO") => true
143  supported<double>("NO_SUCH_KEYWORD") => false
144 
145  The method does not at all consult the content of the container - it is a
146  static method.
147  */
148  template <typename T>
149  static bool supported(const std::string& keyword);
150 
151  /*
152  The keys() function will return a list of keys corresponding to the fully
153  initialized keywords in the container. Observe that the implementation
154  special cases the PORV and ACTNUM keywords, since these are present with
155  special functions porv(bool) and actnum() the "PORV" and "ACTNUM" string
156  literals are excluded from the keys() list.
157  */
158  template <typename T>
159  std::vector<std::string> keys() const;
160 
162  get_int_field_data(const std::string& keyword) const;
163 
168  get_double_field_data(const std::string& keyword, bool allow_unsupported=false) const;
169  virtual const std::vector<int>& get_int(const std::string& keyword) const { return this->get<int>(keyword); }
170  virtual std::vector<int> get_global_int(const std::string& keyword) const { return this->get_global<int>(keyword); }
171 
172  virtual const std::vector<double>& get_double(const std::string& keyword) const { return this->get<double>(keyword); }
173  virtual std::vector<double> get_global_double(const std::string& keyword) const { return this->get_global<double>(keyword); }
174 
175  virtual bool has_int(const std::string& keyword) const { return this->has<int>(keyword); }
176  virtual bool has_double(const std::string& keyword) const { return this->has<double>(keyword); }
177 
178  /*
179  The transmissibility keywords TRANX, TRANY and TRANZ do not really fit
180  well in the FieldProps system. The opm codebase is based on a full
181  internalization in the parse phase, and then passing fully assembled
182  objects to the simulator. When it comes to the transmissibilities this
183  model breaks down because the input code in opm-common is not capable of
184  calculating the transmissibility, that is performed in the simulator.
185 
186  The EDIT section can have modifiers on TRAN, these must be applied *after*
187  the initial transmissibilities are calculated. To support this all the
188  modifiers to the TRAN{XYZ} fields are assembled in "transmissibility
189  calculators", and then these modifiers can be applied to a TRAN vector
190  after it has been calculated in the simulator. Usage from the simulator
191  could look like:
192 
193 
194  const auto& fp = eclState.fieldProps();
195 
196  // Calculate transmissibilities using grid and permeability
197  std::vector<double> tranx = ....
198 
199  // Check if there are any active TRANX modifiers and apply them
200  if (fp.tran_active("TRANX"))
201  fp.apply_tran("TRANX", tranx);
202 
203 
204  */
205 
206  /*
207  Will check if there are any TRAN{XYZ} modifiers active in the deck.
208  */
209  virtual bool tran_active(const std::string& keyword) const;
210 
211 
212  /*
213  Will apply all the TRAN modifiers which are present in the deck on the
214  already initialized vector tran_data. The vector tran_data should be
215  organised as the data vectors in the fieldpropsmanager - i.e. one element
216  for each active cell - in lexicographical order. The operations which are
217  supported by the transmissibility calculator are those given by the enum
218  ScalarOperation in FieldProps.hpp.
219  */
220  virtual void apply_tran(const std::string& keyword, std::vector<double>& tran_data) const;
221 
222  void apply_numerical_aquifers(const NumericalAquifers& aquifers);
223 
224 
225  /*
226  When using MPI the FieldPropsManager is typically only assembled on the
227  root node and then distributed to the other nodes afterwards. These
228  methods are support methods for that, the real data used by the
229  transmissibility calculators is in the form of custom 3D fields, they are
230  distributed the same way the rest of the 3D fields are distributed.
231  */
232  virtual std::vector<char> serialize_tran() const;
233  virtual void deserialize_tran(const std::vector<char>& buffer);
234 private:
235  /*
236  Return the keyword values as a std::vector<>. All elements in the return
237  value are guaranteed to be assigned a valid value. If the keyword is not
238  in the container, or not all elements have a valid value - an exception
239  will be raised:
240 
241  - keyword which is not supported at all -> std::logic_error
242  - keyword which is not in the deck at all -> std::out_of_range
243  - keyword which has not been fully initialized -> std::runtime_error
244 
245  Many of the keywords in the container can be automatically created, in
246  that case the get() method will silently create a new keyword and default
247  initialize if it is not already in the container. The different exceptions
248  raised for the different error conditions are the same for get(),
249  get_copy() and get_global().
250  */
251  template <typename T>
252  const std::vector<T>& get(const std::string& keyword) const;
253 
254  /*
255  Will check if the container has the keyword loaded; in a fully initialized
256  state. If you ask for a keyword which is not supported at all you will
257  just get false back.
258  */
259  template <typename T>
260  bool has(const std::string& keyword) const;
261 
262  /*
263  This is exactly like the get() method, but the returned vector will have
264  global cartesian size. If the field has a default value that value will be
265  used for filling in in the inactive cells, otherwise zero is used.
266  */
267  template <typename T>
268  std::vector<T> get_global(const std::string& keyword) const;
269 
270 
271  std::shared_ptr<FieldProps> fp;
272 };
273 
274 
275 void deserialize_tran(std::unordered_map<std::string, Fieldprops::TranCalculator>& tran,
276  const std::vector<char>& buffer);
277 
278 template<class MapType>
279 void apply_tran(const std::unordered_map<std::string, Fieldprops::TranCalculator>& tran,
280  const MapType& double_data,
281  std::size_t active_size,
282  const std::string& keyword, std::vector<double>& data);
283 
284 }
285 
286 #endif
Definition: Deck.hpp:119
About cell information and dimension: The actual grid information is held in a pointer to an ERT ecl_...
Definition: EclipseGrid.hpp:55
Definition: FieldPropsManager.hpp:37
const Fieldprops::FieldData< double > & get_double_field_data(const std::string &keyword, bool allow_unsupported=false) const
Get double field data associated with a keyword.
Definition: Runspec.hpp:57
Definition: TableManager.hpp:64
This class implements a small container which holds the transmissibility mulitpliers for all the face...
Definition: Exceptions.hpp:29
Definition: FieldData.hpp:55