Skip to content

Commit

Permalink
Merge pull request #2744 from tjhei/nonlinear_fail_strategy
Browse files Browse the repository at this point in the history
Nonlinear solver: deal with failure
  • Loading branch information
gassmoeller authored Jul 24, 2024
2 parents 07c763f + f50bd8b commit 694655a
Show file tree
Hide file tree
Showing 106 changed files with 1,236 additions and 72 deletions.
33 changes: 33 additions & 0 deletions include/aspect/parameters.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,38 @@ namespace aspect
false;
}

/**
* A struct that contains the enums to decide what to do when a nonlinear solver fails.
*/
struct NonlinearSolverFailureStrategy
{
enum Kind
{
continue_with_next_timestep,
cut_timestep_size,
abort_program
};

/**
* Parse the enum value from a string.
*/
static
Kind
parse(const std::string &input)
{
if (input == "continue with next timestep")
return continue_with_next_timestep;
else if (input == "cut timestep size")
return cut_timestep_size;
else if (input == "abort program")
return abort_program;
else
AssertThrow(false, ExcNotImplemented());

return Kind();
}
};

/**
* @brief The NullspaceRemoval struct
*/
Expand Down Expand Up @@ -484,6 +516,7 @@ namespace aspect
* @{
*/
typename NonlinearSolver::Kind nonlinear_solver;
typename NonlinearSolverFailureStrategy::Kind nonlinear_solver_failure_strategy;

typename AdvectionStabilizationMethod::Kind advection_stabilization_method;
double nonlinear_tolerance;
Expand Down
9 changes: 9 additions & 0 deletions include/aspect/simulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,14 @@ namespace aspect
Tensor<1,dim> tensor_rotation;
};

/**
* Exception to be thrown when the nonlinear solver needs too many iterations to converge.
*/
DeclExceptionMsg(ExcNonlinearSolverNoConvergence,
"Nonlinear solver failed to converge in the prescribed number of steps. "
"Consider changing `Max nonlinear iterations` or `Nonlinear solver failure "
"strategy`.");

/**
* This is the main class of ASPECT. It implements the overall simulation
* algorithm using the numerical methods discussed in the papers and manuals
Expand Down Expand Up @@ -1995,6 +2003,7 @@ namespace aspect
unsigned int timestep_number;
unsigned int pre_refinement_step;
unsigned int nonlinear_iteration;
unsigned int nonlinear_solver_failures;
/**
* @}
*/
Expand Down
3 changes: 2 additions & 1 deletion include/aspect/time_stepping/interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,6 @@ namespace aspect
void
write_plugin_graph (std::ostream &output_stream);


/**
* A function that is used to register time stepping model objects in such
* a way that the Manager can deal with all of them without having to
Expand Down Expand Up @@ -259,6 +258,8 @@ namespace aspect
TerminationCriteria::Manager<dim> termination_manager;
};



/**
* Given a class name, a name, and a description for the parameter file, register it with the
* aspect::TimeStepping::Manager class.
Expand Down
106 changes: 106 additions & 0 deletions include/aspect/time_stepping/repeat_on_nonlinear_fail.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*
Copyright (C) 2018 - 2023 by the authors of the ASPECT code.
This file is part of ASPECT.
ASPECT is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
ASPECT is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ASPECT; see the file LICENSE. If not see
<http://www.gnu.org/licenses/>.
*/


#ifndef _aspect_time_stepping_repeat_on_nonlinear_fail_h
#define _aspect_time_stepping_repeat_on_nonlinear_fail_h

#include <aspect/time_stepping/interface.h>

namespace aspect
{
namespace TimeStepping
{
using namespace dealii;

/**
* A class that implements a time stepping plugin to repeat a time step if the
* nonlinear solver failed to converge in the specified number of iterations.
* The timestep size will be reduced by the given amount specified by the user
* and hopefully results in the nonlinear solver converging. If necessary, the
* timestep size will be repeatedly reduced.
*
* This class is automatically enabled if the user specifies that he/she wants
* to do this.
*
* @ingroup TimeStepping
*/
template <int dim>
class RepeatOnNonlinearFail : public Interface<dim>, public SimulatorAccess<dim>
{
public:
/**
* Constructor.
*/
RepeatOnNonlinearFail ();

/**
* @copydoc aspect::TimeStepping::Interface<dim>::execute()
*/
double
execute() override;

/**
* This function notifies the plugin that the nonlinear solver
* failed.
*/
void nonlinear_solver_has_failed() const;

/**
* The main execute() function.
*/
std::pair<Reaction, double>
determine_reaction(const TimeStepInfo &info) override;

static
void
declare_parameters (ParameterHandler &prm);

void
parse_parameters (ParameterHandler &prm) override;

private:
/**
* Parameter to determine how much smaller the time step should be
* repeated as.
*/
double cut_back_factor;

/**
* Enabled by nonlinear_solver_has_failed() to signal that this
* plugin needs to act in the current timestep;
*/
mutable bool nonlinear_solver_just_failed;

/**
* How many times should we try cutting the timestep size before giving up?
*/
unsigned int maximum_number_of_repeats;

/**
* How many times have we been repeating already in this timestep?
*/
unsigned int current_number_of_repeats;
};
}
}


#endif
Loading

0 comments on commit 694655a

Please sign in to comment.