changed: move calculateBhpFromThp to WellBhpThpCalculator

This commit is contained in:
Arne Morten Kvarving 2022-10-19 09:55:14 +02:00
parent 0577516cfe
commit 796aa51e79
7 changed files with 126 additions and 79 deletions

View File

@ -1229,7 +1229,12 @@ assembleControlEq(const WellState& well_state,
// Setup function for evaluation of BHP from THP (used only if needed).
auto bhp_from_thp = [&]() {
const auto rates = getRates();
return baseif_.calculateBhpFromThp(well_state, rates, well, summaryState, rho, deferred_logger);
return WellBhpThpCalculator(baseif_).calculateBhpFromThp(well_state,
rates,
well,
summaryState,
rho,
deferred_logger);
};
// Call generic implementation.
baseif_.assembleControlEqInj(well_state,
@ -1247,7 +1252,12 @@ assembleControlEq(const WellState& well_state,
const auto rates = getRates();
// Setup function for evaluation of BHP from THP (used only if needed).
auto bhp_from_thp = [&]() {
return baseif_.calculateBhpFromThp(well_state, rates, well, summaryState, rho, deferred_logger);
return WellBhpThpCalculator(baseif_).calculateBhpFromThp(well_state,
rates,
well,
summaryState,
rho,
deferred_logger);
};
// Call generic implementation.
baseif_.assembleControlEqProd(well_state,

View File

@ -394,7 +394,12 @@ assembleControlEq(const WellState& well_state,
// Setup function for evaluation of BHP from THP (used only if needed).
auto bhp_from_thp = [&]() {
const auto rates = getRates();
return baseif_.calculateBhpFromThp(well_state, rates, well, summaryState, this->getRho(), deferred_logger);
return WellBhpThpCalculator(baseif_).calculateBhpFromThp(well_state,
rates,
well,
summaryState,
this->getRho(),
deferred_logger);
};
// Call generic implementation.
const auto& inj_controls = well.injectionControls(summaryState);
@ -413,7 +418,12 @@ assembleControlEq(const WellState& well_state,
const auto rates = getRates();
// Setup function for evaluation of BHP from THP (used only if needed).
auto bhp_from_thp = [&]() {
return baseif_.calculateBhpFromThp(well_state, rates, well, summaryState, this->getRho(), deferred_logger);
return WellBhpThpCalculator(baseif_).calculateBhpFromThp(well_state,
rates,
well,
summaryState,
this->getRho(),
deferred_logger);
};
// Call generic implementation.
const auto& prod_controls = well.productionControls(summaryState);

View File

@ -29,6 +29,8 @@
#include <opm/input/eclipse/Schedule/VFPInjTable.hpp>
#include <opm/input/eclipse/Schedule/Well/Well.hpp>
#include <opm/material/densead/Evaluation.hpp>
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <opm/simulators/wells/VFPProperties.hpp>
@ -259,6 +261,58 @@ void WellBhpThpCalculator::updateThp(const double rho,
ws.thp = this->calculateThpFromBhp(rates, ws.bhp, rho, alq_value(), deferred_logger);
}
template<class EvalWell>
EvalWell WellBhpThpCalculator::
calculateBhpFromThp(const WellState& well_state,
const std::vector<EvalWell>& rates,
const Well& well,
const SummaryState& summaryState,
const double rho,
DeferredLogger& deferred_logger) const
{
// TODO: when well is under THP control, the BHP is dependent on the rates,
// the well rates is also dependent on the BHP, so it might need to do some iteration.
// However, when group control is involved, change of the rates might impacts other wells
// so iterations on a higher level will be required. Some investigation might be needed when
// we face problems under THP control.
assert(int(rates.size()) == 3); // the vfp related only supports three phases now.
static constexpr int Gas = BlackoilPhases::Vapour;
static constexpr int Oil = BlackoilPhases::Liquid;
static constexpr int Water = BlackoilPhases::Aqua;
const EvalWell aqua = rates[Water];
const EvalWell liquid = rates[Oil];
const EvalWell vapour = rates[Gas];
// pick the reference density
// typically the reference in the top layer
if (well_.isInjector() )
{
const auto& controls = well.injectionControls(summaryState);
const double vfp_ref_depth = well_.vfpProperties()->getInj()->getTable(controls.vfp_table_number).getDatumDepth();
const double dp = wellhelpers::computeHydrostaticCorrection(well_.refDepth(), vfp_ref_depth, rho, well_.gravity());
return well_.vfpProperties()->getInj()->bhp(controls.vfp_table_number, aqua, liquid, vapour, well_.getTHPConstraint(summaryState)) - dp;
}
else if (well_.isProducer()) {
const auto& controls = well.productionControls(summaryState);
const double vfp_ref_depth = well_.vfpProperties()->getProd()->getTable(controls.vfp_table_number).getDatumDepth();
const double dp = wellhelpers::computeHydrostaticCorrection(well_.refDepth(), vfp_ref_depth, rho, well_.gravity());
const auto& wfr = well_.vfpProperties()->getExplicitWFR(controls.vfp_table_number, well_.indexOfWell());
const auto& gfr = well_.vfpProperties()->getExplicitGFR(controls.vfp_table_number, well_.indexOfWell());
const bool use_vfpexplicit = well_.useVfpExplicit();
return well_.vfpProperties()->getProd()->bhp(controls.vfp_table_number,
aqua, liquid, vapour,
well_.getTHPConstraint(summaryState),
well_.getALQ(well_state),
wfr, gfr, use_vfpexplicit) - dp;
}
else {
OPM_DEFLOG_THROW(std::logic_error, "Expected INJECTOR or PRODUCER for well " + well_.name(), deferred_logger);
}
}
template<class ErrorPolicy>
std::optional<double>
WellBhpThpCalculator::
@ -704,4 +758,29 @@ bruteForceBracket(const std::function<double(const double)>& eq,
return finding_bracket;
}
#define INSTANCE(...) \
template __VA_ARGS__ WellBhpThpCalculator:: \
calculateBhpFromThp<__VA_ARGS__>(const WellState&, \
const std::vector<__VA_ARGS__>&, \
const Well&, \
const SummaryState&, \
const double, \
DeferredLogger&) const;
INSTANCE(double)
INSTANCE(DenseAd::Evaluation<double,3,0u>)
INSTANCE(DenseAd::Evaluation<double,4,0u>)
INSTANCE(DenseAd::Evaluation<double,5,0u>)
INSTANCE(DenseAd::Evaluation<double,6,0u>)
INSTANCE(DenseAd::Evaluation<double,7,0u>)
INSTANCE(DenseAd::Evaluation<double,8,0u>)
INSTANCE(DenseAd::Evaluation<double,9,0u>)
INSTANCE(DenseAd::Evaluation<double,-1,4u>)
INSTANCE(DenseAd::Evaluation<double,-1,5u>)
INSTANCE(DenseAd::Evaluation<double,-1,6u>)
INSTANCE(DenseAd::Evaluation<double,-1,7u>)
INSTANCE(DenseAd::Evaluation<double,-1,8u>)
INSTANCE(DenseAd::Evaluation<double,-1,9u>)
INSTANCE(DenseAd::Evaluation<double,-1,10u>)
} // namespace Opm

View File

@ -34,6 +34,7 @@ namespace Opm
class DeferredLogger;
class SummaryState;
class Well;
class WellInterfaceGeneric;
class WellState;
@ -85,6 +86,14 @@ public:
WellState& well_state,
DeferredLogger& deferred_logger) const;
template<class EvalWell>
EvalWell calculateBhpFromThp(const WellState& well_state,
const std::vector<EvalWell>& rates,
const Well& well,
const SummaryState& summaryState,
const double rho,
DeferredLogger& deferred_logger) const;
private:
//! \brief Compute BHP from THP limit for an injector - implementation.
template<class ErrorPolicy>

View File

@ -260,52 +260,6 @@ assembleControlEqInj_(const WellState& well_state,
}
}
template<class FluidSystem>
template<class EvalWell>
EvalWell
WellInterfaceEval<FluidSystem>::
calculateBhpFromThp(const WellState& well_state,
const std::vector<EvalWell>& rates,
const Well& well,
const SummaryState& summaryState,
const double rho,
DeferredLogger& deferred_logger) const
{
// TODO: when well is under THP control, the BHP is dependent on the rates,
// the well rates is also dependent on the BHP, so it might need to do some iteration.
// However, when group control is involved, change of the rates might impacts other wells
// so iterations on a higher level will be required. Some investigation might be needed when
// we face problems under THP control.
assert(int(rates.size()) == 3); // the vfp related only supports three phases now.
const EvalWell aqua = rates[Water];
const EvalWell liquid = rates[Oil];
const EvalWell vapour = rates[Gas];
// pick the reference density
// typically the reference in the top layer
if (baseif_.isInjector() )
{
const auto& controls = well.injectionControls(summaryState);
const double vfp_ref_depth = baseif_.vfpProperties()->getInj()->getTable(controls.vfp_table_number).getDatumDepth();
const double dp = wellhelpers::computeHydrostaticCorrection(baseif_.refDepth(), vfp_ref_depth, rho, baseif_.gravity());
return baseif_.vfpProperties()->getInj()->bhp(controls.vfp_table_number, aqua, liquid, vapour, baseif_.getTHPConstraint(summaryState)) - dp;
}
else if (baseif_.isProducer()) {
const auto& controls = well.productionControls(summaryState);
const double vfp_ref_depth = baseif_.vfpProperties()->getProd()->getTable(controls.vfp_table_number).getDatumDepth();
const double dp = wellhelpers::computeHydrostaticCorrection(baseif_.refDepth(), vfp_ref_depth, rho, baseif_.gravity());
const auto& wfr = baseif_.vfpProperties()->getExplicitWFR(controls.vfp_table_number, baseif_.indexOfWell());
const auto& gfr = baseif_.vfpProperties()->getExplicitGFR(controls.vfp_table_number, baseif_.indexOfWell());
const bool use_vfpexplicit = baseif_.useVfpExplicit();
return baseif_.vfpProperties()->getProd()->bhp(controls.vfp_table_number, aqua, liquid, vapour, baseif_.getTHPConstraint(summaryState), baseif_.getALQ(well_state), wfr, gfr, use_vfpexplicit) - dp;
}
else {
OPM_DEFLOG_THROW(std::logic_error, "Expected INJECTOR or PRODUCER for well " + baseif_.name(), deferred_logger);
}
}
#define INSTANCE_METHODS(A,...) \
template void WellInterfaceEval<A>:: \
assembleControlEqProd_<__VA_ARGS__>(const WellState&, \
@ -328,14 +282,7 @@ assembleControlEqInj_<__VA_ARGS__>(const WellState&, \
const __VA_ARGS__&, \
const std::function<__VA_ARGS__()>&, \
__VA_ARGS__&, \
DeferredLogger&) const; \
template __VA_ARGS__ WellInterfaceEval<A>:: \
calculateBhpFromThp<__VA_ARGS__>(const WellState&, \
const std::vector<__VA_ARGS__>&, \
const Well&, \
const SummaryState&, \
const double, \
DeferredLogger&) const;
DeferredLogger&) const;
using FluidSys = BlackOilFluidSystem<double, BlackOilDefaultIndexTraits>;
@ -356,15 +303,4 @@ INSTANCE_METHODS(FluidSys, DenseAd::Evaluation<double,-1,8u>)
INSTANCE_METHODS(FluidSys, DenseAd::Evaluation<double,-1,9u>)
INSTANCE_METHODS(FluidSys, DenseAd::Evaluation<double,-1,10u>)
#define INSTANCE_BHP(...) \
template double WellInterfaceEval<__VA_ARGS__>:: \
calculateBhpFromThp<double>(const WellState&, \
const std::vector<double>&, \
const Well&, \
const SummaryState&, \
const double, \
DeferredLogger&) const;
INSTANCE_BHP(FluidSys)
} // namespace Opm

View File

@ -49,14 +49,6 @@ class WellInterfaceEval {
static constexpr int Gas = BlackoilPhases::Vapour;
public:
template <class EvalWell>
EvalWell calculateBhpFromThp(const WellState& well_state,
const std::vector<EvalWell>& rates,
const Well& well,
const SummaryState& summaryState,
const double rho,
DeferredLogger& deferred_logger) const;
template<class EvalWell, class BhpFromThpFunc>
void assembleControlEqProd(const WellState& well_state,
const GroupState& group_state,

View File

@ -23,6 +23,7 @@
#include <opm/simulators/utils/DeferredLoggingErrorHelpers.hpp>
#include <opm/simulators/wells/GroupState.hpp>
#include <opm/simulators/wells/TargetCalculator.hpp>
#include <opm/simulators/wells/WellBhpThpCalculator.hpp>
#include <dune/common/version.hh>
@ -811,7 +812,12 @@ namespace Opm
case Well::InjectorCMode::THP:
{
auto rates = ws.surface_rates;
double bhp = this->calculateBhpFromThp(well_state, rates, well, summaryState, this->getRefDensity(), deferred_logger);
double bhp = WellBhpThpCalculator(*this).calculateBhpFromThp(well_state,
rates,
well,
summaryState,
this->getRefDensity(),
deferred_logger);
ws.bhp = bhp;
ws.thp = this->getTHPConstraint(summaryState);
@ -1036,7 +1042,12 @@ namespace Opm
{
auto rates = ws.surface_rates;
this->adaptRatesForVFP(rates);
double bhp = this->calculateBhpFromThp(well_state, rates, well, summaryState, this->getRefDensity(), deferred_logger);
double bhp = WellBhpThpCalculator(*this).calculateBhpFromThp(well_state,
rates,
well,
summaryState,
this->getRefDensity(),
deferred_logger);
ws.bhp = bhp;
ws.thp = this->getTHPConstraint(summaryState);