perf(jacobian-action): major updates to jacobian action application by removing redudant quadrature work. ~5x increase in speed
This commit is contained in:
196
tests/models/model_specifications.cpp
Normal file
196
tests/models/model_specifications.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
#include <concepts>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
import mean_field;
|
||||
import test_helpers;
|
||||
|
||||
namespace {
|
||||
struct NotAModelSpecification final { };
|
||||
|
||||
using PolytropicMassSpecifications = mean_field::models::
|
||||
SpecificationSet<mean_field::eos::Polytrope, mean_field::models::FixedTotalMass, mean_field::surface::Isobaric>;
|
||||
|
||||
using PermutedPolytropicMassSpecifications = mean_field::models::
|
||||
SpecificationSet<mean_field::surface::Isobaric, mean_field::models::FixedTotalMass, mean_field::eos::Polytrope>;
|
||||
|
||||
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<PolytropicMassSpecifications>;
|
||||
using PermutedPolytropicMassModel = mean_field::model::StellarModel<PermutedPolytropicMassSpecifications>;
|
||||
using CentralDensityPolytropicMassModel =
|
||||
mean_field::model::StellarModel<CentralDensityPolytropicMassSpecifications>;
|
||||
} // namespace
|
||||
|
||||
TEST_CASE(
|
||||
"Model Specifications Form Canonical Compile-Time Model Types",
|
||||
tags::model_specification_type_contract
|
||||
) {
|
||||
STATIC_CHECK(mean_field::models::ModelSpecification<mean_field::eos::Polytrope>);
|
||||
STATIC_CHECK(mean_field::models::ModelSpecification<mean_field::surface::ConstantPressureSurface>);
|
||||
STATIC_CHECK(mean_field::models::ModelSpecification<mean_field::models::FixedTotalMass>);
|
||||
STATIC_CHECK(mean_field::models::ModelSpecification<mean_field::models::FixedCentralDensity>);
|
||||
STATIC_CHECK_FALSE(mean_field::models::ModelSpecification<NotAModelSpecification>);
|
||||
STATIC_CHECK(mean_field::models::ResolvedModelSpecification<mean_field::eos::Polytrope>);
|
||||
STATIC_CHECK(mean_field::models::ResolvedModelSpecification<mean_field::surface::ConstantPressureSurface>);
|
||||
STATIC_CHECK(mean_field::models::ResolvedModelSpecification<mean_field::models::FixedTotalMass>);
|
||||
STATIC_CHECK(mean_field::models::ResolvedModelSpecification<mean_field::models::FixedCentralDensity>);
|
||||
|
||||
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<PolytropicMassModel, PermutedPolytropicMassModel>);
|
||||
STATIC_CHECK_FALSE(std::same_as<PolytropicMassModel, CentralDensityPolytropicMassModel>);
|
||||
STATIC_CHECK(mean_field::model::StellarModelType<PolytropicMassModel>);
|
||||
STATIC_CHECK(mean_field::model::StellarModelType<CentralDensityPolytropicMassModel>);
|
||||
}
|
||||
|
||||
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<mean_field::models::FixedTotalMass>,
|
||||
typename MassSignature::GeneratedValues>
|
||||
);
|
||||
|
||||
STATIC_CHECK(
|
||||
mean_field::models::modelTypeListContains<
|
||||
mean_field::models::ResidualFor<mean_field::models::FixedTotalMass>,
|
||||
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<mean_field::models::FixedCentralDensity>,
|
||||
typename CentralDensitySignature::GeneratedValues>
|
||||
);
|
||||
|
||||
STATIC_CHECK(
|
||||
mean_field::models::modelTypeListContains<
|
||||
mean_field::models::ResidualFor<mean_field::models::FixedCentralDensity>,
|
||||
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<Request>);
|
||||
STATIC_CHECK(models::CompiledConstraint<models::CompiledFixedMass>);
|
||||
STATIC_CHECK(std::same_as<typename Request::SpecificationType, models::FixedTotalMass>);
|
||||
STATIC_CHECK(std::same_as<typename Request::GeneratedValueType, models::MultiplierFor<models::FixedTotalMass>>);
|
||||
STATIC_CHECK(std::same_as<typename Request::GeneratedResidualType, models::ResidualFor<models::FixedTotalMass>>);
|
||||
STATIC_CHECK(
|
||||
std::same_as<typename Request::ValueBlockType::GeneratedType, models::MultiplierFor<models::FixedTotalMass>>
|
||||
);
|
||||
STATIC_CHECK(
|
||||
std::same_as<typename Request::ResidualBlockType::GeneratedType, models::ResidualFor<models::FixedTotalMass>>
|
||||
);
|
||||
STATIC_CHECK(std::same_as<typename models::CompiledFixedMass::MultiplierField, field::BarotropicConstant>);
|
||||
STATIC_CHECK(Request::rowInjection == models::ConstraintRowInjection::append);
|
||||
STATIC_CHECK(Request::valueArity == 1);
|
||||
STATIC_CHECK(Request::residualArity == 1);
|
||||
STATIC_CHECK(Request::valueBlock<Form>().index == Form::value_block_count - 1);
|
||||
STATIC_CHECK(Request::residualBlock<Form>().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<mean_field::eos::Polytrope>();
|
||||
constexpr auto surface =
|
||||
mean_field::models::specificationDescriptor<mean_field::surface::ConstantPressureSurface>();
|
||||
constexpr auto mass = mean_field::models::specificationDescriptor<mean_field::models::FixedTotalMass>();
|
||||
constexpr auto centralDensity =
|
||||
mean_field::models::specificationDescriptor<mean_field::models::FixedCentralDensity>();
|
||||
|
||||
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<double>::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<double>::infinity()}},
|
||||
std::invalid_argument
|
||||
);
|
||||
}
|
||||
108
tests/models/typed_stellar_model.cpp
Normal file
108
tests/models/typed_stellar_model.cpp
Normal file
@@ -0,0 +1,108 @@
|
||||
#include <concepts>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
|
||||
#include <catch2/catch_test_macros.hpp>
|
||||
|
||||
import mean_field;
|
||||
import test_helpers;
|
||||
|
||||
namespace {
|
||||
using CanonicalModel = mean_field::model::StellarModel<mean_field::models::SpecificationSet<
|
||||
mean_field::eos::Polytrope,
|
||||
mean_field::surface::Isobaric,
|
||||
mean_field::integral::FixedTotalMass,
|
||||
mean_field::constraint::FixedCentralDensity>>;
|
||||
|
||||
using BaseModel = mean_field::model::StellarModel<mean_field::models::SpecificationSet<
|
||||
mean_field::eos::Polytrope,
|
||||
mean_field::surface::Isobaric,
|
||||
mean_field::integral::FixedTotalMass>>;
|
||||
} // namespace
|
||||
|
||||
TEST_CASE(
|
||||
"Stellar Model Is Deduced From Validated Physical Specifications",
|
||||
tags::stellar_model_specification_api
|
||||
) {
|
||||
using namespace mean_field;
|
||||
|
||||
const auto stellarModel = model::StellarModel(
|
||||
eos::Polytrope({.n = 3.0, .K = 0.25}), surface::Isobaric({.Psurf = dimensions::PressureValue{0.0}}),
|
||||
integral::FixedTotalMass({.Mtotal = dimensions::MassValue{1.5}}),
|
||||
constraint::FixedCentralDensity({.RhoC = dimensions::DensityValue{2.0}})
|
||||
);
|
||||
|
||||
STATIC_CHECK(std::same_as<std::remove_cvref_t<decltype(stellarModel)>, CanonicalModel>);
|
||||
STATIC_CHECK(model::StellarModelType<decltype(stellarModel)>);
|
||||
STATIC_CHECK(models::SpecifiedModelType<decltype(stellarModel)>);
|
||||
STATIC_CHECK(CanonicalModel::specificationCount == 4);
|
||||
STATIC_CHECK(CanonicalModel::symbolicallySquare);
|
||||
STATIC_CHECK(CanonicalModel::hasCompleteEquilibriumCompiler);
|
||||
STATIC_CHECK(CanonicalModel::compilationClass == models::EquilibriumSystemCompilation::complete_equilibrium_system);
|
||||
|
||||
CHECK(stellarModel.specification<eos::Polytrope>().polytropic_index() == 3.0);
|
||||
CHECK(stellarModel.specification<eos::Polytrope>().polytropic_constant() == 0.25);
|
||||
CHECK(stellarModel.specification<surface::Isobaric>().targetPressure() == dimensions::PressureValue{0.0});
|
||||
CHECK(stellarModel.specification<integral::FixedTotalMass>().targetMass() == dimensions::MassValue{1.5});
|
||||
CHECK(
|
||||
stellarModel.specification<constraint::FixedCentralDensity>().targetDensity() == dimensions::DensityValue{2.0}
|
||||
);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Stellar Model Deduction Canonicalizes Unordered Specifications",
|
||||
tags::stellar_model_specification_api
|
||||
) {
|
||||
using namespace mean_field;
|
||||
|
||||
const auto canonical = model::StellarModel(
|
||||
eos::Polytrope({.n = 3.0, .K = 0.25}), surface::Isobaric({.Psurf = dimensions::PressureValue{0.0}}),
|
||||
integral::FixedTotalMass({.Mtotal = dimensions::MassValue{1.0}}),
|
||||
constraint::FixedCentralDensity({.RhoC = dimensions::DensityValue{1.0}})
|
||||
);
|
||||
const auto reordered = model::StellarModel(
|
||||
constraint::FixedCentralDensity({.RhoC = dimensions::DensityValue{1.0}}),
|
||||
integral::FixedTotalMass({.Mtotal = dimensions::MassValue{1.0}}),
|
||||
surface::Isobaric({.Psurf = dimensions::PressureValue{0.0}}), eos::Polytrope({.n = 3.0, .K = 0.25})
|
||||
);
|
||||
const auto base = model::StellarModel(
|
||||
integral::FixedTotalMass({.Mtotal = dimensions::MassValue{1.0}}), eos::Polytrope({.n = 3.0, .K = 0.25}),
|
||||
surface::Isobaric({.Psurf = dimensions::PressureValue{0.0}})
|
||||
);
|
||||
|
||||
STATIC_CHECK(std::same_as<decltype(canonical), decltype(reordered)>);
|
||||
STATIC_CHECK(std::same_as<std::remove_cvref_t<decltype(base)>, BaseModel>);
|
||||
STATIC_CHECK_FALSE(std::same_as<decltype(canonical), decltype(base)>);
|
||||
STATIC_CHECK_FALSE(BaseModel::template containsSpecification<constraint::FixedCentralDensity>);
|
||||
STATIC_CHECK(CanonicalModel::template containsSpecification<constraint::FixedCentralDensity>);
|
||||
|
||||
const auto descriptors = CanonicalModel::runtimeSpecificationDescriptors();
|
||||
REQUIRE(descriptors.size() == 4);
|
||||
CHECK(descriptors[0].specification.name == "Polytrope");
|
||||
CHECK(descriptors[1].specification.name == "IsobaricSurface");
|
||||
CHECK(descriptors[2].specification.name == "FixedTotalMass");
|
||||
CHECK(descriptors[3].specification.name == "FixedCentralDensity");
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Stellar Specification Parameter Constructors Preserve Validation",
|
||||
tags::stellar_model_specification_api
|
||||
) {
|
||||
using namespace mean_field;
|
||||
|
||||
STATIC_CHECK(std::constructible_from<eos::Polytrope, eos::Polytrope::Parameters>);
|
||||
STATIC_CHECK(std::constructible_from<surface::Isobaric, surface::Isobaric::Parameters>);
|
||||
STATIC_CHECK(std::constructible_from<integral::FixedTotalMass, integral::FixedTotalMass::Parameters>);
|
||||
STATIC_CHECK(std::constructible_from<constraint::FixedCentralDensity, constraint::FixedCentralDensity::Parameters>);
|
||||
STATIC_CHECK(std::same_as<decltype(integral::FixedTotalMass::Parameters::Mtotal), dimensions::MassValue>);
|
||||
STATIC_CHECK(std::same_as<decltype(constraint::FixedCentralDensity::Parameters::RhoC), dimensions::DensityValue>);
|
||||
STATIC_CHECK(std::same_as<decltype(surface::Isobaric::Parameters::Psurf), dimensions::PressureValue>);
|
||||
STATIC_CHECK_FALSE(std::constructible_from<integral::FixedTotalMass, double>);
|
||||
|
||||
CHECK_THROWS_AS(eos::Polytrope({.n = 0.5, .K = 1.0}), std::invalid_argument);
|
||||
CHECK_THROWS_AS(eos::Polytrope({.n = 3.0, .K = std::numeric_limits<double>::infinity()}), std::invalid_argument);
|
||||
CHECK_THROWS_AS(surface::Isobaric({.Psurf = dimensions::PressureValue{-1.0}}), std::invalid_argument);
|
||||
CHECK_THROWS_AS(integral::FixedTotalMass({.Mtotal = dimensions::MassValue{0.0}}), std::invalid_argument);
|
||||
CHECK_THROWS_AS(constraint::FixedCentralDensity({.RhoC = dimensions::DensityValue{0.0}}), std::invalid_argument);
|
||||
}
|
||||
Reference in New Issue
Block a user