Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nonlinear solver: deal with failure #2744

Merged
merged 1 commit into from
Jul 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
tjhei marked this conversation as resolved.
Show resolved Hide resolved
{
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