WellProdIndexCalculator: template Scalar type

This commit is contained in:
Arne Morten Kvarving 2024-02-20 23:39:23 +01:00
parent 685bca2c2a
commit bac2087b85
9 changed files with 87 additions and 65 deletions

View File

@ -549,7 +549,7 @@ protected:
std::vector<ParallelWellInfo<Scalar>> parallel_well_info_;
std::vector<std::reference_wrapper<ParallelWellInfo<Scalar>>> local_parallel_well_info_;
std::vector<WellProdIndexCalculator> prod_index_calc_;
std::vector<WellProdIndexCalculator<Scalar>> prod_index_calc_;
mutable ParallelWBPCalculation<Scalar> wbpCalculationService_;
std::vector<int> pvt_region_idx_;

View File

@ -135,7 +135,7 @@ namespace Opm {
DeferredLogger& deferred_logger) override;
void updateProductivityIndex(const Simulator& simulator,
const WellProdIndexCalculator& wellPICalc,
const WellProdIndexCalculator<Scalar>& wellPICalc,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const override;

View File

@ -735,7 +735,7 @@ namespace Opm
void
MultisegmentWell<TypeTag>::
updateProductivityIndex(const Simulator& simulator,
const WellProdIndexCalculator& wellPICalc,
const WellProdIndexCalculator<Scalar>& wellPICalc,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const
{

View File

@ -177,7 +177,7 @@ namespace Opm
DeferredLogger& deferred_logger) override; // should be const?
void updateProductivityIndex(const Simulator& simulator,
const WellProdIndexCalculator& wellPICalc,
const WellProdIndexCalculator<Scalar>& wellPICalc,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const override;

View File

@ -1220,7 +1220,7 @@ namespace Opm
void
StandardWell<TypeTag>::
updateProductivityIndex(const Simulator& simulator,
const WellProdIndexCalculator& wellPICalc,
const WellProdIndexCalculator<Scalar>& wellPICalc,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const
{

View File

@ -255,7 +255,7 @@ public:
DeferredLogger& deferred_logger) = 0; // should be const?
virtual void updateProductivityIndex(const Simulator& simulator,
const WellProdIndexCalculator& wellPICalc,
const WellProdIndexCalculator<Scalar>& wellPICalc,
WellState<Scalar>& well_state,
DeferredLogger& deferred_logger) const = 0;

View File

@ -35,8 +35,9 @@
namespace {
void checkSizeCompatibility(const Opm::WellProdIndexCalculator& wellPICalc,
const std::vector<double>& connMobility)
template<class Scalar>
void checkSizeCompatibility(const Opm::WellProdIndexCalculator<Scalar>& wellPICalc,
const std::vector<Scalar>& connMobility)
{
if (connMobility.size() != wellPICalc.numConnections()) {
throw std::logic_error {
@ -45,7 +46,8 @@ void checkSizeCompatibility(const Opm::WellProdIndexCalculator& wellPICalc,
}
}
double logRescale(const double r0, const double rw, const double rd, const double S)
template<class Scalar>
Scalar logRescale(const Scalar r0, const Scalar rw, const Scalar rd, const Scalar S)
{
const auto numerator = std::log(r0 / rw) + S;
const auto denom = std::log(rd / rw) + S;
@ -53,8 +55,9 @@ double logRescale(const double r0, const double rw, const double rd, const doubl
return numerator / denom;
}
template<class Scalar>
void standardConnFactorsExplicitDrainRadius(const Opm::Well& well,
std::vector<double>& stdConnFact)
std::vector<Scalar>& stdConnFact)
{
const auto& connections = well.getConnections();
const auto rdrain = well.getDrainageRadius();
@ -66,8 +69,9 @@ void standardConnFactorsExplicitDrainRadius(const Opm::Well& well,
});
}
template<class Scalar>
void standardConnFactorsDrainIsEquivalent(const Opm::Well& well,
std::vector<double>& stdConnFact)
std::vector<Scalar>& stdConnFact)
{
const auto& connections = well.getConnections();
@ -78,9 +82,10 @@ void standardConnFactorsDrainIsEquivalent(const Opm::Well& well,
});
}
std::vector<double> calculateStandardConnFactors(const Opm::Well& well)
template<class Scalar>
std::vector<Scalar> calculateStandardConnFactors(const Opm::Well& well)
{
std::vector<double> stdConnFact(well.getConnections().size());
std::vector<Scalar> stdConnFact(well.getConnections().size());
if (well.getDrainageRadius() > 0.0) {
// Well has an explicit drainage radius. Apply logarithmic
@ -98,28 +103,33 @@ std::vector<double> calculateStandardConnFactors(const Opm::Well& well)
} // namespace Anonymous
Opm::WellProdIndexCalculator::WellProdIndexCalculator(const Well& well)
: standardConnFactors_{ calculateStandardConnFactors(well) }
template<class Scalar>
Opm::WellProdIndexCalculator<Scalar>::
WellProdIndexCalculator(const Well& well)
: standardConnFactors_{ calculateStandardConnFactors<Scalar>(well) }
{}
void Opm::WellProdIndexCalculator::reInit(const Well& well)
template<class Scalar>
void Opm::WellProdIndexCalculator<Scalar>::
reInit(const Well& well)
{
this->standardConnFactors_ = calculateStandardConnFactors(well);
this->standardConnFactors_ = calculateStandardConnFactors<Scalar>(well);
}
double
Opm::WellProdIndexCalculator::
template<class Scalar>
Scalar Opm::WellProdIndexCalculator<Scalar>::
connectionProdIndStandard(const std::size_t connIdx,
const double connMobility) const
const Scalar connMobility) const
{
return this->standardConnFactors_[connIdx] * connMobility;
}
// ===========================================================================
std::vector<double>
Opm::connectionProdIndStandard(const WellProdIndexCalculator& wellPICalc,
const std::vector<double>& connMobility)
template<class Scalar>
std::vector<Scalar>
Opm::connectionProdIndStandard(const WellProdIndexCalculator<Scalar>& wellPICalc,
const std::vector<Scalar>& connMobility)
{
checkSizeCompatibility(wellPICalc, connMobility);
@ -133,10 +143,19 @@ Opm::connectionProdIndStandard(const WellProdIndexCalculator& wellPICalc,
return connPI;
}
double Opm::wellProdIndStandard(const WellProdIndexCalculator& wellPICalc,
const std::vector<double>& connMobility)
template<class Scalar>
Scalar Opm::wellProdIndStandard(const WellProdIndexCalculator<Scalar>& wellPICalc,
const std::vector<Scalar>& connMobility)
{
const auto connPI = connectionProdIndStandard(wellPICalc, connMobility);
return std::accumulate(connPI.begin(), connPI.end(), 0.0);
}
template class Opm::WellProdIndexCalculator<double>;
template std::vector<double>
Opm::connectionProdIndStandard(const WellProdIndexCalculator<double>&,
const std::vector<double>&);
template double
Opm::wellProdIndStandard(const WellProdIndexCalculator<double>&,
const std::vector<double>&);

View File

@ -32,6 +32,7 @@ namespace Opm {
/// Collect per-connection static information to enable calculating
/// connection-level or well-level productivity index values when
/// incorporating dynamic phase mobilities.
template<class Scalar>
class WellProdIndexCalculator
{
public:
@ -62,8 +63,8 @@ public:
/// intersected by well's connection \p connIdx.
///
/// \return Connection-level steady-state productivity index.
double connectionProdIndStandard(const std::size_t connIdx,
const double connMobility) const;
Scalar connectionProdIndStandard(const std::size_t connIdx,
const Scalar connMobility) const;
/// Number of connections in this well.
///
@ -79,7 +80,7 @@ private:
/// Corresponds to the well's connection transmissibility factors,
/// multiplied by a ratio of logarithms if the well has an explicit,
/// positive drainage radius.
std::vector<double> standardConnFactors_{};
std::vector<Scalar> standardConnFactors_{};
};
/// Compute connection-level productivity index values for all
@ -94,9 +95,10 @@ private:
///
/// \return Connection-level steady-state productivity index values for
/// all connections.
std::vector<double>
connectionProdIndStandard(const WellProdIndexCalculator& wellPICalc,
const std::vector<double>& connMobility);
template<class Scalar>
std::vector<Scalar>
connectionProdIndStandard(const WellProdIndexCalculator<Scalar>& wellPICalc,
const std::vector<Scalar>& connMobility);
/// Compute well-level productivity index value.
///
@ -108,8 +110,9 @@ connectionProdIndStandard(const WellProdIndexCalculator& wellPICalc,
/// \code wellPICalc.numConnections() \endcode well connection.
///
/// \return Well-level steady-state productivity index value.
double wellProdIndStandard(const WellProdIndexCalculator& wellPICalc,
const std::vector<double>& connMobility);
template<class Scalar>
Scalar wellProdIndStandard(const WellProdIndexCalculator<Scalar>& wellPICalc,
const std::vector<Scalar>& connMobility);
} // namespace Opm

View File

@ -151,7 +151,7 @@ BOOST_AUTO_TEST_SUITE(ConnectionLevel)
BOOST_AUTO_TEST_CASE(allDefaulted_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), noSkinFactor_SameCF())
};
@ -165,7 +165,7 @@ BOOST_AUTO_TEST_CASE(allDefaulted_SameCF)
BOOST_AUTO_TEST_CASE(allDefaulted_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), noSkinFactor_DifferentCF())
};
@ -179,7 +179,7 @@ BOOST_AUTO_TEST_CASE(allDefaulted_DifferentCF)
BOOST_AUTO_TEST_CASE(defaultedDRad_Skin2_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), skin2_SameCF())
};
@ -193,7 +193,7 @@ BOOST_AUTO_TEST_CASE(defaultedDRad_Skin2_SameCF)
BOOST_AUTO_TEST_CASE(defaultedDRad_skin421_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), skin421_DifferentCF())
};
@ -207,7 +207,7 @@ BOOST_AUTO_TEST_CASE(defaultedDRad_skin421_DifferentCF)
BOOST_AUTO_TEST_CASE(logarithmic_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), noSkinFactor_SameCF())
};
@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_SameCF)
BOOST_AUTO_TEST_CASE(logarithmic_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), noSkinFactor_DifferentCF())
};
@ -235,7 +235,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_DifferentCF)
BOOST_AUTO_TEST_CASE(logarithmic_Skin2_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), skin2_SameCF())
};
@ -249,7 +249,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_Skin2_SameCF)
BOOST_AUTO_TEST_CASE(logarithmic_skin421_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), skin421_DifferentCF())
};
@ -269,7 +269,7 @@ BOOST_AUTO_TEST_SUITE(AllConnections)
BOOST_AUTO_TEST_CASE(allDefaulted_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), noSkinFactor_SameCF())
};
@ -290,7 +290,7 @@ BOOST_AUTO_TEST_CASE(allDefaulted_SameCF)
BOOST_AUTO_TEST_CASE(allDefaulted_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), noSkinFactor_DifferentCF())
};
@ -311,7 +311,7 @@ BOOST_AUTO_TEST_CASE(allDefaulted_DifferentCF)
BOOST_AUTO_TEST_CASE(defaultedDRad_Skin2_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), skin2_SameCF())
};
@ -332,7 +332,7 @@ BOOST_AUTO_TEST_CASE(defaultedDRad_Skin2_SameCF)
BOOST_AUTO_TEST_CASE(defaultedDRad_skin421_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), skin421_DifferentCF())
};
@ -353,7 +353,7 @@ BOOST_AUTO_TEST_CASE(defaultedDRad_skin421_DifferentCF)
BOOST_AUTO_TEST_CASE(logarithmic_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), noSkinFactor_SameCF())
};
@ -374,7 +374,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_SameCF)
BOOST_AUTO_TEST_CASE(logarithmic_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), noSkinFactor_DifferentCF())
};
@ -395,7 +395,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_DifferentCF)
BOOST_AUTO_TEST_CASE(logarithmic_Skin2_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), skin2_SameCF())
};
@ -416,7 +416,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_Skin2_SameCF)
BOOST_AUTO_TEST_CASE(logarithmic_skin421_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), skin421_DifferentCF())
};
@ -445,7 +445,7 @@ BOOST_AUTO_TEST_SUITE(WellLevel)
BOOST_AUTO_TEST_CASE(allDefaulted_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), noSkinFactor_SameCF())
};
@ -461,7 +461,7 @@ BOOST_AUTO_TEST_CASE(allDefaulted_SameCF)
BOOST_AUTO_TEST_CASE(allDefaulted_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), noSkinFactor_DifferentCF())
};
@ -477,7 +477,7 @@ BOOST_AUTO_TEST_CASE(allDefaulted_DifferentCF)
BOOST_AUTO_TEST_CASE(defaultedDRad_Skin2_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), skin2_SameCF())
};
@ -493,7 +493,7 @@ BOOST_AUTO_TEST_CASE(defaultedDRad_Skin2_SameCF)
BOOST_AUTO_TEST_CASE(defaultedDRad_skin421_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(drainRadDefaulted(), skin421_DifferentCF())
};
@ -509,7 +509,7 @@ BOOST_AUTO_TEST_CASE(defaultedDRad_skin421_DifferentCF)
BOOST_AUTO_TEST_CASE(logarithmic_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), noSkinFactor_SameCF())
};
@ -525,7 +525,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_SameCF)
BOOST_AUTO_TEST_CASE(logarithmic_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), noSkinFactor_DifferentCF())
};
@ -541,7 +541,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_DifferentCF)
BOOST_AUTO_TEST_CASE(logarithmic_Skin2_SameCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), skin2_SameCF())
};
@ -557,7 +557,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_Skin2_SameCF)
BOOST_AUTO_TEST_CASE(logarithmic_skin421_DifferentCF)
{
const auto wpiCalc = Opm::WellProdIndexCalculator {
const auto wpiCalc = Opm::WellProdIndexCalculator<double> {
createWell(explicitDrainRad(), skin421_DifferentCF())
};
@ -582,7 +582,7 @@ BOOST_AUTO_TEST_SUITE(Re_Init_Connection_Level)
BOOST_AUTO_TEST_CASE(allDefaulted_SameCF)
{
auto well = createWell(drainRadDefaulted(), noSkinFactor_SameCF());
auto wpiCalc = Opm::WellProdIndexCalculator { well };
auto wpiCalc = Opm::WellProdIndexCalculator<double> { well };
well.updateWellProductivityIndex( );
const auto scalingFactor = well.convertDeckPI(2.0) / (1.0*liquid_PI_unit());
@ -605,7 +605,7 @@ BOOST_AUTO_TEST_CASE(allDefaulted_SameCF)
BOOST_AUTO_TEST_CASE(allDefaulted_DifferentCF)
{
auto well = createWell(drainRadDefaulted(), noSkinFactor_DifferentCF());
auto wpiCalc = Opm::WellProdIndexCalculator { well };
auto wpiCalc = Opm::WellProdIndexCalculator<double> { well };
well.updateWellProductivityIndex( );
const auto scalingFactor = well.convertDeckPI(2.0) / (1.0*liquid_PI_unit());
@ -628,7 +628,7 @@ BOOST_AUTO_TEST_CASE(allDefaulted_DifferentCF)
BOOST_AUTO_TEST_CASE(defaultedDRad_Skin2_SameCF)
{
auto well = createWell(drainRadDefaulted(), skin2_SameCF());
auto wpiCalc = Opm::WellProdIndexCalculator { well };
auto wpiCalc = Opm::WellProdIndexCalculator<double> { well };
well.updateWellProductivityIndex( );
const auto scalingFactor = well.convertDeckPI(2.0) / (1.0*liquid_PI_unit());
@ -651,7 +651,7 @@ BOOST_AUTO_TEST_CASE(defaultedDRad_Skin2_SameCF)
BOOST_AUTO_TEST_CASE(defaultedDRad_skin421_DifferentCF)
{
auto well = createWell(drainRadDefaulted(), skin421_DifferentCF());
auto wpiCalc = Opm::WellProdIndexCalculator { well };
auto wpiCalc = Opm::WellProdIndexCalculator<double> { well };
well.updateWellProductivityIndex( );
const auto scalingFactor = well.convertDeckPI(2.0) / (1.0*liquid_PI_unit());
@ -674,7 +674,7 @@ BOOST_AUTO_TEST_CASE(defaultedDRad_skin421_DifferentCF)
BOOST_AUTO_TEST_CASE(logarithmic_SameCF)
{
auto well = createWell(explicitDrainRad(), noSkinFactor_SameCF());
auto wpiCalc = Opm::WellProdIndexCalculator { well };
auto wpiCalc = Opm::WellProdIndexCalculator<double> { well };
well.updateWellProductivityIndex( );
const auto scalingFactor = well.convertDeckPI(2.0) / (1.0*liquid_PI_unit());
@ -697,7 +697,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_SameCF)
BOOST_AUTO_TEST_CASE(logarithmic_DifferentCF)
{
auto well = createWell(explicitDrainRad(), noSkinFactor_DifferentCF());
auto wpiCalc = Opm::WellProdIndexCalculator { well };
auto wpiCalc = Opm::WellProdIndexCalculator<double> { well };
well.updateWellProductivityIndex( );
const auto scalingFactor = well.convertDeckPI(2.0) / (1.0*liquid_PI_unit());
@ -720,7 +720,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_DifferentCF)
BOOST_AUTO_TEST_CASE(logarithmic_Skin2_SameCF)
{
auto well = createWell(explicitDrainRad(), skin2_SameCF());
auto wpiCalc = Opm::WellProdIndexCalculator { well };
auto wpiCalc = Opm::WellProdIndexCalculator<double> { well };
well.updateWellProductivityIndex( );
const auto scalingFactor = well.convertDeckPI(2.0) / (1.0*liquid_PI_unit());
@ -743,7 +743,7 @@ BOOST_AUTO_TEST_CASE(logarithmic_Skin2_SameCF)
BOOST_AUTO_TEST_CASE(logarithmic_skin421_DifferentCF)
{
auto well = createWell(explicitDrainRad(), skin421_DifferentCF());
auto wpiCalc = Opm::WellProdIndexCalculator { well };
auto wpiCalc = Opm::WellProdIndexCalculator<double> { well };
well.updateWellProductivityIndex( );
const auto scalingFactor = well.convertDeckPI(2.0) / (1.0*liquid_PI_unit());