ПривеТ! Решил поделиться с читателями своими небольшими экспериментами с системами частиц в трехмерном пространстве. За основу взял публикацию на Хабре об экспериментах с частицами в 2D пространстве.



Начнем со ссылки на статью которая меня и подтолкнула к действию. Но есть еще одна причина, с недавнего времени все больше перехожу в своих экспериментах на Ubuntu, многое радует начиная со свободной установки ОС и далее по списку плюсов. Минусы есть, у меня это борьба с драйверами при нестандартной установке ОС вроде двух видеокарт и нескольких мониторов.


За основу взял с++, добавил поддержку CUDA как вычислительной платформы, частиц много и центральный процессор явно не справится с такой нагрузкой в реальном времени и графический движок Ogre3D к ним в компанию. Кашу заварили, буду приправлять повествование Gif анимацией и цитатами из статьи о 2D варианте симуляции.


"Сначала я пошёл по стопам игры «жизнь»: у каждой частицы есть счётчик “перенаселения”, который равен сумме обратных квадратов расстояний до других частиц. Если этот счётчик меньше определённого предела, то есть соседей мало, то частица притягивается к другим частицам, а если соседей много — отталкивается. Если частицы пересекаются, то они отталкиваются в любом случае, чтобы не проходить сквозь друг друга.


Случайно раскидываем частицы по полю и смотрим, что выйдет."



Расширенный вариант видео
Теперь немного о логике происходящего в программе. Создается массив частиц с определёнными параметрами. Часть параметров отвечают за физические свойства: радиус, масса, скорость и тд., часть за создание связей между частицами, такими как: тип частиц, кол-во связей частицы с другими частицами и прочее. В среднем использовал в симуляции от 700 до 3000 частиц, так как хотелось считать в реальном времени, большее значение приводило к торможению картинки в следствии роста объема вычислений. Затем все это добро передаётся в память видеокарты, где уже GPU в режиме сильного распараллеливания обрабатывает три основных подпрограммы: симуляция движения частиц, обработка столкновений частиц(соударений) и образование-разрушение связей между частицами.


"Меняем правила игры. Больше не будем считать соседей. Пусть частицы будут просто притягиваться или отталкиваться в зависимости от их типов. Если все частицы одного типа, то тут всего 2 варианта: они либо все отталкиваются, либо все притягиваются."


Пробовал несколько вариантов сил притяжения-отталкивания, линейные зависимости от расстояний между частицами, обратно пропорциональные расстоянию и тд. остановился на обратной квадратичной зависимости, но с ограничением по радиусу действия, чтото вроде 45 радиусов частицы.



"Не будем сильно менять правила. Вместо этого добавим новую фичу. Теперь частицы на небольшом расстоянии будут образовывать связи. Если частицы связаны, то они постоянно притягиваются друг к другу. Это притяжение не ослабевает с расстоянием. Но, если расстояние выше определённого порога, то связь рвётся."


Здесь немного изменил правило, ввел расстояние образования связей, оно же расстояние разрушения связи и расстояния покоя частицы в связи, то есть частица постоянно пытается занять положение около позиции покоя, поэтому при дискретном времени и возникает колебание частицы около нулевого положения. Это видно на всех видео. Возможно применить более сложные законы при формировании связи вроде эластичности(упругости), но пока упростил, все же у нас "первичный суп", а не твердое вещество.



Расширенный вариант видео


или в виде картинки



Далее начался процесс проб и ошибок. Во первых программирование на GPU требует дополнительной внимательности в части так называемого "races on read-modify-write of shared data", что означает что могут быть проблемы когда несколько потоков одновременно пытаются изменить переменную. Возникают нестабильности вроде таких:



Затем надо было ограничить область пространства в котором происходит эксперимент, первое что пришло на ум это куб. Но спасибо багам первых версий программы, частицы смело расползались из него, образуя что-то подобное космическим станциям из фантастики 70-х.



расширенная версия видео


Как говорится если не куб, то пусть будет шар:



Здесь логика в том, что после отлёта от центра на частицу начинает действовать сила обратная ее движению, что даже похоже на гравитацию.


__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}};

Привел кусочек кода как есть, это матрицы взаимодействия трех типов частиц друг с другом.
-первая строчка это принцип образования связей: 1 есть возможность установить связь с другой частицей, 0 соответственно нет.
-вторая строчка- это закон притяжения отталкивания частиц. По сути в этом варианте все отталкиваются друг от друга, кроме притяжения второго типа частиц к третьему. Можно конечно зеркалить матрицу, но в данном случае так.
-третья строчка количество общих связей частиц по типам.
-четвёртая это количество связей частицы с каждым типом частиц.Первый тип например сам с собой не может образовать связь.


Получаем частицы в сильном броунском движении:



расширенная версия видео


Пришлось вводить потерю энергии при столкновениях.



расширенная версия видео


Стало слишком все статично, уменьшаем силы взаимодействия частиц.



расширенная версия видео


Если посмотреть видео видно как происходит постройка каркаса. Потом он остаётся все равно статичным.


Меняем правила в части коэфф матриц.



расширенная версия видео
Видим образование подобия органических молекул. Даже есть бензольные кольца.



Еще одно видео, демострирует что будет, если в динамике менять длину связей между частицами, со второй минуты видео это особо выраженно.



Но надо попробовать повторить вариант 2D автора, чьи цитаты в теле статьи. Есть вариант такой "жизни":



или такой



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


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



Надеюсь кому-то понравится и он шагнёт из 3D дальше, как автор шагнул из 2D. Главное для себя повторил уроки по CUDA и Ogre3D под Ubuntu.



И еще будут идеи пишите, может что интересное придумаем :)

Комментарии (18)


  1. ANIDEANI
    02.06.2019 05:52

    Очень похоже на 3D моделирование белка — третичная структура. Только это реальные научные вычисления, каждый атом имеет физику и модель, реального атома. А структура белка определяет как это всё будет работать


    1. Geotyper Автор
      02.06.2019 08:28

      да, при увеличении кол-ва связей у частиц, происходит укрупнение «молекул». Еще есть вариант, когда начинается самосжимание, так как связей много и они перевешивают отталкивание частиц.


      1. Geotyper Автор
        02.06.2019 08:33

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


  1. genseq
    02.06.2019 09:25

    Спасибо за прекрасные картинки.

    Кстати, об идеях. Давно ищу специалиста, способного заинтересоваться молекулярным 3D-макетирование. Но только не с шариками и т.п., а с модулями, максимально точно описывающими электронные оболочки атомов и молекул:
    habr.com/ru/post/374003
    sketchfab.com/3d-models/04338d9336644387a1f559ba709360c6
    sketchfab.com/3d-models/50dda13c406e4354a0a6c3f2c3f0f91c


    1. Geotyper Автор
      02.06.2019 09:38

      Читал Вашу статью когда решал что делать, идея орбит(оболочек) интересная, но хотелось самоорганизации частиц. Как вариант думал сделать определенные углы для связей. А так пишите в личку, может смогу чем помочь. Просто если говорить о полноценном конструкторе оболочек, то скорее всего это уже работа для коллектива, если прототип чтобы двигался то возможно.


  1. GrigorGri
    02.06.2019 11:41
    +1

    Не пробовали добиться шаблонов из игры Жизнь? Планер, ружье и т.д… В 3д выглядело бы интересно мне кажется


    1. Geotyper Автор
      02.06.2019 11:56

      клеточный автомат «Жизнь» работает в дискретном варианте пространства и времени, упрощенно по клеточкам и тикам времени целочисленным. Есть правила и эти правила порождают в клетке жизнь или убивают или сохраняют. Сотояний клетки два 0 и 1.
      Усложнить можно добавив непрерывное время и вещественное значение для клетки.
      чтото типа такого:


    1. Geotyper Автор
      03.06.2019 13:34


      или такой вариант, когда похоже на клеточный автомат


  1. Refridgerator
    02.06.2019 13:04

    Чья музыка в ролике exp 12?


    1. Geotyper Автор
      02.06.2019 17:14
      +1

      youtu.be/Th29zm5u8yM где на 7 минуте начало


  1. alex_zzzz
    02.06.2019 14:00

    За основу взял с++, добавил поддержку CUDA как вычислительной платформы, частиц много и центральный процессор явно не справится с такой нагрузкой в реальном времени

    Ты недооцениваешь центральный процессор. Из любопытства делаю в Unity симуляцию жидкости — те же частицы с взаимодействиями между соседями. Старый 4-ядерный i5 тянет в реальном времени 10-50 тысяч частиц, в зависимости от их плотности и распределения в пространстве. Под реальным временем понимается 60 fps.


    1. Geotyper Автор
      02.06.2019 17:23

      с центральным процессором наверное на «ты» ) у меня nvidia 1080 хромает после 4000, код конечно неоптимальный в части вычислений, но у карты 2560 ядер так что это не так уж и важно в этом случае. Unity c# с интерпретатором на борту и проблемами с поддержкой многопоточности даже на центральном процессоре, но все может быть. Minecraft на java написан. Хотя там с физикой так себе )


      1. alex_zzzz
        02.06.2019 20:24

        Насколько я понял, у тебя ведь не n-body задача, где все взаимодействуют со всеми, где бы они ни находились. Если n-body, то претензия снимается.


        Если у частиц есть какой-то предельный радиус, дальше которого они друг друга не «видят», то должно быть не от 700 до 3000 частиц, а на порядок больше и 60 fps безо всяких GPU. C GPU должны быть сотни тысяч и миллионы, т.к. задача параллелится.


        1. Geotyper Автор
          02.06.2019 20:31

          полностью поддерживаю про производительность )


          1. alex_zzzz
            02.06.2019 20:44

            За 1080 обидно. :)


            1. Geotyper Автор
              02.06.2019 20:49

              лучше чем биткоины считать, ее как раз дешево купил у фермеров, когда спад был криптовалют. Вопрос оптимизации, для любой задачи есть свои критерии, тянет и хорошо, надо было бы больше-быстрее, пришлось бы делать код сложнее.


  1. alex_zzzz
    02.06.2019 20:17
    +1

    [промахнулся]


    1. Geotyper Автор
      02.06.2019 20:45

      бывает )