From b28527c0ec0a235913f377374df840ac3f602bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Mon, 14 May 2018 11:30:51 +0200 Subject: [PATCH] Update after review. In particular: - correct path for test deck, - use unit system to convert output correctly, - handle and warn for the case where we do not have an explicit connection transmissibility factor from the deck. --- opm/output/eclipse/WriteRestartHelpers.hpp | 4 +- .../output/eclipse/WellDataSerializers.cpp | 40 +++++++++++++++---- tests/test_serialize_SCON.cpp | 20 ++++++---- 3 files changed, 48 insertions(+), 16 deletions(-) diff --git a/opm/output/eclipse/WriteRestartHelpers.hpp b/opm/output/eclipse/WriteRestartHelpers.hpp index f67209abd..1bd6fac5a 100755 --- a/opm/output/eclipse/WriteRestartHelpers.hpp +++ b/opm/output/eclipse/WriteRestartHelpers.hpp @@ -35,6 +35,7 @@ namespace Opm { class EclipseState; class Schedule; class Well; + class UnitSystem; } // Opm @@ -70,7 +71,8 @@ namespace Opm { namespace RestartIO { namespace Helpers { std::vector serialize_SCON(int lookup_step, // The integer index used to look up dynamic properties, e.g. the number of well. int ncwmax, // Max number of completions per well, should be entry 17 from createInteHead. int nsconz, // Number of elements per completion in SCON, should be entry 33 from createInteHead. - const std::vector& sched_wells); + const std::vector& sched_wells, + const UnitSystem& units); }}} // Opm::RestartIO::Helpers diff --git a/src/opm/output/eclipse/WellDataSerializers.cpp b/src/opm/output/eclipse/WellDataSerializers.cpp index 01ab26810..1e397d263 100644 --- a/src/opm/output/eclipse/WellDataSerializers.cpp +++ b/src/opm/output/eclipse/WellDataSerializers.cpp @@ -17,9 +17,10 @@ along with OPM. If not, see . */ +#include #include // containts ICON_XXX_INDEX #include -#include +#include #include // ---------------------------------------------------------------------------- @@ -28,7 +29,8 @@ Opm::RestartIO::Helpers:: serialize_SCON(int lookup_step, int ncwmax, int nsconz, - const std::vector& sched_wells) + const std::vector& sched_wells, + const UnitSystem& units) // ---------------------------------------------------------------------------- { const size_t well_field_size = ncwmax * nsconz; @@ -37,16 +39,38 @@ serialize_SCON(int lookup_step, for (const Opm::Well* well : sched_wells) { const auto& completions = well->getCompletions( lookup_step ); size_t completion_offset = 0; + bool explicit_ctf_not_found = false; for (const auto& completion : completions) { - const size_t offset = well_offset + completion_offset; - - data[ offset + SCON_CF_INDEX ] = - completion.getConnectionTransmissibilityFactor(); - data[ offset + SCON_KH_INDEX ] = UNIMPLEMENTED_VALUE; - + const auto& ctf = completion.getConnectionTransmissibilityFactorAsValueObject(); + if (ctf.hasValue()) { + // CTF explicitly set in deck, overrides calculation + // from Peaceman model. We should also give the Kh + // factor, we output an explicitly invalid value + // instead. This is acceptable since it will not be + // used (the explicit CTF factor is used instead). + const double ctf_SI = ctf.getValue(); + const double ctf_output = units.from_si(UnitSystem::measure::transmissibility, ctf_SI); + data[ offset + SCON_CF_INDEX ] = ctf_output; + data[ offset + SCON_KH_INDEX ] = UNIMPLEMENTED_VALUE; + } else { + // CTF not set in deck, Peaceman formula used to + // compute it. Here we should store the data for the + // connection required to recalculate the CTF (the Kh + // factor), as well as the actual CTF used by the + // simulator, but that requires access to more data + // from the simulator. As an interim measure we write + // invalid values and give a warning. + data[ offset + SCON_CF_INDEX ] = UNIMPLEMENTED_VALUE; + data[ offset + SCON_KH_INDEX ] = UNIMPLEMENTED_VALUE; + explicit_ctf_not_found = true; + } completion_offset += nsconz; } + if (explicit_ctf_not_found) { + OpmLog::warning("restart output completion data missing", + "Explicit connection transmissibility factors for well " + well->name() + " missing, writing dummy values to restart file."); + } well_offset += well_field_size; } return data; diff --git a/tests/test_serialize_SCON.cpp b/tests/test_serialize_SCON.cpp index e6c602606..1bf8789a1 100644 --- a/tests/test_serialize_SCON.cpp +++ b/tests/test_serialize_SCON.cpp @@ -27,14 +27,15 @@ #include // containts SCON_CF_INDEX #include -BOOST_AUTO_TEST_CASE( serialize_icon_test ) +BOOST_AUTO_TEST_CASE( serialize_scon_test ) { - const Opm::Deck deck(Opm::Parser{}.parseFile("tests/FIRST_SIM.DATA")); + const Opm::Deck deck(Opm::Parser{}.parseFile("FIRST_SIM.DATA")); + Opm::UnitSystem units(Opm::UnitSystem::UnitType::UNIT_TYPE_METRIC); // Unit system used in deck FIRST_SIM.DATA. const Opm::EclipseState state(deck); const Opm::Schedule schedule(deck, state); const Opm::TimeMap timemap(deck); - + for (size_t tstep = 0; tstep != timemap.numTimesteps(); ++tstep) { const size_t ncwmax = schedule.getMaxNumCompletionsForWells(tstep); @@ -46,7 +47,8 @@ BOOST_AUTO_TEST_CASE( serialize_icon_test ) Opm::RestartIO::Helpers::serialize_SCON(tstep, ncwmax, SCONZ, - wells); + wells, + units); size_t w_offset = 0; for (const auto w : wells) { @@ -54,11 +56,15 @@ BOOST_AUTO_TEST_CASE( serialize_icon_test ) for (const auto c : w->getCompletions(tstep)) { const size_t offset = w_offset + c_offset; - + const auto ctf = c.getConnectionTransmissibilityFactorAsValueObject(); + const double expected = + ctf.hasValue() + ? units.from_si(Opm::UnitSystem::measure::transmissibility, ctf.getValue()) + : Opm::RestartIO::Helpers::UNIMPLEMENTED_VALUE; BOOST_CHECK_EQUAL(scondata[offset + SCON_CF_INDEX], - c.getConnectionTransmissibilityFactor()); + expected); BOOST_CHECK_EQUAL(scondata[offset + SCON_KH_INDEX], - Opm::RestartIO::Helpers::UNIMPLEMENTED_VALUE); + Opm::RestartIO::Helpers::UNIMPLEMENTED_VALUE); c_offset += SCONZ; }