mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
[bugfix][BlockoilModelEbos] fix invalidation of intensive quantities after
linear solver failure.
This commit is contained in:
parent
dde8333343
commit
439a084508
@ -184,7 +184,7 @@ namespace Opm {
|
|||||||
, current_relaxation_(1.0)
|
, current_relaxation_(1.0)
|
||||||
, dx_old_(AutoDiffGrid::numCells(grid_))
|
, dx_old_(AutoDiffGrid::numCells(grid_))
|
||||||
, isBeginReportStep_(false)
|
, isBeginReportStep_(false)
|
||||||
, isRestart_(false)
|
, invalidateIntensiveQuantitiesCache_(true)
|
||||||
{
|
{
|
||||||
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
|
const double gravity = detail::getGravity(geo_.gravity(), UgGridHelpers::dimensions(grid_));
|
||||||
const std::vector<double> pv(geo_.poreVolume().data(), geo_.poreVolume().data() + geo_.poreVolume().size());
|
const std::vector<double> pv(geo_.poreVolume().data(), geo_.poreVolume().data() + geo_.poreVolume().size());
|
||||||
@ -258,16 +258,21 @@ namespace Opm {
|
|||||||
current_relaxation_ = 1.0;
|
current_relaxation_ = 1.0;
|
||||||
dx_old_ = 0.0;
|
dx_old_ = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset intensive quantities cache useless other options are set
|
||||||
|
// further down
|
||||||
|
invalidateIntensiveQuantitiesCache_ = true;
|
||||||
|
|
||||||
IterationReport iter_report = assemble(timer, iteration, reservoir_state, well_state);
|
IterationReport iter_report = assemble(timer, iteration, reservoir_state, well_state);
|
||||||
std::vector<double> residual_norms;
|
std::vector<double> residual_norms;
|
||||||
const bool converged = getConvergence(timer, iteration,residual_norms);
|
const bool converged = getConvergence(timer, iteration,residual_norms);
|
||||||
residual_norms_history_.push_back(residual_norms);
|
residual_norms_history_.push_back(residual_norms);
|
||||||
bool must_solve = (iteration < nonlinear_solver.minIter()) || (!converged);
|
bool must_solve = (iteration < nonlinear_solver.minIter()) || (!converged);
|
||||||
// is first set to true if a linear solve is needed, but then it is set to false if the solver succeed.
|
|
||||||
isRestart_ = must_solve && (iteration == nonlinear_solver.maxIter());
|
|
||||||
// don't solve if we have reached the maximum number of iteration.
|
// don't solve if we have reached the maximum number of iteration.
|
||||||
must_solve = must_solve && (iteration < nonlinear_solver.maxIter());
|
must_solve = must_solve && (iteration < nonlinear_solver.maxIter());
|
||||||
if (must_solve) {
|
if (must_solve) {
|
||||||
|
|
||||||
// enable single precision for solvers when dt is smaller then 20 days
|
// enable single precision for solvers when dt is smaller then 20 days
|
||||||
//residual_.singlePrecision = (unit::convert::to(dt, unit::day) < 20.) ;
|
//residual_.singlePrecision = (unit::convert::to(dt, unit::day) < 20.) ;
|
||||||
|
|
||||||
@ -276,6 +281,7 @@ namespace Opm {
|
|||||||
const int nw = wellModel().wells().number_of_wells;
|
const int nw = wellModel().wells().number_of_wells;
|
||||||
BVector x(nc);
|
BVector x(nc);
|
||||||
BVector xw(nw);
|
BVector xw(nw);
|
||||||
|
|
||||||
solveJacobianSystem(x, xw);
|
solveJacobianSystem(x, xw);
|
||||||
|
|
||||||
// Stabilize the nonlinear update.
|
// Stabilize the nonlinear update.
|
||||||
@ -298,17 +304,21 @@ namespace Opm {
|
|||||||
updateState(x,reservoir_state);
|
updateState(x,reservoir_state);
|
||||||
wellModel().updateWellState(xw, well_state);
|
wellModel().updateWellState(xw, well_state);
|
||||||
|
|
||||||
// since the solution was changed, the cache for the intensive quantities
|
// since the solution was changed, the cache for the intensive quantities are invalid
|
||||||
// are invalid
|
// ebosSimulator_.model().invalidateIntensiveQuantitiesCache(/*timeIdx=*/0);
|
||||||
ebosSimulator_.model().invalidateIntensiveQuantitiesCache(/*timeIdx=*/0);
|
|
||||||
|
|
||||||
// solver has succeed i.e. no need for restart.
|
|
||||||
isRestart_ = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( converged )
|
||||||
|
{
|
||||||
|
// in case of convergence we do not need to reset intensive quantities
|
||||||
|
invalidateIntensiveQuantitiesCache_ = false ;
|
||||||
|
}
|
||||||
|
|
||||||
const bool failed = false; // Not needed in this model.
|
const bool failed = false; // Not needed in this model.
|
||||||
const int linear_iters = must_solve ? linearIterationsLastSolve() : 0;
|
const int linear_iters = must_solve ? linearIterationsLastSolve() : 0;
|
||||||
return IterationReport{ failed, converged, linear_iters, iter_report.well_iterations };
|
return IterationReport{ failed, converged, linear_iters, iter_report.well_iterations };
|
||||||
}
|
}
|
||||||
|
|
||||||
void printIf(int c, double x, double y, double eps, std::string type) {
|
void printIf(int c, double x, double y, double eps, std::string type) {
|
||||||
if (std::abs(x-y) > eps) {
|
if (std::abs(x-y) > eps) {
|
||||||
std::cout << type << " " <<c << ": "<<x << " " << y << std::endl;
|
std::cout << type << " " <<c << ": "<<x << " " << y << std::endl;
|
||||||
@ -351,7 +361,6 @@ namespace Opm {
|
|||||||
}
|
}
|
||||||
catch ( const Dune::FMatrixError& e )
|
catch ( const Dune::FMatrixError& e )
|
||||||
{
|
{
|
||||||
isRestart_ = true;
|
|
||||||
OPM_THROW(Opm::NumericalProblem,"Well equation did not converge");
|
OPM_THROW(Opm::NumericalProblem,"Well equation did not converge");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -511,10 +520,11 @@ namespace Opm {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// y += \alpha * A * x
|
||||||
virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const
|
virtual void applyscaleadd (field_type alpha, const X& x, Y& y) const
|
||||||
{
|
{
|
||||||
A_.usmv(alpha,x,y);
|
A_.usmv(alpha,x,y);
|
||||||
wellMod_.applyWellModel(x, y );
|
//wellMod_.applyWellModel(x, y );
|
||||||
|
|
||||||
#if HAVE_MPI
|
#if HAVE_MPI
|
||||||
if( comm_ )
|
if( comm_ )
|
||||||
@ -950,13 +960,11 @@ namespace Opm {
|
|||||||
if (std::isnan(mass_balance_residual[phaseIdx])
|
if (std::isnan(mass_balance_residual[phaseIdx])
|
||||||
|| std::isnan(CNV[phaseIdx])
|
|| std::isnan(CNV[phaseIdx])
|
||||||
|| (phaseIdx < np && std::isnan(well_flux_residual[phaseIdx]))) {
|
|| (phaseIdx < np && std::isnan(well_flux_residual[phaseIdx]))) {
|
||||||
isRestart_ = true;
|
|
||||||
OPM_THROW(Opm::NumericalProblem, "NaN residual for phase " << phaseName);
|
OPM_THROW(Opm::NumericalProblem, "NaN residual for phase " << phaseName);
|
||||||
}
|
}
|
||||||
if (mass_balance_residual[phaseIdx] > maxResidualAllowed()
|
if (mass_balance_residual[phaseIdx] > maxResidualAllowed()
|
||||||
|| CNV[phaseIdx] > maxResidualAllowed()
|
|| CNV[phaseIdx] > maxResidualAllowed()
|
||||||
|| (phaseIdx < np && well_flux_residual[phaseIdx] > maxResidualAllowed())) {
|
|| (phaseIdx < np && well_flux_residual[phaseIdx] > maxResidualAllowed())) {
|
||||||
isRestart_ = true;
|
|
||||||
OPM_THROW(Opm::NumericalProblem, "Too large residual for phase " << phaseName);
|
OPM_THROW(Opm::NumericalProblem, "Too large residual for phase " << phaseName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1425,7 +1433,7 @@ namespace Opm {
|
|||||||
ebosSimulator_.problem().beginTimeStep();
|
ebosSimulator_.problem().beginTimeStep();
|
||||||
}
|
}
|
||||||
// if the last step failed we want to recalculate the IntesiveQuantities.
|
// if the last step failed we want to recalculate the IntesiveQuantities.
|
||||||
if (isRestart_) {
|
if ( invalidateIntensiveQuantitiesCache_ ) {
|
||||||
ebosSimulator_.model().invalidateIntensiveQuantitiesCache(/*timeIdx=*/0);
|
ebosSimulator_.model().invalidateIntensiveQuantitiesCache(/*timeIdx=*/0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1454,8 +1462,7 @@ namespace Opm {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
bool isBeginReportStep_;
|
bool isBeginReportStep_;
|
||||||
bool isRestart_;
|
bool invalidateIntensiveQuantitiesCache_;
|
||||||
|
|
||||||
};
|
};
|
||||||
} // namespace Opm
|
} // namespace Opm
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user