fitted.hpp algorithm cmath limits serif/backend/mfem/geometry/deformation/computations.hpp serif/solver/seed/fitted.hpp serif/utils/dependencies/computation_cache.hpp src/include/serif/backend/mfem/solver/seed/state.hpp src/include/serif/solver/seed/state.hpp serif serif::solver serif::solver::seed serif::solver::seed::backend serif::solver::seed::backend::mfem serif::solver::seed::backend::mfem::detail #pragmaonce #include<algorithm> #include<cmath> #include<limits> #include"serif/backend/mfem/geometry/deformation/computations.hpp" #include"serif/solver/seed/fitted.hpp" #include"serif/utils/dependencies/computation_cache.hpp" namespaceserif::solver::seed::backend::mfem{ namespacedetail{ template<typenameDiscretization> [[nodiscard]]autoradial_seed_surface(constDiscretization&discretization){ namespacedeformation=geometry::deformation; namespacedependencies=utils::dependencies; usingSurface=std::remove_cvref_t<decltype(discretization.deformation.model.surface)>; conststd::vector<double>shape; constautoinputs=deformation::backend::mfem::make_deformation_inputs(discretization.deformation.model,discretization.deformation.reference,shape); autocache=dependencies::make_computation_cache<deformation::DeformationFailure>(deformation::backend::mfem::make_deformation_graph<Surface>(),inputs); usingOwner=std::remove_cvref_t<decltype(cache.templateget<deformation::keys::SurfaceMap>())>; usingResult=std::expected<Owner,std::string>; constautoprepared=cache.try_prepare(inputs,dependencies::KeyList<deformation::keys::SurfaceMap>{}); if(!prepared){ returnResult(std::unexpected(prepared.error().error.message)); } returnResult(cache.templateget<deformation::keys::SurfaceMap>()); } } template<typenameDiscretization> [[nodiscard]]std::expected<FittedRadialSeed,std::string>fit_radial_seed(constDiscretization&discretization, constRadialSeed&seed,doublespherical_relative_tolerance=5.0e-4){ if(!std::isfinite(spherical_relative_tolerance)||spherical_relative_tolerance<0.0){ returnstd::unexpected("Radial-guessfittingrequiresafinitenonnegativesphericaltolerance."); } constautosurface=detail::radial_seed_surface(discretization); if(!surface){ returnstd::unexpected(surface.error()); } doubleminimum=std::numeric_limits<double>::infinity(); doublemaximum=0.0; for(constauto&point:(*surface)->reference_positions()){ constdoubleradius=std::hypot(point[0]-seed.center[0],point[1]-seed.center[1],point[2]-seed.center[2]); if(!std::isfinite(radius)||radius<=0.0){ returnstd::unexpected("Radial-guessfittingrequiresfinitepositivereference-surfaceradiiabouttheseedcenter."); } minimum=std::min(minimum,radius); maximum=std::max(maximum,radius); } constdoubleradius=minimum+0.5*(maximum-minimum); if(!std::isfinite(radius)||radius<=0.0||(maximum-minimum)/radius>spherical_relative_tolerance){ returnstd::unexpected("Radial-guessfittingrequiresanonemptysphericalreferencesurfacewithintheselectedrelativetolerance."); } returnserif::solver::seed::fit_radial_seed(seed,dimensions::LengthValue{radius}); } }