automatic_relations.hpp serif/geometry/surface/compilation.hpp serif/discretization/blocks/traits.hpp src/include/serif/geometry/surface/automatic.hpp serif serif::geometry serif::geometry::surface serif::geometry::surface::detail #pragmaonce #include"serif/geometry/surface/compilation.hpp" #include"serif/discretization/blocks/traits.hpp" namespaceserif::geometry::surface::detail{ template<typenameTerm> conceptThermodynamicBoundaryField=discretization::blocks::ScalarTraceTerm<Term>&& discretization::blocks::HasQuantity<Term>&&dimensions::ThermodynamicQuantityType<typename Term::Quantity>&& (discretization::blocks::SpatialTerm<Term>||requires{requiresTerm::thermodynamic_state;}); template<typename...Terms> [[nodiscard]]constevalautothermodynamic_fields(utils::dependencies::KeyList<Terms...>){ returnutils::dependencies::CombinedKeyList<std::conditional_t<ThermodynamicBoundaryField<Terms>,utils::dependencies::KeyList<Terms>,utils::dependencies::KeyList<>>...>{}; } template<typenameQuantity,typenameCarrier,typename...Fields> [[nodiscard]]constevalautoquantity_field(utils::dependencies::KeyList<Fields...>){ usingMatches=decltype(std::tuple_cat(std::declval<std::conditional_t<std::same_as<Quantity,typenameFields::Quantity>,std::tuple<Fields>,std::tuple<>>>()...)); ifconstexpr(std::same_as<Quantity,typenameCarrier::Quantity>){ returnstd::type_identity<Carrier>{}; } elseifconstexpr(std::tuple_size_v<Matches>==1){ returnstd::type_identity<std::tuple_element_t<0,Matches>>{}; } else{ returnstd::type_identity<void>{}; } } template<typenameCarrier,typenameFields,typename...Quantities> [[nodiscard]]constevalautorelation_bindings(utils::dependencies::KeyList<Quantities...>){ usingnamespaceutils::dependencies; ifconstexpr((!std::same_as<void,typenamedecltype(quantity_field<Quantities,Carrier>(Fields{}))::type>&&...)){ returnstd::type_identity<Bindings<Binding<Quantities,typenamedecltype(quantity_field<Quantities,Carrier>(Fields{}))::type>...>>{}; } else{ returnstd::type_identity<void>{}; } } template<typenameEOS,typenameCarrier,typenameFields,typenameRelation> [[nodiscard]]constevalautoinverse_candidate(){ usingnamespaceutils::dependencies; usingQuantities=CombinedKeyList<KeyList<typenameCarrier::Quantity>,typenamesurface::detail::RelationQuantities<Relation>::NonPressureInputs>; usingBindings=typenamedecltype(relation_bindings<Carrier, Fields>(Quantities{}))::type; ifconstexpr(SurfaceStateBindings<Bindings>&&surface::detail::matches_pressure_relation<EOS, Bindings, typename Carrier::Quantity, Relation>()){ returnstd::tuple<std::type_identity<InversePressureSurfaceFormulation<EOS,Bindings,Relation>>>{}; } else{ returnstd::tuple<>{}; } } template<typenameEOS,typenameCarrier,typenameFields,typenameRelation> [[nodiscard]]constevalautodirect_candidate(){ usingnamespaceutils::dependencies; usingQuantities=CombinedKeyList<KeyList<typenameCarrier::Quantity>,typenamesurface::detail::RelationQuantities<Relation>::AllInputs>; usingBindings=typenamedecltype(relation_bindings<Carrier, Fields>(Quantities{}))::type; ifconstexpr(DirectPressureSurfaceCompilable<EOS,Bindings,typenameCarrier::Quantity,Relation>){ returnstd::tuple<std::type_identity<DirectPressureSurfaceFormulation<EOS,Bindings,typenameCarrier::Quantity,Relation>>>{}; } else{ returnstd::tuple<>{}; } } template<boolInverse,typenameEOS,typenameCarrier,typenameFields,typename...Relations> [[nodiscard]]constevalautorelation_candidates(eos::relations::RelationCatalog<Relations...>){ ifconstexpr(Inverse){ returnstd::tuple_cat(inverse_candidate<EOS, Carrier, Fields, Relations>()...); } else{ returnstd::tuple_cat(direct_candidate<EOS, Carrier, Fields, Relations>()...); } } }