The open source software SCoPI written in C++ is designed for the Simulation of Interacting Particle Collections. It enables 2D and 3D simulation of particles (with convex regular shape), interacting with a surrounding medium (obstacles of various types, moving or not, gravity force, possible coupling with a fluid solver) as well as with other particles (inter-particle forces, contacts). The contact model used is of the Contact Dynamics type 1 2. It can be dry (inelastic, with or without friction) or viscous (modeling the force of lubrication in a viscous fluid 3). The algorithms used are implicit and reduce, at each time step, to the solution of a constrained convex problem. The latter can be solved either using the Mosek library, or via projected gradient or accelerated projected gradient algorithms. In the context of an inelastic contact model, it has been used, for example, to study the local rheology of a granular material in front of a towed sphere 4.
Table of Contents
In this section, we propose an example of the simulation of two spheres with opposite velocities.
-
Initialize SCoPI
You have to include
<scopi/scopi.hpp>
file.scopi::initialize("Two spheres simulation");
SCoPI uses cli11 to manage command line options. This initialization just adds a title to your command line options. But, we plan to do much more soon for this step, so get into the habit of using it.
-
Create two spheres
You have to include
<scopi/objects/types/sphere.hpp>
file.constexpr std::size_t dim = 2; scopi::sphere<dim> s1({{-0.2, -0.05}}, 0.1); scopi::sphere<dim> s2({{ 0.2, 0.05}}, 0.1);
We first specify the dimension of our simulation: here is a 2D problem. Then we create two particles represented by spheres. The first argument is the center and the second one is the radius.
SCoPI has other shapes such as superellipsoid, plane, segment and other shapes which are combinations of these.
-
Create the container with all the particles
You have to include
<scopi/container.hpp>
file.scopi::scopi_container<dim> particles; particles.push_back(s1, scopi::property<dim>() .desired_velocity({ {0.25, 0} }) .mass(1.) .moment_inertia(0.1)); particles.push_back(s2, scopi::property<dim>() .desired_velocity({ {-0.25, 0} }) .mass(1.) .moment_inertia(0.1));
To apply a contact solver to our particles and make them move, we need to create a container with all the particles. When you add your particles, you can also mention certain properties such as their velocities, their masses, their rotations... You can also mention that an object is fixed and considered an obstacle.
-
Create the solver and run it
You have to include
<scopi/solver.hpp>
file.double dt = 0.005 scopi::ScopiSolver<dim> solver(particles); std::size_t total_it = 100; solver.run(dt, total_it);
That's it! You have simulated no friction contact of two spheres which is the default behavior.
The whole source file is
#include <scopi/scopi.hpp> #include <scopi/objects/types/sphere.hpp> #include <scopi/container.hpp> #include <scopi/solver.hpp> int main(int argc, char** argv) { scopi::initialize("Two spheres simulation"); constexpr std::size_t dim = 2; scopi::sphere<dim> s1({{-0.2, -0.05}}, 0.1); scopi::sphere<dim> s2({{ 0.2, 0.05}}, 0.1); scopi::scopi_container<dim> particles; particles.push_back(s1, scopi::property<dim>() .desired_velocity({ {0.25, 0} }) .mass(1.) .moment_inertia(0.1)); particles.push_back(s2, scopi::property<dim>() .desired_velocity({ {-0.25, 0} }) .mass(1.) .moment_inertia(0.1)); double dt = 0.005; scopi::ScopiSolver<dim> solver(particles); SCOPI_PARSE(argc, argv); std::size_t total_it = 100; solver.run(dt, total_it); return 0; }
SCOPI_PARSE
allows to get access to internal options. -
Compile using CMake
You can put the script in a file called
two_spheres.cpp
and create aCMakeLists.txt
file with the following contentfind_package(scopi) add_executable(two_spheres two_spheres.cpp) target_link_librairies(two_spheres scopi)
The files must be in the same directory and outside the core scopi project.
Then, you can compile this C++ script using the bash command lines
cmake . -B build -DCMAKE_BUILD_TYPE=Release cmake --build build target all
-
Run
./two_spheres
If you want to see all the options of your executable
./two_spheres -h
If you want to learn more about scopi skills by looking at examples, we encourage you to browse the demos directory.
- Several objects: sphere, superellipsoid, plane, segment, worms...
- Several methods to compute the neighbors of an object: brute force or kd tree
- Several kinds of contact: no friction, friction, viscous, friction and viscous
- Several methods to solve the problem: projected gradient descent, adaptive projected gradient method
Run the cmake configuration
-
With mamba or conda
First, you need to create the environment with all the dependencies installed
mamba env create --file conda/environment.yml mamba activate scopi-env
cmake . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_DEMOS=ON
Build the demos
cmake --build ./build --config Release
If you have any questions or remarks, you can write a message on github discussions, and we will be happy to help you or to discuss with you.
If you want to say thank you or/and support the active development of scopi:
- Add a GitHub Star to the project.
- Tweet about scopi.
- Write interesting articles about the project on Dev.to, Medium or your blog.
Together, we can make scopi better!
First off, thanks for taking the time to contribute! Contributions are what make the open-source community such an amazing place to learn, inspire, and create. Any contributions you make will benefit everybody else and are greatly appreciated.
Please read our contribution guidelines, and thank you for being involved!
This project is licensed under the BSD license.
See LICENSE for more information.
Footnotes
-
Jean, Michel et Moreau, Jean Jacques. Unilaterality and dry friction in the dynamics of rigid body collections. In : 1st contact mechanics international symposium. 1992. p. 31-48. ↩
-
Maury, Bertrand. A time-stepping scheme for inelastic collisions. Numerische Mathematik, 2006, vol. 102, p. 649-679. ↩
-
Lefebvre, Aline. Numerical simulation of gluey particles. ESAIM: Mathematical Modelling and Numerical Analysis, 2009, vol. 43, no 1, p. 53-80. ↩
-
Seguin, A., Lefebvre-Lepot, Aline, Faure, Sylvain, et Gondret, Philippe. Clustering and flow around a sphere moving into a grain cloud. The European Physical Journal E, 2016, vol. 39, no 6, p. 63. ↩