From 4900fbab317f32841c5482836a482f8908164da9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kon=20H=C3=A6gland?= Date: Thu, 20 Jun 2024 22:31:17 +0200 Subject: [PATCH] Add support for SLAVES keyword --- CMakeLists_files.cmake | 3 + .../eclipse/Schedule/KeywordHandlers.cpp | 2 + .../ResCoup/ReservoirCouplingInfo.cpp | 47 ++++++++ .../ResCoup/ReservoirCouplingInfo.hpp | 111 ++++++++++++++++++ .../ReservoirCouplingKeywordHandlers.cpp | 68 +++++++++++ .../ReservoirCouplingKeywordHandlers.hpp | 35 ++++++ opm/input/eclipse/Schedule/Schedule.cpp | 2 + opm/input/eclipse/Schedule/ScheduleState.hpp | 4 + tests/parser/ReservoirCouplingTests.cpp | 67 +++++++++++ 9 files changed, 339 insertions(+) create mode 100644 opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.cpp create mode 100644 opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.hpp create mode 100644 opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingKeywordHandlers.cpp create mode 100644 opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingKeywordHandlers.hpp create mode 100644 tests/parser/ReservoirCouplingTests.cpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index c99f38f6448..77bb1a90a44 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -265,6 +265,8 @@ if(ENABLE_ECL_INPUT) opm/input/eclipse/Schedule/Network/ExtNetwork.cpp opm/input/eclipse/Schedule/Network/NetworkKeywordHandlers.cpp opm/input/eclipse/Schedule/Network/Node.cpp + opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.cpp + opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingKeywordHandlers.cpp opm/input/eclipse/Schedule/UDQ/UDQKeywordHandlers.cpp opm/input/eclipse/Schedule/UDQ/UDQActive.cpp opm/input/eclipse/Schedule/UDQ/UDQAssign.cpp @@ -553,6 +555,7 @@ if(ENABLE_ECL_INPUT) tests/parser/PAvgTests.cpp tests/parser/PYACTION.cpp tests/parser/RawKeywordTests.cpp + tests/parser/ReservoirCouplingTests.cpp tests/parser/test_ReportConfig.cpp tests/parser/ResinsightTest.cpp tests/parser/RestartConfigTests.cpp diff --git a/opm/input/eclipse/Schedule/KeywordHandlers.cpp b/opm/input/eclipse/Schedule/KeywordHandlers.cpp index 6ccbd6cc3c6..8ef94af0fba 100644 --- a/opm/input/eclipse/Schedule/KeywordHandlers.cpp +++ b/opm/input/eclipse/Schedule/KeywordHandlers.cpp @@ -51,6 +51,7 @@ #include "MixingRateControlKeywordHandlers.hpp" #include "MSW/MSWKeywordHandlers.hpp" #include "Network/NetworkKeywordHandlers.hpp" +#include "ResCoup/ReservoirCouplingKeywordHandlers.hpp" #include "RXXKeywordHandlers.hpp" #include "UDQ/UDQKeywordHandlers.hpp" #include "Well/WellCompletionKeywordHandlers.hpp" @@ -371,6 +372,7 @@ KeywordHandlers::KeywordHandlers() getMSWHandlers, getNetworkHandlers, getUDQHandlers, + getReservoirCouplingHandlers, getRXXHandlers, getWellCompletionHandlers, getWellHandlers, diff --git a/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.cpp b/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.cpp new file mode 100644 index 00000000000..a65dba0dc8d --- /dev/null +++ b/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.cpp @@ -0,0 +1,47 @@ +/* + Copyright 2024 Equinor 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 + +namespace Opm { +namespace ReservoirCoupling { +Slave Slave::serializationTestObject() +{ + return Slave{"RES-1", "RC-01_MOD1_PRED", "../mod1", 1}; +} + +bool Slave::operator==(const Slave& rhs) const { + return this->m_name == rhs.m_name; +} + +bool CouplingInfo::operator==(const CouplingInfo& rhs) const { + return this->m_slaves == rhs.m_slaves; +} + +CouplingInfo CouplingInfo::serializationTestObject() +{ + CouplingInfo info; + info.m_slaves = {{"SLAVE1", Slave::serializationTestObject()}}; + return info; +} + +} // namespace ReservoirCoupling +} // namespace Opm diff --git a/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.hpp b/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.hpp new file mode 100644 index 00000000000..153ecd0ca3b --- /dev/null +++ b/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.hpp @@ -0,0 +1,111 @@ +/* + Copyright 2024 Equinor 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 . +*/ +#ifndef RESERVOIR_COUPLING_SLAVES_HPP +#define RESERVOIR_COUPLING_SLAVES_HPP + +#include +#include +#include +#include +#include + +namespace Opm { +namespace ReservoirCoupling { + +class Slave { +public: + Slave() = default; + + explicit Slave(const std::string& name, const std::string& data_filename, const std::string& directory_path, unsigned int numprocs) : + m_name{name}, + m_data_filename{data_filename}, + m_directory_path{directory_path}, + m_numprocs{numprocs} + {} + static Slave serializationTestObject(); + + const std::string& name() const { + return this->m_name; + } + const std::string& dataFilename() const { + return this->m_data_filename; + } + const std::string& directoryPath() const { + return this->m_directory_path; + } + unsigned int numprocs() const { + return this->m_numprocs; + } + + void name(const std::string& value) { + this->m_name = value; + } + void dataFilename(const std::string& value) { + this->m_data_filename = value; + } + void directoryPath(const std::string& value) { + this->m_directory_path = value; + } + void numprocs(unsigned int value) { + this->m_numprocs = value; + } + bool operator==(const Slave& other) const; + + template + void serializeOp(Serializer& serializer) + { + serializer(m_name); + serializer(m_data_filename); + serializer(m_directory_path); + serializer(m_numprocs); + } +private: + std::string m_name; + std::string m_data_filename; + std::string m_directory_path; + unsigned int m_numprocs; +}; + +class CouplingInfo { +public: + CouplingInfo() = default; + + static CouplingInfo serializationTestObject(); + std::map& slaves() { + return this->m_slaves; + } + bool operator==(const CouplingInfo& other) const; + bool has_slave(const std::string& name) const { + return m_slaves.find(name) != m_slaves.end(); + } + const Slave& slave(const std::string& name) const { + return m_slaves.at(name); + } + template + void serializeOp(Serializer& serializer) + { + serializer(m_slaves); + } +private: + std::map m_slaves; +}; + +} // namespace ReservoirCoupling +} // namespace Opm +#endif \ No newline at end of file diff --git a/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingKeywordHandlers.cpp b/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingKeywordHandlers.cpp new file mode 100644 index 00000000000..54be46444a9 --- /dev/null +++ b/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingKeywordHandlers.cpp @@ -0,0 +1,68 @@ +/* + Copyright 2024 Equinor 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 "ReservoirCouplingKeywordHandlers.hpp" +#include "ReservoirCouplingInfo.hpp" +#include "../HandlerContext.hpp" + +#include +#include + +#include + +#include + +#include + +namespace Opm { + +namespace { + +void handleSLAVES(HandlerContext& handlerContext) +{ + auto rescoup = handlerContext.state().rescoup(); + const auto& keyword = handlerContext.keyword; + + for (const auto& record : keyword) { + const std::string& slave_name = record.getItem().getTrimmedString(0); + const std::string& data_filename = record.getItem().getTrimmedString(0); + const std::string& directory_path = record.getItem().getTrimmedString(0); + const int numprocs_int = record.getItem().get(0); + if (numprocs_int <= 0) { + std::string msg = fmt::format("Number of processors must be positive. Got: {}.", numprocs_int); + throw OpmInputError(msg, handlerContext.keyword.location()); + } + const unsigned int numprocs = static_cast(numprocs_int); + ReservoirCoupling::Slave slave{ slave_name, data_filename, directory_path, numprocs}; + rescoup.slaves().emplace( slave_name, std::move( slave )); + } + + handlerContext.state().rescoup.update( std::move( rescoup )); +} +} // anonymous namespace + +std::vector> +getReservoirCouplingHandlers() +{ + return { + { "SLAVES", &handleSLAVES }, + }; +} + +} // namespace Opm diff --git a/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingKeywordHandlers.hpp b/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingKeywordHandlers.hpp new file mode 100644 index 00000000000..d32b38139ba --- /dev/null +++ b/opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingKeywordHandlers.hpp @@ -0,0 +1,35 @@ +/* + Copyright 2024 Equinor 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 . + */ +#ifndef RESERVOIR_COUPLING_KEYWORD_HANDLERS_HPP +#define RESERVOIR_COUPLING_KEYWORD_HANDLERS_HPP + +#include "../KeywordHandlers.hpp" + +#include +#include +#include + +namespace Opm { + +//! \brief Obtain a list of reservoir coupling keyword handlers. +std::vector> getReservoirCouplingHandlers(); + +} + +#endif diff --git a/opm/input/eclipse/Schedule/Schedule.cpp b/opm/input/eclipse/Schedule/Schedule.cpp index 0d487773c5f..416d6e1f542 100644 --- a/opm/input/eclipse/Schedule/Schedule.cpp +++ b/opm/input/eclipse/Schedule/Schedule.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include #include @@ -2325,6 +2326,7 @@ void Schedule::create_first(const time_point& start_time, const std::optional glo; ptr_member network; ptr_member network_balance; + ptr_member rescoup; ptr_member rpt_config; ptr_member rft_config; diff --git a/tests/parser/ReservoirCouplingTests.cpp b/tests/parser/ReservoirCouplingTests.cpp new file mode 100644 index 00000000000..7ceab231b47 --- /dev/null +++ b/tests/parser/ReservoirCouplingTests.cpp @@ -0,0 +1,67 @@ +/* + Copyright 2024 Equinor 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 "config.h" +#define BOOST_TEST_MODULE ReservoirCouplingTests + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace Opm; +namespace { +Schedule make_schedule(const std::string& schedule_string) { + Parser parser; + auto python = std::make_shared(); + Deck deck = parser.parseString(schedule_string); + EclipseGrid grid(10,10,10); + TableManager table ( deck ); + FieldPropsManager fp( deck, Phases{true, true, true}, grid, table); + Runspec runspec (deck); + Schedule schedule(deck, grid , fp, runspec, python); + return schedule; +} +} + +BOOST_AUTO_TEST_CASE(SLAVES) { + std::string deck_string = R"( + +SCHEDULE +SLAVES + 'RES-1' 'RC-01_MOD1_PRED' 1* '../mod1' 4 / + 'RES-2' 'RC-01_MOD2_PRED' 1* '../mod2' 1 / +/ + +)"; + + const auto& schedule = make_schedule(deck_string); + const auto& rescoup = schedule[0].rescoup(); + BOOST_CHECK(rescoup.has_slave("RES-1")); + auto slave = rescoup.slave("RES-1"); + BOOST_CHECK_EQUAL(slave.name(), "RES-1"); + BOOST_CHECK_EQUAL(slave.dataFilename(), "RC-01_MOD1_PRED"); + BOOST_CHECK_EQUAL(slave.directoryPath(), "../mod1"); + BOOST_CHECK_EQUAL(slave.numprocs(), 4); +}