use loadGeometry and ConnectionFinder together - it sort of works but doesn't?
Hi,
At the end there is a question, I promise, but first I thought I describe how I got there.
I have a block of unbonded particles of random size that fall down on a surface. I then wait a bit until all the particles have come to rest so that I have an unmoving heap of particles, and then I do other stuff with that heap, like slowly moving it into a barrier to form a wedge. One thing I wanted to do was create bonds between the particles once they have formed the heap, just to see what might happen.
You can't create new bonds in the middle of the simulation (right?), so I take a checkpointer file from when the heap has come to rest and turn it into a .geo file. The .geo-file then gets loaded in with sim.loadGeometr
"It is not possible to combine readGeometry and ConnectionFinder. ConnectionFinder is only designed to work with geometries created in-simulation, via RandomBoxPacker for example."
But there are ways to work around that. We can make (just make, NOT create!) SimpleSpheres that have the exact same attributes as the particles we just loaded in with loadGeometry, put the Simple Spheres in a list and give that list to ConnectionFinder:
sim.readGeometr
particleList = sim.getParticle
SphereList = []
for particle in particleList:
SSphere = SimpleSphere(
SSphere.
SphereList.
Does this work? Yes! Is it a good idea? I have no idea.
Instead of loading a .geo file (which automatically creates particles) we can load the checkpointer .txt file and create SimpleSpheres based on what is written there:
particleList = []
with open("test1_
for line in inputfile:
numbers = line.split()
if len(numbers) > 5:
particle = SimpleSphere(
particle.
particleList
sim.createParti
This also works, and we don't have to worry about mixing SimpleSpheres and NRotParticles. Both methods deliver the exact same results. But do they deliver the exact same results as if I created the spheres with RandomBoxPacker instead of loading them in?
Sort of. To investigate I made a small simulation: 36 particles created by RandomBoxPacker fall from a height of ~ 8m onto a surface over a time of 5s and 5000 time steps. To control particle mass I use setParticleDens
Anyway, there is an easy way to get around this. When you use loadGeometry you have to use setParticleDensity afterwards, because .geo files don't include mass information. If you load the particle information from the checkpinter .txt file you can just use that mass and don't have to recalculate it with setParticleDensity.
So now I have two simulations that have identical starting conditions, so they should do the exact same thing. The only difference is that one has particles created by RandomBoxPacker, and the other loads them in.
The start looks good: the checkpointer files for both simulations at t=0 are identical. However, at the end of the simulation there is a significant difference. For example the position of one particle: RBP (0.725675323 0.479624327 0), load (0.699173192 0.611043039 0)
If the particles are all the same and the forces are all the same the simulations should be identical, right? There should be absolutely no randomness in a DEM simulation, so where does the difference come from?
Here is the code for the test simulation. Just comment/uncomment the proper block and change checkpoint name to switch between simulations
from esys.lsm import *
from esys.lsm.util import *
from esys.lsm.geometry import *
# create simulation container object
sim = LsmMpi(
sim.initNeighbo
particleType = "NRotSphere",
gridSpacing = 1.25,
verletDist = 0.05)
# force 2D computation
sim.force2dComp
# specify number of timesteps an increment
sim.setNumTimeS
sim.setTimeStep
# specify spatial domain
sim.setSpatialD
bBox = BoundingBox(
circDimList = [False,
# construct rectangle of unbonded particles with non-uniform size
packer = RandomBoxPacker(
minRadius = 0.25,
maxRadius = 0.5,
cubicPackRadius = 1.1,
maxInsertFails = 1000,
bBox = BoundingBox(
circDimList=
tolerance = 1.0e-5)
packer.generate()
particleList = packer.
for particle in particleList:
particle.setTag(1)
sim.createPart
"""
# load particles
particleList = []
with open("bondtest1
for line in inputfile:
numbers = line.split()
if len(numbers) > 5:
particle = SimpleSphere(
particle.
particleList
sim.createParti
"""
# bind particles
sim.createConne
ConnectionFinder(
maxDist = 0.05,
bondTag = 1,
pList = particleList))
# specify the bond between particles
BondGrp = sim.createInter
NRotBondPrms(
name = "particleBonds",
normalK = 100.0,
breakDistance = 3,
tag = 1,
scaling = True))
# add wall to the bottom of the simulation
sim.createWall(
name = "bottomWall",
posn = Vec3(0,0,0),
normal = Vec3(0,1,0))
# add repulsion to floor
sim.createInter
NRotElasticWal
name = "bottomWallRepu
wallName = "bottomWall",
normalK = 10000))
# friction between particles
sim.createInter
NRotFrictionPrms(
name = "pp-friction",
normalK = 1000,
dynamicMu = 0.6,
shearK = 100,
scaling = True))
# set particle density
# sim.setParticle
# add gravity
sim.createInter
GravityPrms(
# add damping
sim.createInter
LinDampingPrms(
name = "damping",
viscosity = 1,
maxIterations = 100))
# create check pointer as data output
sim.createCheck
CheckPointPrms(
fileNamePrefix = "bondtest1_chkptr",
beginTimeStep = 0,
endTimeStep = 5000,
timeStepIncr = 1000))
# execute simulation
sim.run()
Question information
- Language:
- English Edit question
- Status:
- Expired
- Assignee:
- No assignee Edit question
- Last query:
- Last reply: