factor_computations.hpp concepts cstddef expected string type_traits vector serif/solver/normalization/keys.hpp serif/solver/normalization/layout.hpp serif/solver/normalization/plan.hpp serif/solver/normalization/diagonal.hpp serif/solver/normalization/detail/validation.hpp serif/solver/normalization/point_rows.hpp serif/solver/normalization/scales.hpp serif/utils/dependencies/computation.hpp src/include/serif/solver/normalization/computations.hpp serif serif::solver serif::solver::normalization serif::solver::normalization::detail #pragmaonce #include<concepts> #include<cstddef> #include<expected> #include<string> #include<type_traits> #include<vector> #include"serif/solver/normalization/keys.hpp" #include"serif/solver/normalization/layout.hpp" #include"serif/solver/normalization/plan.hpp" #include"serif/solver/normalization/diagonal.hpp" #include"serif/solver/normalization/detail/validation.hpp" #include"serif/solver/normalization/point_rows.hpp" #include"serif/solver/normalization/scales.hpp" #include"serif/utils/dependencies/computation.hpp" namespaceserif::solver::normalization::detail { template<typenameScalesT,typenameQuantityT> conceptProvidesScale=requires(constScalesT&scales) { {characteristic_scale(scales,QuantityT{})}->std::same_as<dimensions::QuantityValue<QuantityT>>; }; template<discretization::blocks::RepresentedValueKindKind,typenameCoordinateT,CoordinateLayoutTypeLayoutT> [[nodiscard]]std::expected<std::size_t,std::string>coordinate_size(constLayoutT&layout) { conststd::size_tsize=layout.templatesize<Kind,CoordinateT>(); usingTerm=typenamedecltype(metric_term<CoordinateT>())::type; returnvalidate_coordinate_size(size,discretization::blocks::GlobalScalarTerm<Term>); } template<discretization::blocks::RepresentedValueKindKind,typenameCoordinateT,CoordinateLayoutTypeLayoutT> [[nodiscard]]std::expected<void,std::string>check_coordinate_size(constLayoutT&layout,std::size_treceived) { constautosize=coordinate_size<Kind, CoordinateT>(layout); if(!size) { returnstd::unexpected(size.error()); } returncheck_coordinate_size(*size,received); } template<discretization::blocks::RepresentedValueKindKind,typenameCoordinateT,typenameLayoutT,typenameScalesT> [[nodiscard]]autocoordinate_computation(IdentityCoordinate) { usingnamespaceutils::dependencies; returnmake_computation<keys::Factors<Kind,CoordinateT>,InputList<keys::Layout>>( [](constLayoutT&layout)->std::expected<std::vector<double>,std::string> { constautosize=coordinate_size<Kind, CoordinateT>(layout); if(!size) { returnstd::unexpected(size.error()); } returnstd::vector<double>(*size,1.0); }); } template<discretization::blocks::RepresentedValueKindKind,typenameCoordinateT,typenameLayoutT,typenameScalesT,typenameQuantityT> requiresProvidesScale<ScalesT, QuantityT> [[nodiscard]]autocoordinate_computation(PhysicalRieszCoordinate<QuantityT,UnitMetric>) { usingnamespaceutils::dependencies; returnmake_computation<keys::Factors<Kind,CoordinateT>,InputList<keys::Layout,keys::Scales>>( [](constLayoutT&layout,constScalesT&scales)->std::expected<std::vector<double>,std::string> { constautosize=coordinate_size<Kind, CoordinateT>(layout); if(!size) { returnstd::unexpected(size.error()); } constautofactor=make_riesz_factor(Kind,1.0,characteristic_scale(scales,QuantityT{}).value()); if(!factor) { returnstd::unexpected(factor.error()); } returnstd::vector<double>(*size,*factor); }); } template<discretization::blocks::RepresentedValueKindKind,typenameCoordinateT,typenameLayoutT,typenameScalesT,typenameQuantityT,typenameMetricT> requires(!std::same_as<MetricT,UnitMetric>&&ProvidesScale<ScalesT, QuantityT>) [[nodiscard]]autocoordinate_computation(PhysicalRieszCoordinate<QuantityT,MetricT>) { usingnamespaceutils::dependencies; returnmake_computation<keys::Factors<Kind,CoordinateT>,InputList<keys::Layout,keys::Scales,MetricT>>( [](constLayoutT&layout,constScalesT&scales,conststd::vector<double>&metric)->std::expected<std::vector<double>,std::string> { constautovalid=check_coordinate_size<Kind, CoordinateT>(layout,metric.size()); if(!valid) { returnstd::unexpected(valid.error()); } returnmake_riesz_factors(Kind,metric,characteristic_scale(scales,QuantityT{}).value()); }); } template<discretization::blocks::RepresentedValueKindKind,typenameCoordinateT,typenameLayoutT,typenameScalesT,typenameQuantityT,typenameMetricT,typenamePointQuantityT,typenameSelectionT> requires(Kind==discretization::blocks::RepresentedValueKind::residual&&!std::same_as<MetricT,UnitMetric>&&ProvidesScale<ScalesT, QuantityT>&&ProvidesScale<ScalesT, PointQuantityT>) [[nodiscard]]autocoordinate_computation(WithPointRows<PhysicalRieszCoordinate<QuantityT,MetricT>,PointQuantityT,SelectionT>) { usingnamespaceutils::dependencies; returnmake_computation<keys::Factors<Kind,CoordinateT>,InputList<keys::Layout,keys::Scales,MetricT,SelectionT>>( [](constLayoutT&layout,constScalesT&scales,conststd::vector<double>&metric,conststd::vector<int>&rows)->std::expected<std::vector<double>,std::string> { constautovalid=check_coordinate_size<Kind, CoordinateT>(layout,metric.size()); if(!valid) { returnstd::unexpected(valid.error()); } returnmake_point_replaced_residual_factors(metric,characteristic_scale(scales,QuantityT{}).value(),rows,characteristic_scale(scales,PointQuantityT{}).value()); }); } template<discretization::blocks::RepresentedValueKindKind,typenameCoordinateT,typenameLayoutT,typenameScalesT,typenameQuantityT> requiresProvidesScale<ScalesT, QuantityT> [[nodiscard]]autocoordinate_computation(DimensionlessRieszCoordinate<QuantityT,UnitMetric,ReferenceGeometry::algebraic>){ returncoordinate_computation<Kind, CoordinateT, LayoutT, ScalesT>(PhysicalRieszCoordinate<QuantityT,UnitMetric>{}); } template<discretization::blocks::RepresentedValueKindKind,typenameCoordinateT,typenameLayoutT,typenameScalesT,typenameQuantityT,typenameMetricT,ReferenceGeometryGeometry> requires(!std::same_as<MetricT,UnitMetric>&&ProvidesScale<ScalesT, QuantityT>&&ProvidesScale<ScalesT, dimensions::Length>) [[nodiscard]]autocoordinate_computation(DimensionlessRieszCoordinate<QuantityT,MetricT,Geometry>){ usingnamespaceutils::dependencies; returnmake_computation<keys::Factors<Kind,CoordinateT>,InputList<keys::Layout,keys::Scales,MetricT>>( [](constLayoutT&layout,constScalesT&scales,conststd::vector<double>&metric)->std::expected<std::vector<double>,std::string>{ constautovalid=check_coordinate_size<Kind, CoordinateT>(layout,metric.size()); if(!valid){ returnstd::unexpected(valid.error()); } constautoscale=dimensionless_riesz_scale(Kind,Geometry,characteristic_scale(scales,QuantityT{}).value(),characteristic_scale(scales,dimensions::Length{}).value()); if(!scale){ returnstd::unexpected(scale.error()); } returnmake_riesz_factors(Kind,metric,*scale); }); } template<discretization::blocks::RepresentedValueKindKind,typenameCoordinateT,typenameLayoutT,typenameScalesT,typenameQuantityT,typenameMetricT,ReferenceGeometryGeometry,typenamePointQuantityT,typenameSelectionT> requires(Kind==discretization::blocks::RepresentedValueKind::residual&&!std::same_as<MetricT,UnitMetric>&&ProvidesScale<ScalesT, QuantityT>&&ProvidesScale<ScalesT, PointQuantityT>&&ProvidesScale<ScalesT, dimensions::Length>) [[nodiscard]]autocoordinate_computation(WithPointRows<DimensionlessRieszCoordinate<QuantityT,MetricT,Geometry>,PointQuantityT,SelectionT>){ usingnamespaceutils::dependencies; returnmake_computation<keys::Factors<Kind,CoordinateT>,InputList<keys::Layout,keys::Scales,MetricT,SelectionT>>( [](constLayoutT&layout,constScalesT&scales,conststd::vector<double>&metric,conststd::vector<int>&rows)->std::expected<std::vector<double>,std::string>{ constautovalid=check_coordinate_size<Kind, CoordinateT>(layout,metric.size()); if(!valid){ returnstd::unexpected(valid.error()); } constautoscale=dimensionless_riesz_scale(Kind,Geometry,characteristic_scale(scales,QuantityT{}).value(),characteristic_scale(scales,dimensions::Length{}).value()); if(!scale){ returnstd::unexpected(scale.error()); } returnmake_point_replaced_residual_factors(metric,*scale,rows,characteristic_scale(scales,PointQuantityT{}).value()); }); } template<discretization::blocks::RepresentedValueKindKind,typenameCoordinateT,typenameLayoutT,typenameScalesT,typenamePrescriptionT> requiresrequires(conststd::remove_cvref_t<PrescriptionT>&prescription,std::size_tsize) { {prescription.prepare_factors(keys::Factors<Kind,CoordinateT>{},size)}->std::same_as<std::expected<std::vector<double>,std::string>>; } [[nodiscard]]autocoordinate_computation(RuntimePreparedCoordinate<PrescriptionT>) { usingnamespaceutils::dependencies; usingPrescription=std::remove_cvref_t<PrescriptionT>; returnmake_computation<keys::Factors<Kind,CoordinateT>,InputList<keys::Layout,keys::Prescription<Prescription>>>( []<typenameSuppliedPrescription>(constLayoutT&layout,constSuppliedPrescription&prescription)->std::expected<std::vector<double>,std::string> requiresstd::same_as<std::remove_cvref_t<SuppliedPrescription>,Prescription> { constautosize=coordinate_size<Kind, CoordinateT>(layout); if(!size) { returnstd::unexpected(size.error()); } autofactors=prescription.prepare_factors(keys::Factors<Kind,CoordinateT>{},*size); if(!factors) { returnfactors; } constautovalid_size=check_coordinate_size(*size,factors->size()); if(!valid_size) { returnstd::unexpected(valid_size.error()); } constautovalid_factors=validate_factors(*factors); if(!valid_factors) { returnstd::unexpected(valid_factors.error()); } returnfactors; }); } }