DEM Examples
Collision of 2 particles
This tutorial aims to build the simulation for 2 bodies colliding in an elastic way. The user declares a sphero-cube and a sphero-tetrahedron in a collision course. The energy, liner and angular momenta can be measured to check these conservation laws. The whole simulation is described in the following code which will be explained in detail:// MechSys #include <mechsys/dem/domain.h> int main(int argc, char **argv) try { DEM::Domain dom; // add cube Vec3_t x(-10,0,0); Vec3_t v(1.,0,0); Vec3_t w(0,M_PI/5,0); dom.AddCube (/*Tag*/-1, /*Position*/x,/*SpheroRadius*/0.3,/*Length*/3.,/*Density*/1.); dom.Particles[0]->v = v; dom.Particles[0]->w = w; // add tetrahedron x = 10.0, 0 , 0; w = 0.0, 0 , M_PI/10.; v = -1.0, 0 , 0; dom.AddTetra (/*Tag*/-1, /*Position*/x,/*SpheroRadius*/0.5,/*Length*/5.,/*Density*/1.); dom.Particles[1]->v = v; dom.Particles[1]->w = w; // particle parameters Dict D; D.Set(-1,"Gn Gt Mu",0.0,0.0,0.0); dom.SetProps(D); // initial constants Vec3_t l0; Vec3_t p0; double Ek0,Ep0,E0; dom.LinearMomentum (p0); dom.AngularMomentum (l0); E0 = d.CalcEnergy (Ek0,Ep0); // solve dom.CamPos = 0.0,30.0,0.0; dom.Solve(/*tf*/30.0, /*dt*/1.0e-4, /*dtOut*/0.3, NULL, NULL, /*filekey*/"test_dynamics"); // final constants Vec3_t l1; // initial linear momentum Vec3_t p1; // initial angular momentum double Ek1,Ep1,E1; // initial energy dom.LinearMomentum (p1); dom.AngularMomentum (l1); E1 = dom.CalcEnergy (Ek1,Ep1); // check double tol = 1.0e-3; double err_l = norm(l1-l0); double err_p = norm(p1-p0); double err_E = fabs(E1-E0); double error = err_l + err_p + err_E; cout << "Error in energy = " << err_E << endl; cout << "Error in angular momentum = " << err_l << endl; cout << "Error in linear momentum = " << err_p << endl; // results if (error > tol) return 1; else return 0; } MECHSYS_CATCH
Initialization
MechSys/DEM simulations are prepared with a C++ source code. The first step is to include the required MechSys libraries. In this case the file domain.h contains the DEM domain definitions:
#include <mechsys/dem/domain.h>
Simulation script structure
The simulation script structure is:
#include ... int main(int argc, char **argv) try { ... } MECHSYS_CATCH
After including the required MechSys' libraries (and C++ standard libraries, if necessary), the main
function is declared.
For MechSys, it is important to add the try
keyword just after
the int main()
and before the first opening brace {
. Then, after the last closing
brace the MECHSYS_CATCH
is added.
Declaring the DEM Domain and Particles
The line,
DEM::Domain d;
declares the container dom
of the class
DEM::Domain
. This class defines the DEM universe and also has many functions
to include particles, some of which will be used in this tutorial.
To declare the cube, some 3D vectors are needed. The Vec3_t
data type is used
for fast vectorial operations:
Vec3_t x(-10,0,0); Vec3_t v(1.,0,0); Vec3_t w(0,M_PI/5,0);
The vectors x
v
w
define respectively the cube center position, its linear velocity and its angular velocity. The declared angular velocity ensures that the cube will
spin around the y-axis counter clockwise. Once these three vectors are declared, the cube is introduced into the domain:
dom.AddCube (/*Tag*/-1, /*Position*/x,/*SpheroRadius*/0.3,/*Length*/3.,/*Density*/1.);
This function creates a cube into the memory. The first argument is a Tag which will be useful later on. The second is the position vector declared above. Next is the Sphero-Radius which is the radius of the rounded corners, and is required for the collision law. Ideally this spheroradius should be large enough so the overlapping between the colliding particles is small compared to the particles dimensions. The 4th argument is the length of the cube's edges and finally the density of the cube is also declared.
The method, however, initializes the particle at rest and without rotation. Therefore, to add the vector velocities, internal variables must be accessed:
dom.Particles[0]->v = v; dom.Particles[0]->w = w;
The object dom.Particles
is an array that contains the memory pointers to all the particles created in the domain dom
. To access
the first particle, which is the cube, the index 0
must be introduced. Therefore dom.Particles[0]
is a pointer to the cube. The internal vector variables v
and w
are the cube's linear and angular velocity vectors.
In a similar way the tetrahedron is included at the right side of the cube moving towards it:
x = 10.0, 0 , 0; w = 0.0, 0 , M_PI/10.; v = -1.0, 0 , 0; dom.AddTetra (/*Tag*/-1, /*Position*/x,/*SpheroRadius*/0.5,/*Length*/5.,/*Density*/1.); dom.Particles[1]->v = v; dom.Particles[1]->w = w;
With both particles properly defined, some collision parameters must be set. MechSys uses the spheropolyhedra method to model the collision of
solid objects. The collision law is defined by two spring constants Kn
and Kt
; two dissipative constants Gn
and Gt
; and a friction coefficient μ. Since this simulation deals with an elastic collision, the
two dissipative constants and the friction coefficient must be set to zero. In MechSys this is achieved by the use of dictionaries as follows:
Dict D; D.Set(-1,"Gn Gt Mu",0.0,0.0,0.0); dom.SetProps(D);
Where the dictionary D
contains the user information on the new parameters. The first argument of the
function D.Set
is the particle's tag. Hence different groups of particles can be associated with different
collision parameters. The elastic parameters Kn
and Kt
(as Kn
and Kt
in the dictionary string) can also be included into the dictionary, however for this example we will work
with their default values.
Starting the simulation
To check the conservation laws some values must be calculated before the simulation starts:
Vec3_t l0; Vec3_t p0; double Ek0,Ep0,E0; dom.LinearMomentum (p0); dom.AngularMomentum (l0); E0 = d.CalcEnergy (Ek0,Ep0);
The vectors l0
and p0
will store the linear and angular momenta given by the functions dom.LinearMomentum
and dom.AngularMomentum
. The three numbers Ek0
, Ep0
and E0
will be respectively the total kinetic energy, the
total potential energy and the total energy as given by the function dom.CalcEnergy
. This variable will be kept in memory to be compared with the situation after the simulation.
With the DEM universe defined, the simulation will begin. First, for future visualization, is useful to define the position of a camera:
dom.CamPos = 0.0,30.0,0.0;
Then the system evolves for as long as defined by the user by means of the dom.Solve
:
dom.Solve(/*tf*/30.0, /*dt*/1.0e-4, /*dtOut*/0.3, NULL, NULL, /*filekey*/"test_dynamics");
The system will evolve in this case up to tf = 30.0
seconds of simulation time. The next
argument is the integration time step dt
, the smaller the more accurate the simulation is but also the more
time consuming. The 3rd argument is the report time step, in other words, the time span between movie frames. The next two arguments are
pointers to functions which are not explained in this simple example. This functions may be called from inside the Solve function, and hence offer
some control over the evolution of the system from outside. Finally, the last argument is a file key which is used to identify the report and
animation files form this simulation.
At the end of the simulation, the same variables that were measured before it are measured again:
Vec3_t l1; Vec3_t p1; double Ek1,Ep1,E1; dom.LinearMomentum (p1); dom.AngularMomentum (l1); E1 = d.CalcEnergy (Ek1,Ep1);
And compared with their initial values:
double tol = 1.0e-3; double err_l = norm(l1-l0); double err_p = norm(p1-p0); double err_E = fabs(E1-E0); double error = err_l + err_p + err_E; cout << "Error in energy = " << err_E << endl; cout << "Error in angular momentum = " << err_l << endl; cout << "Error in linear momentum = " << err_p << endl;
After compiling and running, the simulation should give this results
Error in energy = 0.128839 Error in angular momentum = 0.000122599 Error in linear momentum = 8.30147e-10
Unfortunately the conservation laws are not exactly met in the DEM and therefore there is a difference between the initial and final values. As mentioned before this error can be tuned down with the integration time step
Simulation visualization
MechSys uses VisIt to visualize simulation results. A full tutorial can be found here. After following the instructions the dynamics of the system should resemble the following video: