DEM Examples

Loading a particle from mesh

                                    #include <mechsys/dem/domain.h>
                                    #include <mechsys/util/fatal.h>
                                    #include <mechsys/util/util.h>
                                    
                                    using std::cout;
                                    using std::endl;
                                    using Util::PI;
                                    using Util::FmtErr;
                                    using DEM::Domain;
                                    
                                    int main(int argc, char **argv) try
                                    {
                                        // test the mesh particle generation
                                        double R = 0.1;
                                        Domain d;
                                        d.AddFromJson(-1, "test.msh", R, 1.0, 1.0);
                                        d.Particles[0]->Position(OrthoSys::O);
                                        double epsilon = R/pow(d.Particles[0]->Props.V,1.0/3.0);
                                    
                                    
                                        std::cout << "\n--- Results for mass properties from surface integrals --------------------------------------\n";
                                        cout << "  Volume            = " << d.Particles[0]->Props.V << "\n";
                                        cout << "  Center of mass    = " << d.Particles[0]->x(0)    << ", " << d.Particles[0]->x(1) << ", " << d.Particles[0]->x(2) << "\n";
                                        cout << "  Moment of inertia = " << d.Particles[0]->I(0)    << ", " << d.Particles[0]->I(1) << ", " << d.Particles[0]->I(2) << "\n";
                                        cout << "  Quaternion        = " << d.Particles[0]->Q(0)    << ", " << d.Particles[0]->Q(1) << ", " << d.Particles[0]->Q(2) << ", " << d.Particles[0]->Q(3) << "\n";
                                        cout << endl;
                                    
                                    
                                    
                                        d.Particles[0]->Props.V *= 1.0 + 3.0*epsilon;
                                        d.Particles[0]->I       *= 1.0 + 5.0*epsilon;
                                    
                                        std::cout << "\n--- Results for mass properties from surface integrals corrected by spheroradius ------------\n";
                                        cout << "  Volume            = " << d.Particles[0]->Props.V << "\n";
                                        cout << "  Center of mass    = " << d.Particles[0]->x(0)    << ", " << d.Particles[0]->x(1) << ", " << d.Particles[0]->x(2) << "\n";
                                        cout << "  Moment of inertia = " << d.Particles[0]->I(0)    << ", " << d.Particles[0]->I(1) << ", " << d.Particles[0]->I(2) << "\n";
                                        cout << "  Quaternion        = " << d.Particles[0]->Q(0)    << ", " << d.Particles[0]->Q(1) << ", " << d.Particles[0]->Q(2) << ", " << d.Particles[0]->Q(3) << "\n";
                                        cout << endl;
                                    
                                        d.Particles[0]->CalcProps(10000);
                                        // output
                                        std::cout << "\n--- Results for mass properties from Monte Carlo integration -------------------------------\n";
                                        cout << "  Volume            = " << d.Particles[0]->Props.V << "\n";
                                        cout << "  Center of mass    = " << d.Particles[0]->x(0)    << ", " << d.Particles[0]->x(1) << ", " << d.Particles[0]->x(2) << "\n";
                                        cout << "  Moment of inertia = " << d.Particles[0]->I(0)    << ", " << d.Particles[0]->I(1) << ", " << d.Particles[0]->I(2) << "\n";
                                        cout << "  Quaternion        = " << d.Particles[0]->Q(0)    << ", " << d.Particles[0]->Q(1) << ", " << d.Particles[0]->Q(2) << ", " << d.Particles[0]->Q(3) << "\n";
                                        cout << endl;
                                    
                                        // draw
                                        d.WriteXDMF ("test_mesh");
                                        return 0;
                                    }
                                    MECHSYS_CATCH
                                

The example is simpler than the previous one on the collision of two particles. The key component of this example is the function Domain::AddFromJson,

                                        d.AddFromJson(-1, "test.msh", R, 1.0, 1.0);
                                

The first argument is the tag. As explained in the previous example, the tags are used mainly to assign different properties to different sets of particles. The second argument is the name of the file that contains the mesh data to generate the particle. Please open 'test.msh' to see its structure. If you wish to produce your own mesh file using the open source Blender software, please follow Pei Zhang's excellent tutorial that you can find here. Additionally you will need the python plugin to properly export the blender mesh into the Mechsys format .The third argument is the spheroradius which is the key parameter for the collision law (please see the references on the method). The fourth argument is the density which is irrelevant in this example since the particle is not going to move. The fifth argument is the scale factor which is the multiplier of the polyhedron dimensions. There are some more arguments taking default values, please see mechsys/lib/domain.h for details.

The next two lines of code determine the position and correction factors for the particles mass properties,

                                        d.Particles[0]->Position(OrthoSys::O);
                                        double epsilon = R/pow(d.Particles[0]->Props.V,1.0/3.0);
                                

The first one puts the center of mass of the particle in the position Orthosys::O which is the zero vector in Mechsys (Alternatively Vec3_t(0,0,0) could be used). The second line declares a correction parameter epsilon which accounts for the spheroradius dilation. The variable Props.V Is the volume of the Particle.

Next some of the mass properties are reported. Mechsys calculates the mass properties of DEM particles in two ways. The first one and fastest is by using Green's theorem to turn the volume integrals into surface integrals over each face of the polyhedron. Mass properties are the volume, the center of mass x, the principal values of the moment of inertia tensor I (represented as a Vec3_t) and the quaternion representing the current orientation Q

                                        std::cout << "\n--- Results for mass properties from surface integrals --------------------------------------\n";
                                        cout << "  Volume            = " << d.Particles[0]->Props.V << "\n";
                                        cout << "  Center of mass    = " << d.Particles[0]->x(0)    << ", " << d.Particles[0]->x(1) << ", " << d.Particles[0]->x(2) << "\n";
                                        cout << "  Moment of inertia = " << d.Particles[0]->I(0)    << ", " << d.Particles[0]->I(1) << ", " << d.Particles[0]->I(2) << "\n";
                                        cout << "  Quaternion        = " << d.Particles[0]->Q(0)    << ", " << d.Particles[0]->Q(1) << ", " << d.Particles[0]->Q(2) << ", " << d.Particles[0]->Q(3) << "\n";
                                        cout << endl;
                                

Such quantities can be corrected by the correction factor epsilon to account for the dilation of the spheroradious. These corrections should be accurate enough provided the spheroradious is small compared with the dimensions of the polyhedral skeleton.

                                        d.Particles[0]->Props.V *= 1.0 + 3.0*epsilon;
                                        d.Particles[0]->I       *= 1.0 + 5.0*epsilon;
                                

Finally, after reporting them, the last method of mass properties calculation is used, the Monte Carlo integration which is slow but already integrates over the volume of the polyhedral skeleton dilated by the spheroradious. Such calculation is carried out by the Particle::CalcProps method of the Particle class with an argument giving the number of iterations.

                                        d.Particles[0]->CalcProps(10000);
                                

After reporting the mass properties from all these methods, the polyhedra is draw so it can be visualized by the function Domain::WriteXDMF:

                                        d.WriteXDMF ("test_mesh");
                                

This function is called internally when the dynamic loop (function Solve of the previous example) is called as well.