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:
2026-08-23 10:13:53 -04:00
parent dc912fd15e
commit 0f3ca8050b
137 changed files with 29975 additions and 16389 deletions

View File

@@ -38,8 +38,7 @@ namespace {
return identity;
}
mapping::MappingPointContext
make_context(const mfem::DenseMatrix &jacobian) {
mapping::MappingPointContext make_context(const mfem::DenseMatrix &jacobian) {
mapping::MappingPointContext context;
context.mapping_jacobian = jacobian;
context.mapping_determinant = jacobian.Det();
@@ -70,9 +69,8 @@ namespace {
const mfem::DenseMatrix &jacobian_variation
) {
mapping::MappingPointVariation variation;
variation.mapping_jacobian_variation = jacobian_variation;
variation.mapping_determinant_variation =
determinant_variation(jacobian, jacobian_variation);
variation.mapping_jacobian_variation = jacobian_variation;
variation.mapping_determinant_variation = determinant_variation(jacobian, jacobian_variation);
variation.physical_position_variation.SetSize(dimension);
variation.physical_position_variation = 0.0;
return variation;
@@ -99,11 +97,7 @@ namespace {
mfem::DenseMatrix difference(computed);
difference -= reference;
return matrix_norm(difference) /
std::max(
matrix_norm(reference),
std::numeric_limits<double>::epsilon()
);
return matrix_norm(difference) / std::max(matrix_norm(reference), std::numeric_limits<double>::epsilon());
}
double matrix_asymmetry(const mfem::DenseMatrix &matrix) {
@@ -111,8 +105,7 @@ namespace {
for (int row = 0; row < matrix.Height(); ++row) {
for (int column = 0; column < matrix.Width(); ++column) {
const double difference =
matrix(row, column) - matrix(column, row);
const double difference = matrix(row, column) - matrix(column, row);
asymmetry_squared += difference * difference;
}
}
@@ -130,20 +123,16 @@ namespace {
for (int row = 0; row < dimension; ++row) {
for (int column = 0; column < dimension; ++column) {
plus_jacobian(row, column) +=
step * jacobian_variation(row, column);
minus_jacobian(row, column) -=
step * jacobian_variation(row, column);
plus_jacobian(row, column) += step * jacobian_variation(row, column);
minus_jacobian(row, column) -= step * jacobian_variation(row, column);
}
}
REQUIRE(plus_jacobian.Det() > 0.0);
REQUIRE(minus_jacobian.Det() > 0.0);
const mapping::MappingPointContext plus_context =
make_context(plus_jacobian);
const mapping::MappingPointContext minus_context =
make_context(minus_jacobian);
const mapping::MappingPointContext plus_context = make_context(plus_jacobian);
const mapping::MappingPointContext minus_context = make_context(minus_jacobian);
mfem::DenseMatrix plus_tensor;
mfem::DenseMatrix minus_tensor;
@@ -184,22 +173,17 @@ TEST_CASE(
);
cases.push_back(
{"anisotropic stretch",
make_matrix({1.20, 0.00, 0.00, 0.00, 0.85, 0.00, 0.00, 0.00, 1.10}),
{"anisotropic stretch", make_matrix({1.20, 0.00, 0.00, 0.00, 0.85, 0.00, 0.00, 0.00, 1.10}),
make_matrix({0.08, 0.01, -0.03, 0.02, -0.05, 0.04, 0.01, -0.02, 0.07})}
);
cases.push_back(
{"sheared mapping",
make_matrix({1.10, 0.20, -0.05, 0.04, 0.90, 0.12, -0.03, 0.08, 1.15}),
make_matrix(
{0.06, -0.04, 0.02, 0.03, 0.05, -0.07, -0.01, 0.04, -0.02}
)}
{"sheared mapping", make_matrix({1.10, 0.20, -0.05, 0.04, 0.90, 0.12, -0.03, 0.08, 1.15}),
make_matrix({0.06, -0.04, 0.02, 0.03, 0.05, -0.07, -0.01, 0.04, -0.02})}
);
cases.push_back(
{"strong general mapping",
make_matrix({1.35, 0.31, -0.18, -0.12, 0.78, 0.22, 0.09, -0.16, 1.27}),
{"strong general mapping", make_matrix({1.35, 0.31, -0.18, -0.12, 0.78, 0.22, 0.09, -0.16, 1.27}),
make_matrix({-0.11, 0.08, 0.05, 0.07, 0.09, -0.04, -0.06, 0.03, 0.12})}
);
@@ -207,37 +191,22 @@ TEST_CASE(
DYNAMIC_SECTION(test_case.name) {
REQUIRE(test_case.jacobian.Det() > 0.0);
const mapping::MappingPointContext context =
make_context(test_case.jacobian);
const mapping::MappingPointVariation variation = make_variation(
test_case.jacobian, test_case.jacobian_variation
);
const mapping::MappingPointContext context = make_context(test_case.jacobian);
const mapping::MappingPointVariation variation =
make_variation(test_case.jacobian, test_case.jacobian_variation);
mfem::DenseMatrix analytic_variation;
mapping::ComputeHDivMassTensorVariation(
context, variation, analytic_variation
);
mapping::ComputeHDivMassTensorVariation(context, variation, analytic_variation);
const mfem::DenseMatrix finite_difference =
centered_mass_tensor_difference(
test_case.jacobian, test_case.jacobian_variation, 1.0e-6
);
const double relative_error =
relative_matrix_error(analytic_variation, finite_difference);
const double asymmetry = matrix_asymmetry(analytic_variation);
centered_mass_tensor_difference(test_case.jacobian, test_case.jacobian_variation, 1.0e-6);
const double relative_error = relative_matrix_error(analytic_variation, finite_difference);
const double asymmetry = matrix_asymmetry(analytic_variation);
INFO("Mapping determinant = " << context.mapping_determinant);
INFO(
"Determinant variation = "
<< variation.mapping_determinant_variation
);
INFO(
"Analytic variation norm = " << matrix_norm(analytic_variation)
);
INFO(
"Finite-difference variation norm = "
<< matrix_norm(finite_difference)
);
INFO("Determinant variation = " << variation.mapping_determinant_variation);
INFO("Analytic variation norm = " << matrix_norm(analytic_variation));
INFO("Finite-difference variation norm = " << matrix_norm(finite_difference));
INFO("Relative tensor-variation error = " << relative_error);
INFO("Tensor-variation asymmetry = " << asymmetry);
@@ -252,31 +221,24 @@ TEST_CASE(
"Convergence",
tags::unit &tags::transformations &tags::convergence
) {
const mfem::DenseMatrix jacobian =
make_matrix({1.18, 0.17, -0.09, -0.04, 0.92, 0.14, 0.07, -0.11, 1.23});
const mfem::DenseMatrix jacobian = make_matrix({1.18, 0.17, -0.09, -0.04, 0.92, 0.14, 0.07, -0.11, 1.23});
const mfem::DenseMatrix jacobian_variation =
make_matrix({0.09, -0.06, 0.04, 0.03, 0.07, -0.05, -0.02, 0.08, -0.03});
const mapping::MappingPointContext context = make_context(jacobian);
const mapping::MappingPointVariation variation =
make_variation(jacobian, jacobian_variation);
const mapping::MappingPointContext context = make_context(jacobian);
const mapping::MappingPointVariation variation = make_variation(jacobian, jacobian_variation);
mfem::DenseMatrix analytic_variation;
mapping::ComputeHDivMassTensorVariation(
context, variation, analytic_variation
);
mapping::ComputeHDivMassTensorVariation(context, variation, analytic_variation);
const std::array<double, 3> steps{4.0e-2, 2.0e-2, 1.0e-2};
std::array<double, 3> errors{};
for (int i = 0; i < static_cast<int>(steps.size()); ++i) {
const mfem::DenseMatrix finite_difference =
centered_mass_tensor_difference(
jacobian, jacobian_variation, steps[i]
);
errors[i] =
relative_matrix_error(finite_difference, analytic_variation);
centered_mass_tensor_difference(jacobian, jacobian_variation, steps[i]);
errors[i] = relative_matrix_error(finite_difference, analytic_variation);
INFO("Step = " << steps[i] << ", relative error = " << errors[i]);
}
@@ -295,24 +257,20 @@ TEST_CASE(
"Hdiv Mass Tensor Variation Vanishes For Translation",
tags::unit &tags::transformations
) {
const mfem::DenseMatrix jacobian =
make_matrix({1.12, 0.08, -0.03, 0.02, 0.94, 0.07, -0.01, 0.05, 1.09});
const mfem::DenseMatrix jacobian = make_matrix({1.12, 0.08, -0.03, 0.02, 0.94, 0.07, -0.01, 0.05, 1.09});
mfem::DenseMatrix zero_jacobian_variation(dimension);
zero_jacobian_variation = 0.0;
zero_jacobian_variation = 0.0;
mapping::MappingPointContext context = make_context(jacobian);
mapping::MappingPointVariation variation =
make_variation(jacobian, zero_jacobian_variation);
mapping::MappingPointContext context = make_context(jacobian);
mapping::MappingPointVariation variation = make_variation(jacobian, zero_jacobian_variation);
variation.physical_position_variation.SetSize(dimension);
variation.physical_position_variation(0) = 0.7;
variation.physical_position_variation(1) = -0.4;
variation.physical_position_variation(2) = 0.9;
mfem::DenseMatrix tensor_variation;
mapping::ComputeHDivMassTensorVariation(
context, variation, tensor_variation
);
mapping::ComputeHDivMassTensorVariation(context, variation, tensor_variation);
CHECK_THAT(variation.mapping_determinant_variation, WithinAbs(0.0, 0.0));
check_zero_matrix(tensor_variation, 1.0e-14);
@@ -323,23 +281,17 @@ TEST_CASE(
"Identity",
tags::unit &tags::transformations
) {
const mfem::DenseMatrix identity = make_identity_matrix();
const mfem::DenseMatrix identity = make_identity_matrix();
const mfem::DenseMatrix rotation_variation =
make_matrix({0.0, -0.30, 0.20, 0.30, 0.0, -0.15, -0.20, 0.15, 0.0});
const mfem::DenseMatrix rotation_variation = make_matrix({0.0, -0.30, 0.20, 0.30, 0.0, -0.15, -0.20, 0.15, 0.0});
const mapping::MappingPointContext context = make_context(identity);
const mapping::MappingPointVariation variation =
make_variation(identity, rotation_variation);
const mapping::MappingPointVariation variation = make_variation(identity, rotation_variation);
mfem::DenseMatrix tensor_variation;
mapping::ComputeHDivMassTensorVariation(
context, variation, tensor_variation
);
mapping::ComputeHDivMassTensorVariation(context, variation, tensor_variation);
CHECK_THAT(
variation.mapping_determinant_variation, WithinAbs(0.0, 1.0e-15)
);
CHECK_THAT(variation.mapping_determinant_variation, WithinAbs(0.0, 1.0e-15));
check_zero_matrix(tensor_variation, 1.0e-14);
}
@@ -355,26 +307,18 @@ TEST_CASE(
for (int i = 0; i < dimension; ++i)
jacobian_variation(i, i) = scaling_variation;
const mapping::MappingPointContext context = make_context(identity);
const mapping::MappingPointVariation variation =
make_variation(identity, jacobian_variation);
const mapping::MappingPointContext context = make_context(identity);
const mapping::MappingPointVariation variation = make_variation(identity, jacobian_variation);
mfem::DenseMatrix tensor_variation;
mapping::ComputeHDivMassTensorVariation(
context, variation, tensor_variation
);
mapping::ComputeHDivMassTensorVariation(context, variation, tensor_variation);
CHECK_THAT(
variation.mapping_determinant_variation,
WithinAbs(3.0 * scaling_variation, 1.0e-14)
);
CHECK_THAT(variation.mapping_determinant_variation, WithinAbs(3.0 * scaling_variation, 1.0e-14));
for (int row = 0; row < dimension; ++row) {
for (int column = 0; column < dimension; ++column) {
const double expected = row == column ? -scaling_variation : 0.0;
CHECK_THAT(
tensor_variation(row, column), WithinAbs(expected, 1.0e-14)
);
CHECK_THAT(tensor_variation(row, column), WithinAbs(expected, 1.0e-14));
}
}
}
@@ -387,21 +331,16 @@ TEST_CASE(
const mfem::DenseMatrix identity = make_identity_matrix();
mfem::DenseMatrix jacobian_variation(dimension);
jacobian_variation = 0.0;
jacobian_variation(0, 1) = shear_variation;
jacobian_variation = 0.0;
jacobian_variation(0, 1) = shear_variation;
const mapping::MappingPointContext context = make_context(identity);
const mapping::MappingPointVariation variation =
make_variation(identity, jacobian_variation);
const mapping::MappingPointContext context = make_context(identity);
const mapping::MappingPointVariation variation = make_variation(identity, jacobian_variation);
mfem::DenseMatrix tensor_variation;
mapping::ComputeHDivMassTensorVariation(
context, variation, tensor_variation
);
mapping::ComputeHDivMassTensorVariation(context, variation, tensor_variation);
CHECK_THAT(
variation.mapping_determinant_variation, WithinAbs(0.0, 1.0e-15)
);
CHECK_THAT(variation.mapping_determinant_variation, WithinAbs(0.0, 1.0e-15));
CHECK_THAT(tensor_variation(0, 1), WithinAbs(shear_variation, 1.0e-14));
CHECK_THAT(tensor_variation(1, 0), WithinAbs(shear_variation, 1.0e-14));
@@ -418,16 +357,14 @@ TEST_CASE(
"Mapping Determinant Variation Matches Jacobi Formula",
tags::unit &tags::transformations
) {
const mfem::DenseMatrix jacobian =
make_matrix({1.24, 0.19, -0.07, -0.06, 0.88, 0.16, 0.04, -0.12, 1.19});
const mfem::DenseMatrix jacobian = make_matrix({1.24, 0.19, -0.07, -0.06, 0.88, 0.16, 0.04, -0.12, 1.19});
const mfem::DenseMatrix jacobian_variation =
make_matrix({0.08, -0.03, 0.05, 0.02, 0.06, -0.04, -0.01, 0.07, -0.02});
const mapping::MappingPointContext context = make_context(jacobian);
const mapping::MappingPointVariation variation =
make_variation(jacobian, jacobian_variation);
constexpr double difference_step = 1.0e-3;
const mapping::MappingPointContext context = make_context(jacobian);
const mapping::MappingPointVariation variation = make_variation(jacobian, jacobian_variation);
constexpr double difference_step = 1.0e-3;
mfem::DenseMatrix plus_one(context.mapping_jacobian);
mfem::DenseMatrix plus_two(context.mapping_jacobian);
@@ -439,12 +376,10 @@ TEST_CASE(
minus_one.Add(-difference_step, variation.mapping_jacobian_variation);
minus_two.Add(-2.0 * difference_step, variation.mapping_jacobian_variation);
const double finite_difference = (minus_two.Det() - 8.0 * minus_one.Det() +
8.0 * plus_one.Det() - plus_two.Det()) /
(12.0 * difference_step);
const double analytic = variation.mapping_determinant_variation;
const double relative_error = std::abs(finite_difference - analytic) /
std::max(std::abs(analytic), 1.0e-14);
const double finite_difference =
(minus_two.Det() - 8.0 * minus_one.Det() + 8.0 * plus_one.Det() - plus_two.Det()) / (12.0 * difference_step);
const double analytic = variation.mapping_determinant_variation;
const double relative_error = std::abs(finite_difference - analytic) / std::max(std::abs(analytic), 1.0e-14);
INFO("Analytic determinant variation = " << analytic);
INFO("Finite-difference determinant variation = " << finite_difference);