feat(preconditioner): major work on preconditioner system

first preconditioner MVP
This commit is contained in:
2026-09-04 07:54:10 -04:00
parent 25510008dd
commit 71423d543f
61 changed files with 15920 additions and 422 deletions

View File

@@ -1,5 +1,6 @@
module;
#include "mfem.hpp"
#include "profile.h"
#include <array>
#include <cmath>
@@ -11,6 +12,8 @@ namespace mean_field::physics {
const mfem::GridFunction &rho,
const mfem::Vector &com
) {
MEAN_FIELD_PROFILE_SCOPE_WARMUP("analysis::quadrupole", 0);
const int dim = fem.mesh->Dimension();
mfem::DenseMatrix local_Q(dim, dim);
local_Q = 0.0;
@@ -18,6 +21,9 @@ namespace mean_field::physics {
mapping::GridFunctionMappingEvaluator mapping_evaluator(
*fem.domainMapperStateless, *fem.displacement, *fem.compactificationCoordinate
);
std::uint64_t mapping_evaluations = 0;
mapping::VolumeMappingContext mapping_context;
mfem::Vector x_prime(dim);
for (int i = 0; i < fem.mesh->GetNE(); ++i) {
if (!DomainSchema::template attribute_belongs_to<utils::domain::Stellar>(fem.mesh->GetAttribute(i)))
@@ -36,19 +42,18 @@ namespace mean_field::physics {
const mfem::IntegrationPoint &ip = ir.IntPoint(j);
trans->SetIntPoint(&ip);
mapping::VolumeMappingContext mapping_context;
MFEM_VERIFY(
mapping_evaluator.EvaluateVolume(*trans, ip, mapping_context) == mapping::MappingStatus::valid,
"Quadrupole integration encountered an invalid mapping."
);
++mapping_evaluations;
const double weight = mapping_context.quadrature.weight;
const double rho_val = rho.GetValue(i, ip);
const mfem::Vector &phys_point = mapping_context.mapping.physical_position;
mfem::Vector x_prime(dim);
double r_sq = 0.0;
double r_sq = 0.0;
for (int d = 0; d < dim; ++d) {
x_prime(d) = phys_point(d) - com(d);
@@ -65,6 +70,8 @@ namespace mean_field::physics {
}
}
MEAN_FIELD_PROFILE_COUNT("analysis::quadrupole mapping evaluations", mapping_evaluations);
mfem::DenseMatrix global_Q(dim, dim);
MPI_Allreduce(local_Q.GetData(), global_Q.GetData(), dim * dim, MPI_DOUBLE, MPI_SUM, fem.mesh->GetComm());
@@ -106,6 +113,8 @@ namespace mean_field::physics {
const mfem::GridFunction &rho,
const mfem::GridFunction &displacement
) {
MEAN_FIELD_PROFILE_SCOPE_WARMUP("physics::solve_gravity_field", 0);
MFEM_VERIFY(f.mesh != nullptr, "Gravity initialization requires a parallel mesh.");
MFEM_VERIFY(f.densityFes != nullptr, "Gravity initialization requires the density finite-element space.");
MFEM_VERIFY(
@@ -150,15 +159,23 @@ namespace mean_field::physics {
constexpr auto gravity_poisson_residual_block =
utils::blocks::get_residual_block<form>(utils::blocks::gravity_field.poisson_term);
using DomainSchema = utils::domain::CoreEnvelopeVacuumDomainSchema;
const field::FieldDofGridFunctionAdapter density_adapter =
field::make_field_dof_grid_function_adapter<field::Density, DomainSchema>(*f.densityFes);
const field::FieldDofGridFunctionAdapter displacement_adapter =
field::make_field_dof_grid_function_adapter<field::Displacement, DomainSchema>(*f.displacementFes);
const field::FieldDofGridFunctionAdapter gravity_flux_adapter =
field::make_field_dof_grid_function_adapter<field::Gravity, DomainSchema>(*f.gravityFluxFes);
const field::FieldDofGridFunctionAdapter gravity_potential_adapter =
field::make_field_dof_grid_function_adapter<field::Gravity, DomainSchema>(*f.gravityPotentialFes);
using DomainSchema = utils::domain::CoreEnvelopeVacuumDomainSchema;
const field::FieldDofGridFunctionAdapter density_adapter = MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: density map", 0,
field::make_field_dof_grid_function_adapter<field::Density, DomainSchema>(*f.densityFes)
);
const field::FieldDofGridFunctionAdapter displacement_adapter = MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: displacement map", 0,
field::make_field_dof_grid_function_adapter<field::Displacement, DomainSchema>(*f.displacementFes)
);
const field::FieldDofGridFunctionAdapter gravity_flux_adapter = MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: flux map", 0,
field::make_field_dof_grid_function_adapter<field::Gravity, DomainSchema>(*f.gravityFluxFes)
);
const field::FieldDofGridFunctionAdapter gravity_potential_adapter = MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: potential map", 0,
field::make_field_dof_grid_function_adapter<field::Gravity, DomainSchema>(*f.gravityPotentialFes)
);
const field::FieldDofMap &density_map = density_adapter.dof_map();
const field::FieldDofMap &displacement_map = displacement_adapter.dof_map();
@@ -174,34 +191,56 @@ namespace mean_field::physics {
gravity_flux_map.reduced_size(), gravity_potential_map.reduced_size()
};
const utils::blocks::form_layout<form> layout(value_sizes, residual_sizes);
const mfem::Vector density = density_adapter.gather(rho);
const mfem::Vector reduced_displacement = displacement_adapter.gather(displacement);
operators::context::gravity_field::GravityFieldLinearizationContext linearization_context(
f, *f.domainMapperStateless
const utils::blocks::form_layout<form> layout = MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: block layout", 0, utils::blocks::form_layout<form>(value_sizes, residual_sizes)
);
operators::GravityFieldJacobianOperator gravity_jacobian(
f, *f.domainMapperStateless, linearization_context, layout.value_offsets(), layout.residual_offsets()
const mfem::Vector density =
MEAN_FIELD_PROFILE_EVALUATE_WARMUP("gravity solve: gather density", 0, density_adapter.gather(rho));
const mfem::Vector reduced_displacement = MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: gather displacement", 0, displacement_adapter.gather(displacement)
);
operators::GravityFieldOperator gravity_operator(
f, *f.domainMapperStateless, linearization_context, layout.value_offsets(), gravity_jacobian
operators::context::gravity_field::GravityFieldLinearizationContext linearization_context =
MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: linearization context", 0,
operators::context::gravity_field::GravityFieldLinearizationContext(f, *f.domainMapperStateless)
);
operators::GravityFieldJacobianOperator gravity_jacobian = MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: jacobian operator", 0,
operators::GravityFieldJacobianOperator(
f, *f.domainMapperStateless, linearization_context, layout.value_offsets(), layout.residual_offsets()
)
);
operators::context::gravity_field::GravityFieldGeometryContext reduced_geometry_context(
f, *f.domainMapperStateless
operators::GravityFieldOperator gravity_operator = MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: nonlinear operator", 0,
operators::GravityFieldOperator(
f, *f.domainMapperStateless, linearization_context, layout.value_offsets(), gravity_jacobian
)
);
operators::ReducedGravityFieldOperator reduced_operator(
gravity_operator, reduced_geometry_context, reduced_displacement
operators::context::gravity_field::GravityFieldGeometryContext reduced_geometry_context =
MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: reduced geometry context", 0,
operators::context::gravity_field::GravityFieldGeometryContext(f, *f.domainMapperStateless)
);
operators::ReducedGravityFieldOperator reduced_operator = MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: reduced operator", 0,
operators::ReducedGravityFieldOperator(gravity_operator, reduced_geometry_context, reduced_displacement)
);
operators::ReducedGravityFieldPreconditioner reduced_preconditioner = MEAN_FIELD_PROFILE_EVALUATE_WARMUP(
"gravity solve: preconditioner construction", 0,
operators::ReducedGravityFieldPreconditioner(f, reduced_geometry_context)
);
operators::ReducedGravityFieldPreconditioner reduced_preconditioner(f, reduced_geometry_context);
mfem::Vector right_hand_side;
reduced_operator.BuildRightHandSide(density, right_hand_side);
MEAN_FIELD_PROFILE_CALL_WARMUP(
"gravity solve: right-hand side", 0, reduced_operator.BuildRightHandSide(density, right_hand_side)
);
MFEM_VERIFY(
right_hand_side.Size() == reduced_operator.Height(),
@@ -219,14 +258,18 @@ namespace mean_field::physics {
minres.SetMaxIter(options.maximumIterations);
// minres.SetPrintLevel(args.verbose ? 1 : 0);
minres.SetPrintLevel(0);
minres.Mult(right_hand_side, gravity_state);
MEAN_FIELD_PROFILE_CALL_WARMUP("gravity solve: MINRES", 0, minres.Mult(right_hand_side, gravity_state));
MEAN_FIELD_PROFILE_COUNT("gravity solve: MINRES iterations", minres.GetNumIterations());
MFEM_VERIFY(minres.GetConverged(), "The reduced gravity solve failed to converge.");
GravitySolution solution(f);
gravity_flux_adapter.scatter(gravity_state.GetBlock(gravity_gradient_residual_block), solution.gradPhi);
gravity_potential_adapter.scatter(gravity_state.GetBlock(gravity_poisson_residual_block), solution.phi);
MEAN_FIELD_PROFILE_CALL_WARMUP(
"gravity solve: scatter solution", 0,
gravity_flux_adapter.scatter(gravity_state.GetBlock(gravity_gradient_residual_block), solution.gradPhi);
gravity_potential_adapter.scatter(gravity_state.GetBlock(gravity_poisson_residual_block), solution.phi)
);
return solution;
}