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

@@ -168,10 +168,7 @@ namespace mean_field::mapping {
const double map_determinant = map_jacobian.Det();
MFEM_VERIFY(
map_determinant > 0.0,
"Domain mapping has a non-positive Jacobian determinant."
);
MFEM_VERIFY(map_determinant > 0.0, "Domain mapping has a non-positive Jacobian determinant.");
mfem::MultAtB(map_jacobian, map_jacobian, matrix);
matrix *= 1.0 / std::abs(map_determinant);

View File

@@ -27,26 +27,17 @@ namespace {
} // namespace
namespace mean_field::mapping::compactification {
KelvinCompactification::KelvinCompactification(
options::KelvinCompactificationOptions options
)
KelvinCompactification::KelvinCompactification(options::KelvinCompactificationOptions options)
: m_options(options) {
if (!std::isfinite(m_options.r_star_ref) ||
!std::isfinite(m_options.r_inf_ref)) {
throw std::invalid_argument(
"Kelvin compactification radii must be finite."
);
if (!std::isfinite(m_options.r_star_ref) || !std::isfinite(m_options.r_inf_ref)) {
throw std::invalid_argument("Kelvin compactification radii must be finite.");
}
if (m_options.r_star_ref <= 0.0 ||
m_options.r_inf_ref <= m_options.r_star_ref) {
throw std::invalid_argument(
"Kelvin compactification requires 0 < r_star_ref < r_inf_ref."
);
if (m_options.r_star_ref <= 0.0 || m_options.r_inf_ref <= m_options.r_star_ref) {
throw std::invalid_argument("Kelvin compactification requires 0 < r_star_ref < r_inf_ref.");
}
if (!std::isfinite(m_options.coordinate_tolerance) ||
m_options.coordinate_tolerance < 0.0 ||
if (!std::isfinite(m_options.coordinate_tolerance) || m_options.coordinate_tolerance < 0.0 ||
m_options.coordinate_tolerance >= 1.0) {
throw std::invalid_argument(
"Kelvin compactification coordinate tolerance must be finite "
@@ -65,8 +56,7 @@ namespace mean_field::mapping::compactification {
const double tolerance = m_options.coordinate_tolerance;
if (compactification_coordinate < -tolerance ||
compactification_coordinate > 1.0 + tolerance) {
if (compactification_coordinate < -tolerance || compactification_coordinate > 1.0 + tolerance) {
return MappingStatus::outside_reference_domain;
}
@@ -78,26 +68,22 @@ namespace mean_field::mapping::compactification {
return MappingStatus::at_compactified_infinity;
}
const double radial_extent = m_options.r_inf_ref - m_options.r_star_ref;
const double computational_radius =
m_options.r_star_ref + coordinate * radial_extent;
const double radial_extent = m_options.r_inf_ref - m_options.r_star_ref;
const double computational_radius = m_options.r_star_ref + coordinate * radial_extent;
if (!std::isfinite(computational_radius) ||
computational_radius <= 0.0) {
if (!std::isfinite(computational_radius) || computational_radius <= 0.0) {
return MappingStatus::invalid_reference_radius;
}
const double one_minus_coordinate = 1.0 - coordinate;
const double denominator = computational_radius * one_minus_coordinate;
const double denominator = computational_radius * one_minus_coordinate;
if (!std::isfinite(denominator) || denominator <= 0.0) {
return MappingStatus::non_finite_result;
}
const double scale = m_options.r_star_ref / denominator;
const double scale_derivative =
scale *
(1.0 / one_minus_coordinate - radial_extent / computational_radius);
const double scale = m_options.r_star_ref / denominator;
const double scale_derivative = scale * (1.0 / one_minus_coordinate - radial_extent / computational_radius);
if (!std::isfinite(scale) || !std::isfinite(scale_derivative)) {
return MappingStatus::non_finite_result;
@@ -122,21 +108,18 @@ namespace mean_field::mapping::compactification {
return MappingStatus::invalid_dimension;
}
if (input.displacement_jacobian.Height() != dimension ||
input.displacement_jacobian.Width() != dimension) {
if (input.displacement_jacobian.Height() != dimension || input.displacement_jacobian.Width() != dimension) {
return MappingStatus::invalid_dimension;
}
if (!vector_is_finite(input.reference_position) ||
!vector_is_finite(input.displaced_position) ||
if (!vector_is_finite(input.reference_position) || !vector_is_finite(input.displaced_position) ||
!vector_is_finite(input.compactification_coordinate_gradient) ||
!matrix_is_finite(input.displacement_jacobian)) {
return MappingStatus::non_finite_input;
}
RadialFactors factors;
const MappingStatus factor_status =
ComputeRadialFactors(input.compactification_coordinate, factors);
const MappingStatus factor_status = ComputeRadialFactors(input.compactification_coordinate, factors);
if (factor_status != MappingStatus::valid)
return factor_status;
@@ -144,21 +127,16 @@ namespace mean_field::mapping::compactification {
result.mapping_jacobian.SetSize(dimension, dimension);
for (int i = 0; i < dimension; ++i) {
result.physical_position(i) =
factors.scale * input.displaced_position(i);
result.physical_position(i) = factors.scale * input.displaced_position(i);
for (int j = 0; j < dimension; ++j) {
const double scale_gradient =
factors.scale_derivative *
input.compactification_coordinate_gradient(j);
const double scale_gradient = factors.scale_derivative * input.compactification_coordinate_gradient(j);
result.mapping_jacobian(i, j) =
factors.scale * input.displacement_jacobian(i, j) +
input.displaced_position(i) * scale_gradient;
factors.scale * input.displacement_jacobian(i, j) + input.displaced_position(i) * scale_gradient;
}
}
if (!vector_is_finite(result.physical_position) ||
!matrix_is_finite(result.mapping_jacobian)) {
if (!vector_is_finite(result.physical_position) || !matrix_is_finite(result.mapping_jacobian)) {
return MappingStatus::non_finite_result;
}
@@ -185,13 +163,11 @@ namespace mean_field::mapping::compactification {
return MappingStatus::invalid_dimension;
}
if (input.displacement_jacobian.Height() != dimension ||
input.displacement_jacobian.Width() != dimension) {
if (input.displacement_jacobian.Height() != dimension || input.displacement_jacobian.Width() != dimension) {
return MappingStatus::invalid_dimension;
}
if (result.physical_position.Size() != dimension ||
result.mapping_jacobian.Height() != dimension ||
if (result.physical_position.Size() != dimension || result.mapping_jacobian.Height() != dimension ||
result.mapping_jacobian.Width() != dimension) {
return MappingStatus::invalid_dimension;
}
@@ -202,23 +178,20 @@ namespace mean_field::mapping::compactification {
return MappingStatus::invalid_dimension;
}
if (!vector_is_finite(input.reference_position) ||
!vector_is_finite(input.displaced_position) ||
if (!vector_is_finite(input.reference_position) || !vector_is_finite(input.displaced_position) ||
!vector_is_finite(input.compactification_coordinate_gradient) ||
!matrix_is_finite(input.displacement_jacobian)) {
return MappingStatus::non_finite_input;
}
if (!vector_is_finite(result.physical_position) ||
!matrix_is_finite(result.mapping_jacobian) ||
if (!vector_is_finite(result.physical_position) || !matrix_is_finite(result.mapping_jacobian) ||
!vector_is_finite(direction.displaced_position_variation) ||
!matrix_is_finite(direction.displacement_jacobian_variation)) {
return MappingStatus::non_finite_input;
}
RadialFactors factors;
const MappingStatus factor_status =
ComputeRadialFactors(input.compactification_coordinate, factors);
const MappingStatus factor_status = ComputeRadialFactors(input.compactification_coordinate, factors);
if (factor_status != MappingStatus::valid)
return factor_status;
@@ -226,16 +199,12 @@ namespace mean_field::mapping::compactification {
variation.mapping_jacobian_variation.SetSize(dimension, dimension);
for (int i = 0; i < dimension; ++i) {
variation.physical_position_variation(i) =
factors.scale * direction.displaced_position_variation(i);
variation.physical_position_variation(i) = factors.scale * direction.displaced_position_variation(i);
for (int j = 0; j < dimension; ++j) {
const double scale_gradient =
factors.scale_derivative *
input.compactification_coordinate_gradient(j);
const double scale_gradient = factors.scale_derivative * input.compactification_coordinate_gradient(j);
variation.mapping_jacobian_variation(i, j) =
factors.scale *
direction.displacement_jacobian_variation(i, j) +
factors.scale * direction.displacement_jacobian_variation(i, j) +
direction.displaced_position_variation(i) * scale_gradient;
}
}

View File

@@ -15,10 +15,7 @@ namespace {
domain_mapper.ComputeJacobian(transformation, map_jacobian);
const double map_determinant = map_jacobian.Det();
MFEM_VERIFY(
map_determinant > 0.0,
"Domain mapping has a non-positive Jacobian determinant."
);
MFEM_VERIFY(map_determinant > 0.0, "Domain mapping has a non-positive Jacobian determinant.");
return map_determinant;
}
} // namespace
@@ -32,8 +29,7 @@ namespace mean_field::mapping {
m_r_star_ref(r_star_ref),
m_r_inf_ref(r_inf_ref) {
InitAllScratchSpaces();
CalcIsIdentity() ? m_displacement_is_identity = true
: m_displacement_is_identity = false;
CalcIsIdentity() ? m_displacement_is_identity = true : m_displacement_is_identity = false;
}
DomainMapper::DomainMapper(
@@ -46,8 +42,7 @@ namespace mean_field::mapping {
m_r_star_ref(r_star_ref),
m_r_inf_ref(r_inf_ref) {
InitAllScratchSpaces();
CalcIsIdentity() ? m_displacement_is_identity = true
: m_displacement_is_identity = false;
CalcIsIdentity() ? m_displacement_is_identity = true : m_displacement_is_identity = false;
}
bool DomainMapper::is_vacuum(const mfem::ElementTransformation &T) const {
@@ -76,14 +71,12 @@ namespace mean_field::mapping {
m_d = &d;
InvalidateCache();
CalcIsIdentity() ? m_displacement_is_identity = true
: m_displacement_is_identity = false;
CalcIsIdentity() ? m_displacement_is_identity = true : m_displacement_is_identity = false;
}
bool DomainMapper::HasCompactification() const noexcept {
return std::isfinite(m_r_star_ref) && std::isfinite(m_r_inf_ref) &&
m_r_star_ref > 0.0 && m_r_inf_ref > m_r_star_ref &&
m_xi_clamp > 0.0 && m_xi_clamp < 1.0;
return std::isfinite(m_r_star_ref) && std::isfinite(m_r_inf_ref) && m_r_star_ref > 0.0 &&
m_r_inf_ref > m_r_star_ref && m_xi_clamp > 0.0 && m_xi_clamp < 1.0;
}
bool DomainMapper::HasDisplacementField() const noexcept {
@@ -95,10 +88,9 @@ namespace mean_field::mapping {
return true;
}
const int local_identity = m_d->Normlinf() == 0.0 ? 1 : 0;
const int local_identity = m_d->Normlinf() == 0.0 ? 1 : 0;
const auto *parallel_displacement =
dynamic_cast<const mfem::ParGridFunction *>(m_d);
const auto *parallel_displacement = dynamic_cast<const mfem::ParGridFunction *>(m_d);
if (parallel_displacement == nullptr) {
return local_identity == 1;
@@ -106,8 +98,7 @@ namespace mean_field::mapping {
int global_identity = 0;
MPI_Allreduce(
&local_identity, &global_identity, 1, MPI_INT, MPI_MIN,
parallel_displacement->ParFESpace()->GetComm()
&local_identity, &global_identity, 1, MPI_INT, MPI_MIN, parallel_displacement->ParFESpace()->GetComm()
);
return global_identity == 1;
@@ -116,8 +107,7 @@ namespace mean_field::mapping {
void DomainMapper::ResetDisplacement() {
m_d = nullptr;
InvalidateCache();
CalcIsIdentity() ? m_displacement_is_identity = true
: m_displacement_is_identity = false;
CalcIsIdentity() ? m_displacement_is_identity = true : m_displacement_is_identity = false;
}
void DomainMapper::ComputeJacobian(
@@ -223,11 +213,7 @@ namespace mean_field::mapping {
mfem::Vector n_unit(dim);
n_unit = n_raw;
n_unit /= n_raw_mag;
return FaceQuadratureContext{
.normal = n_unit,
.ds = ip.weight * n_raw_mag,
.v_dot_n_scale = 1.0
};
return FaceQuadratureContext{.normal = n_unit, .ds = ip.weight * n_raw_mag, .v_dot_n_scale = 1.0};
}
// Nanson's Formula
@@ -253,9 +239,7 @@ namespace mean_field::mapping {
const double n_raw_mag = n_raw.Norml2();
return FaceQuadratureContext{
.normal = n_unit,
.ds = ip.weight * n_raw_mag,
.v_dot_n_scale = n_phys_mag / n_raw_mag
.normal = n_unit, .ds = ip.weight * n_raw_mag, .v_dot_n_scale = n_phys_mag / n_raw_mag
};
}
@@ -297,15 +281,11 @@ namespace mean_field::mapping {
const mfem::Vector &reference_flux,
mfem::Vector &physical_flux
) const {
MFEM_VERIFY(
reference_flux.Size() == m_dim,
"The reference H(div) flux has the wrong dimension."
);
MFEM_VERIFY(reference_flux.Size() == m_dim, "The reference H(div) flux has the wrong dimension.");
mfem::DenseMatrix map_jacobian(m_dim, m_dim);
const double map_determinant = get_positive_map_jacobian(
*this, transformation, integration_point, map_jacobian
);
const double map_determinant =
get_positive_map_jacobian(*this, transformation, integration_point, map_jacobian);
mfem::Vector mapped_flux(m_dim);
map_jacobian.Mult(reference_flux, mapped_flux);
@@ -320,15 +300,11 @@ namespace mean_field::mapping {
const mfem::Vector &physical_flux,
mfem::Vector &reference_flux
) const {
MFEM_VERIFY(
physical_flux.Size() == m_dim,
"The physical flux has the wrong dimension."
);
MFEM_VERIFY(physical_flux.Size() == m_dim, "The physical flux has the wrong dimension.");
mfem::DenseMatrix map_jacobian(m_dim, m_dim);
const double map_determinant = get_positive_map_jacobian(
*this, transformation, integration_point, map_jacobian
);
const double map_determinant =
get_positive_map_jacobian(*this, transformation, integration_point, map_jacobian);
mfem::DenseMatrix inverse_map_jacobian(m_dim, m_dim);
mfem::CalcInverse(map_jacobian, inverse_map_jacobian);
@@ -346,15 +322,10 @@ namespace mean_field::mapping {
const mfem::Vector &reference_gradient,
mfem::Vector &physical_gradient
) const {
MFEM_VERIFY(
reference_gradient.Size() == m_dim,
"The reference gradient has the wrong dimension."
);
MFEM_VERIFY(reference_gradient.Size() == m_dim, "The reference gradient has the wrong dimension.");
mfem::DenseMatrix map_jacobian(m_dim, m_dim);
get_positive_map_jacobian(
*this, transformation, integration_point, map_jacobian
);
get_positive_map_jacobian(*this, transformation, integration_point, map_jacobian);
mfem::DenseMatrix inverse_map_jacobian(m_dim, m_dim);
mfem::CalcInverse(map_jacobian, inverse_map_jacobian);
@@ -382,8 +353,7 @@ namespace mean_field::mapping {
}
double DomainMapper::GetCacheHitRate() const {
return (static_cast<double>(m_cache_hits)) /
static_cast<double>(m_cache_misses + m_cache_hits);
return (static_cast<double>(m_cache_hits)) / static_cast<double>(m_cache_misses + m_cache_hits);
}
void DomainMapper::ResetCacheStats() const {
@@ -404,9 +374,9 @@ namespace mean_field::mapping {
const mfem::Vector &x_ref,
mfem::Vector &x_phys
) const {
const double r_ref = x_ref.Norml2();
double xi = (r_ref - m_r_star_ref) / (m_r_inf_ref - m_r_star_ref);
xi = std::clamp(xi, 0.0, m_xi_clamp);
const double r_ref = x_ref.Norml2();
double xi = (r_ref - m_r_star_ref) / (m_r_inf_ref - m_r_star_ref);
xi = std::clamp(xi, 0.0, m_xi_clamp);
const double factor = m_r_star_ref / (r_ref * (1 - xi));
x_phys *= factor;
}
@@ -428,8 +398,7 @@ namespace mean_field::mapping {
const double k = m_r_star_ref / (r_ref * denom);
const double dk_dr =
m_r_star_ref * ((1.0 / (delta_R * r_ref * denom * denom)) -
(1.0 / (r_ref * r_ref * denom)));
m_r_star_ref * ((1.0 / (delta_R * r_ref * denom * denom)) - (1.0 / (r_ref * r_ref * denom)));
J.SetSize(m_dim, m_dim);
const double outer_factor = dk_dr / r_ref;
@@ -445,14 +414,11 @@ namespace mean_field::mapping {
m_cached_elem_id = -1;
}
void DomainMapper::UpdateElementCache(
const mfem::ElementTransformation &T
) const {
void DomainMapper::UpdateElementCache(const mfem::ElementTransformation &T) const {
if (!HasDisplacementField())
return;
if (T.ElementNo != m_cached_elem_id ||
T.ElementType != m_cached_elem_type) {
if (T.ElementNo != m_cached_elem_id || T.ElementType != m_cached_elem_type) {
m_cache_misses++;
m_cached_elem_id = T.ElementNo;
m_cached_elem_type = T.ElementType;

View File

@@ -39,9 +39,7 @@ namespace mean_field::mapping {
: m_element(&element),
m_dofs(dofs) {
if (element.GetRangeType() != mfem::FiniteElement::SCALAR) {
throw std::invalid_argument(
"Compactification coordinate requires a scalar finite element."
);
throw std::invalid_argument("Compactification coordinate requires a scalar finite element.");
}
if (element.GetMapType() != mfem::FiniteElement::VALUE) {
@@ -75,8 +73,7 @@ namespace mean_field::mapping {
}
}
const mfem::FiniteElement &
ElementCompactificationData::GetElement() const noexcept {
const mfem::FiniteElement &ElementCompactificationData::GetElement() const noexcept {
return *m_element;
}
@@ -102,8 +99,7 @@ namespace mean_field::mapping {
"The displacement element must have at least one degree of "
"freedom."
);
if (displacement_dofs.Size() <= 0 ||
displacement_dofs.Size() % dof_count != 0) {
if (displacement_dofs.Size() <= 0 || displacement_dofs.Size() % dof_count != 0) {
throw std::invalid_argument(
"The displacement vector size must be a positive multiple of "
"the "
@@ -117,31 +113,25 @@ namespace mean_field::mapping {
if (ordering == mfem::Ordering::byNODES) {
for (int component = 0; component < m_dimension; ++component) {
for (int i = 0; i < dof_count; ++i) {
m_dof_matrix(i, component) =
displacement_dofs(i + component * dof_count);
m_dof_matrix(i, component) = displacement_dofs(i + component * dof_count);
}
}
} else if (ordering == mfem::Ordering::byVDIM) {
for (int i = 0; i < dof_count; ++i) {
for (int component = 0; component < m_dimension; ++component) {
m_dof_matrix(i, component) =
displacement_dofs(component + i * m_dimension);
m_dof_matrix(i, component) = displacement_dofs(component + i * m_dimension);
}
}
} else {
throw std::invalid_argument(
"Unsupported MFEM displacement ordering."
);
throw std::invalid_argument("Unsupported MFEM displacement ordering.");
}
}
const mfem::FiniteElement &
ElementDisplacementData::GetElement() const noexcept {
const mfem::FiniteElement &ElementDisplacementData::GetElement() const noexcept {
return *m_element;
}
const mfem::DenseMatrix &
ElementDisplacementData::GetDofMatrix() const noexcept {
const mfem::DenseMatrix &ElementDisplacementData::GetDofMatrix() const noexcept {
return m_dof_matrix;
}
@@ -161,9 +151,7 @@ namespace mean_field::mapping {
const mfem::FiniteElement &element,
const mfem::Vector &displacement_dofs
) {
return ElementDisplacementData(
element, displacement_dofs, mfem::Ordering::byNODES
);
return ElementDisplacementData(element, displacement_dofs, mfem::Ordering::byNODES);
}
DomainMapperStateless::Workspace::Workspace(const int dimension) {
@@ -172,9 +160,7 @@ namespace mean_field::mapping {
void DomainMapperStateless::Workspace::SetDimension(const int dimension) {
if (dimension <= 0) {
throw std::invalid_argument(
"Domain mapping workspace dimension must be positive."
);
throw std::invalid_argument("Domain mapping workspace dimension must be positive.");
}
m_dimension = dimension;
@@ -197,9 +183,7 @@ namespace mean_field::mapping {
m_exterior_result.mapping_jacobian.SetSize(dimension, dimension);
m_exterior_variation.physical_position_variation.SetSize(dimension);
m_exterior_variation.mapping_jacobian_variation.SetSize(
dimension, dimension
);
m_exterior_variation.mapping_jacobian_variation.SetSize(dimension, dimension);
}
int DomainMapperStateless::Workspace::GetDimension() const noexcept {
@@ -213,22 +197,15 @@ namespace mean_field::mapping {
: m_options(options),
m_exterior_map(std::move(exterior_map)) {
if (m_options.dimension <= 0)
throw std::invalid_argument(
"The domain-mapping dimension must be positive."
);
throw std::invalid_argument("The domain-mapping dimension must be positive.");
if (m_options.vacuum_element_attribute <= 0)
throw std::invalid_argument(
"The vacuum element attribute must be positive."
);
throw std::invalid_argument("The vacuum element attribute must be positive.");
if (!m_exterior_map)
throw std::invalid_argument(
"DomainMapperStateless requires an exterior-domain mapping."
);
throw std::invalid_argument("DomainMapperStateless requires an exterior-domain mapping.");
}
bool DomainMapperStateless::IsCompactifiedElement(
const mfem::ElementTransformation &transformation
) const noexcept {
bool
DomainMapperStateless::IsCompactifiedElement(const mfem::ElementTransformation &transformation) const noexcept {
return transformation.Attribute == m_options.vacuum_element_attribute;
}
@@ -240,17 +217,13 @@ namespace mean_field::mapping {
return m_options.vacuum_element_attribute;
}
const compactification::ExteriorDomainMap &
DomainMapperStateless::GetExteriorMap() const noexcept {
const compactification::ExteriorDomainMap &DomainMapperStateless::GetExteriorMap() const noexcept {
return *m_exterior_map;
}
void DomainMapperStateless::ValidateElementData(
const ElementMappingData &element_data
) const {
const ElementDisplacementData &displacement = element_data.displacement;
const ElementCompactificationData &compactification =
element_data.compactification;
void DomainMapperStateless::ValidateElementData(const ElementMappingData &element_data) const {
const ElementDisplacementData &displacement = element_data.displacement;
const ElementCompactificationData &compactification = element_data.compactification;
if (displacement.GetDimension() != m_options.dimension) {
throw std::invalid_argument(
@@ -275,8 +248,7 @@ namespace mean_field::mapping {
);
}
if (displacement.GetElement().GetGeomType() !=
compactification.GetElement().GetGeomType()) {
if (displacement.GetElement().GetGeomType() != compactification.GetElement().GetGeomType()) {
throw std::invalid_argument(
"Displacement and compactification finite elements have "
"different "
@@ -284,31 +256,25 @@ namespace mean_field::mapping {
);
}
if (compactification.GetElement().GetRangeType() !=
mfem::FiniteElement::SCALAR) {
throw std::invalid_argument(
"Compactification coordinate requires a scalar finite element."
);
if (compactification.GetElement().GetRangeType() != mfem::FiniteElement::SCALAR) {
throw std::invalid_argument("Compactification coordinate requires a scalar finite element.");
}
if (compactification.GetElement().GetMapType() !=
mfem::FiniteElement::VALUE) {
if (compactification.GetElement().GetMapType() != mfem::FiniteElement::VALUE) {
throw std::invalid_argument(
"Compactification coordinate requires a value-mapped finite "
"element."
);
}
if (compactification.GetElement().GetDerivType() !=
mfem::FiniteElement::GRAD) {
if (compactification.GetElement().GetDerivType() != mfem::FiniteElement::GRAD) {
throw std::invalid_argument(
"Compactification coordinate finite element does not provide a "
"gradient."
);
}
if (compactification.GetDofCount() !=
compactification.GetElement().GetDof()) {
if (compactification.GetDofCount() != compactification.GetElement().GetDof()) {
throw std::invalid_argument(
"Compactification coordinate DOF count does not match its "
"finite "
@@ -328,8 +294,7 @@ namespace mean_field::mapping {
const mfem::Vector &dofs = compactification.GetDofs();
const int dof_count = element.GetDof();
if (workspace.GetDimension() != m_options.dimension ||
transformation.GetSpaceDim() != m_options.dimension ||
if (workspace.GetDimension() != m_options.dimension || transformation.GetSpaceDim() != m_options.dimension ||
element.GetDim() != m_options.dimension) {
return MappingStatus::invalid_dimension;
}
@@ -346,22 +311,14 @@ namespace mean_field::mapping {
transformation.SetIntPoint(&integration_point);
workspace.m_compactification_shape.SetSize(dof_count);
workspace.m_compactification_dshape.SetSize(
dof_count, m_options.dimension
);
workspace.m_compactification_dshape.SetSize(dof_count, m_options.dimension);
element.CalcShape(
integration_point, workspace.m_compactification_shape
);
element.CalcPhysDShape(
transformation, workspace.m_compactification_dshape
);
element.CalcShape(integration_point, workspace.m_compactification_shape);
element.CalcPhysDShape(transformation, workspace.m_compactification_dshape);
point_data.coordinate = dofs * workspace.m_compactification_shape;
point_data.coordinate_gradient.SetSize(m_options.dimension);
workspace.m_compactification_dshape.MultTranspose(
dofs, point_data.coordinate_gradient
);
workspace.m_compactification_dshape.MultTranspose(dofs, point_data.coordinate_gradient);
if (!std::isfinite(point_data.coordinate)) {
return MappingStatus::non_finite_result;
@@ -411,15 +368,10 @@ namespace mean_field::mapping {
ValidateElementData(element_data);
if (workspace.GetDimension() != m_options.dimension)
throw std::invalid_argument(
"The mapping workspace has the wrong dimension."
);
throw std::invalid_argument("The mapping workspace has the wrong dimension.");
if (transformation.GetSpaceDim() != m_options.dimension)
throw std::invalid_argument(
"The element transformation has the wrong spatial dimension."
);
if (transformation.GetGeometryType() !=
element_data.displacement.GetElement().GetGeomType())
throw std::invalid_argument("The element transformation has the wrong spatial dimension.");
if (transformation.GetGeometryType() != element_data.displacement.GetElement().GetGeomType())
throw std::invalid_argument(
"The element transformation geometry does not match the "
"supplied "
@@ -432,12 +384,11 @@ namespace mean_field::mapping {
transformation.Transform(integration_point, context.reference_position);
EvaluateField(
element_data.displacement, transformation, integration_point,
workspace, workspace.m_field_value, workspace.m_field_jacobian
element_data.displacement, transformation, integration_point, workspace, workspace.m_field_value,
workspace.m_field_jacobian
);
if (!vector_is_finite(context.reference_position) ||
!vector_is_finite(workspace.m_field_value) ||
if (!vector_is_finite(context.reference_position) || !vector_is_finite(workspace.m_field_value) ||
!matrix_is_finite(workspace.m_field_jacobian)) {
return MappingStatus::non_finite_input;
}
@@ -446,9 +397,7 @@ namespace mean_field::mapping {
context.displaced_position = context.reference_position;
context.displaced_position += workspace.m_field_value;
context.displacement_jacobian.SetSize(
m_options.dimension, m_options.dimension
);
context.displacement_jacobian.SetSize(m_options.dimension, m_options.dimension);
context.displacement_jacobian = workspace.m_field_jacobian;
for (int i = 0; i < m_options.dimension; ++i)
context.displacement_jacobian(i, i) += 1.0;
@@ -456,43 +405,34 @@ namespace mean_field::mapping {
context.compactified = IsCompactifiedElement(transformation);
if (context.compactified) {
const MappingStatus coordinate_status =
EvaluateCompactificationCoordinate(
element_data.compactification, transformation,
integration_point, workspace,
workspace.m_compactification_point
);
const MappingStatus coordinate_status = EvaluateCompactificationCoordinate(
element_data.compactification, transformation, integration_point, workspace,
workspace.m_compactification_point
);
if (coordinate_status != MappingStatus::valid)
return coordinate_status;
const compactification::ExteriorMapInput exterior_input{
.reference_position = context.reference_position,
.displaced_position = context.displaced_position,
.displacement_jacobian = context.displacement_jacobian,
.compactification_coordinate =
workspace.m_compactification_point.coordinate,
.compactification_coordinate_gradient =
workspace.m_compactification_point.coordinate_gradient
.reference_position = context.reference_position,
.displaced_position = context.displaced_position,
.displacement_jacobian = context.displacement_jacobian,
.compactification_coordinate = workspace.m_compactification_point.coordinate,
.compactification_coordinate_gradient = workspace.m_compactification_point.coordinate_gradient
};
const MappingStatus exterior_status = m_exterior_map->Evaluate(
exterior_input, workspace.m_exterior_result
);
const MappingStatus exterior_status = m_exterior_map->Evaluate(exterior_input, workspace.m_exterior_result);
if (exterior_status != MappingStatus::valid)
return exterior_status;
context.physical_position =
workspace.m_exterior_result.physical_position;
context.mapping_jacobian =
workspace.m_exterior_result.mapping_jacobian;
context.physical_position = workspace.m_exterior_result.physical_position;
context.mapping_jacobian = workspace.m_exterior_result.mapping_jacobian;
} else {
context.physical_position = context.displaced_position;
context.mapping_jacobian = context.displacement_jacobian;
}
if (!vector_is_finite(context.physical_position) ||
!matrix_is_finite(context.mapping_jacobian))
if (!vector_is_finite(context.physical_position) || !matrix_is_finite(context.mapping_jacobian))
return MappingStatus::non_finite_result;
context.mapping_determinant = context.mapping_jacobian.Det();
@@ -501,12 +441,8 @@ namespace mean_field::mapping {
if (context.mapping_determinant <= 0.0)
return MappingStatus::non_positive_determinant;
context.inverse_mapping_jacobian.SetSize(
m_options.dimension, m_options.dimension
);
mfem::CalcInverse(
context.mapping_jacobian, context.inverse_mapping_jacobian
);
context.inverse_mapping_jacobian.SetSize(m_options.dimension, m_options.dimension);
mfem::CalcInverse(context.mapping_jacobian, context.inverse_mapping_jacobian);
if (!matrix_is_finite(context.inverse_mapping_jacobian))
return MappingStatus::non_finite_result;
@@ -521,33 +457,22 @@ namespace mean_field::mapping {
Workspace &workspace,
VolumeMappingContext &context
) const {
const MappingStatus point_status = EvaluatePoint(
element_data, transformation, integration_point, workspace,
context.mapping
);
const MappingStatus point_status =
EvaluatePoint(element_data, transformation, integration_point, workspace, context.mapping);
if (point_status != MappingStatus::valid)
return point_status;
transformation.SetIntPoint(&integration_point);
mfem::Mult(
context.mapping.mapping_jacobian, transformation.Jacobian(),
workspace.m_full_element_jacobian
);
mfem::Mult(context.mapping.mapping_jacobian, transformation.Jacobian(), workspace.m_full_element_jacobian);
context.quadrature.J_inv.SetSize(
m_options.dimension, m_options.dimension
);
mfem::CalcInverse(
workspace.m_full_element_jacobian, context.quadrature.J_inv
);
context.quadrature.J_inv.SetSize(m_options.dimension, m_options.dimension);
mfem::CalcInverse(workspace.m_full_element_jacobian, context.quadrature.J_inv);
context.quadrature.detJ = context.mapping.mapping_determinant;
context.quadrature.weight = integration_point.weight *
transformation.Weight() *
context.mapping.mapping_determinant;
context.quadrature.detJ = context.mapping.mapping_determinant;
context.quadrature.weight =
integration_point.weight * transformation.Weight() * context.mapping.mapping_determinant;
if (!matrix_is_finite(context.quadrature.J_inv) ||
!std::isfinite(context.quadrature.weight))
if (!matrix_is_finite(context.quadrature.J_inv) || !std::isfinite(context.quadrature.weight))
return MappingStatus::non_finite_result;
if (context.quadrature.weight <= 0.0)
return MappingStatus::non_positive_determinant;
@@ -555,33 +480,24 @@ namespace mean_field::mapping {
return MappingStatus::valid;
}
mfem::ElementTransformation &
DomainMapperStateless::SelectFaceElementTransformation(
mfem::ElementTransformation &DomainMapperStateless::SelectFaceElementTransformation(
mfem::FaceElementTransformations &transformation,
const FaceElementSide side
) {
if (side == FaceElementSide::element_1) {
MFEM_VERIFY(
transformation.Elem1 != nullptr,
"The face does not have an element-1 transformation."
);
MFEM_VERIFY(transformation.Elem1 != nullptr, "The face does not have an element-1 transformation.");
return *transformation.Elem1;
}
MFEM_VERIFY(
transformation.Elem2 != nullptr,
"The face does not have an element-2 transformation."
);
MFEM_VERIFY(transformation.Elem2 != nullptr, "The face does not have an element-2 transformation.");
return *transformation.Elem2;
}
const mfem::IntegrationPoint &
DomainMapperStateless::SelectFaceElementIntegrationPoint(
const mfem::IntegrationPoint &DomainMapperStateless::SelectFaceElementIntegrationPoint(
mfem::FaceElementTransformations &transformation,
const FaceElementSide side
) {
mfem::ElementTransformation &element_transformation =
SelectFaceElementTransformation(transformation, side);
mfem::ElementTransformation &element_transformation = SelectFaceElementTransformation(transformation, side);
return element_transformation.GetIntPoint();
}
@@ -594,63 +510,47 @@ namespace mean_field::mapping {
FaceMappingContext &context
) const {
transformation.SetAllIntPoints(&integration_point);
mfem::ElementTransformation &element_transformation =
SelectFaceElementTransformation(transformation, side);
mfem::ElementTransformation &element_transformation = SelectFaceElementTransformation(transformation, side);
const mfem::IntegrationPoint &element_integration_point =
SelectFaceElementIntegrationPoint(transformation, side);
const MappingStatus point_status = EvaluatePoint(
element_data, element_transformation, element_integration_point,
workspace, context.mapping
);
const MappingStatus point_status =
EvaluatePoint(element_data, element_transformation, element_integration_point, workspace, context.mapping);
if (point_status != MappingStatus::valid)
return point_status;
workspace.m_reference_normal.SetSize(m_options.dimension);
mfem::CalcOrtho(
transformation.Jacobian(), workspace.m_reference_normal
);
mfem::CalcOrtho(transformation.Jacobian(), workspace.m_reference_normal);
if (side == FaceElementSide::element_2)
workspace.m_reference_normal *= -1.0;
const double reference_normal_magnitude =
workspace.m_reference_normal.Norml2();
if (!std::isfinite(reference_normal_magnitude) ||
reference_normal_magnitude <= 0.0)
const double reference_normal_magnitude = workspace.m_reference_normal.Norml2();
if (!std::isfinite(reference_normal_magnitude) || reference_normal_magnitude <= 0.0)
return MappingStatus::non_finite_result;
context.reference_normal.SetSize(m_options.dimension);
context.reference_normal = workspace.m_reference_normal;
context.reference_normal /= reference_normal_magnitude;
context.mapping.inverse_mapping_jacobian.MultTranspose(
workspace.m_reference_normal, workspace.m_mapped_normal
);
context.mapping.inverse_mapping_jacobian.MultTranspose(workspace.m_reference_normal, workspace.m_mapped_normal);
workspace.m_mapped_normal *= context.mapping.mapping_determinant;
const double mapped_normal_magnitude =
workspace.m_mapped_normal.Norml2();
if (!std::isfinite(mapped_normal_magnitude) ||
mapped_normal_magnitude <= 0.0)
const double mapped_normal_magnitude = workspace.m_mapped_normal.Norml2();
if (!std::isfinite(mapped_normal_magnitude) || mapped_normal_magnitude <= 0.0)
return MappingStatus::non_finite_result;
context.quadrature.normal.SetSize(m_options.dimension);
context.quadrature.normal = workspace.m_mapped_normal;
context.quadrature.normal /= mapped_normal_magnitude;
context.reference_surface_weight =
integration_point.weight * reference_normal_magnitude;
context.physical_surface_weight =
integration_point.weight * mapped_normal_magnitude;
context.reference_surface_weight = integration_point.weight * reference_normal_magnitude;
context.physical_surface_weight = integration_point.weight * mapped_normal_magnitude;
context.quadrature.ds = context.reference_surface_weight;
context.quadrature.v_dot_n_scale =
mapped_normal_magnitude / reference_normal_magnitude;
context.quadrature.ds = context.reference_surface_weight;
context.quadrature.v_dot_n_scale = mapped_normal_magnitude / reference_normal_magnitude;
if (!vector_is_finite(context.quadrature.normal) ||
!std::isfinite(context.reference_surface_weight) ||
!std::isfinite(context.physical_surface_weight) ||
!std::isfinite(context.quadrature.v_dot_n_scale)) {
if (!vector_is_finite(context.quadrature.normal) || !std::isfinite(context.reference_surface_weight) ||
!std::isfinite(context.physical_surface_weight) || !std::isfinite(context.quadrature.v_dot_n_scale)) {
return MappingStatus::non_finite_result;
}
@@ -668,8 +568,7 @@ namespace mean_field::mapping {
) const {
ValidateElementData(element_data);
const ElementMappingData direction_data{
.displacement = direction,
.compactification = element_data.compactification
.displacement = direction, .compactification = element_data.compactification
};
ValidateElementData(direction_data);
@@ -679,9 +578,7 @@ namespace mean_field::mapping {
"degree-of-freedom counts."
);
if (workspace.GetDimension() != m_options.dimension)
throw std::invalid_argument(
"The mapping workspace has the wrong dimension."
);
throw std::invalid_argument("The mapping workspace has the wrong dimension.");
if (base_context.compactified != IsCompactifiedElement(transformation))
throw std::invalid_argument(
"The base mapping context does not match the current element "
@@ -689,86 +586,66 @@ namespace mean_field::mapping {
);
EvaluateField(
direction, transformation, integration_point, workspace,
workspace.m_field_value, workspace.m_field_jacobian
direction, transformation, integration_point, workspace, workspace.m_field_value, workspace.m_field_jacobian
);
if (!vector_is_finite(workspace.m_field_value) ||
!matrix_is_finite(workspace.m_field_jacobian))
if (!vector_is_finite(workspace.m_field_value) || !matrix_is_finite(workspace.m_field_jacobian))
return MappingStatus::non_finite_input;
variation.displacement_variation = workspace.m_field_value;
variation.displacement_jacobian_variation = workspace.m_field_jacobian;
if (base_context.compactified) {
const MappingStatus coordinate_status =
EvaluateCompactificationCoordinate(
element_data.compactification, transformation,
integration_point, workspace,
workspace.m_compactification_point
);
const MappingStatus coordinate_status = EvaluateCompactificationCoordinate(
element_data.compactification, transformation, integration_point, workspace,
workspace.m_compactification_point
);
if (coordinate_status != MappingStatus::valid)
return coordinate_status;
const compactification::ExteriorMapInput exterior_input{
.reference_position = base_context.reference_position,
.displaced_position = base_context.displaced_position,
.displacement_jacobian = base_context.displacement_jacobian,
.compactification_coordinate =
workspace.m_compactification_point.coordinate,
.compactification_coordinate_gradient =
workspace.m_compactification_point.coordinate_gradient
.reference_position = base_context.reference_position,
.displaced_position = base_context.displaced_position,
.displacement_jacobian = base_context.displacement_jacobian,
.compactification_coordinate = workspace.m_compactification_point.coordinate,
.compactification_coordinate_gradient = workspace.m_compactification_point.coordinate_gradient
};
workspace.m_exterior_result.physical_position =
base_context.physical_position;
workspace.m_exterior_result.mapping_jacobian =
base_context.mapping_jacobian;
workspace.m_exterior_result.physical_position = base_context.physical_position;
workspace.m_exterior_result.mapping_jacobian = base_context.mapping_jacobian;
const compactification::ExteriorMapDirection exterior_direction{
.displaced_position_variation =
variation.displacement_variation,
.displacement_jacobian_variation =
variation.displacement_jacobian_variation
.displaced_position_variation = variation.displacement_variation,
.displacement_jacobian_variation = variation.displacement_jacobian_variation
};
// ReSharper disable once CppTooWideScopeInitStatement
const MappingStatus exterior_status =
m_exterior_map->EvaluateVariation(
exterior_input, workspace.m_exterior_result,
exterior_direction, workspace.m_exterior_variation
);
const MappingStatus exterior_status = m_exterior_map->EvaluateVariation(
exterior_input, workspace.m_exterior_result, exterior_direction, workspace.m_exterior_variation
);
if (exterior_status != MappingStatus::valid) {
return exterior_status;
}
variation.physical_position_variation =
workspace.m_exterior_variation.physical_position_variation;
variation.mapping_jacobian_variation =
workspace.m_exterior_variation.mapping_jacobian_variation;
variation.physical_position_variation = workspace.m_exterior_variation.physical_position_variation;
variation.mapping_jacobian_variation = workspace.m_exterior_variation.mapping_jacobian_variation;
} else {
variation.physical_position_variation =
variation.displacement_variation;
variation.mapping_jacobian_variation =
variation.displacement_jacobian_variation;
variation.physical_position_variation = variation.displacement_variation;
variation.mapping_jacobian_variation = variation.displacement_jacobian_variation;
}
mfem::Mult(
base_context.inverse_mapping_jacobian,
variation.mapping_jacobian_variation, workspace.m_matrix_temp_1
base_context.inverse_mapping_jacobian, variation.mapping_jacobian_variation, workspace.m_matrix_temp_1
);
double trace = 0.0;
for (int i = 0; i < m_options.dimension; ++i)
trace += workspace.m_matrix_temp_1(i, i);
variation.mapping_determinant_variation =
base_context.mapping_determinant * trace;
variation.mapping_determinant_variation = base_context.mapping_determinant * trace;
variation.inverse_mapping_jacobian_variation.SetSize(
m_options.dimension, m_options.dimension
);
variation.inverse_mapping_jacobian_variation.SetSize(m_options.dimension, m_options.dimension);
mfem::Mult(
workspace.m_matrix_temp_1, base_context.inverse_mapping_jacobian,
variation.inverse_mapping_jacobian_variation
@@ -795,34 +672,26 @@ namespace mean_field::mapping {
VolumeMappingVariation &variation
) const {
const MappingStatus point_status = EvaluatePointVariation(
element_data, direction, transformation, integration_point,
base_context.mapping, workspace, variation.mapping
element_data, direction, transformation, integration_point, base_context.mapping, workspace,
variation.mapping
);
if (point_status != MappingStatus::valid)
return point_status;
transformation.SetIntPoint(&integration_point);
mfem::Mult(
variation.mapping.mapping_jacobian_variation,
transformation.Jacobian(), workspace.m_full_element_jacobian
);
mfem::Mult(
base_context.quadrature.J_inv, workspace.m_full_element_jacobian,
workspace.m_matrix_temp_1
variation.mapping.mapping_jacobian_variation, transformation.Jacobian(), workspace.m_full_element_jacobian
);
mfem::Mult(base_context.quadrature.J_inv, workspace.m_full_element_jacobian, workspace.m_matrix_temp_1);
variation.inverse_element_jacobian_variation.SetSize(
m_options.dimension, m_options.dimension
);
variation.inverse_element_jacobian_variation.SetSize(m_options.dimension, m_options.dimension);
mfem::Mult(
workspace.m_matrix_temp_1, base_context.quadrature.J_inv,
variation.inverse_element_jacobian_variation
workspace.m_matrix_temp_1, base_context.quadrature.J_inv, variation.inverse_element_jacobian_variation
);
variation.inverse_element_jacobian_variation *= -1.0;
variation.weight_variation =
integration_point.weight * transformation.Weight() *
variation.mapping.mapping_determinant_variation;
integration_point.weight * transformation.Weight() * variation.mapping.mapping_determinant_variation;
if (!matrix_is_finite(variation.inverse_element_jacobian_variation) ||
!std::isfinite(variation.weight_variation))
@@ -842,30 +711,24 @@ namespace mean_field::mapping {
FaceMappingVariation &variation
) const {
transformation.SetAllIntPoints(&integration_point);
mfem::ElementTransformation &element_transformation =
SelectFaceElementTransformation(transformation, side);
mfem::ElementTransformation &element_transformation = SelectFaceElementTransformation(transformation, side);
const mfem::IntegrationPoint &element_integration_point =
SelectFaceElementIntegrationPoint(transformation, side);
const MappingStatus point_status = EvaluatePointVariation(
element_data, direction, element_transformation,
element_integration_point, base_context.mapping, workspace,
element_data, direction, element_transformation, element_integration_point, base_context.mapping, workspace,
variation.mapping
);
if (point_status != MappingStatus::valid)
return point_status;
workspace.m_reference_normal.SetSize(m_options.dimension);
mfem::CalcOrtho(
transformation.Jacobian(), workspace.m_reference_normal
);
mfem::CalcOrtho(transformation.Jacobian(), workspace.m_reference_normal);
if (side == FaceElementSide::element_2)
workspace.m_reference_normal *= -1.0;
const double reference_normal_magnitude =
workspace.m_reference_normal.Norml2();
if (!std::isfinite(reference_normal_magnitude) ||
reference_normal_magnitude <= 0.0)
const double reference_normal_magnitude = workspace.m_reference_normal.Norml2();
if (!std::isfinite(reference_normal_magnitude) || reference_normal_magnitude <= 0.0)
return MappingStatus::non_finite_result;
base_context.mapping.inverse_mapping_jacobian.MultTranspose(
@@ -878,32 +741,23 @@ namespace mean_field::mapping {
variation.mapping.inverse_mapping_jacobian_variation.MultTranspose(
workspace.m_reference_normal, variation.physical_normal_variation
);
variation.physical_normal_variation *=
base_context.mapping.mapping_determinant;
variation.physical_normal_variation *= base_context.mapping.mapping_determinant;
variation.physical_normal_variation.Add(
variation.mapping.mapping_determinant_variation,
workspace.m_vector_temp
variation.mapping.mapping_determinant_variation, workspace.m_vector_temp
);
const double mapped_normal_magnitude =
workspace.m_mapped_normal.Norml2();
if (!std::isfinite(mapped_normal_magnitude) ||
mapped_normal_magnitude <= 0.0)
const double mapped_normal_magnitude = workspace.m_mapped_normal.Norml2();
if (!std::isfinite(mapped_normal_magnitude) || mapped_normal_magnitude <= 0.0)
return MappingStatus::non_finite_result;
const double mapped_normal_magnitude_variation =
base_context.quadrature.normal *
variation.physical_normal_variation;
base_context.quadrature.normal * variation.physical_normal_variation;
variation.physical_normal_variation.Add(
-mapped_normal_magnitude_variation, base_context.quadrature.normal
);
variation.physical_normal_variation.Add(-mapped_normal_magnitude_variation, base_context.quadrature.normal);
variation.physical_normal_variation /= mapped_normal_magnitude;
variation.physical_surface_weight_variation =
integration_point.weight * mapped_normal_magnitude_variation;
variation.normal_flux_scale_variation =
mapped_normal_magnitude_variation / reference_normal_magnitude;
variation.physical_surface_weight_variation = integration_point.weight * mapped_normal_magnitude_variation;
variation.normal_flux_scale_variation = mapped_normal_magnitude_variation / reference_normal_magnitude;
if (!vector_is_finite(variation.physical_normal_variation) ||
!std::isfinite(variation.physical_surface_weight_variation) ||

View File

@@ -41,15 +41,12 @@ namespace mean_field::mapping {
mfem::Vector &physical_gradient
) {
MFEM_VERIFY(
reference_gradient.Size() ==
context.inverse_mapping_jacobian.Height(),
reference_gradient.Size() == context.inverse_mapping_jacobian.Height(),
"The reference scalar gradient has the wrong dimension."
);
physical_gradient.SetSize(reference_gradient.Size());
context.inverse_mapping_jacobian.MultTranspose(
reference_gradient, physical_gradient
);
context.inverse_mapping_jacobian.MultTranspose(reference_gradient, physical_gradient);
}
void MapPhysicalGradientToReference(
@@ -63,9 +60,7 @@ namespace mean_field::mapping {
);
reference_gradient.SetSize(physical_gradient.Size());
context.mapping_jacobian.MultTranspose(
physical_gradient, reference_gradient
);
context.mapping_jacobian.MultTranspose(physical_gradient, reference_gradient);
}
void MapReferenceVectorGradientToPhysical(
@@ -74,19 +69,12 @@ namespace mean_field::mapping {
mfem::DenseMatrix &physical_gradient
) {
MFEM_VERIFY(
reference_gradient.Width() ==
context.inverse_mapping_jacobian.Height(),
reference_gradient.Width() == context.inverse_mapping_jacobian.Height(),
"The reference vector gradient has the wrong dimension."
);
physical_gradient.SetSize(
reference_gradient.Height(),
context.inverse_mapping_jacobian.Width()
);
mfem::Mult(
reference_gradient, context.inverse_mapping_jacobian,
physical_gradient
);
physical_gradient.SetSize(reference_gradient.Height(), context.inverse_mapping_jacobian.Width());
mfem::Mult(reference_gradient, context.inverse_mapping_jacobian, physical_gradient);
}
void MapPhysicalVectorGradientToReference(
@@ -99,12 +87,8 @@ namespace mean_field::mapping {
"The physical vector gradient has the wrong dimension."
);
reference_gradient.SetSize(
physical_gradient.Height(), context.mapping_jacobian.Width()
);
mfem::Mult(
physical_gradient, context.mapping_jacobian, reference_gradient
);
reference_gradient.SetSize(physical_gradient.Height(), context.mapping_jacobian.Width());
mfem::Mult(physical_gradient, context.mapping_jacobian, reference_gradient);
}
double MapHDivDivergenceToPhysical(
@@ -120,19 +104,11 @@ namespace mean_field::mapping {
) {
const int dimension = context.mapping_jacobian.Height();
MFEM_VERIFY(
context.mapping_jacobian.Width() == dimension,
"The mapping Jacobian must be square."
);
MFEM_VERIFY(
context.mapping_determinant > 0.0,
"The mapping determinant must be positive."
);
MFEM_VERIFY(context.mapping_jacobian.Width() == dimension, "The mapping Jacobian must be square.");
MFEM_VERIFY(context.mapping_determinant > 0.0, "The mapping determinant must be positive.");
mass_tensor.SetSize(dimension, dimension);
mfem::MultAtB(
context.mapping_jacobian, context.mapping_jacobian, mass_tensor
);
mfem::MultAtB(context.mapping_jacobian, context.mapping_jacobian, mass_tensor);
mass_tensor *= 1 / context.mapping_determinant;
}
@@ -143,19 +119,12 @@ namespace mean_field::mapping {
const int dimension = context.inverse_mapping_jacobian.Height();
MFEM_VERIFY(
context.inverse_mapping_jacobian.Width() == dimension,
"The inverse mapping Jacobian must be square."
);
MFEM_VERIFY(
context.mapping_determinant > 0.0,
"The mapping determinant must be positive."
context.inverse_mapping_jacobian.Width() == dimension, "The inverse mapping Jacobian must be square."
);
MFEM_VERIFY(context.mapping_determinant > 0.0, "The mapping determinant must be positive.");
diffusion_tensor.SetSize(dimension, dimension);
mfem::MultABt(
context.inverse_mapping_jacobian, context.inverse_mapping_jacobian,
diffusion_tensor
);
mfem::MultABt(context.inverse_mapping_jacobian, context.inverse_mapping_jacobian, diffusion_tensor);
diffusion_tensor *= context.mapping_determinant;
}
@@ -170,9 +139,7 @@ namespace mean_field::mapping {
);
physical_field.SetSize(reference_field.Size());
context.inverse_mapping_jacobian.MultTranspose(
reference_field, physical_field
);
context.inverse_mapping_jacobian.MultTranspose(reference_field, physical_field);
}
void MapPhysicalFieldToHCurlReference(
@@ -239,35 +206,24 @@ namespace mean_field::mapping {
const MappingPointVariation &variation,
mfem::DenseMatrix &mass_tensor_variation
) {
const double determinant = context.mapping_determinant;
const double determinant_variation =
variation.mapping_determinant_variation;
const int dimension = context.inverse_mapping_jacobian.Width();
const double determinant = context.mapping_determinant;
const double determinant_variation = variation.mapping_determinant_variation;
const int dimension = context.inverse_mapping_jacobian.Width();
mass_tensor_variation.SetSize(dimension, dimension);
MFEM_VERIFY(
std::isfinite(determinant) && determinant > 0.0,
"The mapping determinant must be positive and finite."
);
MFEM_VERIFY(
std::isfinite(determinant_variation),
"The mapping determinant variation must be finite."
std::isfinite(determinant) && determinant > 0.0, "The mapping determinant must be positive and finite."
);
MFEM_VERIFY(std::isfinite(determinant_variation), "The mapping determinant variation must be finite.");
mfem::DenseMatrix determinant_correction(dimension, dimension);
ComputeHDivMassTensor(context, determinant_correction);
determinant_correction *= determinant_variation / determinant;
mfem::DenseMatrix right_jacobian_variation(dimension, dimension);
mfem::MultAtB(
context.mapping_jacobian, variation.mapping_jacobian_variation,
right_jacobian_variation
);
mfem::MultAtB(
variation.mapping_jacobian_variation, context.mapping_jacobian,
mass_tensor_variation
);
mfem::MultAtB(context.mapping_jacobian, variation.mapping_jacobian_variation, right_jacobian_variation);
mfem::MultAtB(variation.mapping_jacobian_variation, context.mapping_jacobian, mass_tensor_variation);
mass_tensor_variation += right_jacobian_variation;
mass_tensor_variation *= 1 / determinant;