GridProperty.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2014 Statoil 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
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #ifndef ECLIPSE_GRIDPROPERTY_HPP_
20 #define ECLIPSE_GRIDPROPERTY_HPP_
21 
22 #include <iostream>
23 #include <string>
24 #include <vector>
25 #include <algorithm>
26 #include <unordered_map>
27 #include <boost/lexical_cast.hpp>
28 
29 #include <ert/ecl/EclKW.hpp>
30 
35 
36 /*
37  This class implemenents a class representing properties which are
38  define over an ECLIPSE grid, i.e. with one value for each logical
39  cartesian cell in the grid.
40 
41  The class is implemented as a thin wrapper around std::vector<T>;
42  where the most relevant specialisations of T are 'int' and 'float'.
43 */
44 
45 
46 
47 
48 namespace Opm {
49 
50 template <class ValueType>
52 {
53 protected:
55 
56 public:
57  virtual void apply(std::vector<ValueType>& values) const = 0;
58 };
59 
60 
61 
62 
63 template <class DataType>
65 {
66 public:
69 
71  {}
72 
73  GridPropertySupportedKeywordInfo(const std::string& name,
74  std::shared_ptr<const Initializer> initializer,
75  std::shared_ptr<const PostProcessor> postProcessor,
76  const std::string& dimString)
77  : m_keywordName(name),
78  m_initializer(initializer),
79  m_postProcessor(postProcessor),
80  m_dimensionString(dimString)
81  {}
82 
83 
84  GridPropertySupportedKeywordInfo(const std::string& name,
85  std::shared_ptr<const Initializer> initializer,
86  const std::string& dimString)
87  : m_keywordName(name),
88  m_initializer(initializer),
89  m_dimensionString(dimString)
90  {}
91 
92  // this is a convenience constructor which can be used if the default value for the
93  // grid property is just a constant...
94  GridPropertySupportedKeywordInfo(const std::string& name,
95  const DataType defaultValue,
96  const std::string& dimString)
97  : m_keywordName(name),
98  m_initializer(new Opm::GridPropertyConstantInitializer<DataType>(defaultValue)),
99  m_dimensionString(dimString)
100  {}
101 
102  GridPropertySupportedKeywordInfo(const std::string& name,
103  const DataType defaultValue,
104  std::shared_ptr<const PostProcessor> postProcessor,
105  const std::string& dimString)
106  : m_keywordName(name),
107  m_initializer(new Opm::GridPropertyConstantInitializer<DataType>(defaultValue)),
108  m_postProcessor(postProcessor),
109  m_dimensionString(dimString)
110  {}
111 
112 
113 
115 
116 
117  const std::string& getKeywordName() const {
118  return m_keywordName;
119  }
120 
121 
122  const std::string& getDimensionString() const {
123  return m_dimensionString;
124  }
125 
126 
127  std::shared_ptr<const Initializer> getInitializer() const {
128  return m_initializer;
129  }
130 
131 
132  std::shared_ptr<const PostProcessor> getPostProcessor() const {
133  return m_postProcessor;
134  }
135 
136 
137  bool hasPostProcessor() const {
138  return static_cast<bool>(m_postProcessor);
139  }
140 
141 
142 
143 private:
144  std::string m_keywordName;
145  std::shared_ptr<const Initializer> m_initializer;
146  std::shared_ptr<const PostProcessor> m_postProcessor;
147  std::string m_dimensionString;
148 };
149 
150 
151 
152 template <typename T>
154 public:
156 
157  GridProperty(size_t nx , size_t ny , size_t nz , const SupportedKeywordInfo& kwInfo) {
158  m_nx = nx;
159  m_ny = ny;
160  m_nz = nz;
161  m_kwInfo = kwInfo;
162  m_data.resize( nx * ny * nz );
163 
164  m_kwInfo.getInitializer()->apply(m_data);
165  m_hasRunPostProcessor = false;
166  }
167 
168  size_t getCartesianSize() const {
169  return m_data.size();
170  }
171 
172  size_t getNX() const {
173  return m_nx;
174  }
175 
176  size_t getNY() const {
177  return m_ny;
178  }
179 
180  size_t getNZ() const {
181  return m_nz;
182  }
183 
184 
185  T iget(size_t index) const {
186  if (index < m_data.size()) {
187  return m_data[index];
188  } else {
189  throw std::invalid_argument("Index out of range \n");
190  }
191  }
192 
193 
194  T iget(size_t i , size_t j , size_t k) const {
195  size_t g = i + j*m_nx + k*m_nx*m_ny;
196  return iget(g);
197  }
198 
199  void iset(size_t index, T value) {
200  if (index < m_data.size())
201  m_data[index] = value;
202  else
203  throw std::invalid_argument("Index out of range \n");
204  }
205 
206  void iset(size_t i , size_t j , size_t k , T value) {
207  size_t g = i + j*m_nx + k*m_nx*m_ny;
208  iset(g,value);
209  }
210 
211  bool containsNaN() const;
212 
213  const std::string& getDimensionString() const;
214 
215  void multiplyWith(const GridProperty<T>& other) {
216  if ((m_nx == other.m_nx) && (m_ny == other.m_ny) && (m_nz == other.m_nz)) {
217  for (size_t g=0; g < m_data.size(); g++)
218  m_data[g] *= other.m_data[g];
219  } else
220  throw std::invalid_argument("Size mismatch between properties in mulitplyWith.");
221  }
222 
223 
224  void multiplyValueAtIndex(size_t index, T factor) {
225  m_data[index] *= factor;
226  }
227 
228  const std::vector<T>& getData() const {
229  return m_data;
230  }
231 
232 
233 
234  void maskedSet(T value, const std::vector<bool>& mask) {
235  for (size_t g = 0; g < getCartesianSize(); g++) {
236  if (mask[g])
237  m_data[g] = value;
238  }
239  }
240 
241 
242  void maskedMultiply(T value, const std::vector<bool>& mask) {
243  for (size_t g = 0; g < getCartesianSize(); g++) {
244  if (mask[g])
245  m_data[g] *= value;
246  }
247  }
248 
249 
250  void maskedAdd(T value, const std::vector<bool>& mask) {
251  for (size_t g = 0; g < getCartesianSize(); g++) {
252  if (mask[g])
253  m_data[g] += value;
254  }
255  }
256 
257 
258  void maskedCopy(const GridProperty<T>& other, const std::vector<bool>& mask) {
259  for (size_t g = 0; g < getCartesianSize(); g++) {
260  if (mask[g])
261  m_data[g] = other.m_data[g];
262  }
263  }
264 
265 
266 
267  void initMask(T value, std::vector<bool>& mask) {
268  mask.resize(getCartesianSize());
269  for (size_t g = 0; g < getCartesianSize(); g++) {
270  if (m_data[g] == value)
271  mask[g] = true;
272  else
273  mask[g] = false;
274  }
275  }
276 
277 
278 
287  const auto deckItem = getDeckItem(deckKeyword);
288  for (size_t dataPointIdx = 0; dataPointIdx < deckItem->size(); ++dataPointIdx) {
289  if (!deckItem->defaultApplied(dataPointIdx))
290  setDataPoint(dataPointIdx, dataPointIdx, deckItem);
291  }
292  }
293 
294 
295 
296  void loadFromDeckKeyword(std::shared_ptr<const Box> inputBox, DeckKeywordConstPtr deckKeyword) {
297  if (inputBox->isGlobal())
298  loadFromDeckKeyword( deckKeyword );
299  else {
300  const auto deckItem = getDeckItem(deckKeyword);
301  const std::vector<size_t>& indexList = inputBox->getIndexList();
302  if (indexList.size() == deckItem->size()) {
303  for (size_t sourceIdx = 0; sourceIdx < indexList.size(); sourceIdx++) {
304  size_t targetIdx = indexList[sourceIdx];
305  if (sourceIdx < deckItem->size()
306  && !deckItem->defaultApplied(sourceIdx))
307  {
308  setDataPoint(sourceIdx, targetIdx, deckItem);
309  }
310  }
311  } else {
312  std::string boxSize = std::to_string(static_cast<long long>(indexList.size()));
313  std::string keywordSize = std::to_string(static_cast<long long>(deckItem->size()));
314 
315  throw std::invalid_argument("Size mismatch: Box:" + boxSize + " DecKeyword:" + keywordSize);
316  }
317  }
318  }
319 
320 
321 
322  void copyFrom(const GridProperty<T>& src, std::shared_ptr<const Box> inputBox) {
323  if (inputBox->isGlobal()) {
324  for (size_t i = 0; i < src.getCartesianSize(); ++i)
325  m_data[i] = src.m_data[i];
326  } else {
327  const std::vector<size_t>& indexList = inputBox->getIndexList();
328  for (size_t i = 0; i < indexList.size(); i++) {
329  size_t targetIndex = indexList[i];
330  m_data[targetIndex] = src.m_data[targetIndex];
331  }
332  }
333  }
334 
335  void scale(T scaleFactor , std::shared_ptr<const Box> inputBox) {
336  if (inputBox->isGlobal()) {
337  for (size_t i = 0; i < m_data.size(); ++i)
338  m_data[i] *= scaleFactor;
339  } else {
340  const std::vector<size_t>& indexList = inputBox->getIndexList();
341  for (size_t i = 0; i < indexList.size(); i++) {
342  size_t targetIndex = indexList[i];
343  m_data[targetIndex] *= scaleFactor;
344  }
345  }
346  }
347 
348 
349  void add(T shiftValue , std::shared_ptr<const Box> inputBox) {
350  if (inputBox->isGlobal()) {
351  for (size_t i = 0; i < m_data.size(); ++i)
352  m_data[i] += shiftValue;
353  } else {
354  const std::vector<size_t>& indexList = inputBox->getIndexList();
355  for (size_t i = 0; i < indexList.size(); i++) {
356  size_t targetIndex = indexList[i];
357  m_data[targetIndex] += shiftValue;
358  }
359  }
360  }
361 
362 
363 
364 
365  void setScalar(T value , std::shared_ptr<const Box> inputBox) {
366  if (inputBox->isGlobal()) {
367  std::fill(m_data.begin(), m_data.end(), value);
368  } else {
369  const std::vector<size_t>& indexList = inputBox->getIndexList();
370  for (size_t i = 0; i < indexList.size(); i++) {
371  size_t targetIndex = indexList[i];
372  m_data[targetIndex] = value;
373  }
374  }
375  }
376 
377  const std::string& getKeywordName() const {
378  return m_kwInfo.getKeywordName();
379  }
380 
381  const SupportedKeywordInfo& getKeywordInfo() const {
382  return m_kwInfo;
383  }
384 
385 
387  if (m_kwInfo.hasPostProcessor() && !m_hasRunPostProcessor)
388  return true;
389  else
390  return false;
391  }
392 
393 
395  if (postProcessorRunRequired()) {
396  // This is set here before the post processor has actually
397  // completed; this is to protect against circular loops if
398  // the post processor itself calls for the same grid
399  // property.
400  m_hasRunPostProcessor = true;
401  auto postProcessor = m_kwInfo.getPostProcessor();
402  postProcessor->apply( m_data );
403  }
404  }
405 
406 
407  ERT::EclKW<T> getEclKW() const {
408  ERT::EclKW<T> eclKW( getKeywordName() , getCartesianSize());
409  eclKW.assignVector( getData() );
410  return eclKW;
411  }
412 
413 
414  ERT::EclKW<T> getEclKW(std::shared_ptr<const EclipseGrid> grid) const {
415  ERT::EclKW<T> eclKW( getKeywordName() , grid->getNumActive());
416  size_t activeIndex = 0;
417  for (size_t g = 0; g < getCartesianSize(); g++) {
418  if (grid->cellActive( g )) {
419  eclKW[activeIndex] = iget(g);
420  activeIndex++;
421  }
422  }
423 
424  return eclKW;
425  }
426 
427 
428 
429 
434  void checkLimits(T min , T max) const {
435  for (size_t g=0; g < m_data.size(); g++) {
436  T value = m_data[g];
437  if ((value < min) || (value > max))
438  throw std::invalid_argument("Property element outside valid limits");
439  }
440  }
441 
442 
443 private:
444  Opm::DeckItemConstPtr getDeckItem(Opm::DeckKeywordConstPtr deckKeyword) {
445  if (deckKeyword->size() != 1)
446  throw std::invalid_argument("Grid properties can only have a single record (keyword "
447  + deckKeyword->name() + ")");
448  if (deckKeyword->getRecord(0)->size() != 1)
449  // this is an error of the definition of the ParserKeyword (most likely in
450  // the corresponding JSON file)
451  throw std::invalid_argument("Grid properties may only exhibit a single item (keyword "
452  + deckKeyword->name() + ")");
453 
454  const auto deckItem = deckKeyword->getRecord(0)->getItem(0);
455 
456  if (deckItem->size() > m_data.size())
457  throw std::invalid_argument("Size mismatch when setting data for:" + getKeywordName() +
458  " keyword size: " + boost::lexical_cast<std::string>(deckItem->size())
459  + " input size: " + boost::lexical_cast<std::string>(m_data.size()));
460 
461  return deckItem;
462  }
463 
464  void setDataPoint(size_t sourceIdx, size_t targetIdx, Opm::DeckItemConstPtr deckItem);
465 
466  size_t m_nx,m_ny,m_nz;
467  SupportedKeywordInfo m_kwInfo;
468  std::vector<T> m_data;
469  bool m_hasRunPostProcessor;
470 };
471 
472 
473 }
474 #endif
void runPostProcessor()
Definition: GridProperty.hpp:394
void loadFromDeckKeyword(std::shared_ptr< const Box > inputBox, DeckKeywordConstPtr deckKeyword)
Definition: GridProperty.hpp:296
void initMask(T value, std::vector< bool > &mask)
Definition: GridProperty.hpp:267
void checkLimits(T min, T max) const
Definition: GridProperty.hpp:434
void scale(T scaleFactor, std::shared_ptr< const Box > inputBox)
Definition: GridProperty.hpp:335
const std::string & getKeywordName() const
Definition: GridProperty.hpp:377
void iset(size_t index, T value)
Definition: GridProperty.hpp:199
GridPropertySupportedKeywordInfo()
Definition: GridProperty.hpp:70
Definition: GridProperty.hpp:64
GridPropertyBaseInitializer< DataType > Initializer
Definition: GridProperty.hpp:67
void maskedMultiply(T value, const std::vector< bool > &mask)
Definition: GridProperty.hpp:242
void maskedSet(T value, const std::vector< bool > &mask)
Definition: GridProperty.hpp:234
Definition: Deck.hpp:29
GridPropertySupportedKeywordInfo(const std::string &name, std::shared_ptr< const Initializer > initializer, const std::string &dimString)
Definition: GridProperty.hpp:84
const std::string & getKeywordName() const
Definition: GridProperty.hpp:117
GridPropertyBasePostProcessor< DataType > PostProcessor
Definition: GridProperty.hpp:68
ERT::EclKW< T > getEclKW(std::shared_ptr< const EclipseGrid > grid) const
Definition: GridProperty.hpp:414
std::shared_ptr< const DeckKeyword > DeckKeywordConstPtr
Definition: DeckKeyword.hpp:71
size_t getCartesianSize() const
Definition: GridProperty.hpp:168
void add(T shiftValue, std::shared_ptr< const Box > inputBox)
Definition: GridProperty.hpp:349
GridProperty(size_t nx, size_t ny, size_t nz, const SupportedKeywordInfo &kwInfo)
Definition: GridProperty.hpp:157
const std::string & getDimensionString() const
Definition: GridProperty.hpp:122
std::shared_ptr< const DeckItem > DeckItemConstPtr
Definition: DeckItem.hpp:127
std::shared_ptr< const Initializer > getInitializer() const
Definition: GridProperty.hpp:127
size_t getNX() const
Definition: GridProperty.hpp:172
void setScalar(T value, std::shared_ptr< const Box > inputBox)
Definition: GridProperty.hpp:365
T iget(size_t index) const
Definition: GridProperty.hpp:185
void copyFrom(const GridProperty< T > &src, std::shared_ptr< const Box > inputBox)
Definition: GridProperty.hpp:322
void maskedCopy(const GridProperty< T > &other, const std::vector< bool > &mask)
Definition: GridProperty.hpp:258
bool containsNaN() const
ERT::EclKW< T > getEclKW() const
Definition: GridProperty.hpp:407
bool hasPostProcessor() const
Definition: GridProperty.hpp:137
virtual void apply(std::vector< ValueType > &values) const =0
const std::vector< T > & getData() const
Definition: GridProperty.hpp:228
GridPropertySupportedKeywordInfo(const std::string &name, std::shared_ptr< const Initializer > initializer, std::shared_ptr< const PostProcessor > postProcessor, const std::string &dimString)
Definition: GridProperty.hpp:73
size_t getNY() const
Definition: GridProperty.hpp:176
void multiplyValueAtIndex(size_t index, T factor)
Definition: GridProperty.hpp:224
size_t getNZ() const
Definition: GridProperty.hpp:180
std::shared_ptr< const PostProcessor > getPostProcessor() const
Definition: GridProperty.hpp:132
T iget(size_t i, size_t j, size_t k) const
Definition: GridProperty.hpp:194
Definition: GridPropertyInitializers.hpp:52
void maskedAdd(T value, const std::vector< bool > &mask)
Definition: GridProperty.hpp:250
GridPropertySupportedKeywordInfo(const std::string &name, const DataType defaultValue, const std::string &dimString)
Definition: GridProperty.hpp:94
const SupportedKeywordInfo & getKeywordInfo() const
Definition: GridProperty.hpp:381
void multiplyWith(const GridProperty< T > &other)
Definition: GridProperty.hpp:215
bool postProcessorRunRequired()
Definition: GridProperty.hpp:386
GridPropertyBasePostProcessor()
Definition: GridProperty.hpp:54
GridPropertySupportedKeywordInfo(const std::string &name, const DataType defaultValue, std::shared_ptr< const PostProcessor > postProcessor, const std::string &dimString)
Definition: GridProperty.hpp:102
const std::string & getDimensionString() const
Definition: GridProperty.hpp:51
void loadFromDeckKeyword(DeckKeywordConstPtr deckKeyword)
Definition: GridProperty.hpp:286
GridPropertySupportedKeywordInfo< T > SupportedKeywordInfo
Definition: GridProperty.hpp:155
Definition: GridPropertyInitializers.hpp:63
void iset(size_t i, size_t j, size_t k, T value)
Definition: GridProperty.hpp:206
Definition: GridProperty.hpp:153