#include #include #include #include #include import mean_field; import test_helpers; namespace { struct NotAModelSpecification final { }; using PolytropicMassSpecifications = mean_field::models:: SpecificationSet; using PermutedPolytropicMassSpecifications = mean_field::models:: SpecificationSet; using CentralDensityPolytropicMassSpecifications = mean_field::models::SpecificationSet< mean_field::models::FixedCentralDensity, mean_field::surface::Isobaric, mean_field::eos::Polytrope, mean_field::models::FixedTotalMass>; using PolytropicMassModel = mean_field::model::StellarModel; using PermutedPolytropicMassModel = mean_field::model::StellarModel; using CentralDensityPolytropicMassModel = mean_field::model::StellarModel; } // namespace TEST_CASE( "Model Specifications Form Canonical Compile-Time Model Types", tags::model_specification_type_contract ) { STATIC_CHECK(mean_field::models::ModelSpecification); STATIC_CHECK(mean_field::models::ModelSpecification); STATIC_CHECK(mean_field::models::ModelSpecification); STATIC_CHECK(mean_field::models::ModelSpecification); STATIC_CHECK_FALSE(mean_field::models::ModelSpecification); STATIC_CHECK(mean_field::models::ResolvedModelSpecification); STATIC_CHECK(mean_field::models::ResolvedModelSpecification); STATIC_CHECK(mean_field::models::ResolvedModelSpecification); STATIC_CHECK(mean_field::models::ResolvedModelSpecification); STATIC_CHECK( mean_field::models::ValidModelSpecificationPack< mean_field::eos::Polytrope, mean_field::models::FixedTotalMass, mean_field::surface::Isobaric> ); STATIC_CHECK_FALSE( mean_field::models::ValidModelSpecificationPack< mean_field::eos::Polytrope, mean_field::models::FixedTotalMass, mean_field::models::FixedTotalMass, mean_field::surface::Isobaric> ); STATIC_CHECK_FALSE( mean_field::models::ValidModelSpecificationPack< mean_field::models::FixedTotalMass, mean_field::surface::Isobaric> ); STATIC_CHECK(std::same_as); STATIC_CHECK_FALSE(std::same_as); STATIC_CHECK(mean_field::model::StellarModelType); STATIC_CHECK(mean_field::model::StellarModelType); } TEST_CASE( "Invariant And Phase Specifications Generate Balanced Residual And Value Types", tags::model_specification_type_contract ) { using MassSignature = PolytropicMassModel::OperatorSignature; STATIC_CHECK(MassSignature::generatedValueArity == 1); STATIC_CHECK(MassSignature::generatedResidualArity == 1); STATIC_CHECK(MassSignature::symbolicallySquare); STATIC_CHECK( mean_field::models::modelTypeListContains< mean_field::models::MultiplierFor, typename MassSignature::GeneratedValues> ); STATIC_CHECK( mean_field::models::modelTypeListContains< mean_field::models::ResidualFor, typename MassSignature::GeneratedResiduals> ); using CentralDensitySignature = CentralDensityPolytropicMassModel::OperatorSignature; STATIC_CHECK(CentralDensitySignature::generatedValueArity == 2); STATIC_CHECK(CentralDensitySignature::generatedResidualArity == 2); STATIC_CHECK(CentralDensitySignature::symbolicallySquare); STATIC_CHECK( mean_field::models::modelTypeListContains< mean_field::models::BorderFor, typename CentralDensitySignature::GeneratedValues> ); STATIC_CHECK( mean_field::models::modelTypeListContains< mean_field::models::ResidualFor, typename CentralDensitySignature::GeneratedResiduals> ); } TEST_CASE( "Fixed Total Mass Compiles Its Generated Multiplier And Canonical Residual Row", tags::model_specification_type_contract ) { using namespace mean_field; using Request = models::FixedMassLayoutRequest; using Form = utils::blocks::barotropic_equilibrium_form; STATIC_CHECK(models::ConstraintLayoutRequestType); STATIC_CHECK(models::CompiledConstraint); STATIC_CHECK(std::same_as); STATIC_CHECK(std::same_as>); STATIC_CHECK(std::same_as>); STATIC_CHECK( std::same_as> ); STATIC_CHECK( std::same_as> ); STATIC_CHECK(std::same_as); STATIC_CHECK(Request::rowInjection == models::ConstraintRowInjection::append); STATIC_CHECK(Request::valueArity == 1); STATIC_CHECK(Request::residualArity == 1); STATIC_CHECK(Request::valueBlock
().index == Form::value_block_count - 1); STATIC_CHECK(Request::residualBlock().index == Form::residual_block_count - 1); const models::CompiledFixedMass compiled = models::compileConstraint(models::FixedTotalMass{dimensions::MassValue{1.75}}); CHECK(compiled.targetMass() == dimensions::MassValue{1.75}); CHECK(compiled.specification().targetMass() == dimensions::MassValue{1.75}); } TEST_CASE( "Model Specification Descriptors Preserve Roles And Generated Arity", tags::model_specification_type_contract ) { constexpr auto polytrope = mean_field::models::specificationDescriptor(); constexpr auto surface = mean_field::models::specificationDescriptor(); constexpr auto mass = mean_field::models::specificationDescriptor(); constexpr auto centralDensity = mean_field::models::specificationDescriptor(); STATIC_CHECK(polytrope.name == "Polytrope"); STATIC_CHECK(polytrope.role == mean_field::models::SpecificationRole::constitutive_law); STATIC_CHECK(polytrope.generatedValueArity == 0); STATIC_CHECK(polytrope.generatedResidualArity == 0); STATIC_CHECK(surface.name == "IsobaricSurface"); STATIC_CHECK(surface.role == mean_field::models::SpecificationRole::boundary_condition); STATIC_CHECK(mass.name == "FixedTotalMass"); STATIC_CHECK(mass.role == mean_field::models::SpecificationRole::invariant); STATIC_CHECK(mass.generatedValueArity == 1); STATIC_CHECK(mass.generatedResidualArity == 1); STATIC_CHECK(centralDensity.name == "FixedCentralDensity"); STATIC_CHECK(centralDensity.role == mean_field::models::SpecificationRole::phase_condition); STATIC_CHECK(centralDensity.generatedValueArity == 1); STATIC_CHECK(centralDensity.generatedResidualArity == 1); } TEST_CASE( "Invariant And Phase Specification Values Reject Invalid Targets", tags::model_specification_type_contract ) { const mean_field::models::FixedTotalMass mass{mean_field::dimensions::MassValue{1.25}}; const mean_field::models::FixedCentralDensity centralDensity{mean_field::eos::DensityValue{2.5}}; CHECK(mass.targetMass() == mean_field::dimensions::MassValue{1.25}); CHECK(centralDensity.targetDensity() == mean_field::eos::DensityValue{2.5}); CHECK_THROWS_AS(mean_field::models::FixedTotalMass{mean_field::dimensions::MassValue{0.0}}, std::invalid_argument); CHECK_THROWS_AS(mean_field::models::FixedTotalMass{mean_field::dimensions::MassValue{-1.0}}, std::invalid_argument); CHECK_THROWS_AS( mean_field::models::FixedTotalMass{mean_field::dimensions::MassValue{std::numeric_limits::infinity()}}, std::invalid_argument ); CHECK_THROWS_AS(mean_field::models::FixedCentralDensity{mean_field::eos::DensityValue{0.0}}, std::invalid_argument); CHECK_THROWS_AS( mean_field::models::FixedCentralDensity{mean_field::eos::DensityValue{-1.0}}, std::invalid_argument ); CHECK_THROWS_AS( mean_field::models::FixedCentralDensity{mean_field::eos::DensityValue{std::numeric_limits::infinity()}}, std::invalid_argument ); }