Support NEFAC and clean up implementation

This commit is contained in:
Vegard Kippe
2025-01-20 13:24:01 +01:00
parent cc68f7246a
commit 44a87f8e65
7 changed files with 52 additions and 27 deletions

View File

@@ -78,6 +78,12 @@ const SupportedKeywordItems<double>&
fullySupported()
{
static const SupportedKeywordItems<double> fully_supported_keywords_double = {
{
"NEFAC",
{
{2,{true, [](double x) { return x > 0 && x <= 1.0; }, "NEFAC(EFF_FACTOR: Efficiency must be in the range (0,1]"}}, // NETWORK_EFF_FACTOR
},
},
{
"WPIMULT",
{

View File

@@ -397,7 +397,6 @@ const KeywordValidation::UnsupportedKeywords& unsupportedKeywords()
{"NARROW", {true, std::nullopt}},
{"NCONSUMP", {true, std::nullopt}},
{"NCOMPS", {false, std::nullopt}},
{"NEFAC", {true, std::nullopt}},
{"NETCOMPA", {true, std::nullopt}},
{"NEXT", {false, std::nullopt}},
{"NEXTSTPL", {true, std::nullopt}},

View File

@@ -1373,6 +1373,10 @@ updateAndCommunicateGroupData(const int reportStepIdx,
reportStepIdx,
well_state_nupcol,
this->groupState());
WellGroupHelpers<Scalar>::updateNetworkLeafNodeProductionRates(schedule(),
reportStepIdx,
well_state_nupcol,
this->groupState());
WellGroupHelpers<Scalar>::updateGroupProductionRates(fieldGroup,
schedule(),

View File

@@ -41,7 +41,7 @@ GroupState<Scalar> GroupState<Scalar>::serializationTestObject()
{
GroupState result(3);
result.m_production_rates = {{"test1", {1.0, 2.0}}};
result.m_network_production_rates={{"test1", {1.0, 20}}};
result.m_network_leaf_node_production_rates={{"test1", {1.0, 20}}};
result.production_controls = {{"test2", Group::ProductionCMode::LRAT}};
result.prod_red_rates = {{"test3", {3.0, 4.0, 5.0}}};
result.inj_red_rates = {{"test4", {6.0, 7.0}}};
@@ -62,7 +62,7 @@ template<class Scalar>
bool GroupState<Scalar>::operator==(const GroupState& other) const
{
return this->m_production_rates == other.m_production_rates &&
this->m_network_production_rates == other.m_network_production_rates &&
this->m_network_leaf_node_production_rates == other.m_network_leaf_node_production_rates &&
this->production_controls == other.production_controls &&
this->prod_red_rates == other.prod_red_rates &&
this->inj_red_rates == other.inj_red_rates &&
@@ -86,10 +86,10 @@ bool GroupState<Scalar>::has_production_rates(const std::string& gname) const
}
template<class Scalar>
bool GroupState<Scalar>::has_network_production_rates(const std::string& gname) const
bool GroupState<Scalar>::has_network_leaf_node_production_rates(const std::string& gname) const
{
auto group_iter = this->m_network_production_rates.find(gname);
return (group_iter != this->m_network_production_rates.end());
auto group_iter = this->m_network_leaf_node_production_rates.find(gname);
return (group_iter != this->m_network_leaf_node_production_rates.end());
}
template<class Scalar>
@@ -103,13 +103,13 @@ void GroupState<Scalar>::update_production_rates(const std::string& gname,
}
template<class Scalar>
void GroupState<Scalar>::update_network_production_rates(const std::string& gname,
void GroupState<Scalar>::update_network_leaf_node_production_rates(const std::string& gname,
const std::vector<Scalar>& rates)
{
if (rates.size() != this->num_phases)
throw std::logic_error("Wrong number of phases");
this->m_network_production_rates[gname] = rates;
this->m_network_leaf_node_production_rates[gname] = rates;
}
template<class Scalar>
@@ -125,10 +125,10 @@ GroupState<Scalar>::production_rates(const std::string& gname) const
template<class Scalar>
const std::vector<Scalar>&
GroupState<Scalar>::network_production_rates(const std::string& gname) const
GroupState<Scalar>::network_leaf_node_production_rates(const std::string& gname) const
{
auto group_iter = this->m_network_production_rates.find(gname);
if (group_iter == this->m_network_production_rates.end())
auto group_iter = this->m_network_leaf_node_production_rates.find(gname);
if (group_iter == this->m_network_leaf_node_production_rates.end())
throw std::logic_error("No such group");
return group_iter->second;

View File

@@ -50,13 +50,13 @@ public:
bool operator==(const GroupState& other) const;
bool has_production_rates(const std::string& gname) const;
bool has_network_production_rates(const std::string& gname) const;
bool has_network_leaf_node_production_rates(const std::string& gname) const;
void update_production_rates(const std::string& gname,
const std::vector<Scalar>& rates);
void update_network_production_rates(const std::string& gname,
void update_network_leaf_node_production_rates(const std::string& gname,
const std::vector<Scalar>& rates);
const std::vector<Scalar>& production_rates(const std::string& gname) const;
const std::vector<Scalar>& network_production_rates(const std::string& gname) const;
const std::vector<Scalar>& network_leaf_node_production_rates(const std::string& gname) const;
void update_well_group_thp(const std::string& gname, const double& thp);
Scalar well_group_thp(const std::string& gname) const;
@@ -134,7 +134,7 @@ public:
auto forAllGroupData = [&](auto& func) {
iterateContainer(m_production_rates, func);
iterateContainer(m_network_production_rates, func);
iterateContainer(m_network_leaf_node_production_rates, func);
iterateContainer(prod_red_rates, func);
iterateContainer(inj_red_rates, func);
iterateContainer(inj_resv_rates, func);
@@ -192,7 +192,7 @@ public:
{
serializer(num_phases);
serializer(m_production_rates);
serializer(m_network_production_rates);
serializer(m_network_leaf_node_production_rates);
serializer(production_controls);
serializer(group_thp);
serializer(prod_red_rates);
@@ -211,7 +211,7 @@ public:
private:
std::size_t num_phases{};
std::map<std::string, std::vector<Scalar>> m_production_rates;
std::map<std::string, std::vector<Scalar>> m_network_production_rates;
std::map<std::string, std::vector<Scalar>> m_network_leaf_node_production_rates;
std::map<std::string, Group::ProductionCMode> production_controls;
std::map<std::string, std::vector<Scalar>> prod_red_rates;
std::map<std::string, std::vector<Scalar>> inj_red_rates;

View File

@@ -742,16 +742,29 @@ updateGroupProductionRates(const Group& group,
rates[phase] = sumWellPhaseRates(false, group, schedule, wellState, reportStepIdx, phase, /*isInjector*/ false);
}
group_state.update_production_rates(group.name(), rates);
}
template<class Scalar>
void WellGroupHelpers<Scalar>::
updateNetworkLeafNodeProductionRates(const Schedule& schedule,
const int reportStepIdx,
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state)
{
const auto& network = schedule[reportStepIdx].network();
if (network.active()) {
std::vector<Scalar> network_rates = rates;
if (network.needs_instantaneous_rates(schedule, reportStepIdx)) {
for (int phase = 0; phase < np; ++phase) {
network_rates[phase] = sumWellPhaseRates(false, group, schedule, wellState, reportStepIdx, phase, /*isInjector*/ false, /*network*/ true);
const int np = wellState.numPhases();
for (const auto& group_name : network.leaf_nodes()) {
assert(schedule[reportStepIdx].groups.has(group_name));
const auto& group = schedule[reportStepIdx].groups.get(group_name);
std::vector<Scalar> network_rates(np, 0.0);
if (group.numWells() > 0) {
for (int phase = 0; phase < np; ++phase) {
network_rates[phase] = sumWellPhaseRates(false, group, schedule, wellState, reportStepIdx, phase, /*isInjector*/ false, /*network*/ true);
}
}
group_state.update_network_leaf_node_production_rates(group_name, network_rates);
}
group_state.update_network_production_rates(group.name(), network_rates);
}
}
@@ -938,8 +951,8 @@ computeNetworkPressures(const Network::ExtNetwork& network,
node_inflows[node] = zero_rates;
continue;
}
node_inflows[node] = group_state.network_production_rates(node);
node_inflows[node] = group_state.network_leaf_node_production_rates(node);
// Add the ALQ amounts to the gas rates if requested.
if (network.node(node).add_gas_lift_gas()) {
const auto& group = schedule.getGroup(node, report_time_step);
@@ -966,10 +979,7 @@ computeNetworkPressures(const Network::ExtNetwork& network,
std::vector<Scalar>& up = node_inflows[(*upbranch).uptree_node()];
const std::vector<Scalar>& down = node_inflows[node];
// @TODO@ Also support NEFAC (for nodes that do not correspond to groups)
double efficiency = 1.0;
if (schedule.hasGroup(node, report_time_step)) {
efficiency = schedule.getGroup(node, report_time_step).getGroupEfficiencyFactor(/*network*/ true);
}
const double efficiency = network.node(node).efficiency();
if (up.empty()) {
up = std::vector<Scalar>(down.size(), 0.0);
}

View File

@@ -200,6 +200,12 @@ public:
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state);
static void updateNetworkLeafNodeProductionRates(const Schedule& schedule,
const int reportStepIdx,
const WellState<Scalar>& wellState,
GroupState<Scalar>& group_state);
static void updateWellRatesFromGroupTargetScale(const Scalar scale,
const Group& group,
const Schedule& schedule,