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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user