Yade

Printable version | Disclaimers | Privacy policy | Latest revision

Comparisons with PFC3D

Revision as of 11:10, 5 July 2012 by Christian (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Contents

Introduction

This page gives comparisons of CPU times between YADE and Itasca's PFC3D, kindly reported by Christian Jakob.

Model setup

The model for determining calculation speed consists of a regular cubic assembly of particles and a slight angular planar wall underneath.

regular cubic assembly of 10x10x10 particles model after 100.000 steps

A linear contact model (without viscous damping) with stiffness of 106 for the particles and 108 for the walls was chosen. The friction angle is 26,6° (= friction coefficient 0,5) for the wall and the particles. The density of the particles was set to 1000 [kg/m3]. Gravity acts in negative z-direction with 9,81 [m/s2]. A local damping constant of 0,7 was set. The time step was kept constant to 10 − 3 [s] during calculations.

Realization of speed test

To make the results comparably the calculations were performed without graphical user interface. The tests were performed on an Intel Xeon X5460 3,16 GHz (only one core was used). Also no other calculations were performed during the speed test. The same geometries, parameters and model specifications were used for both programs.

Results

The speed test was done with 10x10x10 = 1000 spheres, 20x20x20 = 8000 spheres, ... , 60x60x60 = 216000 spheres. All calculations were performed 20 times with 1000 steps. The average values of the calculation times (in seconds) and the calculation speed (in steps/second) are shown in the following table. Also the relative differences of the calculation times are included (positive, when YADE needed less calc. times).

model dimensions -- number of spheres calc. time PFC in [s] calc. time YADE in [s] steps/second PFC steps/second YADE difference in [%]
10x10x10 -- 1000 0,97 1,06 1034 946,4 -9
20x20x20 -- 8000 29,5 30,3 33,8 33 -2,8
30x30x30 -- 27000 113,1 107,1 8,8 9,3 5,3
40x40x40 -- 64000 284 279 3,5 3,6 1,7
50x50x50 -- 125000 594 567 1,7 1,77 4,6
60x60x60 -- 216000 1130 1007 0,89 0,99 10,9

Calculation times:

calculation times for different numbers of spheres


Calculation speed (semilogy):

calculation speed  for different numbers of spheres

Discussion

For 1000 spheres the calc. times with PFC are 9% lower than with YADE. For 8000 to 125000 spheres calc. times are nearly the same for both programs. With a high number of particles YADE is up to 10% faster than PFC.

Scripts

The script for Yade:

#!/usr/bin/python
# -*- coding: utf-8 -*-
num_balls1D = 20
num_balls = num_balls1D*num_balls1D*num_balls1D
logfilename = 'time-and-speed%iballs.out' % (int(num_balls))
origin_wall = num_balls1D/2
x_pos = 0
y_pos = 0
z_pos = 0
friction=0.5
angle=atan(friction)
id_WallMat=O.materials.append(ViscElMat(kn=1e8,ks=1e8,cn=0.0,cs=0.0,density=1000,frictionAngle=angle))
id_SphereMat=O.materials.append(ViscElMat(kn=1e6,ks=1e6,cn=0.0,cs=0.0,density=1000,frictionAngle=angle))
WallMat=O.materials[id_WallMat]
SphereMat=O.materials[id_SphereMat]
O.engines=[
 ForceResetter(),
 InsertionSortCollider([Bo1_Sphere_Aabb(),Bo1_Box_Aabb()]),
 InteractionLoop(
  [Ig2_Sphere_Sphere_ScGeom(),Ig2_Box_Sphere_ScGeom()],
  [Ip2_ViscElMat_ViscElMat_ViscElPhys()],
  [Law2_ScGeom_ViscElPhys_Basic()],
 ),
 NewtonIntegrator(damping=0.7,gravity=(0,0,-9.81)),
]
#rotation quaternion:
orientationWall = Quaternion(Vector3(.01,.01,1),math.pi)
#create box:
id_box=O.bodies.append(utils.box((origin_wall,origin_wall,-.5),(200,200,.5),orientationWall,fixed=True,material=WallMat))
for ii in range(1,num_balls1D+1):
 x_pos = x_pos + 1
 y_pos = 0
 z_pos = 0
 for jj in range(1,num_balls1D+1):
  y_pos = y_pos + 1
  z_pos = 0
  for kk in range(1,num_balls1D+1):
   z_pos = z_pos + 1
   O.bodies.append(utils.sphere([x_pos,y_pos,z_pos], material=SphereMat, radius=0.5,))
O.dt=1e-3
O.saveTmp()
#### run 20 times 1000 steps to determine average calc. time and calc. speed
sum_time = 0.0
sum_speed = 0.0
for ii in range(1,21):
 if ii != 1:
  O.loadTmp()
 O.run(100,True)		#to get sure, that initial steps do not influence the calculation time measurement
 start_time = O.realtime
 O.run(1000,True)
 stop_time = O.realtime
 calc_time_sec = stop_time-start_time
 calc_speed = 1000/calc_time_sec
 sum_time = sum_time + calc_time_sec
 sum_speed = sum_speed + calc_speed
 print ('------------------- run %i of 20 -------------------'% ii)
 print calc_time_sec
av_speed = sum_speed/20
av_time = sum_time/20
#write output file
f = open(logfilename, 'w')
f.write('av. time: %e / av. speed: %e'% (av_time, av_speed))
f.close()

The script for PFC:

new
call %fist%\2d_3d\fishcall.fis
set echo off
set notice off
def pre_settings
 num_balls1D = 20
 num_balls = num_balls1D*num_balls1D*num_balls1D
 logfilename = 'time-and-speed'+string(num_balls)+'balls.out'
 helpfilename = 'help.out'
 origin_wall = num_balls1D/2
 c_comp_time = 0
 c_write = 0
 id_counter = 0
 sum_time = 0
 sum_speed = 0
 x_pos = 0
 y_pos = 0
 z_pos = 0
 array help(3)
end
pre_settings
def write_help_file
 help(1) = c_write
 help(2) = sum_time
 help(3) = sum_speed
 status=open(helpfilename,1,0)
 status=write(help,3)
 status=close
end
write_help_file
wall id 1 kn 1e8 ks 1e8 friction 0.5 normal 0.02 0.02 1 origin origin_wall origin_wall 0 
def generate_balls
 loop ii (1,num_balls1D)
   x_pos = x_pos + 1
   y_pos = 0
   z_pos = 0
   loop jj (1,num_balls1D)
     y_pos = y_pos + 1
     z_pos = 0
     loop kk (1,num_balls1D)
       z_pos = z_pos + 1
       id_counter = id_counter + 1
       command
         ball id id_counter rad 0.5 x x_pos y y_pos z z_pos density 1000 
         property kn 1e6 ks 1e6 friction 0.5 range id id_counter
       end_command
     end_loop
   end_loop
 end_loop
end
generate_balls
set grav 0 0 -9.81
set dt 1e-3
def get_computer_time
 c_comp_time = c_comp_time + 1
 comp_time_now = clock/100.0
 if c_comp_time = 1
   comp_time_start = comp_time_now
 else
   comp_time_end = comp_time_now
   calc_time_sec = comp_time_end - comp_time_start
   calc_time_min = calc_time_sec/60.0
   calc_time_hour = calc_time_min/60.0
 end_if
end
def lets_go
 command
   get_computer_time
   cycle 1000
   get_computer_time
 end_command
 status=open(helpfilename,0,0)
 status=read(help,3)
 c_write = help(1)
 sum_time = help(2)
 sum_speed = help(3)
 status=close
 c_write = c_write + 1
 calc_speed = 1000/calc_time_sec
 sum_time = sum_time + calc_time_sec
 sum_speed = sum_speed + calc_speed
 
 help(1) = c_write
 help(2) = sum_time
 help(3) = sum_speed
 status=open(helpfilename,1,0)
 status=write(help,3)
 status=close
 oo = out('------------------- run '+string(c_write)+' of 20 -------------------')
end
cycle 100
save model-speed-test-start-condition.sav
;#### run 20 times 1000 steps to determine average calc. time and calc. speed
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go  ;run 5
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go  ;run 10
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go  ;run 15
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go
restore model-speed-test-start-condition.sav
lets_go  ;run 20
def write_output
 av_speed = sum_speed/c_write
 av_time = sum_time/c_write
 help(1)='av. time: '+string(av_time)+' / av. speed: '+string(av_speed)
 status=open(logfilename,1,1)
 status=write(help,1)
 status=close
end
write_output


Find

Browse
YADE Home
Editing wiki
News
Recent changes
Random page
Help
Edit
View source
Editing help
This page
Discuss this page
New section
Printable version
Context
Yade history
What links here
Related changes
My pages
Log in / create account
Special pages
New pages
File list
Statistics
More...