По умолчанию Gmsh строит симплициальные сетки (треугольные, тетраэдральные). Однако он (я считаю, что Gmsh - это он, триангулятор, несмотря на все его CAD, Solver и Postprocessing способности) может сделать разбиение и другими элементами. Вот их список (взят из описания формата выходного файла сетки):
Рекомбинирование
Gmsh дает возможность рекомбинировать треугольную сетку таким образом, чтобы получить четырехугольные элементы. Вообще говоря, рекомбинирование не даст вам в общем случае только четырехугольную сетку. Рассмотрим простой пример.
Определим в Gmsh'е квадрат со стороной 1:
Полученная сетка имеет вид:
Чтобы получить рекомбинированную сетку, можно, как обычно, пойти двумя путями: через окно меню и через .geo файл. И, как обычно, мы рассматриваем только второй вариант, т.к., во-первых, интерфейс Gmsh'а довольно сильно меняется с выходом новой версии, поэтому приведенные здесь скриншоты меню через некоторое время станут неактуальны (а скрипт .geo файла работает всегда); а во-вторых, вам и самим будет интересно полазить в меню, так что не буду лишать вас удовольствия открытия новых кнопочек. Могу еще добавить чисто субъективно - задавать параметры разбиения удобнее в .geo файле. Но вы, конечно, можете со мной не согласиться.
Для построения рекомбинированной сетки в конец .geo файла достаточно добавить строку
Построив сетку (Mesh->2D), вы увидите следующее:
Как видно, в разбиении присутствуют как четырехугольные элементы, так и треугольные. Однако так происходит только если вы рекомбинируете неструктурированную (нерегулярную) треугольную сетку.
Структурированная сетка
Попробуем разбить область на одинаковые треугольники. Для этого заменим последнюю строку .geo файла (где мы определяли рекомбинированную поверхность) на следующую:
Построив сетку (Mesh->2D), вы увидите следующее:
При этом мелкость разбиения определяется параметром cl, с которым заданы точки области. Обратите внимание, что вы получите регулярную сетку только в том случае, если для всех точек области будет задана одинаковая характеристическая длина. Для области, заданной с различными значениями cl, трансфинитный алгоритм может и вовсе не сработать (а может и сработать - это как повезет).
Теперь рекомбинируем полученную сетку. Так же как и раньше добавим в конец .geo файла строку
Новая сетка имеет вид:
Итак, мало того, что наша сетка состоит только из четырехугольников, так они все еще и прямоугольники. Кстати, даже если вы зададите различные значения cl для точек области, после применения трансфинитного алгоритма (если он сработает) рекомбинирование все равно полностью избавит ваше разбиение от треугольников. Конечно, в этом случае вы не получите прямоугольную сетку, но может вам и четырехугольников достаточно. Зато вы можете локально мельчить сетку (иногда). Для тех, кто хочет мельчить сетку всегда и/или получать прямоугольники - следующий раздел.
Локальное измельчение прямоугольной сетки
Для того, чтобы измельчить (или наоборот - загрубить) прямоугольную сетку, нужно применить трансфинитный алгоритм не к поверхности, а к линиям. Приведу весь текст .geo файла целиком (скачать этот файл можно здесь):
строки 15-23: Для того, чтобы получить прямоугольную сетку, необходимо разбить линии, ограничивающие поверхность, одномерным трансфинитным алгоритмом. Для этого необходимо указать эти линии с ключевым словом Transfinite и количеством точек, участвующих в разбиении. Формат команды такой: Transfinite Line{номера существующих линий через запятую} = количество точек <опционально Using Progression | Bump число>;. Опции Using Progression и Using Bump используются для сгущения точек к одному из краев линии (в случае Progression) или к середине линии (в случае Bump). При этом число, указанное после слова Progression | Bump, означает отношение длины следующего отрезка линии к длине предыдущего (примечание: почему то в случае Bump это не совсем так). В качестве иллюстрации приведем сетки, полученные при значениях параметров k = 1.2, t = 0 и k = 10, t = 1.
Следует отметить также, что теперь характеристическая длина не оказывает никакого влияния на мелкость сетки - все задается количеством точек (параметр n в скрипте).
строка 24: Вообще говоря, поверхность, которую планируется разбить трансфинитным алгоритмом, нужно определять именно так. Номера 1, 2, 3 и 4 - это номера точек, образующих углы области. Если эти номера не указывать, Gmsh автоматически их определит. Если после разбиения поверхности на регулярные треугольники не планируется рекомбинировать сетку, то можно указать направление ориентации треугольников с помощью ключевых слов Left | Right | Alternate. То есть полностью команда будет иметь вид: Transfinite Surface(1) = {1, 2, 3, 4} Left;. В качестве иллюстрации - регулярная треугольная сетка, полученная с каждым из этих параметров в порядке - Left, Right, Alternate:
- 3-узловой треугольник
- 4-узловой четырехугольник
- 4-узловой тетраэдр
- 8-узловой шестигранник (гексаэдр)
- 6-узловая призма
- 5-узловая пирамида
- а также элементы 2-го, 3-го, 4-го и 5-го порядков (не для всех типов элементов)
Рекомбинирование
Gmsh дает возможность рекомбинировать треугольную сетку таким образом, чтобы получить четырехугольные элементы. Вообще говоря, рекомбинирование не даст вам в общем случае только четырехугольную сетку. Рассмотрим простой пример.
Определим в Gmsh'е квадрат со стороной 1:
- cl = 0.1;
- Point(1) = {0, 0, 0, cl};
- Point(2) = {1, 0, 0, cl};
- Point(3) = {1, 1, 0, cl};
- Point(4) = {0, 1, 0, cl};
- Line(1) = {1, 2};
- Line(2) = {2, 3};
- Line(3) = {3, 4};
- Line(4) = {4, 1};
- Line Loop(5) = {1, 2, 3, 4};
- Plane Surface(1) = {5};
Чтобы получить рекомбинированную сетку, можно, как обычно, пойти двумя путями: через окно меню и через .geo файл. И, как обычно, мы рассматриваем только второй вариант, т.к., во-первых, интерфейс Gmsh'а довольно сильно меняется с выходом новой версии, поэтому приведенные здесь скриншоты меню через некоторое время станут неактуальны (а скрипт .geo файла работает всегда); а во-вторых, вам и самим будет интересно полазить в меню, так что не буду лишать вас удовольствия открытия новых кнопочек. Могу еще добавить чисто субъективно - задавать параметры разбиения удобнее в .geo файле. Но вы, конечно, можете со мной не согласиться.
Для построения рекомбинированной сетки в конец .geo файла достаточно добавить строку
- Recombine Surface{1};
Как видно, в разбиении присутствуют как четырехугольные элементы, так и треугольные. Однако так происходит только если вы рекомбинируете неструктурированную (нерегулярную) треугольную сетку.
Структурированная сетка
Попробуем разбить область на одинаковые треугольники. Для этого заменим последнюю строку .geo файла (где мы определяли рекомбинированную поверхность) на следующую:
- Transfinite Surface{1};
При этом мелкость разбиения определяется параметром cl, с которым заданы точки области. Обратите внимание, что вы получите регулярную сетку только в том случае, если для всех точек области будет задана одинаковая характеристическая длина. Для области, заданной с различными значениями cl, трансфинитный алгоритм может и вовсе не сработать (а может и сработать - это как повезет).
Теперь рекомбинируем полученную сетку. Так же как и раньше добавим в конец .geo файла строку
- Recombine Surface{1};
Итак, мало того, что наша сетка состоит только из четырехугольников, так они все еще и прямоугольники. Кстати, даже если вы зададите различные значения cl для точек области, после применения трансфинитного алгоритма (если он сработает) рекомбинирование все равно полностью избавит ваше разбиение от треугольников. Конечно, в этом случае вы не получите прямоугольную сетку, но может вам и четырехугольников достаточно. Зато вы можете локально мельчить сетку (иногда). Для тех, кто хочет мельчить сетку всегда и/или получать прямоугольники - следующий раздел.
Локальное измельчение прямоугольной сетки
Для того, чтобы измельчить (или наоборот - загрубить) прямоугольную сетку, нужно применить трансфинитный алгоритм не к поверхности, а к линиям. Приведу весь текст .geo файла целиком (скачать этот файл можно здесь):
- cl = 0.1;
- n = 15;
- k = 10;
- t = 1; // 0 for Progression, 1 for Bump
- Point(1) = {0, 0, 0, cl};
- Point(2) = {1, 0, 0, cl};
- Point(3) = {1, 1, 0, cl};
- Point(4) = {0, 1, 0, cl};
- Line(1) = {1, 2};
- Line(2) = {2, 3};
- Line(3) = {3, 4};
- Line(4) = {4, 1};
- Line Loop(5) = {1, 2, 3, 4};
- Plane Surface(1) = {5};
- If (t == 0)
- Transfinite Line{1} = n Using Progression k;
- Transfinite Line{2} = n Using Progression k;
- Transfinite Line{3} = n Using Progression 1/k;
- Transfinite Line{4} = n Using Progression 1/k;
- EndIf
- If (t == 1)
- Transfinite Line{1, 2, 3, 4} = n Using Bump k;
- EndIf
- Transfinite Surface(1) = {1, 2, 3, 4};
- Recombine Surface{1};
Следует отметить также, что теперь характеристическая длина не оказывает никакого влияния на мелкость сетки - все задается количеством точек (параметр n в скрипте).
строка 24: Вообще говоря, поверхность, которую планируется разбить трансфинитным алгоритмом, нужно определять именно так. Номера 1, 2, 3 и 4 - это номера точек, образующих углы области. Если эти номера не указывать, Gmsh автоматически их определит. Если после разбиения поверхности на регулярные треугольники не планируется рекомбинировать сетку, то можно указать направление ориентации треугольников с помощью ключевых слов Left | Right | Alternate. То есть полностью команда будет иметь вид: Transfinite Surface(1) = {1, 2, 3, 4} Left;. В качестве иллюстрации - регулярная треугольная сетка, полученная с каждым из этих параметров в порядке - Left, Right, Alternate:
Ай шайтан! А мне все времени не хватает толком разобраться... А вы уже пользовались "Compound Surface" и "Compound Line"?
ОтветитьУдалитьВ рабочих моделях не использовал. А так, да - посмотрел, попробовал.
УдалитьУ меня потом проблемы с разбивкой таких плоскостей. Пересечения конечных элементов по таким поверхностям
УдалитьВ смысле сетка не согласованная? Помнится, там может быть такое, что строится 2 сетки - одна на исходной поверхности, другая - на Compound поверхности. И тогда чисто визуально - как будто сетка кривая, а на самом деле их просто две. Может это ваш случай? Как бы то ни было, ваш конкретный неработающий пример помог бы разобраться.
УдалитьС удовольствием предоставлю пример! И пользуясь случаем задам еще вопрос. Каким образом, на ваш взгляд, силами GMSH можно создать цилиндр, вьющийся по спирали (прядь каната)?
УдалитьКак лучше представить пример (50 строк)? в комментарии или на почту отправить?
УдалитьПример давайте сюда, тут и будем разбираться. По поводу цилиндра - нужно задать поверхность - основание цилиндра, а потом с помощью Extrude с поворотом вытянуть. У вас, таким образом, получится часть нужной фигуры (зависит от угла поворота). Затем эту часть можно копировать с перемещением: связка команд Duplicata и Translate. Должно получиться.
Удалитьну я так и сделал, просто думал может еще какие варианты.
УдалитьГеометрия: цилиндр в цилиндре.
ОтветитьУдалитьЗамечания по коду приветствуются.
При создании 3D сетки появляются пересечения по Compound Surface.
/*сам код*/
cl = 0.25;
R = 1; //радиус внутреннего цилиндра
//создание цилиндра из окружности путем вытягивания
P_c = newp; Point (P_c) = {0, 0, 0, cl};
P_sm = newp; Point (P_sm) = {0, R, 0, cl};
temp_mas[] = Rotate {{ 0, 0, 10},{0, 0, 0}, -2*Pi/3} { Duplicata { Point{P_sm}; } };
P_s1 = newp; P_s1 = temp_mas[0];
temp_mas[] = Rotate {{ 0, 0, 10},{0, 0, 0}, 2*Pi/3} { Duplicata { Point{P_sm}; } };
P_s2 = newp; P_s2 = temp_mas[0];
Circ_s_1 = newreg; Circle (Circ_s_1) = {P_s1, P_c, P_s2};
Circ_s_2 = newreg; Circle (Circ_s_2) = {P_s2, P_c, P_sm};
Circ_s_3 = newreg; Circle (Circ_s_3) = {P_sm, P_c, P_s1};
line_loop_s = newreg; Line Loop (line_loop_s) = {Circ_s_1, Circ_s_2, Circ_s_3};
Surface_s = newreg; Plane Surface (Surface_s) = {line_loop_s};
ee = 0;
tt[] = Extrude {0, 0, 2} {Surface{Surface_s};};
For kk In {2:4}
side[ee] = tt[kk]; //сбор идентификаторов боковых поверхностей цилиндра
ee++;
EndFor
in_vol = tt[1];
Surface_en = tt[0];
CS = 500; //объединенная поверхность
Compound Surface(CS) = {side[]};
R_ex = 5*R; //радиус большого цилиндра
P_c_ex = newp; Point (P_c_ex) = {0, 0, -5, cl};
P_sm_ex = newp; Point (P_sm_ex) = {0, R_ex, -5, cl};
temp_mas[] = Rotate {{ 0, 0, 10},{0, 0, 0}, -2*Pi/3} { Duplicata { Point{P_sm_ex}; } };
P_s1_ex = newp; P_s1_ex = temp_mas[0];
temp_mas[] = Rotate {{ 0, 0, 10},{0, 0, 0}, 2*Pi/3} { Duplicata { Point{P_sm_ex}; } };
P_s2_ex = newp; P_s2_ex = temp_mas[0];
Circ_s_1_ex = newreg; Circle (Circ_s_1_ex) = {P_s1_ex, P_c_ex, P_s2_ex};
Circ_s_2_ex = newreg; Circle (Circ_s_2_ex) = {P_s2_ex, P_c_ex, P_sm_ex};
Circ_s_3_ex = newreg; Circle (Circ_s_3_ex) = {P_sm_ex, P_c_ex, P_s1_ex};
line_loop_s_ex = newreg; Line Loop (line_loop_s_ex) = {Circ_s_1_ex, Circ_s_2_ex, Circ_s_3_ex};
Surface_s_ex = newreg; Plane Surface (Surface_s_ex) = {line_loop_s_ex};
ee = 0;
tt[] = Extrude {0, 0, 12} {Surface{Surface_s_ex};};
For kk In {2:4}
side_ex[ee] = tt[kk];
ee++;
EndFor
ex_vol = tt[1];
Surface_ex_en = tt[0];
//ниже идет создание объема внутри большого цилиндра, за вычетом маленького.
esp = newreg; Surface Loop (esp) = {Surface_s, Surface_s_ex, Surface_en, Surface_ex_en, side_ex[], CS};
bv = newreg; Volume(bv) = {esp};
air_vol = newreg;
Physical Volume (air_vol)= {bv};
Замечаний по коду нет - все написано толково.
УдалитьВ общем, почти сразу заметил вот эту конструкцию
Surface Loop (esp) = {Surface_s, Surface_s_ex, Surface_en, Surface_ex_en, side_ex[], CS};
и она мне не понравилась вот почему: Compound не позволяет работать с несколькими геометрическими элементами, как с одним, чтобы потом использовать его в других командах по созданию модели. Compound создан для другого. Я, наверное, оформлю это чуть попозже в виде полноценного поста с блекджеком и картинками, чтобы стал более понятен смысл Compound. А для работоспособности вашего кода просто замените CS на side[] и все.
Кстати, вы, наверное, сетку строили фронтальным алгоритмом, который, таки да - построит сетку, но кривую. Делоне в этом смысле покапризней. Заругается и тетраэдров не даст.
Будет очень интересно почитать. В моей модели больше трехсот тысяч поверхностей и я очень надеялся с помощью Compound уменьшить их количество.
УдалитьА еще будет очень интересно побольше узнать об алгоритмах мешера. И еще интересно, как можно уменьшить потребление памяти мешером.
УдалитьВот и пост http://numlab.blogspot.com/2012/09/gmsh-compound.html
УдалитьПо поводу алгоритмов ничего, выходящего за рамки документации, сказать не могу. Хотелось бы поковыряться и что-нибудь оформить, но, к сожалению, сейчас нет времени.
Удалить