Handle NETBALAN keyword in Schedule

This commit is contained in:
Joakim Hove 2021-10-04 12:35:47 +02:00
parent 0074364560
commit e1b9602a25
9 changed files with 241 additions and 0 deletions

View File

@ -129,6 +129,7 @@ if(ENABLE_ECL_INPUT)
src/opm/parser/eclipse/EclipseState/Schedule/MSW/AICD.cpp
src/opm/parser/eclipse/EclipseState/Schedule/MSW/SICD.cpp
src/opm/parser/eclipse/EclipseState/Schedule/MSW/Valve.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Network/Balance.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Network/Branch.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Network/ExtNetwork.cpp
src/opm/parser/eclipse/EclipseState/Schedule/Network/Node.cpp
@ -778,6 +779,7 @@ if(ENABLE_ECL_INPUT)
opm/parser/eclipse/EclipseState/Schedule/Action/State.hpp
opm/parser/eclipse/EclipseState/Schedule/ArrayDimChecker.hpp
opm/parser/eclipse/EclipseState/Schedule/GasLiftOpt.hpp
opm/parser/eclipse/EclipseState/Schedule/Network/Balance.hpp
opm/parser/eclipse/EclipseState/Schedule/Network/Branch.hpp
opm/parser/eclipse/EclipseState/Schedule/Network/ExtNetwork.hpp
opm/parser/eclipse/EclipseState/Schedule/Network/Node.hpp

View File

@ -0,0 +1,89 @@
/*
Copyright 2021 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 NETWORK_BALANCE_HPP
#define NETWORK_BALANCE_HPP
#include <optional>
#include <cstddef>
namespace Opm {
class DeckKeyword;
class Tuning;
namespace Network {
class Balance {
public:
enum class CalcMode {
None = 0,
TimeInterval = 1,
TimeStepStart = 2,
NUPCOL = 3
};
Balance() = default;
Balance(const Tuning& tuning, const DeckKeyword& keyword);
CalcMode mode() const;
double interval() const;
double pressure_tolerance() const;
std::size_t pressure_max_iter() const;
double thp_tolerance() const;
std::size_t thp_max_iter() const;
double target_balance_error() const;
double max_balance_error() const;
double min_tstep() const;
static Balance serializeObject();
bool operator==(const Balance& other) const;
template<class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(this->calc_mode);
serializer(this->calc_interval);
serializer(this->ptol);
serializer(this->m_pressure_max_iter);
serializer(this->m_thp_tolerance);
serializer(this->m_thp_max_iter);
serializer(this->target_branch_balance_error);
serializer(this->max_branch_balance_error);
serializer(this->m_min_tstep);
}
private:
CalcMode calc_mode{CalcMode::None};
std::optional<double> calc_interval;
double ptol;
std::size_t m_pressure_max_iter;
double m_thp_tolerance;
std::size_t m_thp_max_iter;
double target_branch_balance_error;
double max_branch_balance_error;
double m_min_tstep;
};
}
}
#endif

View File

@ -301,6 +301,7 @@ namespace Opm
pack_unpack<GConSump, Serializer>(serializer);
pack_unpack<WListManager, Serializer>(serializer);
pack_unpack<Network::ExtNetwork, Serializer>(serializer);
pack_unpack<Network::Balance, Serializer>(serializer);
pack_unpack<RPTConfig, Serializer>(serializer);
pack_unpack<Action::Actions, Serializer>(serializer);
pack_unpack<UDQActive, Serializer>(serializer);
@ -602,6 +603,7 @@ namespace Opm
void handleMESSAGES (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleMULTFLT (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleMXUNSUPP (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNETBALAN (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNODEPROP (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleNUPCOL (const HandlerContext&, const ParseContext&, ErrorGuard&);
void handleRPTONLY (const HandlerContext&, const ParseContext&, ErrorGuard&);

View File

@ -42,6 +42,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GConSump.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Group/GConSale.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Network/ExtNetwork.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Network/Balance.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/VFPProdTable.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/VFPInjTable.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Action/Actions.hpp>
@ -358,6 +359,7 @@ namespace Opm {
ptr_member<WellTestConfig> wtest_config;
ptr_member<GasLiftOpt> glo;
ptr_member<Network::ExtNetwork> network;
ptr_member<Network::Balance> network_balance;
ptr_member<RPTConfig> rpt_config;
ptr_member<RFTConfig> rft_config;
@ -379,6 +381,8 @@ namespace Opm {
return this->wlist_manager;
else if constexpr ( std::is_same_v<T, Network::ExtNetwork> )
return this->network;
else if constexpr ( std::is_same_v<T, Network::Balance> )
return this->network_balance;
else if constexpr ( std::is_same_v<T, RPTConfig> )
return this->rpt_config;
else if constexpr ( std::is_same_v<T, Action::Actions> )
@ -417,6 +421,8 @@ namespace Opm {
return this->wlist_manager;
else if constexpr ( std::is_same_v<T, Network::ExtNetwork> )
return this->network;
else if constexpr ( std::is_same_v<T, Network::Balance> )
return this->network_balance;
else if constexpr ( std::is_same_v<T, RPTConfig> )
return this->rpt_config;
else if constexpr ( std::is_same_v<T, Action::Actions> )

View File

@ -738,6 +738,11 @@ namespace {
parseContext.handleError( ParseContext::UNSUPPORTED_SCHEDULE_GEO_MODIFIER , msg_fmt, handlerContext.keyword.location(), errors );
}
void Schedule::handleNETBALAN(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
Network::Balance new_balance(this->snapshots.back().tuning(), handlerContext.keyword);
this->snapshots.back().network_balance.update( std::move(new_balance) );
}
void Schedule::handleNODEPROP(const HandlerContext& handlerContext, const ParseContext&, ErrorGuard&) {
auto ext_network = this->snapshots.back().network.get();
@ -2028,6 +2033,7 @@ namespace {
{ "MULTY-" , &Schedule::handleMXUNSUPP },
{ "MULTZ" , &Schedule::handleMXUNSUPP },
{ "MULTZ-" , &Schedule::handleMXUNSUPP },
{ "NETBALAN", &Schedule::handleNETBALAN },
{ "NODEPROP", &Schedule::handleNODEPROP },
{ "NUPCOL" , &Schedule::handleNUPCOL },
{ "RPTONLY" , &Schedule::handleRPTONLY },

View File

@ -0,0 +1,117 @@
/*
Copyright 2021 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/parser/eclipse/Parser/ParserKeywords/N.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Network/Balance.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Tuning.hpp>
#include <opm/parser/eclipse/Deck/DeckKeyword.hpp>
namespace Opm {
namespace Network {
Balance::Balance(const Tuning& tuning, const DeckKeyword& keyword) {
using NB = ParserKeywords::NETBALAN;
const auto& record = keyword[0];
double interval = record.getItem<NB::TIME_INTERVAL>().getSIDouble(0);
if (interval < 0)
this->calc_mode = CalcMode::NUPCOL;
else if (interval == 0)
this->calc_mode = CalcMode::TimeStepStart;
else {
this->calc_mode = CalcMode::TimeInterval;
this->calc_interval = interval;
}
this->ptol = record.getItem<NB::PRESSURE_CONVERGENCE_LIMIT>().getSIDouble(0);
this->m_pressure_max_iter = record.getItem<NB::MAX_ITER>().get<int>(0);
this->m_thp_tolerance = record.getItem<NB::THP_CONVERGENCE_LIMIT>().get<double>(0);
this->m_thp_max_iter = record.getItem<NB::MAX_ITER_THP>().get<int>(0);
this->target_branch_balance_error = record.getItem<NB::TARGET_BALANCE_ERROR>().getSIDouble(0);
this->max_branch_balance_error = record.getItem<NB::MAX_BALANCE_ERROR>().getSIDouble(0);
auto tstep_item = record.getItem<NB::MIN_TIME_STEP>();
if (tstep_item.defaultApplied(0))
this->m_min_tstep = tuning.TSMINZ;
else
this->m_min_tstep = record.getItem<NB::MIN_TIME_STEP>().getSIDouble(0);
}
Balance::CalcMode Balance::mode() const {
return this->calc_mode;
}
double Balance::interval() const {
return this->calc_interval.value();
}
double Balance::pressure_tolerance() const {
return this->ptol;
}
double Balance::thp_tolerance() const {
return this->m_thp_tolerance;
}
std::size_t Balance::thp_max_iter() const {
return this->m_thp_max_iter;
}
std::size_t Balance::pressure_max_iter() const {
return this->m_pressure_max_iter;
}
double Balance::target_balance_error() const {
return this->target_branch_balance_error;
}
double Balance::max_balance_error() const {
return this->max_branch_balance_error;
}
double Balance::min_tstep() const {
return this->m_min_tstep;
}
Balance Balance::serializeObject() {
Balance balance;
balance.calc_mode = Balance::CalcMode::NUPCOL;
balance.m_min_tstep = 123;
balance.ptol = 0.25;
balance.m_pressure_max_iter = 567;
return balance;
}
bool Balance::operator==(const Balance& other) const {
return this->calc_mode == other.calc_mode &&
this->calc_interval == other.calc_interval &&
this->ptol == other.ptol &&
this->m_pressure_max_iter == other.m_pressure_max_iter &&
this->m_thp_tolerance == other.m_thp_tolerance &&
this->m_thp_max_iter == other.m_thp_max_iter &&
this->target_branch_balance_error == other.target_branch_balance_error &&
this->max_branch_balance_error == other.max_branch_balance_error &&
this->m_min_tstep == other.m_min_tstep;
}
}
}

View File

@ -1771,6 +1771,7 @@ void Schedule::create_first(const time_point& start_time, const std::optional<ti
sched_state.guide_rate.update( GuideRateConfig() );
sched_state.rft_config.update( RFTConfig() );
sched_state.rst_config.update( RSTConfig::first( this->m_static.rst_config ) );
sched_state.network_balance.update( Network::Balance() );
//sched_state.update_date( start_time );
this->addGroup("FIELD", 0);
}

View File

@ -249,6 +249,7 @@ bool ScheduleState::operator==(const ScheduleState& other) const {
this->m_whistctl_mode == other.m_whistctl_mode &&
this->m_nupcol == other.m_nupcol &&
this->network.get() == other.network.get() &&
this->network_balance.get() == other.network_balance.get() &&
this->wtest_config.get() == other.wtest_config.get() &&
this->well_order.get() == other.well_order.get() &&
this->group_order.get() == other.group_order.get() &&
@ -300,6 +301,7 @@ ScheduleState ScheduleState::serializeObject() {
ts.actions.update( Action::Actions::serializeObject() );
ts.udq_active.update( UDQActive::serializeObject() );
ts.network.update( Network::ExtNetwork::serializeObject() );
ts.network_balance.update( Network::Balance::serializeObject() );
ts.well_order.update( NameOrder::serializeObject() );
ts.group_order.update( GroupOrder::serializeObject() );
ts.udq.update( UDQConfig::serializeObject() );

View File

@ -51,6 +51,7 @@
#include <opm/parser/eclipse/EclipseState/Schedule/Well/WellMatcher.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/NameOrder.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Well/PAvg.hpp>
#include <opm/parser/eclipse/EclipseState/Schedule/Network/Balance.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <opm/parser/eclipse/Deck/DeckItem.hpp>
@ -4374,6 +4375,9 @@ WCONPROD
TSTEP -- 1
10 /
NETBALAN
1 2 3 4 5 6 7 8 /
WELPI
'P1' 200.0 /
/
@ -4422,6 +4426,18 @@ END
}
sched.shut_well("P1", 0);
auto netbalan0 = sched[0].network_balance();
BOOST_CHECK(netbalan0.mode() == Network::Balance::CalcMode::None);
auto netbalan1 = sched[1].network_balance();
BOOST_CHECK(netbalan1.mode() == Network::Balance::CalcMode::TimeInterval);
BOOST_CHECK_EQUAL( netbalan1.interval(), 86400 );
BOOST_CHECK_EQUAL( netbalan1.pressure_tolerance(), 200000 );
BOOST_CHECK_EQUAL( netbalan1.pressure_max_iter(), 3 );
BOOST_CHECK_EQUAL( netbalan1.thp_tolerance(), 4 );
BOOST_CHECK_EQUAL( netbalan1.thp_max_iter(), 5 );
}
bool compare_dates(const time_point& t, int year, int month, int day) {