feat(solver/linear): Implemented a few linear solver frontends
As with much of the code, the actual solvers are implemented (through MFEM) in the backend. This provides an interface so we can more easily swap out the linear solvers on the backend in the future
This commit is contained in:
32
src/lib/serif/solver/linear/linear.cpp
Normal file
32
src/lib/serif/solver/linear/linear.cpp
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "serif/solver/linear/linear.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <stdexcept>
|
||||
#include "serif/utils/error/errors.hpp"
|
||||
|
||||
namespace serif::solver::linear {
|
||||
void Control::validate() const {
|
||||
utils::errors::serif_ensure<utils::errors::SERiFErrorCode::SOLVER_ERROR, std::invalid_argument>(
|
||||
std::isfinite(relative_tolerance) && relative_tolerance >= 0.0 &&
|
||||
std::isfinite(absolute_tolerance) && absolute_tolerance >= 0.0 && maximum_iterations > 0,
|
||||
"A linear solve needs finite nonnegative tolerances and a positive iteration budget; received {}, {}, and {}.",
|
||||
relative_tolerance, absolute_tolerance, maximum_iterations);
|
||||
}
|
||||
|
||||
double Control::convergence_threshold(double right_hand_side_norm) const {
|
||||
validate();
|
||||
const double relative_threshold = relative_tolerance * right_hand_side_norm;
|
||||
utils::errors::serif_ensure<utils::errors::SERiFErrorCode::SOLVER_ERROR, std::invalid_argument>(
|
||||
std::isfinite(right_hand_side_norm) && right_hand_side_norm >= 0.0 && std::isfinite(relative_threshold),
|
||||
"A linear convergence threshold needs a finite nonnegative right-hand-side norm and finite product with the relative tolerance; received {}.",
|
||||
right_hand_side_norm);
|
||||
return std::max(absolute_tolerance, relative_threshold);
|
||||
}
|
||||
|
||||
void FGMRES::validate() const {
|
||||
utils::errors::serif_ensure<utils::errors::SERiFErrorCode::SOLVER_ERROR, std::invalid_argument>(
|
||||
restart_length > 0 && print_level >= -1 && print_level <= 3,
|
||||
"FGMRES needs a positive restart length and print level between -1 and 3; received {} and {}.", restart_length, print_level);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user