Как создавать рандомизированную геометрию с использованием макросов

05/06/2017

Хотели ли вы когда-нибудь включить рандомизированную геометрию в свою модель? Возможно, вы думали о том, чтобы смоделировать биологический или природный материал или задать расположение частей или фрагментов с определенным статическим распределением размеров. Это как раз несколько примеров того, когда пригодилось бы опция сознания рандомизированной геометрии в COMSOL Multiphysics®. Начиная с версии 5.3 такую геометрию можно создавать с использованием макросов для модели (т.н. model methods). Давайте посмотрим, как это сделать, на наглядном и «вкусном» примере.

Построение геометрической модели швейцарского сыра

Выбрать лучший сыр в мире — очень непростая задача. На мой взгляд, хороший Эмменталь всегда будет являться одним из фаворитов. Опытные сыроделы могут шутить, что дырки в сыре добавляют ему аромат. Поэтому, если мы хотим построить хорошую модель головки сыра в COMSOL Multiphysics, нам не обойтись без них в геометрической последовательности.

На рисунке изображена модель головки сыра с рандомизированным распределением дырок.
Модель сыра Эмменталь с рандомизированным распределением дырок.

В данной заметке мы не будем рассматривать и моделировать процесс образования дыр в швейцарском сыре, так как причины этого довольно сложны. Вместо этого просто создадим и настроим модель геометрии сыра, как на изображении выше. Давайте включим в геометрию случайно распределённые по всему объёму сыра дырки-отверстия, радиус которых произвольно меняется между верхним и нижним пределами. Для данной задачи воспользуемся новым функционалом COMSOL Multiphysics, который доступен начиная с версии 5.3, речь пойдет про макросы для модели (Model Methods) . Давайте же посмотрим, как это сделать…

Основы создания макросов в COMSOL Multiphysics®

Начиная с версии 5.3 при запуске COMSOL Multiphysics® на платформе Windows® в окне Model Builder (Построитель моделей) стала доступна вкладка Developer (Разработчик) справа в ленте Ribbon, как показано на скриншоте ниже. Одной из функций является Record Method (Записать макрос). После нажатия на иконку в выпадающем меню предлагается ввести Name (Имя) и Method type (Тип макроса). В строке Name вы можете ввести любое имя, а затем выбрать один из двух типов макроса: Application method (Макрос для приложения) или Model method (Макрос для модели).

Макрос для приложения может использоваться в приложениях COMSOL. Ознакомьтесь с данным учебным видео, в котором показаны основы их создания и использования. Макросом для модели можно воспользоваться в активной модели COMSOL Multiphysics для её изменения или добавления определенных данных.

Вкладка Developer в версии 5.3 COMSOL Multiphysics®.
Скриншот вкладки Developer с кнопками Record Method (Записать макрос для модели) и Run Model Method (Запустить макрос для модели).

Введя имя и выбрав тип макроса, нажимаем на кнопку OK в диалоговом окне Record Method, после чего вокруг всего графического пользовательского интерфейса появится красная подсветка и рамка. Все операции, которые будут при этом сделаны, будут записываться как код и составные команды макроса до тех пор, пока вы не нажмёте на кнопку Stop Recording (Остановить запись). Затем можно переключиться в Среду разработки приложений (Application Builder) и посмотреть записанный макрос. На скриншоте ниже изображена Среда разработки приложений (Application Builder) и открытый в ней макрос для создания одного геометрического объекта. Объектом является цилиндр с тегом cyl1, радиус которого 40 см, а высота 20 см. Это и будет начальной формой для нашей головки сыра.

Код макроса для модели в Среде разработки приложений (Application Builder).
Скриншот окна Среды разработки приложений (Application Builder) с открытым кодом макроса для создания геометрии.

В последующем при работе в Построителе моделей (Model Builder) можно вызвать этот макрос (конечно при условии, что в геометрической последовательности модели еще не создан объект с данным тегом cyl1) по нажатию на кнопку Run Model Method во вкладке Developer. Данный простой пример макроса создаёт только цилиндр. Если мы хотим воссоздать дырки, нужно добавить немного «рандомности» в наш макрос. Разберём это подробнее в следующем разделе.

Создание рандомизированного набора геометрических объектов

В макросах вы можете использовать стандартные команды и классы языка Java®. К примеру, Math.random class возвращает число двойной точности (в формате double), лежащее в промежутке между 0.0 и 1.0. С помощью этой функции и нескольких дополнительных строчек кода мы зададим определённое количество отверстий с рандомизированным расположением и размерами в нашей модели головки сыра.

Предположим, что мы хотим задать 1000 рандомизированно расположенных по всему объёму сыра отверстий произвольного радиуса от 0.1 до 1 см. Также учтём, что вокруг головки сыра Эмменталя находится натуральная оболочка, в которой дырок нет. Очевидно, что нам понадобится логическое условие, которое будет проверять, что все дырки находятся внутри головки сыра. Ниже приведён полный текст макроса (с пронумерованными строками и выделенными красным цветом текстовыми выражениями), представляющий собой набор команд для создания требуемой геометрии сыра.

1  int NUMBER_OF_HOLES = 1000;
2  int ind = 0;
3  double hx, hy, hz, hr = 0.0;
4  double CHEESE_HEIGHT = 20.0;
5  double CHEESE_RADIUS = 40.0;
6  double RIND_THICKNESS = 0.2;
7  double HOLE_MIN_RADIUS = 0.1;
8  double HOLE_MAX_RADIUS = 1.0;
9  model.component("comp1").geom("geom1").lengthUnit("cm");
10 model.component("comp1").geom("geom1").selection().create("csel1", "CumulativeSelection");
11 while (ind  CHEESE_RADIUS-RIND_THICKNESS) {continue; }
12   hx = (2.0*Math.random()-1.0)*CHEESE_RADIUS;
13   hy = (2.0*Math.random()-1.0)*CHEESE_RADIUS;
14   hz = Math.random()*CHEESE_HEIGHT;
15   hr = Math.random()*(HOLE_MAX_RADIUS-HOLE_MIN_RADIUS)+HOLE_MIN_RADIUS;
16   if ((Math.sqrt(hx*hx+hy*hy)+hr) > CHEESE_RADIUS-RIND_THICKNESS) {continue; }
17   if (((hz-hr)  CHEESE_HEIGHT-RIND_THICKNESS)) {continue; }
18   model.component("comp1").geom("geom1").create("sph"+ind, "Sphere");
19   model.component("comp1").geom("geom1").feature("sph"+ind).set("r", hr);
20   model.component("comp1").geom("geom1").feature("sph"+ind).set("pos", new double[]{hx, hy, hz});
21   model.component("comp1").geom("geom1").feature("sph"+ind).set("contributeto", "csel1");
22   ind++;
23 }
24 model.component("comp1").geom("geom1").create("cyl1", "Cylinder");
25 model.component("comp1").geom("geom1").feature("cyl1").set("r", CHEESE_RADIUS);
26 model.component("comp1").geom("geom1").feature("cyl1").set("h", CHEESE_HEIGHT);
27 model.component("comp1").geom("geom1").create("dif1", "Difference");
28 model.component("comp1").geom("geom1").feature("dif1").selection("input").set("cyl1");
29 model.component("comp1").geom("geom1").feature("dif1").selection("input2").named("csel1");
30 model.component("comp1").geom("geom1").run();

Давайте построчно разберем данный макрос.

1. Инициализируем переменную и определяем общее количество дырок в сыре.
2. Инициализируем и задаём счетчик количества отверстий, который нам понадобится в дальнейшем.
3. Инициализируем набор чисел двойной точности, в которых будут храниться координаты xyz и радиус каждой "дырки".
4–8. Устанавливаем и задаём переменные, определяющие высоту, радиус, толщину головки сыра, и максимальный и минимальный радиус каждого отверстия в сантиметрах.
9. Устанавливаем сантиметры в качестве единиц измерения длины в геометрии.
10. Создаём новую выборку (selection) с тегом csel и называем CumulativeSelection (Кумулятивная выборка). Обратите внимание, что в самой модели не должно уже быть выборки с таким названием, иначе возникнет ошибка. Нужно будет внести очевидные изменения в данный макрос, если вы захотите его использовать несколько раз подряд в одной модели.
11. Определяем цикл типа «while», чтобы создать указанное количество "дырок".
12–14. Определяем xyz-положение отверстий, используя рандомизированный метод и масштабируя получающиеся значения таким образом, чтобы координаты отверстий попадали внутрь сыра.
15. Определяем радиус каждого отверстия так, чтобы он лежал в заданных пределах.
16–17. Проводим проверку, что положение отверстия и его размеры таковы, что оно находится внутри головки сыра. Если это действительно так, переходим к следующей итерации цикла while, не выполняя последующих строк. Эта проверка может быть выполнена одной строкой либо разделена на три строки, в зависимости от вашего стиля записи кода.
18. Создаем сферу и присваиваем ей имя, соответствующее текущему индексу счетчика.
19–20. Задаём радиус и положение новой сферы. Радиус сферы можно напрмую завадавать как double, в то время как ее положение должно быть определено как новый массив из чисел двойной точности.
21. Указываем, что сфера является частью выборки csel1.
22–23. Обновляем индекс, указав, что сфера создана, и закрываем цикл типа «while».
24–26. Создаём цилиндр, представляющий нашу головку сыра.
27–29. Определяем логическую операцию Difference (Разность). Добавляем цилиндр как исходный объект и вычитаем из него геометрическую выборку всех созданных ранее сфер.
30. Запускаем и финализируем геометрическую последовательность, тем самым дав команду программе вырезать все отверстия и построить конечную геометрию головки сыра.

Данный макрос можно запустить в новом (и пустом) файле, чтобы создать модель головки сыра. Каждый раз будет получаться совершенно новая рандомизированная геометрия. Геометрическая последовательность в файле модели будет содержать все сгенерированные сферы, один цилиндр, а также команду логического вычитания.

При желании можно также добавить дополнительные команды в макрос, чтобы сохранить уже итоговый файл с названием "сыр". Этот файл можно сохранить в стандартном формате COMSOL Multiphysics, либо как файл в STL-формате. Также можно записать данный файл в формате Parasolid® или ACIS®, при использовании одного из модулей интеграции, который содержит геометрическое ядро от Parasolid®. Работа с конечной геометрией после её экспорта и повторного импорта происходит быстрее, чем создание новой геометрической последовательности.

На изображении ниже можно увидеть результаты наших усилий. Согласитесь — даже выглядит вкусно!

На рисунке изображена модель головки сыра Эмменталь как пример рандомизированной геометрии.
Модель головки сыра Эмменталь, готовая к дегустации.

Заключительные комментарии по созданию рандомизированной геометрии с помощью макросов

В данной заметке мы рассмотрели простой пример работы с макросами для создания геометрии с рандомизированно расположенными отверстиями произвольного радиуса. Мы не стали рассматривать усложнение данной геометрии. Например, можно было бы задать такое условие, чтобы отверстия не налезали друг на друга или были максимально плотно сосредоточены в определённой области. Но для этого необходимы достаточно глубокие математические знания, рассказ о которых выходит за рамки данного блога.

Конечно, существует огромное количество применений, в которых будет актуально использование макросов. Мы обязательно рассмотрим некоторые из них в наших последующих статьях. Стоит отметить, что существуют и другие способы создания рандомизированной геометрии, и в частности приём с использованием параметрического задания поверхностей.

Дополнительные материалы

ACIS является зарегистрированной торговой маркой компании Spatial Corporation. Oracle и Java являются зарегистрированными торговыми марками корпорации Oracle и (или) аффилированных с ней компаний. Parasolid является зарегистрированной торговой маркой или торговой маркой компании Siemens Product Lifecycle Management Software Inc. или ее дочерних компаний в США и других странах. Microsoft и Windows являются товарными знаками или зарегистрированными товарными знаками Microsoft Corporation в США и других странах.


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

Оставить комментарий
Войти | Регистрация
Загрузка...
РУБРИКАТОР БЛОГА COMSOL
РУБРИКИ
ТЕГИ