From 33dcc0bd506a53a0d9de035f9aceb5dc07da63c8 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Mon, 19 Feb 2024 12:04:18 +0100 Subject: [PATCH] FractionCalculator: put in separate translation unit --- CMakeLists_files.cmake | 2 + opm/simulators/wells/FractionCalculator.cpp | 177 ++++++++++++++++++++ opm/simulators/wells/FractionCalculator.hpp | 77 +++++++++ opm/simulators/wells/WellGroupControls.cpp | 1 + opm/simulators/wells/WellGroupHelpers.cpp | 125 +------------- opm/simulators/wells/WellGroupHelpers.hpp | 33 ---- 6 files changed, 258 insertions(+), 157 deletions(-) create mode 100644 opm/simulators/wells/FractionCalculator.cpp create mode 100644 opm/simulators/wells/FractionCalculator.hpp diff --git a/CMakeLists_files.cmake b/CMakeLists_files.cmake index 404779c3e..b361864ac 100644 --- a/CMakeLists_files.cmake +++ b/CMakeLists_files.cmake @@ -98,6 +98,7 @@ list (APPEND MAIN_SOURCE_FILES opm/simulators/wells/BlackoilWellModelGuideRates.cpp opm/simulators/wells/BlackoilWellModelRestart.cpp opm/simulators/wells/ConnFiltrateData.cpp + opm/simulators/wells/FractionCalculator.cpp opm/simulators/wells/GasLiftCommon.cpp opm/simulators/wells/GasLiftGroupInfo.cpp opm/simulators/wells/GasLiftSingleWellGeneric.cpp @@ -565,6 +566,7 @@ list (APPEND PUBLIC_HEADER_FILES opm/simulators/wells/BlackoilWellModelGuideRates.hpp opm/simulators/wells/BlackoilWellModelRestart.hpp opm/simulators/wells/ConnFiltrateData.hpp + opm/simulators/wells/FractionCalculator.hpp opm/simulators/wells/GasLiftCommon.hpp opm/simulators/wells/GasLiftGroupInfo.hpp opm/simulators/wells/GasLiftSingleWellGeneric.hpp diff --git a/opm/simulators/wells/FractionCalculator.cpp b/opm/simulators/wells/FractionCalculator.cpp new file mode 100644 index 000000000..2a7a4f574 --- /dev/null +++ b/opm/simulators/wells/FractionCalculator.cpp @@ -0,0 +1,177 @@ +/* + Copyright 2019 Norce. + Copyright 2020 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 . +*/ + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +namespace Opm::WellGroupHelpers { + +FractionCalculator::FractionCalculator(const Schedule& schedule, + const WellState& well_state, + const GroupState& group_state, + const int report_step, + const GuideRate* guide_rate, + const GuideRateModel::Target target, + const PhaseUsage& pu, + const bool is_producer, + const Phase injection_phase) + : schedule_(schedule) + , well_state_(well_state) + , group_state_(group_state) + , report_step_(report_step) + , guide_rate_(guide_rate) + , target_(target) + , pu_(pu) + , is_producer_(is_producer) + , injection_phase_(injection_phase) +{ +} + +double FractionCalculator::fraction(const std::string& name, + const std::string& control_group_name, + const bool always_include_this) +{ + double fraction = 1.0; + std::string current = name; + while (current != control_group_name) { + fraction *= localFraction(current, always_include_this ? name : ""); + current = parent(current); + } + return fraction; +} + +double FractionCalculator::localFraction(const std::string& name, + const std::string& always_included_child) +{ + const double my_guide_rate = guideRate(name, always_included_child); + const Group& parent_group = schedule_.getGroup(parent(name), report_step_); + const double total_guide_rate = guideRateSum(parent_group, always_included_child); + + // the total guide gate is the same as my_guide rate + // the well/group is probably on its own, i.e. return 1 + // even is its guide_rate is zero + const double guide_rate_epsilon = 1e-12; + if ( std::abs(my_guide_rate - total_guide_rate) < guide_rate_epsilon ) + return 1.0; + + assert(total_guide_rate > my_guide_rate); + return my_guide_rate / total_guide_rate; +} + +std::string FractionCalculator::parent(const std::string& name) +{ + if (schedule_.hasWell(name)) { + return schedule_.getWell(name, report_step_).groupName(); + } else { + return schedule_.getGroup(name, report_step_).parent(); + } +} + +double FractionCalculator::guideRateSum(const Group& group, + const std::string& always_included_child) +{ + double total_guide_rate = 0.0; + for (const std::string& child_group : group.groups()) { + bool included = (child_group == always_included_child); + if (is_producer_) { + const auto ctrl = this->group_state_.production_control(child_group); + included |= (ctrl == Group::ProductionCMode::FLD) || + (ctrl == Group::ProductionCMode::NONE); + } else { + const auto ctrl = this->group_state_.injection_control(child_group, + this->injection_phase_); + included |= (ctrl == Group::InjectionCMode::FLD) || + (ctrl == Group::InjectionCMode::NONE); + } + if (included) { + total_guide_rate += guideRate(child_group, always_included_child); + } + } + for (const std::string& child_well : group.wells()) { + bool included = (child_well == always_included_child); + if (is_producer_) { + included |= well_state_.isProductionGrup(child_well); + } else { + included |= well_state_.isInjectionGrup(child_well); + } + + if (included) { + total_guide_rate += guideRate(child_well, always_included_child); + } + } + return total_guide_rate; +} + +double FractionCalculator::guideRate(const std::string& name, const std::string& always_included_child) +{ + if (schedule_.hasWell(name, report_step_)) { + return WellGroupHelpers::getGuideRate(name, schedule_, well_state_, group_state_, + report_step_, guide_rate_, target_, pu_); + } else { + if (groupControlledWells(name, always_included_child) > 0) { + if (is_producer_ && guide_rate_->has(name)) { + return guide_rate_->get(name, target_, getGroupRateVector(name)); + } else if (!is_producer_ && guide_rate_->has(name, injection_phase_)) { + return guide_rate_->get(name, injection_phase_); + } else { + // We are a group, with default guide rate. + // Compute guide rate by accumulating our children's guide rates. + const Group& group = schedule_.getGroup(name, report_step_); + const double eff = group.getGroupEfficiencyFactor(); + return eff * guideRateSum(group, always_included_child); + } + } else { + // No group-controlled subordinate wells. + return 0.0; + } + } +} + +int FractionCalculator::groupControlledWells(const std::string& group_name, + const std::string& always_included_child) +{ + return WellGroupHelpers::groupControlledWells(schedule_, + well_state_, + this->group_state_, + report_step_, + group_name, + always_included_child, + is_producer_, + injection_phase_); +} + +GuideRate::RateVector FractionCalculator::getGroupRateVector(const std::string& group_name) +{ + assert(is_producer_); + return WellGroupHelpers::getProductionGroupRateVector(this->group_state_, + this->pu_, + group_name); +} + +} // namespace Opm::WGHelpers diff --git a/opm/simulators/wells/FractionCalculator.hpp b/opm/simulators/wells/FractionCalculator.hpp new file mode 100644 index 000000000..9d83c9ced --- /dev/null +++ b/opm/simulators/wells/FractionCalculator.hpp @@ -0,0 +1,77 @@ +/* + Copyright 2019 Norce. + + 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 . +*/ + + +#ifndef OPM_FRACTION_CALCULATOR_HEADER_INCLUDED +#define OPM_FRACTION_CALCULATOR_HEADER_INCLUDED + +#include + +#include + +namespace Opm { +class GroupState; +struct PhaseUsage; +class Schedule; +class WellState; +} + +namespace Opm::WellGroupHelpers { + +class FractionCalculator +{ +public: + FractionCalculator(const Schedule& schedule, + const WellState& well_state, + const GroupState& group_state, + const int report_step, + const GuideRate* guide_rate, + const GuideRateModel::Target target, + const PhaseUsage& pu, + const bool is_producer, + const Phase injection_phase); + double fraction(const std::string& name, + const std::string& control_group_name, + const bool always_include_this); + double localFraction(const std::string& name, + const std::string& always_included_child); + +private: + std::string parent(const std::string& name); + double guideRateSum(const Group& group, + const std::string& always_included_child); + double guideRate(const std::string& name, + const std::string& always_included_child); + int groupControlledWells(const std::string& group_name, + const std::string& always_included_child); + GuideRate::RateVector getGroupRateVector(const std::string& group_name); + const Schedule& schedule_; + const WellState& well_state_; + const GroupState& group_state_; + int report_step_; + const GuideRate* guide_rate_; + GuideRateModel::Target target_; + const PhaseUsage& pu_; + bool is_producer_; + Phase injection_phase_; +}; + +} // namespace Opm::WellGroupHelpers + +#endif // OPM_FRACTION_CALCULATOR_HEADER_INCLUDED diff --git a/opm/simulators/wells/WellGroupControls.cpp b/opm/simulators/wells/WellGroupControls.cpp index dba8bc0e1..8856297f7 100644 --- a/opm/simulators/wells/WellGroupControls.cpp +++ b/opm/simulators/wells/WellGroupControls.cpp @@ -30,6 +30,7 @@ #include +#include #include #include #include diff --git a/opm/simulators/wells/WellGroupHelpers.cpp b/opm/simulators/wells/WellGroupHelpers.cpp index 053c12a66..7c0711b0d 100644 --- a/opm/simulators/wells/WellGroupHelpers.cpp +++ b/opm/simulators/wells/WellGroupHelpers.cpp @@ -35,6 +35,7 @@ #include #include +#include #include #include #include @@ -1073,130 +1074,6 @@ namespace WellGroupHelpers return num_wells; } - FractionCalculator::FractionCalculator(const Schedule& schedule, - const WellState& well_state, - const GroupState& group_state, - const int report_step, - const GuideRate* guide_rate, - const GuideRateModel::Target target, - const PhaseUsage& pu, - const bool is_producer, - const Phase injection_phase) - : schedule_(schedule) - , well_state_(well_state) - , group_state_(group_state) - , report_step_(report_step) - , guide_rate_(guide_rate) - , target_(target) - , pu_(pu) - , is_producer_(is_producer) - , injection_phase_(injection_phase) - { - } - double FractionCalculator::fraction(const std::string& name, - const std::string& control_group_name, - const bool always_include_this) - { - double fraction = 1.0; - std::string current = name; - while (current != control_group_name) { - fraction *= localFraction(current, always_include_this ? name : ""); - current = parent(current); - } - return fraction; - } - double FractionCalculator::localFraction(const std::string& name, const std::string& always_included_child) - { - const double my_guide_rate = guideRate(name, always_included_child); - const Group& parent_group = schedule_.getGroup(parent(name), report_step_); - const double total_guide_rate = guideRateSum(parent_group, always_included_child); - - // the total guide gate is the same as my_guide rate - // the well/group is probably on its own, i.e. return 1 - // even is its guide_rate is zero - const double guide_rate_epsilon = 1e-12; - if ( std::abs(my_guide_rate - total_guide_rate) < guide_rate_epsilon ) - return 1.0; - - assert(total_guide_rate > my_guide_rate); - return my_guide_rate / total_guide_rate; - } - std::string FractionCalculator::parent(const std::string& name) - { - if (schedule_.hasWell(name)) { - return schedule_.getWell(name, report_step_).groupName(); - } else { - return schedule_.getGroup(name, report_step_).parent(); - } - } - double FractionCalculator::guideRateSum(const Group& group, const std::string& always_included_child) - { - double total_guide_rate = 0.0; - for (const std::string& child_group : group.groups()) { - bool included = (child_group == always_included_child); - if (is_producer_) { - const auto ctrl = this->group_state_.production_control(child_group); - included = included || (ctrl == Group::ProductionCMode::FLD) || (ctrl == Group::ProductionCMode::NONE); - } else { - const auto ctrl = this->group_state_.injection_control(child_group, this->injection_phase_); - included = included || (ctrl == Group::InjectionCMode::FLD) || (ctrl == Group::InjectionCMode::NONE); - } - if (included) { - total_guide_rate += guideRate(child_group, always_included_child); - } - } - for (const std::string& child_well : group.wells()) { - bool included = (child_well == always_included_child); - if (is_producer_) { - included = included || well_state_.isProductionGrup(child_well); - } else { - included = included || well_state_.isInjectionGrup(child_well); - } - - if (included) { - total_guide_rate += guideRate(child_well, always_included_child); - } - } - return total_guide_rate; - } - double FractionCalculator::guideRate(const std::string& name, const std::string& always_included_child) - { - if (schedule_.hasWell(name, report_step_)) { - return getGuideRate(name, schedule_, well_state_, group_state_, - report_step_, guide_rate_, target_, pu_); - } else { - if (groupControlledWells(name, always_included_child) > 0) { - if (is_producer_ && guide_rate_->has(name)) { - return guide_rate_->get(name, target_, getGroupRateVector(name)); - } else if (!is_producer_ && guide_rate_->has(name, injection_phase_)) { - return guide_rate_->get(name, injection_phase_); - } else { - // We are a group, with default guide rate. - // Compute guide rate by accumulating our children's guide rates. - const Group& group = schedule_.getGroup(name, report_step_); - const double eff = group.getGroupEfficiencyFactor(); - return eff * guideRateSum(group, always_included_child); - } - } else { - // No group-controlled subordinate wells. - return 0.0; - } - } - } - int FractionCalculator::groupControlledWells(const std::string& group_name, - const std::string& always_included_child) - { - return ::Opm::WellGroupHelpers::groupControlledWells( - schedule_, well_state_, this->group_state_, report_step_, group_name, always_included_child, is_producer_, injection_phase_); - } - - GuideRate::RateVector FractionCalculator::getGroupRateVector(const std::string& group_name) - { - assert(is_producer_); - return getProductionGroupRateVector(this->group_state_, this->pu_, group_name); - } - - std::vector groupChainTopBot(const std::string& bottom, const std::string& top, const Schedule& schedule, const int report_step) { diff --git a/opm/simulators/wells/WellGroupHelpers.hpp b/opm/simulators/wells/WellGroupHelpers.hpp index c48862db1..573dc00b7 100644 --- a/opm/simulators/wells/WellGroupHelpers.hpp +++ b/opm/simulators/wells/WellGroupHelpers.hpp @@ -235,39 +235,6 @@ namespace WellGroupHelpers const Phase injection_phase); - class FractionCalculator - { - public: - FractionCalculator(const Schedule& schedule, - const WellState& well_state, - const GroupState& group_state, - const int report_step, - const GuideRate* guide_rate, - const GuideRateModel::Target target, - const PhaseUsage& pu, - const bool is_producer, - const Phase injection_phase); - double fraction(const std::string& name, const std::string& control_group_name, const bool always_include_this); - double localFraction(const std::string& name, const std::string& always_included_child); - - private: - std::string parent(const std::string& name); - double guideRateSum(const Group& group, const std::string& always_included_child); - double guideRate(const std::string& name, const std::string& always_included_child); - int groupControlledWells(const std::string& group_name, const std::string& always_included_child); - GuideRate::RateVector getGroupRateVector(const std::string& group_name); - const Schedule& schedule_; - const WellState& well_state_; - const GroupState& group_state_; - int report_step_; - const GuideRate* guide_rate_; - GuideRateModel::Target target_; - const PhaseUsage& pu_; - bool is_producer_; - Phase injection_phase_; - }; - - std::pair checkGroupConstraintsInj(const std::string& name, const std::string& parent, const Group& group,