radial_interpolation.cpp cmath limits serif/geometry/deformation/radial_interpolation.hpp serif serif::geometry serif::geometry::deformation #include<cmath> #include<limits> #include"serif/geometry/deformation/radial_interpolation.hpp" namespaceserif::geometry::deformation { std::expected<RadialInterpolation,DeformationFailure>make_radial_interpolation(RadialInterpolationDatadata) { conststd::size_tcount=data.logical_radii.size(); if(count==0||data.surface_scalar_dofs.size()==0||data.stellar_support.size()!=count||data.vacuum_support.size()!=count||data.row_offsets.size()!=count+1||!(data.stellar_radius>0.0)||!(data.infinity_radius>data.stellar_radius)||!std::isfinite(data.infinity_radius)) { returnstd::unexpected(DeformationFailure{.reason=DeformationFailureReason::invalid_configuration,.message="Radialinterpolationsupports,rowsandshellradiiareinconsistent."}); } if(data.surface_columns.size()!=data.interpolation_weights.size()||data.row_offsets.front()!=0||data.row_offsets.back()<0||static_cast<std::size_t>(data.row_offsets.back())!=data.surface_columns.size()) { returnstd::unexpected(DeformationFailure{.reason=DeformationFailureReason::invalid_configuration,.message="Radialinterpolationrowoffsetsdonotspanthestoredentries."}); } intprevious_surface_dof=-1; for(constintsurface_dof:data.surface_scalar_dofs) { if(surface_dof<=previous_surface_dof||static_cast<std::size_t>(surface_dof)>=count) { returnstd::unexpected(DeformationFailure{.reason=DeformationFailureReason::invalid_configuration,.message="Radialsurfacenodesmustbedistinct,ascendingandinsidethevolumescalarspace."}); } previous_surface_dof=surface_dof; } constdoubleradial_tolerance=128.0*std::numeric_limits<double>::epsilon()*data.infinity_radius; for(std::size_tnode=0;node<count;++node) { constintstellar=data.stellar_support[node]; constintvacuum=data.vacuum_support[node]; constdoubleradius=data.logical_radii[node]; if((stellar!=0&&stellar!=1)||(vacuum!=0&&vacuum!=1)||(stellar&&radius>data.stellar_radius+radial_tolerance)||(vacuum&&(radius<data.stellar_radius-radial_tolerance||radius>data.infinity_radius+radial_tolerance))) { returnstd::unexpected(DeformationFailure{.reason=DeformationFailureReason::invalid_configuration,.message="Radialnodesupportandlogicalshellradiiareinconsistent."}); } if(data.row_offsets[node]>data.row_offsets[node+1]||!std::isfinite(data.logical_radii[node])||data.logical_radii[node]<0.0) { returnstd::unexpected(DeformationFailure{.reason=DeformationFailureReason::invalid_configuration,.message="Radialinterpolationrowsmustincreaseandlogicalradiimustbefiniteandnonnegative."}); } } for(std::size_tentry=0;entry<data.surface_columns.size();++entry) { if(data.surface_columns[entry]<0||static_cast<std::size_t>(data.surface_columns[entry])>=data.surface_scalar_dofs.size()||!std::isfinite(data.interpolation_weights[entry])) { returnstd::unexpected(DeformationFailure{.reason=DeformationFailureReason::invalid_configuration,.message="Aradialinterpolationentryhasaninvalidcolumnorweight."}); } } constdoublecenter_tolerance=64.0*std::numeric_limits<double>::epsilon()*data.infinity_radius; for(std::size_tnode=0;node<count;++node) { constboolmoving=data.stellar_support[node]?data.logical_radii[node]>center_tolerance:data.vacuum_support[node]&&data.logical_radii[node]!=data.infinity_radius; if(moving) { doublepartition=0.0; for(intentry=data.row_offsets[node];entry<data.row_offsets[node+1];++entry) { partition+=data.interpolation_weights[entry]; } if(!std::isfinite(partition)||std::abs(partition-1.0)>2.0e-12) { returnstd::unexpected(DeformationFailure{.reason=DeformationFailureReason::invalid_configuration,.message="Amovingradialinterpolationrowmustpreserveaconstantsurfacetrace."}); } } } returnRadialInterpolation(std::move(data)); } }//namespaceserif::geometry::deformation