module; #include #include #include #include #include #include export module mean_field:surface.dependencies; export import :eos.relations; export import :field.registry; export namespace mean_field::surface { template concept SurfaceFieldType = requires { { Candidate::name } -> std::convertible_to; } && (std::string_view{Candidate::name}.size() > 0); class SurfaceFieldId final { public: explicit constexpr SurfaceFieldId(const std::string_view name) noexcept : m_name(name) { } [[nodiscard]] constexpr std::string_view name() const noexcept { return m_name; } [[nodiscard]] friend constexpr bool operator==( const SurfaceFieldId &, const SurfaceFieldId & ) noexcept = default; private: std::string_view m_name; }; template inline constexpr SurfaceFieldId surfaceFieldId{std::string_view{Field::name}}; template struct SurfaceStateBinding final { using Quantity = ThermodynamicQuantity; using FieldType = Field; }; template struct SurfaceStateBindings final { }; namespace detail { template struct SurfaceTypesAreUnique : std::true_type { }; template struct SurfaceTypesAreUnique : std::bool_constant< (!std::same_as && ...) && SurfaceTypesAreUnique::value> { }; template struct SurfaceBindingsAreValid : std::false_type { }; template struct SurfaceBindingsAreValid> : std::bool_constant< (sizeof...(Bindings) > 0) && (requires { typename Bindings::Quantity; typename Bindings::FieldType; } && ...) && (eos::ThermodynamicQuantityType< typename Bindings::Quantity> && ...) && (SurfaceFieldType && ...) && SurfaceTypesAreUnique< typename Bindings::Quantity...>::value> { }; template struct SurfaceBindingCount; template struct SurfaceBindingCount, Quantity> : std::integral_constant< std::size_t, (std::size_t{0} + ... + (std::same_as ? std::size_t{1} : std::size_t{0}))> { }; template struct SurfaceFieldForQuantity; template struct SurfaceFieldForQuantity, Quantity> : std::conditional_t< std::same_as, std::type_identity, SurfaceFieldForQuantity, Quantity>> { }; template struct CarrierFieldMatchesSurfaceBinding : std::false_type { }; template struct CarrierFieldMatchesSurfaceBinding : std::bool_constant::type, typename Candidate::CarrierField>> { }; template < typename Candidate, bool BindingsAreValid = SurfaceBindingsAreValid::value> struct FormulationBindingsMatchCarrier : std::false_type { }; template struct FormulationBindingsMatchCarrier : CarrierFieldMatchesSurfaceBinding< Candidate, SurfaceBindingCount< typename Candidate::StateBindings, typename Candidate::CarrierQuantity>::value> { }; template struct IsSurfaceConstraintFormulation : std::false_type { }; template struct IsSurfaceConstraintFormulation< Candidate, std::void_t< typename Candidate::CarrierQuantity, typename Candidate::CarrierField, typename Candidate::StateBindings>> : std::bool_constant< eos::ThermodynamicQuantityType && SurfaceFieldType && FormulationBindingsMatchCarrier::value> { }; } // namespace detail template concept ValidSurfaceStateBindings = detail::SurfaceBindingsAreValid>::value; template inline constexpr std::size_t surfaceBindingCount = detail::SurfaceBindingCount::value; template requires(surfaceBindingCount == 1) using SurfaceFieldForQuantityT = typename detail::SurfaceFieldForQuantity::type; template < eos::ThermodynamicQuantityType CarrierThermodynamicQuantity, SurfaceFieldType CarrierFieldType, ValidSurfaceStateBindings Bindings> requires( surfaceBindingCount == 1 && std::same_as, CarrierFieldType> ) struct SurfaceConstraintFormulation final { using CarrierQuantity = CarrierThermodynamicQuantity; using CarrierField = CarrierFieldType; using StateBindings = Bindings; }; using BarotropicSurfaceFormulation = SurfaceConstraintFormulation< eos::quantity::SpecificEnthalpy, field::Enthalpy, SurfaceStateBindings>>; template concept SurfaceConstraintFormulationType = detail::IsSurfaceConstraintFormulation>::value; struct RuntimeSurfaceConstraintDependencies final { SurfaceFieldId residualRowField; std::span stateFields; }; template struct SurfaceConstraintDependencies final { using RowField = ResidualField; using StateFieldTypes = field::TypeList; inline static constexpr std::array runtimeStateFields{ surfaceFieldId... }; [[nodiscard]] static constexpr RuntimeSurfaceConstraintDependencies runtimeDescription() noexcept { return RuntimeSurfaceConstraintDependencies{ .residualRowField = surfaceFieldId, .stateFields = std::span{runtimeStateFields} }; } }; } // namespace mean_field::surface