feat(jacobian): Added regularization

There are times when the jacobian matrix has infinities or nans. If
these cases correspond to species (rows or columns) which have
effectivley zero abundance (i.e. if Y(Cl-32) ~ 1e-310 and
(dY(H-2)/dt)/dY(Cl-32) is inf) then it is safe to regularize these
entries to 0. If this is not done then the solver will end up finding
NaN values for the molar abundances on subsequent steps. This has been
implimented through a small regularization function in the
CVODE_solver_strategy file.
This commit is contained in:
2025-11-14 18:49:29 -05:00
parent 2ed629e0bf
commit b5d76e3728
7 changed files with 365 additions and 16 deletions

View File

@@ -9,6 +9,8 @@
#include <unordered_map>
namespace gridfire {
using JacobianEntry = std::pair<std::pair<fourdst::atomic::Species, fourdst::atomic::Species>, double>;
class NetworkJacobian {
public:
explicit NetworkJacobian(
@@ -16,6 +18,10 @@ namespace gridfire {
const std::function<fourdst::atomic::Species(size_t)> &indexToSpeciesFunc
);
NetworkJacobian(const NetworkJacobian& jacobian);
NetworkJacobian(NetworkJacobian&& jacobian) noexcept;
NetworkJacobian& operator=(NetworkJacobian&& jacobian) noexcept;
double operator()(
const fourdst::atomic::Species& row,
const fourdst::atomic::Species& col
@@ -26,12 +32,34 @@ namespace gridfire {
size_t j
) const;
void set(
const fourdst::atomic::Species& row,
const fourdst::atomic::Species& col,
double value
);
void set(
size_t i,
size_t j,
double value
);
void set(
const JacobianEntry &entry
);
std::tuple<size_t, size_t> shape() const;
size_t rank() const;
size_t nnz() const;
bool singular() const;
[[nodiscard]] std::vector<JacobianEntry> infs() const;
[[nodiscard]] std::vector<JacobianEntry> nans() const;
[[nodiscard]] Eigen::SparseMatrix<double> data() const;
[[nodiscard]] const std::unordered_map<fourdst::atomic::Species, size_t>& mapping() const;
private:
Eigen::SparseMatrix<double> m_jacobianMatrix;
std::unordered_map<fourdst::atomic::Species, size_t> m_speciesToIndexMap;

View File

@@ -22,4 +22,8 @@ namespace gridfire::exceptions {
class SingularJacobianError final : public SolverError {
using SolverError::SolverError;
};
class IllConditionedJacobianError final : public SolverError {
using SolverError::SolverError;
};
}