The class MULTREGTSCanner internalizes the content of one or several
MULTREGT keywords and can then scan through GridProperty region objects
to find region interfaces as specified in the MULTREGT keyword.
when it comes to PORV, the final pore volumes of logically Cartesian
grids are hard to implement at this abstraction level because pore
volumes may be either specified using the PORO or by the PORV keywords
and both of them are grid properties. This means that to calculate the
pore volumes using the porosity, the porosity grid property must be
already finished when creating PORV. Because of potential interactions
between the PORV and PORO grid properties this is not possible to do
canonically at the grid property initializer stage...
this makes it possible to define more complicated initializers for
grid properties. (needed for example for keywords like ISGU.) This
patch does not introduce them yet, but only adds the necessary
infrastructure.
notes:
- to get around cyclic definitions in template classes, the
EclipseState is changed to a (defaulted) template parameter which
causes the compiler to only look up the class definition at
instantiation time.
- using std::shared_ptr in the property initializers would lead to
cyclic references which would cause memory leaks. To avoid that,
plain old references where used in most places. I think this is
okay as the GridProperty objects should be considered internal to
EclipseState and thus the EclipseState object should live at least
as long as GridProperty objects...
e.g. Eclipse specifies that for PERMX only the topmost layer needs to
be specified, i.e. the following is valid on a 3x3x3 grid
```
PERMX
9*10 /
```
the previous behaviour was to throw.
also, mark if data items have been defaulted, i.e., the item of
```
PERMX
* /
```
will now return true for 'defaultApplied()'.
and also fix a small build bug in these table classes. I don't know
why they have not been also fully dealt with in the recent table code
refactoring...
since tables can be tricky, we now enforce that the compiler bails out
if the user tries to instantiate a table class manually.
Note that a bit of trickery is needed to keep the low-level unit
tests working...
I know it was only added recently, but all of the "setInDeck()" calls
can now be substituted by a combination of item->size() and
item->defaultApplied(index)...
i.e. remove the defaultSet() method and its friends. this is required
to be able to specify defaults in DATA items like grid properties or
saturation tables. e.g.
SGL
10*0.1 10* 10*0.2 /
would not be possible without this. If no meaningful default for an
item is defined, float and double items get NaN, int items get -1 and
string ones get an empty string. The hope is that if these values get
used in the simulation, they will make the result obviously
incorrect. (Whether a data point of an item was defaulted can be
queried using item->defaultApplied(index).)
also, this renames DeckItem::setInDeck() to DeckItem::wasSetInDeck()
because the former method can easily be confused with a setter method
(which it is not, it is a 'getter').
note that there is a small semantical difference now: the old
signatures specified the status of the whole *item* while the new
variants are specific for a single *data point* of an item. Though at
this point the index passed to the methods is still disregarded..
The class Value<T> will keep track of a named variable, and whether that
particular value has been explicitly initialized. Will throw
std::logic_error if trying to use an unitialized value.
The data values in a deck item can be in three different states, given
by the DeckValue enum in DeckItem.hpp. The three values are:
SET_IN_DECK : The value has been set explictly in the deck.
DEFAULT : The value was not present in the input deck, but a default
value has been supplied in the configuration and that value
has been set.
NOT_SET : No value has been set for this item; it was not explicitly
set in the deck and also not included in the configuration.
If you ask for DeckItem->value which is in state NOT_SET you will get an
exception. The method setInDeck() can be used to check if a value has
been set explicitly in the deck; the method defaultApplied() will check
if a default value has been applied.
Observe that the system for handling defaults is not really well suited
for multi valued data items, as it is only a scalar state variable. In
the case of multi valued data items both defaultApplied() and
setInDeck() might return true.
this is required in situations where double grid properties depend on
the values of integer (i.e, *NUM) ones which appear later in the
deck. Example:
```
PROPS
SWU
* /
REGIONS
SATNUM
*2 /
```
the default value of the SWU keyword depends on the value of the
SATNUM property which only gets defined later in the deck. an
alternative to the approach of this patch would be to process the
grid properties of the REGIONS section before the others. I'm a bit
indifferent which approach is better...
The new constructor allows us to create EclipseGrid objects from decks
that do not have a strict sectioned structure.
Also modify some implementation details. Many methods are now templates,
and can take Deck or Section objects (they have the same
hasKeyword/getKeyword interface).