суббота, 30 июля 2011 г.

Gmsh. Параллелепипеды, призмы

Сегодня мы рассмотрим способы создания трехмерных структурированных сеток, которые довольно часто встречаются при конечно-элементном и конечно-разностном моделировании.

Параллелепипеды
Напомню, что в двумерном случае прямоугольники получались рекомбинированием структурированной треугольной сетки. Воспользоваться этим алгоритмом в трехмерном случае (т.е. написав Recombine Volume) не удастся, потому что Gmsh рекомбинирует только поверхности. Поэтому рассмотрим другие способы получения структурированных сеток. Приведем описания Gmsh-команд, предназначенных для этого (эти команды пригодятся нам также для получения призм):

Extrude {X, Y, Z} { список фигур; слои; <Recombine;> } - вытягивает объекты, заданные в "списке фигур", за счет перемещения, определяемого координатами X, Y, Z. При этом главную роль по структурированю здесь играют "слои", которые задаются следующим образом: Layers {число} или Layers { {список чисел 1}, {список чисел 2} }. В первом случае будет создан только один слой, и "число" задает количество элементов в нем. Во втором случае - "список чисел 1" задает количество элементов в каждом слое, а "список чисел 2" задает нормированную высоту слоев из первого списка, причем значения должны идти по возрастанию 0 < h1 < h2 < ... < hn <= 1. Если не совсем понятно, не отчаивайтесь - далее мы рассмотрим примеры с рисунками, на которых все разъяснится.
При вытягивании линий опция Recombine будет пытаться преобразовать треугольники в четырехугольники. При вытягивании поверхности опция Recombine будет пытаться преобразовать тетраэдры в шестигранники, призмы и пирамиды.

Extrude{{X1, Y1, Z1}, {X2, Y2, Z2}, Angle} { список фигур; слои; <Recombine;> } - вытягивание за счет поворота. X1, Y1, Z1 - координаты линии, вокруг которой осуществляется вращение. X2, Y2, Z2 - координаты точки на этой линии. Angle - угол поворота в радианах. Все остальное аналогично предыдущей команде.

Extrude{{X1, Y1, Z1}, {X2, Y2, Z2}, {X3, Y3, Z3}, Angle} { список фигур; слои; <Recombine;> } - вытягивание за счет перемещения с поворотом. За перемещение отвечает первая тройка чисел. Остальное - как в предыдущей команде.

Теперь приведем пример использования этих команд для получения параллелепипеидальной сетки (скачать скрипт).
  1.    n = 10; // количество точек разбиения линии
  2.    k = 10; // количество слоев

  3.    Point(1) = {0, 0, 0}; // для структурированных сеток
  4.    Point(2) = {1, 0, 0}; // значение характеристической длины
  5.    Point(3) = {1, 1, 0}; // не имеет никакого значения,
  6.    Point(4) = {0, 1, 0}; // поэтому его можно не указывать

  7.    Line(1) = {1, 2}; Transfinite Line{1} = n;
  8.    Line(2) = {2, 3}; Transfinite Line{2} = n;
  9.    Line(3) = {1, 4}; Transfinite Line{3} = n;
  10.    Line(4) = {4, 3}; Transfinite Line{4} = n;

  11.    Line Loop(21) = {1, 2, -4, -3};

  12.    Plane Surface(1) = {21};
  13.    Transfinite Surface(1) = {1, 2, 3, 4};
  14.    Recombine Surface{1}; // прямоугольная сетка

  15.    vol[] = Extrude {0, 0, 1} { Surface{1}; Layers{k}; Recombine; }; // параллелепипеидальная сетка
Итак, в результате мы получим равномерное параллелепипеидальное разбиение (чтобы получить кубическую сетку, нужно задать параметр n в скрипте равным 11). При этом мы создали один слой, состоящий из 10 элементов (см. рисунок)

Теперь сгустим сетку (скачать скрипт).
  •    n = 10; // количество точек разбиения линии
  •    k1 = 3; // количество элементов первого слоя
  •    k2 = 10; // количество элементов второго слоя
  •    k3 = 40; // количество элементов третьего слоя
  •    m = 1.3; // коэффициент сгущения сетки
  •    p1 = 0.3; // высота первого слоя
  •    p2 = 0.6; // высота первого+второго слоя
  •    p3 = 1.0; // высота первого+второго+треьего слоя

  •    Point(1) = {0, 0, 0};
  •    Point(2) = {1, 0, 0};
  •    Point(3) = {1, 1, 0};
  •    Point(4) = {0, 1, 0};

  •    Line(1) = {1, 2}; Transfinite Line{1} = n Using Progression m;
  •    Line(2) = {2, 3}; Transfinite Line{2} = n;
  •    Line(3) = {1, 4}; Transfinite Line{3} = n;
  •    Line(4) = {4, 3}; Transfinite Line{4} = n Using Progression m;

  •    Line Loop(21) = {1, 2, -4, -3};

  •    Plane Surface(1) = {21};
  •    Transfinite Surface(1) = {1, 2, 3, 4};
  •    Recombine Surface{1};

  •    vol[] = Extrude {0, 0, 1} { Surface{1}; Layers{ {k1, k2, k3}, {p1, p2, p3} }; Recombine; };
  • Следующая картинка наглядно продемонстрирует то, что вы получите.

    Призмы
    С призмами все обстоит аналогично. Единственное отличие - поверхность, которую затем вы будете "вытягивать слоями" для получения объема должна быть разбита не на прямоугольники, а на треугольники. Поэтому чтобы получить равномерную призматическую сетку, закомментируйте строку Recombine Surface{1}; в приведенных выше скриптах. Чтобы получить неравномерную призматическую сетку, закомментируйте еще и строку Transfinite Surface(1) = {1, 2, 3, 4}; или посмотрите этот скрипт. Напомню, что встроенный язык Gmsh поддерживает C-подобное комментирование, т.е. // - до конца строки, /**/ - часть текста. Таким образом, любая триангуляция поверхности, вытянутая затем с помощью слоев, приведет вас к призматической сетке.

    Комментариев нет:

    Отправить комментарий