How to quickly reduce unbalancedForce to approximate 0?
Dear all,
I am using the PotentialBlock function to do a regular dodecahedron stacking experiment, but I found that after many time steps unbalancedForce still fluctuates around 1, and the dodecahedron is still shaking. Is there any way to quickly reduce the unbalancedForce or let the polyhedron tend to be stationary and stable.
Thanks in advance.
Jie
Question information
- Language:
- English Edit question
- Status:
- Solved
- For:
- Yade Edit question
- Assignee:
- No assignee Edit question
- Solved by:
- Vasileios Angelidakis
- Solved:
- Last query:
- Last reply:
Revision history for this message
|
#1 |
Hi Jie,
Depends on what stage of your analysis you are.
If you just want to stabilise your sample/particle during initialisation, you can use local damping (in the NewtonIntegrator), which is un-physical but will do the job.
If you want to keep some damping during the main stage of your main simulation, I would advise to not use local damping, but use a small amount of viscousDamping in the KnKsPBLaw instead.
If now you want to stabilise your system during initialisation momentarily, you can invoke "calm()" for some timesteps, to reset the velocity of the particles.
Hope this helps,
Vasileios
Revision history for this message
|
#2 |
Hi Vasileios, and thank you again.
What is the value range of viscousDamping?
Best regards,
Jie
Revision history for this message
|
#3 |
Hi Jie,
The viscousDamping parameter takes values from 0 to 1.0 (it is a percentage) and currently it only applies damping on the normalForce (the shearForce remains undamped for the time being).
Regards,
Vasileios
Revision history for this message
|
#4 |
Thanks Vasileios Angelidakis, that solved my question.
Revision history for this message
|
#5 |
Hi Vasileios, and thank you again.
If I use the calm () function to reset the velocity of the particles, the program appears as follows: shearForce: -nan -nan -nan, normalForce: -0.65154 1.59526 -0.0581212, viscousNormal: -0 0 -0, viscousShear: 0 0 0, geom normal: -0.377888 0.925237 -0.0337099, effective_phi: 1718.87, shearIncrement: 0 0 0, cs: 4.30304, incidentVs: 0 0 0, id1: 865, id2: 1562, debugShear: -0 0 0, phys-> mobilizedShear : -nan.
Some particles disappear, and the non-disappearing particles will then pass through the surface of the container. How to solve this problem?
Best regards,
Jie
Revision history for this message
|
#6 |
Hi Jie,
This is strange. Calm [1] only resets the translational and angular velocity (and the angular momentum), it does not reset forces.
The warning you get comes from [2], which tells you that you have no contact forces (hence the particles pass through boundaries) but I cannot understand why this happens. "Calm" alone cannot cause this behaviour. In order to be more helpful, I need a MWS to reproduce this.
All the best,
Vasileios
[1] https:/
[2] https:/
Revision history for this message
|
#7 |
Hi Vasileios, and thank you again.
I shortened the code, leaving the part where the main problem occurred. At 21,000 steps, I used the calm () function and the above problem occurred. If I don't use the calm () function, I find that after many steps, the entire system is unstable, unbalancedForce fluctuates around 2, and there is no tendency to decrease, which is obviously inconsistent with the actual reality. Can you help by the way to see what is causing this?
Best regards,
Jie
Following is my code:
#################
from yade import polyhedra_
import numpy as np
import math
import random
import os
import errno
try:
os.mkdir('./vtk/')
except OSError as exc:
if exc.errno != errno.EEXIST:
raise
pass
O.engines=[
ForceResetter(),
InsertionSortC
InteractionLoop(
[Ig2_
[Ip2_
[Law2_
),
#GlobalStiffne
NewtonIntegrat
PotentialBlock
]
powderDensity = 3000
O.materials.
#######
meanSize = 0.005
wallThickness = 0.5*meanSize
lengthOfBase = 0.250
heightOfBase = 0.600
#######
sp=pack.
mn,mx=Vector3(
R=sqrt(
sp.makeCloud(
r=0.01*meanSize
aa=[0.525731112
bb=[0.850650808
cc=[-5.
dd=[0.010749786
for s in sp:
b=Body()
b.mask=1
b.aspherical=True
wire=False
color=
highlight=False
b.shape=
wire=wire, highlight=
utils.
b.state.pos = s[0] #s[0] stores center
b.state.ori = Quaternion(
O.bodies.append(b)
#######
r=0.1*wallThickness
bbb=Body()
bbb.mask=3
wire=False
color=[0,0.5,1]
highlight=False
bbb.shape=
utils._
bbb.state.pos = [2*lengthOfBase
O.bodies.
#
bA=Body()
bA.mask=3
wire=False
color=[0,0.5,1]
highlight=False
bA.shape=
utils._
bA.state.pos = [0.5*lengthOfBa
O.bodies.append(bA)
bB=Body()
bB.mask=3
wire=False
color=[0,0.5,1]
highlight=False
bB.shape=
utils._
bB.state.pos = [-0.5*lengthOfB
O.bodies.append(bB)
bC=Body()
bC.mask=3
wire=True
color=[0,0.5,1]
highlight=False
bC.shape=
utils._
bC.state.pos = [2*lengthOfBase
O.bodies.append(bC)
bD=Body()
bD.mask=3
wire=False
color=[0,0.5,1]
highlight=False
bD.shape=
utils._
bD.state.pos = [2*lengthOfBase
O.bodies.append(bD)
#######
def myAddPlotData():
global wallThickness
global meanSize
uf=utils.
if isnan(uf):
uf = 1.0
KE = utils.kineticEn
for b in O.bodies:
if b.state.pos[1] < -5.0*meanSize and len(b.state.
O.bodies.
plot.addData(
from yade import plot
plot.plots=
plot.plot() #Uncomment to view plots
O.engines=
O.engines=
O.dt = 0.2*sqrt(
def still():
if O.iter>21000 and O.iter<22000:
for b in O.bodies:
calm()
from yade import qt
v=qt.View()
v.sceneRadius=3.0
O.saveTmp()
Revision history for this message
|
#8 |
You can change the step size of the calm () function in my code to make it appear earlier, and the same problem will occur.
Revision history for this message
|
#9 |
Hi Jie,
I had a look in your script.
There are several reasons causing instability:
- Your particles pass through the boundaries because the particles forming the boundaries are very thin. A value of wallThickness=0.05 worked well for me.
- frictionAngle must be given in radians, not degrees
- Some particles were erased because you had a statement to erase them inside the myAddPlotData() function
Some further advice:
- Use larger values for "r". If your dodecahedra have an inradius d=0.107, then I would advice using r=0.053 (around half the min(d) value). Please recheck the size of your dodecahedra, because I used d=array(dd)-r in the shape class and I am not sure if you had subtracted "r" from the dd values already.
- calm() resets the velocities of all bodies; no need to put it in a loop
Last, I replaced for you the PotentialBlockV
You can compare the updated script below with your previous script using meld [1]
All the best,
Vasileios
from yade import polyhedra_
import numpy as np
import math
import random
import os
import errno
try:
os.mkdir('./vtk/')
except OSError as exc:
if exc.errno != errno.EEXIST:
raise
pass
#------
# Engines
Kn=1e8
Ks=Kn/10
O.engines=[
ForceResetter(),
InsertionSortC
InteractionLoop(
[Ig2_
[Ip2_
[Law2_
),
NewtonIntegrat
]
O.materials.
#------
# Dimensions
meanSize = 0.05
wallThickness = 0.5*meanSize
lengthOfBase = 0.250
heightOfBase = 0.600
#------
# Make cloud
sp=pack.
mn,mx=Vector3(
R=sqrt(
sp.makeCloud(
#r=0.01*meanSize
aa=[0.525731112
bb=[0.850650808
cc=[-5.
dd=[0.010749786
r=min(dd)/2 #Suggested value
for s in sp:
b=Body()
b.mask=1
b.aspherical=True
color=
b.shape=
utils.
b.state.pos = s[0] #s[0] stores center
b.state.ori = Quaternion(
O.bodies.append(b)
#------
# Bottom plate
color=[0,0.5,1]
r=0.15*
bbb=Body()
bbb.mask=3
wire=False
bbb.shape=
utils._
bbb.state.pos = [2*lengthOfBase
O.bodies.
bA=Body()
bA.mask=3
bA.shape=
utils._
bA.state.pos = [0.5*lengthOfBa
O.bodies.append(bA)
bB=Body()
bB.mask=3
bB.shape=
utils._
bB.state.pos = [-0.5*lengthOfB
O.bodies.append(bB)
bC=Body()
bC.mask=3
bC.shape=
utils._
bC.state.pos = [2*lengthOfBase
O.bodies.append(bC)
bD=Body()
bD.mask=3
bD.shape=
utils._
bD.state.pos = [2*lengthOfBase
O.bodies.append(bD)
#------
# Plot results
def myAddPlotData():
global wallThickness
global meanSize
uf=utils.
if isnan(uf):
uf = 1.0
KE = utils.kineticEn
# for b in O.bodies:
# if b.state.pos[1] < -5.0*meanSize and len(b.state.
# O.bodies.
plot.addData(
from yade import plot
plot.plots=
plot.plot() #Uncomment to view plots
O.engines=
O.engines=
O.dt = 0.2*sqrt(
#------
# Invoke calm()
def still():
KE = utils.kineticEn
if KE<0.01:
calm()
#------
# exportPotential
from yade import export
vtkExporter_
def vtkExport():
vtkExporter_
O.engines=
from yade import qt
v=qt.View()
v.sceneRadius=3.0
O.saveTmp()
Revision history for this message
|
#10 |
A correction: I used meanSize = 0.05. wallThickness is half that.
Cheers,
Vasileios
Revision history for this message
|
#11 |
Thanks Vasileios Angelidakis, that solved my question.
Revision history for this message
|
#12 |
A short comment for future reference: in my experience tricks like "calm()" are needed only when there is another problem in parameters or boundary conditions (e.g. too dynamic).
When the parameters are not doomed calm() only makes the whole thing slower (which is logical: if a system is unbalanced, freezing it will not make it converge faster to equilibrium). It is thus more efficient to track the initial problem when possible.
Bruno