woo.pre

woo.pre.depot

Inheritance diagram of woo.pre.depot

CylDepot

ObjectPreprocessorCylDepot

class woo.pre.depot.CylDepot(**kw)[source]

‘Deposition of particles inside cylindrical tube. This preprocessor was created for pre-generation of dense packing inside cylindrical chamber, which is then exported to STL serving as input to OpenFOAM for computing permeability (pressure loss) of the layering.

The target specimen (particle packing) dimensions are htDiam (cylinder height and diameter); the packing is inside cylindrical wall, with inlet at the bottom and outlet at the top; this cylinder may be longer than the specimen, which is set by extraHt.

The height of compact packing is not known in advance precisely (it is a function of PSD, material, layering etc); the estimate is set by relSettle, which is used to compute ht0, the height of loose packing (where particles are initially generated), which then settles down in gravity.

The packing is settled when unbalanced energy (the ratio of kinetic to elastic energy) drops below unbE.

Once settled, particles are clipped to the required height. The actual value of settlement is computed and printed (so that it can be used iteratively as input for the next simulation).

Layering specification uses the functionality of woo.dem.LayeredAxialBias, which distributed fractions along some axis in particle generation space. Suppose that we are to model the following two scenarios (which correspond to preCooked variants Brisbane 1 and Brisbane 2, which have spherical particles with piecewise-linear PSD distributed in layered fractions:

_images/depot-brisbane.svg

This arrangement is achieved with the following settings:

  1. Brisbane 1:

    PSD is defined (via PsdSphereGenerator.psdPts) to match relative height (and thus mass) of fractions (on the right), which is 0.1777 for the coarser fraction (12.5-20mm) and 0.8222 for the finer fraction. This we set by:

    psdPts=[(6.3e-3,0),(12.5e-3,.82222),(20e-3,1)]
    

    Layering is achieved by assigning LayeredAxialBias to bias. The layers are distributed along the normalized height by setting layerSpec to:

    [VectorX([12.5e-3,20e-3,0,.1777]),VectorX([0,12.5e-3,.1777,1]
    

    where each VectorX contains first minimum and maximum diameter, and at least one axial height range (in normalized coordinates).

  2. Brisbane 2:

    PSD: set psdPts to:

    psdPts=[(6.3e-3,0),(12.5e-3,.4111),(20e-3,1)]
    

    Layering (layerSpec) is set as:

    layerSpec=[VectorX([12.5e-3,20e-3, 0,.1777,.5888,1]),VectorX([0,12.5e-3, .177777,.58888]
    

    where the coarse fraction is distributed uniformly over both intervals in 0-0.1777 and 0.5888-1.0.

Resulting heights of fractions vitally depend on relSettlement, so it may take some experimentation to get the result right:

_images/depot-brisbane-3d.png

[py/pre/depot.py]

► General

preCooked(= '')

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

[type: str, not dumped, choices: , Brisbane 1, Brisbane 2, Lhasa 1]

htDiam(= Vector2(0.45, 0.1))

Height and diameter of the resulting cylinder; the initial cylinder has the height of ht0, and particles are, after stabilization, clipped to htDiam, the resulting height.

[type: Vector2, unit: m]

relSettle(= 0.3)

Estimated relative height after deposition (e.g. 0.4 means that the sample will settle around 0.4 times the original height). This value has to be guessed, as there is no exact relation to predict the amount of settling; 0.3 is a good initial guess, but it may depend on the PSD.

[type: float]

mass(= -1.0)

Mass generated (will be precise up to a single particle weight; when negative, generate as much as fits into the volume (see ht0)

[type: float]

ht0(= 0.9)

Initial height (for loose sample), computed automatically from relSettle and htDiam.

[type: float, not dumped, read-only in python]

gen(= <PsdSphereGenerator @ 0x2139cd0>)

Object for particle generation

[type: ParticleGenerator]

bias(= <PsdAxialBias @ 0x25c9700>)

Uneven distribution of particles in space, depending on their radius. Use axis=2 for altering the distribution along the cylinder axis.

[type: SpatialBias]

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

Contact model and materials.

[type: ContactModelSelector]

cylDiv(= 40)

Fineness of cylinder division

[type: int]

unbE(= 0.0001)

Unbalanced energy as criterion to consider the particles settled.

[type: float]

holderMesh(= None)

Import holder from STL file rather than triangulating one. The htDiam is still used to determine where to generate particles.

[type: MeshImport]

► Triangulation output

stlOut(= '')

Output file with triangulated particles (not the boundary); if empty, nothing will be exported at the end.

[type: str, filename]

stlTol(= 0.0002)

Tolerance for STL export (maximum distance between ideal shape and triangulation; passed to _triangulated.spheroidsToStl)

[type: float, unit: m]

stlUnion(= False)

Compute union of surfaces before exporting to STL (removing surface parts which are inside overlapping volumes). This also causes clusters to be exported as separate solids (will be configurable in the future).

[type: bool]

stlCyl(= True)

Export also cylinder surface (top, bottom and lateral surface are separate solids within the STL file.

[type: bool]

scadOut(= '')

Output OpenSCAD script with union of all particles.

[type: str, filename]

sheetOut(= '')

Output particle coordinates and radii as spreadsheet, in any format supported by pyexcel (XLS, XLSX, CSV, ODS, …).

[type: str, filename]

scadCon(= True)

Export cylinders along contacts (for easier meshing of close parts).

[type: bool]

extraHt(= Vector2(0.5, 0.5))

Extra height to be added to bottom and top of the resulting packing, when the new STL-exported cylinder is created.

[type: Vector2, unit: m]

cylAxDiv(= -1.0)

Fineness of division of the STL cylinder; see woo.triangulated.cylinder axDiv. The defaults create nearly-square triangulation

[type: float]

dtSafety(= 0.7)

Timestep safety coefficient.

[type: float]

__call__((Preprocessor)arg1) → Scene[source]
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(**kw)[source]

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

[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 @ 140476931132472 (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__((Preprocessor)arg1) → Scene[source]
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(**kw)[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.

[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 @ 0x262f850>)

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

[type: ParticleGenerator]

model(= <ContactModelSelector @ 140476931147008 (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__((Preprocessor)arg1) → Scene[source]
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(**kw)[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.

[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 @ 140476931544040 (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.7)

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__((Preprocessor)arg1) → Scene[source]
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(**kw)[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.

[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 @ 140476931568056 (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__((Preprocessor)arg1) → Scene[source]
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(**kw)[source]

Chute for studying dissipation of energy.

[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 @ 0x298f100>)

Particle generator, placed above the chute

[type: ParticleGenerator]

model(= <ContactModelSelector @ 140476935406456 (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__((Preprocessor)arg1) → Scene[source]
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(**kw)[source]

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

[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 @ 0x292b2b0>)

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 @ 140476935545384 (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]

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__((Preprocessor)arg1) → Scene[source]
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.staticmixer

Inheritance diagram of woo.pre.staticmixer
woo.pre.staticmixer.prepareMixer(pre)[source]

StaticMixer

ObjectPreprocessorStaticMixer

class woo.pre.staticmixer.StaticMixer(**kw)[source]

Simulation of a static mixer, with segregation analysis

[py/pre/staticmixer.py]

repeatTimes(= 1)

Repeat the mesh this many times axially

[type: int]

gen1(= <PsdSphereGenerator @ 0x1ac9620>)

Generator for the upper stream

[type: ParticleGenerator]

gen2(= <PsdSphereGenerator @ 0x1bfdd90>)

Generator for the lower stream

[type: ParticleGenerator]

model(= <ContactModelSelector @ 140476935546952 (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]

__call__((Preprocessor)arg1) → Scene[source]
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.toys

Inheritance diagram of woo.pre.toys

PourFeliciter

ObjectPreprocessorPourFeliciter

class woo.pre.toys.PourFeliciter(**kw)[source]

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

[py/pre/toys.py]

__call__((Preprocessor)arg1) → Scene[source]
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.

NewtonsCradle

ObjectPreprocessorNewtonsCradle

class woo.pre.toys.NewtonsCradle(**kw)[source]

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

[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 @ 140476935548744 (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__((Preprocessor)arg1) → Scene[source]
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

Got questions? Ask at ask.woodem.org. Report issues to github.