From 6b781152290df53b883946c1cc6338d2ba91d85d Mon Sep 17 00:00:00 2001 From: Odd Andersen Date: Mon, 7 May 2018 15:37:39 +0200 Subject: [PATCH 1/2] Added new implementation of serialize_ICON The new function has been added to the file WriteRestartHelpers, and intended to take over for the local function 'serialize_ICON' in `restartIO.cpp` when `restartIO::save()` is to be updated. The purpose of the new implementation is to be compatible with Eclipse. --- CMakeLists_files.cmake | 2 + opm/output/eclipse/WriteRestartHelpers.hpp | 6 ++ .../output/eclipse/WellDataSerializers.cpp | 61 ++++++++++++ tests/test_serialize_ICON.cpp | 99 +++++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 src/opm/output/eclipse/WellDataSerializers.cpp create mode 100644 tests/test_serialize_ICON.cpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 038f8bd86..b8f70844c 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -139,6 +139,7 @@ if(ENABLE_ECL_OUTPUT) src/opm/output/eclipse/CreateDoubHead.cpp src/opm/output/eclipse/CreateInteHead.cpp src/opm/output/eclipse/CreateLogiHead.cpp + src/opm/output/eclipse/WellDataSerializers.cpp src/opm/output/eclipse/DoubHEAD.cpp src/opm/output/eclipse/EclipseGridInspector.cpp src/opm/output/eclipse/EclipseIO.cpp @@ -241,6 +242,7 @@ if(ENABLE_ECL_OUTPUT) tests/test_Tables.cpp tests/test_Wells.cpp tests/test_writenumwells.cpp + tests/test_serialize_ICON.cpp ) endif() diff --git a/opm/output/eclipse/WriteRestartHelpers.hpp b/opm/output/eclipse/WriteRestartHelpers.hpp index c26b1bcd6..feb2dcb02 100755 --- a/opm/output/eclipse/WriteRestartHelpers.hpp +++ b/opm/output/eclipse/WriteRestartHelpers.hpp @@ -29,6 +29,7 @@ namespace Opm { class EclipseGrid; class EclipseState; class Schedule; + class Well; } // Opm @@ -54,6 +55,11 @@ namespace Opm { namespace RestartIO { namespace Helpers { std::vector createLogiHead(const EclipseState& es); + std::vector serialize_ICON(int report_step, + int ncwmax, + int niconz, // should be entry 32 from createInteHead + const std::vector& sched_wells); + }}} // Opm::RestartIO::Helpers #endif // OPM_WRITE_RESTART_HELPERS_HPP diff --git a/src/opm/output/eclipse/WellDataSerializers.cpp b/src/opm/output/eclipse/WellDataSerializers.cpp new file mode 100644 index 000000000..3c6a3558f --- /dev/null +++ b/src/opm/output/eclipse/WellDataSerializers.cpp @@ -0,0 +1,61 @@ +/* + Copyright (c) 2018 Statoil ASA + + 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 . +*/ + +#include // containts ICON_XXX_INDEX +#include +#include +#include + +// ---------------------------------------------------------------------------- +std::vector +Opm::RestartIO::Helpers:: +serialize_ICON(int report_step, + int ncwmax, + int niconz, + const std::vector& sched_wells) +// ---------------------------------------------------------------------------- +{ + const size_t well_field_size = ncwmax * niconz; + std::vector data(sched_wells.size() * well_field_size, 0); + size_t well_offset = 0; + for (const Opm::Well* well : sched_wells) { + const auto& completions = well->getCompletions( report_step ); + size_t completion_offset = 0; + for (const auto& completion : completions) { + const size_t offset = well_offset + completion_offset; + + data[ offset + ICON_IC_INDEX ] = completion.complnum(); + data[ offset + ICON_I_INDEX ] = completion.getI() + 1; + data[ offset + ICON_J_INDEX ] = completion.getJ() + 1; + data[ offset + ICON_K_INDEX ] = completion.getK() + 1; + data[ offset + ICON_DIRECTION_INDEX ] = completion.getDirection(); + data[ offset + ICON_STATUS_INDEX ] = + (completion.getState() == WellCompletion::StateEnum::OPEN) ? + 1 : -1000; + data[ offset + ICON_SEGMENT_INDEX ] = + completion.attachedToSegment() ? + completion.getSegmentNumber() : 0; + completion_offset += niconz; + } + + well_offset += well_field_size; + } + + return data; +} diff --git a/tests/test_serialize_ICON.cpp b/tests/test_serialize_ICON.cpp new file mode 100644 index 000000000..435805ef1 --- /dev/null +++ b/tests/test_serialize_ICON.cpp @@ -0,0 +1,99 @@ +/* + Copyright 2016 Statoil ASA. + + 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 . +*/ + +#include + +#include // @@ +#include // @@ +#include // @@ + +#define BOOST_TEST_MODULE serialize_ICON_TEST +#include + +#include +#include +#include // containts ICON_XXX_INDEX +#include + +BOOST_AUTO_TEST_CASE( serialize_icon_test ) +{ + const Opm::Deck deck(Opm::Parser{}.parseFile("tests/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); + + const int ICONZ = 25; // normally obtained from InteHead + const auto wells = schedule.getWells(tstep); + + const std::vector icondata = + Opm::RestartIO::Helpers::serialize_ICON(tstep, + ncwmax, + ICONZ, + wells); + size_t w_offset = 0; + for (const auto w : wells) { + + size_t c_offset = 0; + for (const auto c : w->getCompletions(tstep)) { + + const size_t offset = w_offset + c_offset; + + BOOST_CHECK_EQUAL(icondata[offset + ICON_IC_INDEX], + c.complnum()); + BOOST_CHECK_EQUAL(icondata[offset + ICON_I_INDEX], + c.getI() + 1); + BOOST_CHECK_EQUAL(icondata[offset + ICON_J_INDEX], + c.getJ() + 1); + BOOST_CHECK_EQUAL(icondata[offset + ICON_K_INDEX], + c.getK() + 1); + BOOST_CHECK_EQUAL(icondata[offset + ICON_DIRECTION_INDEX], + c.getDirection()); + + if (c.getState() == Opm::WellCompletion::StateEnum::OPEN) + BOOST_CHECK_EQUAL(icondata[offset + ICON_STATUS_INDEX], + 1); + else + BOOST_CHECK_EQUAL(icondata[offset + ICON_STATUS_INDEX], + -1000); + + if (c.attachedToSegment()) + BOOST_CHECK_EQUAL(icondata[offset + ICON_SEGMENT_INDEX], + c.getSegmentNumber()); + else + BOOST_CHECK_EQUAL(icondata[offset + ICON_SEGMENT_INDEX], + 0); + + c_offset += ICONZ; + } + w_offset += (ICONZ * ncwmax); + } + + std::copy(icondata.begin(), + icondata.end(), + std::ostream_iterator(std::cout, " ")); + std::cout << std::endl; + BOOST_CHECK_EQUAL(1, 1);// @@@ + } +}; + From 49edd1e54dab88ab9b01ec6e82fa48c0401f88a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Atgeirr=20Fl=C3=B8=20Rasmussen?= Date: Sun, 13 May 2018 22:35:36 +0200 Subject: [PATCH 2/2] Minor fixes from review. In particular: - replace tabs -> spaces, - use the term "lookup_step", - document interface better, - use correct path (no path...) for test deck. --- CMakeLists_files.cmake | 4 ++-- opm/output/eclipse/WriteRestartHelpers.hpp | 6 +++--- src/opm/output/eclipse/WellDataSerializers.cpp | 4 ++-- tests/test_serialize_ICON.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index b8f70844c..80000307f 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -139,7 +139,7 @@ if(ENABLE_ECL_OUTPUT) src/opm/output/eclipse/CreateDoubHead.cpp src/opm/output/eclipse/CreateInteHead.cpp src/opm/output/eclipse/CreateLogiHead.cpp - src/opm/output/eclipse/WellDataSerializers.cpp + src/opm/output/eclipse/WellDataSerializers.cpp src/opm/output/eclipse/DoubHEAD.cpp src/opm/output/eclipse/EclipseGridInspector.cpp src/opm/output/eclipse/EclipseIO.cpp @@ -242,7 +242,7 @@ if(ENABLE_ECL_OUTPUT) tests/test_Tables.cpp tests/test_Wells.cpp tests/test_writenumwells.cpp - tests/test_serialize_ICON.cpp + tests/test_serialize_ICON.cpp ) endif() diff --git a/opm/output/eclipse/WriteRestartHelpers.hpp b/opm/output/eclipse/WriteRestartHelpers.hpp index feb2dcb02..dc96615dc 100755 --- a/opm/output/eclipse/WriteRestartHelpers.hpp +++ b/opm/output/eclipse/WriteRestartHelpers.hpp @@ -55,9 +55,9 @@ namespace Opm { namespace RestartIO { namespace Helpers { std::vector createLogiHead(const EclipseState& es); - std::vector serialize_ICON(int report_step, - int ncwmax, - int niconz, // should be entry 32 from createInteHead + std::vector serialize_ICON(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 niconz, // Number of elements per completion in ICON, should be entry 32 from createInteHead. const std::vector& sched_wells); }}} // Opm::RestartIO::Helpers diff --git a/src/opm/output/eclipse/WellDataSerializers.cpp b/src/opm/output/eclipse/WellDataSerializers.cpp index 3c6a3558f..cf0f070ad 100644 --- a/src/opm/output/eclipse/WellDataSerializers.cpp +++ b/src/opm/output/eclipse/WellDataSerializers.cpp @@ -25,7 +25,7 @@ // ---------------------------------------------------------------------------- std::vector Opm::RestartIO::Helpers:: -serialize_ICON(int report_step, +serialize_ICON(int lookup_step, int ncwmax, int niconz, const std::vector& sched_wells) @@ -35,7 +35,7 @@ serialize_ICON(int report_step, std::vector data(sched_wells.size() * well_field_size, 0); size_t well_offset = 0; for (const Opm::Well* well : sched_wells) { - const auto& completions = well->getCompletions( report_step ); + const auto& completions = well->getCompletions( lookup_step ); size_t completion_offset = 0; for (const auto& completion : completions) { const size_t offset = well_offset + completion_offset; diff --git a/tests/test_serialize_ICON.cpp b/tests/test_serialize_ICON.cpp index 435805ef1..a654fb863 100644 --- a/tests/test_serialize_ICON.cpp +++ b/tests/test_serialize_ICON.cpp @@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE( serialize_icon_test ) { - const Opm::Deck deck(Opm::Parser{}.parseFile("tests/FIRST_SIM.DATA")); + const Opm::Deck deck(Opm::Parser{}.parseFile("FIRST_SIM.DATA")); const Opm::EclipseState state(deck); const Opm::Schedule schedule(deck, state); const Opm::TimeMap timemap(deck);