#include #include #include #include #include #include import mean_field; namespace stellar_runtime_contract_test { template class PreparedMissingRieszScalarConstraint; template class PreparedSecondRotationController; template class PreparedRawNestedProtocolConstraint; struct NonDefaultRuntimeReport final { NonDefaultRuntimeReport() = delete; explicit constexpr NonDefaultRuntimeReport(const bool changed) noexcept : m_changed(changed) {} [[nodiscard]] constexpr bool DidAnyWork() const noexcept { return m_changed; } private: bool m_changed; }; struct NonAssignableRuntimeReport final { constexpr NonAssignableRuntimeReport() noexcept = default; NonAssignableRuntimeReport(const NonAssignableRuntimeReport &) = default; NonAssignableRuntimeReport(NonAssignableRuntimeReport &&) = default; NonAssignableRuntimeReport &operator=(const NonAssignableRuntimeReport &) = delete; NonAssignableRuntimeReport &operator=(NonAssignableRuntimeReport &&) = delete; [[nodiscard]] constexpr bool DidAnyWork() const noexcept { return false; } }; /* Deliberately carries no framework-specific work-reporting method. A * third-party report is storage for its author's diagnostics, not an input to * residual-cache correctness. */ struct OpaqueRuntimeReport final { bool prepared{true}; }; template class PreparedReportContractRuntime final { public: using Report = ReportType; template explicit PreparedReportContractRuntime(const Specification &) noexcept {} template [[nodiscard]] Report PrepareAfterPhysical(const StateView &) noexcept { if constexpr (std::default_initializable) { return {}; } else { return Report{false}; } } template [[nodiscard]] mean_field::stellar::StructuralZero AddResidual( Equation, Row &) const noexcept { return mean_field::stellar::structuralZero; } template [[nodiscard]] mean_field::stellar::StructuralZero AddJacobianAction( mean_field::stellar::Derivative, const Direction &, Row &) const noexcept { return mean_field::stellar::zeroDerivative; } [[nodiscard]] constexpr bool IsPrepared() const noexcept { return true; } }; template using PreparedNonDefaultReportRuntime = PreparedReportContractRuntime; template using PreparedNonAssignableReportRuntime = PreparedReportContractRuntime; template using PreparedOpaqueReportRuntime = PreparedReportContractRuntime; template using PreparedAmbiguousRegistrationRuntime = PreparedReportContractRuntime< Model, mean_field::operators::EmptySpecificationPreparationReport>; struct NonDefaultReportConstraint final { struct Parameters final { mean_field::dimensions::SpecificEnthalpyValue target; }; using ScalarDescription = mean_field::stellar::ScalarConstraint< mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, "runtime.non_default.value", "lambda_nd", "runtime.non_default.residual", "R_nd">; using ModelDefinition = mean_field::constraint::ScalarPhaseCondition< NonDefaultReportConstraint, "NonDefaultReportConstraint", mean_field::stellar::Reads< mean_field::stellar::state::SpecificEnthalpy>, mean_field::stellar::Changes< mean_field::stellar::equation::HydrostaticBalance>, ScalarDescription>; using EquilibriumPhysics = mean_field::operators::SpecificationEquilibriumPhysics< PreparedNonDefaultReportRuntime>; explicit constexpr NonDefaultReportConstraint(Parameters parameters) noexcept : m_target(parameters.target) {} [[nodiscard]] constexpr auto target() const noexcept { return m_target; } private: mean_field::dimensions::SpecificEnthalpyValue m_target; }; struct NonAssignableReportConstraint final { struct Parameters final { mean_field::dimensions::SpecificEnthalpyValue target; }; using ScalarDescription = mean_field::stellar::ScalarConstraint< mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, "runtime.non_assignable.value", "lambda_na", "runtime.non_assignable.residual", "R_na">; using ModelDefinition = mean_field::constraint::ScalarPhaseCondition< NonAssignableReportConstraint, "NonAssignableReportConstraint", mean_field::stellar::Reads< mean_field::stellar::state::SpecificEnthalpy>, mean_field::stellar::Changes< mean_field::stellar::equation::HydrostaticBalance>, ScalarDescription>; using EquilibriumPhysics = mean_field::operators::SpecificationEquilibriumPhysics< PreparedNonAssignableReportRuntime>; explicit constexpr NonAssignableReportConstraint(Parameters parameters) noexcept : m_target(parameters.target) {} [[nodiscard]] constexpr auto target() const noexcept { return m_target; } private: mean_field::dimensions::SpecificEnthalpyValue m_target; }; struct OpaqueReportConstraint final { struct Parameters final { mean_field::dimensions::SpecificEnthalpyValue target; }; using ScalarDescription = mean_field::stellar::ScalarConstraint< mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, "runtime.opaque.value", "lambda_opaque", "runtime.opaque.residual", "R_opaque">; using ModelDefinition = mean_field::constraint::ScalarPhaseCondition< OpaqueReportConstraint, "OpaqueReportConstraint", mean_field::stellar::Reads< mean_field::stellar::state::SpecificEnthalpy>, mean_field::stellar::Changes< mean_field::stellar::equation::HydrostaticBalance>, ScalarDescription>; using EquilibriumPhysics = mean_field::operators::SpecificationEquilibriumPhysics< PreparedOpaqueReportRuntime>; explicit constexpr OpaqueReportConstraint(Parameters parameters) noexcept : m_target(parameters.target) {} [[nodiscard]] constexpr auto target() const noexcept { return m_target; } private: mean_field::dimensions::SpecificEnthalpyValue m_target; }; /* This fixture implements the former nested protocol verbatim. It is a * physics-facing declaration, so raw backend access must not make it an * executable contribution. */ struct RawNestedProtocolConstraint final { struct Parameters final { mean_field::dimensions::SpecificEnthalpyValue target; }; using ScalarDescription = mean_field::stellar::ScalarConstraint< mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, "runtime.raw.value", "lambda_raw", "runtime.raw.residual", "R_raw">; using ModelDefinition = mean_field::constraint::ScalarPhaseCondition< RawNestedProtocolConstraint, "RawNestedProtocolConstraint", mean_field::stellar::Reads< mean_field::stellar::state::SpecificEnthalpy>, mean_field::stellar::Changes< mean_field::stellar::equation::HydrostaticBalance>, ScalarDescription>; using EquilibriumPhysics = mean_field::operators::SpecificationEquilibriumPhysics< PreparedRawNestedProtocolConstraint>; explicit constexpr RawNestedProtocolConstraint(Parameters parameters) noexcept : m_target(parameters.target) {} [[nodiscard]] constexpr auto target() const noexcept { return m_target; } private: mean_field::dimensions::SpecificEnthalpyValue m_target; }; struct AmbiguousRuntimeRegistrationConstraint final { struct Parameters final { mean_field::dimensions::SpecificEnthalpyValue target; }; using ScalarDescription = mean_field::stellar::ScalarConstraint< mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, "runtime.ambiguous.value", "lambda_ar", "runtime.ambiguous.residual", "R_ar">; using ModelDefinition = mean_field::constraint::ScalarPhaseCondition< AmbiguousRuntimeRegistrationConstraint, "AmbiguousRuntimeRegistrationConstraint", mean_field::stellar::Reads< mean_field::stellar::state::SpecificEnthalpy>, mean_field::stellar::Changes< mean_field::stellar::equation::HydrostaticBalance>, ScalarDescription>; using EquilibriumPhysics = mean_field::operators::SpecificationEquilibriumPhysics< PreparedAmbiguousRegistrationRuntime>; explicit constexpr AmbiguousRuntimeRegistrationConstraint( Parameters parameters) noexcept : m_target(parameters.target) {} [[nodiscard]] constexpr auto target() const noexcept { return m_target; } private: mean_field::dimensions::SpecificEnthalpyValue m_target; }; /* A complete aggregate backend candidate with no nested provider. Its raw * registration is deliberately not authorized by the built-in concrete core, * so the runtime capability must reject it at exactly that boundary. */ struct UnauthorizedAggregateConstraint final { struct Parameters final { mean_field::dimensions::SpecificEnthalpyValue target; }; using ScalarDescription = mean_field::stellar::ScalarConstraint< mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, mean_field::dimensions::quantity::SpecificEnthalpy, "runtime.unauthorized.value", "lambda_unauthorized", "runtime.unauthorized.residual", "R_unauthorized">; using ModelDefinition = mean_field::constraint::ScalarPhaseCondition< UnauthorizedAggregateConstraint, "UnauthorizedAggregateConstraint", mean_field::stellar::Reads< mean_field::stellar::state::SpecificEnthalpy>, mean_field::stellar::Changes< mean_field::stellar::equation::HydrostaticBalance>, ScalarDescription>; explicit constexpr UnauthorizedAggregateConstraint( Parameters parameters) noexcept : m_target(parameters.target) {} [[nodiscard]] constexpr auto target() const noexcept { return m_target; } private: mean_field::dimensions::SpecificEnthalpyValue m_target; }; struct RegisteredWithoutMakeEquationOfState final { struct Parameters final {}; using ModelDefinition = mean_field::models::ConstitutiveLaw< RegisteredWithoutMakeEquationOfState, "RegisteredWithoutMakeEquationOfState">; explicit RegisteredWithoutMakeEquationOfState(Parameters) noexcept {} }; struct IncompleteSurfaceRuntime final { struct Parameters final {}; using ModelDefinition = mean_field::surface::BoundaryCondition< IncompleteSurfaceRuntime, "IncompleteSurfaceRuntime">; explicit IncompleteSurfaceRuntime(Parameters) noexcept {} }; /* * This constraint is executable and has complete diagnostic metadata, but it * deliberately omits its generated-coordinate Physical Riesz declaration. * It isolates model/discretization compatibility from every other runtime * capability in the rejection-boundary tests below. */ struct MissingRieszScalarConstraint final { struct Parameters final { mean_field::dimensions::MassValue target; }; using TargetValue = mean_field::dimensions::MassValue; using ModelDefinition = mean_field::integral::FixedIntegralWithMultiplier< MissingRieszScalarConstraint, "MissingRieszScalarConstraint", mean_field::models::DependsOn< mean_field::models::stellar::state::Density>, mean_field::models::Affects< mean_field::models::stellar::equation::HydrostaticBalance>, mean_field::models::UnavailableGeneratedNormalization, mean_field::models::GeneratedManifest< "missing_riesz.multiplier", "lambda_mr", "missing_riesz.residual", "R_mr", "mass", "mass">>; using EquilibriumPhysics = mean_field::operators::SpecificationEquilibriumPhysics< PreparedMissingRieszScalarConstraint>; explicit MissingRieszScalarConstraint(Parameters parameters) noexcept : m_target(parameters.target) {} [[nodiscard]] TargetValue target() const noexcept { return m_target; } private: TargetValue m_target; }; /* A second, independently inferred rotation source. Its numerical runtime is * otherwise complete; pairing it with FixedAngularMomentum must fail solely * because a physical model cannot have two owners for the generated rotation * control. */ struct SecondRotationController final { struct Parameters final { mean_field::dimensions::SpecificEnthalpyValue target; }; using TargetValue = mean_field::dimensions::SpecificEnthalpyValue; using ModelDefinition = mean_field::constraint::PhaseCondition< SecondRotationController, "SecondRotationController", mean_field::models::DependsOn< mean_field::models::stellar::state::SpecificEnthalpy>, mean_field::models::Affects< mean_field::models::stellar::equation::HydrostaticBalance>, mean_field::models::GlobalScalarNormalization< mean_field::models::PhysicalScaleLaw::specific_energy, mean_field::models::PhysicalScaleLaw::specific_energy>, mean_field::models::GeneratedManifest< "second_rotation.control", "omega_2", "second_rotation.residual", "R_omega_2", "specific_enthalpy", "specific_enthalpy">>; using EquilibriumPhysics = mean_field::operators::SpecificationEquilibriumPhysics< PreparedSecondRotationController, 1>; explicit SecondRotationController(Parameters parameters) noexcept : m_target(parameters.target) {} [[nodiscard]] TargetValue target() const noexcept { return m_target; } private: TargetValue m_target; }; struct AlternateCoreEquationOfState final { struct Parameters final {}; using ModelDefinition = mean_field::models::ConstitutiveLaw< AlternateCoreEquationOfState, "AlternateCoreEquationOfState">; using Relations = mean_field::eos::RelationCatalog< mean_field::eos::SpecificEnthalpyFromPressure>; explicit AlternateCoreEquationOfState(Parameters) noexcept {} [[nodiscard]] mean_field::dimensions::SpecificEnthalpyValue evaluate( mean_field::eos::SpecificEnthalpyFromPressure, mean_field::dimensions::PressureValue) const; }; struct WrongOwnerEquationOfState final { struct Parameters final {}; using ModelDefinition = mean_field::models::ConstitutiveLaw< WrongOwnerEquationOfState, "WrongOwnerEquationOfState">; explicit WrongOwnerEquationOfState(Parameters) noexcept {} }; /* * A deliberately tiny alternate core. No MFEM stellar assembly is needed: * this type exists to prove that the extension protocol is structural and * does not name the Polytrope implementation. */ class AlternatePhysicalCore : public mfem::Operator { public: using BackendSpecifications = mean_field::models::ModelTypeList< AlternateCoreEquationOfState, WrongOwnerEquationOfState, mean_field::surface::Isobaric, mean_field::models::FixedTotalMass, mean_field::models::FixedAngularMomentum, AmbiguousRuntimeRegistrationConstraint>; using mfem::Operator::Operator; void Mult(const mfem::Vector &, mfem::Vector &) const override; [[nodiscard]] const mean_field::operators::StellarEquilibriumLayout & GetLayout() const noexcept; [[nodiscard]] mean_field::operators::PreparedStellarEquilibriumReport Prepare( const mfem::Vector &, const mean_field::operators::StellarEquilibriumDependencies &, const mean_field::physics::RigidRotation &); void BuildResidual(mfem::Vector &) const; [[nodiscard]] bool IsPrepared() const noexcept; [[nodiscard]] mean_field::operators::RootConstraintReport GetFixedMassReport() const; [[nodiscard]] const mean_field::operators::StellarEquilibriumDependencies & GetDependencies() const; [[nodiscard]] const mean_field::operators::StellarEquilibriumDependencyStamp & GetGeneratedDisplacementDependency() const; [[nodiscard]] const mean_field::operators::PreparedPressureSurfaceConstraint & GetSurfaceConstraintOperator() const; }; class PhysicalRieszGravityContext final { public: [[nodiscard]] const mean_field::field::FieldDofMap &GetDensityMap() const noexcept; [[nodiscard]] const mean_field::field::FieldDofMap & GetGravityGradientMap() const noexcept; [[nodiscard]] const mean_field::field::FieldDofMap & GetGravityPotentialMap() const noexcept; }; class PhysicalRieszHydrostaticOperator final { public: [[nodiscard]] const mean_field::field::FieldDofMap &GetEnthalpyMap() const noexcept; }; class PhysicalRieszDomainDeformation final { public: [[nodiscard]] int parameterCount() const noexcept; }; /* * Declaration-only opt-in mock: the normalization capability is structural, * so none of the heavyweight MFEM physical assembly needs to be constructed * to prove that a distinct core can satisfy it. */ class PhysicalRieszCapableCore final : public AlternatePhysicalCore { public: using AlternatePhysicalCore::AlternatePhysicalCore; [[nodiscard]] const PhysicalRieszGravityContext &GetGravityContext() const noexcept; [[nodiscard]] const PhysicalRieszHydrostaticOperator & GetHydrostaticOperator() const noexcept; [[nodiscard]] const PhysicalRieszDomainDeformation &GetDomainDeformation() const noexcept; }; template class AlternateEquationOfStateRuntime final { public: using Report = mean_field::operators::EmptySpecificationPreparationReport; AlternateEquationOfStateRuntime( mean_field::fem::FEM &, const mean_field::mapping::DomainMapper &, AlternatePhysicalCore &, const Model &) noexcept {} template void ReadPhysicalControls(const StateView &, Controls &) noexcept {} template [[nodiscard]] Report PrepareAfterPhysical( const StateView &, const mean_field::operators::StellarEquilibriumDependencies &, const AlternatePhysicalCore &) noexcept { return {}; } template void AddResidual(const ResidualView &) const noexcept {} template void AddJacobianAction(const DirectionView &, const ActionView &, const AlternatePhysicalCore &) const noexcept {} [[nodiscard]] bool IsPrepared() const noexcept { return true; } }; template class IncompletePreparedSurfaceRuntime final { public: struct Report final { [[nodiscard]] constexpr bool DidAnyWork() const noexcept { return false; } }; IncompletePreparedSurfaceRuntime( mean_field::fem::FEM &, const mean_field::mapping::DomainMapper &, mean_field::operators::PreparedStellarEquilibriumOperator &, const Model &) noexcept {} // Intentionally omits the preparation and operator-action interface. }; template class PreparedMissingRieszScalarConstraint final { public: using Report = mean_field::operators::EmptySpecificationPreparationReport; explicit PreparedMissingRieszScalarConstraint( const MissingRieszScalarConstraint &) noexcept {} template [[nodiscard]] Report PrepareAfterPhysical(const StateView &) noexcept { return {}; } template [[nodiscard]] mean_field::stellar::StructuralZero AddResidual( Equation, Row &) const noexcept { return mean_field::stellar::structuralZero; } template [[nodiscard]] mean_field::stellar::StructuralZero AddJacobianAction( mean_field::stellar::Derivative, const Direction &, Row &) const noexcept { return mean_field::stellar::zeroDerivative; } [[nodiscard]] constexpr bool IsPrepared() const noexcept { return true; } }; template class PreparedSecondRotationController final { public: using Report = mean_field::operators::EmptySpecificationPreparationReport; explicit PreparedSecondRotationController( const SecondRotationController &) noexcept {} template [[nodiscard]] mean_field::physics::RigidRotation GenerateRotation(const StateView &) const { mfem::Vector angularVelocity(3); mfem::Vector center(3); angularVelocity = 0.0; center = 0.0; return {angularVelocity, center}; } template [[nodiscard]] Report PrepareAfterPhysical(const StateView &) noexcept { return {}; } template [[nodiscard]] mean_field::stellar::StructuralZero AddResidual( Equation, Row &) const noexcept { return mean_field::stellar::structuralZero; } template [[nodiscard]] mean_field::stellar::StructuralZero AddJacobianAction( mean_field::stellar::Derivative, const Direction &, Row &) const noexcept { return mean_field::stellar::zeroDerivative; } [[nodiscard]] constexpr bool IsPrepared() const noexcept { return true; } }; template class PreparedRawNestedProtocolConstraint final { public: using Report = OpaqueRuntimeReport; template PreparedRawNestedProtocolConstraint( mean_field::fem::FEM &, const mean_field::mapping::DomainMapper &, Core &, const Model &) noexcept {} template void ReadPhysicalControls(const StateView &, Controls &) noexcept {} template [[nodiscard]] Report PrepareAfterPhysical( const StateView &, const mean_field::operators::StellarEquilibriumDependencies &, const Core &) noexcept { return {}; } template void AddResidual(const ResidualView &) const noexcept {} template void AddJacobianAction(const DirectionView &, const ActionView &, const Core &) const noexcept {} [[nodiscard]] constexpr bool IsPrepared() const noexcept { return true; } }; } // namespace stellar_runtime_contract_test namespace mean_field::operators { template <> struct StellarEquilibriumCoreRuntime< stellar_runtime_contract_test::RegisteredWithoutMakeEquationOfState> { static constexpr bool registered = true; // Intentionally no Make(). Capability follows the callable interface. }; template <> struct StellarEquilibriumCoreRuntime< stellar_runtime_contract_test::AlternateCoreEquationOfState> { static constexpr bool registered = true; using CoreType = stellar_runtime_contract_test::AlternatePhysicalCore; [[nodiscard]] static std::unique_ptr Make( fem::FEM &, const mapping::DomainMapper &, const stellar_runtime_contract_test::AlternateCoreEquationOfState &, const models::CompiledFixedMass &, PressureSurfaceConstraintView, deformation::PreparedDomainDeformationRuntime); [[nodiscard]] static int SurfaceEquationCount(const CoreType &) noexcept; }; template <> struct StellarEquilibriumRuntimeContribution< stellar_runtime_contract_test::AlternateCoreEquationOfState> : PreparedStellarEquilibriumContribution< stellar_runtime_contract_test::AlternateEquationOfStateRuntime> {}; template <> struct StellarEquilibriumCoreRuntime< stellar_runtime_contract_test::WrongOwnerEquationOfState> { static constexpr bool registered = true; using CoreType = stellar_runtime_contract_test::AlternatePhysicalCore; // Intentionally owns the Polytrope core instead of the advertised type. [[nodiscard]] static std::unique_ptr Make( fem::FEM &, const mapping::DomainMapper &, const stellar_runtime_contract_test::WrongOwnerEquationOfState &, const models::CompiledFixedMass &, PressureSurfaceConstraintView, deformation::PreparedDomainDeformationRuntime); [[nodiscard]] static int SurfaceEquationCount(const CoreType &) noexcept; }; template <> struct StellarEquilibriumRuntimeContribution< stellar_runtime_contract_test::WrongOwnerEquationOfState> : PreparedStellarEquilibriumContribution< stellar_runtime_contract_test::AlternateEquationOfStateRuntime> {}; template <> struct StellarEquilibriumRuntimeContribution< stellar_runtime_contract_test::IncompleteSurfaceRuntime> : PreparedStellarEquilibriumContribution< stellar_runtime_contract_test::IncompletePreparedSurfaceRuntime> {}; template <> struct StellarEquilibriumRuntimeContribution< stellar_runtime_contract_test::UnauthorizedAggregateConstraint> : PreparedStellarEquilibriumContribution< stellar_runtime_contract_test:: PreparedRawNestedProtocolConstraint> {}; /* Deliberately duplicates the constraint's nested package. Whether that is an * ambiguity depends on the selected core's own privileged allow-list. */ template <> struct StellarEquilibriumRuntimeContribution< stellar_runtime_contract_test::AmbiguousRuntimeRegistrationConstraint> : PreparedStellarEquilibriumContribution< stellar_runtime_contract_test:: AlternateEquationOfStateRuntime> {}; } // namespace mean_field::operators namespace { using namespace mean_field; using BaseModel = model::StellarModel>; using CentralDensityModel = model::StellarModel>; using AngularMomentumModel = model::StellarModel>; using AngularCentralDensityModel = model::StellarModel>; using DensityValue = utils::blocks::density::mass::value; using SurfaceValue = utils::blocks::surface_deformation::parameters::value; using GravityGradientValue = utils::blocks::gravity::gradient::value; using GravityPotentialValue = utils::blocks::gravity::poisson::value; using EnthalpyValue = utils::blocks::enthalpy::specific::value; using MassValue = utils::blocks::fixed_total_mass::mass_normalization::value; using AngularVelocityValue = utils::blocks::fixed_angular_momentum::angular_velocity::value; using CentralDensityValue = utils::blocks::fixed_central_density::central_value::value; using GravityGradientResidual = utils::blocks::gravity::gradient::residual; using GravityPotentialResidual = utils::blocks::gravity::poisson::residual; using DensityResidual = utils::blocks::density::mass::residual; using SurfaceResidual = utils::blocks::surface_deformation::shape_equilibrium::residual; using EnthalpyResidual = utils::blocks::enthalpy::specific::residual; using MassResidual = utils::blocks::fixed_total_mass::mass_normalization::residual; using AngularMomentumResidual = utils::blocks::fixed_angular_momentum::angular_velocity::residual; using CentralDensityResidual = utils::blocks::fixed_central_density::central_value::residual; using ExpectedAngularMomentumForm = utils::blocks::block_form< utils::blocks::type_list, utils::blocks::type_list< GravityGradientResidual, GravityPotentialResidual, DensityResidual, SurfaceResidual, EnthalpyResidual, MassResidual, AngularMomentumResidual>>; using ExpectedAngularMomentumJacobian = utils::blocks::type_list< utils::blocks::block_row, utils::blocks::block_row, utils::blocks::block_row, utils::blocks::block_row, utils::blocks::block_row, utils::blocks::block_row, utils::blocks::block_row>; using ExpectedAngularCentralDensityForm = utils::blocks::block_form< utils::blocks::type_list, utils::blocks::type_list< GravityGradientResidual, GravityPotentialResidual, DensityResidual, SurfaceResidual, EnthalpyResidual, MassResidual, AngularMomentumResidual, CentralDensityResidual>>; using ExpectedAngularCentralDensityJacobian = utils::blocks::type_list< utils::blocks::block_row, utils::blocks::block_row, utils::blocks::block_row, utils::blocks::block_row, utils::blocks::block_row, utils::blocks::block_row, utils::blocks::block_row, utils::blocks::block_row>; using MissingMassModel = model::StellarModel< models::SpecificationSet>; using RegisteredWithoutMakeModel = model::StellarModel>; using AlternateCoreModel = model::StellarModel>; using AlternateCoreAngularMomentumModel = model::StellarModel>; using MissingRieszModel = model::StellarModel>; using TwoRotationProvidersModel = model::StellarModel>; using NonDefaultReportModel = model::StellarModel>; using NonAssignableReportModel = model::StellarModel>; using OpaqueReportModel = model::StellarModel>; using RawNestedProtocolModel = model::StellarModel>; /* * Focused fixtures for the exact physics-provider contract. Every class is * constructible from the same valid specification, so a failed provider * concept below can only come from its residual/Jacobian overload set. * * RawNestedProtocolConstraint declares one owned constraint row, one changed * physical row, one read physical state, and one owned generated coordinate. * The compiler therefore requires exactly two residual providers and three * derivative providers. */ class CompleteExplicitZeroProvider final { public: explicit CompleteExplicitZeroProvider( const stellar_runtime_contract_test::RawNestedProtocolConstraint &) noexcept {} template [[nodiscard]] stellar::StructuralZero AddResidual( stellar::equation::OwnConstraint, Row &) const noexcept { return stellar::structuralZero; } template [[nodiscard]] stellar::StructuralZero AddResidual( stellar::equation::HydrostaticBalance, Row &) const noexcept { return stellar::structuralZero; } template [[nodiscard]] stellar::StructuralZero AddJacobianAction( stellar::Derivative, const Direction &, Row &) const noexcept { return stellar::zeroDerivative; } template [[nodiscard]] stellar::StructuralZero AddJacobianAction( stellar::Derivative, const Direction &, Row &) const noexcept { return stellar::zeroDerivative; } template [[nodiscard]] stellar::StructuralZero AddJacobianAction( stellar::Derivative, const Direction &, Row &) const noexcept { return stellar::zeroDerivative; } }; class MissingHydrostaticResidualProvider final { public: explicit MissingHydrostaticResidualProvider( const stellar_runtime_contract_test::RawNestedProtocolConstraint &) noexcept {} template [[nodiscard]] stellar::StructuralZero AddResidual( stellar::equation::OwnConstraint, Row &) const noexcept { return stellar::structuralZero; } template [[nodiscard]] stellar::StructuralZero AddJacobianAction( stellar::Derivative, const Direction &, Row &) const noexcept { return stellar::zeroDerivative; } template [[nodiscard]] stellar::StructuralZero AddJacobianAction( stellar::Derivative, const Direction &, Row &) const noexcept { return stellar::zeroDerivative; } template [[nodiscard]] stellar::StructuralZero AddJacobianAction( stellar::Derivative, const Direction &, Row &) const noexcept { return stellar::zeroDerivative; } }; class MissingGeneratedControlDerivativeProvider final { public: explicit MissingGeneratedControlDerivativeProvider( const stellar_runtime_contract_test::RawNestedProtocolConstraint &) noexcept {} template [[nodiscard]] stellar::StructuralZero AddResidual( stellar::equation::OwnConstraint, Row &) const noexcept { return stellar::structuralZero; } template [[nodiscard]] stellar::StructuralZero AddResidual( stellar::equation::HydrostaticBalance, Row &) const noexcept { return stellar::structuralZero; } template [[nodiscard]] stellar::StructuralZero AddJacobianAction( stellar::Derivative, const Direction &, Row &) const noexcept { return stellar::zeroDerivative; } template [[nodiscard]] stellar::StructuralZero AddJacobianAction( stellar::Derivative, const Direction &, Row &) const noexcept { return stellar::zeroDerivative; } }; /* The pre-refactor imperative shape can be constructed, but neither callback * identifies a compiler-enumerated equation/state pair or returns the token * required to prove that the pair was handled. */ class LegacyBroadEmptyProvider final { public: explicit LegacyBroadEmptyProvider( const stellar_runtime_contract_test::RawNestedProtocolConstraint &) noexcept {} template void AddResidual(const ResidualView &) const noexcept {} template void AddJacobianAction(const DirectionView &, const ActionView &, const Core &) const noexcept {} }; template concept HasExactProviderResidual = requires( const Physics &physics, operators::StellarEquilibriumContributionRow< stellar_runtime_contract_test::RawNestedProtocolConstraint, RawNestedProtocolModel, Equation> &row) { { physics.AddResidual(Equation{}, row) } -> stellar::ContributionResult; }; template concept HasExactProviderDerivative = requires( const Physics &physics, const operators::StellarEquilibriumContributionDirection< stellar_runtime_contract_test::RawNestedProtocolConstraint, RawNestedProtocolModel, State> &direction, operators::StellarEquilibriumContributionRow< stellar_runtime_contract_test::RawNestedProtocolConstraint, RawNestedProtocolModel, Equation> &row) { { physics.AddJacobianAction(stellar::Derivative{}, direction, row) } -> stellar::ContributionResult; }; using AmbiguousRuntimeRegistrationModel = model::StellarModel>; using UnauthorizedAggregateModel = model::StellarModel>; using AuthorizedAmbiguousRuntimeRegistrationModel = model::StellarModel>; using PhysicalRieszDiscretization = equilibrium::StellarDiscretizationFor< normalization::PhysicalRieszDiagonal<>>; using BaseProblem = equilibrium::StellarEquilibriumProblem; using BasePhysicalRieszProblem = equilibrium::StellarEquilibriumProblem< BaseModel, PhysicalRieszDiscretization>; using AlternateCoreProblem = equilibrium::StellarEquilibriumProblem; using MissingRieszUnnormalizedProblem = equilibrium::StellarEquilibriumProblem; using WrongOwnerModel = model::StellarModel>; using IncompleteSurfaceRuntimeModel = model::StellarModel>; using CarrierlessManifestForm = utils::blocks::block_form< utils::blocks::type_list< utils::blocks::fixed_total_mass::mass_normalization::value>, utils::blocks::type_list< utils::blocks::fixed_total_mass::mass_normalization::residual>>; struct UnsupportedCentralDensityEquationOfState final { struct Parameters final {}; using ModelDefinition = models::ConstitutiveLaw< UnsupportedCentralDensityEquationOfState, "UnsupportedCentralDensityEquationOfState">; explicit UnsupportedCentralDensityEquationOfState(Parameters) noexcept {} }; using UnsupportedCentralDensityModel = model::StellarModel< models::SpecificationSet>; struct EarlierMultiplier final { struct Parameters final {}; using ModelDefinition = models::FixedIntegralWithMultiplier< EarlierMultiplier, "AardvarkMultiplier", models::DependsOn, models::Affects>; explicit EarlierMultiplier(Parameters) noexcept {} }; using EarlierMultiplierValue = utils::blocks::generated_value_block< models::MultiplierFor>; using EarlierMultiplierModel = model::StellarModel>; struct FullPhysicsStateReader final { struct Parameters final {}; using ModelDefinition = models::FixedIntegralWithPhysicalCoordinate< FullPhysicsStateReader, "FullPhysicsStateReader", models::DependsOn< models::stellar::state::Density, models::stellar::state::SurfaceShape, models::stellar::state::GravityGradient, models::stellar::state::GravitationalPotential, models::stellar::state::SpecificEnthalpy>, models::Affects>; explicit FullPhysicsStateReader(Parameters) noexcept {} }; using FullPhysicsStateReaderModel = model::StellarModel< models::SpecificationSet< eos::Polytrope, surface::Isobaric, models::FixedTotalMass, FullPhysicsStateReader>>; struct CrossAlpha; struct CrossBeta; using CrossAlphaValue = utils::blocks::generated_value_block< models::PhysicalCoordinateFor>; using CrossAlphaResidual = utils::blocks::generated_residual_block>; using CrossBetaValue = utils::blocks::generated_value_block< models::PhysicalCoordinateFor>; using CrossBetaResidual = utils::blocks::generated_residual_block>; struct CrossAlphaTerm final { using value = CrossAlphaValue; using residual = CrossAlphaResidual; }; struct CrossBetaTerm final { using value = CrossBetaValue; using residual = CrossBetaResidual; }; inline constexpr CrossAlphaTerm crossAlphaTerm{}; inline constexpr CrossBetaTerm crossBetaTerm{}; struct NoOpJacobianCallback final { template void operator()(DirectionView &, ActionView &) const noexcept {} }; struct OneArgumentJacobianCallback final { template void operator()(DirectionView &) const noexcept {} }; struct NonVoidJacobianCallback final { template [[nodiscard]] int operator()(DirectionView &, ActionView &) const noexcept { return 0; } }; template < typename JacobianView, typename ResidualTerm, typename ValueTerm, typename Callback = NoOpJacobianCallback> concept CanBindDeclaredJacobianCallback = requires( const JacobianView &jacobian, const ResidualTerm &residual, const ValueTerm &value, Callback callback ) { jacobian.add(residual, value, std::move(callback)); }; template concept CanAddRawJacobianContribution = requires( const JacobianView &jacobian, const ResidualTerm &residual, const ValueTerm &value ) { jacobian.add(residual, value, 1.0); }; template concept CanAddRawJacobianEntry = requires( const JacobianView &jacobian, const ResidualTerm &residual, const ValueTerm &value ) { jacobian.addEntry(residual, value, 0, 1.0); }; /* * Alpha is canonicalized before Beta, yet both of Alpha's edges name a * block contributed by Beta. A sequential compiler loses Alpha's affected * edge because Beta's residual row does not exist yet. */ struct CrossAlpha final { struct Parameters final {}; using ModelDefinition = models::FixedIntegralWithPhysicalCoordinate< CrossAlpha, "CompilerCrossAlpha", models::DependsOn, models::Affects>; explicit CrossAlpha(Parameters) noexcept {} }; struct CrossBeta final { struct Parameters final {}; using ModelDefinition = models::FixedIntegralWithPhysicalCoordinate< CrossBeta, "CompilerCrossBeta", models::DependsOn, models::Affects< utils::blocks::surface_deformation::shape_equilibrium::residual>>; explicit CrossBeta(Parameters) noexcept {} }; using CrossModel = model::StellarModel< models::SpecificationSet>; using PermutedCrossModel = model::StellarModel< models::SpecificationSet>; struct MalformedDeclaration final { struct Parameters final {}; using ModelDefinition = models::FixedIntegralWithPhysicalCoordinate< MalformedDeclaration, "MalformedCompilerDeclaration", models::DependsOn, models::Affects>; explicit MalformedDeclaration(Parameters) noexcept {} }; using MalformedModel = model::StellarModel< models::SpecificationSet>; struct UnmappedStellarState final {}; struct UnmappedPhysicsDependency final { struct Parameters final {}; using ModelDefinition = models::FixedIntegralWithPhysicalCoordinate< UnmappedPhysicsDependency, "UnmappedPhysicsDependency", models::DependsOn, models::Affects>; explicit UnmappedPhysicsDependency(Parameters) noexcept {} }; using UnmappedPhysicsModel = model::StellarModel>; struct UnmappedStellarEquation final {}; struct UnmappedPhysicsEffect final { struct Parameters final {}; using ModelDefinition = models::FixedIntegralWithPhysicalCoordinate< UnmappedPhysicsEffect, "UnmappedPhysicsEffect", models::DependsOn, models::Affects>; explicit UnmappedPhysicsEffect(Parameters) noexcept {} }; using UnmappedPhysicsEffectModel = model::StellarModel>; struct ForeignValueBlock final : utils::blocks::value_block_base {}; struct OrphanEndpoint final { struct Parameters final {}; using ModelDefinition = models::FixedIntegralWithPhysicalCoordinate< OrphanEndpoint, "OrphanCompilerEndpoint", models::DependsOn, models::Affects>; explicit OrphanEndpoint(Parameters) noexcept {} }; using OrphanEndpointModel = model::StellarModel< models::SpecificationSet>; template concept HasCompiledStellarEquilibriumSystem = requires { typename operators::CompiledStellarEquilibriumSystem; }; template concept HasPreparedVariadicStellarEquilibriumOperator = requires { typename operators::PreparedVariadicStellarEquilibriumOperator; }; template concept HasNormalizedStellarEquilibriumOperator = requires { typename normalization::NormalizedStellarEquilibriumOperator; }; template concept CanMakeNormalizedStellarEquilibriumOperator = requires(Problem &problem) { normalization::makeNormalizedStellarEquilibriumOperator(problem); }; template concept CanMakeDefaultStellarPreconditioner = requires(const Problem &problem) { preconditioning::makePreconditioner(problem); }; template concept HasStellarEquilibriumProblem = requires { typename equilibrium::StellarEquilibriumProblem; }; template concept CanDiscretizeStellarModel = requires(Model &&model, Discretization discretization) { equilibrium::discretize(std::move(model), std::move(discretization)); }; template concept CanAccessContributionBlock = requires(const View &view, const Term &term) { view.block(term); }; template concept CanAddContributionBlock = requires(const View &view, const Term &term) { view.add(term, 0.0); }; template concept CanAddContributionVectorAndEntry = requires( const View &view, const Term &term, const mfem::Vector &contribution ) { view.add(term, contribution); view.addEntry(term, 0, 0.0); }; template concept HasPhysicsDensity = requires(const View &view) { view.density(); }; template concept HasPhysicsSurfaceShape = requires(const View &view) { view.surfaceShape(); }; template concept HasPhysicsGravityGradient = requires(const View &view) { view.gravityGradient(); }; template concept HasPhysicsGravitationalPotential = requires(const View &view) { view.gravitationalPotential(); }; template concept HasPhysicsSpecificEnthalpy = requires(const View &view) { view.specificEnthalpy(); }; template concept HasPhysicsGeneratedCoordinate = requires(const View &view) { view.generatedCoordinate(); }; template concept ExposesUnrestrictedRootVector = requires(const View &view) { view.vector(); }; template < typename ExpectedSourceTerm, typename OtherSourceTerm, typename ExpectedResidualTerm, typename OtherResidualTerm, bool NamesOwnGeneratedCoordinate> struct ExactPairAuditCallback final { template requires CanAccessContributionBlock && (!CanAccessContributionBlock) && (HasPhysicsGeneratedCoordinate == NamesOwnGeneratedCoordinate) && (!HasPhysicsDensity) && (!HasPhysicsSpecificEnthalpy) && CanAddContributionBlock && CanAddContributionVectorAndEntry< ActionView, ExpectedResidualTerm> && (!CanAddContributionBlock) && (!ExposesUnrestrictedRootVector) && (!ExposesUnrestrictedRootVector) void operator()(DirectionView &, ActionView &) const noexcept {} }; struct RequiresCrossProductDirectionCallback final { template requires CanAccessContributionBlock && CanAccessContributionBlock void operator()(DirectionView &, ActionView &) const noexcept {} }; struct RequiresCrossProductActionCallback final { template requires CanAddContributionBlock && CanAddContributionBlock void operator()(DirectionView &, ActionView &) const noexcept {} }; } // namespace TEST_CASE("Two-Pass Stellar Compiler Preserves Established Physical Forms", "[stellar-equilibrium][compiler][type-contract]") { using namespace mean_field; STATIC_CHECK(operators::StellarEquilibriumSystemCompilable); STATIC_CHECK(BaseModel::hasCompleteEquilibriumDeclaration); STATIC_CHECK( operators::CompiledStellarEquilibriumSystem::compilationClass == models::EquilibriumSystemCompilation::complete_equilibrium_system); STATIC_CHECK(operators::hasStellarEquilibriumCoreRuntime); STATIC_CHECK(operators::hasCompleteStellarEquilibriumRuntime); STATIC_CHECK(equilibrium::hasStellarEquilibriumSurfaceCompilation); STATIC_CHECK( operators::StellarEquilibriumSystemCompilable); STATIC_CHECK( operators::StellarEquilibriumSystemCompilable); STATIC_CHECK(operators::StellarEquilibriumSystemCompilable< AngularCentralDensityModel>); STATIC_CHECK( (std::same_as, utils::blocks::surface_deformed_stellar_equilibrium_form>)); STATIC_CHECK( (std::same_as< operators::CompiledStellarEquilibriumJacobianForm, utils::blocks::surface_deformed_stellar_equilibrium_jacobian_form>)); STATIC_CHECK( (std::same_as< operators::CompiledStellarEquilibriumForm, utils::blocks::central_density_bordered_stellar_equilibrium_form>)); STATIC_CHECK( (std::same_as< operators::CompiledStellarEquilibriumJacobianForm< CentralDensityModel>, utils::blocks:: central_density_bordered_stellar_equilibrium_jacobian_form>)); STATIC_CHECK((std::same_as< operators::CompiledStellarEquilibriumForm< AngularMomentumModel>, ExpectedAngularMomentumForm>)); STATIC_CHECK((std::same_as< operators::CompiledStellarEquilibriumJacobianForm< AngularMomentumModel>, ExpectedAngularMomentumJacobian>)); STATIC_CHECK((std::same_as< operators::CompiledStellarEquilibriumForm< AngularCentralDensityModel>, ExpectedAngularCentralDensityForm>)); STATIC_CHECK((std::same_as< operators::CompiledStellarEquilibriumJacobianForm< AngularCentralDensityModel>, ExpectedAngularCentralDensityJacobian>)); } TEST_CASE("Runtime Contributions See Only Their Declared Physics Blocks", "[stellar-equilibrium][runtime][sparsity][type-contract]") { using namespace mean_field; using AngularState = operators::StellarEquilibriumContributionStateView< models::FixedAngularMomentum, AngularMomentumModel>; using AngularResidual = operators::StellarEquilibriumContributionResidualView< models::FixedAngularMomentum, AngularMomentumModel>; using CentralState = operators::StellarEquilibriumContributionStateView< models::FixedCentralDensity, CentralDensityModel>; using CentralResidual = operators::StellarEquilibriumContributionResidualView< models::FixedCentralDensity, CentralDensityModel>; using FullPhysicsState = operators::StellarEquilibriumContributionStateView< FullPhysicsStateReader, FullPhysicsStateReaderModel>; STATIC_CHECK(CanAccessContributionBlock< AngularState, decltype(utils::blocks::density_field.mass_term)>); STATIC_CHECK(CanAccessContributionBlock< AngularState, decltype(utils::blocks::surface_deformation_field.parameters_term)>); STATIC_CHECK(CanAccessContributionBlock< AngularState, decltype(utils::blocks::fixed_angular_momentum_constraint .angular_velocity_term)>); STATIC_CHECK_FALSE(CanAccessContributionBlock< AngularState, decltype(utils::blocks::gravity_field.poisson_term)>); STATIC_CHECK(HasPhysicsDensity); STATIC_CHECK(HasPhysicsSurfaceShape); STATIC_CHECK(HasPhysicsGeneratedCoordinate); STATIC_CHECK_FALSE(HasPhysicsGravityGradient); STATIC_CHECK_FALSE(HasPhysicsGravitationalPotential); STATIC_CHECK_FALSE(HasPhysicsSpecificEnthalpy); STATIC_CHECK(CanAddContributionBlock< AngularResidual, decltype(utils::blocks::fixed_angular_momentum_constraint .angular_velocity_term)>); STATIC_CHECK(CanAddContributionBlock< AngularResidual, decltype(utils::blocks::surface_deformation_field .shape_equilibrium_term)>); STATIC_CHECK(CanAddContributionBlock< AngularResidual, decltype(utils::blocks::enthalpy_field.specific_term)>); STATIC_CHECK_FALSE(CanAddContributionBlock< AngularResidual, decltype(utils::blocks::density_field.mass_term)>); STATIC_CHECK(CanAccessContributionBlock< CentralState, decltype(utils::blocks::enthalpy_field.specific_term)>); STATIC_CHECK(CanAccessContributionBlock< CentralState, decltype(utils::blocks::fixed_central_density_phase .central_value_term)>); STATIC_CHECK_FALSE(CanAccessContributionBlock< CentralState, decltype(utils::blocks::density_field.mass_term)>); STATIC_CHECK(HasPhysicsSpecificEnthalpy); STATIC_CHECK(HasPhysicsGeneratedCoordinate); STATIC_CHECK_FALSE(HasPhysicsDensity); STATIC_CHECK_FALSE(HasPhysicsSurfaceShape); // The astronomer-facing names span the complete current barotropic core // and the specification's inferred scalar without exposing backend block // types. Each accessor remains absent unless its dependency was declared. STATIC_CHECK(HasPhysicsDensity); STATIC_CHECK(HasPhysicsSurfaceShape); STATIC_CHECK(HasPhysicsGravityGradient); STATIC_CHECK(HasPhysicsGravitationalPotential); STATIC_CHECK(HasPhysicsSpecificEnthalpy); STATIC_CHECK(HasPhysicsGeneratedCoordinate); STATIC_CHECK(CanAddContributionBlock< CentralResidual, decltype(utils::blocks::enthalpy_field.specific_term)>); STATIC_CHECK(CanAddContributionBlock< CentralResidual, decltype(utils::blocks::fixed_central_density_phase .central_value_term)>); // Residual access is additive-only: declared rows are writable through add, // but no specification can obtain a mutable block and overwrite an earlier // contribution. There is also no escape hatch to the full root vector. STATIC_CHECK_FALSE(CanAccessContributionBlock< AngularResidual, decltype(utils::blocks::enthalpy_field.specific_term)>); STATIC_CHECK_FALSE(CanAccessContributionBlock< CentralResidual, decltype(utils::blocks::enthalpy_field.specific_term)>); STATIC_CHECK_FALSE(ExposesUnrestrictedRootVector); STATIC_CHECK_FALSE(ExposesUnrestrictedRootVector); STATIC_CHECK_FALSE(ExposesUnrestrictedRootVector); STATIC_CHECK_FALSE(ExposesUnrestrictedRootVector); } TEST_CASE("Built-In Physics Declarations Are The Compiler's Single Source", "[stellar-equilibrium][compiler][metadata][physics-api]") { using namespace mean_field; using EmptyBlocks = utils::blocks::type_list<>; using PolytropeCompilation = operators::StellarEquilibriumSpecificationCompilation; using IsobaricCompilation = operators::StellarEquilibriumSpecificationCompilation; using MassContribution = models::SpecificationContribution; using AngularContribution = models::SpecificationContribution; using CentralContribution = models::SpecificationContribution; STATIC_CHECK((std::same_as< typename MassContribution::DependsOn, models::DependsOn>)); STATIC_CHECK((std::same_as< typename MassContribution::Affects, models::Affects< models::stellar::equation::HydrostaticBalance>>)); STATIC_CHECK((std::same_as< typename AngularContribution::DependsOn, models::DependsOn< models::stellar::state::Density, models::stellar::state::SurfaceShape, models::stellar::state::OwnGeneratedCoordinate>>)); STATIC_CHECK((std::same_as< typename AngularContribution::Affects, models::Affects< models::stellar::equation::SurfaceShapeBalance, models::stellar::equation::HydrostaticBalance>>)); STATIC_CHECK((std::same_as< typename CentralContribution::DependsOn, models::DependsOn< models::stellar::state::SpecificEnthalpy>>)); STATIC_CHECK((std::same_as< typename CentralContribution::Affects, models::Affects< models::stellar::equation::HydrostaticBalance>>)); using MassCompilation = operators::StellarEquilibriumSpecificationCompilation< models::FixedTotalMass>; using AngularCompilation = operators::StellarEquilibriumSpecificationCompilation< models::FixedAngularMomentum>; using CentralCompilation = operators::StellarEquilibriumSpecificationCompilation< models::FixedCentralDensity>; STATIC_CHECK( operators::stellarEquilibriumSpecificationCompilationComplete< eos::Polytrope>); STATIC_CHECK( operators::stellarEquilibriumSpecificationCompilationComplete< surface::Isobaric>); STATIC_CHECK((std::same_as< typename PolytropeCompilation::GeneratedValueBlocks, EmptyBlocks>)); STATIC_CHECK((std::same_as< typename PolytropeCompilation::GeneratedResidualBlocks, EmptyBlocks>)); STATIC_CHECK((std::same_as< typename IsobaricCompilation::GeneratedValueBlocks, EmptyBlocks>)); STATIC_CHECK((std::same_as< typename IsobaricCompilation::GeneratedResidualBlocks, EmptyBlocks>)); STATIC_CHECK((std::same_as>)); STATIC_CHECK((std::same_as< typename MassCompilation::AffectedResidualBlocks, utils::blocks::type_list>)); STATIC_CHECK((std::same_as< typename AngularCompilation::DependsOnValueBlocks, utils::blocks::type_list>)); STATIC_CHECK((std::same_as< typename AngularCompilation::AffectedResidualBlocks, utils::blocks::type_list>)); STATIC_CHECK((std::same_as< typename CentralCompilation::DependsOnValueBlocks, utils::blocks::type_list>)); STATIC_CHECK((std::same_as< typename CentralCompilation::AffectedResidualBlocks, utils::blocks::type_list>)); const auto descriptors = AngularCentralDensityModel::runtimeSpecificationDescriptors(); REQUIRE(descriptors.size() == 5); CHECK(descriptors[2].specification.name == "FixedTotalMass"); CHECK(descriptors[3].specification.name == "FixedAngularMomentum"); CHECK(descriptors[4].specification.name == "FixedCentralDensity"); CHECK(descriptors[2].hasDeclarativeDefinition); CHECK(descriptors[3].hasDeclarativeDefinition); CHECK(descriptors[4].hasDeclarativeDefinition); } TEST_CASE("Fixed Total Mass Exposes Its Generated Blocks And Incident Edges", "[stellar-equilibrium][compiler][metadata]") { using namespace mean_field; using Compilation = operators::StellarEquilibriumSpecificationCompilation< models::FixedTotalMass>; using MassValue = utils::blocks::fixed_total_mass::mass_normalization::value; using MassResidual = utils::blocks::fixed_total_mass::mass_normalization::residual; STATIC_CHECK(operators::stellarEquilibriumSpecificationCompilationComplete< models::FixedTotalMass>); STATIC_CHECK((std::same_as>)); STATIC_CHECK((std::same_as>)); STATIC_CHECK((std::same_as>)); STATIC_CHECK(utils::blocks::contains_type_v< operators::EquilibriumJacobianCoupling< MassResidual, utils::blocks::density::mass::value>, typename Compilation::IncidentJacobianCouplings>); STATIC_CHECK(utils::blocks::contains_type_v< operators::EquilibriumJacobianCoupling< utils::blocks::enthalpy::specific::residual, MassValue>, typename Compilation::IncidentJacobianCouplings>); } TEST_CASE("Core Coordinates Are Identified By Type Rather Than Pack Position", "[stellar-equilibrium][compiler][ordering]") { using namespace mean_field; using Form = operators::CompiledStellarEquilibriumForm; using MassValue = utils::blocks::fixed_total_mass::mass_normalization::value; STATIC_CHECK( operators::StellarEquilibriumSystemCompilable); STATIC_CHECK(utils::blocks::type_index_v< EarlierMultiplierValue, typename Form::value_blocks> == 5); STATIC_CHECK(utils::blocks::type_index_v< MassValue, typename Form::value_blocks> == 6); STATIC_CHECK(utils::blocks::has_jacobian_coupling_v< utils::blocks::enthalpy::specific::residual, EarlierMultiplierValue, operators::CompiledStellarEquilibriumJacobianForm< EarlierMultiplierModel>>); } TEST_CASE("Two-Pass Compiler Resolves Couplings Across Independently Declared " "Constraints", "[stellar-equilibrium][compiler][variadic][order-independence]") { using namespace mean_field; using System = operators::CompiledStellarEquilibriumSystem; using Form = typename System::FormType; using Jacobian = typename System::JacobianType; STATIC_CHECK(models::ModelSpecification); STATIC_CHECK(models::ModelSpecification); STATIC_CHECK((std::same_as)); STATIC_CHECK(operators::stellarEquilibriumSpecificationCompilationComplete< CrossAlpha>); STATIC_CHECK( operators::stellarEquilibriumSpecificationCompilationComplete); STATIC_CHECK(operators::StellarEquilibriumSystemCompilable); STATIC_CHECK(Form::value_block_count == 8); STATIC_CHECK(Form::residual_block_count == 8); STATIC_CHECK(utils::blocks::valid_jacobian_form); // Both endpoints are introduced by different declarations. In particular, // R_B does not exist when a one-pass compiler visits Alpha. STATIC_CHECK( utils::blocks::has_jacobian_coupling_v); STATIC_CHECK( utils::blocks::has_jacobian_coupling_v); STATIC_CHECK( utils::blocks::has_jacobian_coupling_v< CrossBetaResidual, utils::blocks::density::mass::value, Jacobian>); STATIC_CHECK(utils::blocks::has_jacobian_coupling_v< utils::blocks::surface_deformation::shape_equilibrium::residual, CrossBetaValue, Jacobian>); // Changes are conservatively state dependent on every declared Read. This // is the Hessian-like block required by nonlinear constrained systems. STATIC_CHECK(utils::blocks::has_jacobian_coupling_v< CrossBetaResidual, CrossBetaValue, Jacobian>); STATIC_CHECK(utils::blocks::contains_type_v< operators::EquilibriumJacobianCoupling, typename System::ContributionJacobianCouplings>); STATIC_CHECK((std::same_as< typename System::GeneratedCorrectionBlocks, utils::blocks::type_list< utils::blocks::fixed_total_mass::mass_normalization::value, CrossAlphaValue, CrossBetaValue>>)); using CrossAlphaJacobian = operators::StellarEquilibriumContributionJacobianView< CrossAlpha, CrossModel>; using AlphaResidualFromBetaValue = ExactPairAuditCallback< CrossBetaTerm, CrossAlphaTerm, CrossAlphaTerm, CrossBetaTerm, false>; using BetaResidualFromAlphaValue = ExactPairAuditCallback< CrossAlphaTerm, CrossBetaTerm, CrossBetaTerm, CrossAlphaTerm, true>; using BetaResidualFromBetaValue = ExactPairAuditCallback< CrossBetaTerm, CrossAlphaTerm, CrossBetaTerm, CrossAlphaTerm, false>; STATIC_CHECK(CanBindDeclaredJacobianCallback< CrossAlphaJacobian, CrossAlphaTerm, CrossBetaTerm, AlphaResidualFromBetaValue>); STATIC_CHECK(CanBindDeclaredJacobianCallback< CrossAlphaJacobian, CrossBetaTerm, CrossAlphaTerm, BetaResidualFromAlphaValue>); STATIC_CHECK(CanBindDeclaredJacobianCallback< CrossAlphaJacobian, CrossBetaTerm, CrossBetaTerm, BetaResidualFromBetaValue>); // Alpha's residual does not read Alpha's coordinate. Although that row and // column are independently present in other callbacks, their undeclared // diagonal cannot bind a callback. Raw scalar writes and malformed callback // protocols are rejected too: all numeric accumulation happens through the // one-row action supplied to a valid callback. STATIC_CHECK_FALSE(CanBindDeclaredJacobianCallback< CrossAlphaJacobian, CrossAlphaTerm, CrossAlphaTerm>); STATIC_CHECK_FALSE(CanAddRawJacobianContribution< CrossAlphaJacobian, CrossAlphaTerm, CrossBetaTerm>); STATIC_CHECK_FALSE(CanAddRawJacobianEntry< CrossAlphaJacobian, CrossAlphaTerm, CrossBetaTerm>); STATIC_CHECK_FALSE(CanBindDeclaredJacobianCallback< CrossAlphaJacobian, CrossAlphaTerm, CrossBetaTerm, OneArgumentJacobianCallback>); STATIC_CHECK_FALSE(CanBindDeclaredJacobianCallback< CrossAlphaJacobian, CrossAlphaTerm, CrossBetaTerm, NonVoidJacobianCallback>); STATIC_CHECK_FALSE(CanBindDeclaredJacobianCallback< CrossAlphaJacobian, CrossAlphaTerm, CrossBetaTerm, RequiresCrossProductDirectionCallback>); STATIC_CHECK_FALSE(CanBindDeclaredJacobianCallback< CrossAlphaJacobian, CrossAlphaTerm, CrossBetaTerm, RequiresCrossProductActionCallback>); STATIC_CHECK_FALSE(CanBindDeclaredJacobianCallback< CrossAlphaJacobian, int, CrossBetaTerm>); } TEST_CASE("Exact Physics Providers Must Cover Every Compiler-Inferred Pair", "[stellar-equilibrium][compiler][physics-provider][contracts]") { using Specification = stellar_runtime_contract_test::RawNestedProtocolConstraint; using Model = RawNestedProtocolModel; using Topology = operators::StellarEquilibriumContributionTopology; STATIC_CHECK(Topology::ResidualEquations::size == 2); STATIC_CHECK(Topology::Derivatives::size == 3); STATIC_CHECK((std::constructible_from)); STATIC_CHECK((HasExactProviderResidual< CompleteExplicitZeroProvider, stellar::equation::OwnConstraint>)); STATIC_CHECK((HasExactProviderResidual< CompleteExplicitZeroProvider, stellar::equation::HydrostaticBalance>)); STATIC_CHECK((HasExactProviderDerivative< CompleteExplicitZeroProvider, stellar::equation::OwnConstraint, stellar::state::SpecificEnthalpy>)); STATIC_CHECK((HasExactProviderDerivative< CompleteExplicitZeroProvider, stellar::equation::HydrostaticBalance, stellar::state::SpecificEnthalpy>)); STATIC_CHECK((HasExactProviderDerivative< CompleteExplicitZeroProvider, stellar::equation::HydrostaticBalance, stellar::state::OwnGeneratedCoordinate>)); STATIC_CHECK((operators::CompleteStellarEquilibriumPhysicsProvider< CompleteExplicitZeroProvider, Specification, Model>)); // This provider has the valid constructor and all three inferred // derivatives. Omitting only the changed physical residual rejects it. STATIC_CHECK((std::constructible_from)); STATIC_CHECK((HasExactProviderResidual< MissingHydrostaticResidualProvider, stellar::equation::OwnConstraint>)); STATIC_CHECK_FALSE((HasExactProviderResidual< MissingHydrostaticResidualProvider, stellar::equation::HydrostaticBalance>)); STATIC_CHECK((HasExactProviderDerivative< MissingHydrostaticResidualProvider, stellar::equation::OwnConstraint, stellar::state::SpecificEnthalpy>)); STATIC_CHECK((HasExactProviderDerivative< MissingHydrostaticResidualProvider, stellar::equation::HydrostaticBalance, stellar::state::SpecificEnthalpy>)); STATIC_CHECK((HasExactProviderDerivative< MissingHydrostaticResidualProvider, stellar::equation::HydrostaticBalance, stellar::state::OwnGeneratedCoordinate>)); STATIC_CHECK_FALSE((operators::CompleteStellarEquilibriumPhysicsProvider< MissingHydrostaticResidualProvider, Specification, Model>)); // This provider has the valid constructor and both inferred residuals. // Omitting only d(hydrostatic)/d(owned coordinate) rejects it. STATIC_CHECK((std::constructible_from< MissingGeneratedControlDerivativeProvider, const Specification &>)); STATIC_CHECK((HasExactProviderResidual< MissingGeneratedControlDerivativeProvider, stellar::equation::OwnConstraint>)); STATIC_CHECK((HasExactProviderResidual< MissingGeneratedControlDerivativeProvider, stellar::equation::HydrostaticBalance>)); STATIC_CHECK((HasExactProviderDerivative< MissingGeneratedControlDerivativeProvider, stellar::equation::OwnConstraint, stellar::state::SpecificEnthalpy>)); STATIC_CHECK((HasExactProviderDerivative< MissingGeneratedControlDerivativeProvider, stellar::equation::HydrostaticBalance, stellar::state::SpecificEnthalpy>)); STATIC_CHECK_FALSE((HasExactProviderDerivative< MissingGeneratedControlDerivativeProvider, stellar::equation::HydrostaticBalance, stellar::state::OwnGeneratedCoordinate>)); STATIC_CHECK_FALSE((operators::CompleteStellarEquilibriumPhysicsProvider< MissingGeneratedControlDerivativeProvider, Specification, Model>)); // Construction alone does not grandfather in the former broad/imperative // callbacks. They provide neither an equation-tagged residual result nor // a derivative-tagged Jacobian result. STATIC_CHECK((std::constructible_from)); STATIC_CHECK_FALSE((HasExactProviderResidual< LegacyBroadEmptyProvider, stellar::equation::OwnConstraint>)); STATIC_CHECK_FALSE((HasExactProviderDerivative< LegacyBroadEmptyProvider, stellar::equation::OwnConstraint, stellar::state::SpecificEnthalpy>)); STATIC_CHECK_FALSE((operators::CompleteStellarEquilibriumPhysicsProvider< LegacyBroadEmptyProvider, Specification, Model>)); } TEST_CASE("Compiler Capability Queries Reject Invalid Declarations Without " "Hard Errors", "[stellar-equilibrium][compiler][sfinae]") { using namespace mean_field; STATIC_CHECK_FALSE( operators::stellarEquilibriumSpecificationCompilationComplete); STATIC_CHECK_FALSE( operators::stellarEquilibriumSpecificationCompilationComplete< MalformedDeclaration>); STATIC_CHECK_FALSE( operators::StellarEquilibriumSystemCompilable); STATIC_CHECK_FALSE(HasCompiledStellarEquilibriumSystem); STATIC_CHECK(models::ModelSpecification); // A valid declaration is not a claim that the numerical compiler knows how // to map every name it contains. STATIC_CHECK(UnmappedPhysicsModel::hasCompleteEquilibriumDeclaration); STATIC_CHECK_FALSE( operators::stellarEquilibriumSpecificationCompilationComplete< UnmappedPhysicsDependency>); STATIC_CHECK_FALSE( operators::StellarEquilibriumSystemCompilable); STATIC_CHECK_FALSE( HasCompiledStellarEquilibriumSystem); STATIC_CHECK(models::ModelSpecification); STATIC_CHECK_FALSE( operators::stellarEquilibriumSpecificationCompilationComplete< UnmappedPhysicsEffect>); STATIC_CHECK_FALSE(operators::StellarEquilibriumSystemCompilable< UnmappedPhysicsEffectModel>); STATIC_CHECK_FALSE( HasCompiledStellarEquilibriumSystem); STATIC_CHECK_FALSE(operators::StellarEquilibriumSystemCompilable); STATIC_CHECK_FALSE(HasCompiledStellarEquilibriumSystem); STATIC_CHECK(operators::StellarEquilibriumBackendSpecificationList< models::ModelTypeList>); STATIC_CHECK(operators::StellarEquilibriumBackendSpecificationList< models::ModelTypeList<>>); STATIC_CHECK_FALSE(operators::StellarEquilibriumBackendSpecificationList< models::ModelTypeList>); STATIC_CHECK_FALSE(operators::StellarEquilibriumBackendSpecificationList< models::ModelTypeList>); STATIC_CHECK_FALSE( operators::StellarEquilibriumBackendSpecificationList); STATIC_CHECK_FALSE(operators::stellarEquilibriumBackendRuntimeAuthorized< int, int>); STATIC_CHECK(operators::stellarEquilibriumBackendRuntimeAuthorized< eos::Polytrope, BaseModel>); STATIC_CHECK(operators::stellarEquilibriumBackendRuntimeAuthorized< models::FixedTotalMass, BaseModel>); STATIC_CHECK(operators::StellarEquilibriumCoreRuntime< stellar_runtime_contract_test:: RegisteredWithoutMakeEquationOfState>::registered); STATIC_CHECK(operators::StellarEquilibriumSystemCompilable< RegisteredWithoutMakeModel>); STATIC_CHECK_FALSE(operators::hasStellarEquilibriumCoreRuntime< RegisteredWithoutMakeModel>); STATIC_CHECK(operators::PreparedStellarEquilibriumPhysicalCore< stellar_runtime_contract_test::AlternatePhysicalCore>); STATIC_CHECK(operators::hasStellarEquilibriumCoreRuntime< AlternateCoreModel>); STATIC_CHECK((std::same_as< operators::StellarEquilibriumPhysicalCoreType< AlternateCoreModel>, stellar_runtime_contract_test::AlternatePhysicalCore>)); STATIC_CHECK(operators::hasCompleteStellarEquilibriumRuntime< AlternateCoreModel>); STATIC_CHECK(operators::stellarEquilibriumBackendRuntimeAuthorized< stellar_runtime_contract_test::AlternateCoreEquationOfState, AlternateCoreModel>); STATIC_CHECK(operators::stellarEquilibriumBackendRuntimeAuthorized< surface::Isobaric, AlternateCoreModel>); STATIC_CHECK(operators::stellarEquilibriumBackendRuntimeAuthorized< models::FixedTotalMass, AlternateCoreModel>); STATIC_CHECK( HasPreparedVariadicStellarEquilibriumOperator); // Core support and constraint support are separate contracts. This tiny // core supports the common outer root, but does not advertise the physical // facilities required by FixedAngularMomentum. STATIC_CHECK(operators::hasStellarEquilibriumCoreRuntime< AlternateCoreAngularMomentumModel>); STATIC_CHECK(operators::stellarEquilibriumBackendRuntimeAuthorized< models::FixedAngularMomentum, AlternateCoreAngularMomentumModel>); STATIC_CHECK_FALSE(operators::hasCompleteStellarEquilibriumRuntime< AlternateCoreAngularMomentumModel>); STATIC_CHECK_FALSE(HasPreparedVariadicStellarEquilibriumOperator< AlternateCoreAngularMomentumModel>); // The pack fold also rejects ambiguous physical-control ownership. Both // contributions are independently executable, but exactly one runtime may // generate the rotation used by the shared physical core. STATIC_CHECK_FALSE( operators::StellarEquilibriumRuntimeContribution< stellar_runtime_contract_test::SecondRotationController>::registered); STATIC_CHECK(operators::StellarEquilibriumPhysicsAvailableFor< stellar_runtime_contract_test::SecondRotationController, TwoRotationProvidersModel>); STATIC_CHECK(operators::StellarEquilibriumSystemCompilable< TwoRotationProvidersModel>); STATIC_CHECK(operators::hasStellarEquilibriumCoreRuntime< TwoRotationProvidersModel>); STATIC_CHECK(operators::hasCompleteStellarEquilibriumRuntime< TwoRotationProvidersModel>); STATIC_CHECK(HasPreparedVariadicStellarEquilibriumOperator< TwoRotationProvidersModel>); STATIC_CHECK_FALSE(equilibrium::StellarEquilibriumModel< TwoRotationProvidersModel>); STATIC_CHECK(operators::stellarEquilibriumRotationProviderCount< TwoRotationProvidersModel> == 2); using AmbiguousRotationRoot = operators::PreparedVariadicStellarEquilibriumOperator< TwoRotationProvidersModel>; STATIC_CHECK_FALSE(std::constructible_from< AmbiguousRotationRoot, fem::FEM &, const mapping::DomainMapper &, std::shared_ptr, operators::PressureSurfaceConstraintView, deformation::PreparedDomainDeformationRuntime>); // Report storage is part of the real runtime protocol: preparation creates // the complete report tuple and assigns each per-specification result into // it. Capability queries must reject both failures without reaching a hard // error inside PreparedVariadicStellarEquilibriumOperator::Prepare(). STATIC_CHECK(operators::StellarEquilibriumSystemCompilable< NonDefaultReportModel>); STATIC_CHECK_FALSE(operators::StellarEquilibriumPhysicsAvailableFor< stellar_runtime_contract_test::NonDefaultReportConstraint, NonDefaultReportModel>); STATIC_CHECK_FALSE(operators::hasCompleteStellarEquilibriumRuntime< NonDefaultReportModel>); STATIC_CHECK_FALSE(equilibrium::StellarEquilibriumModel< NonDefaultReportModel>); STATIC_CHECK(operators::StellarEquilibriumSystemCompilable< NonAssignableReportModel>); STATIC_CHECK_FALSE(operators::StellarEquilibriumPhysicsAvailableFor< stellar_runtime_contract_test:: NonAssignableReportConstraint, NonAssignableReportModel>); STATIC_CHECK_FALSE(operators::hasCompleteStellarEquilibriumRuntime< NonAssignableReportModel>); STATIC_CHECK_FALSE(equilibrium::StellarEquilibriumModel< NonAssignableReportModel>); // Reports are deliberately opaque to the framework. Default construction // and assignment are sufficient for tuple storage; no DidAnyWork member is // required to keep the residual correct. STATIC_CHECK(operators::StellarEquilibriumSystemCompilable< OpaqueReportModel>); STATIC_CHECK(operators::StellarEquilibriumPhysicsAvailableFor< stellar_runtime_contract_test::OpaqueReportConstraint, OpaqueReportModel>); STATIC_CHECK(operators::hasCompleteStellarEquilibriumRuntime< OpaqueReportModel>); STATIC_CHECK(equilibrium::StellarEquilibriumModel); // A nested declaration is the restricted physics-author path. Merely // implementing the former raw FEM/model/core/dependency protocol must not // recover the privileged backend access reserved for explicit registry // specializations. STATIC_CHECK(operators::StellarEquilibriumSystemCompilable< RawNestedProtocolModel>); STATIC_CHECK_FALSE(std::constructible_from< stellar_runtime_contract_test:: PreparedRawNestedProtocolConstraint< RawNestedProtocolModel>, const stellar_runtime_contract_test:: RawNestedProtocolConstraint &>); STATIC_CHECK_FALSE(operators::StellarEquilibriumPhysicsAvailableFor< stellar_runtime_contract_test::RawNestedProtocolConstraint, RawNestedProtocolModel>); STATIC_CHECK_FALSE(operators::hasCompleteStellarEquilibriumRuntime< RawNestedProtocolModel>); STATIC_CHECK_FALSE(equilibrium::StellarEquilibriumModel< RawNestedProtocolModel>); // Even a structurally complete aggregate runtime cannot select itself for // an existing core. Symbolic compilation and core availability remain // independently true, isolating authorization as the failed rung. STATIC_CHECK(operators::StellarEquilibriumSystemCompilable< UnauthorizedAggregateModel>); STATIC_CHECK(operators::hasStellarEquilibriumCoreRuntime< UnauthorizedAggregateModel>); STATIC_CHECK(operators::StellarEquilibriumRuntimeContribution< stellar_runtime_contract_test:: UnauthorizedAggregateConstraint>::registered); STATIC_CHECK_FALSE(operators::stellarEquilibriumBackendRuntimeAuthorized< stellar_runtime_contract_test:: UnauthorizedAggregateConstraint, UnauthorizedAggregateModel>); STATIC_CHECK_FALSE(operators::StellarEquilibriumPhysicsAvailableFor< stellar_runtime_contract_test:: UnauthorizedAggregateConstraint, UnauthorizedAggregateModel>); STATIC_CHECK_FALSE(operators::hasCompleteStellarEquilibriumRuntime< UnauthorizedAggregateModel>); STATIC_CHECK_FALSE(equilibrium::StellarEquilibriumModel< UnauthorizedAggregateModel>); // A raw registry specialization cannot grant itself privileged access to // the built-in core and cannot shadow a valid restricted nested package. STATIC_CHECK(operators::StellarEquilibriumRuntimeContribution< stellar_runtime_contract_test:: AmbiguousRuntimeRegistrationConstraint>::registered); STATIC_CHECK_FALSE(operators::stellarEquilibriumBackendRuntimeAuthorized< stellar_runtime_contract_test:: AmbiguousRuntimeRegistrationConstraint, AmbiguousRuntimeRegistrationModel>); STATIC_CHECK(operators::StellarEquilibriumPhysicsAvailableFor< stellar_runtime_contract_test:: AmbiguousRuntimeRegistrationConstraint, AmbiguousRuntimeRegistrationModel>); STATIC_CHECK(operators::hasCompleteStellarEquilibriumRuntime< AmbiguousRuntimeRegistrationModel>); STATIC_CHECK(equilibrium::StellarEquilibriumModel< AmbiguousRuntimeRegistrationModel>); // A core owner can deliberately authorize an aggregate backend candidate. // If that exact model then also supplies nested physics, the two valid // providers are genuinely ambiguous and are rejected. STATIC_CHECK(operators::stellarEquilibriumBackendRuntimeAuthorized< stellar_runtime_contract_test:: AmbiguousRuntimeRegistrationConstraint, AuthorizedAmbiguousRuntimeRegistrationModel>); STATIC_CHECK_FALSE(operators::StellarEquilibriumPhysicsAvailableFor< stellar_runtime_contract_test:: AmbiguousRuntimeRegistrationConstraint, AuthorizedAmbiguousRuntimeRegistrationModel>); STATIC_CHECK_FALSE(operators::hasCompleteStellarEquilibriumRuntime< AuthorizedAmbiguousRuntimeRegistrationModel>); STATIC_CHECK_FALSE(equilibrium::StellarEquilibriumModel< AuthorizedAmbiguousRuntimeRegistrationModel>); // A registration bit and a plausible core type are insufficient: the // factory must return ownership of the advertised concrete core. STATIC_CHECK_FALSE( operators::hasStellarEquilibriumCoreRuntime); STATIC_CHECK_FALSE(operators::hasCompleteStellarEquilibriumRuntime< WrongOwnerModel>); STATIC_CHECK(operators::StellarEquilibriumRuntimeContribution< stellar_runtime_contract_test:: IncompleteSurfaceRuntime>::registered); STATIC_CHECK_FALSE(operators::stellarEquilibriumBackendRuntimeAuthorized< stellar_runtime_contract_test::IncompleteSurfaceRuntime, IncompleteSurfaceRuntimeModel>); STATIC_CHECK(operators::StellarEquilibriumSystemCompilable< IncompleteSurfaceRuntimeModel>); STATIC_CHECK(operators::hasStellarEquilibriumCoreRuntime< IncompleteSurfaceRuntimeModel>); STATIC_CHECK_FALSE(operators::hasCompleteStellarEquilibriumRuntime< IncompleteSurfaceRuntimeModel>); STATIC_CHECK_FALSE(equilibrium::hasStellarEquilibriumSurfaceCompilation< IncompleteSurfaceRuntimeModel>); STATIC_CHECK_FALSE(equilibrium::StellarEquilibriumModel< IncompleteSurfaceRuntimeModel>); STATIC_CHECK_FALSE( operators::hasCompatibleStellarEquilibriumPhysicalRoot); STATIC_CHECK_FALSE( HasPreparedVariadicStellarEquilibriumOperator); STATIC_CHECK_FALSE(operators::CompilableRootManifestFor< CentralDensityModel, utils::blocks::surface_deformed_stellar_equilibrium_form>); STATIC_CHECK_FALSE(operators::CompilableRootManifestFor< BaseModel, CarrierlessManifestForm>); STATIC_CHECK_FALSE(operators::CompilableRootManifestFor< UnsupportedCentralDensityModel, operators::CompiledStellarEquilibriumForm< UnsupportedCentralDensityModel>>); // This declaration is internally well formed, but its dependency is not // supplied by the final model. Completeness is therefore contextual. STATIC_CHECK(operators::stellarEquilibriumSpecificationCompilationComplete< OrphanEndpoint>); STATIC_CHECK_FALSE( operators::StellarEquilibriumSystemCompilable); STATIC_CHECK_FALSE(HasCompiledStellarEquilibriumSystem); } TEST_CASE("Direct Variadic Root Construction Requires Shared Model Ownership", "[stellar-equilibrium][runtime][lifetime][type-contract]") { using namespace mean_field; using Operator = operators::PreparedVariadicStellarEquilibriumOperator; STATIC_CHECK_FALSE(std::constructible_from< Operator, fem::FEM &, const mapping::DomainMapper &, const BaseModel &, operators::PressureSurfaceConstraintView, deformation::PreparedDomainDeformationRuntime>); STATIC_CHECK(std::constructible_from< Operator, fem::FEM &, const mapping::DomainMapper &, std::shared_ptr, operators::PressureSurfaceConstraintView, deformation::PreparedDomainDeformationRuntime>); } TEST_CASE("Physical Riesz Runtime Capability Follows The Selected Core", "[normalization][stellar-equilibrium][type-contract]") { using namespace mean_field; using AlternateForm = operators::CompiledStellarEquilibriumForm; using AlternateSpecifications = AlternateCoreModel::SpecificationTypes; STATIC_CHECK(normalization::PhysicalRieszStellarEquilibriumCore< operators::PreparedStellarEquilibriumOperator>); STATIC_CHECK_FALSE(normalization::PhysicalRieszStellarEquilibriumCore< stellar_runtime_contract_test::AlternatePhysicalCore>); STATIC_CHECK(normalization::PhysicalRieszStellarEquilibriumCore< stellar_runtime_contract_test::PhysicalRieszCapableCore>); STATIC_CHECK(normalization::StellarNormalizationRuntimeAvailableFor< normalization::Unnormalized, AlternateForm, stellar_runtime_contract_test::AlternatePhysicalCore, AlternateSpecifications>); STATIC_CHECK_FALSE(normalization::StellarNormalizationRuntimeAvailableFor< normalization::PhysicalRieszDiagonal<>, AlternateForm, stellar_runtime_contract_test::AlternatePhysicalCore, AlternateSpecifications>); STATIC_CHECK(normalization::StellarNormalizationRuntimeAvailableFor< normalization::PhysicalRieszDiagonal<>, AlternateForm, stellar_runtime_contract_test::PhysicalRieszCapableCore, AlternateSpecifications>); STATIC_CHECK_FALSE(normalization::StellarNormalizationRuntimeAvailableFor< int, int, int, int>); // Runtime normalization is selected by the discretization type. A lean // alternate core remains fully usable without scaling, while the Physical // Riesz pairing is rejected at the public capability boundary rather than // failing in the normalized operator's constructor body. STATIC_CHECK(equilibrium::StellarEquilibriumModel); STATIC_CHECK(equilibrium::StellarEquilibriumModelDiscretizationCompatible< AlternateCoreModel, equilibrium::StellarDiscretization>); STATIC_CHECK_FALSE(equilibrium::StellarEquilibriumModelDiscretizationCompatible< AlternateCoreModel, PhysicalRieszDiscretization>); STATIC_CHECK_FALSE(HasStellarEquilibriumProblem< AlternateCoreModel, PhysicalRieszDiscretization>); STATIC_CHECK_FALSE(CanDiscretizeStellarModel< AlternateCoreModel, PhysicalRieszDiscretization>); STATIC_CHECK(normalization::NormalizableStellarEquilibriumProblem< BaseProblem>); STATIC_CHECK(normalization::PhysicalRieszStellarEquilibriumProblem< BasePhysicalRieszProblem>); STATIC_CHECK(normalization::NormalizableStellarEquilibriumProblem< BasePhysicalRieszProblem>); STATIC_CHECK(normalization::NormalizableStellarEquilibriumProblem< AlternateCoreProblem>); STATIC_CHECK_FALSE(normalization::PhysicalRieszStellarEquilibriumProblem); STATIC_CHECK_FALSE(normalization::NormalizableStellarEquilibriumProblem); STATIC_CHECK(HasNormalizedStellarEquilibriumOperator); STATIC_CHECK(HasNormalizedStellarEquilibriumOperator< BasePhysicalRieszProblem>); STATIC_CHECK(HasNormalizedStellarEquilibriumOperator); STATIC_CHECK(CanMakeNormalizedStellarEquilibriumOperator); STATIC_CHECK(CanMakeNormalizedStellarEquilibriumOperator< AlternateCoreProblem>); STATIC_CHECK_FALSE(CanMakeNormalizedStellarEquilibriumOperator); } TEST_CASE("Model And Discretization Compatibility Rejects Missing Riesz " "Metadata Without Instantiating A Problem", "[normalization][stellar-equilibrium][type-contract][sfinae]") { using namespace mean_field; using MissingRieszForm = operators::CompiledStellarEquilibriumForm; using MissingConstraint = stellar_runtime_contract_test::MissingRieszScalarConstraint; // Every non-normalization rung is complete for this model. STATIC_CHECK(equilibrium::StellarEquilibriumModel); STATIC_CHECK(operators::StellarEquilibriumSystemCompilable< MissingRieszModel>); STATIC_CHECK(operators::hasCompleteStellarEquilibriumRuntime< MissingRieszModel>); STATIC_CHECK(operators::CompilableRootManifestFor); STATIC_CHECK(models::CompleteGeneratedManifestFor); // Identity normalization covers the generated pair without physical scale // metadata. Physical Riesz correctly requires that missing declaration. STATIC_CHECK_FALSE(models::CompleteGeneratedNormalizationFor< MissingConstraint>); STATIC_CHECK_FALSE(normalization::CompleteGeneratedPhysicalRieszNormalizationFor< MissingConstraint>); STATIC_CHECK_FALSE( normalization::CompleteGeneratedPhysicalRieszRuntimeNormalizationFor< MissingConstraint>); STATIC_CHECK( normalization::CompleteGeneratedPhysicalRieszRuntimeNormalizationFor< models::FixedTotalMass>); STATIC_CHECK(normalization::CompilableNormalizationFor< normalization::Unnormalized, MissingRieszForm>); STATIC_CHECK_FALSE(normalization::CompilableNormalizationFor< normalization::PhysicalRieszDiagonal<>, MissingRieszForm>); STATIC_CHECK_FALSE(normalization::CompleteStellarNormalizationFor< MissingRieszModel, MissingRieszForm>); STATIC_CHECK(equilibrium::StellarEquilibriumModelDiscretizationCompatible< MissingRieszModel, equilibrium::StellarDiscretization>); STATIC_CHECK_FALSE( equilibrium::StellarEquilibriumModelDiscretizationCompatible< MissingRieszModel, PhysicalRieszDiscretization>); STATIC_CHECK_FALSE( equilibrium::StellarEquilibriumModelDiscretizationCompatible); STATIC_CHECK(HasStellarEquilibriumProblem< MissingRieszModel, equilibrium::StellarDiscretization>); STATIC_CHECK_FALSE(HasStellarEquilibriumProblem< MissingRieszModel, PhysicalRieszDiscretization>); STATIC_CHECK_FALSE(HasStellarEquilibriumProblem); STATIC_CHECK(CanDiscretizeStellarModel< MissingRieszModel, equilibrium::StellarDiscretization>); STATIC_CHECK_FALSE(CanDiscretizeStellarModel< MissingRieszModel, PhysicalRieszDiscretization>); STATIC_CHECK(equilibrium::DiscretizedStellarEquilibriumProblem< MissingRieszUnnormalizedProblem>); STATIC_CHECK(normalization::NormalizableStellarEquilibriumProblem< MissingRieszUnnormalizedProblem>); } TEST_CASE("Restricted Equilibrium Physics Automatically Supplies The Default " "Constraint Border", "[preconditioning][stellar-equilibrium][type-contract][sfinae]") { using namespace mean_field; // The ordinary nested provider is the single source of numerical formulas. // Border-incident edges are projected from it automatically, while the // custom pure-structure edge is explicitly proven to be StructuralZero. STATIC_CHECK(equilibrium::StellarEquilibriumModel); STATIC_CHECK(operators::hasCompleteStellarEquilibriumRuntime< MissingRieszModel>); STATIC_CHECK(equilibrium::DiscretizedStellarEquilibriumProblem< MissingRieszUnnormalizedProblem>); STATIC_CHECK(preconditioning::CompleteSpecificationBorderActionsFor< MissingRieszUnnormalizedProblem>); STATIC_CHECK( preconditioning::DefaultStellarPreconditionerAvailableFor< MissingRieszUnnormalizedProblem>); STATIC_CHECK(CanMakeDefaultStellarPreconditioner< MissingRieszUnnormalizedProblem>); }