Skip to content

Commit

Permalink
Clean out fixed point executioner for linear systems. (idaholab#28819)
Browse files Browse the repository at this point in the history
  • Loading branch information
grmnptr committed Oct 22, 2024
1 parent 9fcc640 commit bda4ab9
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 155 deletions.
28 changes: 7 additions & 21 deletions framework/include/executioners/LinearFixedPointSteady.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,14 @@
#pragma once

#include "Executioner.h"
#include "PetscSupport.h"
#include "libmesh/solver_configuration.h"
#include "LinearFixedPointSolve.h"

// Forward declarations
class InputParameters;
class FEProblemBase;

/**
* Solver configuration class used with the linear solvers in a SIMPLE solver.
*/
class LinearFixedPointSolverConfiguration : public libMesh::SolverConfiguration
{
/**
* Override this to make sure the PETSc options are not overwritten in the linear solver
*/
virtual void configure_solver() override {}
};

/**
* LinearFixedPointSteady executioners call "solve()" on two different nonlinear systems in sequence
* Executioner to solve multiple linear systems in a fixed point manner
*/
class LinearFixedPointSteady : public Executioner
{
Expand All @@ -45,18 +33,16 @@ class LinearFixedPointSteady : public Executioner
protected:
bool solveSystem(const unsigned int sys_number, const Moose::PetscSupport::PetscOptions * po);

FEProblemBase & _problem;
/// The solve object
LinearFixedPointSolve _solve;

/// Time-related variables
Real _system_time;
int & _time_step;
Real & _time;

private:
const std::vector<LinearSystemName> & _linear_sys_names;
std::vector<unsigned int> _linear_sys_numbers;
std::vector<Moose::PetscSupport::PetscOptions> _petsc_options;

/// Flag to check if the last solve converged or not
bool _last_solve_converged;
const unsigned int _number_of_iterations;
const bool _print_operators_and_vectors;

};
182 changes: 48 additions & 134 deletions framework/src/executioners/LinearFixedPointSteady.C
Original file line number Diff line number Diff line change
Expand Up @@ -23,179 +23,93 @@ registerMooseObject("MooseTestApp", LinearFixedPointSteady);
InputParameters
LinearFixedPointSteady::validParams()
{
InputParameters params = Executioner::validParams();
params.addRequiredParam<std::vector<LinearSystemName>>(
"linear_systems_to_solve",
"The names of linear systems to solve in the order which they should be solved");
params.addRangeCheckedParam<unsigned int>("number_of_iterations",
1,
"number_of_iterations>0",
"The number of iterations between the two systems.");

params.addParam<std::vector<std::vector<std::string>>>(
"petsc_options", {}, "Singleton PETSc options for each linear equation");
params.addParam<std::vector<std::vector<std::string>>>(
"petsc_options_iname", {}, "Names of PETSc name/value pairs for each linear equation");
params.addParam<std::vector<std::vector<std::string>>>(
"petsc_options_value",
{},
"Values of PETSc name/value pairs (must correspond with \"petsc_options_iname\" for each "
"linear equation");

params.addParam<bool>(
"print_operators_and_vectors",
false,
"Print system matrix, right hand side and solution for the linear systems.");
InputParameters params = LinearFixedPointSolve::validParams();
params += Executioner::validParams();

return params;
}

LinearFixedPointSteady::LinearFixedPointSteady(const InputParameters & parameters)
: Executioner(parameters),
_problem(_fe_problem),
_time_step(_problem.timeStep()),
_time(_problem.time()),
_linear_sys_names(getParam<std::vector<LinearSystemName>>("linear_systems_to_solve")),
_petsc_options(_linear_sys_names.size()),
_number_of_iterations(getParam<unsigned int>("number_of_iterations")),
_print_operators_and_vectors(getParam<bool>("print_operators_and_vectors"))
_solve(*this),
_time_step(_fe_problem.timeStep()),
_time(_fe_problem.time())
{
const auto & raw_petsc_options = getParam<std::vector<std::vector<std::string>>>("petsc_options");
const auto & raw_petsc_options_iname =
getParam<std::vector<std::vector<std::string>>>("petsc_options_iname");
const auto & raw_petsc_options_value =
getParam<std::vector<std::vector<std::string>>>("petsc_options_value");

if (raw_petsc_options.size() > 1 && raw_petsc_options.size() != _linear_sys_numbers.size())
paramError("petsc_options", "Petsc options should be defined for every system separately!");

if (raw_petsc_options_iname.size() > 1 &&
raw_petsc_options_iname.size() != _linear_sys_numbers.size())
paramError("petsc_options_iname",
"Petsc option keys should be defined for every system separately!");

if (raw_petsc_options_value.size() != raw_petsc_options_iname.size())
paramError(
"petsc_options_value",
"Petsc option values should be defined for the same number of system as in the keys!");

for (const auto i : index_range(_linear_sys_names))
{
_linear_sys_numbers.push_back(_problem.linearSysNum(_linear_sys_names[i]));

MultiMooseEnum enum_singles = Moose::PetscSupport::getCommonPetscFlags();

if (raw_petsc_options.size() == 1)
enum_singles = raw_petsc_options[0];
else if (raw_petsc_options.size() > 1)
enum_singles = raw_petsc_options[i];

MultiMooseEnum enum_pair_keys = Moose::PetscSupport::getCommonPetscKeys();
if (raw_petsc_options_iname.size() == 1)
enum_pair_keys = raw_petsc_options_iname[0];
else if (raw_petsc_options_iname.size() > 1)
enum_pair_keys = raw_petsc_options_iname[i];

std::vector<std::string> enum_pair_values;
if (raw_petsc_options_value.size() == 1)
enum_pair_values = raw_petsc_options_value[0];
else if (raw_petsc_options_value.size() > 1)
enum_pair_values = raw_petsc_options_value[i];

if (enum_pair_keys.size() != enum_pair_values.size())
paramError("petsc_options_value",
"The size of petsc option values for system " + _linear_sys_names[i] + " (" +
std::to_string(enum_pair_keys.size()) +
") does not match the size of the input arguments (" +
std::to_string(enum_pair_values.size()) + ")!");

std::vector<std::pair<MooseEnumItem, std::string>> raw_iname_value_pairs;
for (const auto j : index_range(enum_pair_values))
raw_iname_value_pairs.push_back(std::make_pair(enum_pair_keys[j], enum_pair_values[j]));

Moose::PetscSupport::processPetscFlags(enum_singles, _petsc_options[i]);
Moose::PetscSupport::processPetscPairs(
raw_iname_value_pairs, _problem.mesh().dimension(), _petsc_options[i]);
}

_time = 0;
_fixed_point_solve->setInnerSolve(_solve);
_time = _system_time;
}

void
LinearFixedPointSteady::init()
{
if (_app.isRecovering())
{
_console << "\nCannot recover steady solves!\nExiting...\n" << std::endl;
return;
}

_problem.initialSetup();
_fe_problem.execute(EXEC_PRE_MULTIAPP_SETUP);
_fe_problem.initialSetup();
}

void
LinearFixedPointSteady::execute()
{
if (_app.isRecovering())
{
_console << "\nCannot recover steady solves!\nExiting...\n" << std::endl;
return;
}

_time_step = 0;
_problem.outputStep(EXEC_INITIAL);
_time = _time_step;
_fe_problem.outputStep(EXEC_INITIAL);
_time = _system_time;

preExecute();

// first step in any steady state solve is always 1 (preserving backwards compatibility)
_time_step = 1;

_problem.timestepSetup();
#ifdef LIBMESH_ENABLE_AMR

preSolve();
_problem.execute(EXEC_TIMESTEP_BEGIN);
_problem.outputStep(EXEC_TIMESTEP_BEGIN);
_problem.updateActiveObjects();
// Define the refinement loop
unsigned int steps = _fe_problem.adaptivity().getSteps();
for (unsigned int r_step = 0; r_step <= steps; r_step++)
{
#endif // LIBMESH_ENABLE_AMR
_fe_problem.timestepSetup();

_last_solve_converged = _fixed_point_solve->solve();

for (unsigned int i = 0; i < _number_of_iterations; i++)
for (const auto sys_index : index_range(_linear_sys_numbers))
if (!lastSolveConverged())
{
const auto & options = _petsc_options[sys_index];
solveSystem(_linear_sys_numbers[sys_index], &options);
_console << "Aborting as solve did not converge" << std::endl;
break;
}

for (const auto sys_number : _linear_sys_numbers)
_problem.getLinearSystem(sys_number).computeGradients();
_fe_problem.computeIndicators();
_fe_problem.computeMarkers();

_last_solve_converged = true;
// need to keep _time in sync with _time_step to get correct output
_time = _time_step;
_fe_problem.outputStep(EXEC_TIMESTEP_END);
_time = _system_time;

// need to keep _time in sync with _time_step to get correct output
_time = _time_step;
_problem.execute(EXEC_TIMESTEP_END);
_problem.outputStep(EXEC_TIMESTEP_END);
_time = _system_time;
#ifdef LIBMESH_ENABLE_AMR
if (r_step != steps)
{
_fe_problem.adaptMesh();
}

_time_step++;
}
#endif

{
TIME_SECTION("final", 1, "Executing Final Objects")
_problem.postExecute();
_problem.execute(EXEC_FINAL);
_fe_problem.execMultiApps(EXEC_FINAL);
_fe_problem.finalizeMultiApps();
_fe_problem.postExecute();
_fe_problem.execute(EXEC_FINAL);
_time = _time_step;
_problem.outputStep(EXEC_FINAL);
_fe_problem.outputStep(EXEC_FINAL);
_time = _system_time;
}

postExecute();
}

bool
LinearFixedPointSteady::solveSystem(const unsigned int sys_number,
const Moose::PetscSupport::PetscOptions * po)
{
_problem.solveLinearSystem(sys_number, po);
if (_print_operators_and_vectors)
{
auto & sys = _problem.getLinearSystem(sys_number);
LinearImplicitSystem & lisystem = libMesh::cast_ref<LinearImplicitSystem &>(sys.system());
lisystem.matrix->print();
lisystem.rhs->print();
lisystem.solution->print();
}

return true;
}

0 comments on commit bda4ab9

Please sign in to comment.