jaxdem.utils.geometric_asperity_creation#

Legacy utility functions for creating Geometric Asperity particle states in 2D and 3D.

Deprecated since version This: module is a legacy duplicate of jaxdem.utils.particle_creation with an older, incompatible body-type vocabulary ("solid" here roughly corresponds to "phantom" there). Prefer jaxdem.utils.particle_creation.create_ga_state() / jaxdem.utils.particle_creation.build_ga_system() for new code.

Functions

compute_mesh_properties(mesh, mass)

Exact mesh-based: COM, principal inertia (3-vector), and quaternion for a 3D solid.

compute_polygon_properties(shape, mass)

Green's theorem: COM, polar inertia, and principal-axis quaternion for a 2D solid.

duplicate_clump_template(template, com_positions)

template: a single clump with Ns spheres (template.pos_c same for all spheres, template.clump_id same for all spheres) com_positions: (M, dim) desired clump COM positions returns: State with M clumps, total N = M*Ns spheres.

generate_asperities_2d(asperity_radius, ...)

asperity_radius: float - radius of the asperities particle_radius: float - outer-most radius of the particle (major axis if an ellipse) num_vertices: int - number of asperities aspect_ratio: float - optional aspect ratio of the ellipse add_core: bool - optional.

generate_asperities_3d(asperity_radius, ...)

asperity_radius: float - radius of the asperities particle_radius: float - outer-most radius of the particle (major axis if an ellipsoid) target_num_vertices: int - target number of asperities - usually not met due to icosphere subdivision aspect_ratio: Sequence[float] - optional aspect ratios of the ellipsoid add_core: bool - optional.

generate_ga_clump_state(particle_radii, ...)

Build a jaxdem.State containing a system of Geometric Asperity model particles as clumps in either 2D or 3D.

generate_ga_deformable_state(particle_radii, ...)

Build a jaxdem.State and matching DeformableParticleModel containing a system of Geometric Asperity model particles as deformable particles in either 2D or 3D.

generate_mesh(asperity_positions, ...)

make_single_deformable_ga_particle_2d(...[, ...])

Build a single 2D GA particle as a deformable particle.

make_single_deformable_ga_particle_3d(...[, ...])

Build a single 3D GA particle as a deformable particle.

make_single_particle_2d(asperity_radius, ...)

asperity_radius: float - radius of the asperities particle_radius: float - outer-most radius of the particle (major axis if an ellipse) num_vertices: int - number of asperities aspect_ratio: float - optional aspect ratio of the ellipse body_type: str - optional.

make_single_particle_3d(asperity_radius, ...)

asperity_radius: float - radius of the asperities particle_radius: float - outer-most radius of the particle (major axis if an ellipsoid) target_num_vertices: int - target number of asperities - usually not met due to icosphere subdivision aspect_ratio: Sequence[float] - optional aspect ratios of the ellipsoid (length 3) body_type: str - 'true-solid' (physical core), 'solid' (core used for volume and inertia), 'point' (point masses) use_uniform_mesh: bool - whether to use uniformly spaced vertices, only relevant for ellipsoids particle_center: Sequence[float] - optional particle center location mass: float - optional mass of the entire particle mesh_subdivisions: int - number of subdivisions for the icosphere mesh used to define the volume mesh_type: str - one of 'ico', 'octa', or 'tetra' ____ returns: state: State - jaxdem state object containing the single clump particle in 3d.

jaxdem.utils.geometric_asperity_creation.duplicate_clump_template(template: State, com_positions: Array) State[source]#

template: a single clump with Ns spheres (template.pos_c same for all spheres, template.clump_id same for all spheres) com_positions: (M, dim) desired clump COM positions returns: State with M clumps, total N = M*Ns spheres.

jaxdem.utils.geometric_asperity_creation.generate_asperities_2d(asperity_radius: float, particle_radius: float, num_vertices: int, aspect_ratio: float = 1.0, add_core: bool | None = False, use_uniform_mesh: bool = False) tuple[Array, Array][source]#

asperity_radius: float - radius of the asperities particle_radius: float - outer-most radius of the particle (major axis if an ellipse) num_vertices: int - number of asperities aspect_ratio: float - optional aspect ratio of the ellipse add_core: bool - optional. Adds a central core particle (“true” physical core) if True, otherwise does nothing. use_uniform_mesh: bool - whether to use uniformly spaced vertices, only relevant for ellipses ____ returns: asperity_positions: jnp.ndarray - (num_vertices + add_core, 2) array of positions of the asperities asperity_radii: jnp.ndarray - (num_vertices + add_core,) array of radii of the asperities ____ notes: creates a particle composed of a set of surface asperities places asperities along either a circle or an ellipse in 2d makes sure that the outer-most length of the particle is equal to 2 * particle_radius adds a core which is useful for covering up large gaps between adjacent asperities.

jaxdem.utils.geometric_asperity_creation.compute_polygon_properties(shape: Any, mass: float) tuple[Array, Array, Array, Array][source]#

Green’s theorem: COM, polar inertia, and principal-axis quaternion for a 2D solid.

jaxdem.utils.geometric_asperity_creation.compute_mesh_properties(mesh: Any, mass: float) tuple[Array, Array, Array, Array][source]#

Exact mesh-based: COM, principal inertia (3-vector), and quaternion for a 3D solid.

jaxdem.utils.geometric_asperity_creation.make_single_particle_2d(asperity_radius: float, particle_radius: float, num_vertices: int, aspect_ratio: float = 1.0, body_type: str | None = 'solid', use_uniform_mesh: bool = False, particle_center: Sequence[float] = (0.0, 0.0), mass: float = 1.0, quad_segs: int = 10000) State[source]#

asperity_radius: float - radius of the asperities particle_radius: float - outer-most radius of the particle (major axis if an ellipse) num_vertices: int - number of asperities aspect_ratio: float - optional aspect ratio of the ellipse body_type: str - optional. ‘true-solid’ (physical core), ‘solid’ (core used for area and inertia), ‘point’ (point masses) use_uniform_mesh: bool - whether to use uniformly spaced vertices, only relevant for ellipses particle_center: Sequence[float] - optional particle center location mass: float - optional mass of the entire particle quad_segs: int - optional number of segments used to approximate each asperity circle when computing the body’s area and inertia via shapely ____ returns: single_clump_state: State - jaxdem state object containing the single clump particle in 2d.

jaxdem.utils.geometric_asperity_creation.make_single_deformable_ga_particle_2d(asperity_radius: float, particle_radius: float, num_vertices: int, *, aspect_ratio: float = 1.0, use_uniform_mesh: bool = False, particle_center: Sequence[float] = (0.0, 0.0), mass: float = 1.0, 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, random_orientation: bool = True, seed: int | None = None) tuple[State, DeformableParticleModel][source]#

Build a single 2D GA particle as a deformable particle.

Nodes are asperity centers. Boundary elements form a closed polygon through the boundary nodes.

jaxdem.utils.geometric_asperity_creation.make_single_deformable_ga_particle_3d(asperity_radius: float, particle_radius: float, target_num_vertices: int, *, aspect_ratio: Sequence[float] = (1.0, 1.0, 1.0), use_uniform_mesh: bool = False, mesh_type: str = 'ico', particle_center: Sequence[float] = (0.0, 0.0, 0.0), mass: float = 1.0, 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, random_orientation: bool = True, seed: int | None = None) tuple[State, DeformableParticleModel][source]#

Build a single 3D GA particle as a deformable particle.

Nodes are asperity centers. Boundary elements are the convex hull triangles through the boundary nodes.

jaxdem.utils.geometric_asperity_creation.generate_asperities_3d(asperity_radius: float, particle_radius: float, target_num_vertices: int, aspect_ratio: Sequence[float] = (1.0, 1.0, 1.0), add_core: bool | None = False, use_uniform_mesh: bool = False, mesh_type: str = 'ico', return_mesh: bool = False) tuple[Array, Array] | tuple[Array, Array, Any][source]#

asperity_radius: float - radius of the asperities particle_radius: float - outer-most radius of the particle (major axis if an ellipsoid) target_num_vertices: int - target number of asperities - usually not met due to icosphere subdivision aspect_ratio: Sequence[float] - optional aspect ratios of the ellipsoid add_core: bool - optional. Adds a central core particle if True, otherwise does nothing use_uniform_mesh: bool - whether to use uniformly spaced vertices, only relevant for ellipsoids mesh_type: str - one of ‘ico’, ‘octa’, or ‘tetra’ (icosphere, octasphere, tetrasphere). icosphere has the most, but smallest, defects. tetrasphere has the fewest, but largest, defects. octasphere is intermediate. tetrasphere offers the finest granularity of achievable vertex counts (2n^2+2 vs 4n^2+2 for octa and 10n^2+2 for ico). ____ returns: asperity_positions: jnp.ndarray - (num_vertices + add_core, 3) array of positions of the asperities asperity_radii: jnp.ndarray - (num_vertices + add_core,) array of radii of the asperities ____ notes: creates a particle composed of a set of surface asperities places asperities along either a sphere or an ellipsoid in 3d makes sure that the outer-most length of the particle is equal to 2 * particle_radius adds a core which is useful for covering up large gaps between adjacent asperities the number of subdivisions for the icosphere mesh is suggested from target_num_vertices.

jaxdem.utils.geometric_asperity_creation.generate_mesh(asperity_positions: Array, asperity_radii: Array, subdivisions: int) Any[source]#
jaxdem.utils.geometric_asperity_creation.make_single_particle_3d(asperity_radius: float, particle_radius: float, target_num_vertices: int, aspect_ratio: Sequence[float] = (1.0, 1.0, 1.0), body_type: str | None = 'solid', use_uniform_mesh: bool = False, particle_center: Sequence[float] = (0.0, 0.0, 0.0), mass: float = 1.0, mesh_subdivisions: int = 4, mesh_type: str = 'ico') State[source]#

asperity_radius: float - radius of the asperities particle_radius: float - outer-most radius of the particle (major axis if an ellipsoid) target_num_vertices: int - target number of asperities - usually not met due to icosphere subdivision aspect_ratio: Sequence[float] - optional aspect ratios of the ellipsoid (length 3) body_type: str - ‘true-solid’ (physical core), ‘solid’ (core used for volume and inertia), ‘point’ (point masses) use_uniform_mesh: bool - whether to use uniformly spaced vertices, only relevant for ellipsoids particle_center: Sequence[float] - optional particle center location mass: float - optional mass of the entire particle mesh_subdivisions: int - number of subdivisions for the icosphere mesh used to define the volume mesh_type: str - one of ‘ico’, ‘octa’, or ‘tetra’ ____ returns: state: State - jaxdem state object containing the single clump particle in 3d.

jaxdem.utils.geometric_asperity_creation.generate_ga_clump_state(particle_radii: Array, vertex_counts: Array, phi: float, dim: int, asperity_radius: float, *, seed: int | None = None, body_type: str | None = 'solid', use_uniform_mesh: bool = False, mass: float = 1.0, aspect_ratio: float | Sequence[float] | None = None, quad_segs: int = 10000, mesh_subdivisions: int = 4, mesh_type: str = 'ico', use_random_orientations: bool = True) tuple[State, Array][source]#

Build a jaxdem.State containing a system of Geometric Asperity model particles as clumps in either 2D or 3D.

jaxdem.utils.geometric_asperity_creation.generate_ga_deformable_state(particle_radii: Array, vertex_counts: Array, phi: float, dim: int, asperity_radius: float, *, seed: int | None = None, use_uniform_mesh: bool = False, mass: float = 1.0, aspect_ratio: float | Sequence[float] | None = None, mesh_type: str = 'ico', 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, random_orientations: bool = True, plasticity_type: Literal['edge', 'perimeter', 'bending'] | str | None = None) tuple[State, DeformableParticleModel | PlasticBendingDeformableParticleModel | PlasticDeformableParticleModel | PlasticPerimeterDeformableParticleModel, Array][source]#

Build a jaxdem.State and matching DeformableParticleModel containing a system of Geometric Asperity model particles as deformable particles in either 2D or 3D.

Nodes are asperity centers (plus optional core). Topology is auto-generated to support any subset of {em, ec, eb, el, gamma}.

Plasticity is opt-in via plasticity_type: - None or "none": no plasticity (default) - "edge": relax edge rest lengths - "perimeter": relax body perimeter rest lengths - "bending": relax rest bending angles