regularization.cpp serif/solver/preconditioner/backend/mfem/inverse/regularization.hpp algorithm cmath limits serif serif::solver serif::solver::preconditioner serif::solver::preconditioner::backend serif::solver::preconditioner::backend::mfem #include"serif/solver/preconditioner/backend/mfem/inverse/regularization.hpp" #include<algorithm> #include<cmath> #include<limits> namespaceserif::solver::preconditioner::backend::mfem { std::expected<RegularizedDiagonal,Failure>try_regularize_diagonal(std::span<constdouble>diagonal,strategies::inverse::DiagonalRegularizationoptions) { usingutils::errors::SERiFErrorCode; if(!std::isfinite(options.relative_floor)||options.relative_floor<0.0||!std::isfinite(options.absolute_floor)||options.absolute_floor<=0.0) { returnstd::unexpected(Failure{.code=SERiFErrorCode::PRECONDITIONER_INVALID_OPTIONS,.message="Diagonalregularizationrequiresafinitenonnegativerelativefloorandfinitepositiveabsolutefloor."}); } RegularizedDiagonalresult{.values={diagonal.begin(),diagonal.end()},.report={.minimum_magnitude=diagonal.empty()?0.0:std::numeric_limits<double>::infinity()}}; for(doublevalue:diagonal) { if(!std::isfinite(value)) { returnstd::unexpected(Failure{.code=SERiFErrorCode::PRECONDITIONER_NONFINITE_VALUE,.message="Aphysicaldiagonalcontainsanonfiniteentry.Repairitsacceptedlinearizationbeforepreparinganinverse."}); } result.report.minimum_magnitude=std::min(result.report.minimum_magnitude,std::abs(value)); result.report.maximum_magnitude=std::max(result.report.maximum_magnitude,std::abs(value)); } result.report.applied_floor=std::max(options.absolute_floor,options.relative_floor*result.report.maximum_magnitude); if(!std::isfinite(result.report.applied_floor)) { returnstd::unexpected(Failure{.code=SERiFErrorCode::PRECONDITIONER_NONFINITE_VALUE,.message="Therelativediagonalflooroverflowed.Reduceitorchangethereferenceunits."}); } for(double&value:result.values) { if(std::abs(value)<result.report.applied_floor) { value=std::copysign(result.report.applied_floor,value==0.0?1.0:value); ++result.report.regularized_entries; } } returnresult; } }//namespaceserif::solver::preconditioner::backend::mfem