Make getWellConvergence parallel and omit unnecessary computations.

detail::getConvergence computes a lot more than we actually need.
We only need the average over B and the maximum of the well residual.

Therefore we now compute these quantities in getWellConvergence and
do the global reductions manually.
This commit is contained in:
Markus Blatt
2017-03-24 12:12:06 +01:00
parent 4768bc9e90
commit 0e83496740

View File

@@ -919,21 +919,17 @@ namespace Opm {
getWellConvergence(Simulator& ebosSimulator, getWellConvergence(Simulator& ebosSimulator,
const int iteration) const const int iteration) const
{ {
typedef std::vector< double > Vector; typedef double Scalar;
typedef std::vector< Scalar > Vector;
const int np = numPhases(); const int np = numPhases();
const int nc = numCells(); const int nc = numCells();
const double tol_wells = param_.tolerance_wells_; const double tol_wells = param_.tolerance_wells_;
const double maxResidualAllowed = param_.max_residual_allowed_; const double maxResidualAllowed = param_.max_residual_allowed_;
Vector R_sum(np); std::vector< Scalar > B_avg( np, Scalar() );
Vector B_avg(np); std::vector< Scalar > maxNormWell(np, Scalar() );
Vector maxCoeff(np);
Vector maxNormWell(np);
std::vector< Vector > B( np, Vector( nc ) );
std::vector< Vector > R2( np, Vector( nc ) );
std::vector< Vector > tempV( np, Vector( nc ) );
auto& grid = ebosSimulator.gridManager().grid(); auto& grid = ebosSimulator.gridManager().grid();
const auto& gridView = grid.leafGridView(); const auto& gridView = grid.leafGridView();
ElementContext elemCtx(ebosSimulator); ElementContext elemCtx(ebosSimulator);
@@ -950,20 +946,33 @@ namespace Opm {
for ( int idx = 0; idx < np; ++idx ) for ( int idx = 0; idx < np; ++idx )
{ {
Vector& B_idx = B[ idx ]; auto& B = B_avg[ idx ];
const int ebosPhaseIdx = flowPhaseToEbosPhaseIdx(idx); const int ebosPhaseIdx = flowPhaseToEbosPhaseIdx(idx);
B_idx [cell_idx] = 1 / fs.invB(ebosPhaseIdx).value(); B += 1 / fs.invB(ebosPhaseIdx).value();
} }
} }
detail::convergenceReduction(B, tempV, R2, // compute global average
R_sum, maxCoeff, B_avg, maxNormWell, grid.comm().sum(B_avg.data(), B_avg.size());
nc, np, pv_, residual() ); for(auto& bval: B_avg)
bval/=nc;
auto res = residual();
const int nw = res.size() / np;
for ( int idx = 0; idx < np; ++idx )
{
for ( int w = 0; w < nw; ++w ) {
maxNormWell[idx] = std::max(maxNormWell[idx], std::abs(res[nw*idx + w]));
}
}
grid.comm().max(maxNormWell.data(), maxNormWell.size());
Vector well_flux_residual(np); Vector well_flux_residual(np);
bool converged_Well = true; bool converged_Well = true;
// Finish computation // Finish computation
for ( int idx = 0; idx < np; ++idx ) for ( int idx = 0; idx < np; ++idx )
{ {