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