Files
MeanField_SERiF/src/lib/serif/solver/linear/linear.cpp
Emily Boudreaux f520fe5f03 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
2026-11-09 13:25:52 -05:00

33 lines
1.7 KiB
C++

#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);
}
}