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,3 +1,4 @@
#include "profile.h"
#include <catch2/catch_test_macros.hpp>
#include <catch2/matchers/catch_matchers_floating_point.hpp>
@@ -716,6 +717,9 @@ namespace {
const mean_field::physics::GravitySolution &solution,
const mfem::GridFunction &displacement
) {
MEAN_FIELD_PROFILE_SCOPE_WARMUP("gravity virial: energy integration", 0);
std::uint64_t mapping_evaluations = 0;
mean_field::mapping::DomainMapper::Workspace workspace(f.mesh->Dimension());
double local_binding = 0.0;
@@ -729,6 +733,13 @@ namespace {
const int order =
2 * std::max(f.gravityPotentialFes->GetMaxElementOrder(), f.gravityFluxFes->GetMaxElementOrder()) + 8;
std::array<long long, mapping_status_count> local_status_counts{};
mean_field::mapping::VolumeMappingContext context;
mfem::Vector reference_field(3);
mfem::Vector physical_field(3);
mfem::Array<int> displacement_dofs;
mfem::Array<int> compactification_dofs;
mfem::Vector element_displacement;
mfem::Vector element_compactification;
for (int element_id = 0; element_id < f.mesh->GetNE(); ++element_id) {
mfem::ElementTransformation *transformation = f.mesh->GetElementTransformation(element_id);
@@ -739,17 +750,11 @@ namespace {
const mfem::FiniteElement &displacement_element = *f.displacementFes->GetFE(element_id);
const mfem::FiniteElement &compactification_element = *f.compactificationFes->GetFE(element_id);
mfem::Array<int> displacement_dofs;
mfem::Array<int> compactification_dofs;
mfem::DofTransformation *displacement_transform =
f.displacementFes->GetElementVDofs(element_id, displacement_dofs);
mfem::DofTransformation *compactification_transform =
f.compactificationFes->GetElementDofs(element_id, compactification_dofs);
mfem::Vector element_displacement;
mfem::Vector element_compactification;
displacement.GetSubVector(displacement_dofs, element_displacement);
f.compactificationCoordinate->GetSubVector(compactification_dofs, element_compactification);
@@ -778,11 +783,11 @@ namespace {
for (int q = 0; q < rule.GetNPoints(); ++q) {
const mfem::IntegrationPoint &point = rule.IntPoint(q);
mean_field::mapping::VolumeMappingContext context;
context.mapping.mapping_determinant = 0.0;
const mean_field::mapping::MappingStatus status =
f.domainMapperStateless->EvaluateVolume(mapping_data, *transformation, point, workspace, context);
++mapping_evaluations;
const double mapping_determinant = context.mapping.mapping_determinant;
if (std::isfinite(mapping_determinant)) {
@@ -799,14 +804,6 @@ namespace {
continue;
}
if (status != mean_field::mapping::MappingStatus::valid) {
++local_invalid_points;
continue;
}
mfem::Vector reference_field(3);
mfem::Vector physical_field(3);
solution.gradPhi.GetVectorValue(element_id, point, reference_field);
mean_field::mapping::MapHDivFluxToPhysical(context.mapping, reference_field, physical_field);
@@ -819,23 +816,33 @@ namespace {
}
}
MEAN_FIELD_PROFILE_COUNT("gravity virial: energy mapping evaluations", mapping_evaluations);
GravitationalEnergies energies;
MPI_Comm communicator = f.densityFes->GetComm();
MPI_Allreduce(&local_binding, &energies.binding, 1, MPI_DOUBLE, MPI_SUM, communicator);
MPI_Allreduce(&local_virial, &energies.virial, 1, MPI_DOUBLE, MPI_SUM, communicator);
MPI_Allreduce(&local_invalid_points, &energies.invalid_points, 1, MPI_LONG_LONG, MPI_SUM, communicator);
const std::array<double, 2> local_energy{local_binding, local_virial};
std::array<double, 2> global_energy{};
MPI_Allreduce(local_energy.data(), global_energy.data(), 2, MPI_DOUBLE, MPI_SUM, communicator);
energies.binding = global_energy[0];
energies.virial = global_energy[1];
std::array<long long, mapping_status_count + 1> local_counts{};
std::array<long long, mapping_status_count + 1> global_counts{};
local_counts[0] = local_invalid_points;
std::copy(local_status_counts.begin(), local_status_counts.end(), local_counts.begin() + 1);
MPI_Allreduce(
local_status_counts.data(), energies.mapping_status_counts.data(), mapping_status_count, MPI_LONG_LONG,
MPI_SUM, communicator
);
MPI_Allreduce(
&local_minimum_determinant, &energies.minimum_mapping_determinant, 1, MPI_DOUBLE, MPI_MIN, communicator
);
MPI_Allreduce(
&local_maximum_determinant, &energies.maximum_mapping_determinant, 1, MPI_DOUBLE, MPI_MAX, communicator
local_counts.data(), global_counts.data(), mapping_status_count + 1, MPI_LONG_LONG, MPI_SUM, communicator
);
energies.invalid_points = global_counts[0];
std::copy(global_counts.begin() + 1, global_counts.end(), energies.mapping_status_counts.begin());
const std::array<double, 2> local_extrema{local_minimum_determinant, -local_maximum_determinant};
std::array<double, 2> global_extrema{};
MPI_Allreduce(local_extrema.data(), global_extrema.data(), 2, MPI_DOUBLE, MPI_MIN, communicator);
energies.minimum_mapping_determinant = global_extrema[0];
energies.maximum_mapping_determinant = -global_extrema[1];
return energies;
}
@@ -999,6 +1006,8 @@ TEST_CASE(
"Gravity Field Virial Consistency Across Volume Preserving Deformation",
tags::gravity_consistency_accuracy
) {
MEAN_FIELD_PROFILE_RESET();
auto args = test_utils::setup_args();
args.p.rtol = 1.0e-13;
args.p.max_iters = std::max(args.p.max_iters, 1000);
@@ -1054,12 +1063,13 @@ TEST_CASE(
mfem::VectorFunctionCoefficient displacement_coefficient(3, displacement_function);
mfem::ParGridFunction displacement(f.displacementFes.get());
displacement.ProjectCoefficient(displacement_coefficient);
MEAN_FIELD_PROFILE_CALL_WARMUP(
"gravity virial: displacement projection", 0, displacement.ProjectCoefficient(displacement_coefficient);
*f.displacement = displacement
);
*f.displacement = displacement;
f.com = mean_field::analysis::get_com(f, density);
f.Q = mean_field::physics::compute_quadrupole_moment_tensor(f, density, f.com);
f.com = mean_field::analysis::get_com(f, density);
f.Q = mean_field::physics::compute_quadrupole_moment_tensor(f, density, f.com);
const mfem::FiniteElementSpace *nodal_space = f.mesh->GetNodalFESpace();
const mean_field::physics::GravitySolution solution =
@@ -1131,6 +1141,8 @@ TEST_CASE(
<< ", consistency error=" << consistency_errors[index] << '\n';
}
MEAN_FIELD_PROFILE_PRINT(f.mesh->GetComm());
INFO(report.str());
for (std::size_t index = 1; index < amplitudes.size(); ++index) {