perf(allocations): reduced overall allocations by 95%, increaseed jacobian applicatin by 2x
This commit uses global pre allocated work space to dramatically reduce memory usage and allocation time
This commit is contained in:
@@ -60,6 +60,67 @@ TEST_CASE(
|
||||
CHECK(preparedOperator.GetPreparationCount() == 1);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Prepared Mapped Gravity Source Reuses Tables Across Preparation Modes And Rejection",
|
||||
tags::gravity_prepared_unit &tags::geometry
|
||||
) {
|
||||
auto args = test_utils::setup_args();
|
||||
fem::FEM f = fem::setup_fem(args.mesh_file, args, 0);
|
||||
REQUIRE(f.okay());
|
||||
|
||||
operators::PreparedMappedGravitySourceOperator operation(f, *f.domainMapperStateless);
|
||||
const mfem::Vector densityTrue = prepared_test::make_deterministic_vector(f.densityFes->GetTrueVSize(), 0.41);
|
||||
const mfem::Vector density = operation.GetDensityMap().gather(densityTrue);
|
||||
const mfem::Vector displacementTrue = prepared_test::make_displacement(f, 0.4);
|
||||
const mfem::Vector displacement = operation.GetDisplacementMap().gather(displacementTrue);
|
||||
const mfem::Vector directionTrue = prepared_test::make_displacement(f, 0.7);
|
||||
const MPI_Comm communicator = f.mesh->GetComm();
|
||||
|
||||
operation.Prepare(displacement);
|
||||
mfem::Vector baselineAction;
|
||||
mfem::Vector baselineVariation;
|
||||
operation.Mult(density, baselineAction);
|
||||
operation.MultDisplacementVariationTrue(densityTrue, directionTrue, baselineVariation);
|
||||
|
||||
const mfem::Vector primalDisplacementTrue = prepared_test::make_displacement(f, 1.0);
|
||||
operation.PreparePrimal(operation.GetDisplacementMap().gather(primalDisplacementTrue));
|
||||
REQUIRE(operation.IsPrepared());
|
||||
CHECK_FALSE(operation.HasVariationData());
|
||||
mfem::Vector primalAction;
|
||||
mfem::Vector referenceActionTrue;
|
||||
operation.Mult(density, primalAction);
|
||||
operators::kernels::apply_mapped_source(
|
||||
f, *f.domainMapperStateless, densityTrue, primalDisplacementTrue, referenceActionTrue
|
||||
);
|
||||
CHECK_THAT(
|
||||
prepared_test::relative_error(
|
||||
primalAction, operation.GetPotentialMap().gather(referenceActionTrue), communicator
|
||||
),
|
||||
WithinAbs(0.0, 2.0e-11)
|
||||
);
|
||||
|
||||
operation.Prepare(displacement);
|
||||
REQUIRE(operation.HasVariationData());
|
||||
mfem::Vector repeatedAction;
|
||||
mfem::Vector repeatedVariation;
|
||||
operation.Mult(density, repeatedAction);
|
||||
operation.MultDisplacementVariationTrue(densityTrue, directionTrue, repeatedVariation);
|
||||
CHECK(prepared_test::relative_error(repeatedAction, baselineAction, communicator) < 2.0e-14);
|
||||
CHECK(prepared_test::relative_error(repeatedVariation, baselineVariation, communicator) < 2.0e-14);
|
||||
|
||||
const auto rejected = operation.TryPrepare(operation.GetDisplacementMap().gather(make_folding_displacement(f)));
|
||||
REQUIRE_FALSE(rejected.has_value());
|
||||
CHECK_FALSE(operation.IsPrepared());
|
||||
CHECK_FALSE(operation.HasVariationData());
|
||||
REQUIRE(operation.TryPrepare(displacement).has_value());
|
||||
REQUIRE(operation.HasVariationData());
|
||||
operation.Mult(density, repeatedAction);
|
||||
operation.MultDisplacementVariationTrue(densityTrue, directionTrue, repeatedVariation);
|
||||
CHECK(prepared_test::relative_error(repeatedAction, baselineAction, communicator) < 2.0e-14);
|
||||
CHECK(prepared_test::relative_error(repeatedVariation, baselineVariation, communicator) < 2.0e-14);
|
||||
CHECK(operation.GetPreparationCount() == 4);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Prepared Mapped Gravity Source Matches Stateless Kernel",
|
||||
tags::gravity_prepared
|
||||
|
||||
@@ -30,6 +30,61 @@ namespace {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
TEST_CASE(
|
||||
"Prepared Hdiv Geometry Variation Preserves Reference Piola Contractions",
|
||||
tags::gravity_prepared_jacobian_accuracy
|
||||
) {
|
||||
auto args = test_utils::setup_args();
|
||||
fem::FEM f = fem::setup_fem(args.mesh_file, args, 0);
|
||||
REQUIRE(f.okay());
|
||||
|
||||
operators::PreparedMappedHDivMassOperator preparedOperator(f, *f.domainMapperStateless);
|
||||
const MPI_Comm communicator = f.gravityFluxFes->GetComm();
|
||||
const mfem::Vector first = prepared_test::make_deterministic_vector(f.gravityFluxFes->GetTrueVSize(), 0.31);
|
||||
const mfem::Vector second = prepared_test::make_deterministic_vector(f.gravityFluxFes->GetTrueVSize(), 0.79);
|
||||
const mfem::Vector direction = prepared_test::make_displacement(f, 0.43);
|
||||
mfem::Vector firstAction;
|
||||
|
||||
bool hasStellar = false;
|
||||
bool hasVacuum = false;
|
||||
for (int element = 0; element < f.mesh->GetNE(); ++element) {
|
||||
const bool vacuum = f.domainMapperStateless->IsCompactifiedElement(*f.mesh->GetElementTransformation(element));
|
||||
hasVacuum = hasVacuum || vacuum;
|
||||
hasStellar = hasStellar || !vacuum;
|
||||
}
|
||||
const int localDomains[2]{hasStellar ? 1 : 0, hasVacuum ? 1 : 0};
|
||||
int globalDomains[2]{};
|
||||
REQUIRE(MPI_Allreduce(localDomains, globalDomains, 2, MPI_INT, MPI_MAX, communicator) == MPI_SUCCESS);
|
||||
REQUIRE(globalDomains[0] != 0);
|
||||
REQUIRE(globalDomains[1] != 0);
|
||||
|
||||
// The stateless path still constructs each physically mapped RT basis;
|
||||
// compare both an undeformed and a changed prepared geometry, including
|
||||
// Kelvin exterior elements, against the compact forward/dual contractions.
|
||||
for (const double scale : {0.0, 0.7}) {
|
||||
const mfem::Vector displacementTrue = prepared_test::make_displacement(f, scale);
|
||||
const mfem::Vector displacement = preparedOperator.GetDisplacementMap().gather(displacementTrue);
|
||||
preparedOperator.Prepare(displacement);
|
||||
preparedOperator.MultDisplacementVariationTrue(first, direction, firstAction);
|
||||
|
||||
mfem::Vector referenceAction;
|
||||
operators::kernels::apply_mapped_hdiv_mass_variation(
|
||||
f, *f.domainMapperStateless, first, displacementTrue, direction, referenceAction
|
||||
);
|
||||
const double error = prepared_test::relative_error(firstAction, referenceAction, communicator);
|
||||
INFO("Deformation scale = " << scale);
|
||||
INFO("Prepared/stateless geometry-variation relative error = " << error);
|
||||
CHECK(error < 2.0e-11);
|
||||
}
|
||||
|
||||
mfem::Vector secondAction;
|
||||
preparedOperator.MultDisplacementVariationTrue(second, direction, secondAction);
|
||||
const double firstSecond = prepared_test::global_dot(first, secondAction, communicator);
|
||||
const double secondFirst = prepared_test::global_dot(second, firstAction, communicator);
|
||||
CHECK(prepared_test::relative_scalar_error(firstSecond, secondFirst) < 2.0e-11);
|
||||
CHECK(preparedOperator.GetPreparationCount() == 2);
|
||||
}
|
||||
|
||||
TEST_CASE(
|
||||
"Prepared Mapped Hdiv Mass Reports Invalid Candidate Geometry Without Unwinding",
|
||||
tags::gravity_prepared_unit &tags::geometry
|
||||
|
||||
Reference in New Issue
Block a user