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