[pull] develop from lammps:develop#162
Merged
Merged
Conversation
…hreshold condition is met
Build out the granular DEM regression test infrastructure in
unittest/granular/ (modeled on unittest/force-styles/) and the first
test program, test_dem_01, covering MFiX-DEM VVUQ case DEM-01: a freely
falling particle bouncing off a wall.
Harness additions:
- Hybrid YAML model: a 'variables' block emitted as LAMMPS variables for
${var} substitution, plus command lists (pre_commands geometry,
pair_style/pair_coeff, post_commands fixes).
- Multi-segment capture: per-atom positions/velocities/torques/omega
recorded after each run segment as "segment tag x y z" rows.
- Optional analytic checks (test_analytic_models.{h,cpp}), opt-in per
YAML via analytic_enable/_model/_tol/_segment with parameters read from
the variables block; implements the 'freefall' model.
- EXPECT_OMEGA helper; segment-indexed config fields and readers.
test_dem_01 fixtures newton_on/newton_off compare against the same
recorded reference. Four reference YAMLs exercise gran/hooke (3d/si),
gran/hooke (2d/lj), gran/hooke/history, and the modular pair_style
granular with the new-syntax wall/gran. All pass; the freefall analytic
check is verified exact to ~1e-15 (velocity-Verlet integrates constant
acceleration exactly).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extract the common trajectory-comparison logic (init_lammps,
run_and_check, generate_yaml_file, run_dem_trajectory_test) into
test_dem_common.{h,cpp}, compiled into the granular_tests library, so
each test_dem_0N.cpp is reduced to its newton_on/newton_off TEST()
fixtures. This keeps all six DEM drivers in sync.
Add test_dem_02 (MFiX-DEM VVUQ case DEM-02: a particle bouncing
repeatedly off a wall) and a first reference dem02-hooke-3d-si.yaml that
captures several decaying bounces (restitution ~0.82). ctest -R DEM:
5/5 passing.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Implement the 'bounce_height' analytic model: the hard-sphere apex height after the k-th bounce, h_k = r + e^(2k) (h0 - r), evaluated from the free-flight state via energy conservation (apex = z + vz^2/2g) so the segment need not end exactly at the apex. Add DEM-02 reference YAMLs: - dem02-restitution-3d-si: pair_style granular with damping coeff_restitution (e=0.9) and a stiffer spring; the measured apex matches the hard-sphere prediction to ~0.8% (verified to fail at a 0.1% tolerance, pass at 1.5%). - dem02-hooke-2d-lj: 2d/lj multi-bounce variant. - dem02-hookehistory-3d-si: gran/hooke/history multi-bounce variant. ctest -R DEM: 8/8 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add test_dem_03 (MFiX-DEM VVUQ case DEM-03): two equal-mass spheres stacked in a narrow channel between two gran/hooke walls, held in continuous compression under gravity. Reference dem03-hooke-3d-si.yaml uses two create_atoms in a 3.6-radius channel; both particles remain in enduring contact and oscillate (verified bounded over 12000 steps). ctest -R DEM03 passes (newton on/off). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ge 3b/3d) dem03-unequal-3d-si: the actual MFiX DEM-03 setup with unequal densities (rho1=20000, rho2=10000 via two atom types); the lighter upper particle moves more, as expected from momentum exchange. dem03-granular-hooke-3d-si: same two-particle channel driven by the modular pair_style granular (hooke normal + coeff_restitution e=0.9), with the matching new-syntax wall/gran granular; energy visibly dissipates. ctest -R DEM03: 3/3 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Implement the 'stack_energy' analytic model: total mechanical energy (KE + gravitational PE + linear-spring contact PE for the floor, the particle pair, and the ceiling) of the two-particle stack, compared to the initial value. Masses and radii are read from the live simulation (atom->rmass/radius) so the check does not depend on reproducing the LAMMPS mass formula. dem03-elastic-3d-si uses pair_style granular hooke with coeff_restitution e=1.0 (no dissipation); total energy is conserved to ~3e-5 (symplectic integrator fluctuation), verified against a tight tolerance, with the test tolerance set to 5e-4. ctest -R DEM: 12/12 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add test_dem_04 (MFiX-DEM VVUQ case DEM-04): a sphere launched along +x with no spin on a frictional zplane wall; sliding friction decelerates translation and spins the sphere up until it rolls without slipping. Implement the 'slip_cessation' analytic model: after the slip-cessation time t_s = 2 u0/(7 mu g) the sphere rolls with u = 5 u0/7 and omega_y = u/r. dem04-hookehistory-3d-si starts the particle at the gravity-equilibrium overlap so the normal force is steady at mg; the steady-rolling segment matches the analytic to ~0.03% (vx) and ~0.07% (omega_y), checked with a 5e-3 tolerance. ctest -R DEM: 13/13 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dem04-hookehistory-mu02/mu10-3d-si: friction sweep (mu=0.2, 1.0). The steady rolling state u=5u0/7, omega=u/r is independent of mu (only the slip-cessation time t_s=2u0/(7 mu g) changes), so the same slip_cessation analytic applies with segment lengths scaled to clear t_s. dem04-granular-3d-si: modular pair_style granular with tangential linear_history + coeff_restitution. Tangential damping (gamma_t) is needed so the tangential spring settles to the no-slip state rather than ringing; with it the steady state matches the analytic to ~1e-6. ctest -R DEM: 16/16 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…age 5) Add test_dem_05 (MFiX-DEM VVUQ case DEM-05): a sphere strikes a flat wall obliquely (no gravity; controlled approach velocity), and the rebound velocity and friction-induced spin are captured. Implement the 'oblique_impact' analytic model for the gross-sliding regime: vz_out = en vz_in, vx_out = vx_in - mu(1+en) vz_in, omega_y = (5/2) mu(1+en) vz_in/r. Reference YAMLs: - dem05-granular-oblique-3d / -steep-3d: pair_style granular with coeff_restitution at grazing angles; matches the analytic to ~0.2%. - dem05-hookehistory-oblique-3d: classic linear spring-dashpot at 45 deg. - dem05-hertz-oblique-3d: Hertzian gran/hertz/history at 45 deg. The grazing cases use the (correct) modular granular model; the classic gran/hooke/history is kept to the representative 0-65 deg DEM-05 range where it is well behaved. ctest -R DEM: 20/20 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New GRANULAR-package fix applying a Reynolds-number-dependent drag force to finite-size spheres relative to a uniform background fluid: F = -1/2 Cd rho_g (pi r^2) |v_rel| v_rel, Cd = 24/Re (1 + 0.15 Re^0.687), Re = rho_g |v_rel| (2r)/mu_g reducing to Stokes drag 6 pi mu_g r v_rel at low Re. Optional 'velocity' keyword sets a uniform fluid velocity (e.g. an upward gas stream). Supports r-RESPA and minimization, mirroring fix viscous. Verified the force magnitude against the analytic Cd at Re=20. Includes doc page (with .. versionadded:: TBD), Commands_fix.rst entry, src/.gitignore entry, and spelling false-positives (Schiller, Naumann, Reynolds). Passes make check (only the expected pending-TBD tag). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add test_dem_06 (MFiX-DEM VVUQ case DEM-06): a single particle released from rest settling to its terminal velocity under gravity and fluid drag. Two analytic models in test_analytic_models.cpp: - terminal_velocity_linear: fix viscous (Stokes), v_term = m g / gamma; matches to ~1e-5. - terminal_velocity_schiller_naumann: the new fix viscous/nonlinear, terminal speed solved by bisection of m g = 1/2 Cd rho_g pi r^2 v^2; matches to ~4e-4 (Re ~ 115). References dem06-viscous-linear-3d and dem06-nonlinear-3d use a periodic box with pair_style none (no contacts). ctest -R DEM: 22/22 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extend the harness to finite-shape particles: capture per-atom angular momentum (seg_angmom, run_angmom block, EXPECT_ANGMOM) for atom styles that store atom->angmom (ellipsoid/superellipsoid), wired into the shared driver's generator and comparison. Ellipsoid atoms have angmom but no omega, so the existing per-quantity flag guards select the right fields automatically. Add dem05-superellipsoid-3d.yaml: two superellipsoid particles (pair_style granular/superellipsoid, fix nve/asphere) in an off-center collision. Momentum is conserved and the impact generates z-angular momentum on both particles; runs under newton on and off. Guarded by prerequisites (atom ellipsoid / pair granular/superellipsoid) so it skips cleanly without the ASPHERE package. ctest -R DEM: 23/23 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a "Tests for granular (DEM) models" section (before the tools-folder section) describing the unittest/granular suite: the six test_dem_01..06 programs and the MFiX-DEM cases they mirror, the hybrid YAML model (variables + command lists + multi-segment capture), the YAML key table, the quantities compared (pos/vel/torque/omega/angmom) under the newton on/off fixtures, the opt-in analytic models, and step-by-step instructions for adding a new reference YAML or a new test program (including the regenerate-in-place and atom-map caveats). Add spelling false-positives MFiX and VVUQ. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Following the merge of the fix wall/gran hooke/history energy-injection fix (constant tangential stiffness), regenerate the four DEM reference files whose frictional wall/gran hooke/history trajectories changed: the three DEM-04 slip-to-roll cases and the DEM-05 oblique-impact case. The slip_cessation analytic checks still pass, confirming the no-slip rolling limit (kt-independent) is preserved; only the trajectory details shifted. Add a regression test for the bugfix: dem05-hookehistory-grazing-3d.yaml is a grazing (~76 deg) oblique wall impact with friction -- the exact scenario that previously gained energy. It uses a new 'energy_dissipation' analytic model that asserts the post-collision total (translational + rotational) kinetic energy does not exceed the incoming energy. With the fix the rebound is dissipative (vx 4.0 -> 3.05); before the fix it gained energy (vx -> ~4.6). ctest -R DEM: 24/24 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add test_dem_07, a rolling-resistance test inspired by Sim C of Mohajeri, Coetzee & Schott, Powder Technology 447 (2024). A sphere spinning in place on a frictional wall (no tangential friction, so the rolling-resistance model is isolated) is damped only by the SDS rolling torque M = mu_r R N (N = m g), giving a linear spin-down omega_y(t) = omega0 - (5 mu_r g)/(2 R) t. New analytic model 'rolling_decay' verifies this rate; measured torque (-mu_r R m g) and decay match to the half-step startup offset (~0.5 |domega/dt| dt). References dem07-rolling-3d-si plus a mu_r sweep (0.05, 0.2). ctest -R DEM: 27/27 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add test_dem_08 for cohesive/adhesive contact. LAMMPS has no EEPA model (used by Mohajeri, Coetzee & Schott, Powder Technology 447 (2024)), so the DMT and JKR cohesive normal models are exercised instead. New analytic model 'pulloff_dmt' verifies the DMT pull-off force F = 4*pi*gamma*R_eff by holding a sphere at near-zero overlap and reading the static normal force: dem08-dmt-wall-3d (R_eff = R) and dem08-dmt-twosphere-3d (R_eff = R/2) match the closed form to ~3e-7. dem08-jkr-twosphere-3d is a JKR cohesive two-sphere collision (regression only; JKR rejects coeff_restitution damping, so the default viscoelastic damping is used). ctest -R DEM: 30/30 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add test_dem_09 for particle-particle (not wall) collisions, mirroring Sim A (normal) and Sim B (shear) of Mohajeri, Coetzee & Schott, Powder Technology 447 (2024), complementing the wall-based DEM-05. New analytic model 'collision_restitution': for a head-on collision of two equal spheres at +/- vin it checks total x-momentum conservation and that the relative normal speed reverses with coefficient e (dem09-normal-3d, e=0.9, matched to ~1e-3). dem09-shear-3d is an oblique collision (y-offset) that generates spin and lateral deflection via tangential friction (regression). ctest -R DEM: 32/32 passing. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…d check
Stage 10a of the granular/DEM test suite covers bulk behaviour that the
single/two-particle DEM-01..09 cases do not exercise. It ships two
complementary tests driven by the shared test_dem_10 driver:
* dem10-settle-spheres-3d.yaml -- a short (1200-step) 18-sphere lattice
block settling onto a wall/gran floor under gravity with friction and
rolling resistance. The contact phase is brief, so the trajectory is
bit-reproducible and newton-invariant (eps 5e-9): a deterministic
regression for the many-simultaneous-contact code path.
* dem10-aor-spheres-3d.yaml -- a seeded fix pour deposits 120 spheres into
a confined heap; the angle_of_repose analytic model asserts the measured
slope lands in a [15,55] deg band. An 85k-step pour is chaotic and NOT
bit-reproducible across newton on/off or platforms, so only the bulk
angle is robust.
New harness flag analytic_only: yes -- the generator then records no
per-atom run_pos/run_vel/... blocks and run_and_check runs only the
analytic model, so chaotic bulk tests are validated by their bulk
observable rather than an unstable per-atom trajectory. Wired through
test_config.h, test_config_reader.{h,cpp}, and test_dem_common.cpp.
ctest -R DEM = 34/34.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A regular-tetrahedron 4-sphere rigid clump (tests/clump_tetra.mol) drops
onto a wall/gran floor and bounces, integrated by fix rigid/small. This
exercises granular contact forces acting on a multi-sphere rigid body --
the P2 (Saomoto et al.) clump regime. A single clump with few contacts
stays bit-reproducible and newton-invariant through the contact phase
(eps 5e-9), so it is a deterministic regression (unlike the chaotic
bulk pour in dem10-aor).
Notes:
* fix rigid/small molecule needs molecule IDs, so the system uses
atom_style hybrid sphere molecular (sphere supplies radius/omega for
the granular pair, molecular supplies the molecule ID for the body).
* thermo_style is set to "custom step atoms" to avoid the default
thermo_temp compute, which reports negative DOF when every sphere is
bound in a rigid body (rotational DOF removed by the body but not
counted by the translational-only temperature). This is a thermo
accounting detail only; the dynamics are unaffected.
* the molecule file is referenced via the harness-provided ${input_dir}.
ctest -R DEM = 35/35.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Extend the "Tests for granular (DEM) models" developer section to list test_dem_07..10 (rolling resistance, cohesion, two-sphere collisions, bulk angle of repose + clumps), the new analytic models (rolling_decay, pulloff_dmt, collision_restitution, angle_of_repose), and the analytic_only YAML flag for chaotic bulk tests whose per-atom trajectory is not bit-reproducible but whose bulk observable is. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- fix.rst: add the missing :doc:`viscous/nonlinear` entry to the alphabetical fix overview list (it was only in Commands_fix.rst). - Developer_unittest.rst: cite the source publications for the DEM test cases -- Garg et al., Powder Technology 220 (2012) for the MFiX-DEM verification cases DEM-01..06 (the recommended citation, replacing the bare VVUQ-manual web link), Mohajeri et al., Powder Technology 447 (2024) for the rolling-resistance / cohesion / two-particle cases (test_dem_07..09), and Saomoto et al., Soils and Foundations 63 (2023) for the angle-of-repose / clump cases (test_dem_10). Also code-format the analytic model names in the models table. - false_positives.txt: add the author surnames and CTest. Docs build clean (html + spelling). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The reference-review doubt about the m selector was documentation-driven: the bond/angle selection code is already bit-for-bit equivalent to fix shake (both constrain a bond when both atoms are in the group and either endpoint matches the b/t/m criteria, with the same MASSDELTA=0.1 mass tolerance). Only the wording differed. Mirror fix shake's phrasing and state the identity explicitly so the two pages no longer read as if the selection could differ. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YNvuaNpJNkbCKaAE8ngPQv
Addresses review feedback on PR #5052: Memory::destroy()/sfree() are nullptr-safe by design and LAMMPS initializes pointers to nullptr precisely so the base Atom destructor can call them unconditionally. The Kokkos-specific `if (ivector)`/`if (dvector)` guards added for the custom-data port are therefore the wrong approach. Instead, ~AtomKokkos now frees the contiguous k_ivector/k_dvector view data and nulls the legacy ivector[i]/dvector[i] aliases (which point into those views), while leaving the row-pointer arrays in place. The base Atom destructor then memory->destroy()s the (nulled) aliases as a no-op and sfree()s the row-pointer arrays via the standard nullptr-safe path -- the same way iarray/darray are already handled. Both `// (needed for Kokkos)` guards are removed from src/atom.cpp. 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_01Mcx726FjBq6xZFFoyJX6Cg
…traints The ILVES solver converged only linearly (~14-30 Newton iterations) on long constraint clusters in periodic boxes, instead of the near-quadratic ~2-4 iterations the algorithm should give. Root cause: the constraint graph keyed its nodes by raw atom index. A bond (or angle A-C virtual bond) that wraps a periodic boundary has a ghost partner, so the atom and its own ghost image became two separate graph nodes -- the cluster graph fragmented at every wrap point, silently degrading the exact sparse direct solve into a slow block-Jacobi sweep (linear, period-2 convergence that scaled with the number of wraps and the cluster diameter). Give each constraint atom two identities: a GEOMETRY index (the nearest periodic image, from Domain::closest_image, used for the bond vector -- correct at any box size, no minimum-image box-size restriction) and a canonical NODE index (the owner, from atom->map(atom->tag[...]), so an atom and its ghost image are a single graph node and a wrapped bond stays a single edge). The molecule builds its atom/bond graph and Ilves::make_weights detects the shared atom from the node ids; Ilves::make_rhs and accumulate_increment use the geometry indices. Non-wrapping constraints are unaffected (node == geometry). Also fix a latent bug in FixIlves::find_bond_type: a flanking bond stored (newton_bond on) only at a ghost outer angle atom was never found, silently dropping angles that wrap a boundary. Resolve both endpoints to their canonical owner (atom->map(atom->tag[...])) before scanning the bond lists. Verified: wrapped and unwrapped runs are now bit-identical (bond chains and rigid-water bond+angle systems), results are rank-independent to machine precision on 1/2/4 MPI ranks, and the cg-polymers and polymelt example benchmarks converge in 1 Newton iteration instead of ~14 and ~30. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YNvuaNpJNkbCKaAE8ngPQv
Addresses the two cleanup notes from the ILVES algorithm authors' review of PR #5054; both are internal-only and bit-identical. 1. Replace the ported GROMACS growing memory pool and its STL allocator (ilves_mempool.h) with std::pmr::monotonic_buffer_resource and std::pmr::polymorphic_allocator. The custom pool was exactly a monotonic bump arena (append-only, no-op deallocate, free-all at destruction), which is what the C++17 standard resource provides -- so this is a drop-in with the same allocation strategy. (The earlier "std::allocator is ~35% slower on the solver-rebuild path" measurement does not apply here: that was the general-purpose allocator; pmr keeps the bump-arena behavior.) Deletes ilves_mempool.h. 2. Modernize the Ilves and Molecule constructors from the GROMACS-style raw pointer interface (const int *, const double *) to const std::vector<> & references, and drop the now-redundant explicit constraint count (taken from catom1.size()). The inverse-mass vector is still borrowed (the Molecule keeps a data() pointer into the caller-owned vector). Verified bit-identical: the rigid-water thermo matches the pre-change binary to full %.16e precision, np=1 == np=4, and the cg-polymers / polymelt benchmarks still converge in 1 Newton iteration. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YNvuaNpJNkbCKaAE8ngPQv
Add YAML-driven granular/DEM test suite and fix viscous/nonlinear
Fix a batch of Coverity Scan static analysis defects
Add fix ilves: ILVES bond and angle constraint solver (port of the GROMACS implementation)
The Coverity Scan workflow hardcoded the project name "LAMMPS" in three places (tool download, md5 fetch, results upload). Route all three through a workflow-level env var sourced from an optional COVERITY_PROJECT repository variable, falling back to "LAMMPS" when unset, so switching to a new Scan project (e.g. after an admin/ownership change) is a settings-only change with no code edit. A variable rather than a secret is used on purpose: the project name is public, and secrets would be masked as *** in the Actions logs, making the upload URL unreadable. Make the offline triage exporter project-agnostic as well: the "traces" subcommand no longer defaults --project-id to the retired project id 16404. It now derives the projectId from the project_id already recorded in the --cids-from grid export written by the "defects" subcommand, and requires an explicit --project-id only when the grid does not carry one. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01YNvuaNpJNkbCKaAE8ngPQv
Add support for charge-dipole interaction with PPPM
KOKKOS: extend `fix property/atom/kk` to `ivector/iarray/darray` custom types
Improve force style tests for multi-precision KOKKOS support with GPU, Serial, and OpenMP backend
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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 : )