solver.cpp serif/backend/mfem/solver/preconditioner/solver.hpp utility serif/utils/error/errors.hpp serif serif::solver serif::solver::preconditioner serif::solver::preconditioner::backend serif::solver::preconditioner::backend::mfem #include"serif/backend/mfem/solver/preconditioner/solver.hpp" #include<utility> #include"serif/utils/error/errors.hpp" namespaceserif::solver::preconditioner::backend::mfem { Solver::Solver(Inverseinverse,OperatorHandlejacobian):m_inverse(std::move(inverse)),m_jacobian(std::move(jacobian)) { usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::PRECONDITIONER_INVALID_OPERATOR>(m_inverse.action&&m_jacobian, "ThepreconditioneradapterneedsanacceptedinverseandphysicalJacobian.Preparebothbeforebindingthesolver."); height=m_inverse.action->Height(); width=m_inverse.action->Width(); serif_ensure<SERiFErrorCode::PRECONDITIONER_SIZE_MISMATCH>(height==m_jacobian->Width()&&width==m_jacobian->Height(), "TheinversedimensionsdonotreversethephysicalJacobiandimensions.Bindmatchingacceptedoperators."); m_input.SetSize(width); m_output.SetSize(height); iterative_mode=false; } voidSolver::SetOperator(const::mfem::Operator&jacobian) { utils::errors::serif_ensure<utils::errors::SERiFErrorCode::PRECONDITIONER_STALE_LINEARIZATION>(&jacobian==m_jacobian.get(), "ThispreconditionerbelongstoadifferentacceptedJacobian.Prepareandbindanewinverseforthenewlinearization."); } voidSolver::Mult(const::mfem::Vector&input,::mfem::Vector&output)const { utils::errors::serif_ensure<utils::errors::SERiFErrorCode::PRECONDITIONER_SIZE_MISMATCH>(input.Size()==width&&output.Size()==height, "Preconditionerapplicationneeds{}residualand{}statecoefficientsinpreallocatedvectors;received{}and{}.",width,height,input.Size(),output.Size()); m_input=input; m_output=0.0; m_inverse.action->Mult(m_input,m_output); output=m_output; } ApplicationContractSolver::contract()constnoexcept { returnm_inverse.contract; } }//namespaceserif::solver::preconditioner::backend::mfem