feat(surface): surface deformation prescriptions

restricted the unknown state vector to surface deformation and implemented one prescription, NodalRadialSurface, while the full volumetric displacment field is reconstructed analytically from that. This reduced the number of degrees of freedom in the system by a factor of 80 while also removing many null vectors from the system.
This commit is contained in:
2026-09-01 11:50:13 -04:00
parent 0a7f18c5c7
commit 85500fef3b
40 changed files with 8924 additions and 1164 deletions

View File

@@ -45,10 +45,8 @@ namespace {
);
m_stellarOperator.GetGravityOperator().ApplyGravityUnknowns(
gravityGradientDirection,
gravityPotentialDirection,
m_stellarOperator.GetGravityContext().GetGeometryContext(),
gravityAction
gravityGradientDirection, gravityPotentialDirection,
m_stellarOperator.GetGravityContext().GetGeometryContext(), gravityAction
);
}
@@ -113,23 +111,11 @@ namespace {
);
}
void apply_centering_rows(
const mean_field::operators::PreparedStellarEquilibriumOperator &stellarOperator,
const mfem::Vector &direction,
mfem::Vector &action
) {
const auto &layout = stellarOperator.GetLayout();
const mfem::Vector displacementDirection =
experiment::null_space::const_value_view(direction, layout, experiment::null_space::displacementValue);
mfem::Vector displacementAction =
experiment::null_space::residual_view(action, layout, experiment::null_space::displacementResidual);
stellarOperator.GetCenteringConstraintOperator().ApplyJacobianRows(displacementDirection, displacementAction);
}
} // namespace
TEST_CASE(
"Gravity-Completed Rigid Motion Responses Of The Stellar Equilibrium Jacobian",
"[null_space][gravity_completed]"
"Gravity-Completed Reduced Surface Mode Responses Of The Stellar Equilibrium Jacobian",
"[null_space][surface_modes][gravity_completed]"
) {
mean_field::utils::Args args = test_utils::setup_args();
args.p.rtol = 1.0e-11;
@@ -141,7 +127,7 @@ TEST_CASE(
int rank = 0;
MPI_Comm_rank(communicator, &rank);
const auto modes = experiment::null_space::make_rigid_modes(fixture);
const auto modes = experiment::null_space::make_surface_modes(fixture);
constexpr std::array<double, 2> rotationFractions{0.0, 0.5};
const int totalCases = static_cast<int>(rotationFractions.size() * modes.size());
int completedCases = 0;
@@ -163,16 +149,16 @@ TEST_CASE(
gravitySolver.SetMaxIter(2000);
gravitySolver.SetPrintLevel(1);
for (const experiment::null_space::RigidMode &mode : modes) {
for (const experiment::null_space::SurfaceMode &mode : modes) {
experiment::null_space::report_progress(
communicator, "solving the gravity completion for " + mode.name + " at rotation fraction " +
std::to_string(rotationFraction) + " (" + std::to_string(completedCases + 1) + "/" +
std::to_string(totalCases) + ")"
);
const mfem::Vector displacementOnlyAction = fixture.unpinned_jacobian_action(mode.direction);
const mfem::Vector surfaceOnlyAction = fixture.jacobian_action(mode.direction);
mfem::Vector gravityRightHandSide =
gravity_residual_blocks(displacementOnlyAction, fixture.stellar_operator().GetLayout());
gravity_residual_blocks(surfaceOnlyAction, fixture.stellar_operator().GetLayout());
gravityRightHandSide *= -1.0;
mfem::Vector gravityCompletion(gravityUnknownJacobian.Width());
@@ -201,25 +187,14 @@ TEST_CASE(
gravityUnknownJacobian.gravity_gradient_size()
);
const mfem::Vector completedUnpinnedAction = fixture.unpinned_jacobian_action(completedDirection);
mfem::Vector completedConstrainedAction(completedUnpinnedAction);
apply_centering_rows(fixture.stellar_operator(), completedDirection, completedConstrainedAction);
mfem::Vector centeringContribution(completedConstrainedAction);
centeringContribution -= completedUnpinnedAction;
const mfem::Vector completedAction = fixture.jacobian_action(completedDirection);
std::map<std::string, double> metrics{
{"displacement_only_input_norm", experiment::null_space::global_norm(mode.direction, communicator)},
{"surface_only_input_norm", experiment::null_space::global_norm(mode.direction, communicator)},
{"gravity_completion_norm", experiment::null_space::global_norm(gravityCompletion, communicator)},
{"completed_input_norm", experiment::null_space::global_norm(completedDirection, communicator)},
{"displacement_only_action_norm",
experiment::null_space::global_norm(displacementOnlyAction, communicator)},
{"gravity_completed_unpinned_action_norm",
experiment::null_space::global_norm(completedUnpinnedAction, communicator)},
{"gravity_completed_constrained_action_norm",
experiment::null_space::global_norm(completedConstrainedAction, communicator)},
{"centering_contribution_norm",
experiment::null_space::global_norm(centeringContribution, communicator)},
{"surface_only_action_norm", experiment::null_space::global_norm(surfaceOnlyAction, communicator)},
{"gravity_completed_action_norm", experiment::null_space::global_norm(completedAction, communicator)},
{"gravity_solve_rhs_norm", gravityRightHandSideNorm},
{"gravity_solve_residual_norm", gravitySolveResidualNorm},
{"gravity_solve_relative_residual", gravitySolveRelativeResidual},
@@ -228,29 +203,22 @@ TEST_CASE(
};
add_block_metrics(
metrics, "displacement_only_",
metrics, "surface_only_",
experiment::null_space::residual_block_norms(
displacementOnlyAction, fixture.stellar_operator().GetLayout(), communicator
surfaceOnlyAction, fixture.stellar_operator().GetLayout(), communicator
)
);
add_block_metrics(
metrics, "gravity_completed_unpinned_",
metrics, "gravity_completed_",
experiment::null_space::residual_block_norms(
completedUnpinnedAction, fixture.stellar_operator().GetLayout(), communicator
)
);
add_block_metrics(
metrics, "gravity_completed_constrained_",
experiment::null_space::residual_block_norms(
completedConstrainedAction, fixture.stellar_operator().GetLayout(), communicator
completedAction, fixture.stellar_operator().GetLayout(), communicator
)
);
if (rank == 0) {
experiment::record_experiment_result(
"gravity_completed_stellar_rigid_motion_null_space", mode.name,
{{"mode_kind",
mode.kind == experiment::null_space::RigidModeKind::translation ? "translation" : "rotation"},
"gravity_completed_reduced_surface_modes", mode.name,
{{"mode_kind", experiment::null_space::surface_mode_kind_name(mode.kind)},
{"axis", std::to_string(mode.axis)},
{"rotation_fraction_of_keplerian", std::to_string(rotationFraction)},
{"mesh_file", test_utils::setup_args().mesh_file},
@@ -262,12 +230,12 @@ TEST_CASE(
++completedCases;
experiment::null_space::report_progress(
communicator, "completed " + std::to_string(completedCases) + "/" + std::to_string(totalCases) +
" gravity-completed rigid-mode cases"
" gravity-completed reduced surface-mode cases"
);
}
}
experiment::null_space::report_progress(
communicator, "gravity-completed rigid-motion probe complete; writing CSV output"
communicator, "gravity-completed reduced surface-mode probe complete; writing CSV output"
);
}