How can interact spheres with the moving facet when using MPI?

Asked by JINSUN LEE

Hello, everyone. I always appreciate your kind support.

I am trying to apply overburden pressure using a downward-moving topcap (or facet) in an MPI environment. However, the moving facet does not interact with the spheres (although it does interact when using O.run).

I have found a previous related question (https://answers.launchpad.net/yade/+question/700164) and an example (https://gitlab.com/yade-dev/trunk/-/tree/master/examples/DEM2020Benchmark), but I am unable to figure out the correct way to make the facet interact with the spheres.

Could you please let me know the correct way to achieve this?

Thank you in advance.

Regards.

Ubuntu (22.10)
YADE (2022.01a)

=== MWE ===

from yade import pack, plot
from yade import mpy as mp
O.materials.append(FrictMat(young=20e6, poisson=0.17, density=2700, frictionAngle=0.523, label='frictmat'))
O.materials.append(FrictMat(young=20e6, poisson = 0.5, frictionAngle = 0.523, density =2600, label='wallMat'))
O.bodies.append(geom.facetBox((0.0, 0.0, 0.0), (.03, .03, .06), wallMask=31, material='wallMat'))

#radius_mean = .002

# create topcap
width = 0.06
height = 0.17
dx = width/10.0
dy = width/10.0
p5t = (-width/2-dx,-width/2-dy,0.06)
p6t = (-width/2-dx,width/2+dy,0.06)
p7t = (width/2+dx,width/2+dy,0.06)
p8t = (width/2+dx,-width/2-dy,0.06)

topcap1 = utils.facet(vertices=[p5t,p6t,p7t], wire=True, highlight=False)
topcap2 = utils.facet(vertices=[p5t,p8t,p7t], wire=True, highlight=False)

O.bodies.append(topcap1)
O.bodies.append(topcap2)
O.bodies[10].state.vel=(0.0,0.0,-0.5)
O.bodies[11].state.vel=(0.0,0.0,-0.5)

mn,mx=Vector3(-.03,-.03,-.06),Vector3(.03,.03,.05)
pred = pack.inAlignedBox(mn,mx)
O.bodies.append(pack.regularHexa(pred,radius=0.002,gap=0, material='frictmat'))

O.engines = [
    ForceResetter(),
    InsertionSortCollider([Bo1_Sphere_Aabb(), Bo1_Facet_Aabb()], label='collider'), # always add label
    InteractionLoop(
            [Ig2_Sphere_Sphere_ScGeom(), Ig2_Facet_Sphere_ScGeom()], # collision geometry
            [Ip2_FrictMat_FrictMat_FrictPhys()], # collision "physics"
            [Law2_ScGeom_FrictPhys_CundallStrack()] # contact law -- apply forces
    ),
    NewtonIntegrator(gravity=(0, 0, -9.81), damping=0.08),
# VTKRecorder(fileName='mpi/3d-vtk-', recorders=['spheres', 'intr', 'facets', 'colors'], parallelMode=True, iterPeriod=100), #use .pvtu to open spheres, .pvtp for ints, and .vtu for boxes.
    PyRunner(command='addData()', iterPeriod=1000),
    PyRunner(command='control_run()', iterPeriod=100),
    DomainLimiter(lo=(-.1,-.1,-.20), hi=(.1,.1,.20), iterPeriod = 100, label = 'Domain') # destroy balls outside domain in every 100 steps
]

def addData():
     for b in O.bodies:
         b.shape.color=scalarOnColorScale(b.state.vel.norm())

def control_run():
    print ("Current step is ", O.iter, end='\r')

collider.verletDist = -.5

O.dt=0.5*PWaveTimeStep()
O.resetTime()

print("Number of bodies = ", len(O.bodies))

# w/o MPI
#O.run(nSteps= 10000, wait=False)

# MPI
mp.VERBOSE_OUTPUT = False
mp.REALLOCATE_FREQUENCY = 5
mp.ACCUMULATE_FORCES = False
mp.MAX_RANK_OUTPUT = 4
mp.DOMAIN_DECOMPOSITION = True
mp.MERGE_W_INTERACTIONS = False
mp.mpirun(nSteps=10000, np = 5, withMerge=True) # interactive run, numThreads is the number of workers to be initialized, see below for withMerge explanation.
mp.mergeScene()

Question information

Language:
English Edit question
Status:
Expired
For:
Yade Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
Joe L. Thompson (joelthompsons) said :
#1

To make the moving facet interact with the spheres in an MPI environment, you need to take a few steps.

First, you will need to specify that the moving facet is a rigid body, which can be achieved by setting its "dynamic" property to True:

topcap1.dynamic = True
topcap2.dynamic = True

Secondly, you will need to add the moving facet to the list of bodies in the interaction loop engine. This can be done by adding the following line before the InteractionLoop engine:

O.bodies.append(topcap1)
O.bodies.append(topcap2)

Lastly, you will need to include interactions between the moving facet and the other bodies using the appropriate collision geometry and interaction groups in the InteractionLoop engine:

InteractionLoop(
    [Ig2_Sphere_Sphere_ScGeom(), Ig2_Facet_Sphere_ScGeom(), Ig2_Facet_Facet_ScGeom()],
    [Ip2_FrictMat_FrictMat_FrictPhys()],
    [Law2_ScGeom_FrictPhys_CundallStrack()]
),

The line Ig2_Facet_Facet_ScGeom() is added to allow the facet-facet interaction.

With these changes, the moving facet should now interact with the spheres in your simulation when run using MPI.

Revision history for this message
JINSUN LEE (ppk21) said :
#3

Unfortunately, I think that this answer is made using ChatGPT or other bots.
The moving facet will disappear if it's state is defined as dynamic (topcap1.dynamic = True) and there is no Functor "Ig2_Facet_Facet_ScGeom()"

Revision history for this message
Jan Stránský (honzik) said :
#4

> Unfortunately

it depends :-)

> I think that this answer is made using ChatGPT or other bots.

it definitely looks like that.
It looks very naturally and promising.. until you start to investigate the details..

> The moving facet will disappear if it's state is defined as dynamic (topcap1.dynamic = True)

just for reference, you need to set non-zero mass, then it should not disappear

Cheers
Jan

Revision history for this message
JINSUN LEE (ppk21) said :
#5

Dear Stránský,

Thanks to your comment.
In this case, the non-zero mass facets still disappear. The followings are MWE.

Regards,

=====

from yade import pack, plot
from yade import mpy as mp
O.materials.append(FrictMat(young=20e6, poisson=0.17, density=2700, frictionAngle=0.523, label='frictmat'))
O.materials.append(FrictMat(young=20e6, poisson = 0.5, frictionAngle = 0.523, density =2600, label='wallMat'))
O.bodies.append(geom.facetBox((0.0, 0.0, 0.0), (.03, .03, .06), wallMask=31, material='wallMat'))

#radius_mean = .002

# create topcap
width = 0.06
height = 0.17
dx = width/10.0
dy = width/10.0
p5t = (-width/2-dx,-width/2-dy,0.06)
p6t = (-width/2-dx,width/2+dy,0.06)
p7t = (width/2+dx,width/2+dy,0.06)
p8t = (width/2+dx,-width/2-dy,0.06)

topcap1 = utils.facet(vertices=[p5t,p6t,p7t], wire=True, highlight=False, material='wallMat')
topcap2 = utils.facet(vertices=[p5t,p8t,p7t], wire=True, highlight=False, material='wallMat')

topcap1.dynamic = True
topcap2.dynamic = True

O.bodies.append(topcap1)
O.bodies.append(topcap2)

#topcap1.state.vel=(0.0,0.0,-0.5)
#topcap2.state.vel=(0.0,0.0,-0.5)

mn,mx=Vector3(-.03,-.03,-.06),Vector3(.03,.03,.05)
pred = pack.inAlignedBox(mn,mx)
O.bodies.append(pack.regularHexa(pred,radius=0.002,gap=0, material='frictmat'))

O.engines = [
    ForceResetter(),
    InsertionSortCollider([Bo1_Sphere_Aabb(), Bo1_Facet_Aabb()], label='collider'), # always add label
    InteractionLoop(
            [Ig2_Sphere_Sphere_ScGeom(), Ig2_Facet_Sphere_ScGeom()], # collision geometry
            [Ip2_FrictMat_FrictMat_FrictPhys()], # collision "physics"
            [Law2_ScGeom_FrictPhys_CundallStrack()] # contact law -- apply forces
    ),
    NewtonIntegrator(gravity=(0, 0, -9.81), damping=0.08),
# VTKRecorder(fileName='mpi/3d-vtk-', recorders=['spheres', 'intr', 'facets', 'colors'], parallelMode=True, iterPeriod=100), #use .pvtu to open spheres, .pvtp for ints, and .vtu for boxes.
    PyRunner(command='addData()', iterPeriod=1000),
    PyRunner(command='control_run()', iterPeriod=100),
    DomainLimiter(lo=(-.1,-.1,-.20), hi=(.1,.1,.20), iterPeriod = 100, label = 'Domain') # destroy balls outside domain in every 100 steps
]

def addData():
     for b in O.bodies:
         b.shape.color=scalarOnColorScale(b.state.vel.norm())

def control_run():
    print ("Current step is ", O.iter, end='\r')

collider.verletDist = -.5

O.dt=0.5*PWaveTimeStep()
O.resetTime()

print("Number of bodies = ", len(O.bodies))

# w/o MPI
#O.run(nSteps= 10000, wait=False)

# MPI
mp.VERBOSE_OUTPUT = False
mp.REALLOCATE_FREQUENCY = 5
mp.ACCUMULATE_FORCES = False
mp.MAX_RANK_OUTPUT = 4
mp.DOMAIN_DECOMPOSITION = True
mp.MERGE_W_INTERACTIONS = False
mp.mpirun(nSteps=1000, np = 5, withMerge=True) # interactive run, numThreads is the number of workers to be initialized, see below for withMerge explanation.
mp.mergeScene()

Revision history for this message
Launchpad Janitor (janitor) said :
#6

This question was expired because it remained in the 'Open' state without activity for the last 15 days.