feat(polytrope-operator): finished computing the preconditioner
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user