migflow.scontact

C++ Python bindings for the MigFlow particle contact solver.

class migflow.scontact.ParticleProblem(dim, lib_dir='')

Bases: object

MigFlow DEM particle contact problem. Loads libscontact{dim}.so at runtime via dlopen.

Construct a ParticleProblem.

Parameters

dimint

Spatial dimension (2 or 3)

lib_dirstr

Directory containing libscontact{dim}.so. Empty = auto-detect.

Pointer

alias of LP__Structure

add_body(position, imass, iinertia)

Add a rigid body. iinertia is a scalar (broadcast to all components in 3D).

Return type:

int

Parameters

positionNDArray[np.float64]

Position of body center (dim,)

imassfloat

Inverse mass (0 = fixed)

iinertiafloat

Scalar inverse inertia (broadcast to all components)

Returns

body_idint

Index of the new body

add_boundary_segment(x0, x1, tag, material='', radius=0.0)

Add a boundary segment (creates its own body).

Return type:

int

Parameters

x0NDArray[np.float64]

First endpoint (dim,)

x1NDArray[np.float64]

Second endpoint (dim,)

tagstr

Boundary tag name

materialstr

Material name

radiusfloat

Cylinder radius

Returns

segment_idint

Index of the new segment

add_boundary_triangle(x0, x1, x2, tag, material='')

Add a boundary triangle (3D, creates its own body).

Return type:

int

Parameters

x0NDArray[np.float64]

First vertex (dim,)

x1NDArray[np.float64]

Second vertex (dim,)

x2NDArray[np.float64]

Third vertex (dim,)

tagstr

Boundary tag name

materialstr

Material name

Returns

triangle_idint

Index of the new triangle

add_particle(position, radius, mass, material='', forced=False)

Add a sphere particle to a new single-particle body.

Return type:

int

Parameters

positionNDArray[np.float64]

Centre position of the particle (dim,)

radiusfloat

Particle radius

massfloat

Particle mass

materialstr

Material name

forcedbool

If true, body is fixed (infinite mass)

Returns

body_idint

Index of the new body

add_particle_body(positions, radii, masses, material='', forced=False)

Add a multi-sphere body.

Return type:

int

Parameters

positionsNDArray[np.float64]

Particle positions (n, dim)

radiiNDArray[np.float64]

Particle radii (n,)

massesNDArray[np.float64]

Particle masses (n,)

materialstr

Material name

forcedbool

If true, body is fixed

Returns

body_idint

Index of the new body

add_particle_to_body(relative_position, radius, body, material='', tag=0)

Add a sphere particle to an existing body, by material name.

Return type:

int

Parameters

relative_positionNDArray[np.float64]

Position relative to body center (dim,)

radiusfloat

Particle radius

bodyint

Body index

materialstr

Material name; the name ignore keeps the particle out of contact

tagint

Particle tag

Returns

particle_idint

Index of the new particle

add_particle_to_body_raw(body, radius, relative_position, material_id, tag=0)

Add a sphere particle to an existing body, by material index.

Return type:

int

Parameters

bodyint

Body index

radiusfloat

Particle radius

relative_positionNDArray[np.float64]

Position relative to body center (dim,)

material_idint

Material index

tagint

Particle tag

Returns

particle_idint

Index of the new particle

add_periodic_entity(entity_dim, transform)

Add a periodic entity.

Return type:

int

Parameters

entity_dimint

Dimension of the entity (0=point, 1=segment, 2=triangle)

transformNDArray[np.float64]

Translation vector (dim,)

Returns

entity_idint

Index of the new periodic entity

add_periodic_point(entity, position)

Add a periodic point.

Return type:

int

Parameters

entityint

Periodic entity index

positionNDArray[np.float64]

Point position (dim,)

Returns

idint

Index of the new periodic point

add_periodic_segment(entity, positions)

Add a periodic segment.

Return type:

int

Parameters

entityint

Periodic entity index

positionsNDArray[np.float64]

Endpoint positions (2, dim)

Returns

idint

Index of the new periodic segment

add_periodic_triangle(entity, positions)

Add a periodic triangle (3D only).

Return type:

int

Parameters

entityint

Periodic entity index

positionsNDArray[np.float64]

Vertex positions (3, dim)

Returns

idint

Index of the new periodic triangle

add_segment_to_body(x0, x1, body, tag, material='', radius=0.0)

Add a boundary segment to an existing body, by material name.

Return type:

int

Parameters

x0NDArray[np.float64]

First endpoint, relative to the body centre (dim,)

x1NDArray[np.float64]

Second endpoint, relative to the body centre (dim,)

bodyint

Body index

tagstr

Boundary tag name

materialstr

Material name

radiusfloat

Cylinder radius

Returns

segment_idint

Index of the new segment

add_segment_to_body_raw(body, rel_pos, tag_id, material_id, radius=0.0)

Add a boundary segment using relative positions and integer ids.

Return type:

int

Parameters

bodyint

Body index

rel_posNDArray[np.float64]

Endpoint positions relative to body (2, dim)

tag_idint

Tag index

material_idint

Material index

radiusfloat

Cylinder radius

Returns

segment_idint

Index of the new segment

add_triangle_to_body(x0, x1, x2, body, tag, material='')

Add a boundary triangle to an existing body, by material name (3D only).

Return type:

int

Parameters

x0NDArray[np.float64]

First vertex, relative to the body centre (dim,)

x1NDArray[np.float64]

Second vertex, relative to the body centre (dim,)

x2NDArray[np.float64]

Third vertex, relative to the body centre (dim,)

bodyint

Body index

tagstr

Boundary tag name

materialstr

Material name

Returns

triangle_idint

Index of the new triangle

add_triangle_to_body_raw(body, rel_pos, tag_id, material_id)

Add a boundary triangle using relative positions and integer ids (3D only).

Return type:

int

Parameters

bodyint

Body index

rel_posNDArray[np.float64]

Vertex positions relative to body (3, dim)

tag_idint

Tag index

material_idint

Material index

Returns

triangle_idint

Index of the new triangle

allocate_material(n)

Allocate storage for n materials (resizes mu matrix).

Parameters

nint

Number of materials

body_constraint()

Constraint flags of bodies (n_bodies, dim). Returns ——-

constraintNDArray[np.int32]

Constraint array

Return type:

ndarray[Any, dtype[int32]]

body_invert_inertia()

Inverse inertias of bodies. Returns ——-

iinertiaNDArray[np.float64]

Inverse inertia array (n_bodies, iinertia_size)

Return type:

ndarray[Any, dtype[float64]]

body_invert_mass()

Inverse masses of bodies (n_bodies, 1). Returns ——-

imassNDArray[np.float64]

Inverse mass array

Return type:

ndarray[Any, dtype[float64]]

body_omega()

Writable view of body angular velocities. Returns ——-

omegaNDArray[np.float64]

Body omega array (n_bodies, omega_size)

Return type:

ndarray[Any, dtype[float64]]

body_position()

Writable view of body positions (n_bodies, dim). Returns ——-

posNDArray[np.float64]

Body position array (n_bodies, dim)

Return type:

ndarray[Any, dtype[float64]]

body_theta()

Writable view of body orientation angles. Returns ——-

thetaNDArray[np.float64]

Body theta array (n_bodies, theta_size)

Return type:

ndarray[Any, dtype[float64]]

body_uid()

Unique IDs of bodies (n_bodies,). Returns ——-

uidNDArray[np.float64]

UID array (n_bodies,) as int64

Return type:

ndarray[Any, dtype[float64]]

body_velocity()

Writable view of body velocities (n_bodies, dim). Returns ——-

velNDArray[np.float64]

Body velocity array (n_bodies, dim)

Return type:

ndarray[Any, dtype[float64]]

bounding_box_max(padding_ratio=0.0)
Return type:

ndarray[Any, dtype[float64]]

Parameters

padding_ratiofloat

Fractional padding

Returns

maxNDArray[np.float64]

Upper corner of bounding box (dim,)

bounding_box_min(padding_ratio=0.0)
Return type:

ndarray[Any, dtype[float64]]

Parameters

padding_ratiofloat

Fractional padding

Returns

minNDArray[np.float64]

Lower corner of bounding box (dim,)

compute_stress_tensor(nodes, radius)

Compute granular stress tensor at nodes.

Return type:

ndarray[Any, dtype[float64]]

Parameters

nodesNDArray[np.float64]

Node positions (n, dim)

radiusfloat

Averaging radius

Returns

stressNDArray[np.float64]

Stress tensor (n, dim*dim)

contact_detection_d()

Get the contact detection distance (negative = auto from max radius). Returns ——-

dfloat

Contact detection distance

Return type:

float

contact_forces()

Contact forces on each particle (n_particles, dim) or (0,) if not computed. Returns ——-

fNDArray[np.float64]

Contact force array

Return type:

ndarray[Any, dtype[float64]]

contact_heat(ks, young_modulus, poisson_ratio, temperature, isolated_bodies=None)

Heat exchanged at the contacts, per body. Conduction through the Hertzian contact area between two touching bodies. The contact conductance is h = 2 k_eq (3 R_eq F_n / (4 E_eq))**(1/3) in 3D and h = 4 k_eq (3 R_eq F_n / (pi E_eq))**(1/4) in 2D, with the equivalent radius, conductivity and elastic modulus taken pairwise. The flux on each body is h * (T_other - T_self), summed over its contacts. Only particle-particle and particle-segment contacts conduct.

Return type:

ndarray[Any, dtype[float64]]

Parameters

ksNDArray[np.float64]

Conductivity per body (n_bodies,)

young_modulusNDArray[np.float64]

Young modulus per body (n_bodies,)

poisson_ratioNDArray[np.float64]

Poisson ratio per body (n_bodies,)

temperatureNDArray[np.float64]

Temperature per body (n_bodies,)

isolated_bodiesNDArray[np.int32]

Bodies that exchange no heat, or None

Returns

qNDArray[np.float64]

Heat flux per body (n_bodies,)

contact_type_particle_particle()
Return type:

int

Returns

idint

Contact type integer for particle-particle

contact_type_particle_segment()
Return type:

int

Returns

idint

Contact type integer for particle-segment

contact_type_particle_triangle()
Return type:

int

Returns

idint

Contact type integer for particle-triangle (3D only)

contact_type_segment_segment()
Return type:

int

Returns

idint

Contact type integer for segment-segment (3D only)

contacts_basis()

Contact basis (n_contacts, dim, dim). Returns ——-

basisNDArray[np.float64]

Contact basis array

Return type:

ndarray[Any, dtype[float64]]

contacts_contact_type()

Contact type per contact (n_contacts,). Returns ——-

ctNDArray[np.int32]

Contact type array (int32)

Return type:

ndarray[Any, dtype[int32]]

contacts_o()

Object pair indices per contact (n_contacts, 2). Returns ——-

oNDArray[np.int32]

Contact object index pairs (int32)

Return type:

ndarray[Any, dtype[int32]]

contacts_r()

Contact point positions per contact (n_contacts, 2, dim). Returns ——-

rNDArray[np.float64]

Contact point array

Return type:

ndarray[Any, dtype[float64]]

contacts_reaction()

Contact reaction forces (n_contacts, dim). Returns ——-

reactionNDArray[np.float64]

Reaction force array

Return type:

ndarray[Any, dtype[float64]]

contacts_space()

Gap/space per contact (n_contacts,). Returns ——-

spaceNDArray[np.float64]

Contact space array

Return type:

ndarray[Any, dtype[float64]]

delassus()

Compute Delassus operators for each particle. Returns ——-

dNDArray[np.float64]

Delassus operators (n_particles, dim, dim)

Return type:

ndarray[Any, dtype[float64]]

delassus_raw()

Compute Delassus operators - alias for delassus(). Returns ——-

dNDArray[np.float64]

Delassus (n_particles, dim, dim)

Return type:

ndarray[Any, dtype[float64]]

dim()

Alias for dimension(). Returns ——-

dimint

Spatial dimension

Return type:

int

dimension()
Return type:

int

Returns

dimint

Spatial dimension (2 or 3)

filter_new_particles(x, r)

Check which candidate particles can be inserted without overlap.

Return type:

ndarray[Any, dtype[int32]]

Parameters

xNDArray[np.float64]

Candidate positions (n, dim)

rNDArray[np.float64]

Candidate radii (n,)

Returns

keepNDArray[np.int32]

1=accepted, 0=rejected (n,)

get_boundary_force(tag_id)

Get total force on a boundary tag (from contacts).

Return type:

ndarray[Any, dtype[float64]]

Parameters

tag_idint

Boundary tag index

Returns

forceNDArray[np.float64]

Force vector (dim,)

get_boundary_forces(tag)

Get total force on a named boundary.

Return type:

ndarray[Any, dtype[float64]]

Parameters

tagstr

Boundary tag name

Returns

forceNDArray[np.float64]

Force vector (dim,)

get_current_quality(tol)

Worst interpenetration among the contacts detected right now, unlike get_overall_quality() which tracks the whole simulation.

Return type:

float

Parameters

tolfloat

Alert distance; the largest particle radius is used when it is negative

Returns

qfloat

Worst interpenetration

get_iters_contacts_solve()
Return type:

int

Returns

nint

Number of contact solver iterations

get_material_id(material)

Return (or create) integer id for a material name string, allocating material if new.

Return type:

int

Parameters

materialstr

Material name string

Returns

idint

Material index

get_overall_quality()
Return type:

float

Returns

qfloat

Worst interpenetration over entire simulation

get_separation_threshold()
Return type:

float

Returns

thresholdfloat

Separation threshold

get_tag_id(tag)

Return (or create) integer id for a boundary tag string.

Return type:

int

Parameters

tagstr

Tag name string

Returns

idint

Tag index

get_time_contacts_solve()
Return type:

float

Returns

tfloat

Time spent solving contacts

get_time_detection()
Return type:

float

Returns

tfloat

Time spent in contact detection

id()

Return particle tags (alias for particle_tag). Returns ——-

tagNDArray[np.float64]

Tag array (n_particles,)

Return type:

ndarray[Any, dtype[float64]]

init_body(reference_position, relative_positions, particle_masses, particle_radii, material='')

Initialize a rigid body from a cloud of particles (exact inertia).

Return type:

int

Parameters

reference_positionNDArray[np.float64]

Reference position of the body (dim,)

relative_positionsNDArray[np.float64]

Particle relative positions (n, dim)

particle_massesNDArray[np.float64]

Particle masses (n,)

particle_radiiNDArray[np.float64]

Particle radii (n,)

materialstr

Material name

Returns

body_idint

Index of the new body

iterate(dt, forces, body_forces=None, tol=1e-08, force_motion=0)

Advance one time step.

Return type:

int

Parameters

dtfloat

Time step

forcesNDArray[np.float64]

External forces on particles (n_particles, dim)

body_forcesNDArray[np.float64]

External forces on bodies (n_bodies, dim). Defaults to zero.

tolfloat

Convergence tolerance

force_motionint

Force motion if not converged

Returns

convergedint

1 if converged, 0 otherwise

material()

Return particle material indices (n_particles, 1). Returns ——-

matNDArray[np.float64]

Material index array

Return type:

ndarray[Any, dtype[float64]]

material_name(id)

Return the name of a material by index.

Return type:

str

Parameters

idint

Material index

Returns

namestr

Material name string

mu_array()

Friction coefficient matrix (n_mat, n_mat). Returns ——-

muNDArray[np.float64]

Friction matrix

Return type:

ndarray[Any, dtype[float64]]

n_bodies()
Return type:

int

Returns

nint

Number of bodies

n_contacts()
Return type:

int

Returns

nint

Number of contacts

n_materials()
Return type:

int

Returns

nint

Number of registered materials

n_particles()
Return type:

int

Returns

nint

Number of particles

n_periodic_entities()
Return type:

int

Returns

nint

Number of periodic entities

n_periodic_points()
Return type:

int

Returns

nint

Number of periodic points

n_periodic_segments()
Return type:

int

Returns

nint

Number of periodic segments

n_periodic_triangles()
Return type:

int

Returns

nint

Number of periodic triangles (3D only)

n_segments()
Return type:

int

Returns

nint

Number of boundary segments

n_tags()
Return type:

int

Returns

nint

Number of registered boundary tags

n_triangles()
Return type:

int

Returns

nint

Number of boundary triangles (3D only)

omega()

Angular velocities of each particle (n_particles, omega_size). Returns ——-

omegaNDArray[np.float64]

Angular velocity array

Return type:

ndarray[Any, dtype[float64]]

particle_body()

Body index for each particle (n_particles,). Returns ——-

bodyNDArray[np.int32]

Body index array (as int32)

Return type:

ndarray[Any, dtype[int32]]

particle_body_uid()

Return the unique body id of each particle’s body. Returns ——-

uidNDArray[np.float64]

Array of body UIDs per particle

Return type:

ndarray[Any, dtype[float64]]

particle_material()

Material ids of particles (n_particles,). Returns ——-

materialNDArray[np.int32]

Material array (as int32)

Return type:

ndarray[Any, dtype[int32]]

particle_relative_position()

Relative positions of particles w.r.t. body center (n_particles, dim). Returns ——-

relposNDArray[np.float64]

Relative position array

Return type:

ndarray[Any, dtype[float64]]

particle_tag()

Tags of particles (n_particles,) as doubles (uint64 → double). Returns ——-

tagNDArray[np.float64]

Tag array

Return type:

ndarray[Any, dtype[float64]]

position()

Compute current particle positions (absolute). Returns ——-

posNDArray[np.float64]

Particle positions (n_particles, dim)

Return type:

ndarray[Any, dtype[float64]]

r()

Particle radii (n_particles, 1). Returns ——-

rNDArray[np.float64]

Radius array

Return type:

ndarray[Any, dtype[float64]]

read_mig(output_dir, t=-1.0, iteration=-1)

Read particle data from an output directory.

Parameters

output_dirstr

Path to the .mig directory

tfloat

Time to read (-1 = use iteration)

iterationint

Iteration index (-1 = last)

remove_bodies_flag(flag)

Remove bodies (and their particles/segments) based on flag.

Parameters

flagNDArray[np.int32]

1=keep, 0=remove (n_bodies,)

restore_state()

Restore previously saved body state.

save_state()

Save current body state (positions, velocities, orientations, segments).

segments_body()

Body index per segment (n_segments,). Returns ——-

bodyNDArray[np.int32]

Segment body array (int32)

Return type:

ndarray[Any, dtype[int32]]

segments_material()

Material per segment (n_segments,). Returns ——-

materialNDArray[np.int32]

Segment material array (int32)

Return type:

ndarray[Any, dtype[int32]]

segments_position()

Return absolute segment endpoint positions (n_segments, 2, dim). Returns ——-

posNDArray[np.float64]

Segment endpoint positions

Return type:

ndarray[Any, dtype[float64]]

segments_radius()

Radius per segment (n_segments,). Returns ——-

radiusNDArray[np.float64]

Segment radius array

Return type:

ndarray[Any, dtype[float64]]

segments_relative_position()

Relative endpoint positions per segment (n_segments, 2, dim). Returns ——-

relposNDArray[np.float64]

Segment relative positions

Return type:

ndarray[Any, dtype[float64]]

segments_tag()

Tag per segment (n_segments,). Returns ——-

tagNDArray[np.int32]

Segment tag array (int32)

Return type:

ndarray[Any, dtype[int32]]

set_boundary_velocity(tag, velocity)

Set velocity of bodies belonging to segments with given tag.

Parameters

tagstr

Boundary tag name

velocityNDArray[np.float64]

Velocity vector (dim,)

set_boundary_velocity_by_tag(tag_id, velocity)

Set velocity of all bodies belonging to segments with given tag.

Parameters

tag_idint

Boundary tag index

velocityNDArray[np.float64]

Velocity vector (dim,)

set_cohesion_coefficient(c, mat0='', mat1='')

Set the cohesion coefficients between two materials. Unlike friction, cohesion carries one value per contact-law component, so c has 6 entries.

Parameters

cNDArray[np.float64]

Cohesion coefficients (6,)

mat0str

First material name

mat1str

Second material name

set_cohesion_coefficient_ids(c, mat0, mat1)

Same, by material index.

Parameters

cNDArray[np.float64]

Cohesion coefficients (6,)

mat0int

First material index

mat1int

Second material index

set_compute_contact_forces(flag)

Parameters

flagint

1=compute contact forces per particle

set_contact_detection_d(d)

Set the contact detection distance (negative = auto).

Parameters

dfloat

Contact detection distance

set_detection_per_iteration(n)

Parameters

nint

Iterations between contact detection steps

set_fixed_contact_geometry(flag)

Parameters

flagint

1=fixed geometry, 0=recomputed each step

set_friction_coefficient(mu, mat0='', mat1='')

Set friction coefficient between two named materials.

Parameters

mufloat

Friction coefficient value

mat0str

First material name

mat1str

Second material name

set_friction_coefficient_ids(mu, mat0, mat1)

Set friction coefficient using material indices.

Parameters

mufloat

Friction coefficient value

mat0int

First material index

mat1int

Second material index

set_initial(flag)

Parameters

flagint

Initial state flag (1=initial state)

set_jacobi_max_iters(maxit)

Parameters

maxitint

Maximum Jacobi iterations

set_jacobi_mode(flag)

Parameters

flagint

1=Jacobi solver

set_jacobi_relaxation(relax)

Parameters

relaxfloat

Relaxation parameter

set_oriented_faces(flag)

Parameters

flagint

1=faces are oriented

set_predict_basis(flag)

Parameters

flagint

1=predict contact basis

set_redblack_mode(flag)

Parameters

flagint

1=red-black ordering

set_separation_threshold(threshold)

Parameters

thresholdfloat

Separation threshold for oriented faces

set_use_queue(flag)

Parameters

flagint

1=use queue for reordering

tag_name(id)

Return the name of a tag by index.

Return type:

str

Parameters

idint

Tag index

Returns

namestr

Tag name string

triangles_body()

Body index per triangle (n_triangles,). Returns ——-

bodyNDArray[np.int32]

Triangle body array (int32)

Return type:

ndarray[Any, dtype[int32]]

triangles_material()

Material per triangle (n_triangles,). Returns ——-

materialNDArray[np.int32]

Triangle material array (int32)

Return type:

ndarray[Any, dtype[int32]]

triangles_relative_position()

Relative vertex positions per triangle (n_triangles, 3, dim). Returns ——-

relposNDArray[np.float64]

Triangle relative positions

Return type:

ndarray[Any, dtype[float64]]

triangles_tag()

Tag per triangle (n_triangles,). Returns ——-

tagNDArray[np.int32]

Triangle tag array (int32)

Return type:

ndarray[Any, dtype[int32]]

velocity()

Compute current particle velocities. Returns ——-

velNDArray[np.float64]

Particle velocities (n_particles, dim)

Return type:

ndarray[Any, dtype[float64]]

volume()

Particle volumes (n_particles, 1). Returns ——-

volNDArray[np.float64]

Volume array

Return type:

ndarray[Any, dtype[float64]]

write_mig(output_dir, t, write_contacts=True, extra_fields={})

Write particle data to output directory (abin format).

Parameters

output_dirstr

Path to the .mig output directory

tfloat

Simulation time

write_contactsbool

Include contact data in output

extra_fieldsDict[str,NDArray[np.float64]]

Extra per-particle fields as {name: array} dict

write_residues_to_csv(filename)

Write contact residuals to a CSV file (only works in MONITORING mode).

Parameters

filenamestr

Output file path