Skip to content

Commit

Permalink
Add support for USECUPL keyword
Browse files Browse the repository at this point in the history
  • Loading branch information
hakonhagland committed Oct 28, 2024
1 parent 34ea12e commit c09263f
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 31 deletions.
6 changes: 4 additions & 2 deletions CMakeLists_files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,8 @@ if(ENABLE_ECL_INPUT)
opm/input/eclipse/Schedule/ResCoup/MasterGroup.cpp
opm/input/eclipse/Schedule/ResCoup/Slaves.cpp
opm/input/eclipse/Schedule/ResCoup/MasterMinimumTimeStep.cpp
opm/input/eclipse/Schedule/ResCoup/CouplingFile.cpp
opm/input/eclipse/Schedule/ResCoup/ReadCouplingFile.cpp
opm/input/eclipse/Schedule/ResCoup/WriteCouplingFile.cpp
opm/input/eclipse/Schedule/UDQ/UDQKeywordHandlers.cpp
opm/input/eclipse/Schedule/UDQ/UDQActive.cpp
opm/input/eclipse/Schedule/UDQ/UDQAssign.cpp
Expand Down Expand Up @@ -1310,7 +1311,8 @@ if(ENABLE_ECL_INPUT)
opm/input/eclipse/Schedule/ResCoup/MasterGroup.hpp
opm/input/eclipse/Schedule/ResCoup/Slaves.hpp
opm/input/eclipse/Schedule/ResCoup/MasterMinimumTimeStep.hpp
opm/input/eclipse/Schedule/ResCoup/CouplingFile.hpp
opm/input/eclipse/Schedule/ResCoup/ReadCouplingFile.hpp
opm/input/eclipse/Schedule/ResCoup/WriteCouplingFile.hpp
opm/input/eclipse/Schedule/VFPInjTable.hpp
opm/input/eclipse/Schedule/VFPProdTable.hpp
opm/input/eclipse/Schedule/Well/Connection.hpp
Expand Down
62 changes: 62 additions & 0 deletions opm/input/eclipse/Schedule/ResCoup/ReadCouplingFile.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
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 <http://www.gnu.org/licenses/>.
*/


#include <opm/input/eclipse/Schedule/ResCoup/ReadCouplingFile.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.hpp>
#include <opm/input/eclipse/Schedule/ScheduleState.hpp>
#include <opm/input/eclipse/Parser/ParserKeywords/U.hpp>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/common/utility/OpmInputError.hpp>
#include "../HandlerContext.hpp"


namespace Opm {

void handleUSECUPL(HandlerContext& handlerContext)
{
auto& schedule_state = handlerContext.state();
auto rescoup = schedule_state.rescoup();
const auto& keyword = handlerContext.keyword;
// Opm::Parser::parseFile() (see readDeck.cpp in opm-simulators) will throw an exception if there
// is more than one record for this keyword, so we can assume that there is exactly one record here.
auto record = keyword[0];
{
auto deck_item = record.getItem<ParserKeywords::USECUPL::BASE>();
if (deck_item.defaultApplied(0)) {
throw OpmInputError("Root name of coupling file (item 1) cannot be defaulted.", keyword.location());
}
auto root_name = deck_item.getTrimmedString(0);
rescoup.readCouplingFileName(root_name);
}
{
auto deck_item = record.getItem<ParserKeywords::USECUPL::FMT>();
if (deck_item.defaultApplied(0)) {
throw OpmInputError("Format of coupling file (item 2) cannot be defaulted.", keyword.location());
}
auto flag_str = deck_item.getTrimmedString(0);
auto coupling_file_flag = ReservoirCoupling::CouplingInfo::couplingFileFlagFromString(
flag_str, keyword);
rescoup.readCouplingFileFlag(coupling_file_flag);
}
schedule_state.rescoup.update( std::move( rescoup ));
}

} // namespace Opm

28 changes: 28 additions & 0 deletions opm/input/eclipse/Schedule/ResCoup/ReadCouplingFile.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
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 <http://www.gnu.org/licenses/>.
*/
#ifndef OPM_READ_RESERVOIR_COUPLING_FILE_HPP
#define OPM_READ_RESERVOIR_COUPLING_FILE_HPP
namespace Opm {

class HandlerContext;

extern void handleUSECUPL(HandlerContext& handlerContext);

} // namespace Opm
#endif // OPM_READ_RESERVOIR_COUPLING_FILE_HPP
19 changes: 18 additions & 1 deletion opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,35 @@

#include <stdexcept>
#include <limits>
#include <opm/common/utility/OpmInputError.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.hpp>

namespace Opm {
namespace ReservoirCoupling {

CouplingInfo::CouplingFileFlag CouplingInfo::couplingFileFlagFromString(
const std::string& flag_str, const DeckKeyword& keyword
)
{
//DEBUG
if (flag_str == "F") {
return CouplingInfo::CouplingFileFlag::FORMATTED;
} else if (flag_str == "U") {
return CouplingInfo::CouplingFileFlag::UNFORMATTED;
} else {
throw Opm::OpmInputError("Invalid DUMPCUPL value: " + flag_str, keyword.location());
}
}

bool CouplingInfo::operator==(const CouplingInfo& rhs) const {
return this->m_slaves == rhs.m_slaves &&
this->m_master_groups == rhs.m_master_groups &&
this->m_grup_slavs == rhs.m_grup_slavs &&
this->m_master_mode == rhs.m_master_mode &&
this->m_master_min_time_step == rhs.m_master_min_time_step &&
this->m_coupling_file_flag == rhs.m_coupling_file_flag;
this->m_write_coupling_file_flag == rhs.m_write_coupling_file_flag &&
this->m_read_coupling_file_name == rhs.m_read_coupling_file_name &&
this->m_read_coupling_file_flag == rhs.m_read_coupling_file_flag;
}

CouplingInfo CouplingInfo::serializationTestObject()
Expand Down
45 changes: 35 additions & 10 deletions opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#ifndef OPM_RESERVOIR_COUPLING_INFO_HPP
#define OPM_RESERVOIR_COUPLING_INFO_HPP

#include <opm/input/eclipse/Deck/DeckKeyword.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/Slaves.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/GrupSlav.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/MasterGroup.hpp>
Expand All @@ -42,14 +43,6 @@ class CouplingInfo {

// Inline methods (alphabetically)

void couplingFileFlag(CouplingFileFlag flag) {
m_coupling_file_flag = flag;
}

CouplingFileFlag couplingFileFlag() const {
return m_coupling_file_flag;
}

const std::map<std::string, GrupSlav>& grupSlavs() const {
return this->m_grup_slavs;
}
Expand Down Expand Up @@ -106,6 +99,22 @@ class CouplingInfo {
m_master_min_time_step = tstep;
}

void readCouplingFileFlag(CouplingFileFlag flag) {
m_read_coupling_file_flag = flag;
}

CouplingFileFlag readCouplingFileFlag() const {
return m_read_coupling_file_flag;
}

void readCouplingFileName(const std::string& name) {
m_read_coupling_file_name = name;
}

const std::string& readCouplingFileName() const {
return m_read_coupling_file_name;
}

const Slave& slave(const std::string& name) const {
return m_slaves.at(name);
}
Expand All @@ -130,11 +139,25 @@ class CouplingInfo {
serializer(m_grup_slavs);
serializer(m_master_mode);
serializer(m_master_min_time_step);
serializer(m_coupling_file_flag);
serializer(m_write_coupling_file_flag);
serializer(m_read_coupling_file_flag);
serializer(m_read_coupling_file_name);
}

void writeCouplingFileFlag(CouplingFileFlag flag) {
m_write_coupling_file_flag = flag;
}

CouplingFileFlag writeCouplingFileFlag() const {
return m_write_coupling_file_flag;
}


// Non-inline methods (defined in CouplingInfo.cpp)

static CouplingFileFlag couplingFileFlagFromString(
const std::string& flag_str, const DeckKeyword& keyword);

bool operator==(const CouplingInfo& other) const;
static CouplingInfo serializationTestObject();

Expand All @@ -145,7 +168,9 @@ class CouplingInfo {
bool m_master_mode{false};
// Default value: No limit, however a positive value can be set by using keyword RCMASTS
double m_master_min_time_step{0.0};
CouplingFileFlag m_coupling_file_flag{CouplingFileFlag::NONE};
CouplingFileFlag m_write_coupling_file_flag{CouplingFileFlag::NONE};
CouplingFileFlag m_read_coupling_file_flag{CouplingFileFlag::NONE};
std::string m_read_coupling_file_name{};
};

} // namespace Opm::ReservoirCoupling
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
#include "Slaves.hpp"
#include "MasterGroup.hpp"
#include "MasterMinimumTimeStep.hpp"
#include "CouplingFile.hpp"
#include "WriteCouplingFile.hpp"
#include "ReadCouplingFile.hpp"

#include <fmt/format.h>

Expand All @@ -39,6 +40,7 @@ getReservoirCouplingHandlers()
{ "GRUPSLAV", &handleGRUPSLAV},
{ "RCMASTS", &handleRCMASTS},
{ "DUMPCUPL", &handleDUMPCUPL},
{ "USECUPL", &handleUSECUPL},
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/


#include <opm/input/eclipse/Schedule/ResCoup/CouplingFile.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/WriteCouplingFile.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.hpp>
#include <opm/input/eclipse/Schedule/ScheduleState.hpp>
#include <opm/input/eclipse/Parser/ParserKeywords/D.hpp>
Expand All @@ -29,19 +29,6 @@

namespace Opm {

ReservoirCoupling::CouplingInfo::CouplingFileFlag couplingFileFlagFromString(
const std::string& flag_str, const DeckKeyword& keyword
)
{
if (flag_str == "F") {
return ReservoirCoupling::CouplingInfo::CouplingFileFlag::FORMATTED;
} else if (flag_str == "U") {
return ReservoirCoupling::CouplingInfo::CouplingFileFlag::UNFORMATTED;
} else {
throw OpmInputError("Invalid DUMPCUPL value: " + flag_str, keyword.location());
}
}

void handleDUMPCUPL(HandlerContext& handlerContext)
{
auto& schedule_state = handlerContext.state();
Expand All @@ -55,8 +42,10 @@ void handleDUMPCUPL(HandlerContext& handlerContext)
throw OpmInputError("DUMPCUPL keyword cannot be defaulted.", keyword.location());
}
auto flag_str = deck_item.getTrimmedString(0);
auto coupling_file_flag = couplingFileFlagFromString(flag_str, keyword);
rescoup.couplingFileFlag(coupling_file_flag);
//DEBUG
auto coupling_file_flag = ReservoirCoupling::CouplingInfo::couplingFileFlagFromString(
flag_str, keyword);
rescoup.writeCouplingFileFlag(coupling_file_flag);
schedule_state.rescoup.update( std::move( rescoup ));
}

Expand Down
1 change: 1 addition & 0 deletions opm/input/eclipse/share/keywords/000_Eclipse100/U/USECUPL
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"sections": [
"SCHEDULE"
],
"size": 1,
"items": [
{
"name": "BASE",
Expand Down
34 changes: 33 additions & 1 deletion tests/parser/ReservoirCouplingTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include <boost/test/unit_test.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/WriteCouplingFile.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/GrupSlav.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/MasterGroup.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/Slaves.hpp>
Expand Down Expand Up @@ -541,7 +542,7 @@ DUMPCUPL
std::string deck_string = getCouplingFileDeckString(end_of_deck_string);
const auto& schedule = makeSchedule(deck_string, /*slave_mode=*/false);
const auto& rescoup = schedule[0].rescoup();
BOOST_CHECK(rescoup.couplingFileFlag() ==
BOOST_CHECK(rescoup.writeCouplingFileFlag() ==
Opm::ReservoirCoupling::CouplingInfo::CouplingFileFlag::FORMATTED);

}
Expand Down Expand Up @@ -573,3 +574,34 @@ DUMPCUPL
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE(UseCouplingFile)

BOOST_AUTO_TEST_CASE(FORMATTED_FILE) {
std::string end_of_deck_string = R"(
USECUPL
'BASE' 'F' /
)";
std::string deck_string = getCouplingFileDeckString(end_of_deck_string);
const auto& schedule = makeSchedule(deck_string, /*slave_mode=*/false);
const auto& rescoup = schedule[0].rescoup();
BOOST_CHECK(rescoup.readCouplingFileFlag() ==
Opm::ReservoirCoupling::CouplingInfo::CouplingFileFlag::FORMATTED);
BOOST_CHECK(rescoup.readCouplingFileName() == "BASE");

}

BOOST_AUTO_TEST_CASE(DEFAULT_NOT_ALLOWED1) {
std::string end_of_deck_string = R"(
USECUPL
* 'U' /
)";
std::string deck_string = getCouplingFileDeckString(end_of_deck_string);
assertRaisesInputErrorException(
deck_string,
/*slave_mode=*/false,
/*exception_string=*/"Problem with keyword USECUPL\nIn <memory string> line 28\nRoot name of coupling file (item 1) cannot be defaulted."
);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit c09263f

Please sign in to comment.