woo.pre

woo.pre.toys

Inheritance diagram of woo.pre.toys

NewtonsCradle

ObjectPreprocessorNewtonsCradle

class woo.pre.toys.NewtonsCradle(*args, **kwargs)[source]

Showcase for custom packing predicates, and importing surfaces from STL.

Overloaded function.

  1. __init__(self: woo.core.Preprocessor) -> None

  2. __init__(self: woo.core.Preprocessor, *args, **kwargs) -> None

[py/pre/toys.py]

nSpheres(= 5)

Total number of spheres

[type: int]

nFall(= 1)

The number of spheres which are out of the equilibrium position at the beginning.

[type: int]

fallAngle(= 0.7853981633974483)

Initial angle of falling spheres.

[type: float, unit: rad, preferred unit: deg]

rad(= 0.005)

Radius of spheres

[type: float, unit: m]

cabHtWd(= Vector2(0.1, 0.1))

Height and width of the suspension

[type: Vector2, unit: m]

cabRad(= 0.0005)

Radius of the suspending cables

[type: float, unit: m]

model(= <ContactModelSelector @ 139774809270848 (py)>)

Select contact model. The first material is for spheres; the second, optional, material, is for the suspension cables.

[type: ContactModelSelector]

gravity(= Vector3(0, 0, -9.81))

Gravity acceleration

[type: Vector3]

plotEvery(= 10)

How often to collect plot data

[type: int]

dtSafety(= 0.7)

woo.core.Scene.dtSafety

[type: float]

__call__(self: woo.core.Preprocessor)woo.core.Scene[source]
static __new__(klass, **kw)[source]

Create and return a new object. See help(type) for accurate signature.

deepcopy(**kw)

The c++ dedepcopy uses boost::serialization, we need to use pickle. As long as deepcopy is called from python, this function gets precedence over the c++ one. Additional keyword parameters are used to immediately set parameters on the copy before returning.

woo.pre.horse

Inheritance diagram of woo.pre.horse
woo.pre.horse.finished(S)[source]
woo.pre.horse.plotBatchResults(db)[source]

Hook called from woo.batch.writeResults

woo.pre.horse.prepareHorse(pre)[source]

FallingHorse

ObjectPreprocessorFallingHorse

class woo.pre.horse.FallingHorse(*args, **kwargs)[source]

Preprocessor for the falling horse simulation. The falling horse is historically the demo of Woo. IT shows importing triangulated surfaces, filling imported geometry with particle arrangement, selection of material model, export for VTK (Paraview) and the woo.dem.FlowAnalysis tool.

Overloaded function.

  1. __init__(self: woo.core.Preprocessor) -> None

  2. __init__(self: woo.core.Preprocessor, *args, **kwargs) -> None

[py/pre/horse.py]

► General

radius(= 0.002)

Radius of spheres (fill of the upper horse)

[type: float, unit: m, preferred unit: mm]

relGap(= 0.25)

Gap between particles in pattern, relative to radius

[type: float]

halfThick(= 0.002)

Half-thickness of the mesh.

[type: float, unit: m, preferred unit: mm]

relEkStop(= 0.02)

Stop when kinetic energy drops below this fraction of gravity work (and step number is greater than 100)

[type: float]

gravity(= Vector3(0, 0, -9.81))

Gravity acceleration vector

[type: Vector3]

dir(= Vector3(0, 0, 1))

Direction of the upper horse from the lower one. The default is upwards. Will be normalized automatically.

[type: Vector3]

pattern(= 'hexa')

Pattern to use when filling the volume with spheres

[type: str, choices: hexa, ortho]

model(= <ContactModelSelector @ 139774937042352 (py)>)

Select contact model. The first material is for particles; the second, optional, material, is for the meshed horse (the first material is used if there is no second one).

[type: ContactModelSelector]

► Deformability

deformable(= False)

Whether the meshed horse is deformable. Note that deformable horse does not track energy and disables plotting.

[type: bool]

stand(= False)

Whether the bottoms of the legs should be fixed (applicable with deformable only)

[type: bool]

meshDamping(= 0.03)

Damping for mesh nodes; only used when then contact model sets zero damping. In that case, Leapfrog.damping is set to meshDamping and all other nodes set woo.dem.DemData.dampingSkip.

[type: float]

► Tunables

dtSafety(= 0.3)

Safety factor for woo.utils.pWaveDt and woo.dem.DynDt.

[type: float]

► Outputs

reportFmt(= '/tmp/{tid}.xhtml')

Report output format; Scene.tags can be used.

[type: str, filename]

vtkStep(= 40)

How often should woo.dem.VtkExport run. If non-positive, never run the export.

[type: int]

vtkFlowStep(= 40)

How often should VtkFlowExport run. If non-positive, never run.

[type: int]

vtkPrefix(= '/tmp/{tid}-')

Prefix for saving woo.dem.VtkExport and woo.dem.VtkFlowExport data; formatted with format() providing woo.core.Scene.tags as keys.

[type: str, filename]

grid(= False)

Use grid collider (experimental)

[type: bool]

__call__(self: woo.core.Preprocessor)woo.core.Scene[source]
static __new__(klass, **kw)[source]

Create and return a new object. See help(type) for accurate signature.

deepcopy(**kw)

The c++ dedepcopy uses boost::serialization, we need to use pickle. As long as deepcopy is called from python, this function gets precedence over the c++ one. Additional keyword parameters are used to immediately set parameters on the copy before returning.

woo.pre.ell2d

Inheritance diagram of woo.pre.ell2d
woo.pre.ell2d.ell2plot(out, S, bbox, colorRange, colorBy='angVel', **kw)[source]
woo.pre.ell2d.ellGroupUiBuild(S, area)[source]

EllGroup

ObjectPreprocessorEllGroup

class woo.pre.ell2d.EllGroup(*args, **kwargs)[source]

Simulation of group of ellipsoids moving in 2-dimensional box.

Overloaded function.

  1. __init__(self: woo.core.Preprocessor) -> None

  2. __init__(self: woo.core.Preprocessor, *args, **kwargs) -> None

[py/pre/ell2d.py]

rRange(= Vector2(0.02, 0.04))

Range (minimum and maximum) for particle radius (greatest semi-axis); if both are the same, all particles will have the same radius.

[type: Vector2, unit: m]

spheres(= False)

Use spherical particles instead of elliptical

[type: bool]

semiMinRelRnd(= 0.0)

Minimum semi-axis length relative to particle radius; minor semi-axes are randomly selected from (semiMinRelRnd … 1) × greatest semi-axis. If non-positive, semiRelFixed is used instead.

[type: float]

semiRelFixed(= Vector3(1, 0.5, 0.5))

Fixed sizes of semi-axes relative (all elements should be ≤ 1). The \(z\)-component is the out-of-plane size which only indirectly influences contact stiffnesses. This variable is only used if semi-axes are not assigned randomly (see semiMinRelRnd).

[type: Vector3]

boxSize(= Vector2(2, 2))

Size of the 2d domain in which particles move.

[type: Vector2, unit: m]

vMax(= 1.0)

Maximum initial velocity of particle; assigned randomly from 0 to this value; intial angular velocity of all particles is zero.

[type: float, unit: m/s]

model(= <ContactModelSelector @ 139775068714384 (py)>)

Select contact model. The first material is for particles; the second, optional, material is for walls at the boundary (the first material is used if there is no second one).

[type: ContactModelSelector]

exportFmt(= '/tmp/ell2d-{tid}-')

Prefix for saving woo.dem.VtkExport data, and woo.pre.ell2d.ell2plot data; formatted with format() providing woo.core.Scene.tags as keys.

[type: str, filename]

vtkStep(= 0)

How often should woo.dem.VtkExport run. If non-positive, never run the export.

[type: int]

vtkEllLev(= 1)

Tesselation level of ellipsoids when expored as VTK meshes (see woo.dem.VtkExport.ellLev).

[type: int]

ell2Step(= 0)

How often should woo.pre.ell2d.ell2plot run. If non-positive, never run that one.

[type: int]

dtSafety(= 0.5)

Safety coefficient for critical timestep; should be smaller than one.

[type: float]

__call__(self: woo.core.Preprocessor)woo.core.Scene[source]
static __new__(klass, **kw)[source]

Create and return a new object. See help(type) for accurate signature.

deepcopy(**kw)

The c++ dedepcopy uses boost::serialization, we need to use pickle. As long as deepcopy is called from python, this function gets precedence over the c++ one. Additional keyword parameters are used to immediately set parameters on the copy before returning.

woo.pre.chute

Inheritance diagram of woo.pre.chute

DissipChute

ObjectPreprocessorDissipChute

class woo.pre.chute.DissipChute(*args, **kwargs)[source]

Chute for studying dissipation of energy.

Overloaded function.

  1. __init__(self: woo.core.Preprocessor) -> None

  2. __init__(self: woo.core.Preprocessor, *args, **kwargs) -> None

[py/pre/chute.py]

dim(= Vector3(0.2, 0.2, 2))

Chute dimensions: width, depth, height

[type: Vector3, unit: m]

finNum(= 5)

Number of fins protruding from the sides (alternating from left/right

[type: int]

finLen(= 0.15)

Length of fins

[type: float, unit: m]

finSlope(= 0.5235987755982988)

Slope of fins (positive downwards).

[type: float, unit: rad, preferred unit: deg]

gen(= <PsdSphereGenerator @ 0x2767c90>)

Particle generator, placed above the chute

[type: ParticleGenerator]

model(= <ContactModelSelector @ 139774809202016 (py)>)

Contact model

[type: ContactModelSelector]

feedRate(= 5.0)

Feed mass rate

[type: float, unit: kg/s]

feedTime(= 0.5)

Time for which the feed is activated

[type: float, unit: s]

stopTime(= 2.0)

Time when to stop the simulation

[type: float, unit: s]

vtkStep(= 400)

Interval to run VTK export

[type: int]

vtkOut(= '/tmp/{tid}')

Output for VTK files. Tags will be expanded. If empty, VTK export will be disabled.

[type: str]

dtSafety(= 0.7)

woo.core.Scene.dtSafety

[type: float]

saveDone(= '')

File to same simulation at the end; not saved if empty.

[type: str]

__call__(self: woo.core.Preprocessor)woo.core.Scene[source]
static __new__(klass, **kw)[source]

Create and return a new object. See help(type) for accurate signature.

deepcopy(**kw)

The c++ dedepcopy uses boost::serialization, we need to use pickle. As long as deepcopy is called from python, this function gets precedence over the c++ one. Additional keyword parameters are used to immediately set parameters on the copy before returning.

woo.pre.triax

Inheritance diagram of woo.pre.triax
woo.pre.triax.addPlotData_checkProgress(S)[source]
woo.pre.triax.compactionDone(S)[source]
woo.pre.triax.prepareTriax(pre)[source]
woo.pre.triax.triaxDone(S)[source]

TriaxTest

ObjectPreprocessorTriaxTest

class woo.pre.triax.TriaxTest(*args, **kwargs)[source]

Preprocessor for triaxial test with rigid boundary. The test is run in 2 stages:

  • compaction where random loose packing is compressed to attain \(\sigma_{\rm iso}\) (sigIso) in all directions. The compaction finishes when the stress level is sufficiently close to sigIso and unbalanced force drops below maxUnbalanced.

  • Triaxial compression: displacement-controlled compression along the z-axis, with strain rate increasing until maxRates is reached; the test finished when axial strain attains stopStrain. During this phase, lateral (\(x\) and \(y\)) stresses are maintained at \(\sigma_{\rm iso}\), as much as possible.

Overloaded function.

  1. __init__(self: woo.core.Preprocessor) -> None

  2. __init__(self: woo.core.Preprocessor, *args, **kwargs) -> None

[py/pre/triax.py]

► Predefined config

preCooked(= '')

Apply pre-cooked configuration (i.e. change other parameters); this option is not saved.

[type: str, not dumped, choices: , Spheres in cylinder, Capsules in cylinder, Ellipsoids in box, Sphere clumps in box]

► General

sigIso(= -500000.0)

Confining stress (isotropic during compaction)

[type: float, unit: Pa, preferred unit: kPa]

maxRates(= Vector3(0.2, 0.2, 1))

Maximum strain rate during the compaction phase (for all directions), during the triaxial phase in axial sense, and during the triaxial phase in radial sense(s).

[type: Vector3]

stopStrain(= -0.3)

Goal value of axial deformation in the triaxial phase

[type: float, unit: -, preferred unit: %]

planeStrain(= False)

(For demonstration purposes only:) during the triaxial phase, prescribe zero displacement along \(x\) and stress-control only \(y\)-axis.

[type: bool]

shape(= 'cell')

Shape of the volume being compressed; cell is rectangular periodic cell, box is rectangular Wall-delimited box, cylinder is triangulated cylinder aligned with the \(z\)-axis

[type: str, choices: cell, box, cylinder]

iniSize(= Vector3(0.3, 0.3, 0.6))

Initial size of the volume; when shape is cylinder, the second (\(y\)) dimension is ignored.

[type: Vector3, unit: m]

generator(= <PsdCapsuleGenerator @ 0x2138da0>)

Particle generator; partices are then randomly placed in the volume.

[type: ParticleGenerator]

model(= <ContactModelSelector @ 139774932354688 (py)>)

Select contact model. The first material is for particles; the second, optional, material, is for the boundary (the first material is used if there is no second one).

[type: ContactModelSelector]

► Outputs

reportFmt(= '/tmp/{tid}.xhtml')

Report output format; Scene.tags can be used.

[type: str]

saveFmt(= '/tmp/{tid}-{stage}.bin.gz')

Savefile format; keys are Scene.tags; additionally {stage} will be replaced by * init for stress-free but compact cloud, * iso after isotropic compaction, * backup-011234 for regular backups, see backupSaveTime, ‘done’ at the very end.

[type: str]

► Tunables

dtSafety(= 0.7)

See woo.core.Scene.dtSafety.

[type: float]

maxUnbalanced(= 0.1)

Maximum unbalanced force at the end of compaction

[type: float]

cylDiv(= 40)

Number of segments to approximate the cylinder with.

[type: int]

massFactor(= 0.2)

Multiply real mass of particles by this number to obtain the woo.dem.WeirdTriaxControl.mass control parameter

[type: float]

rateStep(= 0.01)

Increase strain rate by this relative amount at the beginning of the triaxial phase, until the value given in maxRates is reached.

[type: float]

__call__(self: woo.core.Preprocessor)woo.core.Scene[source]
static __new__(klass, **kw)[source]

Create and return a new object. See help(type) for accurate signature.

deepcopy(**kw)

The c++ dedepcopy uses boost::serialization, we need to use pickle. As long as deepcopy is called from python, this function gets precedence over the c++ one. Additional keyword parameters are used to immediately set parameters on the copy before returning.

woo.pre.cylTriax

Inheritance diagram of woo.pre.cylTriax
woo.pre.cylTriax.addPlotData(S)[source]
woo.pre.cylTriax.compactionDone(S)[source]
woo.pre.cylTriax.membraneStabilized(S)[source]
woo.pre.cylTriax.mkFacetCyl(aabb, cylDiv, suppMat, sideMat, suppMask, sideMask, suppBlock, sideBlock, sideThick, mass, inertia)[source]

Make closed cylinder from facets. Z is axis of the cylinder. The position is determined by aabb; the cylinder may be elliptical, if the x and y dimensions are different. Return list of particles and list of nodes. The first two nodes in the list are bottom central node and top central node. cylDiv is tuple specifying division in circumferential and axial direcrtion respectively.

woo.pre.cylTriax.plotBatchResults(db, titleRegex=None, out=None, stressPath=True, sorter=None)[source]

Hook called from woo.batch.writeResults

woo.pre.cylTriax.prepareCylTriax(pre)[source]
woo.pre.cylTriax.triaxDone(S)[source]
woo.pre.cylTriax.velocityFieldPlots(S, nameBase)[source]

CylTriaxTest

ObjectPreprocessorCylTriaxTest

class woo.pre.cylTriax.CylTriaxTest(*args, **kwargs)[source]

Preprocessor for cylindrical triaxial test with membrane. The test is run in 3 stages:

  • compaction, where random loose packing of spheres is compressed to attain the \(\sigma_{\rm iso}\) (sigIso) pressure in all directions; during this stage, the cylindrical boundary is rigid and resized along main axes (so it can become (slightly) elliptical); friction is turned off during this stage to achieve better compacity; the compaction finishes when stress level is sufficiently close to the desired one, and unbalanced force drops below maxUnbalanced.

  • Membrane stabilization: once the compression is done, membrane around the cylinder is activated – loaded with surface pressure and made flexible. Friction is activated at this moment. The cylinder may deform axially (stress-controlled), but lateral deformation is now due to membrane-particle interaction. This stage finishes when unbalanced force drops below 1/10th of maxUnbalanced (the reason is that membrane motion is not considered when computing unbalanced force, only mononodal particles are). Surface pressure is adjusted so that the value of lateral stress (in terms of global stress tensor) is close to sigIso. At the same time, friction is increased from initial zero values

  • Triaxial compression: displacement-controlled compression along the z axis, with strain rate increasing until maxRates is reached; the test finishes when axial strain attains stopStrain; during the triaxial phase, lateral pressure is exerted by surface load of membrane elements.

Membrane thickness memThick should be set carefully. The article [ML81] discusses membrane thickness relative to maximum grain size, depending on the ratio of grain stiffness and applied stress.

Supports are from the same material as particles, but they may have their friction reduced (when suppTanPhi is given).

Warning

There are (unfortunately) quite a few tunables which must be tinkered with to get the desired result (those are in the Tunables section: dtSafety, massFactor, model.damping, maxUnbalanced). Several factors are also hard-set in the code, hoping that they will work in different scenarios than those which were tested.

Overloaded function.

  1. __init__(self: woo.core.Preprocessor) -> None

  2. __init__(self: woo.core.Preprocessor, *args, **kwargs) -> None

[py/pre/cylTriax.py]

► Geometry & control

htDiam(= Vector2(0.06, 0.04))

Initial size of the cylinder (radius and height)

[type: Vector2, unit: m]

memThick(= -1.0)

Membrane thickness; if negative, relative to largest particle diameter

[type: float, unit: m]

cylDiv(= 40.0)

Number of segments for cylinder (first component)

[type: float]

sigIso(= -500000.0)

Isotropic compaction stress, and lateral stress during the triaxial phase

[type: float, unit: Pa]

stopStrain(= -0.2)

Goal value of axial deformation in the triaxial phase

[type: float, unit: -, preferred unit: %]

maxRates(= Vector2(0.2, 1))

Maximum strain rates during the compaction phase (for all axes), and during the triaxial phase in the axial sense.

[type: Vector2]

► Materials

model(= <ContactModelSelector @ 139774936682304 (py)>)

Select contact model. The first material is for particles; the second, optional, material, is for the membrane (the first material is used if there is no second one, but its friction is nevertheless reduced during the compaction phase to suppTanPhi).

[type: ContactModelSelector]

psd(= [Vector2(0.002,0), Vector2(0.0025,0.2), Vector2(0.004,1)])

Particle size distribution of particles; first value is diameter, scond is cummulative mass fraction.

[type: [Vector2, …], units: [m,-], preferred units: [mm,%]]

clumps(= [])

Clump definitions (if empty, use spheres, not clumps)

[type: [SphereClumpGeom, …]]

spheresFrom(= '')

Instead of generating spheres, load them from file (space-separated colums with x,y,z,r entries). The initial cylinder is made to fit inside the packing’s axis-aligned bounding box (the user is responsible for having those spheres inside cylinder). Cylinder geometry (htDiam) and particle sizes (psd and clumps) are ignored.

Note

packCacheDir is still used as usual to cache packings after compaction (to disable packing cache, set it to empty string), and will take precedence over spheresFrom if compacted packing for the same parameters is already cached.

[type: str, existing filename]

suppTanPhi(= nan)

Friction at supports; if NaN, the same as for particles is used. Supports use the same material as particles otherwise.

[type: float]

► Outputs

reportFmt(= '/tmp/{tid}.xhtml')

Report output format; Scene.tags can be used.

[type: str, filename]

packCacheDir(= '.')

Directory where to store pre-generated feed packings; if empty, packing wil be re-generated every time.

[type: str, directory name]

saveFmt(= '/tmp/{tid}-{stage}.bin.gz')

Savefile format; keys are Scene.tags; additionally {stage} will be replaced by pre-triax after membrane stabilization (right before the triaxial compression actually starts) and done at the very end.

[type: str, filename]

vtkStep(= 0)

Periodicity of saving VTK exports

[type: int]

vtkFmt(= '/tmp/{title}.{id}-')

Prefix for VTK exports

[type: str, filename]

► Tunables

dtSafety(= 0.9)

Safety factor, stored in woo.core.Scene.dtSafety and used for computing the initial timestep as well as by woo.dem.DynDt later during the simulation.

[type: float]

massFactor(= 10.0)

Multiply real mass of particles by this number to obtain the woo.dem.WeirdTriaxControl.mass control parameter

[type: float]

maxUnbalanced(= 0.05)

Maximum unbalanced force at the end of compaction

[type: float]

__call__(self: woo.core.Preprocessor)woo.core.Scene[source]
static __new__(klass, **kw)[source]

Create and return a new object. See help(type) for accurate signature.

deepcopy(**kw)

The c++ dedepcopy uses boost::serialization, we need to use pickle. As long as deepcopy is called from python, this function gets precedence over the c++ one. Additional keyword parameters are used to immediately set parameters on the copy before returning.

woo.pre.psdrender

Inheritance diagram of woo.pre.psdrender
woo.pre.psdrender.checkSettled(S)[source]
woo.pre.psdrender.finalize(S)[source]

PsdRender

ObjectPreprocessorPsdRender

class woo.pre.psdrender.PsdRender(*args, **kwargs)[source]

Preprocessor for creating layer with given PSD and passing it to POV-Ray for rendering.

Overloaded function.

  1. __init__(self: woo.core.Preprocessor) -> None

  2. __init__(self: woo.core.Preprocessor, *args, **kwargs) -> None

[py/pre/psdrender.py]

size(= Vector2(0.2, 0.3))

Region to be rendered (the particle area will be larger by sizeExtraRel

[type: Vector2, unit: m]

sizeExtraRel(= 0.2)

Enlarge particle area by this much, relative to size.

[type: float]

gen(= <PsdSphereGenerator @ 0x2619b10>)

Particle generator

[type: ParticleGenerator]

relHt(= 2.0)

Bed height relative to largest particle diameter (computed via mass, supposing porosity of porosity)

[type: float]

gravity(= Vector3(0, 0, -9.81))

Gravity acceleration.

[type: Vector3]

porosity(= 0.4)

Approximate porosity to convert bed height (relHt) to mass; it will not influence porosity itself, which is given almost exclusively geometrically.

[type: float]

stepPeriod(= 200)

Periodicity for the factory.

[type: int]

dtSafety(= 0.7)

Safety factor for timestep.

[type: float]

maxUnbalanced(= 0.5)

Unbalanced force/energy to wait for before declared settled.

[type: float]

model(= <ContactModelSelector @ 139774809269488 (py)>)

Contact model and material type; since the simulation is trivial, this has practically no influence, except of friction: less (or zero) friction will make the packing more compact.

[type: ContactModelSelector]

povEnable(= True)

Enable POV-Ray export.

[type: bool]

camPos(= Vector3(0, 0, 0.5))

Camera position; x, y components determine offset from bed normal; z is height above the highest particle center.

[type: Vector3]

out(= '/tmp/{tid}')

Prefix for outputs (woo.core.Scene.tags are expanded).

[type: str]

imgDim(= 2000)

Larger image dimension when the scene is rendered; the scene can be re-rendered by calling POV-Ray by hand anytime with arbitrary resolution.

[type: int]

povLights(= '// light_source{<-8, -20, 30> color rgb .75}\n        // light_source{<25, -12, 12> color rgb .44}\n        light_source{<-.5, -.5, 10> color White area_light <1, 0, 0>, <0, 1, 0>, 5, 5 adaptive 1 jitter }\n        ')

Default light specifications for POV-Ray

[type: str]

saveShapePack(= True)

Create a .shapepack file with particle geometries.

[type: bool]

__call__(self: woo.core.Preprocessor)woo.core.Scene[source]
static __new__(klass, **kw)[source]

Create and return a new object. See help(type) for accurate signature.

deepcopy(**kw)

The c++ dedepcopy uses boost::serialization, we need to use pickle. As long as deepcopy is called from python, this function gets precedence over the c++ one. Additional keyword parameters are used to immediately set parameters on the copy before returning.

Tip

Report issues or inclarities to github.