mirror of
https://github.com/OPM/opm-simulators.git
synced 2024-11-28 20:13:49 -06:00
Compute scaled well residuals correctly for parallel runs.
This commit adapts the PR #375 for parallel runs. That is, the norms are calculated over all wells, not just the ones that perforate the local grid cells. As this is a reduction, too, we move the computation to convergenceReduction method.
This commit is contained in:
parent
9e0b2fed4f
commit
48ce90fcc7
@ -389,7 +389,9 @@ namespace Opm {
|
||||
/// maximum of tempV for the phase i.
|
||||
/// \param[out] B_avg An array of size MaxNumPhases where entry i contains the average
|
||||
/// of B for the phase i.
|
||||
/// \param[out] maxNormWell The maximum of the well equations for each phase.
|
||||
/// \param[in] nc The number of cells of the local grid.
|
||||
/// \param[in] nw The number of wells on the local grid.
|
||||
/// \return The total pore volume over all cells.
|
||||
double
|
||||
convergenceReduction(const Eigen::Array<double, Eigen::Dynamic, MaxNumPhases>& B,
|
||||
@ -398,7 +400,9 @@ namespace Opm {
|
||||
std::array<double,MaxNumPhases>& R_sum,
|
||||
std::array<double,MaxNumPhases>& maxCoeff,
|
||||
std::array<double,MaxNumPhases>& B_avg,
|
||||
int nc) const;
|
||||
std::vector<double>& maxNormWell,
|
||||
int nc,
|
||||
int nw) const;
|
||||
|
||||
void detectNewtonOscillations(const std::vector<std::vector<double>>& residual_history,
|
||||
const int it, const double relaxRelTol,
|
||||
|
@ -1834,7 +1834,9 @@ namespace detail {
|
||||
std::array<double,MaxNumPhases>& R_sum,
|
||||
std::array<double,MaxNumPhases>& maxCoeff,
|
||||
std::array<double,MaxNumPhases>& B_avg,
|
||||
int nc) const
|
||||
std::vector<double>& maxNormWell,
|
||||
int nc,
|
||||
int nw) const
|
||||
{
|
||||
// Do the global reductions
|
||||
#if HAVE_MPI
|
||||
@ -1865,12 +1867,18 @@ namespace detail {
|
||||
B_avg[idx] = std::get<0>(values)/std::get<0>(nc_and_pv);
|
||||
maxCoeff[idx] = std::get<1>(values);
|
||||
R_sum[idx] = std::get<2>(values);
|
||||
maxNormWell[idx] = 0.0;
|
||||
for ( int w=0; w<nw; ++w )
|
||||
{
|
||||
maxNormWell[idx] = std::max(maxNormWell[idx], std::abs(residual_.well_flux_eq.value()[nw*idx + w]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
R_sum[idx] = B_avg[idx] = maxCoeff[idx] = 0.0;
|
||||
maxNormWell[idx] = R_sum[idx] = B_avg[idx] = maxCoeff[idx] = 0.0;
|
||||
}
|
||||
}
|
||||
info.communicator().max(&maxNormWell[0], MaxNumPhases);
|
||||
// Compute pore volume
|
||||
return std::get<1>(nc_and_pv);
|
||||
}
|
||||
@ -1888,6 +1896,11 @@ namespace detail {
|
||||
{
|
||||
R_sum[idx] = B_avg[idx] = maxCoeff[idx] =0.0;
|
||||
}
|
||||
maxNormWell[idx] = 0.0;
|
||||
for ( int w=0; w<nw; ++w )
|
||||
{
|
||||
maxNormWell[idx] = std::max(maxNormWell[idx], std::abs(residual_.well_flux_eq.value()[nw*idx + w]));
|
||||
}
|
||||
}
|
||||
// Compute total pore volume
|
||||
return geo_.poreVolume().sum();
|
||||
@ -1920,6 +1933,7 @@ namespace detail {
|
||||
Eigen::Array<V::Scalar, Eigen::Dynamic, MaxNumPhases> B(nc, cols);
|
||||
Eigen::Array<V::Scalar, Eigen::Dynamic, MaxNumPhases> R(nc, cols);
|
||||
Eigen::Array<V::Scalar, Eigen::Dynamic, MaxNumPhases> tempV(nc, cols);
|
||||
std::vector<double> maxNormWell(MaxNumPhases);
|
||||
|
||||
for ( int idx=0; idx<MaxNumPhases; ++idx )
|
||||
{
|
||||
@ -1932,7 +1946,8 @@ namespace detail {
|
||||
}
|
||||
}
|
||||
|
||||
const double pvSum = convergenceReduction(B, tempV, R, R_sum, maxCoeff, B_avg, nc);
|
||||
const double pvSum = convergenceReduction(B, tempV, R, R_sum, maxCoeff, B_avg,
|
||||
maxNormWell, nc, nw);
|
||||
|
||||
bool converged_MB = true;
|
||||
bool converged_CNV = true;
|
||||
@ -1944,13 +1959,7 @@ namespace detail {
|
||||
mass_balance_residual[idx] = std::abs(B_avg[idx]*R_sum[idx]) * dt / pvSum;
|
||||
converged_MB = converged_MB && (mass_balance_residual[idx] < tol_mb);
|
||||
converged_CNV = converged_CNV && (CNV[idx] < tol_cnv);
|
||||
|
||||
double maxNormWell = 0.0;
|
||||
for ( int w=0; w<nw; ++w )
|
||||
{
|
||||
maxNormWell = std::max(maxNormWell, std::abs(residual_.well_flux_eq.value()[nw*idx + w]));
|
||||
}
|
||||
well_flux_residual[idx] = B_avg[idx] * dt * maxNormWell;
|
||||
well_flux_residual[idx] = B_avg[idx] * dt * maxNormWell[idx];
|
||||
|
||||
converged_Well = converged_Well && (well_flux_residual[idx] < tol_wells);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user