Skip to content

Commit

Permalink
Add support for DUMPCUPL
Browse files Browse the repository at this point in the history
Adds support for the DUMPCUPL keyword used in reservoir coupling.
  • Loading branch information
hakonhagland committed Oct 24, 2024
1 parent d492ac7 commit 16dbcc6
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 4 deletions.
2 changes: 2 additions & 0 deletions CMakeLists_files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ 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/UDQ/UDQKeywordHandlers.cpp
opm/input/eclipse/Schedule/UDQ/UDQActive.cpp
opm/input/eclipse/Schedule/UDQ/UDQAssign.cpp
Expand Down Expand Up @@ -1309,6 +1310,7 @@ 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/VFPInjTable.hpp
opm/input/eclipse/Schedule/VFPProdTable.hpp
opm/input/eclipse/Schedule/Well/Connection.hpp
Expand Down
64 changes: 64 additions & 0 deletions opm/input/eclipse/Schedule/ResCoup/CouplingFile.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
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/CouplingFile.hpp>
#include <opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.hpp>
#include <opm/input/eclipse/Schedule/ScheduleState.hpp>
#include <opm/input/eclipse/Parser/ParserKeywords/D.hpp>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/common/utility/OpmInputError.hpp>
#include "../HandlerContext.hpp"


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();
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::DUMPCUPL::VALUE>();
if (deck_item.defaultApplied(0)) {
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);
schedule_state.rescoup.update( std::move( rescoup ));
}

} // namespace Opm

28 changes: 28 additions & 0 deletions opm/input/eclipse/Schedule/ResCoup/CouplingFile.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 RESERVOIR_COUPLING_FILE_HPP
#define RESERVOIR_COUPLING_FILE_HPP
namespace Opm {

class HandlerContext;

extern void handleDUMPCUPL(HandlerContext& handlerContext);

} // namespace Opm
#endif // RESERVOIR_COUPLING_FILE_HPP
3 changes: 2 additions & 1 deletion opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ bool CouplingInfo::operator==(const CouplingInfo& rhs) const {
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_master_min_time_step == rhs.m_master_min_time_step &&
this->m_coupling_file_flag == rhs.m_coupling_file_flag;
}

CouplingInfo CouplingInfo::serializationTestObject()
Expand Down
16 changes: 16 additions & 0 deletions opm/input/eclipse/Schedule/ResCoup/ReservoirCouplingInfo.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,24 @@ namespace Opm::ReservoirCoupling {

class CouplingInfo {
public:
enum class CouplingFileFlag {
NONE,
FORMATTED,
UNFORMATTED
};

CouplingInfo() = default;

// 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 @@ -116,6 +130,7 @@ class CouplingInfo {
serializer(m_grup_slavs);
serializer(m_master_mode);
serializer(m_master_min_time_step);
serializer(m_coupling_file_flag);
}

// Non-inline methods (defined in CouplingInfo.cpp)
Expand All @@ -130,6 +145,7 @@ 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};
};

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

#include <fmt/format.h>

Expand All @@ -37,6 +38,7 @@ getReservoirCouplingHandlers()
{ "GRUPMAST", &handleGRUPMAST},
{ "GRUPSLAV", &handleGRUPSLAV},
{ "RCMASTS", &handleRCMASTS},
{ "DUMPCUPL", &handleDUMPCUPL},
};
}

Expand Down
59 changes: 56 additions & 3 deletions tests/parser/ReservoirCouplingTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include <opm/input/eclipse/EclipseState/Grid/FieldPropsManager.hpp>
#include <opm/input/eclipse/EclipseState/Tables/TableManager.hpp>
#include <opm/input/eclipse/Python/Python.hpp>
#include <opm/input/eclipse/Units/Units.hpp>
#include <opm/common/utility/OpmInputError.hpp>
#include <opm/common/OpmLog/OpmLog.hpp>
#include <opm/common/OpmLog/StreamLog.hpp>
Expand Down Expand Up @@ -128,6 +129,11 @@ GRUPMAST
return prefix + end_of_deck_string;
}

std::string getCouplingFileDeckString(const std::string &end_of_deck_string)
{
return getMinimumMasterTimeStepDeckString(end_of_deck_string);
}

void removeStringLogger() {
OpmLog::removeBackend("MYLOGGER");
}
Expand Down Expand Up @@ -490,13 +496,13 @@ TUNING
/
RCMASTS
0.01 /
0.0001 /
)";
std::string deck_string = getMinimumMasterTimeStepDeckString(end_of_deck_string);
const auto& schedule = makeSchedule(deck_string, /*slave_mode=*/false);
const auto& rescoup = schedule[0].rescoup();
BOOST_CHECK(rescoup.masterMinTimeStep() == 0.01);

// NOTE: Metric unit system is used by default, to time is in days
BOOST_CHECK(rescoup.masterMinTimeStep() == (0.0001 * Opm::unit::day));
}

BOOST_AUTO_TEST_CASE(NEGATIVE_VALUE_PROVIDED) {
Expand All @@ -520,3 +526,50 @@ RCMASTS
}

BOOST_AUTO_TEST_SUITE_END()

// ------------------------------------------------
// Testing DUMPCUPL keyword (sorted alphabetically)
// ------------------------------------------------

BOOST_AUTO_TEST_SUITE(DumpCouplingFile)

BOOST_AUTO_TEST_CASE(FORMATTED_FILE) {
std::string end_of_deck_string = R"(
DUMPCUPL
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.couplingFileFlag() ==
Opm::ReservoirCoupling::CouplingInfo::CouplingFileFlag::FORMATTED);

}

BOOST_AUTO_TEST_CASE(BAD_VALUE) {
std::string end_of_deck_string = R"(
DUMPCUPL
S /
)";
std::string deck_string = getCouplingFileDeckString(end_of_deck_string);
assertRaisesInputErrorException(
deck_string,
/*slave_mode=*/false,
/*exception_string=*/"Problem with keyword DUMPCUPL\nIn <memory string> line 28\nInvalid DUMPCUPL value: S"
);
}

BOOST_AUTO_TEST_CASE(DEFAULT_NOT_ALLOWED) {
std::string end_of_deck_string = R"(
DUMPCUPL
* /
)";
std::string deck_string = getCouplingFileDeckString(end_of_deck_string);
assertRaisesInputErrorException(
deck_string,
/*slave_mode=*/false,
/*exception_string=*/"Problem with keyword DUMPCUPL\nIn <memory string> line 28\nDUMPCUPL keyword cannot be defaulted."
);
}

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit 16dbcc6

Please sign in to comment.