feat(field-support): added field support system, mid migration

currently the barotope and the pressure force operator are migrated to the new support system
This commit is contained in:
2026-08-23 10:13:53 -04:00
parent dc912fd15e
commit 0f3ca8050b
137 changed files with 29975 additions and 16389 deletions

View File

@@ -24,8 +24,7 @@ namespace prepared_hydrostatic_analytic_solve_test_utils {
public:
EnthalpyJacobianOperator(
const int enthalpySize,
const mean_field::operators::PreparedHydrostaticEquilibriumOperator
&preparedOperator
const mean_field::operators::PreparedHydrostaticEquilibriumOperator &preparedOperator
)
: mfem::Operator(enthalpySize),
m_preparedOperator(preparedOperator) {
@@ -39,13 +38,10 @@ namespace prepared_hydrostatic_analytic_solve_test_utils {
}
private:
const mean_field::operators::PreparedHydrostaticEquilibriumOperator
&m_preparedOperator;
const mean_field::operators::PreparedHydrostaticEquilibriumOperator &m_preparedOperator;
};
mean_field::operators::context::hydrostatic::
HydrostaticEquilibriumDependencies
make_dependencies() {
mean_field::operators::context::hydrostatic::HydrostaticEquilibriumDependencies make_dependencies() {
return {
.discretization = {.identity = 701, .revision = 2},
.enthalpy = {.identity = 709, .revision = 3},
@@ -56,8 +52,7 @@ namespace prepared_hydrostatic_analytic_solve_test_utils {
};
}
mean_field::operators::context::hydrostatic::HydrostaticEquilibriumStateView
make_state(
mean_field::operators::context::hydrostatic::HydrostaticEquilibriumStateView make_state(
const mfem::Vector &enthalpy,
const mfem::Vector &gravityPotential,
const mfem::Vector &displacement
@@ -84,11 +79,9 @@ namespace prepared_hydrostatic_analytic_solve_test_utils {
return vector;
}
mean_field::physics::RigidRotation
make_rotation(const AnalyticCase &analyticCase) {
mean_field::physics::RigidRotation make_rotation(const AnalyticCase &analyticCase) {
return mean_field::physics::RigidRotation(
make_vector(analyticCase.angularVelocity),
make_vector(analyticCase.rotationCenter)
make_vector(analyticCase.angularVelocity), make_vector(analyticCase.rotationCenter)
);
}
@@ -101,9 +94,7 @@ namespace prepared_hydrostatic_analytic_solve_test_utils {
for (int component = 0; component < 3; ++component) {
physicalPosition(component) =
analyticCase
.deformationScale[static_cast<std::size_t>(component)] *
referencePosition(component);
analyticCase.deformationScale[static_cast<std::size_t>(component)] * referencePosition(component);
}
}
@@ -111,11 +102,9 @@ namespace prepared_hydrostatic_analytic_solve_test_utils {
double normalizedRadiusSquared = 0.0;
for (int component = 0; component < 3; ++component) {
const double normalizedCoordinate =
referencePosition(component) / mean_field::utils::RADIUS;
const double normalizedCoordinate = referencePosition(component) / mean_field::utils::RADIUS;
normalizedRadiusSquared +=
normalizedCoordinate * normalizedCoordinate;
normalizedRadiusSquared += normalizedCoordinate * normalizedCoordinate;
}
return enthalpyAmplitude * std::max(0.0, 1.0 - normalizedRadiusSquared);
@@ -137,20 +126,16 @@ namespace prepared_hydrostatic_analytic_solve_test_utils {
*
* analytically.
*/
return bernoulliConstant + rotation.potential(physicalPosition) -
exact_enthalpy_value(referencePosition);
return bernoulliConstant + rotation.potential(physicalPosition) - exact_enthalpy_value(referencePosition);
}
mfem::Array<int>
make_stellar_element_marker(const mean_field::fem::FEM &f) {
mfem::Array<int> make_stellar_element_marker(const mean_field::fem::FEM &f) {
mfem::Array<int> stellarElementMarker(f.mesh->GetNE());
const int vacuumAttribute =
f.domainMapperStateless->GetVacuumElementAttribute();
const int vacuumAttribute = f.domainMapperStateless->GetVacuumElementAttribute();
for (int elementId = 0; elementId < f.mesh->GetNE(); ++elementId) {
stellarElementMarker[elementId] =
f.mesh->GetAttribute(elementId) != vacuumAttribute;
stellarElementMarker[elementId] = f.mesh->GetAttribute(elementId) != vacuumAttribute;
}
return stellarElementMarker;
@@ -159,9 +144,8 @@ namespace prepared_hydrostatic_analytic_solve_test_utils {
TEST_CASE(
"Prepared Hydrostatic Operator Solves Analytic Bernoulli Equilibria",
tags::barotrope &tags::hydro &tags::prepared &tags::integration
&tags::solver &tags::convergence &tags::accuracy
&tags::analytic_comparison
tags::barotrope &tags::hydro &tags::prepared &tags::integration &tags::solver &tags::convergence &tags::accuracy
&tags::analytic_comparison
) {
using prepared_hydrostatic_analytic_solve_test_utils::AnalyticCase;
@@ -191,70 +175,53 @@ TEST_CASE(
.rotationCenter = {0.031, -0.024, 0.018}}}
};
auto args = test_utils::setup_args();
auto args = test_utils::setup_args();
mean_field::fem::FEM f =
mean_field::fem::setup_fem(args.mesh_file, args, 0);
mean_field::fem::FEM f = mean_field::fem::setup_fem(args.mesh_file, args, 0);
const MPI_Comm communicator = f.mesh->GetComm();
const mfem::Array<int> stellarElementMarker =
prepared_hydrostatic_analytic_solve_test_utils::
make_stellar_element_marker(f);
prepared_hydrostatic_analytic_solve_test_utils::make_stellar_element_marker(f);
for (const AnalyticCase &analyticCase : analyticCases) {
DYNAMIC_SECTION(analyticCase.name) {
const double deformationDeterminant =
analyticCase.deformationScale[0] *
analyticCase.deformationScale[1] *
analyticCase.deformationScale[2];
analyticCase.deformationScale[0] * analyticCase.deformationScale[1] * analyticCase.deformationScale[2];
REQUIRE(std::abs(deformationDeterminant - 1.0) < 2.0e-14);
const mean_field::physics::RigidRotation rotation =
prepared_hydrostatic_analytic_solve_test_utils::make_rotation(
analyticCase
);
prepared_hydrostatic_analytic_solve_test_utils::make_rotation(analyticCase);
auto displacementFunction = [&analyticCase](
const mfem::Vector
&referencePosition,
mfem::Vector &displacementValue
) {
mfem::Vector physicalPosition;
auto displacementFunction =
[&analyticCase](const mfem::Vector &referencePosition, mfem::Vector &displacementValue) {
mfem::Vector physicalPosition;
prepared_hydrostatic_analytic_solve_test_utils::map_to_physical(
referencePosition, analyticCase, physicalPosition
);
displacementValue.SetSize(3);
displacementValue = physicalPosition;
displacementValue -= referencePosition;
};
auto potentialFunction = [&analyticCase, &rotation](
const mfem::Vector &referencePosition
) {
return prepared_hydrostatic_analytic_solve_test_utils::
exact_potential_value(
referencePosition, analyticCase, rotation
prepared_hydrostatic_analytic_solve_test_utils::map_to_physical(
referencePosition, analyticCase, physicalPosition
);
displacementValue.SetSize(3);
displacementValue = physicalPosition;
displacementValue -= referencePosition;
};
auto potentialFunction = [&analyticCase, &rotation](const mfem::Vector &referencePosition) {
return prepared_hydrostatic_analytic_solve_test_utils::exact_potential_value(
referencePosition, analyticCase, rotation
);
};
auto enthalpyFunction = [](const mfem::Vector &referencePosition) {
return prepared_hydrostatic_analytic_solve_test_utils::
exact_enthalpy_value(referencePosition);
return prepared_hydrostatic_analytic_solve_test_utils::exact_enthalpy_value(referencePosition);
};
mfem::VectorFunctionCoefficient displacementCoefficient(
f.mesh->Dimension(), displacementFunction
);
mfem::VectorFunctionCoefficient displacementCoefficient(f.mesh->Dimension(), displacementFunction);
mfem::FunctionCoefficient potentialCoefficient(potentialFunction);
mfem::FunctionCoefficient exactEnthalpyCoefficient(
enthalpyFunction
);
mfem::FunctionCoefficient exactEnthalpyCoefficient(enthalpyFunction);
/*
* Project the prescribed geometry and potential.
@@ -284,21 +251,17 @@ TEST_CASE(
mfem::ParGridFunction zeroEnthalpyField(f.enthalpyFes.get());
zeroEnthalpyField = 0.0;
zeroEnthalpyField = 0.0;
const double exactEnthalpyNorm = zeroEnthalpyField.ComputeL2Error(
exactEnthalpyCoefficient, nullptr, &stellarElementMarker
);
const double exactEnthalpyNorm =
zeroEnthalpyField.ComputeL2Error(exactEnthalpyCoefficient, nullptr, &stellarElementMarker);
const double projectionError =
projectedEnthalpyField.ComputeL2Error(
exactEnthalpyCoefficient, nullptr, &stellarElementMarker
);
projectedEnthalpyField.ComputeL2Error(exactEnthalpyCoefficient, nullptr, &stellarElementMarker);
REQUIRE(exactEnthalpyNorm > 0.0);
const double relativeProjectionError =
projectionError / exactEnthalpyNorm;
const double relativeProjectionError = projectionError / exactEnthalpyNorm;
/*
* Begin deliberately far from equilibrium.
@@ -307,16 +270,12 @@ TEST_CASE(
enthalpy = 0.0;
auto dependencies = prepared_hydrostatic_analytic_solve_test_utils::
make_dependencies();
auto dependencies = prepared_hydrostatic_analytic_solve_test_utils::make_dependencies();
mean_field::operators::PreparedHydrostaticEquilibriumOperator
preparedOperator(f, *f.domainMapperStateless);
mean_field::operators::PreparedHydrostaticEquilibriumOperator preparedOperator(f, *f.domainMapperStateless);
const auto initialReport = preparedOperator.Prepare(
prepared_hydrostatic_analytic_solve_test_utils::make_state(
enthalpy, gravityPotential, displacement
),
prepared_hydrostatic_analytic_solve_test_utils::make_state(enthalpy, gravityPotential, displacement),
dependencies, rotation
);
@@ -327,10 +286,7 @@ TEST_CASE(
preparedOperator.BuildResidual(initialResidual);
const double initialResidualNorm =
gravity_prepared_test_utils::global_norm(
initialResidual, communicator
);
const double initialResidualNorm = gravity_prepared_test_utils::global_norm(initialResidual, communicator);
REQUIRE(initialResidualNorm > 1.0e-12);
@@ -344,10 +300,9 @@ TEST_CASE(
* rotation, and displacement makes this a well-defined
* enthalpy solve.
*/
prepared_hydrostatic_analytic_solve_test_utils::
EnthalpyJacobianOperator enthalpyJacobian(
f.enthalpyFes->GetTrueVSize(), preparedOperator
);
prepared_hydrostatic_analytic_solve_test_utils::EnthalpyJacobianOperator enthalpyJacobian(
f.enthalpyFes->GetTrueVSize(), preparedOperator
);
mfem::Vector rightHandSide(initialResidual);
rightHandSide *= -1.0;
@@ -375,9 +330,7 @@ TEST_CASE(
INFO("Linear solver converged = " << linearSolver.GetConverged());
INFO(
"Linear solver iterations = " << linearSolver.GetNumIterations()
);
INFO("Linear solver iterations = " << linearSolver.GetNumIterations());
INFO("Linear solver final norm = " << linearSolver.GetFinalNorm());
@@ -392,9 +345,7 @@ TEST_CASE(
++dependencies.enthalpy.revision;
const auto solvedReport = preparedOperator.Prepare(
prepared_hydrostatic_analytic_solve_test_utils::make_state(
enthalpy, gravityPotential, displacement
),
prepared_hydrostatic_analytic_solve_test_utils::make_state(enthalpy, gravityPotential, displacement),
dependencies, rotation
);
@@ -410,13 +361,9 @@ TEST_CASE(
preparedOperator.BuildResidual(solvedResidual);
const double solvedResidualNorm =
gravity_prepared_test_utils::global_norm(
solvedResidual, communicator
);
const double solvedResidualNorm = gravity_prepared_test_utils::global_norm(solvedResidual, communicator);
const double residualReduction =
solvedResidualNorm / initialResidualNorm;
const double residualReduction = solvedResidualNorm / initialResidualNorm;
/*
* Compare the solved field with the continuum analytic
@@ -431,12 +378,9 @@ TEST_CASE(
solvedEnthalpyField.SetFromTrueDofs(enthalpy);
const double solvedAnalyticError =
solvedEnthalpyField.ComputeL2Error(
exactEnthalpyCoefficient, nullptr, &stellarElementMarker
);
solvedEnthalpyField.ComputeL2Error(exactEnthalpyCoefficient, nullptr, &stellarElementMarker);
const double relativeSolvedAnalyticError =
solvedAnalyticError / exactEnthalpyNorm;
const double relativeSolvedAnalyticError = solvedAnalyticError / exactEnthalpyNorm;
INFO("Deformation determinant = " << deformationDeterminant);
@@ -446,15 +390,9 @@ TEST_CASE(
INFO("Weak residual reduction = " << residualReduction);
INFO(
"Relative analytic projection floor = "
<< relativeProjectionError
);
INFO("Relative analytic projection floor = " << relativeProjectionError);
INFO(
"Relative solved analytic L2 error = "
<< relativeSolvedAnalyticError
);
INFO("Relative solved analytic L2 error = " << relativeSolvedAnalyticError);
/*
* The discrete Bernoulli equation must be solved essentially
@@ -469,10 +407,7 @@ TEST_CASE(
* also contains potential-projection and mapped-space
* compatibility errors.
*/
CHECK(
relativeSolvedAnalyticError <
std::max(5.0 * relativeProjectionError, 1.25e-4)
);
CHECK(relativeSolvedAnalyticError < std::max(5.0 * relativeProjectionError, 1.25e-4));
/*
* Record that the analytic error remains within one order of