有限元剖网格之Gmsh安装与使用入门

文章目录

  • 有限元剖网格之Gmsh安装与使用入门
    • Gmsh介绍
    • Gmsh安装
      • 1. Gmsh图形界面安装
      • 2. Gmsh从源码安装
    • 利用C++语言调用Gmsh的API接口剖网格

有限元剖网格之Gmsh安装与使用入门

有限元法(FEM,Finite Element Method)是一种求解偏微分方程问题的数值方法。随着电子计算机的发展,有限元方法迅速发展成一种现代计算方法,在固体力学、流体力学、热传导、电磁学、声学、生物力学等方面有着广泛的应用。今天就先介绍有限元方法之前处理,利用Gmsh剖网格。

Gmsh介绍

Gmsh是一个自动的三维有限元网格生成带有内置在CAD和后期处理器。当然其也可以生成一维和二维的有限元网格。

Gmsh安装

1. Gmsh图形界面安装

可以去官网下载安装包Gmsh官网

可以在Download处

Download Gmsh for Windows 64-bit, Windows 32-bit, Linux 64-bit, Linux
32-bit or MacOS

点击自己电脑对应的系统下载,安装成功后会在电脑上有如下图所示的软件:
有限元剖网格之Gmsh安装与使用入门_第1张图片
打开后去用其打开下载的"*.geo"(在Download处点击 Download the source code里面可以找到)文件,之后在Gmsh软件界面内点击点击Mesh下的2D,可以得到如下图的网格
有限元剖网格之Gmsh安装与使用入门_第2张图片
注:Gmsh软件上方的菜单栏亦有将网格数据导出的功能,可以导出多种标准格式。

2. Gmsh从源码安装

在官网的Download处点击下载

Download the source code

注:此处链接失效的话可以去前面提到的官网对应位置下载。

解压后有"README.txt"文件里面介绍了如何安装,以下为详细步骤:

  1. 从Terminal进入到如下图所示目录:
    有限元剖网格之Gmsh安装与使用入门_第3张图片
  2. 输入命令:mkdir build
  3. cd build
  4. cmake -DENABLE_BUILD_DYNAMIC=1 …
  5. make
  6. make install

注: 其中第5步时间可能稍长,耐心等待就行。

利用C++语言调用Gmsh的API接口剖网格

可在源码的同级目录下建立demo文件夹,里面放自己学习的代码。将如下代码拷贝到"demo.cpp"文件中

#include 
#include 
#include  
#include 
#include 
using namespace std;


void writeNodes(vector<double>& nodes, string s)
{
	string filename = s + ".txt";
	ofstream outfileb(filename.c_str(), ios::out);
	for(int i = 0; i < nodes.size(); i++)
	{
		outfileb<<(nodes[i])<<endl;
	}
	outfileb.close();
}


void writeElements(vector<std::vector<std::size_t> >& elements, string s)
{
	string filename = s + ".txt";
	ofstream outfileb(filename.c_str(), ios::out);
	for(int i = 0; i < elements[1].size(); i++)
	{
		outfileb<<(elements[1][i])<<endl;
	}
	outfileb.close();
}


int main(int argc, char **argv)
{

	gmsh::initialize();
	gmsh::model::add("Test1");

  	double lcc = 0.05;//2e-1;
  	gmsh::model::geo::addPoint(1.0/3, 1.0/3,  0, lcc, 100);
  	gmsh::model::geo::addPoint(2.0/3, 1.0/3,  0, lcc, 101);
  	gmsh::model::geo::addPoint(2.0/3, 2.0/3,  0, lcc, 102);
  	gmsh::model::geo::addPoint(1.0/3, 2.0/3,  0, lcc, 103);
  	gmsh::model::geo::addLine(100, 101, 100);
  	gmsh::model::geo::addLine(101, 102, 101);
  	gmsh::model::geo::addLine(102, 103, 102);
  	gmsh::model::geo::addLine(103, 100, 103);
  	gmsh::model::geo::addCurveLoop({100, 101, 102, 103}, 100);

  	double lc = 0.2;//2e-1;
  	gmsh::model::geo::addPoint(-1, 0,  0, lc, 1);
  	gmsh::model::geo::addPoint(1,  0,  0, lc, 2);
  	gmsh::model::geo::addPoint(1,  1,  0, lc, 3);
  	gmsh::model::geo::addPoint(-1, 1,  0, lc, 4);
  	gmsh::model::geo::addPoint(0,  0,  0, lc, 555);

  	gmsh::model::geo::addLine(1, 555, 1);
  	gmsh::model::geo::addLine(555, 2, 555);
  	gmsh::model::geo::addLine(2, 3, 2);
  	gmsh::model::geo::addLine(3, 4, 3);
  	gmsh::model::geo::addLine(4, 1, 4);

  	gmsh::model::geo::addCurveLoop({1, 555, 2, 3, 4}, 1);
  	gmsh::model::geo::addPlaneSurface({1, -100}, 1);

  	gmsh::model::geo::addPoint(1,  2,  0, lc, 5);
  	gmsh::model::geo::addPoint(-1, 2,  0, lc, 6);
  	gmsh::model::geo::addLine(3, 5, 5);
  	gmsh::model::geo::addLine(5, 6, 6);
  	gmsh::model::geo::addLine(6, 4, 7);
  	gmsh::model::geo::addCurveLoop({-3, 5, 6, 7}, 2);
	gmsh::model::geo::addPlaneSurface({2}, 2);

	gmsh::model::setPhysicalName(2, 6, "My surface");
	gmsh::model::geo::synchronize();

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

	// get mesh information
	// Nodes
	vector<double> nodes,y;
	vector<std::size_t> nodeTags;
	gmsh::model::mesh::getNodes(nodeTags, nodes, y, -2, -1, false, true);
	cout<<"The number of nodes: "<<nodes.size()/3<<endl;
#if 0
	cout<<endl;
	for(int i = 0; i < nodes.size(); i++)
	{
		cout<<nodes[i]<<endl;
	}
#endif
	writeNodes(nodes, "nodes");

	//Elements
	vector<int> elementTypes;
	vector<std::vector<std::size_t> > elementTags, nodeTags2;
	gmsh::model::mesh::getElements(elementTypes, elementTags, nodeTags2, -2, -1);
	cout<<"The number of elements: "<<nodeTags2[1].size()/3<<endl;
#if 0
	cout<<endl;
	for(int j = 0; j < nodeTags2[1].size(); j++)
	{
		cout<<nodeTags2[1][j]<<endl;
		
	}
#endif
	writeElements(nodeTags2, "elements");
	gmsh::write("demo.msh");
	gmsh::finalize();
	return 0;
}

然后在终端进入到有"demo.cpp"文件的目录下,输入如下命令:

g++ demo.cpp -std=c++11 -Iinclude -lgmsh -o exe

之后再输入:

./exe

则会在终端有如下的输出:

The number of nodes: 239
The number of elements: 410

同时文件夹下会多出"demo.msh", “elements.txt”, "nodes.txt"三个文件,用图形画的Gmsh软件,打开"demo.msh"文件,既可以看到如下图所示的网格:

以上事例程序写的比较粗糙,仅作为测试,可去我的GitHub网站下载学习。通过写C++程序调用Gmsh的API接口,自己也用了很长一段时间了,也写了不少EXample程序,后面时间充足会都总结上传到我的GitHub仓库中,欢迎大家一起学习讨论。

你可能感兴趣的:(有限元,c++)