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