module; #include #include export module mean_field:material.thermodynamic_equations; export import :eos.polytrope; export import :surface.compiler; export import :utils.blocks; export namespace mean_field::material { /** * A thermodynamic field identifies the physical quantity represented by * its discrete degree of freedom. The quantity belongs to the field, not * to an EOS-specific aggregate description. */ template concept ThermodynamicField = surface::SurfaceFieldType && requires { typename std::remove_cvref_t::PhysicalQuantity; requires eos::ThermodynamicQuantityType::PhysicalQuantity>; }; /** * Declares the algebraic blocks owned by one thermodynamic governing * equation. Its physical quantity is inferred from Field. */ template requires std::derived_from && std::derived_from struct ThermodynamicEquation final { using FieldType = Field; using PhysicalQuantity = typename Field::PhysicalQuantity; using Correction = CorrectionBlock; using Residual = ResidualBlock; }; /** * Registry of thermodynamic governing equations available to a problem. * The problem form, rather than the registry, selects the active subset. */ template struct ThermodynamicEquationCatalog final { static constexpr int size = sizeof...(Equations); }; namespace detail { template struct IsThermodynamicEquation : std::false_type { }; template struct IsThermodynamicEquation> : std::true_type { }; template struct IsThermodynamicEquationCatalog : std::false_type { }; template struct IsThermodynamicEquationCatalog> : std::bool_constant<(sizeof...(Equations) > 0) && (IsThermodynamicEquation::value && ...)> { }; template struct CatalogEntriesAreUnique : std::false_type { }; template struct CatalogEntriesAreUnique> : std::bool_constant< utils::blocks::types_are_unique_v> && utils::blocks::types_are_unique_v< utils::blocks::type_list> && utils::blocks::types_are_unique_v> && utils::blocks::types_are_unique_v>> { }; template struct EquationForField; template struct EquationForField, Field> : std::conditional_t< std::same_as, std::type_identity, EquationForField, Field>> { }; template struct EquationForField, Field> { using type = void; }; template struct EquationFieldCount; template struct EquationFieldCount, Field> : std::integral_constant< int, (int{0} + ... + (std::same_as ? 1 : 0))> { }; template struct EquationForCorrection; template struct EquationForCorrection, Correction> : std::conditional_t< std::same_as, std::type_identity, EquationForCorrection, Correction>> { }; template struct EquationForCorrection, Correction> { using type = void; }; template struct PrependEquation; template struct PrependEquation> { using Type = ThermodynamicEquationCatalog; }; template struct SelectActiveEquations; template struct SelectActiveEquations, AvailableEquations> { using Type = ThermodynamicEquationCatalog<>; }; template struct SelectActiveEquations, AvailableEquations> { private: using Tail = typename SelectActiveEquations, AvailableEquations>::Type; using Match = typename EquationForCorrection::type; public: using Type = std::conditional_t, Tail, typename PrependEquation::Type>; }; template struct CatalogMatchesForm : std::false_type { }; template struct CatalogMatchesForm< ThermodynamicEquationCatalog, utils::blocks::block_form, utils::blocks::type_list>> : std::bool_constant< ((utils::blocks:: contains_type_v> == utils::blocks:: contains_type_v>) && ...)> { }; template struct SurfaceBindingsForEquations; template struct SurfaceBindingsForEquations> { using Type = surface::SurfaceStateBindings< surface::SurfaceStateBinding...>; }; template struct SurfaceFieldsBelongToEquations : std::false_type { }; template struct SurfaceFieldsBelongToEquations, Equations> : std::bool_constant<((EquationFieldCount::value == 1) && ...)> { }; template struct ThermodynamicCompilationIsAvailable : std::false_type { }; template struct ThermodynamicCompilationIsAvailable< EquationOfState, Form, AvailableEquations, std::enable_if_t< eos::EquationOfStateModel && utils::blocks::block_form_is_valid_v
&& IsThermodynamicEquationCatalog::value && CatalogEntriesAreUnique::value && CatalogMatchesForm::value>> { private: using ActiveEquations = typename SelectActiveEquations::Type; using StateBindings = typename SurfaceBindingsForEquations::Type; public: static constexpr bool value = (ActiveEquations::size > 0) && surface::PressureSurfaceFormulationCompilable; }; template struct IsCompiledThermodynamicEquations : std::false_type { }; template struct IsCompiledThermodynamicEquations< Candidate, std::void_t< typename Candidate::EquationOfStateType, typename Candidate::Equations, typename Candidate::StateBindings, typename Candidate::PressureSurfaceFormulation>> : std::bool_constant< eos::EquationOfStateModel && IsThermodynamicEquationCatalog::value && CatalogEntriesAreUnique::value && surface::ValidSurfaceStateBindings && std::same_as< typename Candidate::StateBindings, typename SurfaceBindingsForEquations::Type> && surface::SurfaceConstraintFormulationType && std::same_as< typename Candidate::PressureSurfaceFormulation::StateBindings, typename Candidate::StateBindings>> { }; } // namespace detail template concept ThermodynamicEquationType = detail::IsThermodynamicEquation>::value; template concept ValidThermodynamicEquationCatalog = detail::IsThermodynamicEquationCatalog>::value && detail::CatalogEntriesAreUnique>::value; template concept CompiledThermodynamicEquations = detail::IsCompiledThermodynamicEquations>::value; template requires(detail::EquationFieldCount::value == 1) using ThermodynamicEquationForFieldT = typename detail::EquationForField::type; template inline constexpr bool fieldsBelongToThermodynamicEquations = detail::SurfaceFieldsBelongToEquations::value; template concept ThermodynamicEquationsCompilable = detail::ThermodynamicCompilationIsAvailable< std::remove_cvref_t, std::remove_cvref_t, std::remove_cvref_t>::value; template requires surface::PressureSurfaceFormulationCompilable< typename detail::SurfaceBindingsForEquations::Type, EquationOfState> struct ThermodynamicEquationSet final { using EquationOfStateType = EquationOfState; using Equations = ActiveEquations; using StateBindings = typename detail::SurfaceBindingsForEquations::Type; using PressureSurfaceFormulation = surface::CompiledPressureSurfaceFormulationT; }; template < eos::EquationOfStateModel EquationOfState, typename Form, ValidThermodynamicEquationCatalog AvailableEquations> requires ThermodynamicEquationsCompilable struct CompileThermodynamicEquations final { using Equations = typename detail::SelectActiveEquations::Type; using Type = ThermodynamicEquationSet; }; template requires ThermodynamicEquationsCompilable using CompiledThermodynamicEquationsT = typename CompileThermodynamicEquations< std::remove_cvref_t, std::remove_cvref_t, std::remove_cvref_t>::Type; using StellarEquilibriumThermodynamicEquations = ThermodynamicEquationCatalog< ThermodynamicEquation< field::Density, utils::blocks::density::mass::value, utils::blocks::density::mass::residual>, ThermodynamicEquation< field::Enthalpy, utils::blocks::enthalpy::specific::value, utils::blocks::enthalpy::specific::residual>>; static_assert(ValidThermodynamicEquationCatalog); } // namespace mean_field::material