From 6b781152290df53b883946c1cc6338d2ba91d85d Mon Sep 17 00:00:00 2001 From: Odd Andersen Date: Mon, 7 May 2018 15:37:39 +0200 Subject: [PATCH] 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);// @@@ + } +}; +