前言
前面写过三篇关于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剖网格的教程,欢迎大家一起讨论学习交流。