Extract 2D cross-sections from the 3D sphere pack.

Asked by Ram

Hi All,

I modified the GravityDeposition.py from the examples for my case. Particularly, the 'checkUnbalanced()' function and here is how it looks:

def checkUnbalanced():
   if unbalancedForce() < .1:
      sp.toSimulation() # Add small sphere pack to the simulation until there are at least 100 bodies.
      O.run();
      if (len(O.bodies) > 100):# and (unbalancedForce() < .1): #O.bodies.numberOfGrains() > 5000
       O.run();
       if unbalancedForce() < .1:
        O.pause()
        #plot.saveDataTxt('bbb.txt.bz2')
        ### Write cross-sections to image files. ###
  X,Y,Z = np.meshgrid(np.arange(int(2*cylRad)),np.arange(int(2*cylRad)),np.arange(int(cylHt)),sparse=True,copy=False);
  F = np.zeros(X.shape);
  print len(O.bodies)
  for i in range(len(O.bodies)):
   b = O.bodies[i]
   if isinstance(b.shape,Sphere):
    a = b.state.pos
    idx = (np.sqrt((X - a[0])**2 + (Y - a[1])**2 + (Z - a[2])**2) <= b.shape.radius[i]).nonzero()
    F[idx] = 128;
  Xres = np.arange(int(4*cylRad)); Yres = np.arange(int(4*cylRad)); Zres = np.arange(int(2*cylHt));
  from scipy.interpolate import griddata
  I = griddata([X,Y,Z],F,[Xres,Yres,Zres],method='cubic');

In the above code, I have difficulty (or am getting errors) reproducing the assignment of F and the correct way to pass arguments to 'griddata' function. Could anyone please point out the correct way to do it?

** Following are the error messages**

Corresponding to assignment of 'idx' in my Python code, I get following error:

    --> 132 idx = (np.sqrt((X - spherePos[i,0])**2 + (Y - spherePos[i,1])**2 + (Z - spherePos[i,2])**2) <= sphereRad[i]).nonzero()
        133 F[idx] = 128;
        134 Xres = np.arange(int(4*cylRad)); Yres = np.arange(int(4*cylRad)); Zres = np.arange(int(2*cylHt));

    TypeError: 'float' object has no attribute '__getitem__'

If I comment the lines involving assignment of 'idx' and 'F' in my Python code, I get following error:

    /usr/lib/python2.7/dist-packages/scipy/interpolate/ndgriddata.pyc in griddata(points, values, xi, method, fill_value)
    177 xi, = xi
    178 # Sort points/values together, necessary as input for interp1d
    --> 179 idx = np.argsort(points)
        180 points = points[idx]
        181 values = values[idx]

    /usr/lib/python2.7/dist-packages/numpy/core/fromnumeric.pyc in argsort(a, axis, kind, order)
        873 except AttributeError:
        874 return _wrapit(a, 'argsort', axis, kind, order)
    --> 875 return argsort(axis, kind, order)
        876
        877

    ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

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
Jérôme Duriez (jduriez) said :
#1

Do the provided error message and script really match ??

Your script seems to express "idx" according to "a", whereas the error message shows an "idx" expression according to "spherePos".....
Exception of the name difference, one should visibly have one index: "a[0]", whereas spherePos should have two: "spherePos[i,0]"...

As an of-topic remark "for i in range(len(O.bodies)): b = O.bodies[i]" may be directly replaced by "for b in O.bodies:". See any example of the doc, e.g. in https://yade-dem.org/doc/tutorial-data-mining.html#local-data

Revision history for this message
Ram (prasad3130) said :
#2

Thanks for your reply Jerome. Sorry for the delay.

There was a mix up in posting my question above. Essentially, I am trying to convert the following Matlab code to Python:

[X,Y,Z] = meshgrid(linspace(1,cylRad,100),linspace(1,cylRad,100),linspace(1,cylHt,100));
F = zeros(size(X));
for i = 1:numParticles
    F( sqrt((X - spherePos(i,1)).^2 + (Y - spherePos(i,2)).^2 + (Z - spherePos(i,3)).^2) <= sphereRad(i) ) = 128;
end

In the above code, cylRad, cylHt, are defined. numParticles is essentially len(O.bodies) and spherePos is an array of the centers of the spheres in the packing. The above code essentially sets a value of 128 for the voxels belonging to spheres and 0 elsewhere. So, in particular I am having difficulty in the line assigning value 128 in array F.

--
Thanks.

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

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