【FastCAE源码阅读8】调用gmsh生成网格

news2024/11/14 14:53:40

FastCAE使用gmsh进行网格划分,划分的时候直接启动一个新的gmsh进程,个人猜测这么设计是为了规避gmsh的GPL协议风险。
进行网格划分时,其大体运行如下图:
在这里插入图片描述

一、Python到gmshModule模块

GUI操作到Python这步不再分析,比较简单。执行的Python代码大概如下:

gmsher = Mesher.Gmsher()
gmsher.setDim(3)
gmsher.selectedAll()
gmsher.setElementType("Tet")
gmsher.setElementOrder(1)
gmsher.setMethod(1)
gmsher.setSizeFactor(1)
gmsher.setMinSize(0)
gmsher.setMaxSize(100)
gmsher.cleanGeo()
gmsher.startGenerationThread()

这些代码可以在控制台找到,如下图:
在这里插入图片描述
这样创建了一个gmsher对象,赋予网格划分的控制参数,最后调用startGenerationThread()方法,这个方法的源码在Mesher.py文件中。对于三维问题,会调用gmshModule模块的接口GenerateMesh3D()。gmshModule同样提供了针对二维、流体网格的划分接口,代码在GmshPy.h文件中,如下图所示。
在这里插入图片描述

二、启动gmsh线程,写出gmsh文件,生成网格

在GmshPy::GenerateMesh3D()函数中,只是准备网格划分的参数,最后会调用到GmshModule::generateSlot()函数中。

void GmshModule::generateSlot(GMshPara *para)
{
	GmshThread *thread = iniGmshThread(para);
	auto processBar = new ModuleBase::ProcessBar(_mainwindow, tr("Gmsh Working..."));
	_threadManager->insertThread(processBar, thread); // 运行gmsh线程
}

// 初始化gmsh线程
GmshThread *GmshModule::iniGmshThread(GMshPara *para)
{
	if (_threadManager->isRuning())
	{
		delete para;
		ModuleBase::Message m(Common::Message::Error, QString("Gmsh is running !"));
		emit printMessageToMessageWindow(m);
	}
	GmshThread *thread = new GmshThread(_mainwindow, _preWindow, this, para->_dim);
	thread->setPara(para);
	delete para;
	return thread;
}

在GmshModule::generateSlot函数中,会初始化一个线程,并启动运行。
再打开GmshThread的run方法,大体流程就是合并几何对象,形成一个TopoDS_Compound对象,调用BRepTools::Write写出geometry.brep文件。写出gmsh控制文件,最后调用gmsh命令生成网格文件。

	void GmshThread::run()
	{
		this->mergeGeometry(); // 写出几何文件
		this->initGmshEnvoirment(); // 写出gmsh的控制文件
		this->generate(); // 执行gmsh命令
	}

	void GmshThread::mergeGeometry()
	{
		QString exelPath = QCoreApplication::applicationDirPath();
		const QString tempDir = exelPath + "/../temp/";
		QDir dir(tempDir);
		if (!dir.exists())
			dir.mkpath(tempDir);
        
        // 清理之前的临时文件
		const QString meshfilename = exelPath + "/../temp/mesh.vtk";
		if (QFile::exists(meshfilename))
			QFile::remove(meshfilename);

		const QString geofilename = exelPath + "/../temp/geometry.brep";
		if (QFile::exists(geofilename))
			QFile::remove(geofilename);

		const QString gmshfilename = exelPath + "/../temp/gmsh.Geo";
		if (QFile::exists(gmshfilename))
			QFile::remove(gmshfilename);

		const QString tempPath = tempDir + QString("geometry.brep");

		if (_fluidMesh)
			_fluidMeshProcess->mergeFluidField(_compounnd, _solidHash);
		else if (_selectall)
			mergeAllGeo();       // 将需要划分网格的组成一个compounnd对象
		else if (_selectvisible)
			mergeVisibleGeo();
		else
			mergeSelectGeo();
		QByteArray arr = tempPath.toLatin1();
		BRepTools::Write(*_compounnd, arr.data()); // 使用BRepTools写出geometry.brep文件
	}

	void GmshThread::initGmshEnvoirment()
	{
		QString exelPath = QCoreApplication::applicationDirPath();
		const QString tempDir = exelPath + "/../temp/";
		// const QString gmshDir = exelPath + "/gmsh/";
		QFile::remove(tempDir + "gmsh.Geo");

		_scriptWriter->setCompound(_compounnd);
		setGmshScriptData();

		if (_fluidMesh)
		{
			QList<int> curve = _fluidMeshProcess->getInerMember(1);
			QList<int> surface = _fluidMeshProcess->getInerMember(2);
			_scriptWriter->writeFluidMeshScript(tempDir, _solidHash, curve, surface);
		}
		else
			_scriptWriter->writeGmshScript(tempDir); //  写出gmsh控制文件
	}

	void GmshThread::generate()
	{
		QString exelPath = QCoreApplication::applicationDirPath();
		const QString tempDir = exelPath + "/../temp/";
		// const QString gmshDir = exelPath + "/gmsh/";
		QString gmshexe = exelPath + "/gmsh";

		bool ok = false;
#ifdef Q_OS_WIN
		ok = QFile::exists(gmshexe + ".exe");
#endif
#ifdef Q_OS_LINUX
		ok = QFile::exists(gmshexe);
#endif
		if (!ok)
		{
			QMessageBox::warning(_mainwindow, QString(tr("Warning")), QString(tr("Gmsh is not exist !")));
			return;
		}

        // 调用gmsh生成网格
		QString startProcess = QString("%1 %2 -format vtk -bin -o %3 -%4").arg(gmshexe).arg(tempDir + "gmsh.Geo").arg(tempDir + "mesh.vtk").arg(_dim);

		if (gmshexe.contains(" "))
			startProcess = QString("\"%1\"").arg(startProcess);
		qDebug() << startProcess;

		_process.start(startProcess);
	}

最后调用的gmsh命令大体如下,生成mesh.vtk网格文件。
C:/workspace/FastCAE/build/Debug/gmsh C:/workspace/FastCAE/build/Debug/…/temp/gmsh.Geo -format vtk -bin -o C:/workspace/FastCAE/build/Debug/…/temp/mesh.vtk -3

三、读取网格文件

读取网格文件代码在GmshThread::readMesh函数中,注意执行这段代码时gmsh线程已经结束了。

void GmshThread::readMesh()
{
	MeshData::MeshData *data = MeshData::MeshData::getInstance();
	QString exelPath = QCoreApplication::applicationDirPath();
	const QString fileName = exelPath + "/../temp/mesh.vtk";
	QTextCodec *codec = QTextCodec::codecForName("GB18030");
	QByteArray ba = codec->fromUnicode(fileName);
	vtkSmartPointer<vtkDataSetReader> vtkReader = vtkSmartPointer<vtkDataSetReader>::New();
	vtkReader->SetFileName(ba);
	vtkReader->Update();
	vtkDataSet *dataset = vtkReader->GetOutput();
	if (dataset == nullptr)
		return;
	if (!_isSaveToKernal)
		emit writeToSolveFileSig(dataset);
	else
	{
		auto k = new MeshData::MeshKernal();
		k->setName(QString("Mesh_%1").arg(k->getID()));
		k->setMeshData(dataset);
		data->appendMeshKernal(k);
		if (!_fluidMesh)
			setGmshSettingData(k);
		emit _gmshModule->updateMeshTree();
		emit _gmshModule->updateSetTree();
		//			emit _preWindow->updateMeshActorSig();
		emit _gmshModule->updateActions();
		emit updateMeshActor();
	}
}

由于gmsh输出的是vtk文件,这里直接使用vtkDataSetReader读取的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1202625.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++学习第三十七天----第十章--对象和类

10.2.2 C中的类 类是一种将抽象转换未用户定义类型的C工具&#xff0c;它将数据表示和操作数据的方法合成一个整洁的包。 接口&#xff1a;一个共享框架&#xff0c;供两个系统交互时使用。 1.访问控制 使用类对象的程序可以直接访问类的公有部分&#xff0c;但只能通过公有…

单片机定时器讲解和实现

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、计数器是什么&#xff1f;二、单片机定时器结构2.1***两个8位如何合成16位&#xff0c;16位如何分成两个8位***2.2 计数器的位数组合&#xff1f;2.3 定时功…

用python将csv表格数据做成热力图

python的开发者为处理表格和画图提供了库的支持&#xff0c;使用pandas库可以轻松完成对csv文件的读写操作&#xff0c;使用matplotlib库提供了画热力图的各种方法。实现这个功能首先需要读出csv数&#xff0c;然后设置自定义色条的各种属性如颜色&#xff0c;位置&#xff0c;…

[Android]新建项目使用AppCompatActivity后运行闪退

报错 日志&#xff1a; Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity. FATAL EXCEPTION: main Process: com.example.gatestdemol, PID: 26071 java.lang.RuntimeException: Unable to start a…

Maya v2024(3D动画制作软件)

Maya 2024是一款三维计算机图形动画制作软件。它被广泛应用于电影、电视、游戏、动画等领域中&#xff0c;用于创建各种三维模型、场景、特效和动画。 以下是Maya的主要特点&#xff1a; 强大的建模工具&#xff1a;Maya提供了各种建模工具&#xff0c;如多边形建模、NURBS建模…

VsCode 安装 GitHub Copilot插件 (最新)

##在线安装&#xff1a; 打开Vscode扩展商店&#xff0c;输入 "GitHub Copilot " ,选择下载人数最多的那个。&#xff08;这个是你写一部分代码或者注释&#xff0c;Ai自动帮你提示/补全代码&#xff09;,建议选择这个 注意下面有个和他类似的 "GitHub Copilo…

Linux系统编程——其他类型数据写到文件并读取

函数原型解读 由前面章节可知&#xff0c;对文件的操作都是基于字符串&#xff0c;但对文件的操作并不仅限于此&#xff0c;这个时候需要重新审视几个文件操作的函数原型&#xff0c;函数原型如下&#xff1a; ssize_t write(int fd, const void *buf, size_t count); ssize_…

月入8.3k,新传文科生转行5G网络优化工程师,张雪峰:这专业,报考就打晕…

新闻传播专业的就业是什么样子的&#xff1f; 考研名师张雪峰说&#xff1a;如果我是家长的话&#xff0c;孩子非要报新闻学&#xff0c;我一定会干一个事&#xff0c;就是把他打晕&#xff0c;然后给他报个别的。 新闻传播专业似乎已经成了一个备受争议的话题&#xff0c;就业…

测试用例之翻页功能

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

《Linux从练气到飞升》No.26 Linux中的线程控制

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux菜鸟刷题集 &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的…

目标检测问题总结

目标检测问题总结 目标检测二阶段和一阶段的核心区别目标检测二阶段比一阶段的算法精度高的原因1. 正负样本不平衡2.样本的不一致性 如何解决目标检测中遮挡问题如何解决动态目标检测FPN的作用如何解决训练数据样本过少的问题IOU代码实现NMS代码实现NMS的改进思路 目标检测二阶…

DBC文件解析成C语言

1. 安装python环境 例如Windows安装python3.10版本 下载地址https://cdn.npmmirror.com/binaries/python/3.10.9/python-3.10.9-amd64.exe 2. 安装cantools函数库 打开CMD窗口后&#xff0c;输入pip install cantools 3. 执行dbc文件转为C语言 注意&#xff1a;c文件和…

时间序列预测(2) — 时间序列预测数据集

目录 数据集1&#xff1a;GEFCom2014负荷数据 数据集2&#xff1a;爱奇艺用户留存预测挑战赛数据集 数据集1&#xff1a;GEFCom2014负荷数据 数据集下载&#xff1a; 百度网盘&#xff1a;链接&#xff1a;https://pan.baidu.com/s/1PgCWHx8vYUfGB9UGtCmaVA?pwdktn0 提取码…

儿童HPV感染有哪些症状?皮肤性病科谭巍主任讲述五大要点

HPV&#xff0c;人乳头瘤病毒&#xff0c;是一种常见的感染性强的病毒&#xff0c;相比成人儿童也会感染HPV。家长及时了解儿童感染HPV的症状对于早期发现和治疗至关重要。为了帮助家长们更好预防儿童HPV感染&#xff0c;今日特邀劲松中西医医院皮肤性病科主任谭巍详细介绍儿童…

MoveIt 机械臂运动 学习 01-MoveIt 初次见面

ROS中有针对机器人进行移动操作的一套工具——MoveIt&#xff01;。在主页http://moveit.ros.org 上 包含使用MoveIt&#xff01;的文档、教程、安装说明以及多种机械臂&#xff08;或机器人&#xff09;的示例演示&#xff0c;如一些 移动操作任务&#xff0c;包括抓握、拾取和…

前端框架图谱

以上图谱基于个人经验总结&#xff0c;比如小程序、第三方平台等未在其中有所体现

Web安全之PHP的伪协议漏洞利用,以及伪协议漏洞防护方法

一、背景 今天介绍一个比较冷门的知识&#xff0c;只有在PHP环境中存在的伪协议漏洞&#xff0c;那么什么是PHP伪协议呢&#xff1f;PHP伪协议事实上就是支持的协议与封装协议。可用于类似 fopen()、 copy()、 file_exists() 和 filesize() 的文件系统函数。 除了这些封装协议…

sqlmap requires ‘python-pymysql‘ third-party library

使用sqlmap进行udf提权报错&#xff1a; [14:06:04] [CRITICAL] sqlmap requires python-pymysql third-party library in order to directly connect to the DBMS MySQL. You can download it from https://github.com/PyMySQL/PyMySQL. Alternative is to use a package pyt…

[WSL] 安装MySQL8

安装版本 mysql --version mysql Ver 8.0.35-0ubuntu0.20.04.1 for Linux on x86_64 ((Ubuntu))安装步骤 sudo apt-get update sudo apt-get upgradesudo apt-get install mysql-server apt install mysql-client apt install libmysqlclient-devsudo usermod -d /var/lib/m…