Expose cached gravity target for prepared trial verification

This commit is contained in:
2026-09-17 09:39:39 -04:00
parent 5e03188816
commit 237485de51
2 changed files with 42 additions and 22 deletions

View File

@@ -561,6 +561,23 @@ export namespace mean_field::solver {
return m_baseGeneration;
}
void BuildLinearPrediction(
const double alpha,
mfem::Vector &gravityResidual
) const {
RequireCollectively(
m_hasBase && gravityResidual.Size() == m_baseResidual.Size(),
"A gravity prediction requires a captured base and a preallocated gravity residual."
);
RequireStepLength(alpha);
bool finite = true;
for (int index = 0; index < gravityResidual.Size(); ++index) {
gravityResidual(index) = m_baseResidual(index) + alpha * m_baseAction(index);
finite = finite && std::isfinite(gravityResidual(index));
}
RequireCollectively(finite, "The captured gravity linear prediction is nonfinite.");
}
// The caller owns candidate preparation and commits only after a new
// complete residual evaluation. A failed inner solve never modifies
// an accepted state; its output remains a diagnostic correction only.
@@ -572,29 +589,12 @@ export namespace mean_field::solver {
) {
const auto &partition = m_subsystem->GetPartition();
RequireCollectively(
m_hasBase && m_subsystem->IsCurrent() && std::isfinite(alpha) && alpha >= 0.0 &&
trialResidual.Size() == partition.RootResidualSize() &&
m_hasBase && m_subsystem->IsCurrent() && trialResidual.Size() == partition.RootResidualSize() &&
gravityCorrection.Size() == partition.GravityValueSize(),
"Gravity curvature correction requires a captured base, a current "
"candidate, and valid vectors."
);
double minimumAlpha = 0.0;
double maximumAlpha = 0.0;
if (MPI_Allreduce(&alpha, &minimumAlpha, 1, MPI_DOUBLE, MPI_MIN, m_subsystem->GetCommunicator()) !=
MPI_SUCCESS ||
MPI_Allreduce(&alpha, &maximumAlpha, 1, MPI_DOUBLE, MPI_MAX, m_subsystem->GetCommunicator()) !=
MPI_SUCCESS) {
throw std::runtime_error(
"Gravity curvature correction could not verify "
"its distributed step length."
);
}
if (minimumAlpha != maximumAlpha) {
throw std::invalid_argument(
"Gravity curvature correction requires the "
"same step length on every rank."
);
}
RequireStepLength(alpha);
partition.GatherGravityResiduals(trialResidual, m_rightHandSide);
for (int index = 0; index < m_rightHandSide.Size(); ++index) {
m_rightHandSide(index) = m_baseResidual(index) + alpha * m_baseAction(index) - m_rightHandSide(index);
@@ -604,6 +604,23 @@ export namespace mean_field::solver {
}
private:
void RequireStepLength(const double alpha) const {
RequireCollectively(
std::isfinite(alpha) && alpha >= 0.0, "Gravity curvature requires a finite, non-negative step length."
);
double minimumAlpha = 0.0;
double maximumAlpha = 0.0;
if (MPI_Allreduce(&alpha, &minimumAlpha, 1, MPI_DOUBLE, MPI_MIN, m_subsystem->GetCommunicator()) !=
MPI_SUCCESS ||
MPI_Allreduce(&alpha, &maximumAlpha, 1, MPI_DOUBLE, MPI_MAX, m_subsystem->GetCommunicator()) !=
MPI_SUCCESS) {
throw std::runtime_error("Gravity curvature could not verify its distributed step length.");
}
if (minimumAlpha != maximumAlpha) {
throw std::invalid_argument("Gravity curvature requires the same step length on every rank.");
}
}
void RequireCollectively(
const bool valid,
const char *message