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

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读取的。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于《环境影响评价技术导则大气环境(HJ 2.2-2018)》的AERMOD模型配置方法

数值模式模拟是分析大气污染物时空分布和成分贡献的重要工具&#xff0c;利用模拟结果可以分析大气污染的来源、成因、污染程度、持续时间、主要成分、相对贡献等问题&#xff0c;有助于分析并合理控制污染源排放&#xff0c;为产业调整提供参考。当前&#xff0c;针对不同理论…

深度学习 python opencv 实现人脸年龄性别识别 计算机竞赛

文章目录 0 前言1 项目课题介绍2 关键技术2.1 卷积神经网络2.2 卷积层2.3 池化层2.4 激活函数&#xff1a;2.5 全连接层 3 使用tensorflow中keras模块实现卷积神经网络4 Keras介绍4.1 Keras深度学习模型4.2 Keras中重要的预定义对象4.3 Keras的网络层构造 5 数据集处理训练5.1 …

C++面向对象编程(4)——浅谈C++内存模型

目录 一. 说明 二. GDB实验 2.1 实验1&#xff1a;栈 2.2 实验2&#xff1a;堆 一. 说明 不同的操作系统对程序内存的管理和划分会有所不同。如上图所示的C内存区域划分主要是针对一般的情况&#xff0c;说明如下&#xff1a; 1. Stack&#xff1a;栈。由编译器管理分配和回…

CKA认证模块②-K8S企业运维和落地实战-2

CKA认证模块②-K8S企业运维和落地实战-2 K8S常见的存储方案及具体应用场景分析 k8s存储-empty emptyDir类型的Volume是在Pod分配到Node上时被创建&#xff0c;Kubernetes会在Node上自动分配一个目录&#xff0c;因此无需指定宿主机Node上对应的目录文件。 这个目录的初始内容…

从0到0.01入门React | 005.精选 React 面试题

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

快速批量去除文件夹名称中多余重复文字!一键轻松优化文件夹命名!

您是否曾经因为文件夹名称中多余重复文字而烦恼&#xff1f;是否因为文件夹重命名而浪费大量时间&#xff1f;现在&#xff0c;我们为您推荐一款全新的文件夹批量改名工具——快速批量去除文件夹名称中多余重复文字&#xff0c;轻松实现文件夹改名优化&#xff0c;让您的整理效…

企业微信后台通过小程序给员工发送文字信息附带超链接实现(加上A标签:<a href=“网址“> </a>)

如下&#xff0c;在编辑文本消息的时候&#xff0c;添加上HTML的A标签 <a href"www.baidu"> </a>即可实现点击直接跳转

移远EC600U-CN开发板 day04

控件探索-滑杆&#xff08;lv.slider&#xff09; 1. 显示一个简单的滑杆 def slider_event_cb(evt): slider evt.get_target()# 修改label的值label.set_text(str(slider.get_value()))slider lv.slider(scr) #创建滑杆组件 slider.set_width(200) #设置滑杆宽…

上门洗衣洗鞋app小程序

上门洗衣洗鞋app小程序作为专业的帮助用户洗衣服务的软件,许多朋友都使用过。在这里,小编就帮助大家收集一些非常不错的洗衣洗鞋软件。 不知道大家是否还在为洗衣而烦恼,而怕麻烦,现在大家都在用网上的洗衣洗鞋小程序来洗衣服,用户只需要打开手机软件,发起订单,门店即可收到订单…

Flink SQL --命令行的使用(02)

1、窗口函数&#xff1a; 1、创建表&#xff1a; -- 创建kafka 表 CREATE TABLE bid (bidtime TIMESTAMP(3),price DECIMAL(10, 2) ,item STRING,WATERMARK FOR bidtime AS bidtime ) WITH (connector kafka,topic bid, -- 数据的topicproperties.bootstrap.servers m…

产品速递 | 璞华采云端,打造降本增效的企业采购订单协同平台

为应对快速变化的市场环境&#xff0c;企业需要建立起更加敏捷、灵活的采购体系&#xff0c;利用数字化手段提高工作效率、降低潜在风险&#xff0c;将是企业构筑新时代竞争壁垒的关键要素。 而控制采购成本对一个企业的经营业绩至关重要。采购成本下降不仅体现在企业现金流出的…

正交试验DOE

它原本是日本学者为了质量管理而设计的试验。后来被用在算法的参数设计上&#xff0c;可以利用部分的试验确定出最合理的参数组合。 举个例子&#xff0c;比如遗传算法中的种群数pop&#xff0c;交叉概率pr&#xff0c;变异概率pm&#xff0c;以及迭代次数N&#xff0c;每个参…

字符串和内存函数(1)

文章目录 目录1. 前言2. 函数介绍2.1 strlen2.2 strcpy2.3 strcat2.4 strcmp2.5 strncpy2.6 strncat2.7 strncmp2.8 strstr2.9 strtok2.10 strerror2.11 字符分类函数2.12 字符转换函数 目录 求字符串长度函数长度不受限制的字符串函数长度受限制的字符串函数字符串查找函数错…

1.0.0 IGP高级特性简要介绍(OSPF-下篇)

二、OSPF_精细的路由控制 1.OSPF数据库上限 简介 ​ OSPF技术要求同一个区域内的路由器保存着相同的LSDB信息。 ​ 但随着网络上路由数量不断增加&#xff0c;一些路由器由于系统资源有限&#xff0c;不能再承载如此多的路由信息&#xff0c;这种状态就被称为数据库超限&am…

蓝桥杯每日一题2023.11.13

题目描述 蓝桥杯大赛历届真题 - C 语言 B 组 - 蓝桥云课 (lanqiao.cn) 题目分析 由于每次吹灭的蜡烛与年龄相同故我们想到使用前缀和可以让我们求出各个区间的和&#xff0c;我们将每个区间都枚举一遍&#xff0c;如果符合要求就输出区间开始的位置&#xff08;答案&#xff…

基于GoogleNet深度学习网络的花朵类型识别matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1. GoogleNet网络结构 4.2. 基于GoogleNet的花朵类型识别 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 .............................…

sql查询查看数据库空间使用情况

SELECT UPPER(F.TABLESPACE_NAME) "表空间名", D.TOT_GROOTTE_MB "表空间大小(M)", D.TOT_GROOTTE_MB - F.TOTAL_BYTES "已使用空间(M)", TO_CHAR(ROUND((D.TOT_GROOTTE_MB - F.TOTAL_BYTES) / D.TOT_GROOTTE_MB * 100,2),990.99) || % "使…

Ansys Electronics Desktop仿真——HFSS线圈寄生电阻,电感

利用ANSYS Electronics Desktop&#xff0c;可在综合全面、易于使用的设计平台中集成严格的电磁场分析和系统电路仿真。按需求解器技术让您能集成电磁场仿真器和电路及系统级仿真&#xff0c;以探索完整的系统性能。 HFSS&#xff08;High Frequency Structure Simulator&#…

如何使用软路由R4S+iStoreOS实现远程访问内网电脑桌面

软路由R4SiStoreOS实现公网远程桌面局域网内电脑 文章目录 软路由R4SiStoreOS实现公网远程桌面局域网内电脑简介一、配置远程桌面公网地址二、家中使用永久固定地址 访问公司电脑**具体操作方法是&#xff1a;** 简介 上篇教程我们介绍了如何在iStoreOS中安装Cpolar&#xff0…

RE切入点:选择SLI,设定SLO

还是先来复习下上节课讲的“系统可用性”的两种计算方式&#xff0c;一种是从故障角度出发&#xff0c;以时长维度对系统进行稳定性评估&#xff1b;另一种是从成功请求占比角度出发&#xff0c;以请求维度对系统进行稳定性评估。同时&#xff0c;我们还讲到&#xff0c;在 SRE…