Integrate polynomial feasibility with typed stellar enthalpy strategy

This commit is contained in:
2026-09-17 09:28:01 -04:00
parent 6628e237d3
commit 9e0e1bc42a
3 changed files with 215 additions and 2 deletions

View File

@@ -37,12 +37,16 @@ export namespace mean_field::solver {
};
enum class EnthalpyDirectionRepairStatus {
feasible, invalid_base, invalid_anchor, invalid_direction, unresolved
feasible, invalid_base, invalid_anchor, invalid_direction, unresolved, no_descent
};
struct EnthalpyDirectionRepairReport final {
EnthalpyDirectionRepairStatus status{EnthalpyDirectionRepairStatus::unresolved};
double minimumSafeFraction{1.0};
double chosenFraction{0.0};
double meritDirectionalDerivative{std::numeric_limits<double>::quiet_NaN()};
double linearModelResidualNorm{std::numeric_limits<double>::quiet_NaN()};
int jacobianApplications{0};
PolynomialSignReport base;
PolynomialSignReport anchor;
PolynomialSignReport candidate;
@@ -415,7 +419,17 @@ export namespace mean_field::solver {
if (report.base.status != PolynomialSignStatus::certified_nonnegative || !ZeroTrace(base)) {
report.status = EnthalpyDirectionRepairStatus::invalid_base; return report;
}
report.anchor = Check(anchor);
// The anchor can be reused only for identical coefficients. All
// ranks agree on the cache path before any later scatter/reduction.
bool cached = m_cachedAnchor.Size() == anchor.Size() && m_hasCachedAnchor;
if (cached)
for (int i = 0; i < anchor.Size(); ++i) cached = cached && m_cachedAnchor(i) == anchor(i);
if (enthalpy_detail::CollectiveMaximum(cached ? 0 : 1,m_space->GetComm())) {
m_cachedAnchorReport = Check(anchor);
m_cachedAnchor = anchor;
m_hasCachedAnchor = true;
}
report.anchor = m_cachedAnchorReport;
if (report.anchor.status != PolynomialSignStatus::certified_nonnegative || !ZeroTrace(anchor)) {
report.status = EnthalpyDirectionRepairStatus::invalid_anchor; return report;
}
@@ -504,5 +518,8 @@ export namespace mean_field::solver {
EnthalpyAdmissibilityOptions m_options;
std::map<std::pair<int,int>,std::unique_ptr<TensorBernsteinPolynomial<3>>> m_bases;
std::vector<ElementData> m_elements;
mutable mfem::Vector m_cachedAnchor;
mutable PolynomialSignReport m_cachedAnchorReport;
mutable bool m_hasCachedAnchor{false};
};
}