Skip to content

Commit

Permalink
Add support for GSATPROD in the input/output code
Browse files Browse the repository at this point in the history
  • Loading branch information
Tor Harald Sandve committed Sep 11, 2024
1 parent bd8c5d2 commit 85d841e
Show file tree
Hide file tree
Showing 13 changed files with 305 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CMakeLists_files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ if(ENABLE_ECL_INPUT)
opm/input/eclipse/Schedule/Group/GConSale.cpp
opm/input/eclipse/Schedule/Group/GConSump.cpp
opm/input/eclipse/Schedule/Group/GroupEconProductionLimits.cpp
opm/input/eclipse/Schedule/Group/GSatProd.cpp
opm/input/eclipse/Schedule/Group/GTNode.cpp
opm/input/eclipse/Schedule/MSW/AICD.cpp
opm/input/eclipse/Schedule/MSW/Compsegs.cpp
Expand Down Expand Up @@ -1349,6 +1350,7 @@ if(ENABLE_ECL_INPUT)
opm/input/eclipse/Schedule/Group/GuideRate.hpp
opm/input/eclipse/Schedule/Group/GConSale.hpp
opm/input/eclipse/Schedule/Group/GConSump.hpp
opm/input/eclipse/Schedule/Group/GSatProd.hpp
opm/input/eclipse/Schedule/Group/GroupEconProductionLimits.hpp
opm/input/eclipse/Schedule/Group/GuideRateConfig.hpp
opm/input/eclipse/Schedule/Group/GuideRateModel.hpp
Expand Down
69 changes: 69 additions & 0 deletions opm/input/eclipse/Schedule/Group/GSatProd.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
Copyright 2019 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/Group/GSatProd.hpp>
#include <stdexcept>

namespace Opm {

GSatProd GSatProd::serializationTestObject()
{
GSatProd result;
result.groups = { {"test1", {1.0,2.0,3.0,4.0,5.0} } };

return result;
}

bool GSatProd::has(const std::string& name) const {
return (groups.find(name) != groups.end());
}


const GSatProd::GSatProdGroup& GSatProd::get(const std::string& name) const {

auto it = groups.find(name);
if (it == groups.end())
throw std::invalid_argument("Current GSatPRod obj. does not contain '" + name + "'.");
else
return it->second;
}

void GSatProd::add(const std::string& name, const double& oil_rate,
const double& gas_rate, const double& water_rate,
const double& resv_rate, const double& glift_rate) {

GSatProd::GSatProdGroup& group = groups[name];

group.oil_rate = oil_rate;
group.gas_rate = gas_rate;
group.water_rate = water_rate;
group.resv_rate = resv_rate;
group.glift_rate = glift_rate;
}


size_t GSatProd::size() const {
return groups.size();
}

bool GSatProd::operator==(const GSatProd& data) const {
return this->groups == data.groups;
}

}
81 changes: 81 additions & 0 deletions opm/input/eclipse/Schedule/Group/GSatProd.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*
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 GSATPROD_H
#define GSATPROD_H

#include <map>
#include <string>

namespace Opm {

class SummaryState;

class GSatProd {
public:
struct GSatProdGroup {
double oil_rate;
double gas_rate;
double water_rate;
double resv_rate;
double glift_rate;

bool operator==(const GSatProdGroup& data) const {
return oil_rate == data.oil_rate &&
gas_rate == data.gas_rate &&
water_rate == data.water_rate &&
resv_rate == data.resv_rate &&
glift_rate == data.glift_rate;
}

template<class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(oil_rate);
serializer(gas_rate);
serializer(water_rate);
serializer(resv_rate);
serializer(glift_rate);
}
};

static GSatProd serializationTestObject();

bool has(const std::string& name) const;
const GSatProdGroup& get(const std::string& name) const;
void add(const std::string& name, const double& oil_rate,
const double& gas_rate, const double& water_rate,
const double& resv_rate, const double& glift_rate);
size_t size() const;

bool operator==(const GSatProd& data) const;

template<class Serializer>
void serializeOp(Serializer& serializer)
{
serializer(groups);
}

private:
std::map<std::string, GSatProdGroup> groups;
};

}

#endif
35 changes: 35 additions & 0 deletions opm/input/eclipse/Schedule/Group/GroupKeywordHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSale.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSump.hpp>
#include <opm/input/eclipse/Schedule/Group/GSatProd.hpp>
#include <opm/input/eclipse/Schedule/Group/Group.hpp>
#include <opm/input/eclipse/Schedule/Group/GroupEconProductionLimits.hpp>
#include <opm/input/eclipse/Schedule/Group/GuideRateConfig.hpp>
Expand Down Expand Up @@ -308,6 +309,39 @@ void handleGCONPROD(HandlerContext& handlerContext)
}
}

void handleGSATPROD(HandlerContext& handlerContext)
{
const auto& keyword = handlerContext.keyword;
auto new_gsatprod = handlerContext.state().gsatprod.get();

for (const auto& record : keyword) {
const std::string& groupNamePattern = record.getItem("SATELLITE_GROUP_NAME_OR_GROUP_NAME_ROOT").getTrimmedString(0);
const auto group_names = handlerContext.groupNames(groupNamePattern);
if (group_names.empty()) {
handlerContext.invalidNamePattern(groupNamePattern);
}
const auto oil_rate = record.getItem("OIL_PRODUCTION_RATE").getSIDouble(0);
const auto gas_rate = record.getItem("GAS_PRODUCTION_RATE").getSIDouble(0);
const auto water_rate = record.getItem("WATER_PRODUCTION_RATE").getSIDouble(0);
const auto resv_rate = record.getItem("RES_FLUID_VOL_PRODUCTION_RATE").getSIDouble(0);
const auto glift_rate = record.getItem("LIFT_GAS_SUPPLY_RATE").getSIDouble(0);

for (const auto& group_name : group_names) {
const bool is_field { group_name == "FIELD" } ;
if (is_field) {
std::string msg_fmt = "Problem with {keyword}\n"
"In {file} line {line}\n"
"GSATPROD group cannot be named FIELD ";
const auto& parseContext = handlerContext.parseContext;
auto& errors = handlerContext.errors;
parseContext.handleError(ParseContext::SCHEDULE_GROUP_ERROR, msg_fmt, keyword.location(), errors);
}
new_gsatprod.add(group_name, oil_rate, gas_rate, water_rate, resv_rate, glift_rate);
}
}
handlerContext.state().gsatprod.update( std::move(new_gsatprod) );
}

void handleGCONSALE(HandlerContext& handlerContext)
{
auto new_gconsale = handlerContext.state().gconsale.get();
Expand Down Expand Up @@ -452,6 +486,7 @@ getGroupHandlers()
{ "GCONPROD", &handleGCONPROD },
{ "GCONSALE", &handleGCONSALE },
{ "GCONSUMP", &handleGCONSUMP },
{ "GSATPROD", &handleGSATPROD },
{ "GECON" , &handleGECON },
{ "GEFAC" , &handleGEFAC },
{ "GPMAINT" , &handleGPMAINT },
Expand Down
2 changes: 2 additions & 0 deletions opm/input/eclipse/Schedule/Schedule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <opm/input/eclipse/Schedule/Action/SimulatorUpdate.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSale.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSump.hpp>
#include <opm/input/eclipse/Schedule/Group/GSatProd.hpp>
#include <opm/input/eclipse/Schedule/Group/GroupEconProductionLimits.hpp>
#include <opm/input/eclipse/Schedule/Group/GTNode.hpp>
#include <opm/input/eclipse/Schedule/Group/GuideRateConfig.hpp>
Expand Down Expand Up @@ -2374,6 +2375,7 @@ void Schedule::create_first(const time_point& start_time, const std::optional<ti
sched_state.wtest_config.update( WellTestConfig() );
sched_state.gconsale.update( GConSale() );
sched_state.gconsump.update( GConSump() );
sched_state.gsatprod.update( GSatProd() );
sched_state.gecon.update( GroupEconProductionLimits() );
sched_state.wlist_manager.update( WListManager() );
sched_state.network.update( Network::ExtNetwork() );
Expand Down
1 change: 1 addition & 0 deletions opm/input/eclipse/Schedule/Schedule.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,7 @@ namespace Opm
this->template pack_unpack<WellTestConfig>(serializer);
this->template pack_unpack<GConSale>(serializer);
this->template pack_unpack<GConSump>(serializer);
this->template pack_unpack<GSatProd>(serializer);
this->template pack_unpack<GroupEconProductionLimits>(serializer);
this->template pack_unpack<WListManager>(serializer);
this->template pack_unpack<Network::ExtNetwork>(serializer);
Expand Down
3 changes: 3 additions & 0 deletions opm/input/eclipse/Schedule/ScheduleState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSale.hpp>
#include <opm/input/eclipse/Schedule/Group/GConSump.hpp>
#include <opm/input/eclipse/Schedule/Group/GSatProd.hpp>
#include <opm/input/eclipse/Schedule/Group/GroupEconProductionLimits.hpp>
#include <opm/input/eclipse/Schedule/Group/GuideRateConfig.hpp>
#include <opm/input/eclipse/Schedule/Network/Balance.hpp>
Expand Down Expand Up @@ -307,6 +308,7 @@ bool ScheduleState::operator==(const ScheduleState& other) const {
this->group_order.get() == other.group_order.get() &&
this->gconsale.get() == other.gconsale.get() &&
this->gconsump.get() == other.gconsump.get() &&
this->gsatprod.get() == other.gsatprod.get() &&
this->wlist_manager.get() == other.wlist_manager.get() &&
this->rpt_config.get() == other.rpt_config.get() &&
this->actions.get() == other.actions.get() &&
Expand Down Expand Up @@ -353,6 +355,7 @@ ScheduleState ScheduleState::serializationTestObject() {
ts.wtest_config.update( WellTestConfig::serializationTestObject() );
ts.gconsump.update( GConSump::serializationTestObject() );
ts.gconsale.update( GConSale::serializationTestObject() );
ts.gsatprod.update( GSatProd::serializationTestObject() );
ts.gecon.update( GroupEconProductionLimits::serializationTestObject() );
ts.wlist_manager.update( WListManager::serializationTestObject() );
ts.rpt_config.update( RPTConfig::serializationTestObject() );
Expand Down
4 changes: 4 additions & 0 deletions opm/input/eclipse/Schedule/ScheduleState.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ namespace Opm {
class GasLiftOpt;
class GConSale;
class GConSump;
class GSatProd;
class GroupEconProductionLimits;
class GroupOrder;
class GuideRateConfig;
Expand Down Expand Up @@ -385,6 +386,7 @@ namespace Opm {

ptr_member<GConSale> gconsale;
ptr_member<GConSump> gconsump;
ptr_member<GSatProd> gsatprod;
ptr_member<GroupEconProductionLimits> gecon;
ptr_member<GuideRateConfig> guide_rate;

Expand Down Expand Up @@ -428,6 +430,8 @@ namespace Opm {
return this->gconsale;
else if constexpr ( std::is_same_v<T, GConSump> )
return this->gconsump;
else if constexpr ( std::is_same_v<T, GSatProd> )
return this->gsatprod;
else if constexpr ( std::is_same_v<T, GroupEconProductionLimits> )
return this->gecon;
else if constexpr ( std::is_same_v<T, WListManager> )
Expand Down
5 changes: 5 additions & 0 deletions opm/input/eclipse/share/keywords/000_Eclipse100/G/GSATPROD
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,31 @@
{
"name": "OIL_PRODUCTION_RATE",
"value_type": "DOUBLE",
"dimension": "LiquidSurfaceVolume/Time",
"default": 0
},
{
"name": "WATER_PRODUCTION_RATE",
"value_type": "DOUBLE",
"dimension": "LiquidSurfaceVolume/Time",
"default": 0
},
{
"name": "GAS_PRODUCTION_RATE",
"value_type": "DOUBLE",
"dimension": "GasSurfaceVolume/Time",
"default": 0
},
{
"name": "RES_FLUID_VOL_PRODUCTION_RATE",
"value_type": "DOUBLE",
"dimension": "ReservoirVolume/Time",
"default": 0
},
{
"name": "LIFT_GAS_SUPPLY_RATE",
"value_type": "DOUBLE",
"dimension": "GasSurfaceVolume/Time",
"default": 0
},
{
Expand Down
33 changes: 32 additions & 1 deletion opm/output/eclipse/Summary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@

#include <opm/input/eclipse/Schedule/Action/Actions.hpp>
#include <opm/input/eclipse/Schedule/GasLiftOpt.hpp>
#include <opm/input/eclipse/Schedule/Group/GSatProd.hpp>
#include <opm/input/eclipse/Schedule/Group/Group.hpp>
#include <opm/input/eclipse/Schedule/MSW/Segment.hpp>
#include <opm/input/eclipse/Schedule/MSW/WellSegments.hpp>
Expand Down Expand Up @@ -655,6 +656,29 @@ alq_type(const Opm::ScheduleState& sched_state,
return sched_state.vfpprod(vfp_table_number).getALQType();
}

inline double accum_groups(const rt phase, const Opm::Schedule& schedule, const size_t sim_step, const std::string& gr_name)
{
double sum = 0.0;
if (!schedule.hasGroup(gr_name, sim_step)) {
return sum;
}
const auto& top_group = schedule.getGroup(gr_name, sim_step);
for (const auto& child : top_group.groups()) {
sum += accum_groups(phase, schedule, sim_step, child);
}
const auto& gsatprod = schedule[sim_step].gsatprod.get();
if (gsatprod.has(gr_name)) {
const auto& gs = gsatprod.get(gr_name);
if (phase == rt::oil)
sum += gs.oil_rate;
if (phase == rt::gas)
sum += gs.gas_rate;
if (phase == rt::wat)
sum += gs.water_rate;
}
return sum;
}

inline quantity artificial_lift_quantity( const fn_args& args ) {
// Note: This function is intentionally supported only at the well level
// (meaning there's no loop over args.schedule_wells by intention). Its
Expand Down Expand Up @@ -773,13 +797,19 @@ inline quantity rate( const fn_args& args ) {
sum *= -1.0;
}

const auto& gsatprod = args.schedule[args.sim_step].gsatprod.get();
if (!injection && gsatprod.size() > 0 && !args.group_name.empty()) {
sum += accum_groups(phase, args.schedule, args.sim_step, args.group_name);
}

if (phase == rt::polymer || phase == rt::brine) {
return { sum, measure::mass_rate };
}

return { sum, rate_unit< phase >() };
}


template <bool injection = true>
inline quantity filtrate_connection_quantities( const fn_args& args ) {

Expand Down Expand Up @@ -3253,8 +3283,9 @@ namespace Evaluator {
(this->node_.category == Cat::Group) ||
(this->node_.category == Cat::Node);

const auto def_gr_name = this->node_.category == Cat::Field ? std::string{"FIELD"} : std::string{""};
return need_grp_name
? this->node_.wgname : std::string{""};
? this->node_.wgname : def_gr_name;
}

bool use_number() const
Expand Down
Loading

0 comments on commit 85d841e

Please sign in to comment.