feat(polytrope-operator): finished computing the preconditioner

This commit is contained in:
2025-04-21 08:04:49 -04:00
parent 274f24034c
commit 4a6b7aaa35
2 changed files with 10 additions and 23 deletions

View File

@@ -193,10 +193,9 @@ void PolytropeOperator::Mult(const mfem::Vector &x, mfem::Vector &y) const {
// Trying to understand the multimodal hump in the residuals vector.
// There is a jupyter notebook about this. I was thinking that this was
// perhapse related to the non consistent application of boundary conditions.
void approxJacobiInvert(const mfem::SparseMatrix& mat, std::unique_ptr<mfem::SparseMatrix>& invMat, std::string name="matrix") {
// TODO: This likely can be made much more efficient and will probably be called in tight loops, a good
// place for some easy optimization might be here.
// Get the diagonal of the matrix
void approxJacobiInvert(const mfem::SparseMatrix& mat, std::unique_ptr<mfem::SparseMatrix>& invMat, const std::string& name="matrix") {
// PERF: This likely can be made much more efficient and will probably be called in tight loops, a good
// PERF: place for some easy optimization might be here.
mfem::Vector diag;
mat.GetDiag(diag);
@@ -230,23 +229,12 @@ void PolytropeOperator::updateInverseSchurCompliment() const {
mfem::SparseMatrix* temp_QxdfInv = mfem::Mult(*m_Qmat, *m_invNonlinearJacobian); // Q * df^{-1}
mfem::SparseMatrix* temp_QxdfInvxM = mfem::Mult(*temp_QxdfInv, *m_Mmat); // Q * df^{-1} * M
// PERF: Could potentially add some caching in here to only update the preconditioner when some condition has been met
schurCompliment->Add(-1, *temp_QxdfInvxM); // D - Q * df^{-1} * M
approxJacobiInvert(*schurCompliment, m_invSchurCompliment, "Schur Compliment");
// Note: EMB (April 9, 2025) Where I left for the day, so I don't pull my hair out tomorrow:
/*
* Need to calculate the inverse of Schur's compliment to precondition the jacobian
* I think I have this close; however, when running there is a seg fault when converting to a DenseMatrix for
* writing out to CSV. This bodes poorly for the underlying memory structure.
*
* Also, there is a lot of math happening in these tight loops, probably need to think about that and
* make it more efficient.
*/
// TODO Also I need to actually invert the schur compliment since so far I have just found its non inverted state
// Should probably add an energy check to make sure it is roughly diagonal
// I did this manually in python for the non linear jacobian and the energy along the diagonal was ~99.999 % of the
// total energy indicating that it is very strongly diagonal.
m_schurPreconditioner->SetDiagonalBlock(0, m_invNonlinearJacobian.get());
m_schurPreconditioner->SetDiagonalBlock(1, m_invSchurCompliment.get());
}
mfem::Operator& PolytropeOperator::GetGradient(const mfem::Vector &x) const {

View File

@@ -64,15 +64,14 @@ private:
/*
* The schur preconditioner has the form
*
* | df/drtheta^-1 0 |
* | 0 S^-1 |
* ⎡ḟ(θ)^-1 0 ⎤
* ⎣ 0 S^-1
*
* Where S is the Schur compliment of the system
*
*/
// TODO: I have not combined these parts yet and they need to be combined
mutable std::unique_ptr<mfem::SparseMatrix> m_schurPreconditioner;
mutable std::unique_ptr<mfem::BlockDiagonalPreconditioner> m_schurPreconditioner;
bool m_isFinalized = false;