schur.cpp serif/solver/preconditioner/backend/mfem/gravity/schur.hpp cmath serif/solver/preconditioner/backend/mfem/inverse/validation.hpp serif serif::solver serif::solver::preconditioner serif::solver::preconditioner::backend serif::solver::preconditioner::backend::mfem #include"serif/solver/preconditioner/backend/mfem/gravity/schur.hpp" #include<cmath> #include"serif/solver/preconditioner/backend/mfem/inverse/validation.hpp" namespaceserif::solver::preconditioner::backend::mfem { std::expected<std::shared_ptr<const::mfem::SparseMatrix>,Failure>try_gravity_schur(const::mfem::SparseMatrix&divergence,conststd::span<constdouble>mapped_mass_diagonal) { usingenumutils::errors::SERiFErrorCode; if(!divergence.Finalized()||divergence.Height()<=0||divergence.Width()<=0||mapped_mass_diagonal.size()!=static_cast<std::size_t>(divergence.Width())) { returndetail::failure<PRECONDITIONER_SIZE_MISMATCH>("ThegravitySchursurrogaterequiresfinalizedcomputationaldivergenceandonemappedmassentrypergradientcoordinate."); } ::mfem::Vectorreciprocal(divergence.Width()); for(intindex=0;index<reciprocal.Size();++index) { constdoubleentry=mapped_mass_diagonal[index]; if(!std::isfinite(entry)||entry<=0.0||!std::isfinite(1.0/entry)) { returndetail::failure<PRECONDITIONER_INVALID_OPERATOR>("Mappedmassentry{}mustbepositive,finiteandhavearepresentablereciprocalbeforeformingthegravitySchursurrogate.",index); } reciprocal[index]=1.0/entry; } for(intindex=0;index<divergence.NumNonZeroElems();++index) { if(!std::isfinite(divergence.GetData()[index])) { returndetail::failure<PRECONDITIONER_NONFINITE_VALUE>("Computationaldivergencecontainsanonfinitecoefficient."); } } ::mfem::SparseMatrixweighted(divergence); weighted.ScaleColumns(reciprocal); conststd::unique_ptr<::mfem::SparseMatrix>transpose(::mfem::Transpose(divergence)); conststd::shared_ptr<const::mfem::SparseMatrix>schur(::mfem::Mult(weighted,*transpose)); for(intindex=0;index<schur->NumNonZeroElems();++index) { if(!std::isfinite(schur->GetData()[index])) { returndetail::failure<PRECONDITIONER_NONFINITE_VALUE>("ThegravitySchurproductoverflowed.Rescalethefieldcoordinatesbeforepreparingitsinverse."); } } returnschur; } }//namespaceserif::solver::preconditioner::backend::mfem