feat(operator): added matrix free inverter and SchurComplement operator

In order to maintain memory efficienty I have implimented a matrix free SchurComplement operator as well as an operator which uses a few iterations of GMRES to approxinate the inverse of any general operator.
This commit is contained in:
2025-05-18 15:32:08 -04:00
parent ddab27b833
commit b16ba8a7b6
2 changed files with 166 additions and 118 deletions

View File

@@ -26,6 +26,42 @@
#include "probe.h"
class SchurCompliment final : public mfem::Operator {
public:
SchurCompliment(const mfem::MixedBilinearForm &QOp, const mfem::BilinearForm &DOp, const mfem::MixedBilinearForm &MOp, const mfem::Solver &GradInvOp);
SchurCompliment(const mfem::MixedBilinearForm &QOp, const mfem::BilinearForm &DOp, const mfem::MixedBilinearForm &MOp);
~SchurCompliment() override = default;
void Mult(const mfem::Vector &x, mfem::Vector &y) const override;
void SetOperator(const mfem::MixedBilinearForm &QOp, const mfem::BilinearForm &DOp, const mfem::MixedBilinearForm &MOp, const mfem::Solver &GradInvOp);
void updateInverseNonlinearJacobian(const mfem::Solver &gradInv);
private:
void updateConstantTerms(const mfem::MixedBilinearForm &QOp, const mfem::BilinearForm &DOp, const mfem::MixedBilinearForm &MOp);
private:
// Note that these are not owned by this class
const mfem::MixedBilinearForm* m_QOp = nullptr;
const mfem::BilinearForm* m_DOp = nullptr;
const mfem::MixedBilinearForm* m_MOp = nullptr;
const mfem::Solver* m_GradInvOp = nullptr;
int m_nPhi = 0;
int m_nTheta = 0;
mutable std::unique_ptr<mfem::SparseMatrix> m_matrixForm;
};
class GMRESInverter final : public mfem::Operator {
public:
explicit GMRESInverter(const SchurCompliment& op);
~GMRESInverter() override = default;
void Mult(const mfem::Vector &x, mfem::Vector &y) const override;
private:
const SchurCompliment& m_op;
mfem::GMRESSolver m_solver;
};
class PolytropeOperator final : public mfem::Operator {
public:
PolytropeOperator(
@@ -70,13 +106,16 @@ private:
SSE::MFEMArrayPair m_theta_ess_tdofs;
SSE::MFEMArrayPair m_phi_ess_tdofs;
std::unique_ptr<mfem::SparseMatrix> m_Mmat, m_Qmat, m_Dmat;
// std::unique_ptr<mfem::SparseMatrix> m_Mmat, m_Qmat, m_Dmat;
std::unique_ptr<mfem::ScaledOperator> m_negM_op;
std::unique_ptr<mfem::ScaledOperator> m_negQ_op;
mutable std::unique_ptr<mfem::BlockOperator> m_jacobian;
mutable std::unique_ptr<mfem::SparseMatrix> m_invSchurCompliment;
mutable std::unique_ptr<mfem::SparseMatrix> m_invNonlinearJacobian;
// mutable std::unique_ptr<mfem::SparseMatrix> m_invSchurCompliment;
// mutable std::unique_ptr<mfem::SparseMatrix> m_invNonlinearJacobian;
mutable std::unique_ptr<SchurCompliment> m_schurCompliment;
mutable std::unique_ptr<GMRESInverter> m_invSchurCompliment;
mutable std::unique_ptr<mfem::Solver> m_invNonlinearJacobian;
/*
* The schur preconditioner has the form
@@ -91,10 +130,10 @@ private:
mutable std::unique_ptr<mfem::BlockDiagonalPreconditioner> m_schurPreconditioner;
bool m_isFinalized = false;
double m_polytropicIndex;
private:
void updateInverseNonlinearJacobian(const mfem::Operator &grad) const;
void updateInverseSchurCompliment() const;
void updatePreconditioner(const mfem::Operator &grad) const;
};