Gmsh剖三维网格教程附代码

前言

前面写过三篇关于Gmsh的教程:

  1. 有限元剖网格之Gmsh安装与使用入门
  2. Gmsh剖一维网格教程附代码
  3. Gmsh剖二维网格教程附代码

以上文章对Gmsh都有一定的介绍,在此不再重复直接接剖三维网格的C++代码。
注:因有一个OpenCASCADE库暂时没安装好,所以目前只能用插点,连线,线连面,面拼体的方式构造三维几何体。

一、程序代码

#include <iostream>
#include <gmsh.h>
#include <vector> 
#include <fstream>
#include <iomanip>
using namespace std;

int main(int argc, char **argv)
{
	// Before using any functions in the C++ API, Gmsh must be initialized.
	gmsh::initialize();
	// By default Gmsh will not print out any messages: in order to output
	// messages on the terminal, just set the standard Gmsh option
	// "General.Terminal" (same format and meaning as in .geo files) using
	// gmsh::option::setNumber():
	gmsh::option::setNumber("General.Terminal", 1);

	// This adds a new model, named "t1". If gmsh::model::add() is not called, a
	// new default (unnamed) model will be created on the fly, if necessary.
	gmsh::model::add("Test1");
	// The C++ API provides direct access to the internal CAD kernels. The
    // built-in CAD kernel was used in t1.geo: the corresponding API functions
    // live in the "gmsh::model::geo" namespace. To create geometrical points with
    // the built-in CAD kernel, one thus uses gmsh::model::geo::addPoint():
    //
    // - the first 3 arguments are the point coordinates (x, y, z)
    //
    // - the next (optional) argument is the target mesh size close to the point
    //
    // - the last (optional) argument is the point tag

  	double lc = 1;
    int pIndex = 1;
  	gmsh::model::geo::addPoint(-4, -4,  -4, lc, pIndex++);
  	gmsh::model::geo::addPoint(4,  -4,  -4, lc, pIndex++);
  	gmsh::model::geo::addPoint(4,   4,  -4, lc, pIndex++);
  	gmsh::model::geo::addPoint(-4,  4,  -4, lc, pIndex++);
  	gmsh::model::geo::addPoint(-4, -4,   4, lc,  pIndex++);
  	gmsh::model::geo::addPoint(4,  -4,   4, lc,  pIndex++);
  	gmsh::model::geo::addPoint(4,   4,   4, lc,  pIndex++);
  	gmsh::model::geo::addPoint(-4,  4,   4, lc,  pIndex++);

  	// The API to create lines with the built-in kernel follows the same
  	// conventions: the first 2 arguments are point tags, the last (optional one)
  	// is the line tag.
    int lIndex = 1;
    int p, q;
    p = 1;
    for(int i = 0; i < 3; i++)
    {
      gmsh::model::geo::addLine(p, p+1, lIndex++);
      p++;
    }
    gmsh::model::geo::addLine(p, 1, lIndex++);

    p = 5;
    for(int i = 0; i < 3; i++)
    {
      gmsh::model::geo::addLine(p, p+1, lIndex++);
      p++;
    }
    gmsh::model::geo::addLine(p, 5, lIndex++);

    p = 1;
    q = 5;
    for(int i = 0; i < 4; i++)
    {
       gmsh::model::geo::addLine(p, q, lIndex++);
       p++;
       q++;
    }

  	// The philosophy to construct curve loops and surfaces is similar: the first
  	// argument is now a vector of integers.
  	gmsh::model::geo::addCurveLoop({1, 2, 3, 4},     1);
  	gmsh::model::geo::addCurveLoop({5, 6, 7, 8},     2);
  	gmsh::model::geo::addCurveLoop({1, 10, -5, -9},  3);
  	gmsh::model::geo::addCurveLoop({2, 11, -6, -10}, 4);
  	gmsh::model::geo::addCurveLoop({3, 12, -7, -11}, 5);
  	gmsh::model::geo::addCurveLoop({-4,12, 8,   -9}, 6);

  	gmsh::model::geo::addPlaneSurface({1}, 1);
  	gmsh::model::geo::addPlaneSurface({2}, 2);
  	gmsh::model::geo::addPlaneSurface({3}, 3);
  	gmsh::model::geo::addPlaneSurface({4}, 4);
  	gmsh::model::geo::addPlaneSurface({5}, 5);
  	gmsh::model::geo::addPlaneSurface({6}, 6);

    gmsh::model::geo::addSurfaceLoop({1, 2, 3, 4, 5, 6}, 1);
    gmsh::model::geo::addVolume({1}, 1);
  	// Physical groups are defined by providing the dimension of the group (0 for
  	// physical points, 1 for physical curves, 2 for physical surfaces and 3 for
  	// phsyical volumes) followed by a vector of entity tags. The last (optional)
  	// argument is the tag of the new group to create.

	gmsh::model::setPhysicalName(3, 1, "My volume");

    // Before it can be meshed, the internal CAD representation must be
    // synchronized with the Gmsh model, which will create the relevant Gmsh data
    // structures. This is achieved by the gmsh::model::geo::synchronize() API
    // call for the built-in CAD kernel. Synchronizations can be called at any
    // time, but they involve a non trivial amount of processing; so while you
    // could synchronize the internal CAD data after every CAD command, it is
    // usually better to minimize the number of synchronization points.
    gmsh::model::geo::synchronize();

    // We can then generate a 2D mesh...
    gmsh::model::mesh::generate();
    //gmsh::model::mesh::refine();

    // ... and save it to disk
    gmsh::write("demo.msh");

    // Remember that by default, if physical groups are defined, Gmsh will export
    // in the output mesh file only those elements that belong to at least one
    // physical group. To force Gmsh to save all elements, you can use
    //
    // gmsh::option::setNumber("Mesh.SaveAll", 1);

    // This should be called at the end:
    gmsh::finalize();
    return 0;
}

二、程序结果

程序会在对应目录下产生一个“demo.msh”文件,用图形界面的gmsh软件打开,可以设置各种参数查看网格结果。

1. 带有点标号的结果图

在这里插入图片描述

2. 没有点标号的结果图

在这里插入图片描述

三、总结

以上代码可以去我的GitHub网站下载查看。后续会整理用Gmsh剖网格的教程,欢迎大家一起讨论学习交流。

  • 2
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OCC是一个开源的CAD内核,可用于三维建模,几何计算,网格处理等。而Gmsh是一个开源的三维有限元网格划分软件,可以用于建立复杂的三维几何模型,并将其转化为有限元网格。因此,我们可以使用OCC创建一个三维几何模型,然后使用Gmsh将其转化为有限元网格。 以下是一个基于OCC和Gmsh网格划分的示例代码: ```python # 导入必要的模块 import OCC.Core.BRepPrimAPI as BPA import OCC.Core.STEPControl as STEP import OCC.Core.GProp as GPROP import OCC.Core.BRepGProp as BGPROP import OCC.Core.TopoDS as TOPODS import OCC.Core.TopExp as TOP_EXP import OCC.Core.TopAbs as TOP_ABS import OCC.Core.BRepTools as BREP_TOOLS import OCC.Core.BRepMesh as BREP_MESH import OCC.Core.GProp as GPROP import OCC.Core.TColgp as TCOLGP import OCC.Core.TopAbs as TOP_ABS import OCC.Display.SimpleGui as SG import gmsh # 创建一个立方体模型 my_box = BPA.BRepPrimAPI_MakeBox(10, 20, 30).Shape() # 将模型保存为STEP格式 step_writer = STEP.STEPControl_Writer() step_writer.Transfer(my_box, STEP.STEPControl_AsIs) step_writer.Write('my_box.stp') # 初始化Gmsh gmsh.initialize() # 导入模型 gmsh.model.occ.importShapes('my_box.stp') # 定义网格大小 mesh_size = 0.5 # 划分网格 gmsh.model.mesh.generate(3) # 获取网格 mesh = gmsh.model.mesh.getNodes(), gmsh.model.mesh.getElements() # 关闭Gmsh gmsh.finalize() ``` 在此示例中,我们首先使用OCC创建了一个立方体模型,并将其保存为STEP格式。然后,我们使用Gmsh导入该模型,并使用`gmsh.model.mesh.generate()`方法将其转化为有限元网格。最后,我们使用`gmsh.model.mesh.getNodes()`和`gmsh.model.mesh.getElements()`方法获取网格的节点和元素信息,并将其存储在`mesh`变量中。 请注意,在使用Gmsh之前,我们需要使用`gmsh.initialize()`方法初始化Gmsh,并在使用完毕后使用`gmsh.finalize()`方法关闭Gmsh
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值