3D Particle Life

    Hello! I decided to share with my readers my small experiments with particle systems in three-dimensional space. I took as a basis the publication on Habré about experiments with particles in 2D space.



    Let's start with a link to an article that pushed me to action. But there is another reason, since recently I’ve been moving more and more to Ubuntu in my experiments, a lot of things have been good since the free installation of the OS and then on the list of pluses. There are minuses, I have a struggle with drivers for non-standard OS installation like two video cards and several monitors.


    I took C ++ as the basis, added support for CUDA as a computing platform, there are a lot of particles and the central processor obviously can not cope with such a load in real time, and the Ogre3D graphics engine for them in the company. They made the porridge, I will season the Gif narrative with animations and quotes from the article on the 2D version of the simulation.


    “First, I followed in the footsteps of the“ life ”game: each particle has a“ overpopulation ”counter, which is equal to the sum of the inverse squares of the distances to other particles. If this counter is less than a certain limit, that is, there are few neighbors, then the particle is attracted to other particles, and if there are many neighbors, it repels, if the particles intersect, then they repel in any case, so as not to pass through each other.


    We randomly scatter particles around the field and see what happens. "



    Advanced version of the video
    Now a little about the logic of what is happening in the program. An array of particles with certain parameters is created. Some of the parameters are responsible for physical properties: radius, mass, speed, etc., part for creating bonds between particles, such as: type of particles, number of particle connections with other particles, etc. On average, I used from 700 to 3000 particles in the simulation, since I wanted to count in real time, a larger value led to inhibition of the picture due to the increase in the volume of calculations. Then all this stuff is transferred to the memory of the video card, where the GPU, in the strong parallelization mode, processes three main subprograms: simulation of particle motion, processing of particle collisions (collisions) and the formation and destruction of bonds between particles.


    “We are changing the rules of the game. We will no longer count neighbors. Let the particles simply attract or repulse depending on their types. If all particles are of the same type, then there are only 2 options: they either all repel or all attract.”


    I tried several options for attractive-repulsive forces, linear dependencies on the distances between particles, inversely proportional to the distance, etc. settled on the inverse quadratic dependence, but with a restriction on the radius of action, something like 45 particle radii.



    "We won’t change the rules much. Instead, we’ll add a new feature. Now the particles will form bonds at a short distance. If the particles are connected, they are constantly attracted to each other. This attraction does not weaken with the distance. But, if the distance is above a certain threshold, then the connection is broken. "


    Here, the rule changed a little, introduced the distance of bond formation, it is the distance of bond destruction and the resting distance of the particle in the bond, that is, the particle is constantly trying to take a position near the resting position, therefore, at discrete time, the particle oscillates near the zero position. This is visible on all videos. It’s possible to apply more complex laws when forming a bond like elasticity, but for now I’ve simplified it, yet we have a “primary soup” and not a solid substance.



    Advanced Video


    or as a picture



    Then the trial and error process began. Firstly, programming on the GPU requires extra care regarding the so-called "races on read-modify-write of shared data", which means that there may be problems when several threads simultaneously try to change the variable. Instabilities arise like these:



    Then it was necessary to limit the area of ​​space in which the experiment takes place, the first thing that came to mind is a cube. But thanks to the bugs of the first versions of the program, particles boldly crawled out of it, forming something similar to space stations from the fiction of the 70s.



    extended version of video


    As the saying goes, if not a cube, then let there be a ball:



    Here the logic is that after the departure from the center of the particle, a force begins to act opposite to its movement, which even looks like gravity.


    __device__ static int Links[3][3] =      {{1,0,1},{1,0,0},{1,1,0}};
    __device__ static int LinksField[3][3] = {{0,0,0},{0,0,1},{0,0,0}};
    __device__ static int LinkTypeSize[3] =  {3,8,2};
    __device__ static int LinkTypePP[3][3] = {{0,1,1},{8,1,6},{0,1,1}};

    He brought a piece of code as it is, these are matrixes of interaction of three types of particles with each other.
    -the first line is the principle of forming bonds: 1 there is the opportunity to establish a connection with another particle, 0, respectively, no.
    -the second line is the law of attraction of repulsion of particles. In fact, in this embodiment, all repel each other, except for the attraction of the second type of particles to the third. You can of course mirror the matrix, but in this case.
    -th third line is the number of common particle bonds by type.
    -fourth is the number of particle bonds with each type of particle. The first type, for example, cannot form a bond with itself.


    We get particles in a strong Brownian motion:



    extended version of video


    I had to introduce energy loss in collisions.



    extended version of video


    Everything has become too static, we reduce the forces of particle interaction.



    extended version of video


    If you watch the video, you can see how the frame is being built. Then it remains static anyway.


    We change the rules regarding matrix coefficients.



    extended version of the video.
    We see the formation of a likeness of organic molecules. There are even benzene rings.



    Another video demonstrates what will happen if you change the length of the bonds between particles in the dynamics, from the second minute of the video this is especially pronounced.



    But we must try to repeat the version of the 2D author, whose quotes are in the body of the article. There is a variant of such a "life":



    or such



    Что можно добавить? Во первых Исходники программы. Во вторых на хабре есть несколько статей с описанием клеточных автоматов или пободных систем(в теории клеточный автомат является эквивалентом машины Тьюринга) с вынесенным заголовком включающим слово "жизнь", поэтому и решил тоже использовать его, вроде как традиция. Хотя это скорее просто каледоскоп, простые правила порождают сложное поведение, как частицы и система зеркал в детской игрушке.


    И еще ролик добавил, на самом деле завораживающая картина, то кажутся молекулы, то нейросети, но жизни пока там нет. Как вариант развития генетику нужно добавлять, но непонятно, что может являться фитнес функцией для этих "существ".



    I hope someone will like it and it will step further from 3D as the author has stepped from 2D. The main thing for myself was repeating the lessons on CUDA and Ogre3D under Ubuntu.



    And there will be ideas write, maybe we’ll come up with something interesting :)


    Also popular now: