Snapshot optimized solver and audit diagnostics before numerical experiments
This commit is contained in:
@@ -345,6 +345,11 @@ namespace mean_field::operators {
|
||||
}
|
||||
}
|
||||
|
||||
void PreparedMappedGravitySourceOperator::PrepareReference(const mfem::Vector &displacement) {
|
||||
auto result = TryPrepareImpl(displacement, PreparationMode::linearization, false);
|
||||
if (!result.has_value()) throwGravitySourcePreparationRejection(result.error());
|
||||
}
|
||||
|
||||
void PreparedMappedGravitySourceOperator::PreparePrimal(const mfem::Vector &displacement) {
|
||||
MEAN_FIELD_PROFILE_SCOPE_WARMUP("PreparedMappedGravitySourceOperator::Prepare primal", 0);
|
||||
auto result = TryPrepareImpl(displacement, PreparationMode::primal);
|
||||
@@ -366,7 +371,7 @@ namespace mean_field::operators {
|
||||
|
||||
GravitySourcePreparationResult PreparedMappedGravitySourceOperator::TryPrepareImpl(
|
||||
const mfem::Vector &displacement,
|
||||
const PreparationMode mode
|
||||
const PreparationMode mode, const bool useCachedMeshWeight
|
||||
) {
|
||||
MFEM_VERIFY(
|
||||
displacement.Size() == m_displacement_map.reduced_size(),
|
||||
@@ -513,7 +518,12 @@ namespace mean_field::operators {
|
||||
|
||||
transformation.SetIntPoint(&integration_point);
|
||||
|
||||
const double quadrature_value = integration_point.weight * transformation.Weight() * coefficient_value;
|
||||
// EvaluateVolume already cached the computational mesh geometry.
|
||||
// Resetting IntPoint above invalidates MFEM's local weight cache.
|
||||
const auto *fixed = useCachedMeshWeight ?
|
||||
m_domain_mapper.GetFixedMeshGeometry(transformation, integration_point) : nullptr;
|
||||
const double meshWeight = fixed ? fixed->weight : transformation.Weight();
|
||||
const double quadrature_value = integration_point.weight * meshWeight * coefficient_value;
|
||||
|
||||
if (!std::isfinite(quadrature_value) || quadrature_value <= 0.0) {
|
||||
localNonFiniteQuadrature = true;
|
||||
@@ -608,9 +618,27 @@ namespace mean_field::operators {
|
||||
}
|
||||
|
||||
void PreparedMappedGravitySourceOperator::MultDisplacementVariationTrue(
|
||||
const mfem::Vector &densityTrue,
|
||||
const mfem::Vector &displacementVariationTrue,
|
||||
const mfem::Vector &densityTrue, const mfem::Vector &displacementVariationTrue,
|
||||
mfem::Vector &actionVariationTrue
|
||||
) const {
|
||||
MultDisplacementVariationTrueImpl(densityTrue, displacementVariationTrue, actionVariationTrue, true);
|
||||
}
|
||||
void PreparedMappedGravitySourceOperator::MultDisplacementVariationTrueReference(
|
||||
const mfem::Vector &densityTrue, const mfem::Vector &displacementVariationTrue,
|
||||
mfem::Vector &actionVariationTrue
|
||||
) const {
|
||||
MultDisplacementVariationTrueImpl(densityTrue, displacementVariationTrue, actionVariationTrue, false);
|
||||
}
|
||||
int PreparedMappedGravitySourceOperator::GetTensorVariationElementCount() const noexcept {
|
||||
int count = 0;
|
||||
for (const auto &data : m_elements)
|
||||
count += data.displacement_reference && data.displacement_reference->HasTensorEvaluation3D();
|
||||
return count;
|
||||
}
|
||||
|
||||
void PreparedMappedGravitySourceOperator::MultDisplacementVariationTrueImpl(
|
||||
const mfem::Vector &densityTrue, const mfem::Vector &displacementVariationTrue,
|
||||
mfem::Vector &actionVariationTrue, const bool useTensorPath
|
||||
) const {
|
||||
MFEM_VERIFY(
|
||||
m_is_prepared,
|
||||
@@ -667,10 +695,15 @@ namespace mean_field::operators {
|
||||
|
||||
m_reference_displacement_jacobian.SetSize(dimension, dimension);
|
||||
m_quadrature_variation_action.SetSize(data.integration_rule->GetNPoints());
|
||||
data.GetDensityBasis().Mult(m_element_density, m_quadrature_variation_action);
|
||||
if (useTensorPath && data.density_reference && data.density_reference->HasTensorEvaluation3D())
|
||||
data.density_reference->EvaluateValuesTensor3D(m_element_density, m_quadrature_variation_action, m_tensorWorkspace);
|
||||
else data.GetDensityBasis().Mult(m_element_density, m_quadrature_variation_action);
|
||||
const bool tensor = useTensorPath && data.displacement_reference &&
|
||||
data.displacement_reference->HasTensorEvaluation3D();
|
||||
if (tensor) data.displacement_reference->EvaluateTensor3D(direction_dofs, m_tensorSamples, m_tensorWorkspace);
|
||||
|
||||
for (int quadrature_point = 0; quadrature_point < data.integration_rule->GetNPoints(); ++quadrature_point) {
|
||||
mfem::MultAtB(
|
||||
if (!tensor) mfem::MultAtB(
|
||||
direction_dofs, data.displacement_reference->GetGradients(quadrature_point),
|
||||
m_reference_displacement_jacobian
|
||||
);
|
||||
@@ -680,7 +713,8 @@ namespace mean_field::operators {
|
||||
for (int column = 0; column < dimension; ++column) {
|
||||
logarithmic_jacobian_variation +=
|
||||
data.inverse_element_jacobians(quadrature_point, row * dimension + column) *
|
||||
m_reference_displacement_jacobian(column, row);
|
||||
(tensor ? m_tensorSamples(quadrature_point, 4*column+row+1) :
|
||||
m_reference_displacement_jacobian(column, row));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -693,7 +727,9 @@ namespace mean_field::operators {
|
||||
}
|
||||
|
||||
m_element_variation_action.SetSize(data.potential_dofs.Size());
|
||||
data.GetPotentialBasis().MultTranspose(m_quadrature_variation_action, m_element_variation_action);
|
||||
if (useTensorPath && data.potential_reference && data.potential_reference->HasTensorEvaluation3D())
|
||||
data.potential_reference->ApplyTransposeTensor3D(m_quadrature_variation_action, m_element_variation_action, m_tensorWorkspace);
|
||||
else data.GetPotentialBasis().MultTranspose(m_quadrature_variation_action, m_element_variation_action);
|
||||
|
||||
if (data.potential_dof_transformation != nullptr) {
|
||||
data.potential_dof_transformation->TransformDual(m_element_variation_action);
|
||||
|
||||
Reference in New Issue
Block a user