module; #include #include #include #include #include #include #include #include #include #include #include #include #include #include export module mean_field:operators.prepared_variadic_stellar_equilibrium; export import :operators.prepared_angular_momentum; export import :operators.prepared_central_density; export import :operators.prepared_stellar_equilibrium; export import :operators.stellar_equilibrium_compiler; /* * A physics-authored residual or derivative provider must make one of two * explicit statements for every row/edge inferred from Reads/Changes: * * - return the token produced by row.add(...); or * - return structuralZero when the declared edge is identically zero. * * The outer runtime, rather than the extension, enumerates the compiler's * complete incidence set. These tiny result types let that enumeration * distinguish an intentional mathematical zero from an accidentally empty * hook without exposing any backend block machinery to a physics author. */ export namespace mean_field::stellar { struct ContributionAdded final { }; struct StructuralZero final { }; inline constexpr StructuralZero structuralZero{}; inline constexpr StructuralZero zeroDerivative{}; template concept ContributionResult = std::same_as, ContributionAdded> || std::same_as, StructuralZero>; } // namespace mean_field::stellar export namespace mean_field::operators { /** * Capability boundary for the coupled finite-element physics core. * Describing an EOS is intentionally easier than implementing its * finite-element runtime core. Surface equations are compiled and * prepared by their own specification contribution, so this backend is * selected solely by the constitutive law. */ template struct StellarEquilibriumCoreRuntime { static constexpr bool registered = false; }; template <> struct StellarEquilibriumCoreRuntime { static constexpr bool registered = true; using CoreType = PreparedStellarEquilibriumOperator; [[nodiscard]] static std::unique_ptr Make( fem::FEM &finiteElements, const mapping::DomainMapper &domainMapper, const eos::Polytrope &equationOfState, const models::CompiledFixedMass &fixedMass, PressureSurfaceConstraintView surfaceConstraint, deformation::PreparedDomainDeformationRuntime domainDeformation ) { return std::make_unique( finiteElements, domainMapper, equationOfState, fixedMass, surfaceConstraint, std::move(domainDeformation) ); } [[nodiscard]] static int SurfaceEquationCount(const CoreType &core) noexcept { return static_cast(core.GetSurfaceConstraintOperator().GetSurfaceRows().size()); } }; /** * Minimal common protocol consumed by the variadic outer root. * * EOS backends may use different concrete core types. They only need to * implement this numerical protocol and expose that type as * StellarEquilibriumCoreRuntime::CoreType. Specification runtimes * are audited separately against the selected concrete core, so a * constraint that needs additional physical facilities is rejected at its * own compile-time boundary. */ template concept PreparedStellarEquilibriumPhysicalCore = std::derived_from, mfem::Operator> && requires( std::remove_cvref_t &core, const std::remove_cvref_t &constantCore, const mfem::Vector &state, mfem::Vector &residual, const StellarEquilibriumDependencies &dependencies, const physics::RigidRotation &rotation ) { { constantCore.GetLayout() } -> std::same_as; { core.Prepare(state, dependencies, rotation) } -> std::same_as; { constantCore.BuildResidual(residual) } -> std::same_as; { constantCore.IsPrepared() } -> std::convertible_to; { constantCore.GetFixedMassReport() } -> std::same_as; { constantCore.GetDependencies() } -> std::same_as; { constantCore.GetGeneratedDisplacementDependency() } -> std::same_as; { constantCore.GetSurfaceConstraintOperator() } -> std::same_as; }; template concept FalliblePreparedStellarEquilibriumPhysicalCore = PreparedStellarEquilibriumPhysicalCore && requires( std::remove_cvref_t &core, const mfem::Vector &state, const StellarEquilibriumDependencies &dependencies, const physics::RigidRotation &rotation ) { { core.TryPrepare(state, dependencies, rotation) } -> std::same_as>; }; namespace detail { template struct BackendSpecificationListTraits final { static constexpr bool valid = false; template static constexpr bool contains = false; }; template struct BackendSpecificationListTraits> final { static constexpr bool valid = (models::ModelSpecification && ...) && utils::blocks::types_are_unique_v>; template static constexpr bool contains = (std::same_as, Specifications> || ...); }; template struct CoreRuntimeInterfaceAudit { using CoreType = void; static constexpr bool complete = false; }; template struct CoreRuntimeInterfaceAudit< Model, std::void_t< typename StellarEquilibriumCoreRuntime< typename std::remove_cvref_t::EquationOfStateType>::CoreType, typename StellarEquilibriumCoreRuntime< typename std::remove_cvref_t::EquationOfStateType>::CoreType::BackendSpecifications, std::bool_constant(StellarEquilibriumCoreRuntime::EquationOfStateType>::registered)>>> { private: using ModelType = std::remove_cvref_t; using EquationOfState = typename ModelType::EquationOfStateType; using Runtime = StellarEquilibriumCoreRuntime; public: using CoreType = typename Runtime::CoreType; static constexpr bool complete = BackendSpecificationListTraits::valid && PreparedStellarEquilibriumPhysicalCore && requires( fem::FEM &finiteElements, const mapping::DomainMapper &domainMapper, const EquationOfState &equationOfState, const models::CompiledFixedMass &fixedMass, PressureSurfaceConstraintView surfaceConstraint, deformation::PreparedDomainDeformationRuntime domainDeformation, const CoreType &core ) { requires Runtime::registered; { Runtime::Make( finiteElements, domainMapper, equationOfState, fixedMass, surfaceConstraint, std::move(domainDeformation) ) } -> std::same_as>; { Runtime::SurfaceEquationCount(core) } -> std::convertible_to; }; }; } // namespace detail /** * Structural contract for the privileged specification list owned by an * EOS/core backend. Ordinary EOS, surface, and constraint authors do not * use this facility; their nested EquilibriumPhysics package remains the * restricted, astronomy-facing extension path. */ template concept StellarEquilibriumBackendSpecificationList = detail::BackendSpecificationListTraits>::valid; /** * Backend runtime extension point for one physical model specification. * * The prepared stellar root is assembled by folding this trait over the * model's canonical specification list. A new specification therefore * contributes one prepared slot; no specialization for a *combination* of * specifications is ever required. New physics-facing specifications * should prefer their nested EquilibriumPhysics package below; explicit * specializations remain the library/backend registry mechanism, but are * selected only when the concrete core owner lists that exact * specification in CoreType::BackendSpecifications. */ template struct StellarEquilibriumRuntimeContribution { static constexpr bool registered = false; static constexpr std::size_t rotationProviders = 0; }; template