With this commit the VFP tables are stored internally in DynamicState<VFPxTable>
container, this facilitates updates to the VFP tables during the simulation. In
addition the default constructor and the ::init( ) method has been removed from
the VFPxTable implementations.
Capture the maximum number of segmented wells, the maximum number of
segments per well, and the maximum number of lateral branches per
(segmented) well.
These maximum sizes are needed to correctly define portions of the
contents of the INTEHEAD vector in a restart step.
Decrement timestep where necessary to avoid well post-configuration.
Consider the following:
.
.
.
WELLSPECS
'W1' 'G1' ... /
TSTEP
2*1 /
WELLSPECS
'W1' 'G2' .../
TSTEP
2*1 /
In that case the parent group of W1 is changed after two timesteps. At timestep
two the Group parent will indicate G2, while the GOPT:G2 at timestep two should
be reported for what has progressed up until timestep two.
we only the definition with METRIC unit system. Not sure how they should
be used with other unit sytem, since we do not know the units of these
values, which is not easy to find out either.
For the moment, we only handle the METRIC unit system for now.
Capture the maximum number of connections/perforations per well, the
maximum number of wells (or sub-groups) per well/node group, and the
maximum number of well/node groups in the field.
These maximum sizes are needed to correctly define the portions of
the contents of the INTEHEAD vector in a restart step.
Allow keywords that can be default constructed to do so when acted uppon
by MULTIPLY and ADD.
Setting the "MULTIPLY" keyword to act on "PORV" would throw an
exception:
"Program threw an exception: Fatal error processing MULTIPLY keyword.
Tried to scale not defined keyword PORV"
Now the initPORV is called if the MULTIPLY keyword is parsed with PORV.
Note that MULTIPLY for PORV will also work in the GRID section (which it
does not in eclipse), but will fail if it is placed prior to setting a
variable PORV depends on.
Commit authored by Sveinung Styve Rundhovde and Lars Petter Hauge
Efficiency factors are multiplied when specified at multiple levels of
the well/group hierarchy.
The factors are included as follows:
* Well Rate - No efficiency factor
* Well Total - WEFAC & GEFAC (whole hierarchy)
* Group Rate - WEFAC & GEFAC (only subgroups)
* Group Total - WEFAC & GEFAC (whole hierarchy)
* Field Rate - WEFAC & GEFAC (whole hierarchy)
* Field Total - WEFAC & GEFAC (whole hierarchy)
* Region Rate - WEFAC & GEFAC (whole hierarchy)
* Region Total - WEFAC & GEFAC (whole hierarchy)
* Completion Rate - No efficiency factor
* Completion Total - WEFAC & GEFAC (whole hierarchy)
Authored by Sveinung Rundhovde and Lars Petter Hauge
Applying efficiency factor to region keywords requires a list of wells
having completions inside the region.
Authored by Sveinung Rundhovde and Lars Petter Hauge
clean up
removed aquancon collection from Aquifer CT
clean up and unit test
clean up
Conflicts:
lib/eclipse/CMakeLists.txt
Add reference to Van Everdingen and Hurst
remove cmakelists
added test in Cmake
Added aquiferct to cmake
is a shared library
additional condition for opm-parser as it forces dyn boost test (not
strictly necessary but it highlights the different behaviour for now)
These classes are only used by opm-material and its downstreams. The
reason for doing moving it there is that this allows more freedom in
reorganizing the lower-level OPM modules (i.e., opm-common,
opm-parser, opm-output) while still avoiding a hard dependency of the
thermodynamic and numerical framework modules on the ECL file parsing
libraries.
even though the official documentation does not seem to specify
whether the specified heat capacities of the SPECROCK and SPECHEAT
keywords are for constant pressure or for constant volume, the
implicitly seem to be for the latter: pressure dependent heat
capacites cannot be specified, yet the enthalpy for an incompressible
fluid *is* pressure dependent, so the specified heat capacities must
be for constant volume and they specify the internal energy instead of
the enthalpy.
earlier the assumption has been that all test executables have a test_ prefix
which was stripped off. now we just use the full name if the prefix is not
found.
Aquancon object
Reorganized and changed the way the aqurecord object works
Working aquancon object. Still need to implement better logic. Also added test case
Changed indexing bug
Fixed the correct indices for the collate function
Made a private function for getting the record index matching the aquifer id
Reformatted the private function for readibility
Added logic to find unique global cell indices
Collate function done... Now need to apply logic to these entries...
clean up
Conflicts:
lib/eclipse/EclipseState/Aquancon.cpp
edit object definition
Otherwise implicit dependencies are never search for. That was the case
for dune-geometry and dune-grid when configuring opm-core as these are only
transitively required via opm-grid.
With this commit we include <module>-prereqs.cmake in <module>-config.cmake
and thus trigger searches for all modules that this module depends on.
We also install the file now <module>-prereqs.cmake as we need it for
installed modules, too.
use pure config mode.
we no longer compile a test application for the libraries,
however checks have been tightened by making sure version of
all opm modules are the same.
this allows for putting prereqs directly in the module repositories
since dune.module is primarily required for dunecontrol support and
you cannot run dunecontrol without dune-common anyway, nothing changes
for dunecontrol users.
for users who do not use dunecontrol, nothing changes either because
the dependencies are specified in opm-common-prereqs.cmake which stays
untouched by this commit.
the class takes a boolean parameter as its first template parameter
and a type name as the second. if the boolean parameter is false,
nothing is stored, else an object of the type of the second template
parameter gets created. this mechanism allows to disable member
attributes based on compile time conditions.
The usage semantics of that class are that of a smart pointer class, i.e.,
the equivalent of
```
Foo foo;
foo.bar()
```
is
```
Opm::ConditionalStorage<true, Foo> foo;
foo->bar();
```
If the condition argument for the ConditionalStorage is false, that
code will still compile but an exception is thrown at runtime.
Mostly to remove trailing underscores. The internal 'tabdims'
vector in Opm::Tables has been renamed to 'm_tabdims' to avoid
conflicting with the member function named 'tabdims'.
This commit extends the INIT file Table writing to also output the
saturation function tables in normalised form. We support
generating the INIT file's SGFN, SOFN, and SWFN tables--including
the derivative information--for both two and three phases from both
families of saturation function keywords (S{G,W}OF and S{G,W}FN +
SOF{2,3}). We do not yet support generating the appropriate tables
from input keyword SLGOF.
We leverage the LinearisedOutputTable to abstract away some of the
details of indexing into the linear 'tab' array and create a helper
function to loop across saturation function regions whence each
table generator need only be concerned about the specific data
pertaining to that region's saturation function (i.e., the values of
independent and dependent variates and number of active rows). We
allocate the output tables according to information in the TABDIMS
keyword, notably the number of saturation nodes (item 3 of TABDIMS).
Generating the three-phase SOFN table, which has the same columns as
the input table SOF3, in the case of family One (SGOF and SWOF) is
slightly involved. In particular we need to join the SGOF and SWOF
tables on common oil saturation values and derive/insert missing
KroX data through piecewise linear interpolation in the appropriate
input table. We defer the details of merging on common (and uniqe)
oil saturation values to the standard library routine 'set_union()'
which outputs repeated saturation values exactly once rather than
for each occurrence. That way we only need to wrap the input tables
in a simple class to facilitate look-up of oil saturation values and
the mechanics of piecewise linear interpolation of the relative
permeability column for oil. Due to this merging process, the
number of rows in SOFN is twice the number of saturation nodes in
this case.
Since this support depends on being able to determine which phases
are active in a particular run, what table sizes to use for the
output and which keywords are being used to represent the saturation
function tables we introduce a single new public member function
void Tables::addSatFunc(const EclipseState& es)
This function determines the run's active phases and dispatches to
the new helper functions
void Tables::addSatFunc_FamilyOne()
void Tables::addSatFunc_FamilyTwo()
according to which keyword family exists in the input deck. These
functions in turn call additional helper functions to handle each
phase table separately. For instance addSatFunc_FamilyOne() uses
the helper function
SatFunc::Oil::ThreePhase::fromSGOFandSWOF()
to generate a three-phase SOFN table based on the information in the
SGOF and SWOF tables.
Information about slopes/derivatives for the piecewise interpolants
of the dependent variates is computed through the helper function
DifferentiateOutputTable::calcSlopes()
whence the first entry of each derivative column is undefined (i.e.,
assigned the sentinel value 1e+20). This should arguably be zero
instead. Further testing and comparison with INIT result sets
generated by ECL will inform the decision here.
We add unit tests for all combinations of number of active phases
(two or three) and which saturation function keyword family is
present in the simulation case. The unit tests use the tables from
SPE 9 for keyword family One and the tables from SPE 1 for keyword
family Two. Comparison data is extracted directly from the ECL INIT
file in the case of the SPE 9 tables and derived from independent
calculation for the SPE 1 tables.
This is more in keeping with the intended application--at least for
saturation function output to the INIT result set.
While here, also remove an unused data table (SWOF from SPE1).
This commit introduces a new helper class, LinearisedOutputTable,
that is oriented towards managing tabular data such as the PVT or
saturation functions in an ECL result set (typically, .INIT file).
The class knows about row padding and the column oriented nature of
Fortran-like tables.
While here, and in anticipation of adding output of tabulated
saturation functions, also provide a mechanism for calculating
slopes of piecewise linear interpolants. The ECL format stipulates
that function derivatives be output along with the actual table
data for most functions.
This commit switches the internal implementation of the 'tab' and
'tabdims' vectors from being a mix of ECL keyword structures and
std::vector<>s to being purely std::vector<>s. We remove the
fwrite() member function and rather reimplement the feature in terms
of new query member functions
const std::vector<int>& tabdims() const
const std::vector<double>& tab() const
that return read-only references to internal data members.
this is just like the solvent "phase" and the polymer "phase". Since
IMO this is a bit awkward, the Phases class should possibly be renamed to
something like "ConservedQuantities".
an alternative is to add heat capacity, but this is more cumbersome
because some heat capacities are volumetric while others are mass
specific. (note that the "single division" shenengian of the unit
system's expression parser needs to be considered for most energy
related keywords.)
this used to provide autotools compatibility, but it has not been working for a while. Thus it is IMO better to remove it in order not to mislead people.
this used to provide autotools compatibility, but it has not been working for a while. Thus it is IMO better to remove it in order not to mislead people.
this used to provide autotools compatibility, but it has not been working for a while. Thus it is IMO better to remove it in order not to mislead people.
inconsistent and unnecessary.
this is purely a cosmetic change, the only exception was a function with
the generic name 'split', which was renamed to splitParam to avoid confusion.
This commit adds a verbose flag to the constructor of
ParameterGroup to allow for deactivating any
output to std:cout. This is handy for parallel runs where we only
want to print statistics on one process.
A new method ParameterGroup::unhandledArguments() is available to
access the list of unhandled arguments. Before, when such arguments
were encountered they were ignored and a warning was printed to
standard out.
Apart from the lack of a (potentially misleading) warning, this
should not change the behaviour of existing clients of the class.
These functions are referred to from templates which may not be
instantiated. Since they were in an anonymous namespace they were
not reachable otherwise, and a warning is emitted. This only applies
to Clang; GCC consider them used.
If we make them static helper functions instead, the warning
disappears.
make all non-implementation headers includable without
preconditions. Also, this removes the GravityColumnSolver.hpp file,
because it tried to include a non-existing file and it was thus unused.
our policy is that we only use boost if necessary, i.e., if the oldest
supported compiler does not support a given feature but boost
does. since we recently switched to GCC 4.4 or newer, std::shared_ptr
is available unconditionally.
Every program that relies on manual inspection has been moved to a new
(hopefully short-lived) directory called not-unit/; every remaining
file has been given the prefix test_ to indicate that this is the
executable test to be run.
Disabled by default, this statement attempted to pass a std::istream to
function std::fclose() which is meaningless and should not be enabled at
any time--even for a MATLAB-related build.
This is useful if a set of parameters can all be defaulted in which
case launching the executable *should* be a simple as
./a.out
but the constructor requirement leads to using
./a.out a=b
or something similar.
When running test in opm-parser, this never showed up as a problem since
Equil.hpp seems to be always included after <vector> is included (either
directly or by including other files). However, this can become a
problem when using opm-parser in other projects (eg, sunbeam)
before OPM/opm-simulators#1309 it was required, but this was not
enforced by the build system because the SuiteSparse tests are run by
the opm-core build system first and UMFpack is optional there.
thanks to [at]akva2 and [at]blattms for the heads-up.
Since all supported DUNE versions have a CMake based build system,
when can drop the magic and use the module version exported by CMake
directly.
The magic used previously was broken when setting CMAKE_INSTALL_LIBDIR to
an absolute path.
it seems like most build systems pass a -DHAVE_CONFIG_H flag to the
compiler which still causes `#if HAVE_CONFIG_H` to be false while it
clearly is supposed to be triggered.
That said, I do not really see a good reason why the inclusion of the
`config.h` file should be guarded in the first place: the file is
guaranteed to always available by proper build systems, and if it was
not included the build either breaks at the linking stage or -- at the
very least -- the runtime behavior of the resulting libraries will be
very awkward.
it do not even build because it the "EclipseGridInspector.hpp" header
file is nowhere to be seen. I'm deleting this file outright because if
this functionallity ought to be revived, the code can be brought back
from the annals of git.
As opm-common is search in the toplevel CMakeLists.txt of each module in
config mode and the dependencies and defines are only processed in
opm_find_package(opm-common), we allow a second search using module mode
to trigger opm_find_package.
Otherwise some defines and macros will not be set as this is done
in opm_find_package. This might also make sense for dunecontrol
which always will set *_DIR.
Theses variables are already set in opm-output-config.cmake. Unfortunately,
theres is still a bug there which will be fixed by a PR in opm-output. After
that everything should work and have less guess work in it.
Previously, ecl_DIR was always set to the build directory used even
for the installed cmake configuration file. This patch at least allows
to overwrite that location and for the installed version tries to guess
the correct location. The guess is that libecl and opm-parser are installed
under the same prefix. As a fallback we use the package registry.
Previously we assumed it to be ecl (like the project name).
That is not correct. With this commit we now use the correct
default clone directory, libecl, in the sibling search.
Even though people are telling that ecl is already found using
sibling search it turned out that this statement is false. It
was always found using the CMake package cache. When installing
this lead to the installed package using ecl from the build tree.
With this commit we first try to find ecl without the package cache
but maybe using sibling search. Building installed packages no works
by setting -DSIBLING_SEARCH=Off -DCMAKE_INSTALL_PREFIX=/install/path
We use ${module}_DIR to set the correct path when sibling search is activated.
The package configuration files set all the necessary variable and we save
us a lot of CMake magic.
The Sunbeam project https://github.com/Statoil/sunbeam is replacing the
python bindings. The bindings have long been deprecated and are finally
removed.
make this default to off.
additionally, check that the found superlu version
is compatible with the dune-istl version in use.
in particular superlu5 is not compatible with dune-istl 2.4
before this, dune modules that are not using the OPM build system
needed to treat opm-parser as an external library. With this patch,
opm-parser can be build as part of duncontrol build chains, i.e.,
other modules just need to specify a depencency on opm-parser in their
dune.module file and opm-parser's libraries and headers get picked up
just fine.
Things like generating opm-parser-config.cmake should quite likely be
done in a better way, but I'm not really a cmake expert and the
solution proposed in this patch seems to get things done regardless of
whether opm-parser is system-installed or not. Comprehensive solutions
are highly appreciated.
the exported file refers to imported targets through their
name with the expectation that these are defined whenever
the target file is included.
the use of custom imported targets for boost thus becomes
problematic in downstreams, since they are forced to define
these targets prior to opm-parser inclusion.
as the targets are named the same as their library
counterparts it appears to work per murphy's law.
cmake will simply fall back to interpreting the target names as
library names, e.g. it will do -lboost_filesystem.
Up to now we assumed that if there is interest in the
initial OIP value (e.g. to calculate FOE) then oip has
to be presented to EclipseWriter during the call of
writeInitial. For the downstream simulators OIP is
not available at this stage. This commit gives the simulator
the possibility to overwrite/reset the values later and
allows the current implementations to let output calculate
and output FOE.
It seems like OPM support for Dune 2.3 is going to be removed sooner
rather than later. Also, all relevant distributions which I'm aware of
seem to ship at least Dune-2.4 packages.
note that this patch switches to Dune 2.4.1 instead of the latest Dune
2.4 release (i.e., 2.4.2) because travis seems to block downloads from
sites it does not know -- in this case dune-project.org -- and the
Dune github mirrors seem to have been abandoned a few months ago and
thus do not feature dune 2.4.2.
Remove or update referring to Boost ptime.
Change type of exception tested for in
dateFromEclipseThrowsInvalidRecord.
Add test initTimestepsLongStep that has a deck with time step of 25550
days.
Add test initTimestepsDistantDates that has a deck with dates of Jan 1st
2040 and 2050.
Add test for mkdatetime().
Remove constructor and overloads using Boost ptime. Also remove methods
rendered obsolete by the removal of ptime dependency. Rename methods
whose name was initially set to differentiate from ptime counterparts,
an example of which being 'timeTFromEclipse' renamed to
'timeFromEclipse'.
Replace use of gmtime() with util_set_date_values_utc().
Change signature of addTStep(std::time_t) to addTStep(int64_t).
Change base of month indices returned from eclipseMonthIndices(). Now
indices are 1-based.
Simplify timeFromEclipse() (previously timeTFromEclipse()).
Add mkdatetime(), analogous to mkdate() but with also hour, minute
and second parameters.
Make use of static method mkdate() rather then using new static method
dateToTM().
Fix error in addTime(std::time_t)
Remove obsolete method dateToTm() and TODO comments.
Previously, we checked for header CpGrid.hpp which finally
tried to include the non-existent generic geometry headers
as the checks for dune-geometry versions do not work during
a CMake run.
With this patch we search for the header GlobalIdMapper.hpp which
does not use any version checks and therefore works for every DUNE
version.
it would be weird if the default for the OPERNUM would be region 0
(a.k.a. -1 in C++) while it is 1 for any other *NUM keyword.
also, the //* token should never appear in any productive code. if a
case distinction between C and C++ is necessary, use `#if __cplusplus`!
The keyword generator will no longer scan the directory with keywords,
instead the explicitly/manually maintained list of keywords will be
passed as an argument to the keyword generator.
The generator will only run once, creating header files, source and
test.
On some systems, in particular Windows or custom boosts, plenty
information about configuration is embedded into the library name.
However, opm-parser's boost names were hard coded to the vanilla library
names, which leads to libraries not being found.
Generate the target names dynamically (and address them as variables) so
that the target names match the name of the library actually being
linked to - a name which is also then later exported to the
opm-parser-config.cmake file.
These take precendence over the package registry where we have no control
on which entry will be used. The registry is only the last resort.
On some Linux version the most recently created package registry key will
be used. Please not that an entry is only created for a build try that is
not already in the registry. If there is already key, then not even the
modification date of the key will be updated. This default behaviour might
lead to strange mixes of build configurations.
- the implicit casts from std::string/char* is part of the design for
the view class so we do not want to disable those.
- intializer list constructors should be implicitly called
For cylindrical grids based on the keyword set DRV, DTHETAV, DZV and
TOPS the EclipseGrid implementation will create a cornerpoint
representation of the grid.
Simplify the generator logic a bit by only creating one
ParserKeywords.cpp file, and create either source code for the library
or for the test. This is faster to compile serially, but is not possible
to compile in parallel. Still, it's a fair simplification, and clarifes
the makefile quite a bit, and makes dependencies and generation clearer.
In an effort to reduce the numbers of targets built, and consequently
the repeated work and overhead of compiling boost test, a series of
test programs are combined to larger modules.
Every target typically has a constant cost of 3-6s, depending on the
computer, just for the make to set up dependencies and for the compiler
to parse and compile the testing framework and other dependencies. Each
set of tests typically add very little, so significant savings are
achieved by merging targets.
When tested on a 2015 i5m laptop, this reduced serial, single-core
compile time from ~14m45s to ~11m15s.
Tune the makefile according to new principles, which adds a few bells
and whistles and for clarity.
Synopsis:
* The dependency on opm-common is completely gone. This is reflected in
travis and appveyor as well. No non-kitware cmake modules are used.
* Directories are flattened, quite a bit - source code is located in the
lib/ directory if it belongs to opm-parser, and external/ if third
party.
* The sibling build feature is implemented through cmake's
export(PACKAGE) rather than implicitly looking through source files.
* Targets explicitly set required public and private include
directories, compile options and definitions, which cmake will handle
and propagate
* opm-parser-config.cmake for downstream users is now provided.
* Dependencies are set up using targets. In the future, when cmake 3.x+
can be used, these should be either targets from newer Find modules,
or interface libraries.
* Fewer system specific assumptions are coded in, instead we assume
cmake or users set up system specific details.
* All module wide configuration and looking up libraries is handled in
the root makefile - all sub directories only set up libraries and
compile options for the module in question.
* Targets are defined and links handled transitively because cmake now
is told about them. ${module_LIBRARIES} variables are gone.
This is largely guided by the principles outlined in
https://rix0r.nl/blog/2015/08/13/cmake-guide/
Most source files are just moved - if they have some content change then
it's nothing more than include fixes or similar in order to make them
compile.
CONFIG mode is usually a fallback when Find* modules are not found, but
opm-parser is now mainly meant to be used with config mode, so it's the
first thing being tried. If that fails, continue with the old logic.
Some legacy requires HAVE_ERT being set somewhere, so this logic is
injected here.
If the region keywords from the SUMMARY section, like e.g. RPR, are
specified without explicit region numbers a summary key is added for all
region values from 1..NTFIP, irrespective of which region values are
actually present.
```
opm-parser/opm/parser/eclipse/EclipseState/EndpointScaling.cpp: In constructor ‘Opm::EndpointScaling::EndpointScaling(const Opm::Deck&)’:
/opm-parser/opm/parser/eclipse/EclipseState/EndpointScaling.cpp:102:14: warning: declaration of ‘reversible’ shadows a member of 'this' [-Wshadow]
bool reversible = true;
```
Previously, this failed if one dependency was a static library compiled
without -fPIC. This is is the case for library libsuitesparseconfig on
Debian which has no dynamic alternative. The error messages read e.g.
```
/usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/libsuitesparseconfig.a(SuiteSparse_config.o): relocation R_X86_64_PC32 against undefined symbol `malloc@@GLIBC_2.2.5' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
```
With this patch we change the target_link_libraries call when using
BUILD_SHARED_LIBS=ON. We only pass the dynamic libraries as PUBLIC such
that they will get linked to the library. The static ones are passed as
INTERFACE libraries. This means that they will be automatically linked
to executables which link to the main library. Currently this transitive
linking will only work in the same module as we do not correctly export
libraries. But our build system explicitly links the others ones anyway.
Namely, that m requires an argument and not n as indicated to
getopt. This caused the help message to be printed whenever users
did not want exceptions to be thrown.
Additionally we fix the error message for options that need an argument
but do not get one.
- Will throw an exception if solution data has wrong size.
- struct ResatrtValue used as RestartIO::load( ) return value.
- RestartIO can take arbitrary double vectors as extra data.
The GridProperties::hasDeckKewyord( ) will return false for keywords
which have only been auto generated. Have also renamed
getInitializedkeyword( ) to getDeckKeyword( ).
The GridProperties.hasKeyword( ) would previously return false if a
keyword in the properties container had been auto created. This is now
changed, the hasKeyword( ) implementation will not consider whether a
keyword has been autocreated or not.
Have also added a void method GridProperties.assertKeyword( kw ) which by
side effect will ensure that the container contains the keyword kw.
Pass eclGridProperties from EclipseState to Completions in order to set
default saturation table. Most changes are due to interface change in
Schedule(...)
this object corresponds to the EQLDIMS keyword. Probably it is not the
most intuitive place to provide access to this keyword, but as far as
I can see the table manager is the only place where this object is
already properly instantiated.
The main content of this commit is that the loading of restart files is
based on map of keys passed in from calling scope. This way the
selection of keywords to save and load is fully under control of calling
scope, but in addition there are many small refactorings:
- The EclipseWriter class and implementation has been renamed
EclipseIO.
- The loading and saving of restart files has been moved to file and
namespace RestartIO, which contains two loose functions load( ) and
save( ).
- The Summary() and RFT( ) data get their own copies of the data::Cells
vector.
- Removed some abstractions and wrrappers around C / ert
datastructures. Using ecl_file_view when loading restart files,
instead of bare ecl_file. Simplified opening of unified restart
files.
- Removed the ability to save restart keywords in double precision.
* Fully internalized JFUNC
* Added JFunc.cpp, throw on wrong FLAG/DIR in JFUNC kw
* added tests for JFUNC in TableManagerTests
* added protected member m_jfunc to SimpleTable
* Added getJFuncColumn to accompany getPcowColumn
* Throws if pressure or jfunc is accessed inappropriately
* ... meaning if getPcowColumn is called when JFUNC is in deck, or
* getJFuncColumn is called when JFUNC is not in deck
* added tests for throwing and for getJFuncColumn
* SimpleTable.getColumn("PCOW/PCOG") throws if JFUNC
* In the event that one tries to get "PCOW" or "PCOG" via getColumn
* ... this will throw if JFUNC is present in the deck.
* Added tests.
Several tables are identical both in structure *and* parsing, i.e. the
code required to parse them only differ in output type and possibly
number of items to read.
FlatTable is a simple vector-based template that expands into this exact
parsing routine, based on a simple specification of the record.
Adding the DEBUG keyword specification. Makes us no longer choke on it,
but we're not using it for anything in partcular. The keyword name is
DEBUG_ since DEBUG often is defined as a macro in C++ and the auto
generation would then fail. We look up the name itself by using the
deck_names field.
Support for COMPLUMP. a keyword to re-assign completion numbers that can
be used with keywords such as WELOPEN.
Some helper functions were moved out of handleWELOPEN and reused in
handleCOMPLUMP.
No longer chokes when WELOPEN is given its last two parameters, C1 and
C2 for completion number begin/end. Instead, these now weigh in on
whether or not a well matches the criteria for opening or closing.
Includes some test fixes and some restructuring of handleWELOPEN.
Obsolete verifications of throwing on COMPLUMP have been removed.
Work around a weakness of older boosts by forcing C locale if
std::locale throws.
The real solution is to not have broken locales, but this should make it
slightly easier to get the JSON keywords compiled.
Changes DynamicState's implementation to, instead of maintaining a
current and initial element, rely on std::vector's capabilities. This
introduces a small change in semantics.
The new DynamicState will up-front allocate a vector of TimeMap.size,
and all entries will be the initial value. Lookup is then simplified to
vector.at. DynamicState.update will assgin to the given index and *all
consecutive elements* which will enforce the same invariant as before.
The behavorial change is that DynamicState will no longer throw on
update(x); update(y); where y < x. Instead, the resulting effect will be
that update(x) was never called.
This means that the Group.setInjectionPhase function behaves slightly
differently, because DynamicState.size is non-sensical. If multiple
distinct injection phases are specified for a group inside the same time
step then the last specified phase will be used. The comment has been
updated accordingly.
Fixes operator== for production properties which didn't take prediction
into account. Additionally added the operator<< with iostream for
unit testing and debugging purposes.
Extend the interface of OilVaporizationProperties to not rely on
checking the enum for existence checks. This facilities checking
hasOilVaporizationProperties which rely on DynamicState.size.
Fixes a bug where completions specified after a record just updated a
completion would be assigned a too high completion number.
COMPDAT can be used to re-specify some properties of connections, in
which case they're not actually new completions and the completion
number shouldn't change.
Connections are given a completion number starting at 1 implicitly when
they're first defined by the COMPDAT keyword. Until now this number has
been ignored.
The number itself isn't *used* for anything with this patch, just stored
and accessible.
The reference depth is not a static property on first creation, but can
change on subsequent WELSPECs. Wrap the ref depth in DynamicState to
handle this.
Well.headI and Well.headJ was assumed to be fixed on first declaration,
and that all subsequent changes of this position was an error. This
turns out not to be the case, so the I/J positions are made dynamic.
/home/mblatt/src/dune/opm/opm-parser/opm/parser/eclipse/EclipseState/Schedule/GroupTree.cpp: In member function ‘void Opm::GroupTree::update(const string&, const string&)’:
/home/mblatt/src/dune/opm/opm-parser/opm/parser/eclipse/EclipseState/Schedule/GroupTree.cpp:39:76: warning: declaration of ‘parent’ shadows a member of 'this' [-Wshadow]
void GroupTree::update( const std::string& name, const std::string& parent ) {
^
/home/mblatt/src/dune/opm/opm-parser/opm/parser/eclipse/EclipseState/Schedule/GroupTree.cpp: In member function ‘std::vector<std::basic_string<char> > Opm::GroupTree::children(const string&) const’:
/home/mblatt/src/dune/opm/opm-parser/opm/parser/eclipse/EclipseState/Schedule/GroupTree.cpp:76:77: warning: declaration of ‘parent’ shadows a member of 'this' [-Wshadow]
std::vector< std::string > GroupTree::children( const std::string& parent ) const {
Field efficiency: (OIP(initial) - OIP(now)) / OIP(initial). The initial
OIP is cached, and FOIP is reused for OIP(now). Adds the
operator-(double,quantity) to make the formula obvious from the FOE
function.
1. Removed Tabdims(int,int,int, ....) constructor and added
Tabdims(Deck) constructor.
2. Added Tabdims member to Runspec( ) object.
3. Changed std_shared_ptr<Tabdims> to Tabdims member in TableManager.
The WellSet class is replaced by std::set, allowing predictable copy
semantics of Group. This change has rather few consequences as accessing
a well through a wellset was hardly ever done.
Getting hold of the corresponding well instance will now have to be done
via a Schedule instance - however, this simplifies the dependency graph
by severing the edge between the Group object and Well objects.
Replaces The GroupTree + GroupTreeNode classes building an explicit tree
of named nodes with a sorted vector of { name, parent-name } pairs that
builds an implicit tree. Provides the same semantics as the previous
group tree implementation, but with less code and copying for free.
The ahead-of-time JSON-to-C++-object compilation step does not need all
the source files as it was passed. Reduces the set of source files
compiled into the createKeywordList binary to just the files it needs.
Redesign of ParserItem so that its sum type nature no longer mandates
indirection, but rather a tag check on all operations. Because of this,
ParserRecords can now store ParserItems directly, and iterators are no
longer iterators to pointers, but behave like normal vector iterators.
Replaces the internal inheritance + unique_ptr scheme to a flat sum type
similar scheme that uses a tag to determine which operations are legal,
rather than using the indirection itself as a tag.
Using an external cJSON installed under /usr/include was not possible before
as the cJSON headers within opm were still used due to relative paths.
With this commit move the copied cJSON source to external/cjson and
thus prevent them to be found if an externally installed cJSON is there.
The SKIPREST keyword is really only needed in eclipse - since we parse
through the entire deck and create a complete internal representation
with random access, we don't need to actually skip parts of the input.
The old behaviour was to mimic some possible failure modes for eclipse,
however this has caused issues for no real benefit.
refs:
* https://github.com/OPM/opm-parser/issues/773
* https://github.com/OPM/opm-parser/issues/960
Several functions were aliased to hide the fact that they shared the
same templated function, but with different specialisations. By
introducing aliases for producer and injector some readability is gained
and some (clumsy) aliases are removed, in favour of passing the
interesting aspect along with the general base name.
There has never really been a natural home for initial properties that
aren't InitConfig, meaning information such as phases in the deck and
other runspec information hasn't had a natural home.
This patch introduces the Runspec object on EclipseState for phase
information and other similar properties that are interesting and static
for when setting up parameters etc. for simulation, that aren't all that
interesting once simulation starts.
An additional benefit is a leaner implementation for the phase enum and
some stricter semantics via enum classes.
To be consistent with the general summary behaviour and more input
tolerant, 0.0 is returned when some phase, completion or well is
requested that isn't provided by the simulator.
Solves the issue discussed in https://github.com/OPM/opm-output/pull/122
and extends the test input deck to trigger this behaviour.
Warning-generating aliases like:
const auto& es = this->es;
were removed. The rest of the code would not need any change since
then 'es' would refer directly to the data member, but in keeping with
the usual ways in this module I changed them to explicitly reference
'this->es', thereby restoring the visual clue that the member is used.
The data exchanged in data::Well::Completions is now a vector, more
closely matching the disk format and the order exposed by the simulator.
Zero'd wells and complations are still written for shut wells, or wells
the simulator does not provide any information for; however, all
non-closed wells (according to the schedule) will be restored. The
completions are written and restored in the same order as CompletionSet
from parser.
1. Will retain already set values when only some items are set.
2. Will parse the sections before the SCHEDULE section to create a
correctly initialized MessageLimits object.
Change the structure used to populate OPM_XWEL to use a plain map of
data::Wells objects rather than dumping a series of vectors to
data::Wells. Tests are added for serialising and restoring wells.
Just relying on the char data type is not sufficient to guard against
overflows, and several input decks would invoke undefined behaviour.
This code path is extremely hot, so we're essentially only reading the
least significant 7 bits to achieve branchless lookup.
for some reason, it looks like `std::find_if()` does not work on
ubuntu 16.10 with clang and enabled optimizations. since as far I can
see this 'if' is a minor performance improvement in non-time critical
code, let's just remove the condition.
The termination logic would sometimes need to scan the full line to see
if some terminating condition was found inside quotes. Plenty of
comments in a file start on the first character of a line, meaning this
scan is unnecessary.
This also means UnitSystem must be default constructible, which now
makes the default unit system metric. GridProperties must also be
default constructible (a valid 0x0x0 grid with no properties).
Will use one common container for both the solution data required for the
restart, e.g. PRESSURE and SWAT and also the auxillary data like KRG and
FIP which is intended as extra information in the restart file, or
alternatively the summary file.
this fixes some annoying inconsistencies (e.g., the recently
introduced 'dyne' unit was unavailable in the opm-core version) and
gets rid of some compiler abiguity errors if 'using namespace
Opm::details' was used by code inside the 'Opm' namespace.
Since opm-parser is a hard dependency of opm-core, the only measure
which must be taken by higher-level code is to include
'opm/parser/eclipse/Units/Units.hpp' instead of
'opm/parser/eclipse/Units/ConversionFactors.hpp' or
'opm/core/utility/Units.hpp'.
Note that a potentially better location for this code would be
opm-common, but this would break the Windows build of opm-parser.
OilVaporizationProperties can now be default constructed, and its
storage has been changed from shared_ptr to value (which mandates the
support for default construction and equality/unequality).
The default constructed Property is considered unspecified and
operations on it will not make sense.
Also makes the *contents* of the vector values, not shared_ptrs.
This introduces the copy constructor (as an alternative to deepcopy())
and comparison operators, mandated by DynamicState.
dynamicstate.get returns a const reference rather than a by-value copy,
in order to be consistent with other container classes.
This introduces a problem for std::vector<bool> with its specialisation,
so all DynamicState<bool> instances has been replaced by
DynamicState<int> and explicit bool conversions.
-- Control mode given by WHISTCTL overwrites control mode given in
WCONHIST
-- option for termination of run if changed to BHP control in not
implemented. But ParseContext is used to inform the user and make
throwing optional.
Replaces checking if the report step is zero with maintaining some state
and determining if any given step is the first time an UNRST file is
written to or not. Extends the test to also cover this case. New
behaviour will remove all time steps from a pre-existing UNRST file from
the restart step being started from, but preserve all steps leading up
to that point.
- restartRegressionTest, initRegressionTest was squashed to one
application, which also supports integration test as well as test
of restart files (non-unified) and .RFT files.
- summaryRegressionTest was renamed compareSummary -- now it can
execute an integration test as well as regression test. Also other
improvements were made.
- The compare library summaryIntegrationTest.cpp and header was added,
which implements a integration test for summary files.
- The summary regression test was enhanced with extended
functionality.
- EclFilesComparator.cpp with header file now includes an integration
test for SGAS, SWAT and PRESSURE in UNRST files, and also the
regression test was improved with cell volume check, as well as checks of more
keyword types.
- The outputwriter will now take a a separate EclipseGrid instance as
input argument, it is assumed that calling scope has already made sure
ACTNUM and ZCORN are correct.
- All active/inactive cell mappings are based on the grid argument, the
naked int* with global / active cell mappings has been completely
removed.
Note that this keyword is pretty quirky. Depending on whether
E100/E300 considers it for MINPV handling or not, this patch is also
not going to cut it. (After this patch, OPM will consider MULTREGP for
the MINPV handling. Could somebody with access to E check?)
This commit adds conversion factors for the ECL LAB unit
conventions--notably Atmospheres for pressures, Hours for time,
Grams for mass, and cubic centimetres for volumes.
The hand-written number parser functions implemented using strtod and
friends were rather slow (profiling indicates that typically 30% of the
program is spent inside of strtod internals). By using
boost::spirit::qi, which we already depend on through boost-filesystem
and others this portion typically seem to be reduced to 20% (via
instruction count) and with somewhat better cache performance.
Rudimentary measuring indicates ~15% speedup overall.
Additionally, the intention is a lot clearer this way, so readability
received a boost. Compilation time of StarToken goes through the roof.
The simProps argument is vector of field properties which have been
initialized / calculated by the simulator. Examples of such properties
include the relative permeabilites KRG, KRO and KRW and the fluid in
place vectors FIPOIL and FIPGAS.
it is parsed and put into the deck, but it is not internalized in any
way. (Note that, given that this keyword is quite simple, adding
sophisticated code to absorb it into EclipseState would be overkill,
in my not so humble opinion.)
In restart files generated by Eclipse the solution fields, i.e. pressure
and saturations are written in 32 bits precision using floats. For
compatibility that is the default behavior in opm/flow as well, but with
this patch it is optionally possible to write the solution fields with
64 bit double precision.
The resulting files will probably be incompatible with third party
applications, so this should be done with extreme caution.
A RestartConfig refurbishment that generalises some of the previously
special-casing. Short synopsis:
* Integer list input is first translated to their corresponding
mnemonics.
* Mnemonic implementation support turning off input parameters via
mnemonic=0, handled generally rather than special-cased for BASIC/FREQ
* Restart configuration setup is handled in one else-less, linear code
path. RPTRST and RPTSCHED are interpreted by their separate helper
functions, but they produce the same resulting object. Should be
easier to follow
* Ignores unknown mnemonics, has a list of known/supported mnemonics
that will be internalised.
The explicit list over supported keywords is from the Eclipse100 manual
and must be manually maintained, i.e. no dynamic solution is in place
yet. This might never be necessary, but support it dynamically isn't a
problem.
RestartConfig is a first-class citizen of EclipseConfig rather than
being embedded in IOConfig. This narrows IOConfig's responsibility to
only that of paths file system definitions and interactions, and
RestartConfig to what and when to output the restart file.
Implementing these checks as function objects improves performance
slightly (5% or so according to my measurements), probably due to the
functions being inlined rather than reduced to function pointers.
Profiling indicates the size-check isn't hoisted properly. In this case,
manually hoising the loop invariant doesn't negatively impact clarity
nor give any more noise, and slightly improves performance.
SCHEDULESection with its special implementation is a remnant of older
design and largely unnecessary now. The implementation also relied on
shared_ptr for efficiency and was not really used at all.
SCHEDULESection now is no longer special, and uses the same
implementation as SUMMARY, RUNSPEC etc. The one thing that separated it,
looking up keywords within a timestep, was only used once and this
computation has been inlined in the function.
Rather than doing add-item-check-duplicates per DeckItem added to a
record, construct all the items at once, then pass them in full to the
DeckRecord object. The DeckRecord object still check for duplicate
names, but with lower complexity and cost.
Reuses the original records string_view rather than expanding to the
same std::string, we save some allocations, memory cache misses and
simplify the class slightly.
Additionally, the uninteresting add-multiple-identical-records logic
ParserItem did before has been moved into RawRecord and is now performed
by std::deque (which also means it can allocate better for itself). The
addition of prepend deprecates push_front.
Book keeping internally in the string class is rather unnecessary and
performed a lot (once per line in the input). Performing a manual copy
without string encumbered book keeping (essentially using the string as
a raw char* buffer) gives some performance, which scales well with the
lines in each deck.
Added restartRegressionTest.cpp, initRegressionTest.cpp, rftRegressionTest.cpp, summaryRegressionTest.cpp, and modifying CMakeLists_files.cmake to include these.
Added EclFilesComparator.cpp, summaryComparator.cpp and summaryRegressionTest.cpp and corresponding header files. Also including these files in CMakeLists_files.cmake, and adding boost tests in the tests directory.
Added restartRegressionTest.cpp, initRegressionTest.cpp, rftRegressionTest.cpp, summaryRegressionTest.cpp, and modifying CMakeLists_files.cmake to include these.
Added EclFilesComparator.cpp, summaryComparator.cpp and summaryRegressionTest.cpp and corresponding header files. Also including these files in CMakeLists_files.cmake, and adding boost tests in the tests directory.
By moving the unit conversion to the low-level arithmetic rather than
the high level functions, the DSL is simplified by inferring result
types rather than requiring explicit conversions. This means the
formulae are more lisp-like and more natural, since there is no more
need for liq_vol and fiends.
An added benefit is that multiplication now is commutative also with
respect to units, so the wonky left-hand-side-converts semantics are
gone.
Write the corresponding unit type (as a string) to the values written in
the Summary file.
Accomplished by running every registered function as the ert entry is
created and obtaining the string representation of the result. The
computation is called with empty, dummy structures.
In line with Eclipse water cuts, gas-oil ratio etc. only applies to
production values, rather than all rates. This sparked some other
refactoring that moves the negative-else-zero logic into the rate
calculation.
The configuration of when to write restart files is quite complex,
involving at least the three keywords RPTSOL, RPTRST and RPTSCHED. This
commit moves that configuration from the IOConfig class to the
RestartConfig class.
At a later stage the RestartConfgig class will be extended with
information of *what* to save in the restart file.
A small set of the completion family of keywords, water/oil/gas
production and injection. The tests and example data file are updated
accordingly, with edge cases.
Looking up well keywords uses the well matching algorithm. This covers
all cases supplied by the eclipse documentation, and extends it slightly
by also allowing matching.
The well matching algorithm has been tuned to not throw when a well name
is used for pattern and the well is not registered. Instead it will
return the empty list, meaning keywords that expects to match over
wells, but passes full identifiers, that also rely on the match to throw
for control flow, will have to manually check the emptiness of the well
list.
The configuration of when to write restart files is quite complex,
involving at least the three keywords RPTSOL, RPTRST and RPTSCHED. This
commit moves that configuration from the IOConfig class to the
RestartConfig class.
At a later stage the RestartConfgig class will be extended with
information of *what* to save in the restart file.
1. The normalizing in keyword names has been moved from
Eclipse3DProperties to GridProperties.
2. The normalizing does both UPPERCASE and removes trailing
whitespace.
Uses boost's temporary path facilities rather than suggesting /tmp for
temporary directory creation. Linux users will observe no difference,
but the test itself will run on Windows.
Windows' compiler complains that {} yields a non-const expr for the
std::initializer_list, meaning compilation breaks. Changed to a const
static instead so that MSVC is happy.
Severs the code dependency on opm-commmon. There was no actual
functional dependency here, with the exception of some enable/disable
warning headers. To properly make opm-parser a stand-alone module the
usage of these headers have been removed and the dependency on
opm-common is gone.
By using the ALL keyword or by denoting the same keyword multiple times,
there would be corresponding multiple entries in the SUMMARY file.
Address this by removing duplicate entries from the list of smspec
nodes.
The internal helper functions have been redesign. The initial ambition
was to create small, composable functions by-value functions and have
the high-level algorithm, which is essentially (concat . map handler
[kwlist]). However, MSVC breaking and therefore poor development speed
of utility libraries mandates adjusting the approach a bit.
The major change here is the "return value" of the helper functions
being passed by-reference to all helpers, which will append the elements
they generate onto the collection.
Generalises the SummaryConfig internal representation building by no
longer special casing the ALL keyword in the loop, but rather explicitly
look it up, analyse the expanded list as a new and isolated deck, and
then merge the results.
Initializer list support makes some tests much easier to write (and
read) and enables some nifty features for when small, special-purpose
decks are needed.
Some minor hygiene, not exposing some highly internal detail. The list
of keywords ALL expands to is duplicated rather than acessible via a
method, but:
1. this is highly likely never an interesting list of applications
2. it's really only useful for testing **AND** is unlikely to change
3. unclutters the header files slightly
A rewritten Summary.cpp with some minor header modifications. Synposis
of the new implementation:
* Uses unordered_map< string, std::function > for dispatch, instead of
multiple functions and a switch
* Some poor man's function composition support has been added
(privately) to avoid a lot of reptition in the post processing.
* Functions assume they work over lists of wells instead of single wells
being special cased - this means groups of well etc. can share
implementation with single wells and field keywords.
* Unsupported keywords are not written in the Summary file.
Furthermore, some comments on special cases and overall approach and
a generally more declarative implementation. This change is invisible to
downstream developers. Users will obviously see no more garbage
keywords.
- Removed class Init completely - writeint an init file is handled by
the method EclipseWriter::writeINITFile( )
- Seperated writing of INIT file and EGRID file better.
Two convenince call for downstream users that allows querying well rates
with the assumption that if something is unsupported or of the wrong
type, return plain zero.
* Removed method getDims since getNXYZ already exists
* Now we throw if EclipseGrid get lean deck
* Removed tests for assertCellInfo and hasCellInfo
* Fixed ResinsightTests to use GridDims
* Added a test to ensure DIMENS/SPECGRID are handled consistently
* Added GridDims.cpp source file and moved code from header
* Added GridDims.(c|h)pp to CMakeLists
* Removed use of MessageContainer in GridDims, updated calls
* Made function getDims(keyword) inline readDims
* Reformatted GridDimens
* Fixed a Section to Section& bug that occurred after removing ptr's
* Renamed initFaults to addFaultFace
* Organized imports in EclipseState and Eclipse3DProperties
* Fixed 2013 to 2016 error in header in E3DP
Simulators might modify the grid post EclipseState creation, so the Grid
fetched from there is unreliable. Copy the Deck-provided grid and apply
the manipulations at EclipseWriter construction time to ensure it uses
the same dimensions and has the same properties as the simulator.
this fixes opm-simulators#702. which turned out to be a quirk of the
build system which is due to the fact that opm-parser likes to do some
things differently than the rest of OPM. (in this case the culprit was
that it does not generate a `config.h` file which resulted in the
HAVE_REGEX macro to be different between opm-parser and downstream
which in turn causes the ABI to be incompatible.)
Note that it would be nice to use `std::regex` instead of Boost, but
this is currently blocked by the requirement that the oldest supported
compiler is GCC 4.8. (GCC 4.8 only provides a stub implementation of
`std::regex`.)
Deprecate the WellPtr -> shared_ptr aliases. The Schedule object is the
sole owner of these objects, and shared_ptr in the interfaces hid that.
The interfaces still relies on pointers to pass Wells around for now,
in order to (mostly) preserve source compability.
Some decks use comma to separate items in a record, but the comma adds
no extra information and is essentially ignored. Post-process the file
after cleaning it and replace all commas with whitespace.
Considering the record "foo bar , , , baz" / baz will silently be moved
to the third item, but handling that situation is a **lot** more
difficult and time consuming and not worth the effort for now.
Additionally, we have yet to receive decks that fail in such a manner,
nor are we sure if it is even a valid record in Eclipse.
Ert is a hard dependency that provides much of the core functionality of
opm-output, whereas boost::filesystem only provided create-directory
features. Since Ert conveniently provides the same features with a
near-identical interface and is used for file-writing anyway, the
responsibility for interacting with the file system has been put on ert.
Boost is now only used for testing in opm-output.
Since production is seen as negative injection, and production rates
often are zero, negative zeros would be returned. Likewise, occasionally
numerical noise gives slightly-below-zero values which are now rounded
to be plain zeros.
* This class contains the following State methods
** getSchedule
** getIOConfig
** getInitConfig
** getSimulationConfig
** getSummaryConfig
* For better decoupling
* For future, ease the shared_ptr-ref transition
It's perfectly legitimate for clients to "default" a well result, e.g.
when it hasn't started up yet, in which case most output will default to
0. Avoid crashing when this happens, and instead calculate based on a
dummy well.
Basing the dest durations on days over seconds make them less noisy,
more readable and closer to actual idiomatic use. Removes some subtle
complexities from the tests.
The to_si/from_si functions were moved into UnitSystem which now manages
table lookup for clients, rather than having to store the raw
conversion tables.
Reading the start time from EclipseState means it's no longer required
as a parameter to every method, and that the current time can be
calculated as start time + time elapsed.
This is-a relationship is never used, and the vtable is never leveraged.
The augmented output writers already use uniquely named output writers
anyway, so there is no reason to go via the hurdle of inheritance.
This gives a lot of flexibility when it comes to interface, since
Eclipse output can make Eclipse-specific assumptions.
The boost object was only used to calculate elapsed posix time anyway,
which is required (and already managed) by the callers. This makes the
interface slightly less complicated and removes an otherwise pointless
dependency.
Hides all the EclipseWriter details and helper classes using pimpl,
which now enforces the non-copyability of EclipseWriter (which relies on
open and stateful file handles).
Rewrites the RFT test to be independent of opm-core data types and
functions, and renames it to test_RFT since the class now represents the
full file, not some open-closing handle.
UnstructuredGrid is deeply tied to core, and is disabled for now.
writeVtk should be rewritten to use EclipseGrid as input or something
similar, but support is dropped in its current state.
The grid structure was only used to read static size-related properties,
meaning the instance itself was rather uninteresting. Replace the grid
argument with raw ints.
Remove the unnecessary or unused includes. Consequence is well enum
conversions being no longer public static. To not break the tests the
functions have been implemented in writenumwells.
Remove the opm-core dependency and re-implement the RFT writer. The
approach has been changed in the sense that we now store and keep alive
a file instance for the RFT file, instead of re-opening the file at
every time step.
To stay consistent with the interface exposed by the other
eclipse-writer components, the summary facilities takes its time elapsed
since simulation start, not on a per-step basis.
The support for reading restart files has been written in order to break
the dependency on opm-core. init_from_restart_file now returns
opm-output defined data types that clients, typically simulators, can
use to populate its own internal structures at will.
Adding the xwel member to data::Wells to support restart file output,
defining an exchange format with that in mind. For convenience,
introduces some initializer_list constructors as the buildup otherwise
is tedious and clumsy. Does not change much w.r.t. external interface.
In a transition period for non-eclipse output, store a pointer to the
underlying SimulationDataContainer. Should be deprecated by writing
non-eclipse output with the new input types.
To break dependencies between modules, and to properly define the input
format for the output facilities, make writeTimeStep take data::Solution
over SimulationDataContainer.
Completely remove the dependency between Schedule and IOConfig. IOConfig
will generate its own instance of TimeMap, rather than relying on
Schedule to construction and keeping it alive.
Break the cyclic dependency between IOConfig and Schedule where Schedule
updated parts of IOConfig. Instead, IOConfig completely builds its own
restart config.
Tests are updated to reflect this.
IOConfig's string constructor has been deprecated in favour of accepting
a Deck. handleGridSection and handleRunspecSection been moved into the
constructor itself. This clarifies the *actual* dependency in expected
IOConfig usage.
Save some implementation by using std::stack as interface and
implementation for InputStack. Remove the vector pair of file and file*
and just use file directly.
The tests requires some boilerplate setup and quickly became slow to
maintain and run. Rewrite so that the tests are grouped on topic instead
of immediate keyword family.
- Moved the handling of keywords from Eclipse3DProperties to
GridProperties<T>.
- The GridProperty<T> postprocessor is invoked from
GridProperties<T>::getKeyword() method. The question of whether the
postprocessor should be invoked or not is determined by the
overload:
public:
const GridProperty<T>& getKeyword(const std::string) const;
private:
GridProperty<T>& getKeyword(const std::string);
The public const overload will run the postprocessor, whereas the
non-const private overload should (will) be used in the construction
phase and should not invoke the post processor.
- The two pass passing where we first internalize integer keywords and
then floating point keywords has been removed.
- Code in GridProperties has mainly been moved to GridProperties.cpp
with explicit instantiation for int and double.
getDeckUnitSystem largely implies getting an *identifier* to the unit
system used in the deck, where the actual object returned has conversion
features to/from SI as well. Augment EclipseState's interface with the
simpler getUnits name.
Occasionally the SUMMARY section requests wells or groups that aren't
defined in the Deck. Ignore these names (which would typically crash
downstream) and carry on.
With the introduction of Parser::parse methods and the relaxed lifetime
requirement of Deck (i.e. users no longer need to keep a Deck instance
around for EclipseState to be considered valid), the UnitSystem cannot
be a reference, but must rather be stored.
Since the unit system is immutable once the deck is read this is
unproblematic. It's also small and cheap to copy.
* EclipseState now copies input ParseContext and keeps it as member
* Made the argument (ParseContext) default as ParseContext()
* Now you can make a new EclipseState with only deck as argument
* Removed test that tested address equality of ParseContext objects
When the TITLE keyword was present in the deck, but no parameter was
given the parser would consume the next keyword as the simulation TITLE.
Override this by writing a default TITLE if it's unset.
Internal names are deprecated, and instead added ParserKeyword instances
are maintained and kept for the lifetime of the ParserKeyword instance.
Querying keyword existence from python picks up on Deck names, expected
to always be the intended case, instead of internal names.
By allowing getline to assume that the next line always starts after the
found \n *or* that after the found newline is the \0, we can avoid a
branch and potential stall.
This function is not an obvious member of Parser, as it is just as
reliant on ParserState which is source-file private to Parser. Moves to
source file only, without externally-visible private symbol table entry.
tryParseKeyword and createRawKeyword don't use anything non-public and
does not rely on any non-public parser state, so they are now
implemented as functions private/static in Parser.cpp
A getline implementation that carries mostly the same assumptions as
istream::getline. Requires ParserState::done() to always be checked (for
negative) to safely retrieve the next line.
Enables tryParseKeywords and friend to only maintain a high level view
of the parsing procedure, and not deal with stream positioning.
Moves the storage/lifetime components of ParserState into its own
helper utility class. Splits the implementation responsibility so that
all input data and state is handled by the InputStack, and "global"
information is managed directly by ParserState.
The splitting of RawRecords into individual symbols uses string_view.
Also updates tests since RawRecord now assumes that the record string it
receives is complete and does *not* contain the terminating slash.
Since string_view uses char* for representation, there is no longer a
need to copy into a local char array for most code paths (only when the
input must be modified due to fortran float formatting).
By representing string_view as char* instead of
std::string::const_iterator the string_view class bring possibly
slightly lower overhead, but mostly enables some optimisations.
Perform a pre-pass over the input and remove everything that isn't
interesting. Preserves empty lines to provide accurate line number for
diagnostics/error output.
The use of string_view for keys allows comparison with keywords from the
file buffers to be compared directly, instead of having to go via
std::string. This removes the need for a series of (inherently)
unecessary copies.
Several inner parser functions modified to use string_view, to reduce
unecessary copying (and indirectly allocationg) related to passing
strings around.
Replaces the parser's dependence on streams with string_view, which
won't copy to its internal buffers. Involves hand-rolling std::getline
for string_view to preserve stream-like behaviour.
Replaces the external stream-support by reading the entire contents of
input files at once, rather than lazily through streams. Uses
stringstreams internally, but keeps the entire file in memory through
std::string
openString/File has been renamed to loadString/File
When considering if a keyword is valid, the parser procedures convert
the same string to uppercase twice, with copies. This behaviour has been
changed, and ParserKeyword now assumes it will be given a
correctly-formatted keyword to look up.
Rewrites ParseState to use an explicit stack of open file streams
instead of spawning multiple ParseState objects. While recursion is
*the* most elegant to solve a typical include-file system, the global
nature of eclipse declarations make this clumsy (at best). Instead,
maintain an explicit stack of open files and logically parse the input
as if it was all concatenated into one large file.
Also adds some convenient ways of accessing the current (and
interesting) top of the stack.
Restructures createRawKeyword to use multiple return statements over
if-else and updating variables, reducing indentation to have fewer
contemporary branches.
Changes the control flow of Parser::createRawKeyword to return on
failing to meet preconditions, rather than if-else block. Reduces
indentation and concurrent code paths.
Makes the actual effects of the various condtions more clear by
emphasising the return of the function rather than some possible action
after the loop.
Restructures the per-iteration check of whether or not to continue
parsing to happen first and be an early-break, instead of this flow
being handled by if-else.
The implementation has been rewritten to use iterators and renamed for
internal use. The public static function still exists for testability
and easy verification, but should be considered an internal part of the
parser.
With the inflexible GridProperty*Function replaced with std::function,
bind parameters individually to each property, indicating exactly what
dependencies any function has.
Replaces the home-grown capturing function object with std::function.
Using the library provided std::function enables creating the objects
via std::bind, enabling non-uniform signatures and relieves us of a
maintenance burden.
By precomputing and storing the keyword-to-enum mapping, accessing and
writing to a node overhead changes from log(N) to constant, and should
behave better w.r.t. cache and memory access.
Not asking sum_rate/vol for wat/oil/gas is a programmer error in the
library and shouldn't happen, but is unfortunately unverifiable with the
current tooling. The fall-through now signals a runtime error instead of
silently returning the wrong value.
This commit is a first step towards reducing the use of the Deck api
outside of opm-parser. Downstream modules should preferably use the
EclipseState api which is richer in features, and also easier to use
correctly.
The current form of the code is temporary, in the future we will remove
the OPM_PARSER_DECK_API_WARNING compile guard.
To clarify intent and the high-level formulas used to calculate the
requested values, a series of partial applications are introduced since
most parameters to the functions are fixed from the caller.
This increases signal-to-noise ratio in the switch dispatch, at the
expense of some boilerplate before the switch itself.
The WRITE test was a mere convenience to create and inspect a summary
file, but this should instead be moved to applications or examples, and
out of tests. The helper class setup now has a destructor that will
automatically attempt to clean up the files produced by ert.
Support for the creation and output of ecl-compatible SUMMARY-section
configured files. Supports a set of Well keywords, with unit conversions
based on user request, and comes with a test suite.
This object turns out to be the actual configuration object, not a
mediator state to obtain a configuration. It is therefore renamed to
reflect intent and behaviour.
* Added ACTNUM as keyword to Eclipse3DProperties
* Removed certain checks from EclipseGrid that are no longer of use
* Added tests to EclipseGridTests that test boxed ACTNUM and activeCells
* Made EclipseGrid non-const in EclipseState since we must run resetACTNUM
* Fixed a minor typo in an error message in EclipseGrid
* Fixed typo in GridProperty: Deckeyword -> DeckKeyword
* Fixed two errors in tests recently introduced relating to Ecl3DProps
* Removed test in EclipseGridTests; We now accept too small ACTNUM vectors
* Added ACTNUM test for GridProperties
this breaks with g++ 4.8 used in redhat builds.
/usr/include/boost148/boost/filesystem/v3/path.hpp:710:24 error: 'path'
is already declared in this scope.
just like for macros that start and end with `__`, `clang++
-Weverything` likes to complain about macros which start and end with
a single underscore. This is basically the same issue as
Ensembles/ert#1048
Enable support for querying what fluid-in-point regions are defined in
the deck. For now the only interesting regions are the ones specified by
the FIPNUM keyword in the REGIONS section.
The implementation is somewhat inefficient (n log n over the number of
cells in the grid), but since this is likely to only be called when
default-expanding SUMMARY section keywords this isn't too bad, since the
implementation is so dead simple.
Introduces a simple format for data exchange between the simulators and
the the output facilities. Output functions will expect these types, and
it is the simulator's responsibility to create and provide it.
This patch introduces aggregates for well-related information: well
rates, bottom hole pressures and completion rates. Uses a simple bitmask
scheme to differentiate between written values and random garbage.
* Added Eclipse3DPropertiesTests
* Refactored tests to use Eclipse3DProperties instead of EclipseState
* Added unsigned literal to MessageContainerTest
* Added keyword "OPERNUM" to supported keywords in Eclipse3DProperties
* Updated tests to use Eclipse3DProperties API instead of GridProperties
* Moved init sequence of title into constructor
* ThresholdPressure and SimulationConfig now tasks Deck ref instead of shared_ptr
* Removed obsolete test and unused tests that tested gridProperties
* Refactor use of TableManager. Is now a reference.
* Added non-const GridProperties.getKeyword(size_t i)
* moved region-property from EclipseState to Eclipse3DProperties
* moved initGridopts from EclipseState to Eclipse3DProperties
* made several Eclipse3DProperties methods private
* removed obsolete tests
* replaced log with throw internally in private method---is domain_error
* removed typedef in SatFuncPropertyInitializers
* postprocessors take raw pointers, not shared_ptr---these will be phased out
* fixed return reference instead of copy several places
** gridProperties<T> in Eclipse3DProperties are now references, not shared_ptr
** Eclipse3DProperties takes const Deck&, not shared_ptr
** EclipseGrid and Section are references
* Removed all references to state, need to fix initPORV
* Made TransMult return raw pointer const GridProperty over shared pointer.
* Moved getDirectionProperty and hasDirectionProperty out of API
** Removed tests as these methods are no longer public
* Moved grid properties stuff to new class
* Removed use of deck in SatfuncInitializers, moved to TableManager
* Removed shared_ptr for several members of EclipseState and 3DProperties
* Moved region-property from EclipseState to Eclipse3DProperties
* Moved initGridopts from EclipseState to Eclipse3DProperties
* Made several Eclipse3DProperties methods private
* Postprocessors take raw pointers, not shared_ptr---these will be phased out
* Fixed return reference instead of copy several places
** GridProperties<T> in Eclipse3DProperties are now references, not shared_ptr
** Eclipse3DProperties takes const Deck&, not shared_ptr
* Removed obsolete tests
The const_cast in Deck::get*UnitSystem are potentially undefined
behaviour under a series of (plausible) conditions, and are deprecated
in favour of mutable members. Removes initUnitSystem from the public
interface, as the initialisation is handled on the first getUnitSystem
anyway, cleaning up the Deck interface slightly.
Adds proper constness to the use of unit systems that don't actually
modify the internal state in any way.
By storing it as size_t we explicitly disallow negative line numbers,
and keep 0 as an error/empty/undefined location.
A small problem with this is that MessageContainer.error and friends
still accept negative numbers (often without warning) via size_t
implicit conversion and wrap-around.
For more transactional behaviour and to support MessageContainer in
favour of opm-log, this method now returns an enum describing how the
error should be handled, rather than throwing or no-oping. Throwing is
preserved if ParseContext is configured to do so.
While the implementation is a simple alias to
std::vector<Message>::const_iterator, it enablese generic lookup of the
iterator type at compile time, and enables us to effortlessly change the
underlying implementation later.
Some phenomenons can be configured as error, warning or debug output,
and is not necessarily known in advanced by the entity adding a message.
To facilite adding a message with runtime-defined warning level, the add
method is supported.
By supporting operator bool() we get the same existence checking
capabilities as the unique_ptr implementations, without the hurdles of
non-copyability and manual heap allocation.
this fixes the problem that well totals are off by a factor of
two. Note that the better solution would be to continue to write once
per substep but skipping report step writes if the adaptive time
stepper is used. since I've got no idea how to find this out I propose
this patch.
The general loop through all raw records should be based on the iterator
interface of the RawKeyword, but to resolve INCLUDE statements we have
implemented a special case method to get the first record.
this enables to build opm-output using an unpatched `dunecontrol` from
Dune 2.3 (and Dune 2.4 if USE_CMAKE is set to "no").
In the medium term the build system needs to become compatible with
Dune's cmake based build system since I think I read somewhere that
the Dune devs intend to remove the autotools based build system before
their next release.
Have renamed the OpmLoadDeck test program to the working name opmi - Opm
Inspector. Currently the opmi executable will only load a deck and
create a EclipseState instance, but the plan is to extend this
executable to be a general Eclipse deck inspector, e.g.
opmi --wells CASE.DATA
Could the list the wells and so on.
Changes the implementation of numbers parsing from std::atoi/f to
std::strtod/l. These support setting the optional end-of-string pointer
which are used to determine if a parsing was successful or not. This has
the nice side effect of *greatly* simplifying the logic, at the expense
of some C-style details.
Tests added to verify that the different edge cases are handled
properly.
Since RawRecords now has automatic storage, managed by std::list,
offering iterators is feasible. The random access
RawKeyword::getRecord's real use was accessing the records in order,
which now is handled via iterators.
By changing the underlying storage of RawKeyword to std::list, we ensure
that the RawRecords aren't reallocated and moved, preserving the
validity of string_view's. This changes the access complexity of
RawRecord from O(1) to O(n).
Implement support for creating and instantiation smspec_nodes for the
C-family of keywords of the SUMMARY section. Covers all defaulting
mechanisms.
Due to poor map/concat/filter support, this was written in a more
traditional foreach-if-then-append style.
To reduce duplication, calculating a dimensions array from EclipseGrid
is its own function instead for a repeated body across multiple
(similar) functions.
The Summary object understands and stores some (simple) Region type
keywords. Does not support inter-region keywords, nor underscore or
custom regions.
These functions are called a lot and are trivial accessors to the
underlying containers. By opening them for inlining we get a decent
performance benefit "for free" via optimisation opportunities.
1. The build-opm-parser.sh script - which is used by downstream
modules, does not build the Python bindings.
2. The main travis script uses the build-shared script from opm-common.
The accumulated strings are moved into RawRecords, which reduces
execution time (rough measurements indicates 4-8%). To facilitate this,
RawRecords are stored directly in the vector in favour of via
shared_ptrs.
An attacker using very long decimal integers as input could trigger a
buffer overflow write during int/double parsing.
The vulnerability has been fixed and raw buffer boundaries are checked.
Additionally, integer buffer size is determined by platform 'int' width.
'double' uses a heuristic to support both pure decimal formats (up to 64
characters long) and float formats.
The underlying iterators were default constructed (aka uninitialised)
when a Deck was default constructed, meaning possible invocation of
undefined behaviour.
While the empty Deck typically is only used for testing, this is a
possible bug in production code. This small patch makes sure even
default constructed Decks are well defined.
The push_front() method can cause reallocation of expanded_items,
thereby invalidating iterators already stored in m_recordItems.
Switching to std::list fixes this.
The translation between ParserRecord knows in advance how many DeckItem
entries there are in the resulting DeckRecord. We can use this
information to efficiently preallocate memory in the DeckRecord.
boost::trim_right loses a lot of performance from being locale aware.
Since this is not a problem for our ASCII fortran-type files, ignore
this issue and use isspace for trimming.
readValueToken spent almost half its time dealing with weirdly formed or
broken floats. Now has a shorter path that can early return a
successfully parsed float and only do slow handling of cases that need
it (notably zero, fortran style exponent and errors).
This function was rather slow and accounted for too much execution time.
Replaced with a simple implementation relying on toupper. Locale
awareness, the benefit of to_upper_copy, is not an issue since it's all
ASCII.
Instead of going via an immediately discarded temporary, feed the
readValueToken result value directly to push_back. This enables rvalue
optimisations to kick in, when available.
The boost provided lexical cast are inefficient and is shown to be a
slowdown in the inner loop. Replaces them with std::atoi/std::atof and
some simple correctness checking.
Modifies RawRecord to internally use string_view instead of copies of
the substrings. This *vastly* reduces copying in the processing of each
record and subsequently improves performance. Reduces total memory usage
in Deck construction.
A simple non-mutating view into a string. Implements a shallow reference
to a std::string, replicating its operations to be drop-in replaceable.
Primarily designed for inner loop use, where expensive string
allocations become a performance killer.
Borrows macros and common infrastructure from the rest of the opm
project instead of half-implementing its own (as parser must do).
Largely a build system simplification.
The templated readValueToken has been moved to source file, and uses
explicit instantiation and linking. The deprecated float specialisation
has been removed.
The assumptions and interface for these two functions are distinct. Init
does not have to take a preallocated vector, but post processing
requires an input vector. Splits the two and changes their signatures.
Most users of the findVerticalPoints function didn't use more than one
of the vectors returned. By splitting them up into seperate functions,
we only have to compute what we'll use.
Most users of the findCritical function didn't use more than one of the
vectors returned. By splitting them up into seperate functions, we only
have to compute what we'll use.
Most users of the findSaturationEndpoints function didn't use more than
one of the four vectors returned. By splitting them up into seperate
functions, we only have to compute what we'll use.
Changes GridPropertyFunction's external interface to use references
rather than pointers. Means slightly less flexibility for tests, but
makes it clear what its dependencies are.
In an effort to make GridPropertyInitializer and
SatfuncPropertyInitializer functionality more maintainble, the
shared-ptr-to-base-class model has been replaced by a specialised
function object and free functions. This means:
* GridPropertyBaseInitializer and everything derived from it is gone
* All SatfuncPropertyInitializer code has been heavily rewritten to
emphasise dependencies. Now behaves like proper functions.
* EclipseState intialisation code is somewhat simpler
* Code is more declarative. In particular, some maybe unintended
behaviour has been discovered and described.
The new GridPropertyFunction processes grid cell property vectors and
replaces GridPropertyBase* inheritance model. This implementation
re-uses the old implementations as a transition.
GridProperty< T > has only two sensible types to parametrise, int and
double. Moves the implementation and instantiation of GridProperty to
GridProperty.cpp. This also applies to GridPropertyInitializers which
has also been moved to source files.
Results are a cleaner header file (for reading & understanding the
interface) and faster compilations.
Changes the type of the stored supported keywords from pointer-to-vector
to vector. This accomplishes the following:
* we avoid an unecessary level of indirection
* we enable initializer list syntax for tests etc.
* GridProperties' interface properly communicates that it takes over
ownership of the passed keywords.
* it feels more natural in use as generating and returning a vector in a
free function can be returned and directly passed to the constructor
(the motivation for this change).
Bundled with this is the move of the supported keyword population into
using loops to exploit the similarities of families of keywords w.r.t.
GridProperties representation.
Introduces Equil, a thin storage class for 'EQUIL' derived information,
accessible through EclipseState.
Previously this was handled through "raw" deck access, provided by
EquilWrapper. The interface for Equil has been derived from the
EquilWrapper, but they're to be seen as different entities altogether.
More importantly, Equil is owned by EclipseState, not some stand-alone
Deck reading unit.
Utility/Functional is a lightweight high level functional-oriented sub
library that attempts to abstract some common uses and boilerplate
around the parser code (and later maybe for other modules to use).
This patch introduce only three functions, but they have proven common
enough to warrant some common implementation.
ECLIPSE resolves path aliases defined in an included file globally, i.e.
/
|> include.inc
|-- PATHS 'alias' 'path/to/dir'
|> main.data
|-- INCLUDE 'include.inc' /
| [...]
|-- INCLUDE '$alias/file.inc' /
will resolve as 'path/to/dir/file.inc'. This behaviour is now adopted by
opm-parser.
Removes shared_ptr< ParserKeyword > exchange in Parser interface and
replaces it with unique_ptr storage and raw pointers for return values.
This has some implications:
* addParserKeyword() no longer takes shared_ptr<>, but unique_ptr&&
addParserKeyword has been modified to create unique_ptr instead of
shared_ptr.
* generated-source/ParserKeyword* no longer use make_shared which had a
-massive- impact on compile times, which are now more-or-less
trivialised (on my machine: 7.5s -> 1s per file). This because the
compiler no longer generates a bunch of forwarding make_shared
instances of subclasses that are immediately thrown away, but rather
uses an inline make_unique that instantiates the -parent- class
unique_ptr.
the intend is to better reflect that these properties where explicitly
created in the deck. The old method names can still be used, but they
will result in deprecation warnings.
I'm pretty sure that most users do not expect this. If that behaviour
was really intentional, one can add a
```
FOO
$NUM_CELLS*
```
line to the deck before the keyword which requires FOO to initialize
itself.
that's because they are not supposed to be modified outside of the
EclipseState. (if they are, why? I'd consider that *very* bad style
since it is also possible to copy these objects and modify the copy
and also this was used nowhere within the OPM project.)
also, the has*Property() is now working as expected: if e.g.,
```c++
bool hasSatnum = eclipseState->hasIntProperty("SATNUM");
eclipseState->getIntProperty("SATNUM");
assert(hasSatnum == eclipseState->hasIntProperty("SATNUM"));
```
will now work for decks which does not explicitly specify
SATNUM. (before the getIntProperty() method silently created the
SATNUM property which caused hasIntProperty() to change its
opinion. With this patch, the property will still be silently created,
but has*Property() ignores it, i.e., that method could be renamed to
hasExplicit*Property() which -- as far as I understand this -- was its
intention from start.)
Builds an internal representation, based on ERT's smspec_node, of the
SUMMARY section of an input file, that can be used to determine what
data from a simulation to output.
In essence, this is a simple map from DeckKeyword to smspec_node that
carries over the interesting data. Introduces two higher order functions
(map and concat) to aid in this, thoroughly isolating each case.
Depends on ert pull request #1013https://github.com/Ensembles/ert/pull/1013
The completely constructed Deck isn't supposed to have any relationship
with the Parser structures (which are completely stateless in terms of
input data), and ParserKeyword in DeckKeyword was an anomaly. With
recent refactorings this lead to subtle lifetime issues.
This patch breaks this dependency and cleans up DeckKeyword accordingly,
while changing checkDeck to now take the parser as an additional
argument, to look up whether or not some DeckKeyword is in the right
section. This now also means that Parser* objects can be destroyed once
the Deck is created.
The Section::checkSectionTopology has been moved to Parser.cpp. It is a
temporary home for the feature to make the project compile nicely (i.e.
createKeywordList can be compiled as before, without introducing a
circular dependency on itself via Parser.cpp), until some proper cleanup
of the parser code has been done. It never really fully belonged in
Section.cpp anyway, so this is a first step in the direction of some
slight renaming.
Since the Deck* family of classes have changed their interfaces to no
longer use shared_ptr, a lot of code broke. This patch fixes all
problems in tests, other signatures and accesses to now use the new Deck
interfaces.
The deck no longer exposes shared_ptrs, but uses automatically managed
memory, meaning ownership of DeckKeywords are now obvious and clear.
shared_ptr in the interface has been replaced by references.
This refactoring reflects the ownership semantics of Deck* classes -
Section and Section-derived classes no longer claim ownership over
partial decks, but rather provide a -view- into an already
established Deck.
The Deck class itself is now unique in the sense that it is the only
supporter of write operations, meaning a DeckView derived instance can
never modify the deck it's viewing.
DeckKeyword now internally uses a vector of records instead of a vector
of shared_ptr< DeckRecord >. Updates the interface to reflect this, by
returning references over shared_ptr. DeckKeyword is now the sole owner
of its own record resources.
Replaces shared_ptr use in DeckRecord with automatically allocated
DeckItem, as the DeckRecord itself owns and manages the lifetime of
DeckItems. To reflect this, methods and queries no longer return
shared_ptrs, but (const) references.
Using a virtual base class DeckItem that exposed DeckInt/Double/String
types means it cannot be held in a vector and managed automatically
without unique_ptr, which is clunky and makes iterator aliases
impossible. This patch moves the unique_ptr details into DeckItem which
now behaves as if it was virtual, except it only forwards calls to its
inner, managed object (much like private implementation).
This gives the benefit of automatic/stack allocation, and no particular
drawback aside from slightly less obvious implementation. Clients can
still call get< int > on a DeckItem::double, but that was also possible
with the virtual solution (i.e. nothing lost).
The Deck<*> classes are mostly straight-up copies of eachother, but with
a different type parameter. Re-implementation of this into common
template implementations with local specialisations where necessary.
Functionally the implementation is identical.
Similar to the already-existant Schedule::getWells, this simple method
returns (const) pointers to all groups, suitable for iteration, maps and
for-all-in operations.
Every header is self-contained and includes only what it must to
function, relying on users include what they need in source files,
adopting a pay-what-you-use model (in particular for internal
dependencies).
To reduce compiler stress and be more explicit w.r.t. dependencies, all
files now includes only the keywords they need, instead of the
collection of all files.
Most tables are trivial extensions of SimpleTable, but had their
implementation in headers. This required them to include more headers
than we want to expose and makes them harder to maintain and verify.
Instead, all these SimpleTable derivatives are now implemented in
Tables.cpp, only declaring their interfaces in their respective .hpp
files. Clients won't notice the difference.
rebase into tables
This is an effort to improve build performance. Several includes
scattered across the project are either unused or partially used (i.e.
just used to import a type name, not depending on the actual contents of
the header file).
Replaces a lot of these includes with forward declarations.
In order to reduce parsing load on clients, the generated ParserKeywords
now come in their own sorted-by-first-letter files, so that inclusion of
the entire tree is unnecessary when only a handful of keywords will do.
This also applies to the generated source code (which is pretty heavy to
compile), which now is split into multiple files to enable parallel
builds.
- Create a new shared library libcopmparser with small files cxxxx
which wrap general Cxx classes with C linkage.
- Added Python packages & modules, based on Python ctypes and the
ert.cwrap package.
limitations for now:
1. The input with a range is not supported yet.
2. More than one completion for a segment is not supported yet.
3. Calculating distance based on thickness of grid block is not supported yet.
4. Calculting completion depth based on COMPDAT is not supported yet.
which is for Fortran style memory management. Although it can also be
good for preventing people from giving too random branch numbers and
segment numbers.
In particular this warning is removed:
"In file included from /home/mblatt/src/dune/opm/opm-parser/opm/parser/eclipse/EclipseState/EclipseState.cpp:34:0:
/home/mblatt/src/dune/opm/opm-parser/opm/parser/eclipse/EclipseState/Grid/SatfuncPropertyInitializers.hpp:438:66: warning: type qualifiers ignored on function return type [-Wignored-qualifiers]
const SaturationFunctionFamily getSaturationFunctionFamily() const{"
^
This PR adds support for item 10 in welspecs where a flag is used to
determine whether the well should allow cross flow or not.
A test is added to check default behavior.
The PLYSHLOG table specification is based on alternating header and data
records, this is not supported by th parser - and the thing will throw
if more than table is specified.
The SimpleTable class is initialized with a DeckItem instance containing
all the date for the table, instead of a DeckRecord (or DeckKeyword). As
a consequence the getFlatXxxx() methods have been removed.
With the current implementation the THPRES pressure table is implemented
with a map indexed by the equilibration region indicies for the regions
in contact.
- Moves saturation function family check from EclipseState to
SatfuncPropertyInitializers
- Add tests in SatfuncPropertyInitializersTests
- Fixes error in the SatfuncPropertyInitializers implementation for
familyII
Now either family I (SWOF,SGOF) or family II (SWFN, SGFN and SOF3)
keywords can be specified.
Other keyword alternatives like SLGOF, SOF2 and SGWFN and the two
dimensional saturation tables are still not supported.
If SWOF and SGOF (family1) are specified in the deck the function
returns 1
If SWFN, SGFN and SOF3 (family2) are specified in the deck the function
return 2
If keywords are missing or mixed, an error is given.
Also change defaults for production rate properties to
-999e100, since 0 is an actual possible rate, and while
it would be possible to ask if a default was applied
(the default should be no rate or limit, not a zero rate),
unlike for wells there are no methods doing this currently.
Completely reimplemented the ParseMode class. Now the main datastructure
is a map<string,action> where the possible error situations are the
keys. This approach allows for a much more flexible
setting/filtering/querying of the ParseMode settings.
Done by using the disable_warnings.h and reenable_warnings.h headers.
In some cases also a little reordering of includes, to put all boost
includes in the warning-suppressed part.
Main change is in VFPPRod::getALQTYpe() where we use the
DeckItem::defaultApplied() method instead of comparing with the special
default value ' '. The other functions are changed just to be consistent.
During the work with ParseMode the the construction of the Schedule
object has been changed; previously the complete deck was iterated in
the method iterateSchedulesection() - whereas the correct is to only
iterate over the keywords in the Schedule section. This has led to a
minor fixup in the testdata for this commit.
There are probably more bugs in the IOConfig object - because there
RPTRST / RPTSCHED / keywords in the SOLUTION section have been taken
into account twice, both as part of the SOLUTION and then again
incorrectly as part of the SCHEDULE section.
Previously random text in the input deck which was not formatted as a
valid keyword header was simply ignored; i.e. this
DIMENS
10 10 10 /
Mohaha random gibbersih - not according to any Spec.
GRID
Would suprisingly parse just fine. This will now be handled according
to the ParseMode::randomText setting. Observe that as a side effect of
this it turned out that many of the test datasets had additional
terminating slashes which were now detected as 'ranomdText'.
- Introduce a very simple class ParseMode which will become a simple
value object which can be used to control the behavior when errors
and inconsistencies are encountered in the parse and EclipseState
construction phases.
- Added ParseMode instance as second argument to all parseXXX()
methods.
- The handleSolutionsection() method would initialize the timemap, but
not the storage vector.
- Renamed initRestartOutputConfig -> assertTimeMap and calling it
unconditionally.
i.e. first try to convert it normally and only if this fails, replace
'd' by 'e' and try again.
this is because the slowdown when always taking the second path was
about 7 to 9% for the Norne deck on my machine. (I think this is quite
surprising.)
thanks to [at]joakim-hove for the hint.
i.e., the PC[GW] and KR[OGW] properties plus their imbibition and
directional variants. the properties required for three-point vertical
scaling (i.e., KRWR, et al.) are still to be done.
i.e., it now throws if it is queried for an unsupported grid
properties. The main intention is to make code like
```c++
if (eclipseState->hasDoubleGridProperty("IHAVEATYPO"))
{
auto prop = eclipseState->getDoubleGridProperty("IHAVEATYPO"));
}
```
no longer run without raising and exception.
Have added a new bool strict flag to the parsing functions, if the
strict flag is set to false the parser will just skip lines with unknwon
keywords, including pure garbage in the input. I.e. for a deck like:
TABDIMS
1 1 1 /
Crap - not a keyword at all
-- Correctly formatted - unknown keyword
IGNORED
0 1 /
The parser will load the TABDIMS keyword correctly, and skip the rest.
1) use addNNC() method to store the NNCs
2) convert all int's to size_t
3) remove .reserve() from the loop
4) use m_xxx instead of xxx_
5) rename xyz1 to ijk1 etc.
This class provides the raw non-neighboring connections data as read
from the deck and/or added using the addNNC method.
The NNC data is currently not processed. I.e. multiple NNC connection
between the same cell can exist side by side.
With this commit the generation of built in keywords is completely
changed. The most important changes include:
1) We have autogenerated a class for each keyword in the new
ParserKeywords { ... } namespace.
2) The autogenerated classes derive from ParserKeyword, and the
default constructor will build of a fully initialized
ParserKeyword instance, i.e. the keyword used to parse the EQUIL
keyword can be instantiated as simple as:
ParserKeywords::EQUIL kw;
3) The generated keywords have built in static constants for keyword
and item names, and item default values. That way it should be
possible for the compiler to catch trivial errors like trying to
access the keyword "PoRO"; also the the access to default values
means that properties can be initialized without actually
insantiating a DeckKeyword.
4) Two new classes Generator/KeywordLoader and
Generator/KeywordGenerator have been created, with the help of
these classes the keyword generation code is significantly
simplified.
- use a opm-macro to reduce code duplication
- add a 'test-suite' target which builds tests. for use if BUILD_TESTING
is 0.
- add a 'check' target which builds tests, then executes them
Old code used to first initialize with 1, and then check the
EclipseState - will rather just ask the EclipseState; which will
automagically create a keyword if that is required.
Also The SATNUM keyword was previously immediately overwritten with the
content of the ENDNUM keyword, that is now changed.
- Removed the KeywordContainer class; and implemented the behaviour
directly in the Deck.
- Added begin() and end() iterators to the Deck.
- Section class inherits from Deck.
- The new LogUtil.cpp / LogUtil.hpp files contain the enum definitions
for MessageType and formatting functions.
- The Logger class is meant to be the instance which is held by the
static OpmLog singleton class.
This commit shows a very basic example of how Logging singleton can be
implemented. The commit consists of a fully static class OpmLog which
manages a Logger class; in this case an instance of the ParserLog
class. The static OpmLog class can then be used from anywhere in the opm
code with:
OpmLog::addMessage( messageType , "Log message")
Before this can be really useful the Logger class should be extended /
subclassed / ... for general usability.
The SAVE keyword should support both having one slash terminated record,
and no records at all. To be able to handle both of these forms we have
used size_type UNKNOWN.
the intention of it is to specify the component index which should be
used to calculate the properties of the gas and oil phase in the case of
thermal black-oil runs. The keywords are supposed to use Eclipse-style
indices, i.e., "1" is stands for the first component.
The reason why I think that this is required at all is that I have not
found out if Eclipse does use temperature dependent gas viscosities
and densities for non-compositional runs. (I have found a few
equations in the RM and TD for gas which include temperature for
compositional runs on E300, though.)
Note that there won't be a WCOMPIDX because compositional simulations
in Eclipse do not seem to treat water as a separate component...
if somebody has a better idea or knows how eclipse does this for
thermal black-oil simulations, let me know...
strangely enough, [at]totto82 an me did not find a corresponding
keyword for the gas phase. Also, the documentation of the second item
of the WATDENT keyword seems to be incorrect to me because its default
in FIELD units it is off by a factor of 10^4 compared to the one for
METRIC (at least in my copy of the RM).
This is required for keywords which do not use "every-day" temperature
values but thermodynamic ones or keywords that use "per degree"
values. Examples of such specimen are the OILCOMPR and WATDENT
keywords.
Withe this commit the ParserRecord objects are created as needed by the
ParserKeyword; i.e a parserkeyword can in principle be totally without a
record.
Also, I tried to convert all keywords that use reservoir volumes and
the associated code. Although I tried my best on that front, it might
not be enough. (in any case, I consider it very unlikely that there
are any regressions caused by this.)
it turns out that, in contrast to the RATE item, this item is always a
liquid rate (-> bbl/day in FIELD units), i.e., the dimension is always
"LiquidVolume/Time" irrespectibly of the fluid phase.
quite a few important methods (e.g., getWells()) missed the variants
which are marked as 'const'. this leads to the problem that these
can't be called on the object returned by EclipseState::getSchedule()
because it returns a ScheduleConstPtr. (this issue can possibly be
worked-around by creating a new mutable copy of the schedule object
from the one returned by EclipseState::getSchedule(), but to me, this
seems to be strikingly inelegant and inefficient...)
this fixes the compilation of the ECL blackoil simulator of eWoms...
For some keywords the number of records is given as the value of an item
in another keyword, for instance the number of records in the EQUIL
keyword is given by NTEQUL item in the EQLDIMS keyword.
If the EQLDIMS keyword is not given in the deck the Parser will consult
the default values of EQLDIMS keyword; i.e. a missing keyword is treated
as all-defaulted.
it turns out that the number of columns of this class depends on the
number of specified components. this lead to all kinds of fun like
manual unit conversion, etc.
this is required by the Norne deck. the EQLOPTS keyword seems weird,
though, because its records seem to have a variable number of items...
for most of these the RM says that if nothing is specified, a value of
another item should be used. some items even have legitimate
defaults, but they are only mentioned in the prose of the RM's item
description. (e.g.the wetting_phase_flag item of the EHYSTR keyword...)
The getKeyword() method will autocreate and initialize a keyword if you
ask for one which is supported, but has not yet been accessed. The new
getInitializedkeyword() method will raise an exception if the keyword
has not already been initialized.
... but throw later when trying to access the data of the item in
question.
Note that this was demanded by [at] joakim-hove and that I do not want
to be held responsible for any issues which are caused by this
approach. (read: please direct your barks to Joakim if you fell on
your nose because of this...)
for many of them the RM says "default is undefined" but that I've come
to the conclusion that this doesn't mean that no default could be
applied, but that the simulator is allowed to screw up if the values
of them are accessed. (Note that in this sense this change is no
change from the current situation, but makes the screw-up more
explicit.)
In particular, note the GRIDUNIT keyword which had some serious JSON
syntax errors in it but so far the unit tests worked anyway for some
reason...
this can be used to directly specify transmissibilities for
NNCs. Note that this keyword is quite a mess for everything after
the mandatory items according to the documentation.
this is required because Eclipse is inconsistent when specifying
transmissiblities: the only difference between transmissibilities in
metric and field units is that the pressures are in bars instead of
PSI, i.e. the numerator for metric units is still given in centi-Poise
times bbl. This makes it impossible to specify the transmissibilities
in terms of their constituting bits...
mostly, include the keyword names, so that the user can fix these
errors without using gdb. (Not that I mind gdb, but I have been told
that gdb is a big no-no. ;)
(this patch also fixes a few typos...)
The region multipliers are no longer added to the cartesian logical
MULT[XYZ] structure. Instead a new method
getRegionMultiplier(globalIndex1, globalIndex2,FaceDir) is added that
return the multiplier between globalIndex1 cell and globalIndex2 cell.
The face direction is added to support directional dependent MULTREGT
input. This implementation of MULTREGT also supports restricting the
multipliers to only apply for NNC or NONNNC.
This one could only be enable by modifying the source code. If such
debugging output is needed, it should be directly added via std::cout
and removed it before proposing the PR...
note that comment handling is currently a bit too simplistic as stuff
like
FOO
'-- hello' /
won't work. as far as I can see, this is not different from the state
before this patch, though.
this is just the result of
```
find -iname "*.[ch]pp" | xargs sed -i "s/ *$//"
find opm/parser/share/keywords -type f | xargs sed -i "s/ *$//"
```
so if it causes conflicts with other patches, the others should get
priority. The rationale behind this patch is that some people tell
their editor to remove white space which leads to larger than
necessary patches...
E100 does not know about TEMPI, but it is wise not to use the
geothermal gradient directly, but to go over the "temperature at
cell-center" detour as specified by the E300 TEMPI keyword. The depth
vs. temperature table is given by the RTEMPVD keyword. The intend is
that if TEMPI stays unspecified the temperature is calculated at each
cell center and the result is put into TEMPI from where it gets picked
up by the simulator.
(Note that E300 says that TEMPVD is an alias for RTEMPVD even though
the possible sections of these two do not exhibit any overlap, WTF?)
this requires the possibility of specifying an offset for the SI
conversion because Eclipse in its eternal wisdom chooses to specify
temperatures using degrees Celsius and degrees Fahrenheit instead of
using Kelvin an Rankine...
i see no reason to keep the separate library and this circumvents
shared vs static linking issues.
an alternative fix is to fix the opm buildsystems to prioritize config
mode. that would be more involved.
- probe only for system lib (i.e. only probe in prefix paths)
old code ended up not installing the json lib due to finding a copy
in the build folder if a reconfiguration was performed.
- build internal copy static and bundle in libopm-json.so
no reason to install this as a shared library. if it is updated
originating from opm, the entire parser library is updated anyways.
my emacs always asks me whether I want to apply these settings as it
consideres them unsafe. Furthermore, I use a different directory
structure, so these settings are useless to harmful for me.
If you want to keep these settings around, please move them to ~/.emacs
This commit contains quite large changes to the EclipseGrid. The main
functional change is that the access to the ecl_grid_type pointer is
protected. In addition there are 'white space' changes due to methods
moving around and some methods have been marked static.
In many cases the only required information in an EclipseGrid instance
is the cartesian dimensions. To facilitate simpler testing - and not
have to create a full dummy grid the dimensions have been internalized
as a separate nx,ny,nz triplet. With this commit it is possible to
instantiate a grid with only dimensions, and no underlying ecl_grid_type
pointer.
i.e., make keywords ALL_UPPERCASE before using them because Eclipse
seems to be case-insensitive (although this is one of its undocumented
features...)
The Norne deck actually exhibits this atrocity in form of the
'fluxnum' keyword in the file 'INCLUDE/PETRO/FLUXNUM_0704.prop'.
I don't know if Eclipse cares about the case of the keywords, but
opm-parser currently does for sure. (If Eclipse turns out to be
case-insensitive, the easiest fix for us is to just make all keywords
ALL_UPPERCASE...)
there is still the public variant of Parser::parseStream() which
parses an arbitrary std::istream. the name of the state-taking variant
was just confusing, IMO...
- the AllMessageTypes is not part of the MessageType enum anymore
- the getMessageType() now returns a MessageType enum instead of an integer.
- the clear() and append() methods have been added.
in this context, the line number of the parser state object is the
location where the keyword is finished, while it is much more useful
to get the line where the keyword starts...
which is more what the method does because the keyword can still
contain an error in its data which would make it non-parseable.
While at it, split the method into a "get keyword name from input
line" and "is a valid keyword name" part. (this will be needed later.)
This allows to arbitrary characters like stars into strings. e.g.
MYKEYWORD
'123*456' 2*'Hello, World! (*)' /
is now a valid record with three strings while it threw an exception
before.
This patch works by transferring the removal of the quotes from the
RawDeck class to the readValueToken<T>() function which now has a
specialization for strings that deals with quotes. One small
complication is that the RawDeck needs to be adapted in order not to
split tokens in the middle of strings.
Finally, the StarToken class does not deal with the conversion from
string to the value type of the item anymore which allows it to become
a normal class instead of a template...
seems like some compilers don't overwrite an inline method of a
template class with its specialization. A compiler warning would have
been nice to have in this case, though...
this fixes a really ugly and hard to find bug if EclipseState was
instanced multiple times: The EclipseState object passed to some of
these structures was destroyed, but the arrays stayed even if the next
EclipseState object was at a different location and also could use a
completely different grid...
this seems to be a compiler bug, but it could be something
else. Anyway, using multiple functions for the tests instead of nested
scopes is probably not the worst idea anyway...
The documentation of this keyword is quite well hidden in the "Other
SUMMARY keywords" section of the Eclipse reference manual, but the
keyword itself seems to be widely used...
the problem was the ALL keyword which caused a naming conflict with
Opm::ParserItemSizeEnum::ALL. I haven't considered the possibility to
break the build by adding a keyword, so sorry for the breakage.
On a more philosophical ground I think it is a bit questionable to
auto-generate test cases at build time because they will automatically
match the keyword definition, whether this definition makes sense or
not...
Previously the control mode was initialized to ORAT; this was later set
to the correct value when parsing the relevant keywords - but in the
case of a SHUT well the control mode was not updated, and we were left
with a well under ORAT control.
For the petrophysical properties PERM? and PORO only the top layer must
be specified, cells further down can be copied from the layer
above. This functionality is implemented with a GridProperty
postprocessor.
If no ParserLog object is provided, stdout is used by default. The
stream can also be used to write to a logfile or it can be omitted
entirely. thanks to [at] joakim-hove for insisting on it...
this basically comes down to adding a few flag keywords but also
requires to add a few E300 fields to TABDIMS...
the grid cannot be instantiated yet as these deck seem to use some
peculiar constructs to specify the grid data. In particular it uses
property modifiers for keywords that specify the grid. (which might be
not allowed by Eclipse but work anyway...) the deck contains something
like
```
GRID
EQUALS
DX 50.0 /
DY 50.0 /
DZ 50.0 /
/
```
which Opm::EclipseGrid can't handle yet because grid properties are only
evaluated after the grid has been instantiated...
unsurprisingly, it's called ParserLog. For now, it is not used very
extensively, but it allows to demingle the log messages from the deck
objects. (i.e., it's possible to pass a const pointer to the deck
object to e.g. EclipseState and one will still get additional log
messages.)
this is useful because DeckKeywords can have almost arbitrary names
(which match a regular expression) which makes it hard to retrieve
additional information about the keyword after it has been created...
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...
it is _strongly_ encuraged to use the properly named methods to access
the respective columns, but opm-core's current endpoint scaling code
makes it hard to use these...
for some kinds of tables this means linear interpolation for some
columns, constant for other columns and some tables do not allow to
specify default. Since there is no clear rule, this patch involved
checking the reference manual for every single f****** table keyword
plus some guess-work if the reference manual is unclear about
monotonicity and/or defaults.
... and constant interpolation at the fringes. this kind of evaluation
in between sampling point only makes sense for tables where the first
column is strictly monotonic, though.
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..
these are not really documented, but they are used by the file
./INCLUDE/SUMMARY/extra.inc of the Norne deck. I don't know why this
did not bite anyone so far, probably people just commented out the
INCLUDE statement of this file...
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 the first of several large commits changing several aspects of
the handling of defaults. The overall main purpose of these changes is
to protect against using non sensible values in the case the values have
not been sensibly specified in the deck. The changes in this commit
include:
1. The "default default" values to be used when an item without an
explicit default are defaulted are removed completely.
2. If a ParserItem is queried for a default value when no default has
been assigned it will raise an exception.
We now have an enum which can keep track of three possible states for
the data in a deck item:
VALID : A valid value has been set
DEFAULT : The default value has been applied
NOT_SET : The value has not been set.
The intention is to throw if/when a DeckItem with status == NOT_SET is
accessed.
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...
It seems like some optimization passes of CLang which are enabled by
-O2 (at least in my version, 3.3) do not like nested scopes and long
functions too much. Thus, slightly change the generated source. Timing
on my (quite beefy) machine:
without patch:
make
rm -rf generated-source; time make
time make
[...]
real 10m31.110s
user 10m16.264s
sys 0m13.672s
with patch:
make
rm -rf generated-source; time make
time make
[...]
real 0m47.011s
user 0m44.670s
sys 0m1.968s
the memory used by the compiler goes from 28.8GB to about 330 MB. (I
suppose not everybody has 32 Gigs of memory yet. ;)
these includes are required by the headers. If the affected files
would have been included without the headers included before, a
compiler error would have been produced.
for this, an Section::isDeckValid() method is introduced which checks
that a given deck is valid when it comes to the sections
(i.e. presence of mandatory sections and section ordering)
We now do not require the sections to be correctly ordered and the
presence of the mandatory sections since even the unit tests did not
always specify all mandatory sections, which lead to a section
containing the rest of the deck if one of the expected next sections
was not specified.
also it seems like the DeckKeyword::getDeckIndex() does not correctly
work in some situations which lead
assert(deck->getKeyword(i)->name() == startKeyword);
to fail in the Section::populateKeywords() method. now the deck is
always sequentially traversed to find the position of a section's
start keyword. (This is necessary anyway if one wants to make sure
that the deck does not specify the same section more than once, a
feature which this patch also adds.)
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).
for me, setting only CMAKE_CXX_FLAGS did not do the trick when I was
trying to compile everyting with libstdc++'s debug mode enabled. (it
caused linker errors because opm-parser was not linked against
std::debug in this case.) Maybe I got something wrong, though...
this comes with a minor API change as well, as the FaultCollection
class did not use the Cartesian size of the grid at all, so I decided
to remove the attributes and the arguments to the constructor...
this is required to make the opm-core build succeed if ERT was build
with -DBUILD_SHARED_LIBS=OFF . (without it, I get errors like
/home/and/src/ert/devel/libert_util/src/thread_pool_posix.c:328: error: undefined reference to 'pthread_create'
it returns a const reference to a vector which does not allow
manipulation of its members. the getData() can thus be safely called
on constant GridProperty objects.
i.e. MULT[XYZ]- was trimmed to MULT[XYZ]. Also, the RawKeyword now
uses ParserKeyword::isValidDeckName() instead of a regular expression
which makes it automatically consistent and also should make it
slightly faster...
If a well is available for group control, we should add that control
mode to its Injection or ProductionProperties before assigning a new
current (active) control mode to the well ('.controlMode').
Suggested by: [at] joakim-hove.
This commit splits the creation of WellProductionProperties objects,
and especially the ad-hoc helper functions historyProperties()
and predictionProperties() out to a separate module,
WellProductionProperties.[hc]pp. Creating the properties object
from a DeckRecordConstPtr is deferred to two named constructors,
WellProductionProperties::history() and
WellProductionProperties::prediction()
that, respectively, assume the roles of historyProperties() and
predictionProperties(). Reimplement handleWCONProducer() in terms
of these named constructors and remove the producerProperties()
helper whose task, inspecting the status and retrieving/setting the
CMODE if not SHUT, can be assumed by handleWCONProducer().
Add a simple test module, WellPropertiesTest.cpp, to enforce the
rather peculiar semantics of the WCONHIST keyword. Control modes
{O,W,G}RAT, LRAT, and RESV are *always* (unconditionally) supported
in WCONHIST but there is no control mode switching. The latter is
deferred to client code, depending on the '.predictionMode' flag.
Suggested by: [at] joakim-hove
This fixes a programming error introduced in the refactoring of
Schedule::handleWCONProducer() (commit 3889e92). When there is a BHP
limit in WCONHIST, we obviously need the value specified in the input
deck. The refactoring led to the limit being extracted only in the
prediction mode.
Pointy hat: [at] bska
Keyword WCONHIST always supports GRAT control mode, even when
defaulted. The default value (zero) might not be very useful in a
simulation case but it's supported nonetheless.
This commit splits Schedule::handleWCONProducer() into those parts
that are specific to the individual keywords (WCONHIST/matching and
WCONPROD/prediction) and those that are common to both.
In particular we introduce two new helper functions
matchingProperties() and predictionProperties()
of which the first constructs a WellProductionProperties object
specific to matching semantics and the latter constructs a similar
object specifc to prediction. In the case of WCONHIST, the well
always supports component rates at surface conditions ({O,W,G}RAT)
as well as liquid rate (LRAT) and (total) reservoir volume rate
(RESV). The prediction mode keeps the existing semantics of not
supporting control modes for which the values have been defaulted.
The final helper, function producerProperties(), dispatches to
matchingProperties() or predictionProperties() depending on
handleWCONProducer()'s 'isPredictionMode' flag and handles the
record properties that are common to both WCONHIST and WCONPROD,
including whether or not to assign a new active control mode.
The end result is that handleWCONProducer() becomes a loop of
keyword data records that
1) Determines the wells affected by a given record
2) Determines whether or not the wells are OPEN
3) Computes control mode properties (producerProperties())
4) Assigns status and those properties to all affected wells
This approach reorders the well loop compared to the previous
implementation which computed separate WellProductionProperties for
each well.
it turns out that boost::regex does not work for the libstdc++ debug
mode. This patch should fix this for sufficiently new compilers.
Note that this requires the FindCXX11Features.cmake tests pulled in
from opm-core and an additional compiler flag...
Parser::hasKeyword() was called with deckNames but looked up the map
for internal names. This patch renames the method to hasDeckName(),
renames Parser::getKeyword() to Parser::getKeywordFromDeckName() and
adapts/extends the tests.
the RE used is specified via the "deck_name_regex" in the JSON file of
the respective keyword. A deck name is assumed to match a given parser
internal keyword if the deck name is valid and if it is either in the
list specified by the "deck_names" entry or if it matches the regular
expression.
This functionality is useful to implement the well probes for the
tracers as well as replacing the current "wild card keyword"
implementation which only allows a star as a suffix.
this is required for regex-matching keywords. Once GCC 4.9 is the
minimum compiler version to be supported, this can be dropped in favor
of std::regex ...
Whoever came up with that keyword deserves a spanking because its
semantics are adapting thickness of the grid layers using the rock
properties without modifying the grid (and thus the output is not
showing what is actually used). As I understood that whole affair,
this is also done incorrectly, because the flow is not distorted in
depth direction but this the permeability should be divided by the NTG
values as the fluids seep through the thinner layers more quickly...
Anyway, we have to implement it, so here we go.
before this, the variants with the trailing minus were just silently
ignored, and even if they were not, the code generator would have
produced illegal code, because the keyword name is used for a C++
variable there, i.e. the names needed to be valid names in the C++
sense. "Happily", these the former bug canceled the latter, so the
build went through...
now, there is only one internal keyword called "MULT_XYZ" which
matches on all possible variants which are allowed in a deck. The
mechanism used is a deck name list...
These are all keywords which are used by the Norne deck within some
property modifiers plus all variants of these. (sans the variants for
radial grids which are completely pointless IMO.) The chances that
keywords which have not been added yet can also be used are very close
to 100%, though.
Note that the default values for these keywords are currently
incorrect as the Eclipse RM states that the values must be looked up
in their corresponding table if the keyword is left unspecified (see
e.g. the documentation SWU). This probably means that we need to
implement "ghosty" keywords which magically appear if they have not
been explicitly specified or maybe we should only provide them in
EclipseState to be able to do the context dependent table look-up
"vodoo"...
this uses a small amount of template magic, to automatically change
the API of the GridProperty class depending on wheter it is
instantiated for double or for int.
there was a "typename" outside of a template, but because the
syntactic sugar is created by the Boost unit testing framework, it was
not clear wheter it was a template or not.
Also, some harmless warnings have been fixed. These only appeared
because a few variables have recently been converted from int to
size_t...
This commit introduces support for the SOIL (initial oil saturation)
keyword. This is similar to existing keywords 'SWAT' and 'SGAS' and
needed to input some decks.
this has the potential to reduce the memory requirements of the parser
for opm-benchmarks considerably and is quite easy to add since
internally all parsing happend on istreams anyway...
The parser integration test has been extended to test the new method
as well as `parseString()` which was omitted previously. (I wonder who
introduced this without changing the test. ;)
Improved performance by checking for wildcard before entering the loop. Logic slightly changed since method now only supports wildcards at the end of the string.
It turns out that the empty-record detection worked fine, but that the
last empty record of a keyword is ignored by opm-parser for reasons
which are not clear to me...
Now all unit tests pass.
In the current version, the runTimeMapTest binary was run because of a
copy-and-pasto. oops.
Also, not all of the tests pass but that is because of another problem
of opm-parser for which I don't know a good fix: It currently seems to
be impossible to specify empty records if there are non-defaulted
items in the JSON keyword specification, but such empty records are
used as table separators by Eclipse...
that's because the Eclipse capillary pressure definitions
inconsistent: SWOF specifies the "water-oil capillary pressure" as $p_o
- p_w$, while SGOF uses $p_g - p_o$ as the "oil-gas capillary pressure".
For SimpleTable, that is simply the number of records in a keyword, for
MultiRecordTables, it is the number of _empty_ records.
this patch makes supporting multi-PVT easier and cleaner.
this was just a copy of PVTW and is quite embarassing. We should
prevent this in the future by making sure that the filename
corresponds to the JSON name when generating the C++ keyword list...
- fix typo: use "POLYMER" instead of "PLOYMER"
- according to the Eclipse RM, the size of the table is given by the
"NTMISC" item of the "MISCIBLE" keyword...
The purpose of this flag is to keep track of whether a keyword is
supposed to have only one element, i.e. scalar, or several. The
defaultApplied method only makes sense in the case of scalar items, this
method will now throw if it is called on a non-scalar item.
this is used in opm-core but I doubt that these code paths have
actually been tested recently because the parser would have thrown up
as soon as it had encountered PVCDO...
This entails:
- Adding a new data member of type Opm::Phase::PhaseEnum.
- Adding method getPreferredPhase().
- Adding extra constructor argument.
- Modifying constructor call in Schedule::addWell().
- Adding unit test for the new preferredPhase property.
- Modifying constructor call in all the well unit tests.
for SPE-9 only the well/group names contain spurious white space, but
I suppose that other decks also feature them in control modes, status,
etc. so it's probably a good idea to trim these as well...
which is like getString() but with the leading and trailing white
space removed. It is intended for names which seem to not care about
such white space in Eclipse.
for some reason, the Norne deck included whitespace for some control
modes of some wells which lead to an exception. Since Eclipse seems to
eat this, and Eclipse is correct by defintion, let's adapt our
digestion system a bit...
While reformatting the parser-prereqs file I accidentally replaced
the feature search 'CXX11Features' with 'CXX10Features'. This
commit fixes that blunder.
The benchmark library uses Boost::iostreams to do decompression. Since
we only scan for the Boost dependency once, this submodule is added to
all of the projects in order to have a coherent dependency on Boost.
This commit makes a few adjustments to the white-space of file
'opm-parser-prereqs.cmake' to honour the conventions of the other
*-prereqs.cmake files within the OPM project's module suites.
No functional changes.
basically, we now can access the beginning of a timestep its length
and the total time passed since the beginning of life, the universe
and all the rest.
this is necessary because boost::gregorian::date does not have a
notion of "time during a day" which is required to specify time step
lengths less than a day...
the wrapper could be a bit more sophisticated and do the conversion
internally, but the new wells management code seems to ignore the
wrapper anyway, so there is no real point in investing time into that
(yet).
this is meant for those nasty keywords where the dimension of an entry
depends on a user-defined value of some field of a (potentially
different) keyword. One example for this are the surface rates of the
produced fluids for the .CON(INJ|PROD).* keywords which exhibit
different units depending on whether the user choses to control for
the surface gas or the liquid rate.
the approach taken in this patch is to convert all numbers to NaN if
the unit is queried in SI (via item->getSIDouble()). It might be more
desireable to throw an exception in this case, but this approach would
be more elaborate and NaNs should be quickly noticeable by the users
of this code.
I tried to adapt all implemented keywords, but it's quite likely that
I missed some...
This field is specific to the Eclipse 300 geomechanics module. IMHO,
either all fields for the eclipse 300 geomechanics module should be
added or none. Adapting the table code to "partially defined" keywords
is a pain I'd rather avoid!
Instead of guessing the suffix or subdir of the build directory,
we now simply compare PROJECT_{BINARY,SOURCE]_DIR to detect it.
By this e.g. opm-core/opm-parallel is a possible build directory, too.
this one is a bit more complicated than a plain SimpleTable as the
number of columns depends on the deck. (to be precise, it depends on
the presence of the RKTRMDIR keyword which is also added in this
patch.)
This resulted in _quadratic_ complexity if data points where retrieved
one-by-one. For the Norne case, this had the consequence that
retrieving the data for ZCORN (-> about 1M data points) took hours...
now the data is parsed from a string specified in the source file
instead of a separate file, the PvtgTable utility class is tested and
the order of the fields in the JSON definition of PVTG is the same as
for that of PVTO.
detecting empty records is still pretty hacky: When calculating the
number of flat items, we stop at the first item for which the default
was applied.
Also, this patch corrects the names of the columes used by the PVTG
keyword. (the first column is pressure, then comes Rv.)
these are convenient to convert everything required to rip out the old
parser of sim_fibo_ad. the concrete keywords are:
- COMPDAT
- EQUIL
- GCONINJE
- GCONPROD
- GRUPTREE
- WCONINJE
- WCONINJ
- WCONPROD
- WELOPEN
- WELSPECS
- WGRUPCON
in the medium term it would be nice if these wrapper classes could be
automatically generated from the JSON keyword descriptions.
the motivation for this is the 'TSTEP' eclipse keyword.
the reason why this dimension is not simply called 'Time' is that in
eclipse, different keywords might use different units, e.g. one
keyword could use seconds, another could use years while a third uses
days. As an added bonus, the used time units may be different for
different scales but identical in others (e.g., for one keyword times
might be specified in 'days' for the metric as well as for the
labscale, but in 'days' and 'hours' for another second keyword.)
as it was decided that having editor-specific stuff in files is not
wanted in OPM. for emacs, a .dir-locals.el file is added to the
module's root directory which should have the same effect.
the idea is to create a lightweight wrapper objects around
DeckKeywords which allow more convenient and more readable access to
the data. E.g. instead of
std::vector outerColumnNames{"RV", "P", "BG", "MUG"};
std::vector innerColumnNames{"P", "BG", "MUG"};
Opm::FullTable pvtgTable(deck->getKeyword("PVTG"),
outerColumnNames, innerColumnNames);
pvtgTable->getOuterTable()->getColumn(1);
one now better uses
Opm::PvtgTable pvtgTable(deck->getKeyword("PVTG"));
pvtgTable->getOuterTable()->getPressureColumn();
the idea for the other keywords is similar.
This is intended for keywords like SWOF which currently is a big
vector of doubles but one needs to use the data in a column oriented
way.
This class is intended to be used like this:
Opm::DeckKeywordConstPtr swofKeyword = newParserDeck->getKeyword("SWOF");
Opm::SimpleTable swofTable(swofKeyword,
/*columns=*/std::vector<std::string>{"SW", "KRW", "KROW", "PCOW"},
/*recordIdx=*/table_num);
const std::vector<double>& sw = swofTable.getColumn(0);
// ...
what might be useful is to move the column names into the JSON
description of the keywords, but I could not find a way to go back to
the parser from the deck/keyword. maybe this is not even desireable as
decks might also be created by other means...
Also, a multi-record variant of the class is available. That one is
intended for keywords like PVTO where the first few items of each
record form a table (in the case of PVTO: Rs, pressure, Bo, and
viscosity for staturated oil) and the next entries constitute another
table (in the case of PVTO: pressure, Bo and viscosity for
undersaturated oil with the same RS factor as the first entry).
The second kind of tables can be constructed using the item-based
variant of SimpleTable.
Parser::parseData is quite useful for unit tests to prevent them
spilling files to everything. Also, what was formerly
Parser::parseFile has been renamed to Parser::parseStream and slightly
modified to not be specific for std::ifstream.
also, correct the dimension of the Rv item of the PVDG keyword which
is 1/Rs. Finally, the conversion factor for stock tank barrels to m^3
was off by a factor of 1000. (I suppose that liters instead of m^3
were assumed to be the SI unit in this case.)
the fact that data is lazily converted to SI units should not be
relevant for the caller. This requires to decorate the array for SI
units in the DoubleItem as mutable, though...
If opm-parser_ROOT is given, this should point to a build tree. The
only way to extract the corresponding source directory is to parse
the build cache located there.
Although CMake prefers the uppercase variant variables, and the
find_package_handle_standard_args will convert to them for us, the
part that parses REQUIRED and QUIET arguments to find_package still
only uses the package name verbatim (sic).
equals(ParserIntItem&) has a different signature than equals(ParserItem&),
thus the former method does *not* overload the latter. Virtual just means
then only means that you have created a *new* entry in the v-table. If
you call equals through a pointer/reference to the base class ParserItem,
the defined method in the derived class is not called, and we miss out the
test for the equal default value.
Instead, we should take an argument of the base type and use a dynamic
cast to the derived type. If this downcast fails, then they are not equal;
otherwise we have gotten ourselves a pointer to get the properly typed
default value.
We must use pointers instead of references; if we cast to a reference,
a bad_cast exception is thrown if the expression is not in the proper
type hierarchy.
It doesn't really matter here because "cjson" is only letters, but as
a general rule we define the uppercase variant ourselves so that CMake
doesn't use its own (bizarre) case rules, and then set the lower case
explicitly afterwards.
CMake will do some uppercasing of its own (defining OPM-PARSER_FOUND)
so it works best if we specify the correct uppercase version and sets
the lowercase afterwards.
The CMake script is run in the source tree. We assume a certain
directory layout and that the cjson is available in a sibling
directory of this project. Thus, we can pick up a build tree without
having the library installed.
The library will end up in the opm/json library in a build tree; we
want to be able to point the CJSON_ROOT variable to the root of the
build tree and have it pick up the libraries from there.
Surprisingly, some compilers (notably GCC 4.6.3) will issue a warning
when comparing a literal which is clearly positive to an unsigned type,
when looking for a suitable instantiation in Boost. This is fixed by
making the literal unsigned too, so there's no doubt.
for some of these files this is needed to make to keep it compiling
after the next patch because the new ErrorMacros.hpp file will no
longer implicitly includes <iostream>. for the remaining files it is
just good style.
While at it, the includes for most of these files have been ordered in
order of decreasing abstraction level.
Although they don't use Boost::UnitTest, they can at least pass, so we
can use them to detect simple compilation and runtime errors, although
we miss the semantic check.
(If you have time, please make them proper unit tests)
The <have_boost_redef.hpp> header was introduced (commit 82369f9) as
a work-around for a particular interaction in the Autotools-based
setup of OPM-Core and the Dune core modules. Notably, Dune's
"Enable" trick for Boost failed on some older Autoconf systems. Now
that we're using CMake, however, that kluge is no longer needed
because we (OPM-Core) always
#define HAVE_BOOST 1
i.e., as an explict true/false value.
Therefore, we need no longer include <have_boost_redef.hpp> . The
header will be removed at a later time.
The <have_boost_redef.hpp> header was introduced (commit 82369f9) as
a work-around for a particular interaction in the Autotools-based
setup of OPM-Core and the Dune core modules. Notably, Dune's
"Enable" trick for Boost failed on some older Autoconf systems. Now
that we're using CMake, however, that kluge is no longer needed
because we (OPM-Core) always
#define HAVE_BOOST 1
i.e., as an explict true/false value.
Therefore, we need no longer include <have_boost_redef.hpp> . The
header will be removed at a later time.
Removed the policy control for what to do beyond the domain.
Old behaviour was constant extrapolation, current behaviour
is linear extrapolation. The possibility to choose was never
needed and has beem removed.
The functions of linInt.hpp are now used everywhere, but:
- linInt.hpp -> linearInterpolation.hpp (better name)
- linearInterpolationExtrap() -> linearInterpolation() (extrapolate by default)
Every program that relies on manual inspection has been moved to a new
(hopefully short-lived) directory called not-unit/; every remaining
file has been given the prefix test_ to indicate that this is the
executable test to be run.
Recall that the class that used to be called SinglePvtDead has
been renamed to SinglePvtDeadSpline. If 'props_use_spline' is true,
that class is used (this is the default), which makes a monotone
spline that is uniformly, densely sampled. The new class simply
uses linear interpolation in the input tables.
We have switched to WarnAndContinueOnError instead of ThrowOnError,
to reduce the annoyance factor when suffering from a minor error in
a long simulation run.
symbol 'MATLAB_MEX_FILE' that is automatically defined by MATLAB's
MEX function.
Add declarations for factorisation, lin-sys solution, and matrix
inversion for (symmetric) positive definite full matrices in full
and packed formats. Will be used in the coarse-system assembly
process.
Current status
--------------
Given vectors ZCORN, COORD and ACTNUM as well as the Cartesian
dimensions these vectors implicitly refer to, the code is
currently capable of
* Identify unique points along each pillar
* Assign point numbers for each point specified in ZCORN
* Compute face topology, i.e., the corners that define the geometry
of the faces as well as the cells that are connected through the face.
* Identify and compute intesections that occur in the processing of
face topology.
What remains is
* Handle the face geometry of boundary faces. (simple)
* Compute point coordinates of the final point list.
* Put all pieces together in a tidy manner.
2009-06-11 07:33:50 +00:00
1050 changed files with 106055 additions and 2826 deletions
# print the version number we detected in the configuration log
message(STATUS"Version ${_major}.${_minor}.${_revision} of ${suite}-${module} from ${_dune_mod}")
if(${suite}-${module}_FOUND)
# print the version number we detected in the configuration log
message(STATUS"Version ${${suite}-${module}_VERSION_MAJOR}.${${suite}-${module}_VERSION_MINOR}.${${suite}-${module}_VERSION_PATCH} of ${suite}-${module} from ${${suite}-${module}_DIR}")
This file is part of the Open Porous Media project (OPM).
OPM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OPM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OPM. If not, see <http://www.gnu.org/licenses/>.
*/
#include<opm/test_util/EclFilesComparator.hpp>
#include<opm/common/ErrorMacros.hpp>
#include<ert/util/util.h>
#include<ert/util/stringlist.h>
#include<ert/ecl/ecl_endian_flip.h>
#include<ert/ecl/ecl_file.h>
#include<iostream>
#include<string>
#include<getopt.h>
staticvoidprintHelp(){
std::cout<<"\ncompareECL compares ECLIPSE files (restart (.RST), unified restart (.UNRST), initial (.INIT) or .RFT) and gridsizes (from .EGRID or .GRID file) from two simulations.\n"
<<"The program takes four arguments:\n\n"
<<"1. Case number 1 (full path without extension)\n"
<<"2. Case number 2 (full path without extension)\n"
<<"3. Absolute tolerance\n"
<<"4. Relative tolerance (between 0 and 1)\n\n"
<<"In addition, the program takes these options (which must be given before the arguments):\n\n"
<<"-h Print help and exit.\n"
<<"-i Execute integration test (regression test is default).\n"
<<" The integration test compares SGAS, SWAT and PRESSURE in unified restart files, so this option can not be used in combination with -t.\n"
<<"-I Same as -i, but throws an exception when the number of keywords in the two cases differ. Can not be used in combination with -t.\n"
<<"-k Specify specific keyword to compare (capitalized), for example -k PRESSURE.\n"
<<"-l Only do comparison for the last occurrence. This option is only for the regression test, and can therefore not be used in combination with -i or -I.\n"
<<"-n Do not throw on errors.\n"
<<"-p Print keywords in both cases and exit. Can not be used in combination with -P.\n"
<<"-P Print common and uncommon keywords in both cases and exit. Can not be used in combination with -p.\n"
<<"-t Specify ECLIPSE filetype to compare (unified restart is default). Can not be used in combination with -i or -I. Different possible arguments are:\n"
<<" -t UNRST \t Compare two unified restart files (.UNRST). This the default value, so it is the same as not passing option -t.\n"
<<" -t INIT \t Compare two initial files (.INIT).\n"
<<" -t RFT \t Compare two RFT files (.RFT).\n"
<<" -t RST \t Compare two cases consisting of restart files (.Xnnnn).\n"
<<" -t RST1 \t Compare two cases where the first case consists of restart files (.Xnnnn), and the second case consists of a unified restart file (.UNRST).\n"
<<" -t RST2 \t Compare two cases where the first case consists of a unified restart file (.UNRST), and the second case consists of restart files (.Xnnnn).\n"
<<" Note that when dealing with restart files (.Xnnnn), the program concatenates all of them into one unified restart file, which is used for comparison and stored in the same directory as the restart files.\n"
<<" This will overwrite any existing unified restart file in that directory.\n\n"
<<"Example usage of the program: \n\n"
<<"compareECL -k PRESSURE <path to first casefile> <path to second casefile> 1e-3 1e-5\n"
<<"compareECL -t INIT -k PORO <path to first casefile> <path to second casefile> 1e-3 1e-5\n"
<<"compareECL -i <path to first casefile> <path to second casefile> 0.01 1e-6\n\n"
<<"Exceptions are thrown (and hence program exits) when deviations are larger than the specified "
<<"tolerances, or when the number of cells does not match -- either in the grid file or for a "
<<"specific keyword. Information about the keyword, keyword occurrence (zero based) and cell "
<<"coordinate is printed when an exception is thrown. For more information about how the cases "
<<"are compared, see the documentation of the EclFilesComparator class.\n\n";
std::cout<<"\n\nThe program can handle both unified and non-unified summary files."<<std::endl;
std::cout<<"In the case of non-unified summary files all the files must be located in the same directory. Only the basename (full path without extension) is needed as input."<<std::endl<<std::endl;
std::cout<<"\nThe program takes four arguments"<<std::endl;
std::cout<<"1) <path to file1>/<base_name>, basename without extension"<<std::endl;
std::cout<<"2) <path to file2>/<base_name>, basename without extension"<<std::endl;
std::cout<<"3) absolute tolerance"<<std::endl;
std::cout<<"4) relative tolerance (between 0 and 1)"<<std::endl;
std::cout<<"The program will only throw an exception when both the absolute and relative tolerance are exceeded."<<std::endl;
std::cout<<"The program is capable of performing both a regression test and an integration test, \nhowever only one type of test at a time. ";
std::cout<<"By default the program will run a regression test."<<std::endl;
std::cout<<"\nThe program have command line options:"<<std::endl;
std::cout<<"-h \t\tPrint help message."<<std::endl<<std::endl;
std::cout<<"For the regression test: "<<std::endl;
std::cout<<"-r \t\tChoosing regression test (this is default)."<<std::endl;
std::cout<<"-k keyword \tSpecify a specific keyword to compare, for example - k WOPR:PRODU1."<<std::endl;
std::cout<<"-p \t\tWill print the keywords of the files."<<std::endl;
std::cout<<"-R \t\tWill allow comparison between a restarted simulation and a normal simulation. The files must end at the same time."<<std::endl<<std::endl;
std::cout<<"For the integration test:"<<std::endl;
std::cout<<"-d \t\tThe program will not throw an exception when the volume error ratio exceeds the limit."<<std::endl;
std::cout<<"-g \t\tWill print the vector with the greatest error ratio."<<std::endl;
std::cout<<"-k keyword \tSpecify a specific keyword to compare, for example - k WOPR:PRODU1."<<std::endl;
std::cout<<"-K \t\tWill not allow different amount of keywords in the two files. Throws an exception if the amount are different."<<std::endl;
std::cout<<"-m mainVar \tWill calculate the error ratio for one main variable. Valid input is WOPR, WWPR, WGPR or WBHP."<<std::endl;
std::cout<<"-n \tDo not throw on errors."<<std::endl;
std::cout<<"-p \t\tWill print the keywords of the files."<<std::endl;
std::cout<<"-P keyword \tWill print the summary vectors of a specified kewyord, for example -P WOPR:B-3H."<<std::endl;
std::cout<<"-s int \t\tSets the number of spikes that are allowed for each keyword, for example: -s 5."<<std::endl;
std::cout<<"-v \t\tFor the rate keywords WOPR, WGPR, WWPR and WBHP. Calculates the error volume of \n\t\tthe two summary files. This is printed to screen."<<std::endl;
std::cout<<"-V keyword \tWill calculate the error rate for a specific keyword."<<std::endl<<std::endl;
std::cout<<"Suggested combination of command line options:"<<std::endl;
std::cout<<" -i -g -m mainVariable, will print the vector which have the greatest error ratio of the main variable of interest.\n"<<std::endl;
/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
externconstchar*cJSON_GetErrorPtr(void);
/* These calls create a cJSON item of the appropriate type. */
externcJSON*cJSON_CreateNull(void);
externcJSON*cJSON_CreateTrue(void);
externcJSON*cJSON_CreateFalse(void);
externcJSON*cJSON_CreateBool(intb);
externcJSON*cJSON_CreateNumber(doublenum);
externcJSON*cJSON_CreateString(constchar*string);
externcJSON*cJSON_CreateArray(void);
externcJSON*cJSON_CreateObject(void);
/* These utilities create an Array of count items. */
/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
/// \param nzindex an index counting only nonzero elements.
/// \return the nzindex'th nonzero element.
constT&nonzeroElement(intnzindex)const
{
#ifndef NDEBUG
OPM_ERROR_IF(nzindex<0,"The index of a SparseVector must be non-negative (is "<<nzindex<<")");
OPM_ERROR_IF(nzindex>=nonzeroSize(),"The index of a SparseVector must be smaller than the maximum value (is "<<nzindex<<", max value: "<<nonzeroSize()<<")");
#endif
returndata_[nzindex];
}
/// O(1) index access.
/// \param nzindex an index counting only nonzero elements.
/// \return the index of the nzindex'th nonzero element.
intnonzeroIndex(intnzindex)const
{
assert(nzindex>=0);
assert(nzindex<nonzeroSize());
returnindices_[nzindex];
}
private:
// The vectors data_ and indices_ are always the same size.
// The indices are supposed to be stored in increasing order,
// to be unique, and to be in [0, size_ - 1].
// default_elem_ is returned when a default element is requested.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.