qualification.hpp algorithm cmath expected span serif/solver/nonlinear/result.hpp serif/utils/error/errors.hpp src/include/serif/solver/nonlinear/steps.hpp serif::solver::detail::NewtonFailure serif serif::solver serif::solver::detail #pragmaonce #include<algorithm> #include<cmath> #include<expected> #include<span> #include"serif/solver/nonlinear/result.hpp" #include"serif/utils/error/errors.hpp" namespaceserif::solver::detail{ [[nodiscard]]inlinestd::optional<std::string>preparation_rejection(constauto&problem,constauto&evaluation){ if(evaluation){ returnstd::nullopt; } utils::errors::serif_ensure<utils::errors::SERiFErrorCode::INVALID_ARGUMENT>(problem.recoverable(evaluation.error()), "Equilibriumpreparationhasaninvalidconfiguration:{}",problem.failure_message(evaluation.error())); returnproblem.failure_message(evaluation.error()); } structNewtonFailure{ SolveStatusstatus{SolveStatus::initial_state_rejected}; std::stringmessage; }; [[nodiscard]]inlinestd::expected<MetricEvaluation,NewtonFailure>qualify_candidate(auto&problem,constauto&state, constauto&evaluation,auto&metric_function,auto&strategy,TrialAssessmentassessment={}){ if(constautorejection=preparation_rejection(problem,evaluation)){ returnstd::unexpected(NewtonFailure{.message=*rejection}); } if(assessment.usable){ assessment=strategy.admissible(problem,state); } if(!assessment.usable){ returnstd::unexpected(NewtonFailure{.message=std::move(assessment.message)}); } constMetricEvaluationmetric=metric_function((*evaluation)->residual()); if(!metric.valid()){ returnstd::unexpected(NewtonFailure{.status=SolveStatus::invalid_metric, .message="Thenonlinearmetricisnotfiniteandnonnegative."}); } returnmetric; } [[nodiscard]]inlineboolfinite_correction(std::span<constdouble>correction,constintexpected_size){ usingnamespaceutils::errors; serif_ensure<SERiFErrorCode::INVALID_DOF_COUNT>(static_cast<int>(correction.size())==expected_size, "ThelinearbackendchangedtheNewtoncorrectionsizefrom{}to{}.Returnonecorrectionforeverysolvedcoordinate.",expected_size,static_cast<int>(correction.size())); returnstd::ranges::all_of(correction,[](doublevalue){returnstd::isfinite(value);}); } }