網(wǎng)絡(luò)平臺(tái)怎么弄湖南seo推廣
FastCAE使用gmsh進(jìn)行網(wǎng)格劃分,劃分的時(shí)候直接啟動(dòng)一個(gè)新的gmsh進(jìn)程,個(gè)人猜測(cè)這么設(shè)計(jì)是為了規(guī)避gmsh的GPL協(xié)議風(fēng)險(xiǎn)。
進(jìn)行網(wǎng)格劃分時(shí),其大體運(yùn)行如下圖:
一、Python到gmshModule模塊
GUI操作到Python這步不再分析,比較簡(jiǎn)單。執(zhí)行的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()
這些代碼可以在控制臺(tái)找到,如下圖:
這樣創(chuàng)建了一個(gè)gmsher對(duì)象,賦予網(wǎng)格劃分的控制參數(shù),最后調(diào)用startGenerationThread()方法,這個(gè)方法的源碼在Mesher.py文件中。對(duì)于三維問題,會(huì)調(diào)用gmshModule模塊的接口GenerateMesh3D()。gmshModule同樣提供了針對(duì)二維、流體網(wǎng)格的劃分接口,代碼在GmshPy.h文件中,如下圖所示。
二、啟動(dòng)gmsh線程,寫出gmsh文件,生成網(wǎng)格
在GmshPy::GenerateMesh3D()函數(shù)中,只是準(zhǔn)備網(wǎng)格劃分的參數(shù),最后會(huì)調(diào)用到GmshModule::generateSlot()函數(shù)中。
void GmshModule::generateSlot(GMshPara *para)
{GmshThread *thread = iniGmshThread(para);auto processBar = new ModuleBase::ProcessBar(_mainwindow, tr("Gmsh Working..."));_threadManager->insertThread(processBar, thread); // 運(yùn)行g(shù)msh線程
}// 初始化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函數(shù)中,會(huì)初始化一個(gè)線程,并啟動(dòng)運(yùn)行。
再打開GmshThread的run方法,大體流程就是合并幾何對(duì)象,形成一個(gè)TopoDS_Compound對(duì)象,調(diào)用BRepTools::Write寫出geometry.brep文件。寫出gmsh控制文件,最后調(diào)用gmsh命令生成網(wǎng)格文件。
void GmshThread::run(){this->mergeGeometry(); // 寫出幾何文件this->initGmshEnvoirment(); // 寫出gmsh的控制文件this->generate(); // 執(zhí)行g(shù)msh命令}void GmshThread::mergeGeometry(){QString exelPath = QCoreApplication::applicationDirPath();const QString tempDir = exelPath + "/../temp/";QDir dir(tempDir);if (!dir.exists())dir.mkpath(tempDir);// 清理之前的臨時(shí)文件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(); // 將需要?jiǎng)澐志W(wǎng)格的組成一個(gè)compounnd對(duì)象else if (_selectvisible)mergeVisibleGeo();elsemergeSelectGeo();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_WINok = QFile::exists(gmshexe + ".exe");
#endif
#ifdef Q_OS_LINUXok = QFile::exists(gmshexe);
#endifif (!ok){QMessageBox::warning(_mainwindow, QString(tr("Warning")), QString(tr("Gmsh is not exist !")));return;}// 調(diào)用gmsh生成網(wǎng)格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);}
最后調(diào)用的gmsh命令大體如下,生成mesh.vtk網(wǎng)格文件。
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
三、讀取網(wǎng)格文件
讀取網(wǎng)格文件代碼在GmshThread::readMesh函數(shù)中,注意執(zhí)行這段代碼時(shí)gmsh線程已經(jīng)結(jié)束了。
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讀取的。