Skip to content

[pull] develop from lammps:develop#160

Merged
pull[bot] merged 20 commits into
comphy-lab:developfrom
lammps:develop
Jul 1, 2026
Merged

[pull] develop from lammps:develop#160
pull[bot] merged 20 commits into
comphy-lab:developfrom
lammps:develop

Conversation

@pull

@pull pull Bot commented Jul 1, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

akohlmey and others added 20 commits June 13, 2026 18:50
Sphinx compares the cached build environment's configuration against a
freshly loaded conf.py *before* the builder-inited event, so config
values mutated in place at builder-inited can never match and the cache
is invalidated on every run:

- the sphinx c++ domain reverse-sorts cpp_index_common_prefix; since
  this is an 'env'-rebuild option, the order mismatch forced re-reading
  all ~1070 sources on every "make spelling".  List it pre-sorted.
- 'release' (also 'env'-rebuild) embeds "git describe", forcing a full
  re-read after every commit.  Freeze the git-derived strings for
  spelling builds, where they appear in no output.
- sphinx_tabs/sphinx_design insert generated paths into
  html_static_path, causing a spurious (but harmless) "The configuration
  has changed" message; restore the pristine value before the
  environment is pickled for builders that copy no static files.

Also give "make spelling" a dedicated doctree cache (the html/epub/pdf
builds use -E and sphinx-tabs writes builder-dependent doctrees), read
sources in parallel like "make html", clear stale per-document
.spelling reports the builder never removes, and strip the trailing
newline that get_git_commit() embedded in the html_context download URL.

Repeat spell checks now re-read only changed files.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
"exclude" is the established MD term for skipping pair interactions, and it
pairs naturally with the preceding "to be included". Moved here from the
bpm/peri port branch to keep that PR peri-focused.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ewald/disp ran its single reciprocal k-sum and the self-energy with g_ewald for
ALL interaction types, using g_ewald_6 only in the real-space pair (via extract)
and as a copy target (init: g_ewald_6 = g_ewald when not explicitly set). So
'kspace_modify gewald/disp <v>' pinned only the pair's dispersion damping while the
reciprocal+self kept the auto-estimated g_ewald, silently desyncing the Ewald
split: the total energy/pressure became g-dependent (wrong) with no error/warning.

Wire the dispersion (1/r^6) terms to use g_ewald_6 consistently:
  - coefficients(): dispersion func12 coeffs use eta2_6 = 0.25/g_ewald_6^2
  - init_self() / init_self_peratom(): 1/r^6 self uses g_ewald_6^3
  - rms(): the LJ kmax error term uses g_ewald_6
Coulomb (1/r) and dipole terms still use g_ewald.

When gewald/disp is not set, g_ewald_6 == g_ewald, so results are byte-identical to
before (verified across accuracy/cutoff). With the override, the reciprocal now
tracks g_ewald_6 and the total energy/pressure is g-independent, matching both the
'gewald' knob and pppm/disp (which already used a separate dispersion g).

Co-authored-by: Stan Moore <stanmoore1@gmail.com>
…bustness

Two fixes to the dispersion g_ewald selection in ewald/disp:

1. Real-space RMS force error estimate f() (LJ branch): replace the old erfc-based
   estimate (which under-predicts the true real-space force error by ~3-6x in bulk
   and ~10x at interfaces) with the corrected Kolafa-Perram / Isele-Holder Eq. 20.
   NOTE: the published Eq. 20 [Isele-Holder et al., JCP 137, 174107 (2012)] has a
   dimensional typo in the denominator (sqrt(N) V Rc); the dimensionally consistent
   form is sqrt(N V Rc).  The corrected estimate matches measured bulk RMS force
   errors to ~Kolafa-Perram accuracy (~1.6x), vs the old form's 3-6x under-prediction.

2. NewtonSolve(): the raw Newton step could overshoot to g<=0 at large cutoffs
   (where f is flat near the initial guess), abort, and silently fall back to the
   crude g=(1.35-0.15 ln acc)/rc.  Add damped/backtracking steps (halve until g>0).
   Now converges for all cutoffs (verified rcut 2.5-8: no fallback warnings,
   g*rcut smoothly monotonic instead of the previous dip-and-recover).

Co-authored-by: Stan Moore <stanmoore1@gmail.com>
The reciprocal LJ error estimate in rms() over-predicted the true reciprocal-space
RMS force error by ~300x (wrong km-dependence -- it grew like (pi km/g/prd + 1)
instead of decaying like 1/sqrt(km) -- and was missing the 1/sqrt(V) factor), so
ewald/disp used far more k-vectors than needed to reach a requested accuracy.

Re-derive from scratch (Kolafa-Perram / Deserno-Holm extended to r^-6): the
dispersion influence coefficient has the large-h asymptotic
  B(h) ~ 24 g^5 exp(-h^2/(4 g^2)) / h^2,
and summing |h B(h)|^2 |S(h)|^2 over neglected modes (h_max = 2 pi km/prd) gives
  dF_recip ~ (b2 g^6 / sqrt(N V)) sqrt(prd/(2 pi km)) exp(-pi^2 km^2/(g^2 prd^2)).
Verified numerically vs measured reciprocal force errors: correct scaling, ~2x
(Kolafa-Perram accuracy) vs the old ~300x.

End-to-end (bulk, with the real-space + Newton fixes): the actual total RMS force
error now tracks the requested accuracy (err/acc ~ 0.7-1.2 over 1e-3..1e-5) while
using ~20% fewer k-vectors.

Co-authored-by: Stan Moore <stanmoore1@gmail.com>
The same raw Newton-Raphson step that could overshoot the splitting parameter to
g <= 0 and fail (fixed for ewald/disp) is shared by the other automatic g_ewald
solvers: EwaldDipole::NewtonSolve, PPPMDipole::find_gewald_dipole,
PPPM::adjust_gewald, and PPPMDisp::adjust_gewald_6 (the Kokkos/electrode/spin
variants inherit these).  The x-form solvers abort to a crude fallback on g<0; the
adjust_gewald-form solvers hard-error 'Could not compute/adjust g_ewald'.

Apply the same damped/backtracking step (halve dx until g stays positive) plus a
zero/NaN-derivative guard.  No-op for the common case (verified: Coulomb pppm picks
an identical g_ewald and grid before/after); only changes behavior where the raw
step would otherwise leave the valid domain.

Survey of all Newton solvers in the tree (not just KSPACE): the SRD collision
solver (rtsafe bracket+bisection) and ASPHERE superellipsoid solver (regularized
fallback) are already robust; PTM polar decomposition and INTEL rsqrt refinement
are not root-finders of this kind.  GRANULAR MDR has an unbounded sqrt-domain
Newton that may merit a domain-specific bound, left to its maintainers.

Co-authored-by: Stan Moore <stanmoore1@gmail.com>
…-fix

Co-authored-by: Stan Moore <stanmoore1@gmail.com>
The base KSpace::modify_params parses mix/disp into the mixflag member
(0 = follow pair, 1 = geometric, 2 = none) and consumes the keyword, but
EwaldDisp::init() selected the dispersion mixing rule only from the pair
style's ewald_mix extract and never consulted mixflag.  As a result
kspace_modify mix/disp geom was silently ignored by ewald/disp (pppm/disp
already honors mixflag).

Have ewald/disp honor mixflag: 1 forces geometric, 0 (default) follows the
pair style's rule, and 2 (none) is rejected with a clear message -- ewald/disp
has no eigenvalue-splitting path (the none rule of pppm/disp).  Document the
ewald/disp behavior in kspace_modify.

Verified on a 2-type lj/long/coul/long (long off) box with pair_modify mix
arithmetic: mix/disp geom now forces geometric mixing (elong -3.218 -> -4.174,
previously identical to the default), mix/disp pair matches the default, and
mix/disp none errors cleanly.

Co-authored-by: Stan Moore <stanmoore1@gmail.com>
Adds kspace-ewald_disp_mixgeom.yaml: the same 2-type arithmetic-mixing
fourmol config as kspace-ewald_disp_arith.yaml but with kspace_modify
mix/disp geom, which forces geometric mixing in the reciprocal dispersion
sum.  The reference forces differ from the arithmetic ones at the ~1e-5
level (well above the 5e-12 tolerance), so the test pins the geometric
result and would catch a regression of the mix/disp override (e.g. the
keyword being silently ignored again).

Auto-discovered by the kspace-*.yaml glob in the force-styles CMakeLists.

Co-authored-by: Stan Moore <stanmoore1@gmail.com>
The dipole (spin) self-energy term in slabcorr() carried a 1/12 factor
on M_z^2, but the conjugate torque/force term uses -4*pi/V with no such
factor. This made the energy and the torque/force disagree by exactly
1/12, breaking torque = -dE/dtheta self-consistency.

Remove the erroneous 1/12 so the self term is E = (2pi/V) M_z^2, which is
consistent with the -4*pi/V field acting on the dipoles/spins. This is the
same fix applied upstream to PPPMDipole (#5059), now carried
over to EwaldDipole, EwaldDipoleSpin and PPPMDipoleSpin. The matching
per-atom energy prefactor is corrected as well.

Co-Authored-By: Stan Moore <stanmoore1@gmail.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S9FMNhdySkR3iAXXtdjbVN
Updates, corrections, and enhancements of the documentation
@pull pull Bot locked and limited conversation to collaborators Jul 1, 2026
@pull pull Bot added the ⤵️ pull label Jul 1, 2026
@pull pull Bot merged commit c1e3318 into comphy-lab:develop Jul 1, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants