diff --git a/opm/output/eclipse/EclipseIO.hpp b/opm/output/eclipse/EclipseIO.hpp index 409b0cac3..a92131dde 100644 --- a/opm/output/eclipse/EclipseIO.hpp +++ b/opm/output/eclipse/EclipseIO.hpp @@ -53,19 +53,54 @@ public: - /// Write the static eclipse data (grid, PVT curves, etc) to disk, and set - /// up additional initial properties - /// - /// - simProps contains a list of properties which must be - /// calculated by the simulator, e.g. the transmissibility - /// vectors TRANX, TRANY and TRANZ. - /// - /// - The NNC argument is distributed between the EGRID and INIT - /// files. - /// - /// If you want FOE in the SUMMARY section, you must pass the initial - /// oil-in-place "OIP" key in Solution - void writeInitial( data::Solution = data::Solution(), const NNC& = NNC()); +/** \brief Output static properties in EGRID and INIT file. + * + * Write the static eclipse data (grid, PVT curves, etc) to disk, + * and set up additional initial properties. There are no specific + * keywords to configure the output to the INIT files, it seems + * like the algorithm is: "All available keywords are written to + * INIT file". For the current code the algorithm is as such: + * + * + * 1. 3D properties which can be simply calculated in the output + * layer are unconditionally written to disk, that currently + * includes the DX, DY, DZ and DEPTH keyword. + * + * 2. All integer propeerties from the deck are written + * unconditionally, that typically includes the MULTNUM, PVTNUM, + * SATNUM and so on. Observe that the keywords PVTNUM, SATNUM, + * EQLNUM and FIPNUM are autocreated in the output layer, so + * they will be on disk even if they are not explicitly included + * in the deck. + * + * 3. The PORV keyword will *always* be present in the INIT file, + * and that keyword will have nx*ny*nz elements; all other 3D + * properties will only have nactive elements. + * + * 4. For floating point 3D keywords from the deck - like PORO and + * PERMX there is a *hardcoded* list in the writeINIFile( ) + * implementation of which keywords to output - if they are + * available. + * + * 5. The container simProps contains additional 3D floating point + * properties which have been calculated by the simulator, this + * typically includes the transmissibilities TRANX, TRANY and + * TRANZ but could in principle be anye floating point + * property. + * + * If you want the FOE keyword in the summary output the + * simProps container must contain the initial OIP field. + * + * In addition: + * + * - The NNC argument is distributed between the EGRID and INIT + * files. + * + * - PVT curves are written unconditionally, saturation functions + * are not yet written to disk. + */ + + void writeInitial( data::Solution simProps = data::Solution(), const NNC& nnc = NNC()); /*! * \brief Write a reservoir state and summary information to disk. diff --git a/src/opm/output/eclipse/EclipseIO.cpp b/src/opm/output/eclipse/EclipseIO.cpp index a8a2d09c7..803f40bf9 100644 --- a/src/opm/output/eclipse/EclipseIO.cpp +++ b/src/opm/output/eclipse/EclipseIO.cpp @@ -261,19 +261,32 @@ void EclipseIO::Impl::writeINITFile( const data::Solution& simProps, const NNC& // Write properties from the input deck. { - const auto& properties = this->es.get3DProperties(); + const auto& properties = this->es.get3DProperties().getDoubleProperties(); using double_kw = std::pair; + /* + This is a rather arbitrary hardcoded list of 3D keywords + which are written to the INIT file, if they are in the + current EclipseState. + */ std::vector doubleKeywords = {{"PORO" , UnitSystem::measure::identity }, {"PERMX" , UnitSystem::measure::permeability }, {"PERMY" , UnitSystem::measure::permeability }, - {"PERMZ" , UnitSystem::measure::permeability }}; + {"PERMZ" , UnitSystem::measure::permeability }, + {"NTG" , UnitSystem::measure::identity }}; + + // The INIT file should always contain the NTG property, we + // therefor invoke the auto create functionality to ensure + // that "NTG" is included in the properties container. + properties.assertKeyword("NTG"); for (const auto& kw_pair : doubleKeywords) { - const auto& opm_property = properties.getDoubleGridProperty(kw_pair.first); - auto ecl_data = opm_property.compressedCopy( this->grid ); + if (properties.hasKeyword( kw_pair.first)) { + const auto& opm_property = properties.getKeyword(kw_pair.first); + auto ecl_data = opm_property.compressedCopy( this->grid ); - units.from_si( kw_pair.second, ecl_data ); - writeKeyword( fortio, kw_pair.first, ecl_data ); + units.from_si( kw_pair.second, ecl_data ); + writeKeyword( fortio, kw_pair.first, ecl_data ); + } } } @@ -304,10 +317,10 @@ void EclipseIO::Impl::writeINITFile( const data::Solution& simProps, const NNC& // keywords, we therefor call getKeyword() here to invoke the // autocreation property, and ensure that the keywords exist // in the properties container. - properties.getKeyword("PVTNUM"); - properties.getKeyword("SATNUM"); - properties.getKeyword("EQLNUM"); - properties.getKeyword("FIPNUM"); + properties.assertKeyword("PVTNUM"); + properties.assertKeyword("SATNUM"); + properties.assertKeyword("EQLNUM"); + properties.assertKeyword("FIPNUM"); for (const auto& property : properties) { auto ecl_data = property.compressedCopy( this->grid ); diff --git a/tests/test_EclipseIO.cpp b/tests/test_EclipseIO.cpp index 7f01996c3..97a04b84d 100644 --- a/tests/test_EclipseIO.cpp +++ b/tests/test_EclipseIO.cpp @@ -172,6 +172,11 @@ void checkInitFile( const Deck& deck, const data::Solution& simProps) { } } + /* + These keyword should always be in the INIT file, irrespective of + whether they appear in the inut deck or not. + */ + BOOST_CHECK( ecl_file_has_kw( initFile.get() , "NTG" )); BOOST_CHECK( ecl_file_has_kw( initFile.get() , "FIPNUM" )); BOOST_CHECK( ecl_file_has_kw( initFile.get() , "SATNUM" ));