export data with NaN in two data files

Asked by nobody on 2019-10-20

Hi All,
I want to use plot.saveDataTxt command to save data into different files.

the code can run and without errors, but the output data have NaN in these files

here is the code:
#################
from yade import pack, plot,export
import numpy as np
O.bodies.append(geom.facetBox((.5,.5,.5),(.5,.5,.5),wallMask=31))
sp=pack.SpherePack()
sp.makeCloud((0,0,0),(1,1,1),rMean=.1,rRelFuzz=.5, seed =1)
sp.toSimulation()
O.engines=[
 ForceResetter(),
 InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Facet_Aabb()]),
 InteractionLoop(
  [Ig2_Sphere_Sphere_ScGeom(),Ig2_Facet_Sphere_ScGeom()],
  [Ip2_FrictMat_FrictMat_FrictPhys()],
  [Law2_ScGeom_FrictPhys_CundallStrack()]
 ),
 NewtonIntegrator(gravity=(0,0,-9.81),damping=0.4),
 PyRunner(command='checkUnbalanced()',iterPeriod=1000),
 PyRunner(command='addPlotData()',iterPeriod=2500),
 PyRunner(command='coon()',iterPeriod=3000)
]
O.dt=.5*PWaveTimeStep()
print(len(O.bodies))
def checkUnbalanced():
 if unbalancedForce()<.001:
  O.pause()

def addPlotData():
 plot.addData(i=O.iter,unbalanced=unbalancedForce())
 plot.saveDataTxt('data.txt',vars = ("i","unbalanced"))
def coon():
 porosity_cal = utils.voxelPorosity(200,(0,0,0),(0.5,0.5,0.5))
 CoorN=avgNumInteractions(cutoff=0.0, skipFree=False, considerClumps=False)
 plot.addData(i=O.iter,CN=CoorN,porosity=porosity_cal)
 plot.saveDataTxt('CN.txt',vars=("i","CN","porosity"))

##############################

the output of these two files are shown below:
# i CN porosity
2500 nan nan
3000 1.92 0.662186625
5000 nan nan
6000 3.32 0.65279675
7500 nan nan
9000 3.52 0.652999125

####
# i unbalanced
2500 0.527135373123
3000 nan
5000 0.137454303934
6000 nan
7500 0.00701580820745

In the Pyrunner command, I set the iterPeriod to 2500 and 3000. even though I set the iterPeriod to the same, the test files still have NaN.

but I hope the result like this:
##############
# i CN porosity
3000 1.92 0.662186625
6000 3.32 0.65279675
9000 3.52 0.652999125

####
# i unbalanced
2500 0.527135373123
5000 0.137454303934
7500 0.00701580820745

######################
since there is no error, I have no idea why this happens.

best,
yong

Question information

Language:
English Edit question
Status:
Solved
For:
Yade Edit question
Assignee:
No assignee Edit question
Solved by:
Jan Stránský
Solved:
2019-10-20
Last query:
2019-10-20
Last reply:
2019-10-20
Best Jan Stránský (honzik) said : #1

Hi,

plot.data is one dictionary. If you add some data and some not, the not provided data is considered as NaNs:
### a MWE
from yade import plot
plot.addData(a=1,b=2)
plot.addData(c=3,d=4,a=5,b=6)
plot.addData(c=1,d=2)
print(plot.data)
###

So even if you set the same iterPeriod, you call it twice, always with some data missing, resulting in NaNs.
There is no error, because this is intended (and documented) behavior.

cheers
Jan

nobody (nobody01) said : #2

Hi Jan,

which means I can not get the results like this as I mentioned in #1:

##############
# i CN porosity
3000 1.92 0.662186625
6000 3.32 0.65279675
9000 3.52 0.652999125

####
# i unbalanced
2500 0.527135373123
5000 0.137454303934
7500 0.00701580820745

######################

even though we can set whatever variables we want to save it to a txt file, like this: plot.saveDataTxt('CN.txt',vars=("i","CN","porosity")),we just want to save "CN" and "porosity" in this 'CN.txt' file.

we use plot.addData before to include the unbalanced force. so no matter what we do, as long as we export them into several files, we will get the NaNs values.

I think maybe another way to avoid this and get the results I want is to use the pure python method to create a file and then record the data.

or we can still get the results I want by using plot.adddata?

best,
yong

Jan Stránský (honzik) said : #3

There are several ways how to do this:
- some "manual" export
- save is as now and filter NaN values out by some postprocessing
- use several plot.data dicts
- ...

The third method:
###
from yade import plot
O.bodies.append(sphere((0,0,0),1))
newton.gravity = (0,0,-10)
O.engines += [PyRunner(iterPeriod=5,command="plot1()")]
O.engines += [PyRunner(iterPeriod=6,command="plot2()")]
def plot1():
   plot.data = data1
   plot.addData(i=O.iter,v=O.bodies[0].state.vel[2])
def plot2():
   plot.data = data2
   plot.addData(i=O.iter,p=O.bodies[0].state.pos[2])
data1 = {}
data2 = {}
O.run(100,True)
#
plot.data = data1
plot.saveDataTxt("data1.txt")
plot.data = data2
plot.saveDataTxt("data2.txt")
###

plot.addData and plot.saveDataTxt just uses plot.data dictionary, but otherwise does not case about its history, origin etc..

cheers
Jan

nobody (nobody01) said : #4

Thanks Jan Stránský, that solved my question.