Cover both density mass and EOS source in closure quadrature

This commit is contained in:
2026-09-19 10:47:58 -04:00
parent d6554cae6b
commit dd955abca5
8 changed files with 98 additions and 14 deletions

View File

@@ -393,11 +393,11 @@ TEST_CASE(
REQUIRE(densitySource.base_order.has_value());
/*
* L2_2 value order 2
* Registered density value order
* + geometry order 3
* + dynamic coefficient order 4.
*/
CHECK(*densitySource.base_order == 9);
CHECK(*densitySource.base_order == field::Density::Scalar::familyOrder + 3 + 4);
CHECK(densitySource.term == quadrature::Term::density_projection);
@@ -775,4 +775,4 @@ TEST_CASE(
for (int index = 0; index < support.activeTrueDofMarker.Size(); ++index) {
CHECK(support.activeTrueDofMarker[index] == 1);
}
}
}

View File

@@ -839,6 +839,38 @@ namespace prepared_barotropic_closure_test_utils {
make_state_view(baseDensity, baseEnthalpy, baseDisplacement), make_dependencies()
);
// Agreement with the stateless kernel alone cannot expose a
// shared quadrature mistake. Check the actual prepared rule
// against both form orders, allowing MFEM's odd-order aliases.
int checkedRules = 0;
preparedOperator.VisitMappedGeometryRules([&](const int element, const mfem::IntegrationRule &rule) {
const auto &transformation = *f.mesh->GetElementTransformation(element);
const int extraOrder = static_cast<int>(std::ceil(
(condition.polytropicIndex - 1.0) * field::Enthalpy::Scalar::familyOrder
));
const auto sourceQuery = field::Field<field::Enthalpy>::make_query<
field::Enthalpy::Form::EosClosureSource>(
mean_field::quadrature::QuadratureRole::discretization, transformation.OrderW(),
std::array<int, 1>{extraOrder}, mean_field::utils::DOMAINS::STELLAR,
mean_field::quadrature::MappingKind::general
);
const auto massQuery = field::Field<field::Density>::make_query<
field::Density::Form::EosClosureMass>(
mean_field::quadrature::QuadratureRole::discretization, transformation.OrderW(), {},
mean_field::utils::DOMAINS::STELLAR, mean_field::quadrature::MappingKind::general
);
const auto sourceResolution =
f.quadratureFactory->get(sourceQuery, transformation.GetGeometryType());
const auto massResolution =
f.quadratureFactory->get(massQuery, transformation.GetGeometryType());
INFO("Prepared closure element = " << element);
INFO("Actual quadrature exactness = " << rule.GetOrder());
CHECK(rule.GetOrder() >= sourceResolution.resolution.order);
CHECK(rule.GetOrder() >= massResolution.resolution.order);
++checkedRules;
});
CHECK(checkedRules > 0);
mfem::Vector preparedResidual;
mfem::Vector preparedAction;
preparedOperator.BuildResidual(preparedResidual);

View File

@@ -545,14 +545,18 @@ TEST_CASE(
STATIC_CHECK(hdiv_query.base_order.has_value());
STATIC_CHECK(*hdiv_query.base_order == 8);
STATIC_CHECK(*divergence_query.base_order == 6);
STATIC_CHECK(*source_query.base_order == 6);
STATIC_CHECK(*center_of_mass_query.base_order == 5);
STATIC_CHECK(*eos_closure_query.base_order == 13);
STATIC_CHECK(
*source_query.base_order == field::Density::Scalar::familyOrder + field::Gravity::Potential::familyOrder + 2
);
STATIC_CHECK(*center_of_mass_query.base_order == field::Density::Scalar::familyOrder + 1 + 2);
STATIC_CHECK(
*eos_closure_query.base_order == field::Enthalpy::Scalar::familyOrder + field::Density::Scalar::familyOrder + 6 + 2
);
STATIC_CHECK(*equilibrium_gravity_query.base_order == 7);
STATIC_CHECK(*rotation_query.base_order == 7);
STATIC_CHECK(*isobaric_surface_query.base_order == 8);
STATIC_CHECK(*mesh_extension_query.base_order == 6);
STATIC_CHECK(*mass_normalization_query.base_order == 4);
STATIC_CHECK(*mass_normalization_query.base_order == field::Density::Scalar::familyOrder + 2);
STATIC_CHECK(*pressure_integral_query.base_order == 14);
STATIC_CHECK(*equilibrium_constant_query.base_order == 5);