The writer will need to know which cells are the active cells after
post-processing (because these are the cells there is stored results
for in the pressure and saturation arrays), and thus not only the
raw input grid (to get the COORD and ZCORN arrays which is not easily
detainable from the UnstructuredGrid), *and* the UnstructuredGrid
needs to be available.
I originally wanted to make share_obj a class so that I could hide the
helper function, but it turned out that I needed a function after all
since a function template can be inferred from the parameters but the
type cannot from the constructor.
By returning a shared_ptr directly, the compiler can do return object
optimization.
The template function share_obj let you pass regular references
as shared pointers, which makes it easy (perhaps too easy) to quick-
fix old code which pass references and have stern warnings about the
lifetime rules of the objects in the documentation section instead.
This wrapper class aggregate all the result objects (state, timer
etc.) and register itself for notification with the simulator. At
every timestep the simulator should provide a notification. The
wrapper will receive this and pass all the state objects to the
writer(s) which creates a new timestep.
Currently this doesn't work out-of-the-box because only the
two-phase simulator sends notifications and the writer only
understand the state of blackoil simulators, but these two concepts
should be unified.
If an interface requires a shared_ptr, but we have an object that is
known to outlive the client anyway, we can use a custom deleter to
suppress the delete part and pass this object around anyway.
The code is now allowed to use C++11, where shared_ptr is available
in the standard. To specify that the parser object must be present
for the output writer in its entire lifetime, we require to be passed
a shared_ptr. (This can be faked for local storage anyway).
Due to a glitch the order of the names was put incorrectly in the file,
even though the comment stressed that it was important it was right!
Hat tip: @bska
The return type of the path methods has changed in newer version of
Boost; by wrapping them with a new path object we can get a string
in a way that is compatible for both version 2 and 3.
Hat tip: @bska
Using an interface allows us to code the simulator to just pass the
necessary state variables to something which implements this, and
then the user can select the actual output format with configuration
values. This allows us to set new formats without having to change
the code being compiled (for instance, we can have a special debug
"format" which prints out things of interest in each timestep)
By getting a pointer directly into the data store, the copy can be
performed faster than calling a function for every item. Also, the
storage type of the array should now match the C++ one exactly (i.e.
no conversion to float).
C++11 will write a default move constructor that invoke the same in
the base class. However, GCC 4.4 doesn't support this, so we have to
explicitly give the implementation that would be generated on later
compilers.
If we put them in the anonymous namespace, then we cannot have a
reference to the types in the header (because that would mean different
things in each compilation unit).
The only thing it was needed for was the number of cells in the grid,
and the Cartesian dimensions, and those are already available from other
structures.
ecl_grid_alloc_GRDECL_kw takes zcorn first, then coord (slightly
unintuitive if you ask me), and this is also the order that is used
in EclipseGrid::make; thus, the order should be consistent through
the constructor also.
If we restart from a later time, then the SimulatorTimer should be
restarted in that state as well, so it is already always a reflection
of how far we've progressed in the input file's schedule.
The EclipseKeyword class takes care of cleaning up the handle after we
are done using it, and provides several convenience constructors that
make the code read easier.