dem_granular 0.1.3

Granular physics for MDDEM: Hertz normal contact, Mindlin tangential friction, rotational dynamics
Documentation
//! DEM granular contact models: Hertz normal, Mindlin tangential, and rotational dynamics.

pub mod granular_temp;
pub mod normal;
pub mod rotational;
pub mod tangential;

pub use granular_temp::GranularTempPlugin;
pub use normal::HertzNormalForcePlugin;
pub use rotational::RotationalDynamicsPlugin;
pub use tangential::MindlinTangentialForcePlugin;

pub mod contact;

use mddem_app::prelude::*;

use dem_atom::DemAtomPlugin;
use dem_atom_insert::DemAtomInsertPlugin;

pub use contact::HertzMindlinContactPlugin;

/// √(5/3) — viscoelastic damping coefficient
pub const SQRT_5_3: f64 = 0.9128709291752768;
/// Epsilon to avoid division by zero in tangential force
pub const TANGENTIAL_EPSILON: f64 = 1e-30;
/// Large overlap warning threshold (ratio of distance to sum of radii)
pub const LARGE_OVERLAP_WARN_THRESHOLD: f64 = 0.90;
/// Max overlap warnings per step before panic
pub const MAX_OVERLAP_WARNINGS: usize = 100;

/// Default DEM granular physics plugin group.
///
/// Includes, in registration order:
/// - [`DemAtomPlugin`] — per-atom material properties (radius, density) and
///   `MaterialTable` for per-material Young's modulus, Poisson ratio, restitution,
///   friction with geometric-mean mixing
/// - [`DemAtomInsertPlugin`] — random particle insertion from `[[particles.insert]]` config
/// - [`HertzNormalForcePlugin`] — Hertz elastic contact + viscoelastic normal damping
/// - [`MindlinTangentialForcePlugin`] — Mindlin spring-history tangential force with
///   Coulomb friction cap and torque accumulation; ordered after Hertz via `.after("hertz_normal")`
/// - [`RotationalDynamicsPlugin`] — quaternion Velocity Verlet for angular degrees of freedom
///   (I = 2/5 m r² for solid spheres)
/// - [`GranularTempPlugin`] — granular temperature output to file
///
/// Does **not** include infrastructure plugins (input, comm, domain, neighbor,
/// run, verlet, print). Use [`CorePlugins`] to get all infrastructure.
///
/// # Usage
/// ```rust,ignore
/// use mddem::prelude::*;
///
/// let mut app = App::new();
/// app.add_plugins(CorePlugins).add_plugins(GranularDefaultPlugins);
/// app.start();
/// ```
pub struct GranularDefaultPlugins;

impl PluginGroup for GranularDefaultPlugins {
    fn build(self) -> PluginGroupBuilder {
        PluginGroupBuilder::start::<Self>()
            .add(DemAtomPlugin)
            .add(DemAtomInsertPlugin)
            .add(HertzMindlinContactPlugin)
            .add(RotationalDynamicsPlugin)
            .add(GranularTempPlugin)
    }
}