MATLAB PDE Toolbox 的多域 3D 几何

计算科学 有限元 pde matlab gmsh
2021-12-03 10:49:09

原则上,MATLAB 中的 PDE 工具箱可以处理此处所述的多域 3D 几何。

MATLAB R2018a 中引入了此功能和相关的函数 geometryfromMesh。然而,有关如何实际实现此多域功能的相关文档几乎不存在。

我感兴趣的几何由一对完全包含在一个盒子(系统中的宇宙)中的嵌套长方体组成。在未来的迭代中,内部结构将在不同位置重复。

我对生成的网格的期望是覆盖容器内整个空间的 3D 网格,元素 ID 与两个域相关联。然后可以将其与内置语法一起使用。

问题分为两部分:

我知道 gmsh 但一直在努力创建网格化所需的相关几何图形。同样,gmsh 中嵌套几何的任何文档都会有所帮助。

几何学

1个回答

对于复杂的几何图形,您可能需要某种专用的 CAD 工具,而不是内置的 Matlab 功能。GMSH 是一个不错的开源工具,这是我解决此类问题的首选武器。

现在,没有任何关于GMSH 中嵌套几何的具体内容应该反映在文档中。您可能想熟悉创建Points、Lines、Line Loops、Surfaces、Surface Loops 和Volumes 的基本 GMSH 功能。这可以通过挤压明确地完成,甚至可以使用用户定义的宏来增加。此外,通过OpenCASCADE geometry kernel enabled可以获得一些附加功能,但我将跳过它。

因此,您想要绘制立方体的 3 个表面并使用保形四面体元素从中创建三个体积。这几乎就是您的任务归结为的内容。

我有一个Macro我已经写了一点点的东西,我在这里与你分享。看看它是如何工作的,但总体而言:

  • 在给定中心 { , , } 和边长Macro的情况下,通过随后创建所需的点、线、线环、曲面和曲面环来绘制立方体x_ceny_cenz_cena
  • 脚本用不同的边长调用Macro Cube了三次a
  • idMacro返回到数组中的位置,在主脚本中递增Surface LoopElem_slunit_element
  • 最后,创建了三个卷:Volume(1000)对应于最内部几何形状的实体卷Volume(2000)、具有孔的中间卷以及具有Volume(1000)Volume(3000)的外部卷Volume(2000)
  • 由于体积使用与其构建块相同的表面,因此它们之间的网格是共形的
  • 如果您还需要表面网格和线网格(例如,设置边界条件),您应该在Physical Surfaces 和Physical Lines 中添加所需的实体。
Macro Cube
    // Macro to draw an element surface, in this case, a cube
    // Input:
    //      unit_element                    - ID of the element in the overall structure
    //      x_cen, y_cen, z_cen             - location for the center of the cube
    //      a                               - cube side length
    //      cl                              - characteristic length for points
    // Output:
    //      Elem_sl[unit_element]           - surface loop for the unit element

    Elem_pts[0] = newp;     Point(Elem_pts[0])  = {x_cen+a/2,y_cen+a/2,z_cen+a/2,cl};
    Elem_pts[1] = newp;     Point(Elem_pts[1])  = {x_cen+a/2,y_cen-a/2,z_cen+a/2,cl};
    Elem_pts[2] = newp;     Point(Elem_pts[2])  = {x_cen-a/2,y_cen+a/2,z_cen+a/2,cl};
    Elem_pts[3] = newp;     Point(Elem_pts[3])  = {x_cen-a/2,y_cen-a/2,z_cen+a/2,cl};
    Elem_pts[4] = newp;     Point(Elem_pts[4])  = {x_cen+a/2,y_cen+a/2,z_cen-a/2,cl};
    Elem_pts[5] = newp;     Point(Elem_pts[5])  = {x_cen+a/2,y_cen-a/2,z_cen-a/2,cl};
    Elem_pts[6] = newp;     Point(Elem_pts[6])  = {x_cen-a/2,y_cen+a/2,z_cen-a/2,cl};
    Elem_pts[7] = newp;     Point(Elem_pts[7])  = {x_cen-a/2,y_cen-a/2,z_cen-a/2,cl};

    Elem_lns[0] = newl;     Line(Elem_lns[0])   = {Elem_pts[0],Elem_pts[2]};
    Elem_lns[1] = newl;     Line(Elem_lns[1])   = {Elem_pts[2],Elem_pts[3]};
    Elem_lns[2] = newl;     Line(Elem_lns[2])   = {Elem_pts[3],Elem_pts[1]};
    Elem_lns[3] = newl;     Line(Elem_lns[3])   = {Elem_pts[1],Elem_pts[0]};

    Elem_lns[4] = newl;     Line(Elem_lns[4])   = {Elem_pts[4],Elem_pts[6]};
    Elem_lns[5] = newl;     Line(Elem_lns[5])   = {Elem_pts[6],Elem_pts[7]};
    Elem_lns[6] = newl;     Line(Elem_lns[6])   = {Elem_pts[7],Elem_pts[5]};
    Elem_lns[7] = newl;     Line(Elem_lns[7])   = {Elem_pts[5],Elem_pts[4]};

    Elem_lns[8] = newl;     Line(Elem_lns[8])   = {Elem_pts[0],Elem_pts[4]};
    Elem_lns[9] = newl;     Line(Elem_lns[9])   = {Elem_pts[2],Elem_pts[6]};
    Elem_lns[10] = newl;    Line(Elem_lns[10])  = {Elem_pts[3],Elem_pts[7]};
    Elem_lns[11] = newl;    Line(Elem_lns[11])  = {Elem_pts[1],Elem_pts[5]};


    Elem_ll[0] = newreg;    Line Loop(Elem_ll[0]) = {Elem_lns[0],Elem_lns[1],Elem_lns[2],Elem_lns[3]};
    Elem_ll[1] = newreg;    Line Loop(Elem_ll[1]) = {Elem_lns[4],Elem_lns[5],Elem_lns[6],Elem_lns[7]};
    Elem_ll[2] = newreg;    Line Loop(Elem_ll[2]) = {Elem_lns[0],Elem_lns[9],-Elem_lns[4],-Elem_lns[8]};
    Elem_ll[3] = newreg;    Line Loop(Elem_ll[3]) = {-Elem_lns[1],Elem_lns[9],Elem_lns[5],-Elem_lns[10]};
    Elem_ll[4] = newreg;    Line Loop(Elem_ll[4]) = {-Elem_lns[7],Elem_lns[8],Elem_lns[3],-Elem_lns[11]};
    Elem_ll[5] = newreg;    Line Loop(Elem_ll[5]) = {-Elem_lns[6],Elem_lns[11],Elem_lns[2],-Elem_lns[10]};


    Elem_surf[0] = news;    Plane Surface(Elem_surf[0]) = {Elem_ll[0]};
    Elem_surf[1] = news;    Plane Surface(Elem_surf[1]) = {-Elem_ll[1]};
    Elem_surf[2] = news;    Plane Surface(Elem_surf[2]) = {-Elem_ll[2]};
    Elem_surf[3] = news;    Plane Surface(Elem_surf[3]) = {Elem_ll[3]};
    Elem_surf[4] = news;    Plane Surface(Elem_surf[4]) = {-Elem_ll[4]};
    Elem_surf[5] = news;    Plane Surface(Elem_surf[5]) = {-Elem_ll[5]};

    Elem_sl[unit_element] = newsl;
    Surface Loop(Elem_sl[unit_element]) = {Elem_surf[]};
Return 

// MAIN SCRIPT
cl = 0.4;

x_cen = 0.;
y_cen = 0.;
z_cen = 0.;

unit_element = 0;

a = 1.;
Call Cube;
unit_element = unit_element+1;

a = 2.;
Call Cube;
unit_element = unit_element+1;

a = 3.;
Call Cube;
unit_element = unit_element+1;


Volume(1000) = {Elem_sl[0]};
Volume(2000) = {Elem_sl[1],Elem_sl[0]};
Volume(3000) = {Elem_sl[2],Elem_sl[1]};

Physical Volume(1) = {1000};
Physical Volume(2) = {2000};
Physical Volume(3) = {3000};

评论:

  • 可以通过更简单的挤压来完成吗?是的。
  • 可以在没有宏的情况下完成吗?当然。
  • 目标是使用我现有的脚本,并展示如何在 GMSH 中相对灵活地创建这些类型的结构。

在此处输入图像描述