jaxdem.utils.particleCreation#
Utility functions for creating states of GA particles (rigid/DP).
Functions
|
Catch-all builder: polydisperse GA/DP particles at a target packing fraction. |
|
Catch-all builder for a polydisperse sphere packing at a target phi. |
|
Build a |
|
Build a |
|
Build a |
|
Randomly distribute each body's centroid in a box sized for |
|
Per-body surface mask: |
- jaxdem.utils.particleCreation.create_sphere_state(radii: float | Sequence[float] | ndarray | Array, dim: int, *, pos: Sequence[Sequence[float]] | ndarray | Array | None = None, mass: float | Sequence[float] | ndarray | Array = 1.0) State[source]#
Build a
StateofNsimple spheres.No Thomson mesh, no Monte-Carlo union-property integration — this is the lightweight sphere primitive. Each sphere is a single-particle body with its own
clump_id; inertia defaults to the solid-disk (2D) / solid-sphere (3D) formula from the given mass and radius (handled insideState.create()).- Parameters:
radii – Scalar or length-
Nper-sphere radii.dim – Spatial dimension (2 or 3).
pos – Optional
(N, dim)centers. IfNone, all spheres are stacked at the origin (handy for a single tracer).mass – Scalar or length-
Nper-sphere masses. Default1.0.
- jaxdem.utils.particleCreation.create_ga_state(N: int, nv: int, dim: int, particle_radius: float, asperity_radius: float, *, particle_type: str = 'clump', core_type: str = 'hollow', aspect_ratio: float | Sequence[float] | None = None, particle_mass: float = 1.0, n_samples: int = 10000000, seed: int | None = None, mesh_type: str = 'thomson', mesh_kwargs: dict[str, Any] | None = None, asperity_dispersity_type: str = 'constant', asperity_dispersity_kwargs: dict[str, Any] | None = None) State[source]#
Build a
StateofNgeometric-asperity bodies.Surface asperities are placed on a unit shape (set by
mesh_type) and an optional central core sphere is added. The union of asperities (and, if present, the core) defines the body volume that the rigid-body / deformable-body properties are derived from.- Parameters:
particle_type ({"clump", "dp"}) – “clump” produces rigid bodies with a computed COM / principal-axis orientation / inertia. “dp” produces deformable particles whose nodes share a common
bond_idand each carry an equal share of the body mass and union volume. “sphere”-like bodies are thenv = 1degenerate case of “clump”.core_type ({"hollow", "solid", "phantom"}) – “hollow” uses only the surface asperities. “solid” adds a central core sphere that is kept in the final state. “phantom” adds the core only for the property calculation and strips it from the returned state.
mesh_type ({"thomson", "icosphere", "fibonacci", "torus", "helix", "arclength", "faceted"}) –
How asperity positions are generated on the unit shape.
"thomson"(default): generalized Thomson problem on a hyper-ellipsoid (Riesz-energy minimization). Stochastic, near-uniform result seeded byseed."icosphere": recursive icosahedron subdivision (3D) or regular polygon (2D); deterministic;nvmust be a valid icosphere count."fibonacci": golden-angle spiral sphere / evenly-spaced circle; deterministic; anynv."torus": 3D genus-1 torus surface."helix": 3D chiral helix / 2D Archimedean spiral."arclength": 2D only — equal arc-length spacing on the ellipse/circle perimeter. Closed-form analogue of the converged Thomson ground state in 2D; deterministic, anynv."faceted": regular polygon (2D) or icosahedron (3D) with vertex asperities + face/edge-interior fillers. Produces genuinely angular (flat-faced, sharp-cornered) particles rather than smooth spheres.
mesh_kwargs (dict, optional) – Mesh-specific keyword arguments forwarded to the underlying generator. See each generator in
jaxdem.utils.meshesfor accepted keys. Examples:{"steps": 5_000, "alpha": 1.0}(thomson — defaults tosteps=10_000);{"tube_ratio": 0.25}(torus);{"n_turns": 3, "helix_radius": 0.3}(helix);{"n_facets": 8}(faceted, 2D only).asperity_dispersity_type ({"constant", "bidisperse", "uniform", "truncated_gaussian"}) – How asperity radii are drawn. Every distribution is parameterized so its theoretical mean is
asperity_radius, which keepscore_radius = particle_radius - asperity_radiusdeterministic across runs and dispersity settings — only the asperity-to-asperity variation changes. With dispersity, the largest asperities naturally protrude beyondparticle_radiusand the smallest recede; this is by design. See_generate_disperse_asperity_radii()for the per-distribution sampling formulas.asperity_dispersity_kwargs (dict, optional) – Distribution-specific parameters. Defaults:
{}(no effect for"constant");{"size_ratio": 1.4, "fraction_small": 0.5}for"bidisperse";{"size_ratio": 2.0}for"uniform";{"cv": 0.2, "n_sigma": 2.5}for"truncated_gaussian"(wherecv = std / meanandcv * n_sigmamust be< 1to keep radii positive).
- jaxdem.utils.particleCreation.distribute_bodies(state: State, phi: float, *, domain_type: str = 'periodic', box_aspect: Sequence[float] | None = None, seed: int | None = None, max_avg_pe: float | None = 1e-16, randomize_orientation: bool = True, group_by: str = 'auto', collider_type: str = 'naive') tuple[State, Array][source]#
Randomly distribute each body’s centroid in a box sized for
phi.For each body in
state(sphere, rigid clump, or deformable particle), build a bounding sphere from its centroid and the max|node - centroid| + rad. Place those bounding spheres uniformly at random in a periodic (or reflective) box sized to the target packing fraction, FIRE-minimize so nothing overlaps, and translate every body so its centroid lands at the minimized bounding-sphere center. Optionally apply a uniformly random per-body rotation.Note that
phihere is the bounding-sphere packing fraction, not the true body packing fraction (which is lower for non-convex clumps / DPs). The target box volume issum(bounding_sphere_volume) / phi.- Parameters:
state – Input state containing one or more bodies. Body grouping is inferred from
clump_id/bond_id; usegroup_byto force one.phi – Target bounding-sphere packing fraction. Must be in (0, 1).
domain_type –
"periodic"or"reflect"for the analogue sphere minimization domain.box_aspect – Aspect ratios for the box, shape
(dim,). Defaults to isotropic.seed – RNG seed for both the initial random centroid placement and the per-body rotation. Drawn randomly if
None.max_avg_pe – Convergence tolerance for the FIRE minimizer.
randomize_orientation – If
True, apply a uniformly-random per-body rotation after placement.group_by –
"auto"(default),"clump", or"bond". See_resolve_body_grouping().collider_type – Collider for the analogue sphere minimization,
"naive"or"celllist".
- Returns:
The input state with per-body translation and (optionally) per-body random orientation applied, and the periodic box size vector.
- Return type:
- jaxdem.utils.particleCreation.ga_surface_mask(state: State, *, group_by: str = 'bond') Array[source]#
Per-body surface mask:
Trueiff the node lies on the convex hull of its body.For each body, runs
scipy.spatial.ConvexHullon the body’s node positions and flags the hull vertices as surface. Bodies with too few nodes to form a hull (<= dim + 1) or that trigger a Qhull numerical failure are treated conservatively — all their nodes marked surface.Exact for convex (or near-convex) bodies: a node is interior iff it lies strictly inside the convex hull of its body. For Thomson-mesh asperity bodies the surface vs. core separation is unambiguous. Non-convex bodies with concave pockets can misclassify pocket nodes as interior (they sit off the global hull).
- Parameters:
state – State with one or more bodies.
group_by –
"auto"(default),"clump", or"bond"— see_resolve_body_grouping().
- Returns:
(N,)bool mask,Truefor surface nodes.- Return type:
jax.Array
- jaxdem.utils.particleCreation.create_dp_container(state: State, *, em: float | Array | None = None, ec: float | Array | None = None, eb: float | Array | None = None, el: float | Array | None = None, gamma: float | Array | None = None, tau_s: float | Array | None = None, plasticity_type: Literal['edge', 'perimeter', 'bending', 'none', None] = None, group_by: str = 'bond', is_surface: Array | None = None, interior_edges: str | int = 'fan') Any[source]#
Build a
DeformableParticleModel(or a plastic variant) from a DP state.For each body (grouped by
group_by) the surface topology is computed from the node positions: polar-angle-ordered polygon segments in 2D, orscipy.spatial.ConvexHulltriangulation in 3D. Interior nodes (those flaggedFalseinis_surface) are wired to surface nodes as extraedgescarrying the body’selcoefficient; they never participate in surfaceelements/element_adjacency/initial_bendings.Energy coefficients (
em, ec, eb, el, gamma) are per-body scalars or per-body arrays of shape(n_bodies,), matching the existinggenerate_ga_deformable_stateconvention. Ifplasticity_typeis given,tau_sis required and interpreted per-body (perimeter), per- edge (edge), or per-adjacency (bending) as appropriate.- Parameters:
state – State whose nodes make up one or more DPs. Typically produced by
create_ga_state(..., particle_type="dp")and optionally placed viadistribute_bodies.em – Per-body elastic coefficients;
Nonedisables the term.ec – Per-body elastic coefficients;
Nonedisables the term.eb – Per-body elastic coefficients;
Nonedisables the term.el – Per-body elastic coefficients;
Nonedisables the term.gamma – Per-body elastic coefficients;
Nonedisables the term.tau_s – Per-body plastic yield threshold; required whenever
plasticity_typeis notNone.plasticity_type – One of
"edge","perimeter","bending", orNone/"none"for the elastic container.group_by – Body grouping for topology; default
"bond".is_surface – Optional
(N,)bool mask of surface nodes. WhenNone(the default) the mask is computed automatically viaga_surface_mask()(per-body convex hull), which is correct for hollow, solid, and phantom core-type DPs fromcreate_ga_state()and for any other approximately-convex body. Pass an explicit mask to override — useful for non-convex bodies where the convex-hull test would misclassify pocket nodes.interior_edges – How to connect interior nodes to surface nodes.
"fan"(default) connects every interior node to every surface node in its body. AnintK connects each interior node to itsKnearest surface nodes.
- Return type:
DeformableParticleModel or one of its plastic subclasses.
- jaxdem.utils.particleCreation.build_ga_system(particle_radii: Sequence[float] | ndarray, vertex_counts: Sequence[int] | ndarray, asperity_radius: float | Sequence[float] | ndarray, phi: float, dim: int, *, particle_type: str = 'clump', core_type: str = 'hollow', aspect_ratio: Any = None, particle_mass: float | Sequence[float] = 1.0, n_property_samples: int = 1000000, mesh_type: str = 'thomson', mesh_kwargs: dict[str, Any] | None = None, asperity_dispersity_type: str = 'constant', asperity_dispersity_kwargs: dict[str, Any] | None = None, domain_type: str = 'periodic', box_aspect: Sequence[float] | None = None, randomize_orientation: bool = True, compression_step: float = 0.001, compression_pe_tol: float = 1e-16, compression_pe_diff_tol: float = 1e-16, max_n_min_steps_per_outer: int = 200000, compression_progress: bool = False, dt: float = 0.001, linear_integrator_type: str = 'verlet', rotation_integrator_type: str = 'verletspiral', force_model_type: str = 'spring', collider_type: str = 'neighborlist', collider_kw: dict[str, Any] | None = None, minimizer: Any = None, minimizer_kw: dict[str, Any] | None = None, target_fn: Any = None, mat_table: Any = None, e_int: float = 1.0, material_type: str = 'elastic', material_kwargs: dict[str, Any] | None = None, matcher_type: str = 'harmonic', matcher_kwargs: dict[str, Any] | None = None, dp_em: float | None = 1.0, dp_ec: float | None = 1.0, dp_eb: float | None = 1.0, dp_el: float | None = 1.0, dp_gamma: float | None = None, dp_tau_s: float | None = None, dp_plasticity_type: Literal['edge', 'perimeter', 'bending', 'none', None] = None, dp_interior_edges: str | int = 'fan', dp_is_surface: Array | None = None, seed: int | None = None) tuple[Any, ...][source]#
Catch-all builder: polydisperse GA/DP particles at a target packing fraction.
Given per-body polydispersity (radii, vertex counts, aspect ratios, etc.), builds the state, randomly places each body’s bounding sphere at
initial_phi_bb, energy-minimizes the analogue sphere system, transfers the new centroids back to the bodies, builds a System (initially with FIRE for minimization), quasistatically compresses to the target true-body packing fractionphi, and returns the result wrapped in a System built with the user-requested integrator, collider, and material.For
particle_type="dp"aDeformableParticleModel(or a plastic variant) is also built and wired into the returned System as thebonded_force_model. In that case returns(state, system, container); for clumps/spheres returns(state, system).- Parameters:
particle_radii – Per-body arrays (shape
(M,)) or scalars for the last two.vertex_counts – Per-body arrays (shape
(M,)) or scalars for the last two.asperity_radius – Per-body arrays (shape
(M,)) or scalars for the last two.phi – Target true-body packing fraction (uses each body’s union volume, not its bounding sphere).
dim – Spatial dimension (2 or 3).
particle_type –
"clump"(default) or"dp".nv=1clumps are effectively spheres.core_type –
"hollow"(default),"solid", or"phantom".aspect_ratio –
None(isotropic), scalar,(dim,),(M,), or(M, dim).asperity_dispersity_type – Asperity-radius polydispersity. Forwarded as-is to every per-body
create_ga_state()call. Theoretical mean of the chosen distribution always equals each body’sasperity_radius, so the bounding/core geometry is unchanged. Seecreate_ga_state()for the supported distributions and kwargs.asperity_dispersity_kwargs – Asperity-radius polydispersity. Forwarded as-is to every per-body
create_ga_state()call. Theoretical mean of the chosen distribution always equals each body’sasperity_radius, so the bounding/core geometry is unchanged. Seecreate_ga_state()for the supported distributions and kwargs.domain_type –
"periodic"or"reflect"(closed box).compression_step – Packing-fraction increment for quasistatic compression.
compression_pe_tol – Energy tolerances passed to
quasistatic_compress_to_packing_fraction().compression_pe_diff_tol – Energy tolerances passed to
quasistatic_compress_to_packing_fraction().max_n_min_steps_per_outer – Passed to
quasistatic_compress_to_packing_fraction().compression_progress – Passed to
quasistatic_compress_to_packing_fraction().dt – Time step for the returned System.
linear_integrator_type – Integrator types for the final (returned) System.
rotation_integrator_type – Integrator types for the final (returned) System.
force_model_type – Parameters of the final (returned) System.
collider_type – Parameters of the final (returned) System.
collider_kw – Parameters of the final (returned) System.
mat_table – Optional pre-built material table. If supplied, material and matcher specs are ignored.
material_type – Material / matcher spec. When
mat_tableis None a singlematerial_typeis created withmaterial_kwargs(defaulting toyoung=e_int, poisson=0.5, density=1.0) and paired with the given matcher.material_kwargs – Material / matcher spec. When
mat_tableis None a singlematerial_typeis created withmaterial_kwargs(defaulting toyoung=e_int, poisson=0.5, density=1.0) and paired with the given matcher.matcher_type – Material / matcher spec. When
mat_tableis None a singlematerial_typeis created withmaterial_kwargs(defaulting toyoung=e_int, poisson=0.5, density=1.0) and paired with the given matcher.matcher_kwargs – Material / matcher spec. When
mat_tableis None a singlematerial_typeis created withmaterial_kwargs(defaulting toyoung=e_int, poisson=0.5, density=1.0) and paired with the given matcher.e_int – Material / matcher spec. When
mat_tableis None a singlematerial_typeis created withmaterial_kwargs(defaulting toyoung=e_int, poisson=0.5, density=1.0) and paired with the given matcher.dp_em – DP energy parameters. Unused for
particle_type="clump".dp_ec – DP energy parameters. Unused for
particle_type="clump".dp_eb – DP energy parameters. Unused for
particle_type="clump".dp_el – DP energy parameters. Unused for
particle_type="clump".dp_gamma – DP plasticity parameters. Unused for
particle_type="clump".dp_tau_s – DP plasticity parameters. Unused for
particle_type="clump".dp_plasticity_type – DP plasticity parameters. Unused for
particle_type="clump".dp_interior_edges – DP energy / topology parameters. Unused for
particle_type="clump".dp_is_surface – DP energy / topology parameters. Unused for
particle_type="clump".
- Returns:
(state, system)for clumps / spheres, or(state, system, container)for DPs.- Return type:
tuple
- jaxdem.utils.particleCreation.build_sphere_system(particle_radii: Sequence[float] | ndarray, phi: float, dim: int, *, particle_mass: float | Sequence[float] = 1.0, domain_type: str = 'periodic', box_aspect: Sequence[float] | None = None, compression_step: float = 0.001, compression_pe_tol: float = 1e-16, compression_pe_diff_tol: float = 1e-16, max_n_min_steps_per_outer: int = 200000, compression_progress: bool = False, dt: float = 0.001, linear_integrator_type: str = 'verlet', rotation_integrator_type: str = '', force_model_type: str = 'spring', collider_type: str = 'neighborlist', collider_kw: dict[str, Any] | None = None, mat_table: Any = None, e_int: float = 1.0, material_type: str = 'elastic', material_kwargs: dict[str, Any] | None = None, matcher_type: str = 'harmonic', matcher_kwargs: dict[str, Any] | None = None, seed: int | None = None, minimizer: Any = None, minimizer_kw: dict[str, Any] | None = None, target_fn: Any = None) tuple[State, Any][source]#
Catch-all builder for a polydisperse sphere packing at a target phi.
Sphere counterpart to
build_ga_system(). Random positions are drawn loose (phi = 0.3or the target, whichever is smaller) viarandom_sphere_configuration(), then quasistatically compressed tophiunder the same FIRE/spring setup asbuild_ga_system. Returns(state, system)built with the user-requested integrator, collider, and material.Parameters mirror
build_ga_system()(minus all the GA/DP-specific knobs that don’t apply to bare spheres).