mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Add damping treatment to subdomain Newton iterations.
This commit is contained in:
parent
4cf8a50b26
commit
f06c238753
@ -33,6 +33,7 @@
|
|||||||
#include <opm/simulators/flow/countGlobalCells.hpp>
|
#include <opm/simulators/flow/countGlobalCells.hpp>
|
||||||
#include <opm/simulators/flow/partitionCells.hpp>
|
#include <opm/simulators/flow/partitionCells.hpp>
|
||||||
#include <opm/simulators/flow/priVarsPacking.hpp>
|
#include <opm/simulators/flow/priVarsPacking.hpp>
|
||||||
|
#include <opm/simulators/flow/NonlinearSolver.hpp>
|
||||||
#include <opm/simulators/flow/SubDomain.hpp>
|
#include <opm/simulators/flow/SubDomain.hpp>
|
||||||
|
|
||||||
#include <opm/simulators/linalg/extractMatrix.hpp>
|
#include <opm/simulators/linalg/extractMatrix.hpp>
|
||||||
@ -353,6 +354,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
//! \brief Solve the equation system for a single domain.
|
//! \brief Solve the equation system for a single domain.
|
||||||
std::pair<SimulatorReportSingle, ConvergenceReport>
|
std::pair<SimulatorReportSingle, ConvergenceReport>
|
||||||
solveDomain(const Domain& domain,
|
solveDomain(const Domain& domain,
|
||||||
@ -411,6 +413,10 @@ private:
|
|||||||
// Local Newton loop.
|
// Local Newton loop.
|
||||||
const int max_iter = model_.param().max_local_solve_iterations_;
|
const int max_iter = model_.param().max_local_solve_iterations_;
|
||||||
const auto& grid = modelSimulator.vanguard().grid();
|
const auto& grid = modelSimulator.vanguard().grid();
|
||||||
|
double damping_factor = 1.0;
|
||||||
|
std::vector<std::vector<Scalar>> convergence_history;
|
||||||
|
convergence_history.reserve(20);
|
||||||
|
convergence_history.push_back(resnorms);
|
||||||
do {
|
do {
|
||||||
// Solve local linear system.
|
// Solve local linear system.
|
||||||
// Note that x has full size, we expect it to be nonzero only for in-domain cells.
|
// Note that x has full size, we expect it to be nonzero only for in-domain cells.
|
||||||
@ -420,6 +426,9 @@ private:
|
|||||||
detailTimer.start();
|
detailTimer.start();
|
||||||
this->solveJacobianSystemDomain(domain, x);
|
this->solveJacobianSystemDomain(domain, x);
|
||||||
model_.wellModel().postSolveDomain(x, domain);
|
model_.wellModel().postSolveDomain(x, domain);
|
||||||
|
if (damping_factor != 1.0) {
|
||||||
|
x *= damping_factor;
|
||||||
|
}
|
||||||
report.linear_solve_time += detailTimer.stop();
|
report.linear_solve_time += detailTimer.stop();
|
||||||
report.linear_solve_setup_time += model_.linearSolveSetupTime();
|
report.linear_solve_setup_time += model_.linearSolveSetupTime();
|
||||||
report.total_linear_iterations = model_.linearIterationsLastSolve();
|
report.total_linear_iterations = model_.linearIterationsLastSolve();
|
||||||
@ -447,7 +456,9 @@ private:
|
|||||||
// Check for local convergence.
|
// Check for local convergence.
|
||||||
detailTimer.reset();
|
detailTimer.reset();
|
||||||
detailTimer.start();
|
detailTimer.start();
|
||||||
|
resnorms.clear();
|
||||||
convreport = this->getDomainConvergence(domain, timer, iter, logger, resnorms);
|
convreport = this->getDomainConvergence(domain, timer, iter, logger, resnorms);
|
||||||
|
convergence_history.push_back(resnorms);
|
||||||
|
|
||||||
// apply the Schur complement of the well model to the
|
// apply the Schur complement of the well model to the
|
||||||
// reservoir linearized equations
|
// reservoir linearized equations
|
||||||
@ -459,6 +470,18 @@ private:
|
|||||||
const double tt2 = detailTimer.stop();
|
const double tt2 = detailTimer.stop();
|
||||||
report.assemble_time += tt2;
|
report.assemble_time += tt2;
|
||||||
report.assemble_time_well += tt2;
|
report.assemble_time_well += tt2;
|
||||||
|
|
||||||
|
// Check if we should dampen. Only do so if wells are converged.
|
||||||
|
if (!convreport.converged() && !convreport.wellFailed()) {
|
||||||
|
bool oscillate = false;
|
||||||
|
bool stagnate = false;
|
||||||
|
const int numPhases = convergence_history.front().size();
|
||||||
|
detail::detectOscillations(convergence_history, iter, numPhases, 0.2, 1, oscillate, stagnate);
|
||||||
|
if (oscillate) {
|
||||||
|
damping_factor *= 0.85;
|
||||||
|
logger.debug(fmt::format("| Damping factor is now {}", damping_factor));
|
||||||
|
}
|
||||||
|
}
|
||||||
} while (!convreport.converged() && iter <= max_iter);
|
} while (!convreport.converged() && iter <= max_iter);
|
||||||
|
|
||||||
modelSimulator.problem().endIteration();
|
modelSimulator.problem().endIteration();
|
||||||
|
Loading…
Reference in New Issue
Block a user