MultisegmentWellEval: use Scalar type

This commit is contained in:
Arne Morten Kvarving 2024-02-20 22:32:18 +01:00
parent 0da7903f8b
commit 33ad8e3617
2 changed files with 47 additions and 47 deletions

View File

@ -79,35 +79,35 @@ template<typename FluidSystem, typename Indices>
ConvergenceReport
MultisegmentWellEval<FluidSystem,Indices>::
getWellConvergence(const WellState<Scalar>& well_state,
const std::vector<double>& B_avg,
const std::vector<Scalar>& B_avg,
DeferredLogger& deferred_logger,
const double max_residual_allowed,
const double tolerance_wells,
const double relaxed_inner_tolerance_flow_ms_well,
const double tolerance_pressure_ms_wells,
const double relaxed_inner_tolerance_pressure_ms_well,
const Scalar max_residual_allowed,
const Scalar tolerance_wells,
const Scalar relaxed_inner_tolerance_flow_ms_well,
const Scalar tolerance_pressure_ms_wells,
const Scalar relaxed_inner_tolerance_pressure_ms_well,
const bool relax_tolerance,
const bool well_is_stopped) const
{
assert(int(B_avg.size()) == baseif_.numComponents());
// checking if any residual is NaN or too large. The two large one is only handled for the well flux
std::vector<std::vector<double>> abs_residual(this->numberOfSegments(),
std::vector<double>(numWellEq, 0.0));
std::vector<std::vector<Scalar>> abs_residual(this->numberOfSegments(),
std::vector<Scalar>(numWellEq, 0.0));
for (int seg = 0; seg < this->numberOfSegments(); ++seg) {
for (int eq_idx = 0; eq_idx < numWellEq; ++eq_idx) {
abs_residual[seg][eq_idx] = std::abs(linSys_.residual()[seg][eq_idx]);
}
}
std::vector<double> maximum_residual(numWellEq, 0.0);
std::vector<Scalar> maximum_residual(numWellEq, 0.0);
ConvergenceReport report;
// TODO: the following is a little complicated, maybe can be simplified in some way?
for (int eq_idx = 0; eq_idx < numWellEq; ++eq_idx) {
for (int seg = 0; seg < this->numberOfSegments(); ++seg) {
if (eq_idx < baseif_.numComponents()) { // phase or component mass equations
const double flux_residual = B_avg[eq_idx] * abs_residual[seg][eq_idx];
const Scalar flux_residual = B_avg[eq_idx] * abs_residual[seg][eq_idx];
if (flux_residual > maximum_residual[eq_idx]) {
maximum_residual[eq_idx] = flux_residual;
}
@ -115,7 +115,7 @@ getWellConvergence(const WellState<Scalar>& well_state,
// for the top segment (seg == 0), it is control equation, will be checked later separately
if (seg > 0) {
// Pressure equation
const double pressure_residual = abs_residual[seg][eq_idx];
const Scalar pressure_residual = abs_residual[seg][eq_idx];
if (pressure_residual > maximum_residual[eq_idx]) {
maximum_residual[eq_idx] = pressure_residual;
}
@ -127,7 +127,7 @@ getWellConvergence(const WellState<Scalar>& well_state,
using CR = ConvergenceReport;
for (int eq_idx = 0; eq_idx < numWellEq; ++eq_idx) {
if (eq_idx < baseif_.numComponents()) { // phase or component mass equations
const double flux_residual = maximum_residual[eq_idx];
const Scalar flux_residual = maximum_residual[eq_idx];
// TODO: the report can not handle the segment number yet.
if (std::isnan(flux_residual)) {
@ -140,7 +140,7 @@ getWellConvergence(const WellState<Scalar>& well_state,
report.setWellFailed({CR::WellFailure::Type::MassBalance, CR::Severity::Normal, eq_idx, baseif_.name()});
}
} else { // pressure equation
const double pressure_residual = maximum_residual[eq_idx];
const Scalar pressure_residual = maximum_residual[eq_idx];
const int dummy_component = -1;
if (std::isnan(pressure_residual)) {
report.setWellFailed({CR::WellFailure::Type::Pressure, CR::Severity::NotANumber, dummy_component, baseif_.name()});
@ -170,7 +170,7 @@ getWellConvergence(const WellState<Scalar>& well_state,
// for BHP or THP controlled wells, we need to make sure the flow direction is correct
if (!well_is_stopped && baseif_.isPressureControlled(well_state)) {
// checking the flow direction
const double sign = baseif_.isProducer() ? -1. : 1.;
const Scalar sign = baseif_.isProducer() ? -1. : 1.;
const auto weight_total_flux = this->primary_variables_.getWQTotal() * sign;
constexpr int dummy_phase = -1;
if (weight_total_flux < 0.) {
@ -207,7 +207,7 @@ assembleAccelerationPressureLoss(const int seg,
const auto& segment_set = this->segmentSet();
// Add segment head
const double seg_area = segment_set[seg].crossArea();
const Scalar seg_area = segment_set[seg].crossArea();
const EvalWell signed_velocity_head = segments_.accelerationPressureLossContribution(seg, seg_area);
segments.pressure_drop_accel[seg] = signed_velocity_head.value();
@ -225,7 +225,8 @@ assembleAccelerationPressureLoss(const int seg,
// Subtract inlet head(s), opposite signs from above
for (const int inlet : segments_.inlets(seg)) {
// area used in formula is max of areas
const double inlet_area = std::max(seg_area, segment_set[inlet].crossArea());
const Scalar inlet_area = std::max(seg_area,
static_cast<Scalar>(segment_set[inlet].crossArea()));
const EvalWell signed_velocity_head_inlet = segments_.accelerationPressureLossContribution(inlet, inlet_area);
segments.pressure_drop_accel[seg] -= signed_velocity_head_inlet.value();
@ -437,7 +438,7 @@ getFiniteWellResiduals(const std::vector<Scalar>& B_avg,
for (int seg = 0; seg < this->numberOfSegments(); ++seg) {
for (int eq_idx = 0; eq_idx < numWellEq; ++eq_idx) {
double residual = 0.;
Scalar residual = 0.;
if (eq_idx < baseif_.numComponents()) {
residual = std::abs(linSys_.residual()[seg][eq_idx]) * B_avg[eq_idx];
} else {
@ -459,7 +460,7 @@ getFiniteWellResiduals(const std::vector<Scalar>& B_avg,
// handling the control equation residual
{
const double control_residual = std::abs(linSys_.residual()[0][numWellEq - 1]);
const Scalar control_residual = std::abs(linSys_.residual()[0][numWellEq - 1]);
if (std::isnan(control_residual) || std::isinf(control_residual)) {
deferred_logger.debug(fmt::format("nan or inf value for control residual for well {}", baseif_.name()));
return {false, residuals};
@ -471,14 +472,14 @@ getFiniteWellResiduals(const std::vector<Scalar>& B_avg,
}
template<typename FluidSystem, typename Indices>
double
typename MultisegmentWellEval<FluidSystem,Indices>::Scalar
MultisegmentWellEval<FluidSystem,Indices>::
getControlTolerance(const WellState<Scalar>& well_state,
const double tolerance_wells,
const double tolerance_pressure_ms_wells,
const Scalar tolerance_wells,
const Scalar tolerance_pressure_ms_wells,
DeferredLogger& deferred_logger) const
{
double control_tolerance = 0.;
Scalar control_tolerance = 0.;
const int well_index = baseif_.indexOfWell();
const auto& ws = well_state.well(well_index);
@ -538,19 +539,19 @@ getControlTolerance(const WellState<Scalar>& well_state,
}
template<typename FluidSystem, typename Indices>
double
typename MultisegmentWellEval<FluidSystem,Indices>::Scalar
MultisegmentWellEval<FluidSystem,Indices>::
getResidualMeasureValue(const WellState<Scalar>& well_state,
const std::vector<double>& residuals,
const double tolerance_wells,
const double tolerance_pressure_ms_wells,
const std::vector<Scalar>& residuals,
const Scalar tolerance_wells,
const Scalar tolerance_pressure_ms_wells,
DeferredLogger& deferred_logger) const
{
assert(int(residuals.size()) == numWellEq + 1);
const double rate_tolerance = tolerance_wells;
const Scalar rate_tolerance = tolerance_wells;
[[maybe_unused]] int count = 0;
double sum = 0;
Scalar sum = 0;
for (int eq_idx = 0; eq_idx < numWellEq - 1; ++eq_idx) {
if (residuals[eq_idx] > rate_tolerance) {
sum += residuals[eq_idx] / rate_tolerance;
@ -558,13 +559,13 @@ getResidualMeasureValue(const WellState<Scalar>& well_state,
}
}
const double pressure_tolerance = tolerance_pressure_ms_wells;
const Scalar pressure_tolerance = tolerance_pressure_ms_wells;
if (residuals[SPres] > pressure_tolerance) {
sum += residuals[SPres] / pressure_tolerance;
++count;
}
const double control_tolerance = getControlTolerance(well_state,
const Scalar control_tolerance = getControlTolerance(well_state,
tolerance_wells,
tolerance_pressure_ms_wells,
deferred_logger);

View File

@ -32,8 +32,7 @@
#include <utility>
#include <vector>
namespace Opm
{
namespace Opm {
class ConvergenceReport;
class Schedule;
@ -100,13 +99,13 @@ protected:
/// check whether the well equations get converged for this well
ConvergenceReport getWellConvergence(const WellState<Scalar>& well_state,
const std::vector<double>& B_avg,
const std::vector<Scalar>& B_avg,
DeferredLogger& deferred_logger,
const double max_residual_allowed,
const double tolerance_wells,
const double relaxed_inner_tolerance_flow_ms_well,
const double tolerance_pressure_ms_wells,
const double relaxed_inner_tolerance_pressure_ms_well,
const Scalar max_residual_allowed,
const Scalar tolerance_wells,
const Scalar relaxed_inner_tolerance_flow_ms_well,
const Scalar tolerance_pressure_ms_wells,
const Scalar relaxed_inner_tolerance_pressure_ms_well,
const bool relax_tolerance,
const bool well_is_stopped) const;
@ -114,15 +113,15 @@ protected:
getFiniteWellResiduals(const std::vector<Scalar>& B_avg,
DeferredLogger& deferred_logger) const;
double getControlTolerance(const WellState<Scalar>& well_state,
const double tolerance_wells,
const double tolerance_pressure_ms_wells,
Scalar getControlTolerance(const WellState<Scalar>& well_state,
const Scalar tolerance_wells,
const Scalar tolerance_pressure_ms_wells,
DeferredLogger& deferred_logger) const;
double getResidualMeasureValue(const WellState<Scalar>& well_state,
const std::vector<double>& residuals,
const double tolerance_wells,
const double tolerance_pressure_ms_wells,
Scalar getResidualMeasureValue(const WellState<Scalar>& well_state,
const std::vector<Scalar>& residuals,
const Scalar tolerance_wells,
const Scalar tolerance_pressure_ms_wells,
DeferredLogger& deferred_logger) const;
void assembleAccelerationPressureLoss(const int seg,
@ -141,10 +140,10 @@ protected:
MSWSegments segments_; //!< Segment properties
// depth difference between perforations and the perforated grid cells
std::vector<double> cell_perforation_depth_diffs_;
std::vector<Scalar> cell_perforation_depth_diffs_;
// pressure correction due to the different depth of the perforation and
// center depth of the grid block
std::vector<double> cell_perforation_pressure_diffs_;
std::vector<Scalar> cell_perforation_pressure_diffs_;
};
}