module; #include #include #include export module mean_field:surface.compiler; export import :surface.compiled; export namespace mean_field::surface { namespace detail { template struct PressureSurfaceRelationMatches : std::false_type { }; template struct PressureSurfaceRelationMatches< eos::Relation, Formulation, EquationOfState> : std::bool_constant< std::same_as && (std::same_as || ...) && ((std::same_as || (surfaceBindingCount == 1 && eos::SupportsPartialDerivative< EquationOfState, eos::Relation, InputQuantities>)) && ...)> { }; template struct PressureSurfaceRelationMatchesBindings : std::false_type { }; template struct PressureSurfaceRelationMatchesBindings< eos::Relation, Bindings, EquationOfState> : std::bool_constant< (surfaceBindingCount == 1) && (std::same_as || ...) && ((std::same_as || (surfaceBindingCount == 1 && eos::SupportsPartialDerivative< EquationOfState, eos::Relation, InputQuantities>)) && ...)> { }; template struct MatchingPressureSurfaceRelations; template struct MatchingPressureSurfaceRelations, Formulation, EquationOfState> { using Tuple = decltype(std::tuple_cat( std::conditional_t< PressureSurfaceRelationMatches::value, std::tuple, std::tuple<>>{}... )); static constexpr std::size_t count = std::tuple_size_v; }; template struct MatchingPressureSurfaceRelationsForBindings; template struct MatchingPressureSurfaceRelationsForBindings< eos::RelationCatalog, Bindings, EquationOfState> { using Tuple = decltype(std::tuple_cat( std::conditional_t< PressureSurfaceRelationMatchesBindings::value, std::tuple, std::tuple<>>{}... )); static constexpr std::size_t count = std::tuple_size_v; }; template struct UniquePressureSurfaceRelation { using Type = void; }; template struct UniquePressureSurfaceRelation<1, Tuple> { using Type = std::tuple_element_t<0, Tuple>; }; template struct UniquePressureSurfaceFormulation { using Type = void; }; template struct UniquePressureSurfaceFormulation<1, Tuple, Bindings> { using Relation = std::tuple_element_t<0, Tuple>; using CarrierQuantity = eos::RelationOutputT; using CarrierField = SurfaceFieldForQuantityT; using Type = SurfaceConstraintFormulation; }; template struct AppendSurfaceDependency; template struct AppendSurfaceDependency, Field> { using Type = SurfaceConstraintDependencies; }; template struct AppendPressureSurfaceInputDependency { using Type = typename AppendSurfaceDependency>::Type; }; template struct AppendPressureSurfaceInputDependency { using Type = Dependencies; }; template struct AppendPressureSurfaceInputDependencies; template struct AppendPressureSurfaceInputDependencies { using Type = Dependencies; }; template struct AppendPressureSurfaceInputDependencies { using WithFirst = typename AppendPressureSurfaceInputDependency::Type; using Type = typename AppendPressureSurfaceInputDependencies::Type; }; template struct PressureSurfaceDependenciesForRelation; template struct PressureSurfaceDependenciesForRelation, Formulation> { using InitialDependencies = SurfaceConstraintDependencies; using Type = typename AppendPressureSurfaceInputDependencies< InitialDependencies, typename Formulation::StateBindings, InputQuantities...>::Type; }; template struct PressureSurfaceCompilation { using Matches = MatchingPressureSurfaceRelations; using Relation = typename UniquePressureSurfaceRelation::Type; }; template struct PressureSurfaceFormulationCompilation { using Matches = MatchingPressureSurfaceRelationsForBindings< typename EquationOfState::Relations, Bindings, EquationOfState>; using Formulation = typename UniquePressureSurfaceFormulation::Type; }; template requires(PressureSurfaceCompilation::Matches::count == 1) struct CompiledPressureSurfaceConstraintType { using Compilation = PressureSurfaceCompilation; using Relation = typename Compilation::Relation; using Dependencies = typename PressureSurfaceDependenciesForRelation::Type; using Type = CompiledPressureSurfaceConstraint; }; } // namespace detail template concept PressureSurfaceCompilable = SurfaceConstraintFormulationType && eos::EquationOfStateModel && (detail::PressureSurfaceCompilation, std::remove_cvref_t>:: Matches::count == 1); template concept PressureSurfaceFormulationCompilable = ValidSurfaceStateBindings && eos::EquationOfStateModel && (detail::PressureSurfaceFormulationCompilation< std::remove_cvref_t, std::remove_cvref_t>::Matches::count == 1); template requires PressureSurfaceFormulationCompilable using CompiledPressureSurfaceFormulationT = typename detail::PressureSurfaceFormulationCompilation< std::remove_cvref_t, std::remove_cvref_t>::Formulation; template requires PressureSurfaceCompilable using CompiledPressureSurfaceConstraintT = typename detail::CompiledPressureSurfaceConstraintType< std::remove_cvref_t, std::remove_cvref_t>::Type; template < SurfaceConstraintFormulationType Formulation, eos::EquationOfStateModel EquationOfState> requires PressureSurfaceCompilable< Formulation, EquationOfState> [[nodiscard]] CompiledPressureSurfaceConstraintT< Formulation, EquationOfState> compilePressureSurfaceConstraint( const ConstantPressureSurface condition, const EquationOfState &equationOfState ) noexcept { return CompiledPressureSurfaceConstraintT{condition, equationOfState}; } } // namespace mean_field::surface