stellar_problem.hpp expected string variant serif/backend/mfem/solver/admissibility/geometry.hpp serif/backend/mfem/model/equilibrium.hpp serif/solver/nonlinear/options.hpp serif/backend/mfem/solver/linear/solve.hpp serif/types.hpp src/include/serif/backend/mfem/solver/equilibrium.hpp serif::solver::backend::mfem::StellarProblem serif serif::solver serif::solver::backend serif::solver::backend::mfem #pragmaonce #include<expected> #include<string> #include<variant> #include"serif/backend/mfem/solver/admissibility/geometry.hpp" #include"serif/backend/mfem/model/equilibrium.hpp" #include"serif/solver/nonlinear/options.hpp" #include"serif/backend/mfem/solver/linear/solve.hpp" #include"serif/types.hpp" namespaceserif::solver::backend::mfem{ template<typenameEvaluator,typenameInputs=utils::dependencies::DependencyContext<>> classStellarProblem{ public: usingVector=serif::Vector; usingSystem=std::remove_const_t<typenameEvaluator::Result::element_type>; usingModel=std::remove_cvref_t<decltype(std::declval<constEvaluator&>().model())>; usingLayout=typenameEvaluator::Layout; usingFailure=typenameEvaluator::Cache::Failure; StellarProblem(Evaluatorevaluator,Inputsprescribed=Inputs{},::mfem::Vectordisplacement={}): m_evaluator(std::move(evaluator)),m_prescribed(std::move(prescribed)),m_fixed_displacement(std::move(displacement)){} [[nodiscard]]automodel_owner()const{returnm_evaluator.binding().model;} [[nodiscard]]constauto&binding()const{returnm_evaluator.binding();} [[nodiscard]]constLayout&layout()const{returnm_evaluator.layout();} [[nodiscard]]Evaluator&evaluator(){returnm_evaluator;} [[nodiscard]]autoevaluate(constmodel::StellarState<Layout>&state){ returninvoke([&](constauto&...geometry){returnm_evaluator.evaluate(state,geometry...,m_prescribed);}); } [[nodiscard]]autoprepare(constmodel::StellarState<Layout>&state){ returninvoke([&](constauto&...geometry){returnm_evaluator.prepare_linear_system(state,geometry...,m_prescribed);}); } [[nodiscard]]linear::Reportsolve_linear(constauto&prepared,constVector&rhs,Vector&correction,constauto&options){ returnlinear::backend::mfem::solve(options.linear_solver,prepared->system()->jacobian(), prepared->preconditioner(),prepared->contract(),rhs,correction,options.method.linear_solve); } [[nodiscard]]staticstd::stringfailure_message(constFailure&failure){ returnstd::visit([](constauto&error)->std::string{ ifconstexpr(std::same_as<std::remove_cvref_t<decltype(error)>,std::string>){ returnerror; }else{ returnstd::string(error.message); } },failure.error); } [[nodiscard]]staticstd::stringfailure_message(constgeometry::deformation::DeformationFailure&failure){ returnfailure.message; } [[nodiscard]]staticboolrecoverable(constFailure&failure){ returnstd::visit([](constauto&error){ usingError=std::remove_cvref_t<decltype(error)>; ifconstexpr(std::same_as<Error,geometry::deformation::DeformationFailure>){ usingReason=geometry::deformation::DeformationFailureReason; returnerror.reason==Reason::non_finite||error.reason==Reason::unresolved_surface||error.reason==Reason::invalid_geometry; }elseifconstexpr(std::same_as<Error,geometry::surface::SurfaceFailure>){ usingReason=geometry::surface::SurfaceFailureReason; returnerror.reason==Reason::non_finite_state||error.reason==Reason::non_finite_eos_response||error.reason==Reason::non_finite_linearization; }elseifconstexpr(std::same_as<Error,preconditioner::Failure>){ returntrue; }elseifconstexpr(std::same_as<Error,operators::backend::mfem::PreparationRejection>){ returnerror.reason!=operators::backend::mfem::PreparationRejectionReason::MAPPING|| (error.mapping_status!=mapping::MappingStatus::INVALID_DIMENSION&& error.mapping_status!=mapping::MappingStatus::INVALID_REFERENCE_RADIUS); }else{ returnfalse; } },failure.error); } [[nodiscard]]autogeometry_limit(constmodel::StellarState<Layout>&state,std::span<constdouble>direction, constdoublemaximum_step,constdoublesafety,constboolenabled){ returnm_geometry.limit(m_evaluator,state,direction,maximum_step,safety,enabled); } [[nodiscard]]doublenext_step(constdoublestep,constBacktracking&options,constauto&evaluation)const{ returnm_geometry.next(m_evaluator,step,options,!evaluation&&inverted(evaluation.error())); } private: [[nodiscard]]autoinvoke(autocallback){ ifconstexpr(Evaluator::Plan::has_shape){ returncallback(); }else{ returncallback(m_fixed_displacement); } } [[nodiscard]]staticboolinverted(constFailure&failure){ if(constauto*rejection=std::get_if<operators::backend::mfem::PreparationRejection>(&failure.error)){ returnrejection->reason==operators::backend::mfem::PreparationRejectionReason::MAPPING&& rejection->mapping_status==mapping::MappingStatus::NON_POSITIVE_DETERMINATE; } if(constauto*deformation=std::get_if<geometry::deformation::DeformationFailure>(&failure.error)){ returndeformation->reason==geometry::deformation::DeformationFailureReason::invalid_geometry; } returnfalse; } Evaluatorm_evaluator; Inputsm_prescribed; ::mfem::Vectorm_fixed_displacement; admissibility::backend::mfem::GeometryDirectionm_geometry; }; }