From acbb35b4c3ff446320464c86cfbfe9e6909ee2ae Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 25 Jul 2022 10:34:43 +0200 Subject: [PATCH 01/29] Using provider for occgeom and nglib --- src/NETGENPlugin/CMakeLists.txt | 41 +++---- src/NETGENPlugin/NETGENPluginBuilder.py | 23 ++-- .../NETGENPlugin_NETGEN_2D_ONLY.cxx | 89 ++++++++------ src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 14 ++- src/NETGENPlugin/NETGENPlugin_Provider.hxx | 112 ++++++++++++++++++ 5 files changed, 204 insertions(+), 75 deletions(-) create mode 100644 src/NETGENPlugin/NETGENPlugin_Provider.hxx diff --git a/src/NETGENPlugin/CMakeLists.txt b/src/NETGENPlugin/CMakeLists.txt index bfd9494..0177a58 100644 --- a/src/NETGENPlugin/CMakeLists.txt +++ b/src/NETGENPlugin/CMakeLists.txt @@ -34,7 +34,7 @@ INCLUDE_DIRECTORIES( ) # additional preprocessor / compiler flags -ADD_DEFINITIONS( +ADD_DEFINITIONS( ${OMNIORB_DEFINITIONS} ${OpenCASCADE_DEFINITIONS} ${BOOST_DEFINITIONS} @@ -70,27 +70,28 @@ SET(_link_LIBRARIES # header files SET(NETGENEngine_HEADERS - NETGENPlugin_NETGEN_3D.hxx - NETGENPlugin_NETGEN_3D_i.hxx - NETGENPlugin_NETGEN_2D.hxx - NETGENPlugin_NETGEN_2D_i.hxx - NETGENPlugin_NETGEN_2D3D.hxx - NETGENPlugin_NETGEN_2D3D_i.hxx - NETGENPlugin_NETGEN_2D_ONLY.hxx - NETGENPlugin_NETGEN_2D_ONLY_i.hxx - NETGENPlugin_Hypothesis.hxx - NETGENPlugin_Hypothesis_i.hxx - NETGENPlugin_Hypothesis_2D.hxx - NETGENPlugin_Hypothesis_2D_i.hxx - NETGENPlugin_Hypothesis_3D_i.hxx - NETGENPlugin_Hypothesis_2D_ONLY_i.hxx - NETGENPlugin_SimpleHypothesis_2D.hxx - NETGENPlugin_SimpleHypothesis_3D.hxx - NETGENPlugin_SimpleHypothesis_2D_i.hxx - NETGENPlugin_SimpleHypothesis_3D_i.hxx - NETGENPlugin_Mesher.hxx + NETGENPlugin_NETGEN_3D.hxx + NETGENPlugin_NETGEN_3D_i.hxx + NETGENPlugin_NETGEN_2D.hxx + NETGENPlugin_NETGEN_2D_i.hxx + NETGENPlugin_NETGEN_2D3D.hxx + NETGENPlugin_NETGEN_2D3D_i.hxx + NETGENPlugin_NETGEN_2D_ONLY.hxx + NETGENPlugin_NETGEN_2D_ONLY_i.hxx + NETGENPlugin_Hypothesis.hxx + NETGENPlugin_Hypothesis_i.hxx + NETGENPlugin_Hypothesis_2D.hxx + NETGENPlugin_Hypothesis_2D_i.hxx + NETGENPlugin_Hypothesis_3D_i.hxx + NETGENPlugin_Hypothesis_2D_ONLY_i.hxx + NETGENPlugin_SimpleHypothesis_2D.hxx + NETGENPlugin_SimpleHypothesis_3D.hxx + NETGENPlugin_SimpleHypothesis_2D_i.hxx + NETGENPlugin_SimpleHypothesis_3D_i.hxx + NETGENPlugin_Mesher.hxx NETGENPlugin_Remesher_2D.hxx NETGENPlugin_Defs.hxx + NETGENPlugin_Provider.hxx ) # --- sources --- diff --git a/src/NETGENPlugin/NETGENPluginBuilder.py b/src/NETGENPlugin/NETGENPluginBuilder.py index 0f156d3..30adb63 100644 --- a/src/NETGENPlugin/NETGENPluginBuilder.py +++ b/src/NETGENPlugin/NETGENPluginBuilder.py @@ -40,19 +40,19 @@ NETGEN_VERSION_MAJOR = NETGENPlugin.NETGEN_VERSION_MAJOR # Mesh algo type identifiers #---------------------------- -## Algorithm type: Netgen tetrahedron 3D algorithm, see NETGEN_3D_Algorithm +## Algorithm type: Netgen tetrahedron 3D algorithm, see NETGEN_3D_Algorithm NETGEN_3D = "NETGEN_3D" -## Algorithm type: Netgen tetrahedron 1D-2D-3D algorithm, see NETGEN_1D2D3D_Algorithm +## Algorithm type: Netgen tetrahedron 1D-2D-3D algorithm, see NETGEN_1D2D3D_Algorithm NETGEN_1D2D3D = "NETGEN_2D3D" -## Algorithm type: Netgen triangle 1D-2D algorithm, see NETGEN_1D2D_Algorithm +## Algorithm type: Netgen triangle 1D-2D algorithm, see NETGEN_1D2D_Algorithm NETGEN_1D2D = "NETGEN_2D" ## Algorithm type: Netgen triangle 2D algorithm, see NETGEN_2D_Only_Algorithm NETGEN_2D = "NETGEN_2D_ONLY" -## Algorithm type: Synonim of NETGEN_1D2D3D, see NETGEN_1D2D3D_Algorithm +## Algorithm type: Synonim of NETGEN_1D2D3D, see NETGEN_1D2D3D_Algorithm NETGEN_FULL = NETGEN_1D2D3D -## Algorithm type: Synonim of NETGEN_3D, see NETGEN_3D_Algorithm +## Algorithm type: Synonim of NETGEN_3D, see NETGEN_3D_Algorithm NETGEN = NETGEN_3D -## Algorithm type: Synonim of NETGEN_1D2D3D, see NETGEN_1D2D3D_Algorithm +## Algorithm type: Synonim of NETGEN_1D2D3D, see NETGEN_1D2D3D_Algorithm FULL_NETGEN = NETGEN_FULL #---------------------------- @@ -190,7 +190,7 @@ class NETGEN_Algorithm(Mesh_Algorithm): def SetLocalSizeOnShape(self, shape, size ): self.Parameters().SetLocalSizeOnShape(shape, size) pass - + pass # end of NETGEN_Algorithm class @@ -310,7 +310,7 @@ class NETGEN_1D2D3D_Algorithm(NETGEN_Algorithm): pass # end of NETGEN_1D2D3D_Algorithm class -## Triangle NETGEN 1D-2D algorithm. +## Triangle NETGEN 1D-2D algorithm. # # It can be created by calling smeshBuilder.Mesh.Triangle( smeshBuilder.NETGEN_1D2D, geom=0 ) # @@ -328,6 +328,7 @@ class NETGEN_1D2D_Algorithm(NETGEN_1D2D3D_Algorithm): # @internal docHelper = "Creates triangle 2D algorithm for faces" + ## Private constructor. # @param mesh parent mesh object algorithm is assigned to # @param geom geometry (shape/sub-shape) algorithm is assigned to; @@ -360,7 +361,9 @@ class NETGEN_2D_Only_Algorithm(NETGEN_Algorithm): ## doc string of the method # @internal docHelper = "Creates triangle 2D algorithm for faces" - + + isDefault = True + ## Private constructor. # @param mesh parent mesh object algorithm is assigned to # @param geom geometry (shape/sub-shape) algorithm is assigned to; @@ -388,7 +391,7 @@ class NETGEN_2D_Only_Algorithm(NETGEN_Algorithm): def LengthFromEdges(self): hyp = self.Hypothesis("LengthFromEdges", UseExisting=1, CompareMethod=self.CompareEqualHyp) return hyp - + ## Sets @c UseSurfaceCurvature flag # @param toUse new value of the @c UseSurfaceCurvature parameter (@c True by default) def SetUseSurfaceCurvature(self, toUse=True): diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx index cd27c78..a735a1f 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx @@ -25,6 +25,7 @@ #include "NETGENPlugin_Mesher.hxx" #include "NETGENPlugin_Hypothesis_2D.hxx" +#include "NETGENPlugin_Provider.hxx" #include #include @@ -76,7 +77,7 @@ using namespace nglib; //============================================================================= /*! - * + * */ //============================================================================= @@ -85,7 +86,7 @@ NETGENPlugin_NETGEN_2D_ONLY::NETGENPlugin_NETGEN_2D_ONLY(int hypId, : SMESH_2D_Algo(hypId, gen) { _name = "NETGEN_2D_ONLY"; - + _shapeType = (1 << TopAbs_FACE);// 1 bit /shape type _onlyUnaryInput = false; // treat all FACEs at once @@ -103,7 +104,7 @@ NETGENPlugin_NETGEN_2D_ONLY::NETGENPlugin_NETGEN_2D_ONLY(int hypId, //============================================================================= /*! - * + * */ //============================================================================= @@ -114,7 +115,7 @@ NETGENPlugin_NETGEN_2D_ONLY::~NETGENPlugin_NETGEN_2D_ONLY() //============================================================================= /*! - * + * */ //============================================================================= @@ -128,6 +129,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh& aMesh, _hypParameters = 0; _progressByTic = -1; + const list& hyps = GetUsedHypothesis(aMesh, aShape, false); if (hyps.empty()) @@ -226,6 +228,11 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh& aMesh, bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { + aMesh.Lock(); + SMESH_Hypothesis::Hypothesis_Status hypStatus; + this->CheckHypothesis(aMesh, aShape, hypStatus); + aMesh.Unlock(); + netgen::multithread.terminate = 0; //netgen::multithread.task = "Surface meshing"; @@ -233,12 +240,14 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, SMESH_MesherHelper helper(aMesh); helper.SetElementsOnShape( true ); - NETGENPlugin_NetgenLibWrapper ngLib; - ngLib._isComputeOk = false; + NETGENPlugin_NetgenLibWrapper *ngLib; + int id_ngLib = nglib_provider.take(&ngLib); + ngLib->_isComputeOk = false; netgen::Mesh ngMeshNoLocSize; - netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh, & ngMeshNoLocSize }; - netgen::OCCGeometry occgeoComm; + netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib->_ngMesh, & ngMeshNoLocSize }; + netgen::OCCGeometry *occgeoComm; + int id_occgeoComm = occgeom_provider.take(&occgeoComm); // min / max sizes are set as follows: // if ( _hypParameters ) @@ -252,7 +261,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, // else // min = aMesher.GetDefaultMinSize() // max = max segment len of a FACE - NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false); aMesher.SetParameters( _hypParameters ); // _hypParameters -> netgen::mparam const bool toOptimize = _hypParameters ? _hypParameters->GetOptimize() : true; @@ -270,14 +278,14 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, if ( isCommonLocalSize ) // compute common local size in ngMeshes[0] { //list< SMESH_subMesh* > meshedSM[4]; --> all sub-shapes are added to occgeoComm - aMesher.PrepareOCCgeometry( occgeoComm, aShape, aMesh );//, meshedSM ); + aMesher.PrepareOCCgeometry( *occgeoComm, aShape, aMesh );//, meshedSM ); // local size set at MESHCONST_ANALYSE step depends on // minh, face_maxh, grading and curvaturesafety; find minh if not set by the user if ( !_hypParameters || netgen::mparam.minh < DBL_MIN ) { if ( !_hypParameters ) - netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam() / 3.; + netgen::mparam.maxh = occgeoComm->GetBoundingBox().Diam() / 3.; netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh ); } // set local size depending on curvature and NOT closeness of EDGEs @@ -288,15 +296,15 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, netgen::occparam.resthcloseedgeenable = false; netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading; #endif - occgeoComm.face_maxh = netgen::mparam.maxh; + occgeoComm->face_maxh = netgen::mparam.maxh; #ifdef NETGEN_V6 netgen::OCCParameters occparam; - netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0], netgen::mparam, occparam ); + netgen::OCCSetLocalMeshSize( *occgeoComm, *ngMeshes[0], netgen::mparam, occparam ); #else - netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] ); + netgen::OCCSetLocalMeshSize( *occgeoComm, *ngMeshes[0] ); #endif - occgeoComm.emap.Clear(); - occgeoComm.vmap.Clear(); + occgeoComm->emap.Clear(); + occgeoComm->vmap.Clear(); // set local size according to size of existing segments TopTools_IndexedMapOfShape edgeMap; @@ -321,8 +329,8 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } // set local size defined on shapes - aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] ); - aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMeshes[0] ); + aMesher.SetLocalSize( *occgeoComm, *ngMeshes[0] ); + aMesher.SetLocalSizeForChordalError( *occgeoComm, *ngMeshes[0] ); try { ngMeshes[0]->LoadLocalMeshSize( mparam.meshsizefilename ); } catch (NgException & ex) { @@ -330,7 +338,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } } netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization - // ================== // Loop on all FACEs // ================== @@ -419,7 +426,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, netgen::mparam.maxh = edgeLength; } if ( netgen::mparam.maxh < DBL_MIN ) - netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam(); + netgen::mparam.maxh = occgeoComm->GetBoundingBox().Diam(); if ( !isCommonLocalSize ) { @@ -428,16 +435,17 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } // prepare occgeom - netgen::OCCGeometry occgeom; - occgeom.shape = F; - occgeom.fmap.Add( F ); - occgeom.CalcBoundingBox(); - occgeom.facemeshstatus.SetSize(1); - occgeom.facemeshstatus = 0; - occgeom.face_maxh_modified.SetSize(1); - occgeom.face_maxh_modified = 0; - occgeom.face_maxh.SetSize(1); - occgeom.face_maxh = netgen::mparam.maxh; + netgen::OCCGeometry *occgeom; + int id_occgeom = occgeom_provider.take(&occgeom); + occgeom->shape = F; + occgeom->fmap.Add( F ); + occgeom->CalcBoundingBox(); + occgeom->facemeshstatus.SetSize(1); + occgeom->facemeshstatus = 0; + occgeom->face_maxh_modified.SetSize(1); + occgeom->face_maxh_modified = 0; + occgeom->face_maxh.SetSize(1); + occgeom->face_maxh = netgen::mparam.maxh; // ------------------------- // Fill netgen mesh @@ -460,11 +468,11 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, { ngMesh->SetGlobalH ( mparam.maxh ); ngMesh->SetMinimalH( mparam.minh ); - Box<3> bb = occgeom.GetBoundingBox(); + Box<3> bb = occgeom->GetBoundingBox(); bb.Increase (bb.Diam()/10); ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading); - aMesher.SetLocalSize( occgeom, *ngMesh ); - aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMesh ); + aMesher.SetLocalSize( *occgeom, *ngMesh ); + aMesher.SetLocalSizeForChordalError( *occgeoComm, *ngMesh ); try { ngMesh->LoadLocalMeshSize( mparam.meshsizefilename ); } catch (NgException & ex) { @@ -473,7 +481,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } nodeVec.clear(); - faceErr = aMesher.AddSegmentsToMesh( *ngMesh, occgeom, wires, helper, nodeVec, + faceErr = aMesher.AddSegmentsToMesh( *ngMesh, *occgeom, wires, helper, nodeVec, /*overrideMinH=*/!_hypParameters); if ( faceErr && !faceErr->IsOK() ) break; @@ -491,9 +499,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, SMESH_Comment str; try { OCC_CATCH_SIGNALS; - - err = ngLib.GenerateMesh(occgeom, startWith, endWith, ngMesh); - + err = ngLib->GenerateMesh(*occgeom, startWith, endWith, ngMesh); if ( netgen::multithread.terminate ) return false; if ( err ) @@ -515,7 +521,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } if ( err ) { - if ( aMesher.FixFaceMesh( occgeom, *ngMesh, 1 )) + if ( aMesher.FixFaceMesh( *occgeom, *ngMesh, 1 )) break; if ( iLoop == LOC_SIZE ) { @@ -546,7 +552,9 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } } - + occgeom_provider.release(id_occgeoComm, true); + occgeom_provider.release(id_occgeom, true); + aMesh.Lock(); // ---------------------------------------------------- // Fill the SMESHDS with the generated nodes and faces // ---------------------------------------------------- @@ -596,6 +604,9 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, break; } // two attempts } // loop on FACEs + aMesh.Unlock(); + nglib_provider.release(id_ngLib, true); + return true; } diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index 11f0adf..c04985d 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -95,7 +95,7 @@ using namespace std; //============================================================================= /*! - * + * */ //============================================================================= @@ -119,7 +119,7 @@ NETGENPlugin_NETGEN_3D::NETGENPlugin_NETGEN_3D(int hypId, SMESH_Gen* gen) //============================================================================= /*! - * + * */ //============================================================================= @@ -129,7 +129,7 @@ NETGENPlugin_NETGEN_3D::~NETGENPlugin_NETGEN_3D() //============================================================================= /*! - * + * */ //============================================================================= @@ -544,7 +544,7 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, if ( ce && ce->HasBadElems() ) error( ce ); } - + aMesh.Lock(); bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built if ( isOK ) { @@ -576,6 +576,8 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, } } } + aMesh.Unlock(); + return !err; } @@ -641,7 +643,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); if ( elem->NbCornerNodes() != 3 ) return error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); - + // add three nodes of triangle for ( int iN = 0; iN < 3; ++iN ) { @@ -797,7 +799,7 @@ bool NETGENPlugin_NETGEN_3D::Evaluate(SMESH_Mesh& aMesh, } SMESH_subMesh *sm = aMesh.GetSubMesh(aShape); aResMap.insert(std::make_pair(sm,aVec)); - + return true; } diff --git a/src/NETGENPlugin/NETGENPlugin_Provider.hxx b/src/NETGENPlugin/NETGENPlugin_Provider.hxx new file mode 100644 index 0000000..0d2b2ae --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_Provider.hxx @@ -0,0 +1,112 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : NETGENPlugin_Provider.hxx +// Author : Yoann AUDOUIN (EDF) +// Project : SALOME +// +#include +#include +#include +#include +#include +#include + +namespace nglib { +#include +} +#ifndef OCCGEOMETRY +#define OCCGEOMETRY +#endif +#include +#include + +template +class ProviderPtr{ + public: + + ProviderPtr(){ + for(int i=0;i_mydata[i] = nullptr; + this->_useddata[i] = false; + } + } + + ProviderPtr(std::array is, std::array ds){ + for(int i=0;i_mydata[i] = new T(is[i], ds[i]); + this->_useddata[i] = false; + } + } + + int take(T** data){ + + this->_mymutex.lock(); + *data = nullptr; + for(int i=0;i_useddata[i]){ + if (this->_mydata[i] == nullptr) + this->_mydata[i] = new T(); + this->_useddata[i] = true; + *data = this->_mydata[i]; + this->_mymutex.unlock(); + return i; + } + } + this->_mymutex.unlock(); + return -1; + }; + + + bool release(int i, bool clean){ + + this->_mymutex.lock(); + + if(clean){ + delete this->_mydata[i]; + this->_mydata[i] = nullptr; + } + + this->_useddata[i] = false; + + this->_mymutex.unlock(); + + return true; + }; + + void dump(){ + std::cout << "Dumping provider:" << std::endl; + for(int i=0;i_useddata[i] << std::endl; + std::cout << " - adress: " << this->_mydata[i] << std::endl; + if (this->_mydata[i] != nullptr) + std::cout << " - i: " << this->_mydata[i]->i << " d: " << this->_mydata[i]->d << std::endl; + } + }; + + private: + std::array _mydata; + std::array _useddata; + std::mutex _mymutex; + +}; + +ProviderPtr occgeom_provider; +ProviderPtr nglib_provider; + From e0e2b32c557f598632abab301ff3b38817588b67 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Fri, 26 Aug 2022 11:36:21 +0200 Subject: [PATCH 02/29] Working version for run_mesher for netgen 3d --- src/NETGENPlugin/CMakeLists.txt | 19 +- src/NETGENPlugin/NETGENPlugin_Mesher.cxx | 179 +++++---- src/NETGENPlugin/NETGENPlugin_Mesher.hxx | 19 +- .../NETGENPlugin_NETGEN_2D_ONLY.cxx | 64 +-- .../NETGENPlugin_NETGEN_2D_ONLY.hxx | 7 + src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 380 ++++++++++++++++-- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx | 18 + src/NETGENPlugin/NETGENPlugin_Provider.hxx | 58 ++- 8 files changed, 594 insertions(+), 150 deletions(-) diff --git a/src/NETGENPlugin/CMakeLists.txt b/src/NETGENPlugin/CMakeLists.txt index 0177a58..aa6dcb8 100644 --- a/src/NETGENPlugin/CMakeLists.txt +++ b/src/NETGENPlugin/CMakeLists.txt @@ -94,6 +94,12 @@ SET(NETGENEngine_HEADERS NETGENPlugin_Provider.hxx ) +SET(Run_Mesher_HEADERS + DriverStep.hxx + netgen_param.hxx + netgen_mesher.hxx +) + # --- sources --- # sources / static @@ -121,6 +127,12 @@ SET(NETGENEngine_SOURCES NETGENPlugin_i.cxx ) +SET(Run_Mesher_SOURCES + DriverStep.cxx + netgen_mesher.cxx + netgen_param.cxx +) + # --- scripts --- # scripts / static @@ -131,10 +143,13 @@ SET(_bin_SCRIPTS # --- rules --- -ADD_LIBRARY(NETGENEngine ${NETGENEngine_SOURCES}) +ADD_LIBRARY(NETGENEngine ${NETGENEngine_SOURCES} ${Run_Mesher_SOURCES}) TARGET_LINK_LIBRARIES(NETGENEngine ${_link_LIBRARIES} ) INSTALL(TARGETS NETGENEngine EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) -INSTALL(FILES ${NETGENEngine_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) +#ADD_EXECUTABLE(run_mesher ${Run_Mesher_SOURCES}) +#INSTALL(TARGETS NETGENEngine EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) + +INSTALL(FILES ${Run_Mesher_HEADERS} ${NETGENEngine_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) SALOME_INSTALL_SCRIPTS("${_bin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/NETGENPlugin) diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx index 732a244..d1c6ccc 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx @@ -380,7 +380,7 @@ namespace //================================================================================ /*! - * \brief Restrict size of elements on the given edge + * \brief Restrict size of elements on the given edge */ //================================================================================ @@ -572,13 +572,12 @@ void NETGENPlugin_Mesher::SetSelfPointer( NETGENPlugin_Mesher ** ptr ) //================================================================================ /*! - * \brief Initialize global NETGEN parameters with default values + * \brief Initialize given NETGEN parameters with default values */ //================================================================================ -void NETGENPlugin_Mesher::SetDefaultParameters() +void NETGENPlugin_Mesher::SetDefaultParameters(netgen::MeshingParameters &mparams) { - netgen::MeshingParameters& mparams = netgen::mparam; mparams = netgen::MeshingParameters(); // maximal mesh edge size mparams.maxh = 0;//NETGENPlugin_Hypothesis::GetDefaultMaxSize(); @@ -613,6 +612,85 @@ void NETGENPlugin_Mesher::SetDefaultParameters() #endif } +//================================================================================ +/*! + * \brief Initialize global NETGEN parameters with default values + */ +//================================================================================ + +void NETGENPlugin_Mesher::SetDefaultParameters() +{ + netgen::MeshingParameters& mparams = netgen::mparam; + SetDefaultParameters(mparams); + +} + +void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp, netgen::MeshingParameters &mparams) +{ + // Initialize global NETGEN parameters: + // maximal mesh segment size + mparams.maxh = hyp->GetMaxSize(); + // maximal mesh element linear size + mparams.minh = hyp->GetMinSize(); + // minimal number of segments per edge + mparams.segmentsperedge = hyp->GetNbSegPerEdge(); + // rate of growth of size between elements + mparams.grading = hyp->GetGrowthRate(); + // safety factor for curvatures (elements per radius) + mparams.curvaturesafety = hyp->GetNbSegPerRadius(); + // create elements of second order + mparams.secondorder = hyp->GetSecondOrder() ? 1 : 0; + // quad-dominated surface meshing + mparams.quad = hyp->GetQuadAllowed() ? 1 : 0; + _optimize = hyp->GetOptimize(); + _fineness = hyp->GetFineness(); + mparams.uselocalh = hyp->GetSurfaceCurvature(); + netgen::merge_solids = hyp->GetFuseEdges(); + _chordalError = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.; + mparams.optsteps2d = _optimize ? hyp->GetNbSurfOptSteps() : 0; + mparams.optsteps3d = _optimize ? hyp->GetNbVolOptSteps() : 0; + mparams.elsizeweight = hyp->GetElemSizeWeight(); + mparams.opterrpow = hyp->GetWorstElemMeasure(); + mparams.delaunay = hyp->GetUseDelauney(); + mparams.checkoverlap = hyp->GetCheckOverlapping(); + mparams.checkchartboundary = hyp->GetCheckChartBoundary(); + _simpleHyp = NULL; + // mesh size file +#ifdef NETGEN_V6 + // std::string + mparams.meshsizefilename = hyp->GetMeshSizeFile(); +#else + // const char* + mparams.meshsizefilename= hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str(); +#endif + const NETGENPlugin_Hypothesis::TLocalSize& localSizes = hyp->GetLocalSizesAndEntries(); + if ( !localSizes.empty() ) + { + SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen(); + NETGENPlugin_Hypothesis::TLocalSize::const_iterator it = localSizes.begin(); + for ( ; it != localSizes.end() ; it++) + { + std::string entry = (*it).first; + double val = (*it).second; + // -- + GEOM::GEOM_Object_var aGeomObj; + SALOMEDS::SObject_var aSObj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( entry.c_str() ); + if ( !aSObj->_is_nil() ) { + CORBA::Object_var obj = aSObj->GetObject(); + aGeomObj = GEOM::GEOM_Object::_narrow(obj); + aSObj->UnRegister(); + } + TopoDS_Shape S = smeshGen_i->GeomObjectToShape( aGeomObj.in() ); + setLocalSize(S, val); + } + } +#ifdef NETGEN_V6 + + netgen::mparam.closeedgefac = 2; + +#endif +} + //============================================================================= /*! * Pass parameters to NETGEN @@ -623,70 +701,10 @@ void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp) if (hyp) { netgen::MeshingParameters& mparams = netgen::mparam; - // Initialize global NETGEN parameters: - // maximal mesh segment size - mparams.maxh = hyp->GetMaxSize(); - // maximal mesh element linear size - mparams.minh = hyp->GetMinSize(); - // minimal number of segments per edge - mparams.segmentsperedge = hyp->GetNbSegPerEdge(); - // rate of growth of size between elements - mparams.grading = hyp->GetGrowthRate(); - // safety factor for curvatures (elements per radius) - mparams.curvaturesafety = hyp->GetNbSegPerRadius(); - // create elements of second order - mparams.secondorder = hyp->GetSecondOrder() ? 1 : 0; - // quad-dominated surface meshing - mparams.quad = hyp->GetQuadAllowed() ? 1 : 0; - _optimize = hyp->GetOptimize(); - _fineness = hyp->GetFineness(); - mparams.uselocalh = hyp->GetSurfaceCurvature(); - netgen::merge_solids = hyp->GetFuseEdges(); - _chordalError = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.; - mparams.optsteps2d = _optimize ? hyp->GetNbSurfOptSteps() : 0; - mparams.optsteps3d = _optimize ? hyp->GetNbVolOptSteps() : 0; - mparams.elsizeweight = hyp->GetElemSizeWeight(); - mparams.opterrpow = hyp->GetWorstElemMeasure(); - mparams.delaunay = hyp->GetUseDelauney(); - mparams.checkoverlap = hyp->GetCheckOverlapping(); - mparams.checkchartboundary = hyp->GetCheckChartBoundary(); - _simpleHyp = NULL; - // mesh size file -#ifdef NETGEN_V6 - // std::string - mparams.meshsizefilename = hyp->GetMeshSizeFile(); -#else - // const char* - mparams.meshsizefilename= hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str(); -#endif - const NETGENPlugin_Hypothesis::TLocalSize& localSizes = hyp->GetLocalSizesAndEntries(); - if ( !localSizes.empty() ) - { - SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen(); - NETGENPlugin_Hypothesis::TLocalSize::const_iterator it = localSizes.begin(); - for ( ; it != localSizes.end() ; it++) - { - std::string entry = (*it).first; - double val = (*it).second; - // -- - GEOM::GEOM_Object_var aGeomObj; - SALOMEDS::SObject_var aSObj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( entry.c_str() ); - if ( !aSObj->_is_nil() ) { - CORBA::Object_var obj = aSObj->GetObject(); - aGeomObj = GEOM::GEOM_Object::_narrow(obj); - aSObj->UnRegister(); - } - TopoDS_Shape S = smeshGen_i->GeomObjectToShape( aGeomObj.in() ); - setLocalSize(S, val); - } - } + SetParameters(hyp, mparams); } -#ifdef NETGEN_V6 - netgen::mparam.closeedgefac = 2; - -#endif } //============================================================================= @@ -1575,7 +1593,7 @@ void NETGENPlugin_Mesher::FixIntFaces(const netgen::OCCGeometry& occgeom, NETGENPlugin_Internals& internalShapes) { SMESHDS_Mesh* meshDS = internalShapes.getMesh().GetMeshDS(); - + // find ng indices of internal faces set ngFaceIds; for ( int ngFaceID = 1; ngFaceID <= occgeom.fmap.Extent(); ++ngFaceID ) @@ -1735,7 +1753,7 @@ namespace double dist3D = surf->Value( uv1.X(), uv1.Y() ).Distance( surf->Value( uv2.X(), uv2.Y() )); if ( stopHandler == 0 ) // stop recursion return dist3D; - + // start recursion if necessary double dist2D = SMESH_MesherHelper::ApplyIn2D(surf, uv1, uv2, gp_XY_Subtracted, 0).Modulus(); if ( fabs( dist3D - dist2D ) < dist2D * 1e-10 ) @@ -2205,7 +2223,7 @@ void NETGENPlugin_Mesher::AddIntVerticesInSolids(const netgen::OCCGeometry& * \param wires - data of nodes on FACE boundary * \param helper - mesher helper holding the FACE * \param nodeVec - vector of nodes in which node index == netgen ID - * \retval SMESH_ComputeErrorPtr - error description + * \retval SMESH_ComputeErrorPtr - error description */ //================================================================================ @@ -2712,7 +2730,7 @@ int NETGENPlugin_Mesher::FillSMesh(const netgen::OCCGeometry& occgeo, for ( int i = 1; i <= nbVol; ++i ) { - const netgen::Element& elem = ngMesh.VolumeElement(i); + const netgen::Element& elem = ngMesh.VolumeElement(i); int aSolidInd = elem.GetIndex(); TopoDS_Solid aSolid; if ( aSolidInd > 0 && aSolidInd <= occgeo.somap.Extent() ) @@ -2905,7 +2923,7 @@ bool NETGENPlugin_Mesher::Compute() // vector of nodes in which node index == netgen ID vector< const SMDS_MeshNode* > nodeVec; - + { // ---------------- // compute 1D mesh @@ -3511,7 +3529,7 @@ bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap) const int hugeNb = std::numeric_limits::max() / 100; // ---------------- - // evaluate 1D + // evaluate 1D // ---------------- // pass 1D simple parameters to NETGEN if ( _simpleHyp ) @@ -3618,7 +3636,7 @@ bool NETGENPlugin_Mesher::Evaluate(MapShapeNbElems& aResMap) return false; // ---------------- - // evaluate 2D + // evaluate 2D // ---------------- if ( _simpleHyp ) { if ( double area = _simpleHyp->GetMaxElementArea() ) { @@ -3820,9 +3838,9 @@ NETGENPlugin_Mesher::ReadErrors(const vector& nodeVec) } else if ( strncmp( file, "Intersecting: ", 14 ) == 0 ) { -// Intersecting: +// Intersecting: // openelement 18 with open element 126 -// 41 36 38 +// 41 36 38 // 69 70 72 file.getLine(); const char* pos = file; @@ -3939,7 +3957,7 @@ void NETGENPlugin_Mesher::toPython( const netgen::Mesh* ngMesh ) #else //////// V 5 PointIndex pi; - for (pi = PointIndex::BASE; + for (pi = PointIndex::BASE; pi < ngMesh->GetNP()+PointIndex::BASE; pi++) { outfile << "mesh.AddNode( "; @@ -4501,7 +4519,8 @@ void NETGENPlugin_NetgenLibWrapper::setMesh( Ng_Mesh* mesh ) int NETGENPlugin_NetgenLibWrapper::GenerateMesh( netgen::OCCGeometry& occgeo, int startWith, int endWith, - netgen::Mesh* & ngMesh ) + netgen::Mesh* & ngMesh , + netgen::MeshingParameters& mparam) { int err = 0; if ( !ngMesh ) @@ -4511,15 +4530,15 @@ int NETGENPlugin_NetgenLibWrapper::GenerateMesh( netgen::OCCGeometry& occgeo, ngMesh->SetGeometry( shared_ptr( &occgeo, &NOOP_Deleter )); - netgen::mparam.perfstepsstart = startWith; - netgen::mparam.perfstepsend = endWith; + mparam.perfstepsstart = startWith; + mparam.perfstepsend = endWith; std::shared_ptr meshPtr( ngMesh, &NOOP_Deleter ); - err = occgeo.GenerateMesh( meshPtr, netgen::mparam ); + err = occgeo.GenerateMesh( meshPtr, mparam ); #else #ifdef NETGEN_V5 - err = netgen::OCCGenerateMesh(occgeo, ngMesh, netgen::mparam, startWith, endWith); + err = netgen::OCCGenerateMesh(occgeo, ngMesh, mparam, startWith, endWith); #else diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.hxx b/src/NETGENPlugin/NETGENPlugin_Mesher.hxx index 48ea1ec..af7d971 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.hxx @@ -58,6 +58,8 @@ class TopoDS_Shape; namespace netgen { class OCCGeometry; class Mesh; + class MeshingParameters; + extern MeshingParameters mparam; } //============================================================================= /*! @@ -92,12 +94,19 @@ struct NETGENPLUGIN_EXPORT NETGENPlugin_NetgenLibWrapper void setMesh( nglib::Ng_Mesh* mesh ); nglib::Ng_Mesh* ngMesh() { return (nglib::Ng_Mesh*)(void*)_ngMesh; } + + static int GenerateMesh(netgen::OCCGeometry& occgeo, int startWith, int endWith, - netgen::Mesh* & ngMesh); + netgen::Mesh* & ngMesh, netgen::MeshingParameters & mparam); int GenerateMesh(netgen::OCCGeometry& occgeo, int startWith, int endWith ) { - return GenerateMesh( occgeo, startWith, endWith, _ngMesh ); + + return GenerateMesh( occgeo, startWith, endWith, _ngMesh, netgen::mparam ); } + static int GenerateMesh(netgen::OCCGeometry& occgeo, int startWith, int endWith, + netgen::Mesh* & ngMesh){ + return GenerateMesh(occgeo, startWith, endWith, ngMesh, netgen::mparam); + }; static void CalcLocalH( netgen::Mesh * ngMesh ); static void RemoveTmpFiles(); @@ -119,7 +128,7 @@ struct NETGENPLUGIN_EXPORT NETGENPlugin_NetgenLibWrapper */ //============================================================================= -class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher +class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher { public: // ---------- PUBLIC METHODS ---------- @@ -130,6 +139,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher void SetSelfPointer( NETGENPlugin_Mesher ** ptr ); void SetParameters(const NETGENPlugin_Hypothesis* hyp); + void SetParameters(const NETGENPlugin_Hypothesis* hyp, netgen::MeshingParameters &mparams); void SetParameters(const NETGENPlugin_SimpleHypothesis_2D* hyp); void SetParameters(const StdMeshers_ViscousLayers* hyp ); void SetViscousLayers2DAssigned(bool isAssigned) { _isViscousLayers2D = isAssigned; } @@ -201,6 +211,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher const bool overrideMinH=true); void SetDefaultParameters(); + void SetDefaultParameters(netgen::MeshingParameters &mparams); static SMESH_ComputeErrorPtr ReadErrors(const std::vector< const SMDS_MeshNode* >& nodeVec); @@ -272,7 +283,7 @@ public: bool isShapeToPrecompute(const TopoDS_Shape& s); // 2D meshing - // edges + // edges bool hasInternalEdges() const { return !_e2face.empty(); } bool isInternalEdge( int id ) const { return _e2face.count( id ); } const std::map& getEdgesAndVerticesWithFaces() const { return _e2face; } diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx index a735a1f..7b08a3d 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx @@ -65,7 +65,7 @@ namespace nglib { //#include namespace netgen { NETGENPLUGIN_DLL_HEADER - extern MeshingParameters mparam; + // extern MeshingParameters mparam; #ifdef NETGEN_V5 extern void OCCSetLocalMeshSize(OCCGeometry & geom, Mesh & mesh); #endif @@ -75,6 +75,7 @@ using namespace std; using namespace netgen; using namespace nglib; + //============================================================================= /*! * @@ -233,6 +234,9 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, this->CheckHypothesis(aMesh, aShape, hypStatus); aMesh.Unlock(); + netgen::MeshingParameters mparam; + int id_mparam = mparam_provider.take(mparam); + netgen::multithread.terminate = 0; //netgen::multithread.task = "Surface meshing"; @@ -261,19 +265,24 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, // else // min = aMesher.GetDefaultMinSize() // max = max segment len of a FACE + aMesh.Lock(); NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false); - aMesher.SetParameters( _hypParameters ); // _hypParameters -> netgen::mparam + // TODO: Only valid for NETGEN2D_Only + aMesher.SetDefaultParameters(mparam); + aMesher.SetParameters( _hypParameters, mparam ); // _hypParameters -> mparam const bool toOptimize = _hypParameters ? _hypParameters->GetOptimize() : true; if ( _hypMaxElementArea ) { - netgen::mparam.maxh = sqrt( 2. * _hypMaxElementArea->GetMaxArea() / sqrt(3.0) ); + mparam.maxh = sqrt( 2. * _hypMaxElementArea->GetMaxArea() / sqrt(3.0) ); } if ( _hypQuadranglePreference ) - netgen::mparam.quad = true; + mparam.quad = true; // local size is common for all FACEs in aShape? - const bool isCommonLocalSize = ( !_hypLengthFromEdges && !_hypMaxElementArea && netgen::mparam.uselocalh ); + const bool isCommonLocalSize = ( !_hypLengthFromEdges && !_hypMaxElementArea && mparam.uselocalh ); const bool isDefaultHyp = ( !_hypLengthFromEdges && !_hypMaxElementArea && !_hypParameters ); + aMesh.Unlock(); + if ( isCommonLocalSize ) // compute common local size in ngMeshes[0] { @@ -282,11 +291,11 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, // local size set at MESHCONST_ANALYSE step depends on // minh, face_maxh, grading and curvaturesafety; find minh if not set by the user - if ( !_hypParameters || netgen::mparam.minh < DBL_MIN ) + if ( !_hypParameters || mparam.minh < DBL_MIN ) { if ( !_hypParameters ) - netgen::mparam.maxh = occgeoComm->GetBoundingBox().Diam() / 3.; - netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh ); + mparam.maxh = occgeoComm->GetBoundingBox().Diam() / 3.; + mparam.minh = aMesher.GetDefaultMinSize( aShape, mparam.maxh ); } // set local size depending on curvature and NOT closeness of EDGEs #ifdef NETGEN_V6 @@ -294,14 +303,16 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, #else const double factor = netgen::occparam.resthcloseedgefac; netgen::occparam.resthcloseedgeenable = false; - netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading; + netgen::occparam.resthcloseedgefac = 1.0 + mparam.grading; #endif - occgeoComm->face_maxh = netgen::mparam.maxh; + occgeoComm->face_maxh = mparam.maxh; #ifdef NETGEN_V6 netgen::OCCParameters occparam; - netgen::OCCSetLocalMeshSize( *occgeoComm, *ngMeshes[0], netgen::mparam, occparam ); + netgen::OCCSetLocalMeshSize( *occgeoComm, *ngMeshes[0], mparam, occparam ); #else + aMesh.Lock(); netgen::OCCSetLocalMeshSize( *occgeoComm, *ngMeshes[0] ); + aMesh.Unlock(); #endif occgeoComm->emap.Clear(); occgeoComm->vmap.Clear(); @@ -337,7 +348,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, return error( COMPERR_BAD_PARMETERS, ex.What() ); } } - netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization + mparam.uselocalh = toOptimize; // restore as it is used at surface optimization // ================== // Loop on all FACEs // ================== @@ -403,7 +414,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } if ( nbSegments ) edgeLength /= double( nbSegments ); - netgen::mparam.maxh = edgeLength; + mparam.maxh = edgeLength; } else if ( isDefaultHyp ) { @@ -423,14 +434,14 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } } edgeLength = sqrt( maxSeg2 ) * 1.05; - netgen::mparam.maxh = edgeLength; + mparam.maxh = edgeLength; } - if ( netgen::mparam.maxh < DBL_MIN ) - netgen::mparam.maxh = occgeoComm->GetBoundingBox().Diam(); + if ( mparam.maxh < DBL_MIN ) + mparam.maxh = occgeoComm->GetBoundingBox().Diam(); if ( !isCommonLocalSize ) { - netgen::mparam.minh = aMesher.GetDefaultMinSize( F, netgen::mparam.maxh ); + mparam.minh = aMesher.GetDefaultMinSize( F, mparam.maxh ); } } @@ -445,7 +456,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, occgeom->face_maxh_modified.SetSize(1); occgeom->face_maxh_modified = 0; occgeom->face_maxh.SetSize(1); - occgeom->face_maxh = netgen::mparam.maxh; + occgeom->face_maxh = mparam.maxh; // ------------------------- // Fill netgen mesh @@ -499,7 +510,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, SMESH_Comment str; try { OCC_CATCH_SIGNALS; - err = ngLib->GenerateMesh(*occgeom, startWith, endWith, ngMesh); + err = ngLib->GenerateMesh(*occgeom, startWith, endWith, ngMesh, mparam); if ( netgen::multithread.terminate ) return false; if ( err ) @@ -525,8 +536,8 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, break; if ( iLoop == LOC_SIZE ) { - netgen::mparam.minh = netgen::mparam.maxh; - netgen::mparam.maxh = 0; + mparam.minh = mparam.maxh; + mparam.maxh = 0; for ( size_t iW = 0; iW < wires.size(); ++iW ) { StdMeshers_FaceSidePtr wire = wires[ iW ]; @@ -537,13 +548,13 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, netgen::Point3d np( p.X(),p.Y(),p.Z()); double segLen = p.Distance( uvPtVec[ iP-1 ].node ); double size = ngMesh->GetH( np ); - netgen::mparam.minh = Min( netgen::mparam.minh, size ); - netgen::mparam.maxh = Max( netgen::mparam.maxh, segLen ); + mparam.minh = Min( mparam.minh, size ); + mparam.maxh = Max( mparam.maxh, segLen ); } } - //cerr << "min " << netgen::mparam.minh << " max " << netgen::mparam.maxh << endl; - netgen::mparam.minh *= 0.9; - netgen::mparam.maxh *= 1.1; + //cerr << "min " << mparam.minh << " max " << mparam.maxh << endl; + mparam.minh *= 0.9; + mparam.maxh *= 1.1; continue; } else @@ -554,6 +565,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, occgeom_provider.release(id_occgeoComm, true); occgeom_provider.release(id_occgeom, true); + mparam_provider.release(id_mparam); aMesh.Lock(); // ---------------------------------------------------- // Fill the SMESHDS with the generated nodes and faces diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx index b6402f9..de61a7f 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx @@ -24,12 +24,15 @@ #ifndef _NETGENPlugin_NETGEN_2D_ONLY_HXX_ #define _NETGENPlugin_NETGEN_2D_ONLY_HXX_ +#include "NETGENPlugin_Provider.hxx" + #include #include class StdMeshers_MaxElementArea; class StdMeshers_LengthFromEdges; class NETGENPlugin_Hypothesis_2D; +class NETGENPlugin_NetgenLibWrapper; /*! * \brief Mesher generating 2D elements on a geometrical face taking @@ -66,6 +69,10 @@ protected: const NETGENPlugin_Hypothesis_2D* _hypParameters; double _progressByTic; + + Provider mparam_provider; + ProviderPtr occgeom_provider; + ProviderPtr nglib_provider; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index c04985d..caa0268 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -31,6 +31,11 @@ #include "NETGENPlugin_NETGEN_3D.hxx" #include "NETGENPlugin_Hypothesis.hxx" +#include "NETGENPlugin_Provider.hxx" + +#include "DriverStep.hxx" +#include "DriverMesh.hxx" +#include "netgen_param.hxx" #include #include @@ -45,6 +50,7 @@ #include #include #include +#include #include #include @@ -63,6 +69,10 @@ #include #include +#include +#include +namespace fs = boost::filesystem; + /* Netgen include files */ @@ -85,7 +95,6 @@ namespace nglib { namespace netgen { NETGENPLUGIN_DLL_HEADER - extern MeshingParameters mparam; NETGENPLUGIN_DLL_HEADER extern volatile multithreadt multithread; @@ -143,8 +152,8 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis (SMESH_Mesh& aMesh, _maxElementVolume = DBL_MAX; // for correct work of GetProgress(): - netgen::multithread.percent = 0.; - netgen::multithread.task = "Volume meshing"; + //netgen::multithread.percent = 0.; + //netgen::multithread.task = "Volume meshing"; _progressByTic = -1.; list::const_iterator itl; @@ -186,6 +195,297 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis (SMESH_Mesh& aMesh, return aStatus == HYP_OK; } + +void NETGENPlugin_NETGEN_3D::FillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams) +{ + aParams.maxh = hyp->GetMaxSize(); + aParams.minh = hyp->GetMinSize(); + aParams.segmentsperedge = hyp->GetNbSegPerEdge(); + aParams.grading = hyp->GetGrowthRate(); + aParams.curvaturesafety = hyp->GetNbSegPerRadius(); + aParams.secondorder = hyp->GetSecondOrder() ? 1 : 0; + aParams.quad = hyp->GetQuadAllowed() ? 1 : 0; + aParams.optimize = hyp->GetOptimize(); + aParams.fineness = hyp->GetFineness(); + aParams.uselocalh = hyp->GetSurfaceCurvature(); + aParams.merge_solids = hyp->GetFuseEdges(); + aParams.chordalError = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.; + aParams.optsteps2d = aParams.optimize ? hyp->GetNbSurfOptSteps() : 0; + aParams.optsteps3d = aParams.optimize ? hyp->GetNbVolOptSteps() : 0; + aParams.elsizeweight = hyp->GetElemSizeWeight(); + aParams.opterrpow = hyp->GetWorstElemMeasure(); + aParams.delaunay = hyp->GetUseDelauney(); + aParams.checkoverlap = hyp->GetCheckOverlapping(); + aParams.checkchartboundary = hyp->GetCheckChartBoundary(); +#ifdef NETGEN_V6 + // std::string + aParams.meshsizefilename = hyp->GetMeshSizeFile(); +#else + // const char* + aParams.meshsizefilename = hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str(); +#endif +#ifdef NETGEN_V6 + aParams.closeedgefac = 2; +#else + aParams.closeedgefac = 0; +#endif +} + +void NETGENPlugin_NETGEN_3D::exportElementOrientation(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + netgen_params& aParams, + const std::string output_file) +{ + SMESH_MesherHelper helper(aMesh); + NETGENPlugin_Internals internals( aMesh, aShape, /*is3D=*/true ); + SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); + std::map elemOrientation; + + for ( TopExp_Explorer exFa( aShape, TopAbs_FACE ); exFa.More(); exFa.Next()) + { + const TopoDS_Shape& aShapeFace = exFa.Current(); + int faceID = aMesh.GetMeshDS()->ShapeToIndex( aShapeFace ); + bool isInternalFace = internals.isInternalShape( faceID ); + bool isRev = false; + if ( !isInternalFace && + helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) + // IsReversedSubMesh() can work wrong on strongly curved faces, + // so we use it as less as possible + isRev = helper.IsReversedSubMesh( TopoDS::Face( aShapeFace )); + + const SMESHDS_SubMesh * aSubMeshDSFace = proxyMesh->GetSubMesh( aShapeFace ); + if ( !aSubMeshDSFace ) continue; + + SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); + if ( aParams._quadraticMesh && + dynamic_cast< const SMESH_ProxyMesh::SubMesh*>( aSubMeshDSFace )) + { + // add medium nodes of proxy triangles to helper (#16843) + while ( iteratorElem->more() ) + helper.AddTLinks( static_cast< const SMDS_MeshFace* >( iteratorElem->next() )); + + iteratorElem = aSubMeshDSFace->GetElements(); + } + while ( iteratorElem->more() ) // loop on elements on a geom face + { + // check mesh face + const SMDS_MeshElement* elem = iteratorElem->next(); + if ( !elem ) + error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); + if ( elem->NbCornerNodes() != 3 ) + error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); + elemOrientation[elem->GetID()] = isRev; + // Add nodes of triangles and triangles them-selves to netgen mesh + + // add three nodes of triangle +/* bool hasDegen = false; + for ( int iN = 0; iN < 3; ++iN ) + { + const SMDS_MeshNode* node = elem->GetNode( iN ); + const int shapeID = node->getshapeId(); + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && + helper.IsDegenShape( shapeID )) + { + // ignore all nodes on degeneraged edge and use node on its vertex instead + TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); + node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS ); + hasDegen = true; + } + int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; + if ( ngID == invalid_ID ) + { + ngID = ++Netgen_NbOfNodes; + Netgen_point [ 0 ] = node->X(); + Netgen_point [ 1 ] = node->Y(); + Netgen_point [ 2 ] = node->Z(); + Ng_AddPoint(Netgen_mesh, Netgen_point); + } + Netgen_triangle[ isRev ? 2-iN : iN ] = ngID; + } + // add triangle + if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] || + Netgen_triangle[0] == Netgen_triangle[2] || + Netgen_triangle[2] == Netgen_triangle[1] )) + continue; + + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + + if ( isInternalFace && !proxyMesh->IsTemporary( elem )) + { + swap( Netgen_triangle[1], Netgen_triangle[2] ); + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + }*/ + } // loop on elements on a face + } // loop on faces of a SOLID or SHELL + + std::ofstream df(output_file, ios::out|ios::binary); + int size=elemOrientation.size(); + std::cout << size<< std::endl; + std::cout << "vtkIdType " << sizeof(vtkIdType) << std::endl; + + df.write((char*)&size, sizeof(int)); + for(auto const& [id, orient]:elemOrientation){ + df.write((char*)&id, sizeof(vtkIdType)); + df.write((char*)&orient, sizeof(bool)); + } + df.close(); + // for(auto const& [id, orient] : elemOrientation) + // { + // std::cout << id << " : " << orient << ", "; + // } +} + +int NETGENPlugin_NETGEN_3D::ParallelCompute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) +{ + aMesh.Lock(); + SMESH_Hypothesis::Hypothesis_Status hypStatus; + CheckHypothesis(aMesh, aShape, hypStatus); + + // Temporary folder for run + fs::path tmp_folder = aMesh.tmp_folder / fs::unique_path(fs::path("Volume-%%%%-%%%%")); + fs::create_directories(tmp_folder); + // Using MESH2D generated after all triangles where created. + fs::path mesh_file=aMesh.tmp_folder / fs::path("Mesh2D.med"); + fs::path element_orientation_file=tmp_folder / fs::path("element_orientation.dat"); + fs::path new_element_file=tmp_folder / fs::path("new_elements.dat"); + fs::path tmp_mesh_file=tmp_folder / fs::path("tmp_mesh.med"); + // TODO: Remove that file we do not use it + fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med"); + fs::path shape_file=tmp_folder / fs::path("shape.step"); + fs::path param_file=tmp_folder / fs::path("netgen3d_param.txt"); + fs::path log_file=tmp_folder / fs::path("run_mesher.log"); + //TODO: Handle variable mesh_name + std::string mesh_name = "Maillage_1"; + + //Writing Shape + export_shape(shape_file.string(), aShape); + //Writing hypo + netgen_params aParams; + FillParameters(_hypParameters, aParams); + + export_netgen_params(param_file.string(), aParams); + + // Exporting element orientation + exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); + + aMesh.Unlock(); + // Calling run_mesher + std::string cmd; + // TODO: Add run_meher to bin + std::string run_mesher_exe = "/home/B61570/work_in_progress/ssmesh/run_mesher/build/src/run_mesher"; + cmd = run_mesher_exe + + " NETGEN3D " + mesh_file.string() + " " + + shape_file.string() + " " + + param_file.string() + " " + + element_orientation_file.string() + " " + + new_element_file.string() + " " + + output_mesh_file.string() + + " >> " + log_file.string(); + + std::cout << "Running command: " << std::endl; + std::cout << cmd << std::endl; + + // Writing command in log + std::ofstream flog(log_file.string()); + flog << cmd << endl; + flog.close(); + + int ret = system(cmd.c_str()); + + // TODO: error handling + if(ret != 0){ + // Run crahed + //throw Exception("Meshing failed"); + std::cerr << "Issue with command: " << std::endl; + std::cerr << cmd << std::endl; + return false; + } + + + aMesh.Lock(); + std::ifstream df(new_element_file.string(), ios::binary); + + + int Netgen_NbOfNodes; + int Netgen_NbOfNodesNew; + int Netgen_NbOfTetra; + double Netgen_point[3]; + int Netgen_tetrahedron[4]; + int nodeID; + + SMESH_MesherHelper helper(aMesh); + // This function + int _quadraticMesh = helper.IsQuadraticSubMesh(aShape); + helper.SetElementsOnShape( true ); + + // Filling nodevec (correspondence netgen numbering mesh numbering) + // Number of nodes + df.read((char*) &Netgen_NbOfNodes, sizeof(int)); + df.read((char*) &Netgen_NbOfNodesNew, sizeof(int)); + + vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); + + for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) + { + //Id of the point + df.read((char*) &nodeID, sizeof(int)); + // std::cout << "Old Node " << nodeIndex << ": " << nodeID << std::endl; + // TODO: do stuff to fill nodeVec ?? + nodeVec.at(nodeIndex) = nullptr; + SMDS_NodeIteratorPtr iteratorNode = aMesh.GetMeshDS()->nodesIterator(); + while(iteratorNode->more()){ + const SMDS_MeshNode* node = iteratorNode->next(); + if(node->GetID() == nodeID){ + nodeVec.at(nodeIndex) = node; + break; + } + } + if(nodeVec.at(nodeIndex) == nullptr){ + std::cout << "Error could not identify id"; + return false; + } + } + + // Writing info on new points + for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) + { + // Coordinates of the point + df.read((char *) &Netgen_point, sizeof(double)*3); + // std::cout << "Node " << nodeIndex << ": "; + // for(auto coord:Netgen_point){ + // std::cout << coord << " "; + // } + // std::cout << std::endl; + nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], + Netgen_point[1], + Netgen_point[2]); + + } + + // create tetrahedrons + df.read((char*) &Netgen_NbOfTetra, sizeof(int)); + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) + { + df.read((char*) &Netgen_tetrahedron, sizeof(int)*4); + // std::cout << "Element " << elemIndex << ": "; + // for(auto elem:Netgen_tetrahedron){ + // std::cout << elem << " "; + // } + // std::cout << std::endl; + // TODO: Add tetra + helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), + nodeVec.at( Netgen_tetrahedron[1] ), + nodeVec.at( Netgen_tetrahedron[2] ), + nodeVec.at( Netgen_tetrahedron[3] )); + } + df.close(); + + aMesh.Unlock(); + + return true; +} + //============================================================================= /*! *Here we are going to use the NETGEN mesher @@ -195,25 +495,34 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis (SMESH_Mesh& aMesh, bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { - netgen::multithread.terminate = 0; - netgen::multithread.task = "Volume meshing"; + + return ParallelCompute(aMesh, aShape); + aMesh.Lock(); + SMESH_Hypothesis::Hypothesis_Status hypStatus; + CheckHypothesis(aMesh, aShape, hypStatus); + aMesh.Unlock(); + + //netgen::multithread.terminate = 0; + //netgen::multithread.task = "Volume meshing"; _progressByTic = -1.; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - SMESH_MesherHelper helper(aMesh); - _quadraticMesh = helper.IsQuadraticSubMesh(aShape); - helper.SetElementsOnShape( true ); + SMESH_MesherHelper *helper = new SMESH_MesherHelper(aMesh); + _quadraticMesh = helper->IsQuadraticSubMesh(aShape); + helper->SetElementsOnShape( true ); int Netgen_NbOfNodes = 0; double Netgen_point[3]; int Netgen_triangle[3]; - NETGENPlugin_NetgenLibWrapper ngLib; - Ng_Mesh * Netgen_mesh = (Ng_Mesh*)ngLib._ngMesh; + NETGENPlugin_NetgenLibWrapper *ngLib; + int id_nglib = nglib_provider.take(&ngLib); + Ng_Mesh * Netgen_mesh = (Ng_Mesh*)ngLib->_ngMesh; // vector of nodes in which node index == netgen ID vector< const SMDS_MeshNode* > nodeVec; + aMesh.Lock(); { const int invalid_ID = -1; @@ -238,14 +547,14 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); if ( _viscousLayersHyp ) { - netgen::multithread.percent = 3; + //netgen::multithread.percent = 3; proxyMesh = _viscousLayersHyp->Compute( aMesh, aShape ); if ( !proxyMesh ) return false; } if ( aMesh.NbQuadrangles() > 0 ) { - netgen::multithread.percent = 6; + //netgen::multithread.percent = 6; StdMeshers_QuadToTriaAdaptor* Adaptor = new StdMeshers_QuadToTriaAdaptor; Adaptor->Compute(aMesh,aShape,proxyMesh.get()); proxyMesh.reset( Adaptor ); @@ -258,10 +567,10 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, bool isInternalFace = internals.isInternalShape( faceID ); bool isRev = false; if ( checkReverse && !isInternalFace && - helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) + helper->NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) // IsReversedSubMesh() can work wrong on strongly curved faces, // so we use it as less as possible - isRev = helper.IsReversedSubMesh( TopoDS::Face( aShapeFace )); + isRev = helper->IsReversedSubMesh( TopoDS::Face( aShapeFace )); const SMESHDS_SubMesh * aSubMeshDSFace = proxyMesh->GetSubMesh( aShapeFace ); if ( !aSubMeshDSFace ) continue; @@ -272,7 +581,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, { // add medium nodes of proxy triangles to helper (#16843) while ( iteratorElem->more() ) - helper.AddTLinks( static_cast< const SMDS_MeshFace* >( iteratorElem->next() )); + helper->AddTLinks( static_cast< const SMDS_MeshFace* >( iteratorElem->next() )); iteratorElem = aSubMeshDSFace->GetElements(); } @@ -294,7 +603,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, const SMDS_MeshNode* node = elem->GetNode( iN ); const int shapeID = node->getshapeId(); if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && - helper.IsDegenShape( shapeID )) + helper->IsDegenShape( shapeID )) { // ignore all nodes on degeneraged edge and use node on its vertex instead TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); @@ -335,6 +644,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, nodeVec[ n_id->second ] = n_id->first; nodeToNetgenID.clear(); + // TODO: Handle internal vertex if ( internals.hasInternalVertexInSolid() ) { netgen::OCCGeometry occgeo; @@ -344,12 +654,16 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, internals); } } + aMesh.Unlock(); // ------------------------- // Generate the volume mesh // ------------------------- + ngLib->_isComputeOk = compute( aMesh, *helper, nodeVec, *ngLib ); + bool ret = ngLib->_isComputeOk; + nglib_provider.release(id_nglib, true); - return ( ngLib._isComputeOk = compute( aMesh, helper, nodeVec, ngLib )); + return ret; } // namespace @@ -435,7 +749,7 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, vector< const SMDS_MeshNode* >& nodeVec, NETGENPlugin_NetgenLibWrapper& ngLib) { - netgen::multithread.terminate = 0; + //netgen::multithread.terminate = 0; netgen::Mesh* ngMesh = ngLib._ngMesh; Ng_Mesh* Netgen_mesh = ngLib.ngMesh(); @@ -446,11 +760,15 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, int err = 1; NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true ); - netgen::OCCGeometry occgeo; + netgen::OCCGeometry *occgeo; + int id_occgeo = occgeom_provider.take(&occgeo); + netgen::MeshingParameters mparam; + int id_mparam = mparam_provider.take(mparam); + aMesher.SetDefaultParameters(mparam); if ( _hypParameters ) { - aMesher.SetParameters( _hypParameters ); + aMesher.SetParameters( _hypParameters, mparam ); if ( !_hypParameters->GetLocalSizesAndEntries().empty() || !_hypParameters->GetMeshSizeFile().empty() ) @@ -461,10 +779,10 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, ngMesh->GetBox( pmin, pmax, 0 ); ngMesh->SetLocalH( pmin, pmax, _hypParameters->GetGrowthRate() ); } - aMesher.SetLocalSize( occgeo, *ngMesh ); + aMesher.SetLocalSize( *occgeo, *ngMesh ); try { - ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); + ngMesh->LoadLocalMeshSize( mparam.meshsizefilename ); } catch (netgen::NgException & ex) { return error( COMPERR_BAD_PARMETERS, ex.What() ); } @@ -474,24 +792,24 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, } else if ( _hypMaxElementVolume ) { - netgen::mparam.maxh = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. ); - // limitVolumeSize( ngMesh, netgen::mparam.maxh ); // result is unpredictable + mparam.maxh = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. ); + // limitVolumeSize( ngMesh, mparam.maxh ); // result is unpredictable } else if ( aMesh.HasShapeToMesh() ) { - aMesher.PrepareOCCgeometry( occgeo, helper.GetSubShape(), aMesh ); - netgen::mparam.maxh = occgeo.GetBoundingBox().Diam()/2; + aMesher.PrepareOCCgeometry( *occgeo, helper.GetSubShape(), aMesh ); + mparam.maxh = occgeo->GetBoundingBox().Diam()/2; } else { netgen::Point3d pmin, pmax; ngMesh->GetBox (pmin, pmax); - netgen::mparam.maxh = Dist(pmin, pmax)/2; + mparam.maxh = Dist(pmin, pmax)/2; } if ( !_hypParameters && aMesh.HasShapeToMesh() ) { - netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh ); + mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), mparam.maxh ); } try @@ -499,7 +817,7 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, OCC_CATCH_SIGNALS; ngLib.CalcLocalH(ngMesh); - err = ngLib.GenerateMesh(occgeo, startWith, endWith); + err = ngLib.GenerateMesh(*occgeo, startWith, endWith, ngMesh, mparam); if(netgen::multithread.terminate) return false; @@ -544,6 +862,10 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, if ( ce && ce->HasBadElems() ) error( ce ); } + + mparam_provider.release(id_mparam); + occgeom_provider.release(id_occgeo, true); + aMesh.Lock(); bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built if ( isOK ) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx index d89f3b8..0da216f 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx @@ -31,6 +31,7 @@ #ifndef _NETGENPlugin_NETGEN_3D_HXX_ #define _NETGENPlugin_NETGEN_3D_HXX_ +#include "NETGENPlugin_Provider.hxx" #include "NETGENPlugin_Defs.hxx" #include "NETGENPlugin_Mesher.hxx" @@ -41,6 +42,7 @@ class StdMeshers_ViscousLayers; class StdMeshers_MaxElementVolume; class NETGENPlugin_Hypothesis; class NETGENPlugin_NetgenLibWrapper; +class netgen_params; class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo { @@ -68,6 +70,18 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo protected: + void exportElementOrientation(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + netgen_params& aParams, + const std::string output_file); + + void FillParameters(const NETGENPlugin_Hypothesis* hyp, + netgen_params &aParams); + + int ParallelCompute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape); + + bool compute(SMESH_Mesh& mesh, SMESH_MesherHelper& helper, std::vector< const SMDS_MeshNode* >& nodeVec, @@ -79,6 +93,10 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo const StdMeshers_MaxElementVolume* _hypMaxElementVolume; const StdMeshers_ViscousLayers* _viscousLayersHyp; double _progressByTic; + + Provider mparam_provider; + ProviderPtr occgeom_provider; + ProviderPtr nglib_provider; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_Provider.hxx b/src/NETGENPlugin/NETGENPlugin_Provider.hxx index 0d2b2ae..d262789 100644 --- a/src/NETGENPlugin/NETGENPlugin_Provider.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Provider.hxx @@ -21,6 +21,9 @@ // Author : Yoann AUDOUIN (EDF) // Project : SALOME // +#ifndef _NETGENPlugin_Provider_HXX_ +#define _NETGENPlugin_Provider_HXX_ + #include #include #include @@ -48,13 +51,6 @@ class ProviderPtr{ } } - ProviderPtr(std::array is, std::array ds){ - for(int i=0;i_mydata[i] = new T(is[i], ds[i]); - this->_useddata[i] = false; - } - } - int take(T** data){ this->_mymutex.lock(); @@ -107,6 +103,50 @@ class ProviderPtr{ }; -ProviderPtr occgeom_provider; -ProviderPtr nglib_provider; +template +class Provider{ + public: + Provider() = default; + + int take(T& data){ + + this->_mymutex.lock(); + for(int i=0;i_useddata[i]){ + this->_useddata[i] = true; + data = this->_mydata[i]; + this->_mymutex.unlock(); + return i; + } + } + this->_mymutex.unlock(); + return -1; + }; + + + bool release(int i){ + + this->_mymutex.lock(); + this->_useddata[i] = false; + this->_mymutex.unlock(); + + return true; + }; + + void dump(){ + std::cout << "Dumping provider:" << std::endl; + for(int i=0;i_useddata[i] << std::endl; + std::cout << " - i: " << this->_mydata[i].i << " d: " << this->_mydata[i].d << std::endl; + } + }; + + private: + std::array _mydata; + std::array _useddata; + std::mutex _mymutex; + +}; + +#endif \ No newline at end of file From 5fae44dd86e5c178f629cf10ae432bc88c572dc7 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 30 Aug 2022 13:23:18 +0200 Subject: [PATCH 03/29] restoring original compute + Cleanup --- .../NETGENPlugin_NETGEN_2D_ONLY.hxx | 6 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 163 +++++------------- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx | 8 +- 3 files changed, 47 insertions(+), 130 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx index de61a7f..a5d5812 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx @@ -70,9 +70,9 @@ protected: double _progressByTic; - Provider mparam_provider; - ProviderPtr occgeom_provider; - ProviderPtr nglib_provider; + Provider mparam_provider; + ProviderPtr occgeom_provider; + ProviderPtr nglib_provider; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index caa0268..c0ceac9 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -31,7 +31,6 @@ #include "NETGENPlugin_NETGEN_3D.hxx" #include "NETGENPlugin_Hypothesis.hxx" -#include "NETGENPlugin_Provider.hxx" #include "DriverStep.hxx" #include "DriverMesh.hxx" @@ -95,6 +94,7 @@ namespace nglib { namespace netgen { NETGENPLUGIN_DLL_HEADER + extern MeshingParameters mparam; NETGENPLUGIN_DLL_HEADER extern volatile multithreadt multithread; @@ -231,6 +231,7 @@ void NETGENPlugin_NETGEN_3D::FillParameters(const NETGENPlugin_Hypothesis* hyp, #endif } +// wirte in a binary file the orientation for each 2D element of the mesh void NETGENPlugin_NETGEN_3D::exportElementOrientation(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, netgen_params& aParams, @@ -275,53 +276,11 @@ void NETGENPlugin_NETGEN_3D::exportElementOrientation(SMESH_Mesh& aMesh, if ( elem->NbCornerNodes() != 3 ) error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); elemOrientation[elem->GetID()] = isRev; - // Add nodes of triangles and triangles them-selves to netgen mesh - - // add three nodes of triangle -/* bool hasDegen = false; - for ( int iN = 0; iN < 3; ++iN ) - { - const SMDS_MeshNode* node = elem->GetNode( iN ); - const int shapeID = node->getshapeId(); - if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && - helper.IsDegenShape( shapeID )) - { - // ignore all nodes on degeneraged edge and use node on its vertex instead - TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); - node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS ); - hasDegen = true; - } - int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; - if ( ngID == invalid_ID ) - { - ngID = ++Netgen_NbOfNodes; - Netgen_point [ 0 ] = node->X(); - Netgen_point [ 1 ] = node->Y(); - Netgen_point [ 2 ] = node->Z(); - Ng_AddPoint(Netgen_mesh, Netgen_point); - } - Netgen_triangle[ isRev ? 2-iN : iN ] = ngID; - } - // add triangle - if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] || - Netgen_triangle[0] == Netgen_triangle[2] || - Netgen_triangle[2] == Netgen_triangle[1] )) - continue; - - Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); - - if ( isInternalFace && !proxyMesh->IsTemporary( elem )) - { - swap( Netgen_triangle[1], Netgen_triangle[2] ); - Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); - }*/ } // loop on elements on a face } // loop on faces of a SOLID or SHELL std::ofstream df(output_file, ios::out|ios::binary); int size=elemOrientation.size(); - std::cout << size<< std::endl; - std::cout << "vtkIdType " << sizeof(vtkIdType) << std::endl; df.write((char*)&size, sizeof(int)); for(auto const& [id, orient]:elemOrientation){ @@ -329,14 +288,10 @@ void NETGENPlugin_NETGEN_3D::exportElementOrientation(SMESH_Mesh& aMesh, df.write((char*)&orient, sizeof(bool)); } df.close(); - // for(auto const& [id, orient] : elemOrientation) - // { - // std::cout << id << " : " << orient << ", "; - // } } -int NETGENPlugin_NETGEN_3D::ParallelCompute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) +int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) { aMesh.Lock(); SMESH_Hypothesis::Hypothesis_Status hypStatus; @@ -380,20 +335,22 @@ int NETGENPlugin_NETGEN_3D::ParallelCompute(SMESH_Mesh& aMesh, + param_file.string() + " " + element_orientation_file.string() + " " + new_element_file.string() + " " + + std::to_string(0) + " " + output_mesh_file.string() + " >> " + log_file.string(); - std::cout << "Running command: " << std::endl; - std::cout << cmd << std::endl; + //std::cout << "Running command: " << std::endl; + //std::cout << cmd << std::endl; // Writing command in log std::ofstream flog(log_file.string()); flog << cmd << endl; flog.close(); + // TODO: Replace system by something else to handle redirection for windows int ret = system(cmd.c_str()); - // TODO: error handling + // TODO: better error handling (display log ?) if(ret != 0){ // Run crahed //throw Exception("Meshing failed"); @@ -406,7 +363,6 @@ int NETGENPlugin_NETGEN_3D::ParallelCompute(SMESH_Mesh& aMesh, aMesh.Lock(); std::ifstream df(new_element_file.string(), ios::binary); - int Netgen_NbOfNodes; int Netgen_NbOfNodesNew; int Netgen_NbOfTetra; @@ -419,19 +375,17 @@ int NETGENPlugin_NETGEN_3D::ParallelCompute(SMESH_Mesh& aMesh, int _quadraticMesh = helper.IsQuadraticSubMesh(aShape); helper.SetElementsOnShape( true ); - // Filling nodevec (correspondence netgen numbering mesh numbering) - // Number of nodes + // Number of nodes in intial mesh df.read((char*) &Netgen_NbOfNodes, sizeof(int)); + // Number of nodes added by netgen df.read((char*) &Netgen_NbOfNodesNew, sizeof(int)); + // Filling nodevec (correspondence netgen numbering mesh numbering) vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); - for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) { //Id of the point df.read((char*) &nodeID, sizeof(int)); - // std::cout << "Old Node " << nodeIndex << ": " << nodeID << std::endl; - // TODO: do stuff to fill nodeVec ?? nodeVec.at(nodeIndex) = nullptr; SMDS_NodeIteratorPtr iteratorNode = aMesh.GetMeshDS()->nodesIterator(); while(iteratorNode->more()){ @@ -447,33 +401,21 @@ int NETGENPlugin_NETGEN_3D::ParallelCompute(SMESH_Mesh& aMesh, } } - // Writing info on new points + // Add new points and update nodeVec for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) { - // Coordinates of the point df.read((char *) &Netgen_point, sizeof(double)*3); - // std::cout << "Node " << nodeIndex << ": "; - // for(auto coord:Netgen_point){ - // std::cout << coord << " "; - // } - // std::cout << std::endl; + nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], Netgen_point[1], Netgen_point[2]); - } - // create tetrahedrons + // Add tetrahedrons df.read((char*) &Netgen_NbOfTetra, sizeof(int)); for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) { df.read((char*) &Netgen_tetrahedron, sizeof(int)*4); - // std::cout << "Element " << elemIndex << ": "; - // for(auto elem:Netgen_tetrahedron){ - // std::cout << elem << " "; - // } - // std::cout << std::endl; - // TODO: Add tetra helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), nodeVec.at( Netgen_tetrahedron[1] ), nodeVec.at( Netgen_tetrahedron[2] ), @@ -495,34 +437,28 @@ int NETGENPlugin_NETGEN_3D::ParallelCompute(SMESH_Mesh& aMesh, bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { + if(aMesh.IsParallel()) + return RemoteCompute(aMesh, aShape); - return ParallelCompute(aMesh, aShape); - aMesh.Lock(); - SMESH_Hypothesis::Hypothesis_Status hypStatus; - CheckHypothesis(aMesh, aShape, hypStatus); - aMesh.Unlock(); - - //netgen::multithread.terminate = 0; - //netgen::multithread.task = "Volume meshing"; + netgen::multithread.terminate = 0; + netgen::multithread.task = "Volume meshing"; _progressByTic = -1.; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - SMESH_MesherHelper *helper = new SMESH_MesherHelper(aMesh); - _quadraticMesh = helper->IsQuadraticSubMesh(aShape); - helper->SetElementsOnShape( true ); + SMESH_MesherHelper helper(aMesh); + _quadraticMesh = helper.IsQuadraticSubMesh(aShape); + helper.SetElementsOnShape( true ); int Netgen_NbOfNodes = 0; double Netgen_point[3]; int Netgen_triangle[3]; - NETGENPlugin_NetgenLibWrapper *ngLib; - int id_nglib = nglib_provider.take(&ngLib); - Ng_Mesh * Netgen_mesh = (Ng_Mesh*)ngLib->_ngMesh; + NETGENPlugin_NetgenLibWrapper ngLib; + Ng_Mesh * Netgen_mesh = (Ng_Mesh*)ngLib._ngMesh; // vector of nodes in which node index == netgen ID vector< const SMDS_MeshNode* > nodeVec; - aMesh.Lock(); { const int invalid_ID = -1; @@ -547,14 +483,14 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); if ( _viscousLayersHyp ) { - //netgen::multithread.percent = 3; + netgen::multithread.percent = 3; proxyMesh = _viscousLayersHyp->Compute( aMesh, aShape ); if ( !proxyMesh ) return false; } if ( aMesh.NbQuadrangles() > 0 ) { - //netgen::multithread.percent = 6; + netgen::multithread.percent = 6; StdMeshers_QuadToTriaAdaptor* Adaptor = new StdMeshers_QuadToTriaAdaptor; Adaptor->Compute(aMesh,aShape,proxyMesh.get()); proxyMesh.reset( Adaptor ); @@ -567,10 +503,10 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, bool isInternalFace = internals.isInternalShape( faceID ); bool isRev = false; if ( checkReverse && !isInternalFace && - helper->NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) + helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) // IsReversedSubMesh() can work wrong on strongly curved faces, // so we use it as less as possible - isRev = helper->IsReversedSubMesh( TopoDS::Face( aShapeFace )); + isRev = helper.IsReversedSubMesh( TopoDS::Face( aShapeFace )); const SMESHDS_SubMesh * aSubMeshDSFace = proxyMesh->GetSubMesh( aShapeFace ); if ( !aSubMeshDSFace ) continue; @@ -581,7 +517,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, { // add medium nodes of proxy triangles to helper (#16843) while ( iteratorElem->more() ) - helper->AddTLinks( static_cast< const SMDS_MeshFace* >( iteratorElem->next() )); + helper.AddTLinks( static_cast< const SMDS_MeshFace* >( iteratorElem->next() )); iteratorElem = aSubMeshDSFace->GetElements(); } @@ -603,7 +539,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, const SMDS_MeshNode* node = elem->GetNode( iN ); const int shapeID = node->getshapeId(); if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && - helper->IsDegenShape( shapeID )) + helper.IsDegenShape( shapeID )) { // ignore all nodes on degeneraged edge and use node on its vertex instead TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); @@ -644,7 +580,6 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, nodeVec[ n_id->second ] = n_id->first; nodeToNetgenID.clear(); - // TODO: Handle internal vertex if ( internals.hasInternalVertexInSolid() ) { netgen::OCCGeometry occgeo; @@ -654,16 +589,12 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, internals); } } - aMesh.Unlock(); // ------------------------- // Generate the volume mesh // ------------------------- - ngLib->_isComputeOk = compute( aMesh, *helper, nodeVec, *ngLib ); - bool ret = ngLib->_isComputeOk; - nglib_provider.release(id_nglib, true); - return ret; + return (ngLib._isComputeOk = compute( aMesh, helper, nodeVec, ngLib )); } // namespace @@ -749,7 +680,7 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, vector< const SMDS_MeshNode* >& nodeVec, NETGENPlugin_NetgenLibWrapper& ngLib) { - //netgen::multithread.terminate = 0; + netgen::multithread.terminate = 0; netgen::Mesh* ngMesh = ngLib._ngMesh; Ng_Mesh* Netgen_mesh = ngLib.ngMesh(); @@ -760,15 +691,11 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, int err = 1; NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true ); - netgen::OCCGeometry *occgeo; - int id_occgeo = occgeom_provider.take(&occgeo); - netgen::MeshingParameters mparam; - int id_mparam = mparam_provider.take(mparam); - aMesher.SetDefaultParameters(mparam); + netgen::OCCGeometry occgeo; if ( _hypParameters ) { - aMesher.SetParameters( _hypParameters, mparam ); + aMesher.SetParameters( _hypParameters ); if ( !_hypParameters->GetLocalSizesAndEntries().empty() || !_hypParameters->GetMeshSizeFile().empty() ) @@ -779,10 +706,10 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, ngMesh->GetBox( pmin, pmax, 0 ); ngMesh->SetLocalH( pmin, pmax, _hypParameters->GetGrowthRate() ); } - aMesher.SetLocalSize( *occgeo, *ngMesh ); + aMesher.SetLocalSize( occgeo, *ngMesh ); try { - ngMesh->LoadLocalMeshSize( mparam.meshsizefilename ); + ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); } catch (netgen::NgException & ex) { return error( COMPERR_BAD_PARMETERS, ex.What() ); } @@ -792,24 +719,24 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, } else if ( _hypMaxElementVolume ) { - mparam.maxh = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. ); + netgen::mparam.maxh = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. ); // limitVolumeSize( ngMesh, mparam.maxh ); // result is unpredictable } else if ( aMesh.HasShapeToMesh() ) { - aMesher.PrepareOCCgeometry( *occgeo, helper.GetSubShape(), aMesh ); - mparam.maxh = occgeo->GetBoundingBox().Diam()/2; + aMesher.PrepareOCCgeometry( occgeo, helper.GetSubShape(), aMesh ); + netgen::mparam.maxh = occgeo.GetBoundingBox().Diam()/2; } else { netgen::Point3d pmin, pmax; ngMesh->GetBox (pmin, pmax); - mparam.maxh = Dist(pmin, pmax)/2; + netgen::mparam.maxh = Dist(pmin, pmax)/2; } if ( !_hypParameters && aMesh.HasShapeToMesh() ) { - mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), mparam.maxh ); + netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh ); } try @@ -817,7 +744,7 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, OCC_CATCH_SIGNALS; ngLib.CalcLocalH(ngMesh); - err = ngLib.GenerateMesh(*occgeo, startWith, endWith, ngMesh, mparam); + err = ngLib.GenerateMesh(occgeo, startWith, endWith); if(netgen::multithread.terminate) return false; @@ -863,10 +790,6 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, error( ce ); } - mparam_provider.release(id_mparam); - occgeom_provider.release(id_occgeo, true); - - aMesh.Lock(); bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built if ( isOK ) { @@ -898,8 +821,6 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, } } } - aMesh.Unlock(); - return !err; } diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx index 0da216f..4ae5666 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx @@ -78,8 +78,8 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo void FillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams); - int ParallelCompute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + int RemoteCompute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape); bool compute(SMESH_Mesh& mesh, @@ -93,10 +93,6 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo const StdMeshers_MaxElementVolume* _hypMaxElementVolume; const StdMeshers_ViscousLayers* _viscousLayersHyp; double _progressByTic; - - Provider mparam_provider; - ProviderPtr occgeom_provider; - ProviderPtr nglib_provider; }; #endif From b7289f8536560278ac3ba10f84d6629e1e85b960 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 31 Aug 2022 16:07:16 +0200 Subject: [PATCH 04/29] Integration of run_mesher code --- src/NETGENPlugin/CMakeLists.txt | 25 +- src/NETGENPlugin/netgen_mesher.cxx | 575 +++++++++++++++++++++++++++++ src/NETGENPlugin/netgen_mesher.hxx | 57 +++ src/NETGENPlugin/netgen_param.cxx | 204 ++++++++++ src/NETGENPlugin/netgen_param.hxx | 90 +++++ src/NETGENPlugin/run_mesher.cxx | 223 +++++++++++ 6 files changed, 1161 insertions(+), 13 deletions(-) create mode 100644 src/NETGENPlugin/netgen_mesher.cxx create mode 100644 src/NETGENPlugin/netgen_mesher.hxx create mode 100644 src/NETGENPlugin/netgen_param.cxx create mode 100644 src/NETGENPlugin/netgen_param.hxx create mode 100644 src/NETGENPlugin/run_mesher.cxx diff --git a/src/NETGENPlugin/CMakeLists.txt b/src/NETGENPlugin/CMakeLists.txt index aa6dcb8..76f4e46 100644 --- a/src/NETGENPlugin/CMakeLists.txt +++ b/src/NETGENPlugin/CMakeLists.txt @@ -63,6 +63,8 @@ SET(_link_LIBRARIES ${KERNEL_SalomeNS} ${KERNEL_SALOMELocalTrace} ${KERNEL_OpUtil} + VTK::CommonCore + VTK::CommonDataModel SalomeIDLNETGENPLUGIN ) @@ -92,12 +94,8 @@ SET(NETGENEngine_HEADERS NETGENPlugin_Remesher_2D.hxx NETGENPlugin_Defs.hxx NETGENPlugin_Provider.hxx -) - -SET(Run_Mesher_HEADERS - DriverStep.hxx - netgen_param.hxx - netgen_mesher.hxx + netgen_param.hxx + netgen_mesher.hxx ) # --- sources --- @@ -125,12 +123,12 @@ SET(NETGENEngine_SOURCES NETGENPlugin_SimpleHypothesis_3D_i.cxx NETGENPlugin_Remesher_2D.cxx NETGENPlugin_i.cxx + netgen_mesher.cxx + netgen_param.cxx ) SET(Run_Mesher_SOURCES - DriverStep.cxx - netgen_mesher.cxx - netgen_param.cxx + run_mesher.cxx ) # --- scripts --- @@ -143,13 +141,14 @@ SET(_bin_SCRIPTS # --- rules --- -ADD_LIBRARY(NETGENEngine ${NETGENEngine_SOURCES} ${Run_Mesher_SOURCES}) +ADD_LIBRARY(NETGENEngine ${NETGENEngine_SOURCES}) TARGET_LINK_LIBRARIES(NETGENEngine ${_link_LIBRARIES} ) INSTALL(TARGETS NETGENEngine EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) -#ADD_EXECUTABLE(run_mesher ${Run_Mesher_SOURCES}) -#INSTALL(TARGETS NETGENEngine EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) +ADD_EXECUTABLE(run_mesher ${Run_Mesher_SOURCES}) +TARGET_LINK_LIBRARIES(run_mesher ${_link_LIBRARIES} NETGENEngine ) +INSTALL(TARGETS run_mesher EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) -INSTALL(FILES ${Run_Mesher_HEADERS} ${NETGENEngine_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) +INSTALL(FILES ${NETGENEngine_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) SALOME_INSTALL_SCRIPTS("${_bin_SCRIPTS}" ${SALOME_INSTALL_PYTHON}/salome/NETGENPlugin) diff --git a/src/NETGENPlugin/netgen_mesher.cxx b/src/NETGENPlugin/netgen_mesher.cxx new file mode 100644 index 0000000..6b15fb0 --- /dev/null +++ b/src/NETGENPlugin/netgen_mesher.cxx @@ -0,0 +1,575 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : netgen_mesher.cxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#include "netgen_mesher.hxx" + +#include "DriverStep.hxx" +#include "DriverMesh.hxx" +#include "netgen_param.hxx" + +#include +#include +#include +namespace fs = std::filesystem; + +// SMESH include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// NETGENPlugin +// #include +// #include +#include "NETGENPlugin_Mesher.hxx" +#include "NETGENPlugin_Hypothesis.hxx" + + +// OCC include +#include +#include +#include +#include + +#include +#include +/* + Netgen include files +*/ + +#ifndef OCCGEOMETRY +#define OCCGEOMETRY +#endif +#include + +#ifdef NETGEN_V5 +#include +#endif +#ifdef NETGEN_V6 +#include +#endif + +namespace nglib { +#include +} +namespace netgen { + + NETGENPLUGIN_DLL_HEADER + + NETGENPLUGIN_DLL_HEADER + extern volatile multithreadt multithread; + + NETGENPLUGIN_DLL_HEADER + extern bool merge_solids; +} +using namespace nglib; + +int error(int error_type, std::string msg){ + std::cerr << msg << std::endl; + return error_type; +}; + +int error(const SMESH_Comment& comment){ + return error(1, "SMESH_Comment error: "+comment); +}; + +/** + * @brief Set the netgen parameters + * + * @param aParams Internal structure of parameters + * @param mparams Netgen strcuture of parameters + */ +void set_netgen_parameters(netgen_params& aParams){ + + // Default parameters +#ifdef NETGEN_V6 + + netgen::mparam.nthreads = std::thread::hardware_concurrency(); + + if ( getenv( "SALOME_NETGEN_DISABLE_MULTITHREADING" )) + { + netgen::mparam.nthreads = 1; + netgen::mparam.parallel_meshing = false; + } + +#endif + + // Initialize global NETGEN parameters: + netgen::mparam.maxh = aParams.maxh; + netgen::mparam.minh = aParams.minh; + netgen::mparam.segmentsperedge = aParams.segmentsperedge; + netgen::mparam.grading = aParams.grading; + netgen::mparam.curvaturesafety = aParams.curvaturesafety; + netgen::mparam.secondorder = aParams.secondorder; + netgen::mparam.quad = aParams.quad; + netgen::mparam.uselocalh = aParams.uselocalh; + netgen::merge_solids = aParams.merge_solids; + netgen::mparam.optsteps2d = aParams.optsteps2d; + netgen::mparam.optsteps3d = aParams.optsteps3d; + netgen::mparam.elsizeweight = aParams.elsizeweight; + netgen::mparam.opterrpow = aParams.opterrpow; + netgen::mparam.delaunay = aParams.delaunay; + netgen::mparam.checkoverlap = aParams.checkoverlap; + netgen::mparam.checkchartboundary = aParams.checkchartboundary; +#ifdef NETGEN_V6 + // std::string + netgen::mparam.meshsizefilename = aParams.meshsizefilename; + netgen::mparam.closeedgefac = aParams.closeedgefac; + +#else + // const char* + netgen::mparam.meshsizefilename= aParams.meshsizefilename ? 0 : aParams.meshsizefilename.c_str(); +#endif +} + +/** + * @brief compute mesh with netgen + * + * @param input_mesh_file Input Mesh file + * @param shape_file Shape file + * @param hypo_file Parameter file + * @param new_element_file Binary file containing new nodes and new element info + * @param output_mesh If true will export mesh into output_mesh_file + * @param output_mesh_file Output Mesh file + * + * @return error code + */ +int netgen3d(const std::string input_mesh_file, + const std::string shape_file, + const std::string hypo_file, + const std::string element_orientation_file, + const std::string new_element_file, + bool output_mesh, + const std::string output_mesh_file){ + + // Importing mesh + SMESH_Gen gen; + + SMESH_Mesh *myMesh = gen.CreateMesh(false); + //TODO: To define + std::string mesh_name = "Maillage_1"; + + import_mesh(input_mesh_file, *myMesh, mesh_name); + + // Importing shape + TopoDS_Shape myShape; + import_shape(shape_file, myShape); + + // Importing hypothesis + //TODO: make it + netgen_params myParams; + + import_netgen_params(hypo_file, myParams); + + std::cout << "Meshing with netgen3d" << std::endl; + int ret = netgen3d(myShape, *myMesh, myParams, + new_element_file, element_orientation_file, + output_mesh); + + if(!ret){ + std::cout << "Meshing failed" << std::endl; + return ret; + } + + if(output_mesh) + export_mesh(output_mesh_file, *myMesh, mesh_name); + + return ret; +} + +/** + * @brief Compute aShape within aMesh using netgen + * + * @param aShape the shape + * @param aMesh the mesh + * @param aParams the netgen parameters + * @param new_element_file file containing data on the new point/tetra added by netgen + * + * @return error code + */ +int netgen3d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, + std::string new_element_file, std::string element_orientation_file, + bool output_mesh){ + + netgen::multithread.terminate = 0; + netgen::multithread.task = "Volume meshing"; + + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + + SMESH_MesherHelper helper(aMesh); + aParams._quadraticMesh = helper.IsQuadraticSubMesh(aShape); + helper.SetElementsOnShape( true ); + + int Netgen_NbOfNodes = 0; + double Netgen_point[3]; + int Netgen_triangle[3]; + + NETGENPlugin_NetgenLibWrapper ngLib; + Ng_Mesh * Netgen_mesh = (Ng_Mesh*)ngLib._ngMesh; + + // vector of nodes in which node index == netgen ID + vector< const SMDS_MeshNode* > nodeVec; + { + const int invalid_ID = -1; + + SMESH::Controls::Area areaControl; + SMESH::Controls::TSequenceOfXYZ nodesCoords; + + // maps nodes to ng ID + typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap; + typedef TNodeToIDMap::value_type TN2ID; + TNodeToIDMap nodeToNetgenID; + + // find internal shapes + NETGENPlugin_Internals internals( aMesh, aShape, /*is3D=*/true ); + + // --------------------------------- + // Feed the Netgen with surface mesh + // --------------------------------- + + TopAbs_ShapeEnum mainType = aMesh.GetShapeToMesh().ShapeType(); + bool checkReverse = ( mainType == TopAbs_COMPOUND || mainType == TopAbs_COMPSOLID ); + + SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); + if ( aParams._viscousLayersHyp ) + { + netgen::multithread.percent = 3; + proxyMesh = aParams._viscousLayersHyp->Compute( aMesh, aShape ); + if ( !proxyMesh ) + return false; + } + if ( aMesh.NbQuadrangles() > 0 ) + { + netgen::multithread.percent = 6; + StdMeshers_QuadToTriaAdaptor* Adaptor = new StdMeshers_QuadToTriaAdaptor; + Adaptor->Compute(aMesh,aShape,proxyMesh.get()); + proxyMesh.reset( Adaptor ); + } + + // Get list of elements + their orientation from element_orientation file + std::ifstream df(element_orientation_file, ios::binary|ios::in); + int nbElement; + bool orient; + + // Warning of the use of vtkIdType (I had issue when run_mesher was compiled with internal vtk) and salome not + // Sizeof was the same but how he othered the type was different + // Maybe using another type (uint64_t) instead would be better + vtkIdType id; + std::map elemOrientation; + df.read((char*)&nbElement, sizeof(int)); + + for(int ielem=0;ielemelementsIterator(SMDSAbs_Face); + int nbedge = meshDS->NbEdges(); + int nbface = meshDS->NbFaces(); + bool isRev; + bool isInternalFace = false; + + bool isIn; + + while ( iteratorElem->more() ) // loop on elements on a geom face + { + // check mesh face + const SMDS_MeshElement* elem = iteratorElem->next(); + int tmp = elem->GetShapeID(); + if ( !elem ) + return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); + if ( elem->NbCornerNodes() != 3 ) + return error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); + + // Keeping only element that are in the element orientation file + isIn = elemOrientation.count(elem->GetID())==1; + + if(!isIn) + continue; + + + // Get orientation + // Netgen requires that all the triangle point outside + isRev = elemOrientation[elem->GetID()]; + + // Add nodes of triangles and triangles them-selves to netgen mesh + + // add three nodes of triangle + bool hasDegen = false; + for ( int iN = 0; iN < 3; ++iN ) + { + const SMDS_MeshNode* node = elem->GetNode( iN ); + const int shapeID = node->getshapeId(); + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && + helper.IsDegenShape( shapeID )) + { + // ignore all nodes on degeneraged edge and use node on its vertex instead + TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); + node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS ); + hasDegen = true; + } + int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; + if ( ngID == invalid_ID ) + { + ngID = ++Netgen_NbOfNodes; + Netgen_point [ 0 ] = node->X(); + Netgen_point [ 1 ] = node->Y(); + Netgen_point [ 2 ] = node->Z(); + Ng_AddPoint(Netgen_mesh, Netgen_point); + } + + Netgen_triangle[ isRev ? 2-iN : iN ] = ngID; + } + // add triangle + if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] || + Netgen_triangle[0] == Netgen_triangle[2] || + Netgen_triangle[2] == Netgen_triangle[1] )) + continue; + + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + + // TODO: Handle that case (quadrangle 2D) (isInternal is set to false) + if ( isInternalFace && !proxyMesh->IsTemporary( elem )) + { + swap( Netgen_triangle[1], Netgen_triangle[2] ); + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + } + } + + // insert old nodes into nodeVec + nodeVec.resize( nodeToNetgenID.size() + 1, 0 ); + TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); + for ( ; n_id != nodeToNetgenID.end(); ++n_id ) + nodeVec[ n_id->second ] = n_id->first; + nodeToNetgenID.clear(); + + // TODO: Handle internal vertex + //if ( internals.hasInternalVertexInSolid() ) + //{ + // netgen::OCCGeometry occgeo; + // NETGENPlugin_Mesher::AddIntVerticesInSolids( occgeo, + // (netgen::Mesh&) *Netgen_mesh, + // nodeVec, + // internals); + //} + } + + // ------------------------- + // Generate the volume mesh + // ------------------------- + netgen::multithread.terminate = 0; + + netgen::Mesh* ngMesh = ngLib._ngMesh; + Netgen_mesh = ngLib.ngMesh(); + Netgen_NbOfNodes = Ng_GetNP( Netgen_mesh ); + + + int startWith = netgen::MESHCONST_MESHVOLUME; + int endWith = netgen::MESHCONST_OPTVOLUME; + int err = 1; + + NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true ); + netgen::OCCGeometry occgeo; + set_netgen_parameters(aParams); + + if ( aParams.has_netgen_param ) + { + if ( aParams.has_local_size) + { + if ( ! &ngMesh->LocalHFunction() ) + { + netgen::Point3d pmin, pmax; + ngMesh->GetBox( pmin, pmax, 0 ); + ngMesh->SetLocalH( pmin, pmax, aParams.grading ); + } + aMesher.SetLocalSize( occgeo, *ngMesh ); + + try { + ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); + } catch (netgen::NgException & ex) { + return error( COMPERR_BAD_PARMETERS, ex.What() ); + } + } + if ( !aParams.optimize ) + endWith = netgen::MESHCONST_MESHVOLUME; + } + else if ( aParams.has_maxelementvolume_hyp ) + { + netgen::mparam.maxh = pow( 72, 1/6. ) * pow( aParams.maxElementVolume, 1/3. ); + // limitVolumeSize( ngMesh, netgen::mparam.maxh ); // result is unpredictable + } + else if ( aMesh.HasShapeToMesh() ) + { + aMesher.PrepareOCCgeometry( occgeo, helper.GetSubShape(), aMesh ); + netgen::mparam.maxh = occgeo.GetBoundingBox().Diam()/2; + } + else + { + netgen::Point3d pmin, pmax; + ngMesh->GetBox (pmin, pmax); + netgen::mparam.maxh = Dist(pmin, pmax)/2; + } + + if ( !aParams.has_netgen_param && aMesh.HasShapeToMesh() ) + { + netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh ); + } + + try + { + OCC_CATCH_SIGNALS; + + ngLib.CalcLocalH(ngMesh); + err = ngLib.GenerateMesh(occgeo, startWith, endWith, ngMesh, netgen::mparam); + + if(netgen::multithread.terminate) + return false; + if ( err ) + return error(SMESH_Comment("Error in netgen::OCCGenerateMesh() at ") << netgen::multithread.task); + } + catch (Standard_Failure& ex) + { + SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); + str << " at " << netgen::multithread.task + << ": " << ex.DynamicType()->Name(); + if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) + str << ": " << ex.GetMessageString(); + return error(str); + } + catch (netgen::NgException& exc) + { + SMESH_Comment str("NgException"); + if ( strlen( netgen::multithread.task ) > 0 ) + str << " at " << netgen::multithread.task; + str << ": " << exc.What(); + return error(str); + } + catch (...) + { + SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); + if ( strlen( netgen::multithread.task ) > 0 ) + str << " at " << netgen::multithread.task; + return error(str); + } + + int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); + int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); + + // ------------------------------------------------------------------- + // Feed back the SMESHDS with the generated Nodes and Volume Elements + // ------------------------------------------------------------------- + + if ( err ) + { + SMESH_ComputeErrorPtr ce = NETGENPlugin_Mesher::ReadErrors(nodeVec); + if ( ce && ce->HasBadElems() ) + return error( ce ); + } + + bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built + if ( isOK ) + { + std::ofstream df(new_element_file, ios::out|ios::binary); + + double Netgen_point[3]; + int Netgen_tetrahedron[4]; + + // Writing nodevec (correspondance netgen numbering mesh numbering) + // Number of nodes + df.write((char*) &Netgen_NbOfNodes, sizeof(int)); + df.write((char*) &Netgen_NbOfNodesNew, sizeof(int)); + for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) + { + //Id of the point + int id = nodeVec.at(nodeIndex)->GetID(); + df.write((char*) &id, sizeof(int)); + } + + // Writing info on new points + for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) + { + Ng_GetPoint(Netgen_mesh, nodeIndex, Netgen_point ); + // Coordinates of the point + df.write((char *) &Netgen_point, sizeof(double)*3); + } + + // create tetrahedrons + df.write((char*) &Netgen_NbOfTetra, sizeof(int)); + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) + { + Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); + df.write((char*) &Netgen_tetrahedron, sizeof(int)*4); + } + df.close(); + } + + // Adding new files in aMesh as well + if ( output_mesh ) + { + double Netgen_point[3]; + int Netgen_tetrahedron[4]; + + // create and insert new nodes into nodeVec + nodeVec.resize( Netgen_NbOfNodesNew + 1, 0 ); + int nodeIndex = Netgen_NbOfNodes + 1; + for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) + { + Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point ); + nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], + Netgen_point[1], + Netgen_point[2]); + } + + // create tetrahedrons + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) + { + Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); + try + { + helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), + nodeVec.at( Netgen_tetrahedron[1] ), + nodeVec.at( Netgen_tetrahedron[2] ), + nodeVec.at( Netgen_tetrahedron[3] )); + } + catch (...) + { + } + } + } + + return !err; +} \ No newline at end of file diff --git a/src/NETGENPlugin/netgen_mesher.hxx b/src/NETGENPlugin/netgen_mesher.hxx new file mode 100644 index 0000000..f1e2fa9 --- /dev/null +++ b/src/NETGENPlugin/netgen_mesher.hxx @@ -0,0 +1,57 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : netgen_mesher.hxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#ifndef _NETGEN_MESHER_HXX_ +#define _NETGEN_MESHER_HXX_ + +#include +#include + +class TopoDS_Shape; +class SMESH_Mesh; +class SMESH_Comment; +class netgen_params; + +int netgen3d(TopoDS_Shape &aShape, + SMESH_Mesh& aMesh, + netgen_params& aParams, + std::string new_element_file, + std::string element_orientation_file, + bool output_mesh); +int netgen3d(const std::string input_mesh_file, + const std::string shape_file, + const std::string hypo_file, + const std::string element_orienation_file, + const std::string new_element_file, + bool output_mesh, + const std::string output_mesh_file); + +//TODO: Tmp function replace by real error handling +int error(int error_type, std::string msg); +int error(const SMESH_Comment& comment); + +#endif \ No newline at end of file diff --git a/src/NETGENPlugin/netgen_param.cxx b/src/NETGENPlugin/netgen_param.cxx new file mode 100644 index 0000000..3a4a22b --- /dev/null +++ b/src/NETGENPlugin/netgen_param.cxx @@ -0,0 +1,204 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : netgen_param.hxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// +#include "netgen_param.hxx" + +#include +#include +#include +#include + +/** + * @brief Print content of a netgen_params + * + * @param aParams The object to display + */ +void print_netgen_params(netgen_params& aParams){ + std::cout << "has_netgen_param: " << aParams.has_netgen_param << std::endl; + std::cout << "maxh: " << aParams.maxh << std::endl; + std::cout << "minh: " << aParams.minh << std::endl; + std::cout << "segmentsperedge: " << aParams.segmentsperedge << std::endl; + std::cout << "grading: " << aParams.grading << std::endl; + std::cout << "curvaturesafety: " << aParams.curvaturesafety << std::endl; + std::cout << "secondorder: " << aParams.secondorder << std::endl; + std::cout << "quad: " << aParams.quad << std::endl; + std::cout << "optimize: " << aParams.optimize << std::endl; + std::cout << "fineness: " << aParams.fineness << std::endl; + std::cout << "uselocalh: " << aParams.uselocalh << std::endl; + std::cout << "merge_solids: " << aParams.merge_solids << std::endl; + std::cout << "chordalError: " << aParams.chordalError << std::endl; + std::cout << "optsteps2d: " << aParams.optsteps2d << std::endl; + std::cout << "optsteps3d: " << aParams.optsteps3d << std::endl; + std::cout << "elsizeweight: " << aParams.elsizeweight << std::endl; + std::cout << "opterrpow: " << aParams.opterrpow << std::endl; + std::cout << "delaunay: " << aParams.delaunay << std::endl; + std::cout << "checkoverlap: " << aParams.checkoverlap << std::endl; + std::cout << "checkchartboundary: " << aParams.checkchartboundary << std::endl; + std::cout << "has_local_size: " << aParams.has_local_size << std::endl; + std::cout << "meshsizefilename: " << aParams.meshsizefilename << std::endl; + std::cout << "has_maxelementvolume_hyp: " << aParams.has_maxelementvolume_hyp << std::endl; + std::cout << "maxElementVolume: " << aParams.maxElementVolume << std::endl; + std::cout << "closeedgefac: " << aParams.closeedgefac << std::endl; +} + +/** + * @brief Import a param_file into a netgen_params structure + * + * @param param_file Name of the file + * @param aParams Structure to fill + */ +void import_netgen_params(const std::string param_file, netgen_params& aParams){ + std::ifstream myfile(param_file); + std::string line; + + std::getline(myfile, line); + aParams.has_netgen_param = std::stoi(line); + std::getline(myfile, line); + aParams.maxh = std::stod(line); + std::getline(myfile, line); + aParams.minh = std::stod(line); + std::getline(myfile, line); + aParams.segmentsperedge = std::stod(line); + std::getline(myfile, line); + aParams.grading = std::stod(line); + std::getline(myfile, line); + aParams.curvaturesafety = std::stod(line); + std::getline(myfile, line); + aParams.secondorder = std::stoi(line); + std::getline(myfile, line); + aParams.quad = std::stoi(line); + std::getline(myfile, line); + aParams.optimize = std::stoi(line); + std::getline(myfile, line); + aParams.fineness = std::stoi(line); + std::getline(myfile, line); + aParams.uselocalh = std::stoi(line); + std::getline(myfile, line); + aParams.merge_solids = std::stoi(line); + std::getline(myfile, line); + aParams.chordalError = std::stod(line); + std::getline(myfile, line); + aParams.optsteps2d = std::stoi(line); + std::getline(myfile, line); + aParams.optsteps3d = std::stoi(line); + std::getline(myfile, line); + aParams.elsizeweight = std::stod(line); + std::getline(myfile, line); + aParams.opterrpow = std::stoi(line); + std::getline(myfile, line); + aParams.delaunay = std::stoi(line); + std::getline(myfile, line); + aParams.checkoverlap = std::stoi(line); + std::getline(myfile, line); + aParams.checkchartboundary = std::stoi(line); + std::getline(myfile, line); + aParams.closeedgefac = std::stoi(line); + std::getline(myfile, line); + aParams.has_local_size = std::stoi(line); + std::getline(myfile, line); + aParams.meshsizefilename = line; + std::getline(myfile, line); + aParams.has_maxelementvolume_hyp = std::stoi(line); + std::getline(myfile, line); + aParams.maxElementVolume = std::stod(line); + + myfile.close(); +}; + +/** + * @brief Writes the content of a netgen_param into a file + * + * @param param_file the file + * @param aParams the object + */ +void export_netgen_params(const std::string param_file, netgen_params& aParams){ + std::ofstream myfile(param_file); + myfile << aParams.has_netgen_param << std::endl; + myfile << aParams.maxh << std::endl; + myfile << aParams.minh << std::endl; + myfile << aParams.segmentsperedge << std::endl; + myfile << aParams.grading << std::endl; + myfile << aParams.curvaturesafety << std::endl; + myfile << aParams.secondorder << std::endl; + myfile << aParams.quad << std::endl; + myfile << aParams.optimize << std::endl; + myfile << aParams.fineness << std::endl; + myfile << aParams.uselocalh << std::endl; + myfile << aParams.merge_solids << std::endl; + myfile << aParams.chordalError << std::endl; + myfile << aParams.optsteps2d << std::endl; + myfile << aParams.optsteps3d << std::endl; + myfile << aParams.elsizeweight << std::endl; + myfile << aParams.opterrpow << std::endl; + myfile << aParams.delaunay << std::endl; + myfile << aParams.checkoverlap << std::endl; + myfile << aParams.checkchartboundary << std::endl; + myfile << aParams.closeedgefac << std::endl; + myfile << aParams.has_local_size << std::endl; + myfile << aParams.meshsizefilename << std::endl; + myfile << aParams.has_maxelementvolume_hyp << std::endl; + myfile << aParams.maxElementVolume << std::endl; + + myfile.close(); +}; + +/** + * @brief Compares two netgen_parms object + * + * @param params1 Object 1 + * @param params2 Object 2 + + * @return true if the two object are identical + */ +bool diff_netgen_params(netgen_params params1, netgen_params params2){ + bool ret = true; + ret &= params1.maxh == params2.maxh; + ret &= params1.minh == params2.minh; + ret &= params1.segmentsperedge == params2.segmentsperedge; + ret &= params1.grading == params2.grading; + ret &= params1.curvaturesafety == params2.curvaturesafety; + ret &= params1.secondorder == params2.secondorder; + ret &= params1.quad == params2.quad; + ret &= params1.optimize == params2.optimize; + ret &= params1.fineness == params2.fineness; + ret &= params1.uselocalh == params2.uselocalh; + ret &= params1.merge_solids == params2.merge_solids; + ret &= params1.chordalError == params2.chordalError; + ret &= params1.optsteps2d == params2.optsteps2d; + ret &= params1.optsteps3d == params2.optsteps3d; + ret &= params1.elsizeweight == params2.elsizeweight; + ret &= params1.opterrpow == params2.opterrpow; + ret &= params1.delaunay == params2.delaunay; + ret &= params1.checkoverlap == params2.checkoverlap; + ret &= params1.checkchartboundary == params2.checkchartboundary; + ret &= params1.closeedgefac == params2.closeedgefac; + ret &= params1.has_local_size == params2.has_local_size; + ret &= params1.meshsizefilename == params2.meshsizefilename; + ret &= params1.has_maxelementvolume_hyp == params2.has_maxelementvolume_hyp; + ret &= params1.maxElementVolume == params2.maxElementVolume; + + return ret; +} diff --git a/src/NETGENPlugin/netgen_param.hxx b/src/NETGENPlugin/netgen_param.hxx new file mode 100644 index 0000000..fef05f8 --- /dev/null +++ b/src/NETGENPlugin/netgen_param.hxx @@ -0,0 +1,90 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : netgen_param.hxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#ifndef _NETGEN_PARAM_HXX_ +#define _NETGEN_PARAM_HXX_ + +#include + +class NETGENPlugin_Hypothesis; +class StdMeshers_MaxElementVolume; +class StdMeshers_ViscousLayers; + +struct netgen_params{ + // Params from NETGENPlugin_Mesher + // True if _hypParameters is not null + bool has_netgen_param=true; + double maxh; + double minh; + double segmentsperedge; + double grading; + double curvaturesafety; + int secondorder; + int quad; + bool optimize; + int fineness; + bool uselocalh; + bool merge_solids; + double chordalError; + int optsteps2d; + int optsteps3d; + double elsizeweight; + int opterrpow; + bool delaunay; + bool checkoverlap; + bool checkchartboundary; + int closeedgefac; + + + // TODO: add localsize (pass through local size file ?) + // True if we have a mesh size file or local size info + bool has_local_size = false; + std::string meshsizefilename; + + // Params from NETGEN3D + // True if _hypMaxElementVolume is not null + bool has_maxelementvolume_hyp=false; + double maxElementVolume=0.0; + + // to replace + //NETGENPlugin_Hypothesis * _hypParameters=nullptr; + // to remove ? + StdMeshers_MaxElementVolume* _hypMaxElementVolume=nullptr; + // to remove ? + StdMeshers_ViscousLayers* _viscousLayersHyp=nullptr; + //double _progressByTic; + bool _quadraticMesh=false; +}; + +void print_netgen_params(netgen_params& aParams); + +void import_netgen_params(const std::string param_file, netgen_params& aParams); +void export_netgen_params(const std::string param_file, netgen_params& aParams); + +bool diff_netgen_params(netgen_params params1, netgen_params params2); + +#endif \ No newline at end of file diff --git a/src/NETGENPlugin/run_mesher.cxx b/src/NETGENPlugin/run_mesher.cxx new file mode 100644 index 0000000..5733cd0 --- /dev/null +++ b/src/NETGENPlugin/run_mesher.cxx @@ -0,0 +1,223 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : run_mesher.cxx +// Author : Yoann AUDOUIN, EDF +// Module : SMESH +// + +#include "DriverStep.hxx" +#include "DriverMesh.hxx" +#include "netgen_param.hxx" +#include "netgen_mesher.hxx" + +#include +#include + +#include +#include + +/** + * @brief Test of shape Import/Export + * + * @param shape_file + */ +void test_shape(){ + + std::cout << "Testing Shape Import/Export" << std::endl; + std::string shape_file = "box.step"; + + TopoDS_Shape myShape; + + // Test 1 import -> export cmp files + std::string shape_file2 = "/tmp/shape.step"; + + import_shape(shape_file, myShape); + export_shape(shape_file2, myShape); + + assert(diff_step_file(shape_file, shape_file2)); + + // Test 2 import->export->import cmp TopoDS_Shape + std::string shape_file3 = "/tmp/shape2.step"; + TopoDS_Shape myShape1, myShape2; + + import_shape(shape_file, myShape1); + + export_shape(shape_file3, myShape1); + + import_shape(shape_file3, myShape2); + + // TODO: See why this does not work + // TShape seems to be different + //assert(myShape1.IsSame(myShape2)); + +} + +/** + * @brief test of mesh import/export + * + * @param mesh_file + */ +void test_mesh(){ + + std::cout << "Testing Mesh Import/Export" << std::endl; + std::string mesh_file = "box.med"; + SMESH_Gen gen; + + SMESH_Mesh *myMesh = gen.CreateMesh(false); + std::string mesh_name = "Maillage_1"; + + // Test 1 import -> export cmp files + std::string mesh_file2 = "/tmp/mesh.med"; + + import_mesh(mesh_file, *myMesh, mesh_name); + export_mesh(mesh_file2, *myMesh, mesh_name); + + assert(diff_med_file(mesh_file, mesh_file2, mesh_name)); + + // TODO: Compare the two med files via dump ? + + // Test 2 import->export->import cmp TopoDS_Shape + std::string mesh_file3 = "/tmp/mesh2.med"; + SMESH_Mesh *myMesh1 = gen.CreateMesh(false); + SMESH_Mesh *myMesh2 = gen.CreateMesh(false); + + import_mesh(mesh_file, *myMesh1, mesh_name); + + export_mesh(mesh_file3, *myMesh1, mesh_name); + + import_mesh(mesh_file3, *myMesh2, mesh_name); + + // TODO: Compare SMESH_Mesh + //assert(myMesh1==myMesh2); +} + +/** + * @brief Test of import/export of netgen param + * + */ +void test_netgen_params(){ + + std::string param_file = "/tmp/netgen_param.txt"; + netgen_params myParams, myParams2; + myParams.has_netgen_param = true; + myParams.maxh = 34.64; + myParams.minh = 0.14; + myParams.segmentsperedge = 15; + myParams.grading = 0.2; + myParams.curvaturesafety = 1.5; + myParams.secondorder = false; + myParams.quad = false; + myParams.optimize = true; + myParams.fineness = 5; + myParams.uselocalh = true; + myParams.merge_solids = true; + myParams.chordalError = -1; + myParams.optsteps2d = 3; + myParams.optsteps3d = 3; + myParams.elsizeweight = 0.2; + myParams.opterrpow = 2; + myParams.delaunay = true; + myParams.checkoverlap = true; + myParams.checkchartboundary = false; + myParams.closeedgefac = 2; + myParams.has_local_size = false; + myParams.meshsizefilename = ""; + myParams.has_maxelementvolume_hyp = false; + myParams.maxElementVolume = 0.0; + + export_netgen_params(param_file, myParams); + import_netgen_params(param_file, myParams2); + + assert(diff_netgen_params(myParams, myParams2)); + +}; + +void test_netgen3d(){ + + std::cout << "Testing NETGEN 3D mesher" << std::endl; + netgen3d("box_partial2D1D-2.med", + "box-2.step", + "box_param.txt", + "element_orient.dat", + "new_element.dat", + true, + "box_with3D.med"); + + // TODO: Check result +} + +/** + * @brief Main function + * + * @param argc Number of arguments + * @param argv Arguments + * + * @return error code + */ +int main(int argc, char *argv[]){ + + if(argc!=9||(argc==2 && (argv[1] == "-h" || argv[1]=="--help"))){ + std::cout << "Error in number of argument"< Date: Wed, 31 Aug 2022 16:29:01 +0200 Subject: [PATCH 05/29] Generic path for executable --- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index c0ceac9..36ec441 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -326,10 +326,14 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, aMesh.Unlock(); // Calling run_mesher + // TODO: check if we need to handle the .exe for windows std::string cmd; - // TODO: Add run_meher to bin - std::string run_mesher_exe = "/home/B61570/work_in_progress/ssmesh/run_mesher/build/src/run_mesher"; - cmd = run_mesher_exe + + fs::path run_mesher_exe = + fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/ + fs::path("bin")/ + fs::path("salome")/ + fs::path("run_mesher"); + cmd = run_mesher_exe.string() + " NETGEN3D " + mesh_file.string() + " " + shape_file.string() + " " + param_file.string() + " " From 0722b0a29e184a13eab11b3d635b54ecaf0dd59b Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Fri, 9 Sep 2022 09:50:30 +0200 Subject: [PATCH 06/29] partial work for netgen2d in run_mesher + corrections for netgen3d nodeVec + restoring sequential netgen2D_only --- src/NETGENPlugin/NETGENPlugin_Mesher.cxx | 38 +- src/NETGENPlugin/NETGENPlugin_Mesher.hxx | 14 +- .../NETGENPlugin_NETGEN_2D_ONLY.cxx | 357 ++++++++--- .../NETGENPlugin_NETGEN_2D_ONLY.hxx | 19 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 75 ++- src/NETGENPlugin/netgen_mesher.cxx | 581 +++++++++++++++++- src/NETGENPlugin/netgen_mesher.hxx | 14 + src/NETGENPlugin/netgen_param.cxx | 12 +- src/NETGENPlugin/netgen_param.hxx | 3 + src/NETGENPlugin/run_mesher.cxx | 16 +- 10 files changed, 967 insertions(+), 162 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx index d1c6ccc..56c8e1b 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx @@ -576,8 +576,9 @@ void NETGENPlugin_Mesher::SetSelfPointer( NETGENPlugin_Mesher ** ptr ) */ //================================================================================ -void NETGENPlugin_Mesher::SetDefaultParameters(netgen::MeshingParameters &mparams) +void NETGENPlugin_Mesher::SetDefaultParameters() { + netgen::MeshingParameters& mparams = netgen::mparam; mparams = netgen::MeshingParameters(); // maximal mesh edge size mparams.maxh = 0;//NETGENPlugin_Hypothesis::GetDefaultMaxSize(); @@ -618,15 +619,9 @@ void NETGENPlugin_Mesher::SetDefaultParameters(netgen::MeshingParameters &mparam */ //================================================================================ -void NETGENPlugin_Mesher::SetDefaultParameters() +void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp) { netgen::MeshingParameters& mparams = netgen::mparam; - SetDefaultParameters(mparams); - -} - -void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp, netgen::MeshingParameters &mparams) -{ // Initialize global NETGEN parameters: // maximal mesh segment size mparams.maxh = hyp->GetMaxSize(); @@ -691,22 +686,6 @@ void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp, netg #endif } -//============================================================================= -/*! - * Pass parameters to NETGEN - */ -//============================================================================= -void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp) -{ - if (hyp) - { - netgen::MeshingParameters& mparams = netgen::mparam; - SetParameters(hyp, mparams); - } - - -} - //============================================================================= /*! * Pass simple parameters to NETGEN @@ -4519,8 +4498,7 @@ void NETGENPlugin_NetgenLibWrapper::setMesh( Ng_Mesh* mesh ) int NETGENPlugin_NetgenLibWrapper::GenerateMesh( netgen::OCCGeometry& occgeo, int startWith, int endWith, - netgen::Mesh* & ngMesh , - netgen::MeshingParameters& mparam) + netgen::Mesh* & ngMesh) { int err = 0; if ( !ngMesh ) @@ -4530,15 +4508,15 @@ int NETGENPlugin_NetgenLibWrapper::GenerateMesh( netgen::OCCGeometry& occgeo, ngMesh->SetGeometry( shared_ptr( &occgeo, &NOOP_Deleter )); - mparam.perfstepsstart = startWith; - mparam.perfstepsend = endWith; + netgen::mparam.perfstepsstart = startWith; + netgen::mparam.perfstepsend = endWith; std::shared_ptr meshPtr( ngMesh, &NOOP_Deleter ); - err = occgeo.GenerateMesh( meshPtr, mparam ); + err = occgeo.GenerateMesh( meshPtr, netgen::mparam ); #else #ifdef NETGEN_V5 - err = netgen::OCCGenerateMesh(occgeo, ngMesh, mparam, startWith, endWith); + err = netgen::OCCGenerateMesh(occgeo, ngMesh, netgen::mparam, startWith, endWith); #else diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.hxx b/src/NETGENPlugin/NETGENPlugin_Mesher.hxx index af7d971..6d06f81 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.hxx @@ -58,8 +58,6 @@ class TopoDS_Shape; namespace netgen { class OCCGeometry; class Mesh; - class MeshingParameters; - extern MeshingParameters mparam; } //============================================================================= /*! @@ -97,16 +95,12 @@ struct NETGENPLUGIN_EXPORT NETGENPlugin_NetgenLibWrapper static int GenerateMesh(netgen::OCCGeometry& occgeo, int startWith, int endWith, - netgen::Mesh* & ngMesh, netgen::MeshingParameters & mparam); + netgen::Mesh* & ngMesh); int GenerateMesh(netgen::OCCGeometry& occgeo, int startWith, int endWith ) { - - return GenerateMesh( occgeo, startWith, endWith, _ngMesh, netgen::mparam ); + return GenerateMesh( occgeo, startWith, endWith, _ngMesh ); } - static int GenerateMesh(netgen::OCCGeometry& occgeo, int startWith, int endWith, - netgen::Mesh* & ngMesh){ - return GenerateMesh(occgeo, startWith, endWith, ngMesh, netgen::mparam); - }; + static void CalcLocalH( netgen::Mesh * ngMesh ); static void RemoveTmpFiles(); @@ -139,7 +133,6 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher void SetSelfPointer( NETGENPlugin_Mesher ** ptr ); void SetParameters(const NETGENPlugin_Hypothesis* hyp); - void SetParameters(const NETGENPlugin_Hypothesis* hyp, netgen::MeshingParameters &mparams); void SetParameters(const NETGENPlugin_SimpleHypothesis_2D* hyp); void SetParameters(const StdMeshers_ViscousLayers* hyp ); void SetViscousLayers2DAssigned(bool isAssigned) { _isViscousLayers2D = isAssigned; } @@ -211,7 +204,6 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Mesher const bool overrideMinH=true); void SetDefaultParameters(); - void SetDefaultParameters(netgen::MeshingParameters &mparams); static SMESH_ComputeErrorPtr ReadErrors(const std::vector< const SMDS_MeshNode* >& nodeVec); diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx index 7b08a3d..72a2e6c 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx @@ -26,6 +26,7 @@ #include "NETGENPlugin_Mesher.hxx" #include "NETGENPlugin_Hypothesis_2D.hxx" #include "NETGENPlugin_Provider.hxx" +#include "netgen_param.hxx" #include #include @@ -40,6 +41,9 @@ #include #include #include +#include "DriverStep.hxx" +#include "DriverMesh.hxx" + #include #include @@ -51,6 +55,9 @@ #include #include +#include +#include +namespace fs = boost::filesystem; /* Netgen include files */ @@ -65,7 +72,7 @@ namespace nglib { //#include namespace netgen { NETGENPLUGIN_DLL_HEADER - // extern MeshingParameters mparam; + extern MeshingParameters mparam; #ifdef NETGEN_V5 extern void OCCSetLocalMeshSize(OCCGeometry & geom, Mesh & mesh); #endif @@ -220,6 +227,223 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh& aMesh, // } // } + +// write in a binary file the orientation for each 2D element of the mesh +void NETGENPlugin_NETGEN_2D_ONLY::exportElementOrientation(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + netgen_params& aParams, + const std::string output_file) +{ + std::map elemOrientation; + + SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); + for ( TopExp_Explorer exEd( aShape, TopAbs_EDGE ); exEd.More(); exEd.Next()) + { + const TopoDS_Shape& aShapeEdge = exEd.Current(); + const SMESHDS_SubMesh * aSubMeshDSEdge = proxyMesh->GetSubMesh( aShapeEdge ); + if ( !aSubMeshDSEdge ) continue; + + SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSEdge->GetElements(); + while ( iteratorElem->more() ) // loop on elements on a geom face + { + const SMDS_MeshElement* elem = iteratorElem->next(); + elemOrientation[elem->GetID()] = aShapeEdge.Orientation() == TopAbs_INTERNAL; + } + } + + std::ofstream df(output_file, ios::out|ios::binary); + int size=elemOrientation.size(); + + df.write((char*)&size, sizeof(int)); + for(auto const& [id, orient]:elemOrientation){ + df.write((char*)&id, sizeof(vtkIdType)); + df.write((char*)&orient, sizeof(bool)); + } + df.close(); +} + +void NETGENPlugin_NETGEN_2D_ONLY::FillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams) +{ + //TODO: factorize code with the one from NETGEN3D + // Move in netgen_param ? + aParams.maxh = hyp->GetMaxSize(); + aParams.minh = hyp->GetMinSize(); + aParams.segmentsperedge = hyp->GetNbSegPerEdge(); + aParams.grading = hyp->GetGrowthRate(); + aParams.curvaturesafety = hyp->GetNbSegPerRadius(); + aParams.secondorder = hyp->GetSecondOrder() ? 1 : 0; + aParams.quad = hyp->GetQuadAllowed() ? 1 : 0; + aParams.optimize = hyp->GetOptimize(); + aParams.fineness = hyp->GetFineness(); + aParams.uselocalh = hyp->GetSurfaceCurvature(); + aParams.merge_solids = hyp->GetFuseEdges(); + aParams.chordalError = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.; + aParams.optsteps2d = aParams.optimize ? hyp->GetNbSurfOptSteps() : 0; + aParams.optsteps3d = aParams.optimize ? hyp->GetNbVolOptSteps() : 0; + aParams.elsizeweight = hyp->GetElemSizeWeight(); + aParams.opterrpow = hyp->GetWorstElemMeasure(); + aParams.delaunay = hyp->GetUseDelauney(); + aParams.checkoverlap = hyp->GetCheckOverlapping(); + aParams.checkchartboundary = hyp->GetCheckChartBoundary(); +#ifdef NETGEN_V6 + // std::string + aParams.meshsizefilename = hyp->GetMeshSizeFile(); +#else + // const char* + aParams.meshsizefilename = hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str(); +#endif +#ifdef NETGEN_V6 + aParams.closeedgefac = 2; +#else + aParams.closeedgefac = 0; +#endif + aParams.has_LengthFromEdges_hyp = _hypLengthFromEdges; +} +//============================================================================= +/*! + *Here we are going to use the NETGEN mesher remotely + */ +//============================================================================= + +bool NETGENPlugin_NETGEN_2D_ONLY::RemoteCompute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) +{ + aMesh.Lock(); + SMESH_Hypothesis::Hypothesis_Status hypStatus; + CheckHypothesis(aMesh, aShape, hypStatus); + + // Temporary folder for run + fs::path tmp_folder = aMesh.tmp_folder / fs::unique_path(fs::path("Face-%%%%-%%%%")); + fs::create_directories(tmp_folder); + // Using MESH2D generated after all triangles where created. + fs::path mesh_file=aMesh.tmp_folder / fs::path("Mesh1D.med"); + fs::path element_orientation_file=tmp_folder / fs::path("element_orientation.dat"); + fs::path new_element_file=tmp_folder / fs::path("new_elements.dat"); + fs::path tmp_mesh_file=tmp_folder / fs::path("tmp_mesh.med"); + // TODO: Remove that file we do not use it + fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med"); + fs::path shape_file=tmp_folder / fs::path("shape.step"); + fs::path param_file=tmp_folder / fs::path("netgen2d_param.txt"); + fs::path log_file=tmp_folder / fs::path("run_mesher.log"); + //TODO: Handle variable mesh_name + std::string mesh_name = "Maillage_1"; + + //Writing Shape + export_shape(shape_file.string(), aShape); + //Writing hypo + netgen_params aParams; + FillParameters(_hypParameters, aParams); + + export_netgen_params(param_file.string(), aParams); + + // Exporting element orientation + exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); + + aMesh.Unlock(); + // Calling run_mesher + // TODO: check if we need to handle the .exe for windows + std::string cmd; + fs::path run_mesher_exe = + fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/ + fs::path("bin")/ + fs::path("salome")/ + fs::path("run_mesher"); + cmd = run_mesher_exe.string() + + " NETGEN2D " + mesh_file.string() + " " + + shape_file.string() + " " + + param_file.string() + " " + + element_orientation_file.string() + " " + + new_element_file.string() + " " + + std::to_string(0) + " " + + output_mesh_file.string() + + " >> " + log_file.string(); + + std::cout << "Running command: " << std::endl; + std::cout << cmd << std::endl; + + // Writing command in log + std::ofstream flog(log_file.string()); + flog << cmd << endl; + flog.close(); + + // TODO: Replace system by something else to handle redirection for windows + int ret = system(cmd.c_str()); + + // TODO: better error handling (display log ?) + if(ret != 0){ + // Run crahed + //throw Exception("Meshing failed"); + std::cerr << "Issue with command: " << std::endl; + std::cerr << cmd << std::endl; + return false; + } + + aMesh.Lock(); + std::ifstream df(new_element_file.string(), ios::binary); + + int Netgen_NbOfNodes; + int Netgen_NbOfNodesNew; + int Netgen_NbOfTria; + double Netgen_point[3]; + int Netgen_triangle[3]; + int nodeID; + + SMESH_MesherHelper helper(aMesh); + // This function is necessary so that SetElementOnShape works + int _quadraticMesh = helper.IsQuadraticSubMesh(aShape); + helper.SetElementsOnShape( true ); + + // Number of nodes in intial mesh + df.read((char*) &Netgen_NbOfNodes, sizeof(int)); + // Number of nodes added by netgen + df.read((char*) &Netgen_NbOfNodesNew, sizeof(int)); + + // Filling nodevec (correspondence netgen numbering mesh numbering) + vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); + for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) + { + //Id of the point + df.read((char*) &nodeID, sizeof(int)); + nodeVec.at(nodeIndex) = nullptr; + SMDS_NodeIteratorPtr iteratorNode = aMesh.GetMeshDS()->nodesIterator(); + while(iteratorNode->more()){ + const SMDS_MeshNode* node = iteratorNode->next(); + if(node->GetID() == nodeID){ + nodeVec.at(nodeIndex) = node; + break; + } + } + if(nodeVec.at(nodeIndex) == nullptr){ + std::cout << "Error could not identify id"; + return false; + } + } + + // Add new points and update nodeVec + for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) + { + df.read((char *) &Netgen_point, sizeof(double)*3); + + nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], + Netgen_point[1], + Netgen_point[2]); + } + + // Add tetrahedrons + df.read((char*) &Netgen_NbOfTria, sizeof(int)); + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTria; ++elemIndex ) + { + df.read((char*) &Netgen_triangle, sizeof(int)*3); + helper.AddFace (nodeVec.at( Netgen_triangle[0] ), + nodeVec.at( Netgen_triangle[1] ), + nodeVec.at( Netgen_triangle[2] )); + } + df.close(); + + aMesh.Unlock(); + + return true; +} //============================================================================= /*! *Here we are going to use the NETGEN mesher @@ -229,29 +453,23 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh& aMesh, bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { - aMesh.Lock(); - SMESH_Hypothesis::Hypothesis_Status hypStatus; - this->CheckHypothesis(aMesh, aShape, hypStatus); - aMesh.Unlock(); - netgen::MeshingParameters mparam; - int id_mparam = mparam_provider.take(mparam); + if(aMesh.IsParallel()) + return RemoteCompute(aMesh, aShape); netgen::multithread.terminate = 0; - //netgen::multithread.task = "Surface meshing"; + netgen::multithread.task = "Surface meshing"; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); SMESH_MesherHelper helper(aMesh); helper.SetElementsOnShape( true ); - NETGENPlugin_NetgenLibWrapper *ngLib; - int id_ngLib = nglib_provider.take(&ngLib); - ngLib->_isComputeOk = false; + NETGENPlugin_NetgenLibWrapper ngLib; + ngLib._isComputeOk = false; netgen::Mesh ngMeshNoLocSize; - netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib->_ngMesh, & ngMeshNoLocSize }; - netgen::OCCGeometry *occgeoComm; - int id_occgeoComm = occgeom_provider.take(&occgeoComm); + netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh, & ngMeshNoLocSize }; + netgen::OCCGeometry occgeoComm; // min / max sizes are set as follows: // if ( _hypParameters ) @@ -265,21 +483,18 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, // else // min = aMesher.GetDefaultMinSize() // max = max segment len of a FACE - aMesh.Lock(); NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false); - // TODO: Only valid for NETGEN2D_Only - aMesher.SetDefaultParameters(mparam); - aMesher.SetParameters( _hypParameters, mparam ); // _hypParameters -> mparam + aMesher.SetParameters( _hypParameters ); // _hypParameters -> netgen::mparam const bool toOptimize = _hypParameters ? _hypParameters->GetOptimize() : true; if ( _hypMaxElementArea ) { - mparam.maxh = sqrt( 2. * _hypMaxElementArea->GetMaxArea() / sqrt(3.0) ); + netgen::mparam.maxh = sqrt( 2. * _hypMaxElementArea->GetMaxArea() / sqrt(3.0) ); } if ( _hypQuadranglePreference ) - mparam.quad = true; + netgen::mparam.quad = true; // local size is common for all FACEs in aShape? - const bool isCommonLocalSize = ( !_hypLengthFromEdges && !_hypMaxElementArea && mparam.uselocalh ); + const bool isCommonLocalSize = ( !_hypLengthFromEdges && !_hypMaxElementArea && netgen::mparam.uselocalh ); const bool isDefaultHyp = ( !_hypLengthFromEdges && !_hypMaxElementArea && !_hypParameters ); aMesh.Unlock(); @@ -287,15 +502,15 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, if ( isCommonLocalSize ) // compute common local size in ngMeshes[0] { //list< SMESH_subMesh* > meshedSM[4]; --> all sub-shapes are added to occgeoComm - aMesher.PrepareOCCgeometry( *occgeoComm, aShape, aMesh );//, meshedSM ); + aMesher.PrepareOCCgeometry( occgeoComm, aShape, aMesh );//, meshedSM ); // local size set at MESHCONST_ANALYSE step depends on // minh, face_maxh, grading and curvaturesafety; find minh if not set by the user - if ( !_hypParameters || mparam.minh < DBL_MIN ) + if ( !_hypParameters || netgen::mparam.minh < DBL_MIN ) { if ( !_hypParameters ) - mparam.maxh = occgeoComm->GetBoundingBox().Diam() / 3.; - mparam.minh = aMesher.GetDefaultMinSize( aShape, mparam.maxh ); + netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam() / 3.; + netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh ); } // set local size depending on curvature and NOT closeness of EDGEs #ifdef NETGEN_V6 @@ -303,19 +518,19 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, #else const double factor = netgen::occparam.resthcloseedgefac; netgen::occparam.resthcloseedgeenable = false; - netgen::occparam.resthcloseedgefac = 1.0 + mparam.grading; + netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading; #endif - occgeoComm->face_maxh = mparam.maxh; + occgeoComm.face_maxh = netgen::mparam.maxh; #ifdef NETGEN_V6 netgen::OCCParameters occparam; - netgen::OCCSetLocalMeshSize( *occgeoComm, *ngMeshes[0], mparam, occparam ); + netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0], netgen::mparam, occparam ); #else aMesh.Lock(); - netgen::OCCSetLocalMeshSize( *occgeoComm, *ngMeshes[0] ); + netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] ); aMesh.Unlock(); #endif - occgeoComm->emap.Clear(); - occgeoComm->vmap.Clear(); + occgeoComm.emap.Clear(); + occgeoComm.vmap.Clear(); // set local size according to size of existing segments TopTools_IndexedMapOfShape edgeMap; @@ -340,15 +555,15 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } // set local size defined on shapes - aMesher.SetLocalSize( *occgeoComm, *ngMeshes[0] ); - aMesher.SetLocalSizeForChordalError( *occgeoComm, *ngMeshes[0] ); + aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] ); + aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMeshes[0] ); try { - ngMeshes[0]->LoadLocalMeshSize( mparam.meshsizefilename ); + ngMeshes[0]->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); } catch (NgException & ex) { return error( COMPERR_BAD_PARMETERS, ex.What() ); } } - mparam.uselocalh = toOptimize; // restore as it is used at surface optimization + netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization // ================== // Loop on all FACEs // ================== @@ -414,7 +629,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } if ( nbSegments ) edgeLength /= double( nbSegments ); - mparam.maxh = edgeLength; + netgen::mparam.maxh = edgeLength; } else if ( isDefaultHyp ) { @@ -434,29 +649,28 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } } edgeLength = sqrt( maxSeg2 ) * 1.05; - mparam.maxh = edgeLength; + netgen::mparam.maxh = edgeLength; } - if ( mparam.maxh < DBL_MIN ) - mparam.maxh = occgeoComm->GetBoundingBox().Diam(); + if ( netgen::mparam.maxh < DBL_MIN ) + netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam(); if ( !isCommonLocalSize ) { - mparam.minh = aMesher.GetDefaultMinSize( F, mparam.maxh ); + netgen::mparam.minh = aMesher.GetDefaultMinSize( F, netgen::mparam.maxh ); } } // prepare occgeom - netgen::OCCGeometry *occgeom; - int id_occgeom = occgeom_provider.take(&occgeom); - occgeom->shape = F; - occgeom->fmap.Add( F ); - occgeom->CalcBoundingBox(); - occgeom->facemeshstatus.SetSize(1); - occgeom->facemeshstatus = 0; - occgeom->face_maxh_modified.SetSize(1); - occgeom->face_maxh_modified = 0; - occgeom->face_maxh.SetSize(1); - occgeom->face_maxh = mparam.maxh; + netgen::OCCGeometry occgeom; + occgeom.shape = F; + occgeom.fmap.Add( F ); + occgeom.CalcBoundingBox(); + occgeom.facemeshstatus.SetSize(1); + occgeom.facemeshstatus = 0; + occgeom.face_maxh_modified.SetSize(1); + occgeom.face_maxh_modified = 0; + occgeom.face_maxh.SetSize(1); + occgeom.face_maxh = netgen::mparam.maxh; // ------------------------- // Fill netgen mesh @@ -477,28 +691,28 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, if ( iLoop == NO_LOC_SIZE ) { - ngMesh->SetGlobalH ( mparam.maxh ); - ngMesh->SetMinimalH( mparam.minh ); - Box<3> bb = occgeom->GetBoundingBox(); + ngMesh->SetGlobalH ( netgen::mparam.maxh ); + ngMesh->SetMinimalH( netgen::mparam.minh ); + Box<3> bb = occgeom.GetBoundingBox(); bb.Increase (bb.Diam()/10); - ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading); - aMesher.SetLocalSize( *occgeom, *ngMesh ); - aMesher.SetLocalSizeForChordalError( *occgeoComm, *ngMesh ); + ngMesh->SetLocalH (bb.PMin(), bb.PMax(), netgen::mparam.grading); + aMesher.SetLocalSize( occgeom, *ngMesh ); + aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMesh ); try { - ngMesh->LoadLocalMeshSize( mparam.meshsizefilename ); + ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); } catch (NgException & ex) { return error( COMPERR_BAD_PARMETERS, ex.What() ); } } nodeVec.clear(); - faceErr = aMesher.AddSegmentsToMesh( *ngMesh, *occgeom, wires, helper, nodeVec, + faceErr = aMesher.AddSegmentsToMesh( *ngMesh, occgeom, wires, helper, nodeVec, /*overrideMinH=*/!_hypParameters); if ( faceErr && !faceErr->IsOK() ) break; //if ( !isCommonLocalSize ) - //limitSize( ngMesh, mparam.maxh * 0.8); + //limitSize( ngMesh, netgen::mparam.maxh * 0.8); // ------------------------- // Generate surface mesh @@ -510,7 +724,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, SMESH_Comment str; try { OCC_CATCH_SIGNALS; - err = ngLib->GenerateMesh(*occgeom, startWith, endWith, ngMesh, mparam); + err = ngLib.GenerateMesh(occgeom, startWith, endWith, ngMesh); if ( netgen::multithread.terminate ) return false; if ( err ) @@ -532,12 +746,12 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } if ( err ) { - if ( aMesher.FixFaceMesh( *occgeom, *ngMesh, 1 )) + if ( aMesher.FixFaceMesh( occgeom, *ngMesh, 1 )) break; if ( iLoop == LOC_SIZE ) { - mparam.minh = mparam.maxh; - mparam.maxh = 0; + netgen::mparam.minh = netgen::mparam.maxh; + netgen::mparam.maxh = 0; for ( size_t iW = 0; iW < wires.size(); ++iW ) { StdMeshers_FaceSidePtr wire = wires[ iW ]; @@ -548,13 +762,13 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, netgen::Point3d np( p.X(),p.Y(),p.Z()); double segLen = p.Distance( uvPtVec[ iP-1 ].node ); double size = ngMesh->GetH( np ); - mparam.minh = Min( mparam.minh, size ); - mparam.maxh = Max( mparam.maxh, segLen ); + netgen::mparam.minh = Min( netgen::mparam.minh, size ); + netgen:: mparam.maxh = Max( netgen::mparam.maxh, segLen ); } } //cerr << "min " << mparam.minh << " max " << mparam.maxh << endl; - mparam.minh *= 0.9; - mparam.maxh *= 1.1; + netgen::mparam.minh *= 0.9; + netgen::mparam.maxh *= 1.1; continue; } else @@ -563,10 +777,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } } - occgeom_provider.release(id_occgeoComm, true); - occgeom_provider.release(id_occgeom, true); - mparam_provider.release(id_mparam); - aMesh.Lock(); // ---------------------------------------------------- // Fill the SMESHDS with the generated nodes and faces // ---------------------------------------------------- @@ -616,9 +826,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, break; } // two attempts } // loop on FACEs - aMesh.Unlock(); - nglib_provider.release(id_ngLib, true); - return true; } diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx index a5d5812..b1361ed 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx @@ -24,15 +24,14 @@ #ifndef _NETGENPlugin_NETGEN_2D_ONLY_HXX_ #define _NETGENPlugin_NETGEN_2D_ONLY_HXX_ -#include "NETGENPlugin_Provider.hxx" - #include #include class StdMeshers_MaxElementArea; class StdMeshers_LengthFromEdges; class NETGENPlugin_Hypothesis_2D; -class NETGENPlugin_NetgenLibWrapper; +class NETGENPlugin_Hypothesis; +class netgen_params; /*! * \brief Mesher generating 2D elements on a geometrical face taking @@ -52,6 +51,16 @@ public: const TopoDS_Shape& aShape, Hypothesis_Status& aStatus); + void exportElementOrientation(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + netgen_params& aParams, + const std::string output_file); + + void FillParameters(const NETGENPlugin_Hypothesis* hyp, + netgen_params &aParams); + + virtual bool RemoteCompute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape); virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); @@ -69,10 +78,6 @@ protected: const NETGENPlugin_Hypothesis_2D* _hypParameters; double _progressByTic; - - Provider mparam_provider; - ProviderPtr occgeom_provider; - ProviderPtr nglib_provider; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index 36ec441..45c8171 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -231,7 +231,7 @@ void NETGENPlugin_NETGEN_3D::FillParameters(const NETGENPlugin_Hypothesis* hyp, #endif } -// wirte in a binary file the orientation for each 2D element of the mesh +// write in a binary file the orientation for each 2D element of the mesh void NETGENPlugin_NETGEN_3D::exportElementOrientation(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, netgen_params& aParams, @@ -294,8 +294,13 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { aMesh.Lock(); + auto time0 = std::chrono::high_resolution_clock::now(); SMESH_Hypothesis::Hypothesis_Status hypStatus; CheckHypothesis(aMesh, aShape, hypStatus); + auto time1 = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(time1-time0); + std::cout << "Time for check_hypo: " << elapsed.count() * 1e-9 << std::endl; + // Temporary folder for run fs::path tmp_folder = aMesh.tmp_folder / fs::unique_path(fs::path("Volume-%%%%-%%%%")); @@ -315,14 +320,24 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, //Writing Shape export_shape(shape_file.string(), aShape); + auto time2 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time2-time1); + std::cout << "Time for export_shape: " << elapsed.count() * 1e-9 << std::endl; + //Writing hypo netgen_params aParams; FillParameters(_hypParameters, aParams); export_netgen_params(param_file.string(), aParams); + auto time3 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time3-time2); + std::cout << "Time for fill+export param: " << elapsed.count() * 1e-9 << std::endl; // Exporting element orientation exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); + auto time4 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time4-time3); + std::cout << "Time for exportElemnOrient: " << elapsed.count() * 1e-9 << std::endl; aMesh.Unlock(); // Calling run_mesher @@ -353,17 +368,18 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, // TODO: Replace system by something else to handle redirection for windows int ret = system(cmd.c_str()); + auto time5 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time5-time4); + std::cout << "Time for exec of run_mesher: " << elapsed.count() * 1e-9 << std::endl; // TODO: better error handling (display log ?) if(ret != 0){ // Run crahed - //throw Exception("Meshing failed"); std::cerr << "Issue with command: " << std::endl; std::cerr << cmd << std::endl; return false; } - aMesh.Lock(); std::ifstream df(new_element_file.string(), ios::binary); @@ -386,47 +402,48 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, // Filling nodevec (correspondence netgen numbering mesh numbering) vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); + //vector nodeTmpVec ( Netgen_NbOfNodesNew + 1 ); + SMESHDS_Mesh * meshDS = helper.GetMeshDS(); for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) { //Id of the point df.read((char*) &nodeID, sizeof(int)); - nodeVec.at(nodeIndex) = nullptr; - SMDS_NodeIteratorPtr iteratorNode = aMesh.GetMeshDS()->nodesIterator(); - while(iteratorNode->more()){ - const SMDS_MeshNode* node = iteratorNode->next(); - if(node->GetID() == nodeID){ - nodeVec.at(nodeIndex) = node; - break; - } - } - if(nodeVec.at(nodeIndex) == nullptr){ - std::cout << "Error could not identify id"; - return false; - } + nodeVec.at(nodeIndex) = meshDS->FindNode(nodeID); } + auto time6 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time6-time5); + std::cout << "Time for exec of nodeVec: " << elapsed.count() * 1e-9 << std::endl; + + // Add new points and update nodeVec for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) { df.read((char *) &Netgen_point, sizeof(double)*3); nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], - Netgen_point[1], - Netgen_point[2]); + Netgen_point[1], + Netgen_point[2]); } // Add tetrahedrons df.read((char*) &Netgen_NbOfTetra, sizeof(int)); + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) { df.read((char*) &Netgen_tetrahedron, sizeof(int)*4); - helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), - nodeVec.at( Netgen_tetrahedron[1] ), - nodeVec.at( Netgen_tetrahedron[2] ), - nodeVec.at( Netgen_tetrahedron[3] )); + helper.AddVolume( + nodeVec.at( Netgen_tetrahedron[0] ), + nodeVec.at( Netgen_tetrahedron[1] ), + nodeVec.at( Netgen_tetrahedron[2] ), + nodeVec.at( Netgen_tetrahedron[3] )); } df.close(); + auto time7 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time7-time6); + std::cout << "Time for exec of add_in_mesh: " << elapsed.count() * 1e-9 << std::endl; + fs::remove_all(tmp_folder); aMesh.Unlock(); return true; @@ -443,6 +460,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, { if(aMesh.IsParallel()) return RemoteCompute(aMesh, aShape); + auto time0 = std::chrono::high_resolution_clock::now(); netgen::multithread.terminate = 0; netgen::multithread.task = "Volume meshing"; @@ -597,6 +615,9 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, // ------------------------- // Generate the volume mesh // ------------------------- + auto time1 = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(time1-time0); + std::cout << "Time for seq:fill_in_ngmesh: " << elapsed.count() * 1e-9 << std::endl; return (ngLib._isComputeOk = compute( aMesh, helper, nodeVec, ngLib )); } @@ -684,6 +705,8 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, vector< const SMDS_MeshNode* >& nodeVec, NETGENPlugin_NetgenLibWrapper& ngLib) { + auto time0 = std::chrono::high_resolution_clock::now(); + netgen::multithread.terminate = 0; netgen::Mesh* ngMesh = ngLib._ngMesh; @@ -746,6 +769,7 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, try { OCC_CATCH_SIGNALS; + auto time0 = std::chrono::high_resolution_clock::now(); ngLib.CalcLocalH(ngMesh); err = ngLib.GenerateMesh(occgeo, startWith, endWith); @@ -779,6 +803,9 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, str << " at " << netgen::multithread.task; error(str); } + auto time1 = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(time1-time0); + std::cout << "Time for seq:compute: " << elapsed.count() * 1e-9 << std::endl; int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); @@ -825,6 +852,10 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, } } } + auto time2 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time2-time1); + std::cout << "Time for seq:compute: " << elapsed.count() * 1e-9 << std::endl; + return !err; } diff --git a/src/NETGENPlugin/netgen_mesher.cxx b/src/NETGENPlugin/netgen_mesher.cxx index 6b15fb0..2969dba 100644 --- a/src/NETGENPlugin/netgen_mesher.cxx +++ b/src/NETGENPlugin/netgen_mesher.cxx @@ -35,9 +35,11 @@ #include #include namespace fs = std::filesystem; +#include // SMESH include #include +#include #include #include #include @@ -48,6 +50,8 @@ namespace fs = std::filesystem; #include #include #include +#include + // NETGENPlugin // #include @@ -72,6 +76,7 @@ namespace fs = std::filesystem; #define OCCGEOMETRY #endif #include +#include #ifdef NETGEN_V5 #include @@ -86,21 +91,28 @@ namespace nglib { namespace netgen { NETGENPLUGIN_DLL_HEADER + extern MeshingParameters mparam; NETGENPLUGIN_DLL_HEADER extern volatile multithreadt multithread; NETGENPLUGIN_DLL_HEADER extern bool merge_solids; + +#ifdef NETGEN_V5 + extern void OCCSetLocalMeshSize(OCCGeometry & geom, Mesh & mesh); +#endif } using namespace nglib; -int error(int error_type, std::string msg){ +int error(int error_type, std::string msg) +{ std::cerr << msg << std::endl; return error_type; }; -int error(const SMESH_Comment& comment){ +int error(const SMESH_Comment& comment) +{ return error(1, "SMESH_Comment error: "+comment); }; @@ -110,12 +122,16 @@ int error(const SMESH_Comment& comment){ * @param aParams Internal structure of parameters * @param mparams Netgen strcuture of parameters */ -void set_netgen_parameters(netgen_params& aParams){ +void set_netgen_parameters(netgen_params& aParams) +{ // Default parameters #ifdef NETGEN_V6 - netgen::mparam.nthreads = std::thread::hardware_concurrency(); + //netgen::mparam.nthreads = std::thread::hardware_concurrency(); + netgen::mparam.nthreads = 2; + //netgen::mparam.parallel_meshing = false; + if ( getenv( "SALOME_NETGEN_DISABLE_MULTITHREADING" )) { @@ -154,7 +170,7 @@ void set_netgen_parameters(netgen_params& aParams){ } /** - * @brief compute mesh with netgen + * @brief compute mesh with netgen3d * * @param input_mesh_file Input Mesh file * @param shape_file Shape file @@ -171,8 +187,9 @@ int netgen3d(const std::string input_mesh_file, const std::string element_orientation_file, const std::string new_element_file, bool output_mesh, - const std::string output_mesh_file){ - + const std::string output_mesh_file) +{ + auto time0 = std::chrono::high_resolution_clock::now(); // Importing mesh SMESH_Gen gen; @@ -181,35 +198,49 @@ int netgen3d(const std::string input_mesh_file, std::string mesh_name = "Maillage_1"; import_mesh(input_mesh_file, *myMesh, mesh_name); + auto time1 = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(time1-time0); + std::cout << "Time for import_mesh: " << elapsed.count() * 1e-9 << std::endl; // Importing shape TopoDS_Shape myShape; import_shape(shape_file, myShape); + auto time2 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time2-time1); + std::cout << "Time for import_shape: " << elapsed.count() * 1e-9 << std::endl; // Importing hypothesis - //TODO: make it netgen_params myParams; import_netgen_params(hypo_file, myParams); + auto time3 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time3-time2); + std::cout << "Time for import_netgen_param: " << elapsed.count() * 1e-9 << std::endl; std::cout << "Meshing with netgen3d" << std::endl; int ret = netgen3d(myShape, *myMesh, myParams, new_element_file, element_orientation_file, output_mesh); + if(!ret){ std::cout << "Meshing failed" << std::endl; return ret; } - if(output_mesh) + if(output_mesh){ + auto time4 = std::chrono::high_resolution_clock::now(); export_mesh(output_mesh_file, *myMesh, mesh_name); + auto time5 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time5-time4); + std::cout << "Time for export_mesh: " << elapsed.count() * 1e-9 << std::endl; + } return ret; } /** - * @brief Compute aShape within aMesh using netgen + * @brief Compute aShape within aMesh using netgen3d * * @param aShape the shape * @param aMesh the mesh @@ -220,7 +251,10 @@ int netgen3d(const std::string input_mesh_file, */ int netgen3d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, std::string new_element_file, std::string element_orientation_file, - bool output_mesh){ + bool output_mesh) +{ + + auto time0 = std::chrono::high_resolution_clock::now(); netgen::multithread.terminate = 0; netgen::multithread.task = "Volume meshing"; @@ -298,8 +332,6 @@ int netgen3d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, // Adding elements from Mesh SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Face); - int nbedge = meshDS->NbEdges(); - int nbface = meshDS->NbFaces(); bool isRev; bool isInternalFace = false; @@ -309,7 +341,6 @@ int netgen3d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, { // check mesh face const SMDS_MeshElement* elem = iteratorElem->next(); - int tmp = elem->GetShapeID(); if ( !elem ) return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); if ( elem->NbCornerNodes() != 3 ) @@ -387,6 +418,9 @@ int netgen3d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, // internals); //} } + auto time1 = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(time1-time0); + std::cout << "Time for fill_in_ngmesh: " << elapsed.count() * 1e-9 << std::endl; // ------------------------- // Generate the volume mesh @@ -454,7 +488,7 @@ int netgen3d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, OCC_CATCH_SIGNALS; ngLib.CalcLocalH(ngMesh); - err = ngLib.GenerateMesh(occgeo, startWith, endWith, ngMesh, netgen::mparam); + err = ngLib.GenerateMesh(occgeo, startWith, endWith, ngMesh); if(netgen::multithread.terminate) return false; @@ -499,6 +533,9 @@ int netgen3d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, if ( ce && ce->HasBadElems() ) return error( ce ); } + auto time2 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time2-time1); + std::cout << "Time for netgen_compute: " << elapsed.count() * 1e-9 << std::endl; bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built if ( isOK ) @@ -536,6 +573,10 @@ int netgen3d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, } df.close(); } + auto time3 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time3-time2); + std::cout << "Time for write_new_elem: " << elapsed.count() * 1e-9 << std::endl; + // Adding new files in aMesh as well if ( output_mesh ) @@ -569,7 +610,517 @@ int netgen3d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, { } } + auto time4 = std::chrono::high_resolution_clock::now(); + elapsed = std::chrono::duration_cast(time4-time3); + std::cout << "Time for add_element_to_smesh: " << elapsed.count() * 1e-9 << std::endl; + } return !err; +} + +/** + * @brief compute mesh with netgen2d + * + * @param input_mesh_file Input Mesh file + * @param shape_file Shape file + * @param hypo_file Parameter file + * @param new_element_file Binary file containing new nodes and new element info + * @param output_mesh If true will export mesh into output_mesh_file + * @param output_mesh_file Output Mesh file + * + * @return error code + */ +int netgen2d(const std::string input_mesh_file, + const std::string shape_file, + const std::string hypo_file, + const std::string element_orientation_file, + const std::string new_element_file, + bool output_mesh, + const std::string output_mesh_file) +{ + + // Importing mesh + SMESH_Gen gen; + + SMESH_Mesh *myMesh = gen.CreateMesh(false); + //TODO: To define + std::string mesh_name = "Maillage_1"; + + import_mesh(input_mesh_file, *myMesh, mesh_name); + + // Importing shape + TopoDS_Shape myShape; + import_shape(shape_file, myShape); + + // Importing hypothesis + netgen_params myParams; + + import_netgen_params(hypo_file, myParams); + + std::cout << "Meshing with netgen3d" << std::endl; + int ret = netgen2d(myShape, *myMesh, myParams, + new_element_file, element_orientation_file, + output_mesh); + + if(!ret){ + std::cout << "Meshing failed" << std::endl; + return ret; + } + + if(output_mesh) + export_mesh(output_mesh_file, *myMesh, mesh_name); + + return ret; +} + +/** + * @brief Compute aShape within aMesh using netgen2d + * + * @param aShape the shape + * @param aMesh the mesh + * @param aParams the netgen parameters + * @param new_element_file file containing data on the new point/tetra added by netgen + * + * @return error code + */ +int netgen2d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, + std::string new_element_file, std::string element_orientation_file, + bool output_mesh) +{ + netgen::multithread.terminate = 0; + netgen::multithread.task = "Surface meshing"; + + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + SMESH_MesherHelper helper(aMesh); + helper.SetElementsOnShape( true ); + + NETGENPlugin_NetgenLibWrapper ngLib; + ngLib._isComputeOk = false; + + netgen::Mesh ngMeshNoLocSize; + netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh, & ngMeshNoLocSize }; + netgen::OCCGeometry occgeoComm; + + std::map elemOrientation; + + typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap; + typedef TNodeToIDMap::value_type TN2ID; + const int invalid_ID = -1; + int Netgen_NbOfNodes=0; + double Netgen_point[3]; + int Netgen_segment[2]; + int Netgen_triangle[3]; + + // min / max sizes are set as follows: + // if ( _hypParameters ) + // min and max are defined by the user + // else if ( aParams.has_LengthFromEdges_hyp ) + // min = aMesher.GetDefaultMinSize() + // max = average segment len of a FACE + // else if ( _hypMaxElementArea ) + // min = aMesher.GetDefaultMinSize() + // max = f( _hypMaxElementArea ) + // else + // min = aMesher.GetDefaultMinSize() + // max = max segment len of a FACE + NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false); + set_netgen_parameters( aParams ); + const bool toOptimize = aParams.optimize; + if ( aParams.has_maxelementvolume_hyp ) + { + netgen::mparam.maxh = sqrt( 2. * aParams.maxElementVolume / sqrt(3.0) ); + } + netgen::mparam.quad = aParams.quad; + + // local size is common for all FACEs in aShape? + const bool isCommonLocalSize = ( !aParams.has_LengthFromEdges_hyp && !aParams.has_maxelementvolume_hyp && netgen::mparam.uselocalh ); + const bool isDefaultHyp = ( !aParams.has_LengthFromEdges_hyp && !aParams.has_maxelementvolume_hyp && !aParams.has_netgen_param ); + + + if ( isCommonLocalSize ) // compute common local size in ngMeshes[0] + { + //list< SMESH_subMesh* > meshedSM[4]; --> all sub-shapes are added to occgeoComm + aMesher.PrepareOCCgeometry( occgeoComm, aShape, aMesh );//, meshedSM ); + + // local size set at MESHCONST_ANALYSE step depends on + // minh, face_maxh, grading and curvaturesafety; find minh if not set by the user + if ( !aParams.has_netgen_param || netgen::mparam.minh < DBL_MIN ) + { + if ( !aParams.has_netgen_param ) + netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam() / 3.; + netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh ); + } + // set local size depending on curvature and NOT closeness of EDGEs +#ifdef NETGEN_V6 + const double factor = 2; //netgen::occparam.resthcloseedgefac; +#else + const double factor = netgen::occparam.resthcloseedgefac; + netgen::occparam.resthcloseedgeenable = false; + netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading; +#endif + occgeoComm.face_maxh = netgen::mparam.maxh; +#ifdef NETGEN_V6 + netgen::OCCParameters occparam; + netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0], netgen::mparam, occparam ); +#else + netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] ); +#endif + occgeoComm.emap.Clear(); + occgeoComm.vmap.Clear(); + + // Reading list of element to integrate into netgen mesh + std::ifstream df(element_orientation_file, ios::in|ios::binary); + int nbElement; + vtkIdType id; + bool orient; + df.read((char*)&nbElement, sizeof(int)); + + for(int ielem=0;ielemelementsIterator(SMDSAbs_Edge); + while ( iteratorElem->more() ) // loop on elements on a geom face + { + const SMDS_MeshElement* seg = iteratorElem->next(); + // Keeping only element that are in the element orientation file + isIn = elemOrientation.count(seg->GetID())==1; + + if(!isIn) + continue; + + SMESH_TNodeXYZ n1 = seg->GetNode(0); + SMESH_TNodeXYZ n2 = seg->GetNode(1); + gp_XYZ p = 0.5 * ( n1 + n2 ); + netgen::Point3d pi(p.X(), p.Y(), p.Z()); + ngMeshes[0]->RestrictLocalH( pi, factor * ( n1 - n2 ).Modulus() ); + } + + // set local size defined on shapes + aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] ); + aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMeshes[0] ); + try { + ngMeshes[0]->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); + } catch (netgen::NgException & ex) { + return error( COMPERR_BAD_PARMETERS, ex.What() ); + } + } + netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization + // ================== + // Loop on all FACEs + // ================== + + vector< const SMDS_MeshNode* > nodeVec; + + // TopExp_Explorer fExp( aShape, TopAbs_FACE ); + // for ( int iF = 0; fExp.More(); fExp.Next(), ++iF ) + // { + // TopoDS_Face F = TopoDS::Face( fExp.Current() /*.Oriented( TopAbs_FORWARD )*/); + // int faceID = meshDS->ShapeToIndex( F ); + // SMESH_ComputeErrorPtr& faceErr = aMesh.GetSubMesh( F )->GetComputeError(); + + // aParams._quadraticMesh = helper.IsQuadraticSubMesh( F ); + // const bool ignoreMediumNodes = aParams._quadraticMesh; + + // // build viscous layers if required + // if ( F.Orientation() != TopAbs_FORWARD && + // F.Orientation() != TopAbs_REVERSED ) + // F.Orientation( TopAbs_FORWARD ); // avoid pb with TopAbs_INTERNAL + // SMESH_ProxyMesh::Ptr proxyMesh = StdMeshers_ViscousLayers2D::Compute( aMesh, F ); + // if ( !proxyMesh ) + // continue; + + // // ------------------------ + // // get all EDGEs of a FACE + // // ------------------------ + // TSideVector wires = + // StdMeshers_FaceSide::GetFaceWires( F, aMesh, ignoreMediumNodes, faceErr, &helper, proxyMesh ); + // if ( faceErr && !faceErr->IsOK() ) + // continue; + // size_t nbWires = wires.size(); + // if ( nbWires == 0 ) + // { + // faceErr.reset + // ( new SMESH_ComputeError + // ( COMPERR_ALGO_FAILED, "Problem in StdMeshers_FaceSide::GetFaceWires()" )); + // continue; + // } + // if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments + // { + // faceErr.reset + // ( new SMESH_ComputeError + // ( COMPERR_BAD_INPUT_MESH, SMESH_Comment("Too few segments: ")<NbSegments()) ); + // continue; + // } + + // // ---------------------- + // // compute maxh of a FACE + // // ---------------------- + + // if ( !aParams.has_netgen_param ) + // { + // double edgeLength = 0; + // if (aParams.has_LengthFromEdges_hyp ) + // { + // // compute edgeLength as an average segment length + // smIdType nbSegments = 0; + // for ( size_t iW = 0; iW < nbWires; ++iW ) + // { + // edgeLength += wires[ iW ]->Length(); + // nbSegments += wires[ iW ]->NbSegments(); + // } + // if ( nbSegments ) + // edgeLength /= double( nbSegments ); + // netgen::mparam.maxh = edgeLength; + // } + // else if ( isDefaultHyp ) + // { + // // set edgeLength by a longest segment + // double maxSeg2 = 0; + // for ( size_t iW = 0; iW < nbWires; ++iW ) + // { + // const UVPtStructVec& points = wires[ iW ]->GetUVPtStruct(); + // if ( points.empty() ) + // return error( COMPERR_BAD_INPUT_MESH ); + // gp_Pnt pPrev = SMESH_TNodeXYZ( points[0].node ); + // for ( size_t i = 1; i < points.size(); ++i ) + // { + // gp_Pnt p = SMESH_TNodeXYZ( points[i].node ); + // maxSeg2 = Max( maxSeg2, p.SquareDistance( pPrev )); + // pPrev = p; + // } + // } + // edgeLength = sqrt( maxSeg2 ) * 1.05; + // netgen::mparam.maxh = edgeLength; + // } + // if ( netgen::mparam.maxh < DBL_MIN ) + // netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam(); + + // if ( !isCommonLocalSize ) + // { + // netgen::mparam.minh = aMesher.GetDefaultMinSize( F, netgen::mparam.maxh ); + // } + // } + + + + // prepare occgeom + netgen::OCCGeometry occgeom; + occgeom.shape = aShape; + occgeom.fmap.Add( aShape ); + occgeom.CalcBoundingBox(); + occgeom.facemeshstatus.SetSize(1); + occgeom.facemeshstatus = 0; + occgeom.face_maxh_modified.SetSize(1); + occgeom.face_maxh_modified = 0; + occgeom.face_maxh.SetSize(1); + occgeom.face_maxh = netgen::mparam.maxh; + + // ------------------------- + // Fill netgen mesh + // ------------------------- + // maps nodes to ng ID + + + // MESHCONST_ANALYSE step may lead to a failure, so we make an attempt + // w/o MESHCONST_ANALYSE at the second loop + int err = 0; + enum { LOC_SIZE, NO_LOC_SIZE }; + int iLoop = isCommonLocalSize ? 0 : 1; + int faceID = occgeom.fmap.FindIndex(aShape); + int solidID = 0; + for ( ; iLoop < 2; iLoop++ ) + { + //bool isMESHCONST_ANALYSE = false; + //TODO: check how to replace that + //InitComputeError(); + + netgen::Mesh * ngMesh = ngMeshes[ iLoop ]; + ngMesh->DeleteMesh(); + + if ( iLoop == NO_LOC_SIZE ) + { + ngMesh->SetGlobalH ( netgen::mparam.maxh ); + ngMesh->SetMinimalH( netgen::mparam.minh ); + netgen::Box<3> bb = occgeom.GetBoundingBox(); + bb.Increase (bb.Diam()/10); + ngMesh->SetLocalH (bb.PMin(), bb.PMax(), netgen::mparam.grading); + aMesher.SetLocalSize( occgeom, *ngMesh ); + aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMesh ); + try { + ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); + } catch (netgen::NgException & ex) { + return error( COMPERR_BAD_PARMETERS, ex.What() ); + } + } + + TNodeToIDMap nodeToNetgenID; + + nodeVec.clear(); + ngMesh->AddFaceDescriptor( netgen::FaceDescriptor( faceID, solidID, solidID, 0 )); + // set local size according to size of existing segments + SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Edge); + while ( iteratorElem->more() ) // loop on elements on a geom face + { + const SMDS_MeshElement* elem = iteratorElem->next(); + // Keeping only element that are in the element orientation file + bool isIn = elemOrientation.count(elem->GetID())==1; + + if(!isIn) + continue; + + bool isRev = elemOrientation[elem->GetID()]; + std::cerr << isRev; + + + + for ( int iN = 0; iN < 2; ++iN ) + { + const SMDS_MeshNode* node = elem->GetNode( iN ); + const int shapeID = node->getshapeId(); + int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; + if ( ngID == invalid_ID ) + { + ngID = ++Netgen_NbOfNodes; + Netgen_point [ 0 ] = node->X(); + Netgen_point [ 1 ] = node->Y(); + Netgen_point [ 2 ] = node->Z(); + netgen::MeshPoint mp( netgen::Point<3> (node->X(), node->Y(), node->Z()) ); + ngMesh->AddPoint ( mp, 1, netgen::EDGEPOINT ); + } + Netgen_segment[ isRev ? 1-iN : iN ] = ngID; + } + // add segment + + netgen::Segment seg; + seg[0] = Netgen_segment[0]; + seg[1] = Netgen_segment[1]; + seg.edgenr = ngMesh->GetNSeg() +1; + seg.si = faceID; + + ngMesh->AddSegment(seg); + } + int nbNodes2 = ngMesh->GetNP(); + int nseg = ngMesh->GetNSeg(); + + // insert old nodes into nodeVec + nodeVec.resize( nodeToNetgenID.size() + 1, 0 ); + TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); + for ( ; n_id != nodeToNetgenID.end(); ++n_id ) + nodeVec[ n_id->second ] = n_id->first; + nodeToNetgenID.clear(); + + + //if ( !isCommonLocalSize ) + //limitSize( ngMesh, mparam.maxh * 0.8); + + // ------------------------- + // Generate surface mesh + // ------------------------- + + const int startWith = netgen::MESHCONST_MESHSURFACE; + const int endWith = toOptimize ? netgen::MESHCONST_OPTSURFACE : netgen::MESHCONST_MESHSURFACE; + + SMESH_Comment str; + try { + OCC_CATCH_SIGNALS; + err = ngLib.GenerateMesh(occgeom, startWith, endWith, ngMesh); + if ( netgen::multithread.terminate ) + return false; + if ( err ) + str << "Error in netgen::OCCGenerateMesh() at " << netgen::multithread.task; + } + catch (Standard_Failure& ex) + { + err = 1; + str << "Exception in netgen::OCCGenerateMesh()" + << " at " << netgen::multithread.task + << ": " << ex.DynamicType()->Name(); + if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) + str << ": " << ex.GetMessageString(); + } + catch (...) { + err = 1; + str << "Exception in netgen::OCCGenerateMesh()" + << " at " << netgen::multithread.task; + } + if ( err ) + { + if ( iLoop == LOC_SIZE ) + { + std::cout << "Need second run" << std::endl; + /*netgen::mparam.minh = netgen::mparam.maxh; + netgen::mparam.maxh = 0; + for ( size_t iW = 0; iW < wires.size(); ++iW ) + { + StdMeshers_FaceSidePtr wire = wires[ iW ]; + const vector& uvPtVec = wire->GetUVPtStruct(); + for ( size_t iP = 1; iP < uvPtVec.size(); ++iP ) + { + SMESH_TNodeXYZ p( uvPtVec[ iP ].node ); + netgen::Point3d np( p.X(),p.Y(),p.Z()); + double segLen = p.Distance( uvPtVec[ iP-1 ].node ); + double size = ngMesh->GetH( np ); + netgen::mparam.minh = Min( netgen::mparam.minh, size ); + netgen::mparam.maxh = Max( netgen::mparam.maxh, segLen ); + } + } + //cerr << "min " << mparam.minh << " max " << mparam.maxh << endl; + netgen::mparam.minh *= 0.9; + netgen::mparam.maxh *= 1.1; + */ + continue; + } + else + { + //faceErr.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED, str )); + } + } + + // ---------------------------------------------------- + // Fill the SMESHDS with the generated nodes and faces + // ---------------------------------------------------- + + if(output_mesh) + { + int nbNodes = ngMesh->GetNP(); + int nbFaces = ngMesh->GetNSE(); + std::cout << nbFaces << " " << nbNodes << std::endl; + + int nbInputNodes = (int) nodeVec.size()-1; + nodeVec.resize( nbNodes+1, 0 ); + + // add nodes + for ( int ngID = nbInputNodes + 1; ngID <= nbNodes; ++ngID ) + { + const netgen::MeshPoint& ngPoint = ngMesh->Point( ngID ); + SMDS_MeshNode * node = meshDS->AddNode(ngPoint(0), ngPoint(1), ngPoint(2)); + nodeVec[ ngID ] = node; + } + + // create faces + int i,j; + for ( i = 1; i <= nbFaces ; ++i ) + { + Ng_GetVolumeElement(ngLib.ngMesh(), i, Netgen_triangle); + + helper.AddFace (nodeVec.at( Netgen_triangle[0] ), + nodeVec.at( Netgen_triangle[1] ), + nodeVec.at( Netgen_triangle[2] )); + + } + } // output_mesh + + break; + } // two attempts + //} // loop on FACEs + + return true; + } \ No newline at end of file diff --git a/src/NETGENPlugin/netgen_mesher.hxx b/src/NETGENPlugin/netgen_mesher.hxx index f1e2fa9..2cf7d36 100644 --- a/src/NETGENPlugin/netgen_mesher.hxx +++ b/src/NETGENPlugin/netgen_mesher.hxx @@ -36,6 +36,20 @@ class SMESH_Mesh; class SMESH_Comment; class netgen_params; +int netgen2d(TopoDS_Shape &aShape, + SMESH_Mesh& aMesh, + netgen_params& aParams, + std::string new_element_file, + std::string element_orientation_file, + bool output_mesh); +int netgen2d(const std::string input_mesh_file, + const std::string shape_file, + const std::string hypo_file, + const std::string element_orienation_file, + const std::string new_element_file, + bool output_mesh, + const std::string output_mesh_file); + int netgen3d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, diff --git a/src/NETGENPlugin/netgen_param.cxx b/src/NETGENPlugin/netgen_param.cxx index 3a4a22b..0c69081 100644 --- a/src/NETGENPlugin/netgen_param.cxx +++ b/src/NETGENPlugin/netgen_param.cxx @@ -31,12 +31,17 @@ #include #include + +// TODO: Error handling of read/write + /** * @brief Print content of a netgen_params * * @param aParams The object to display */ void print_netgen_params(netgen_params& aParams){ + // TODO: prettier print + // TODO: Add call to print in log std::cout << "has_netgen_param: " << aParams.has_netgen_param << std::endl; std::cout << "maxh: " << aParams.maxh << std::endl; std::cout << "minh: " << aParams.minh << std::endl; @@ -57,11 +62,12 @@ void print_netgen_params(netgen_params& aParams){ std::cout << "delaunay: " << aParams.delaunay << std::endl; std::cout << "checkoverlap: " << aParams.checkoverlap << std::endl; std::cout << "checkchartboundary: " << aParams.checkchartboundary << std::endl; + std::cout << "closeedgefac: " << aParams.closeedgefac << std::endl; std::cout << "has_local_size: " << aParams.has_local_size << std::endl; std::cout << "meshsizefilename: " << aParams.meshsizefilename << std::endl; std::cout << "has_maxelementvolume_hyp: " << aParams.has_maxelementvolume_hyp << std::endl; std::cout << "maxElementVolume: " << aParams.maxElementVolume << std::endl; - std::cout << "closeedgefac: " << aParams.closeedgefac << std::endl; + std::cout << "has_LengthFromEdges_hyp: " << aParams.has_LengthFromEdges_hyp << std::endl; } /** @@ -124,6 +130,8 @@ void import_netgen_params(const std::string param_file, netgen_params& aParams){ aParams.has_maxelementvolume_hyp = std::stoi(line); std::getline(myfile, line); aParams.maxElementVolume = std::stod(line); + std::getline(myfile, line); + aParams.maxElementVolume = std::stoi(line); myfile.close(); }; @@ -161,6 +169,7 @@ void export_netgen_params(const std::string param_file, netgen_params& aParams){ myfile << aParams.meshsizefilename << std::endl; myfile << aParams.has_maxelementvolume_hyp << std::endl; myfile << aParams.maxElementVolume << std::endl; + myfile << aParams.has_LengthFromEdges_hyp << std::endl; myfile.close(); }; @@ -199,6 +208,7 @@ bool diff_netgen_params(netgen_params params1, netgen_params params2){ ret &= params1.meshsizefilename == params2.meshsizefilename; ret &= params1.has_maxelementvolume_hyp == params2.has_maxelementvolume_hyp; ret &= params1.maxElementVolume == params2.maxElementVolume; + ret &= params1.has_LengthFromEdges_hyp == params2.has_LengthFromEdges_hyp; return ret; } diff --git a/src/NETGENPlugin/netgen_param.hxx b/src/NETGENPlugin/netgen_param.hxx index fef05f8..7919837 100644 --- a/src/NETGENPlugin/netgen_param.hxx +++ b/src/NETGENPlugin/netgen_param.hxx @@ -78,6 +78,9 @@ struct netgen_params{ StdMeshers_ViscousLayers* _viscousLayersHyp=nullptr; //double _progressByTic; bool _quadraticMesh=false; + + // Params from NETGEN2D + bool has_LengthFromEdges_hyp=false; }; void print_netgen_params(netgen_params& aParams); diff --git a/src/NETGENPlugin/run_mesher.cxx b/src/NETGENPlugin/run_mesher.cxx index 5733cd0..ae9c7a6 100644 --- a/src/NETGENPlugin/run_mesher.cxx +++ b/src/NETGENPlugin/run_mesher.cxx @@ -36,6 +36,8 @@ #include #include +#include + /** * @brief Test of shape Import/Export * @@ -183,7 +185,7 @@ int main(int argc, char *argv[]){ std::cout << " ELEM_ORIENT_FILE NEW_ELEMENT_FILE OUTPUT_MESH_FILE" << std::endl; std::cout << std::endl; std::cout << "Args:" << std::endl; - std::cout << " MESHER: mesher to use from (NETGEN3D)" << std::endl; + std::cout << " MESHER: mesher to use from (NETGEN3D, NETGEN2D)" << std::endl; std::cout << " INPUT_MESH_FILE: MED File containing lower-dimension-elements already meshed" << std::endl; std::cout << " SHAPE_FILE: STEP file containing the shape to mesh" << std::endl; std::cout << " HYPO_FILE: Ascii file containint the list of parameters" << std::endl; @@ -209,6 +211,7 @@ int main(int argc, char *argv[]){ test_netgen_params(); test_netgen3d(); } else if (mesher=="NETGEN3D"){ + auto begin = std::chrono::high_resolution_clock::now(); netgen3d(input_mesh_file, shape_file, hypo_file, @@ -216,6 +219,17 @@ int main(int argc, char *argv[]){ new_element_file, output_mesh, output_mesh_file); + auto end = std::chrono::high_resolution_clock::now(); + auto elapsed = std::chrono::duration_cast(end - begin); + std::cout << "Time elapsed: " << elapsed.count()*1e-9 << std::endl; + } else if (mesher=="NETGEN2D"){ + netgen2d(input_mesh_file, + shape_file, + hypo_file, + element_orientation_file, + new_element_file, + output_mesh, + output_mesh_file); } else { std::cerr << "Unknown mesher:" << mesher << std::endl; } From 9c3bd8e9d10be490c7b68c83a99a37d686149545 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 12 Sep 2022 08:11:15 +0200 Subject: [PATCH 07/29] Renaming netgen2d/3d internal calls --- src/NETGENPlugin/netgen_mesher.cxx | 118 ++++------------------------- src/NETGENPlugin/netgen_mesher.hxx | 4 +- 2 files changed, 16 insertions(+), 106 deletions(-) diff --git a/src/NETGENPlugin/netgen_mesher.cxx b/src/NETGENPlugin/netgen_mesher.cxx index 2969dba..0f97a07 100644 --- a/src/NETGENPlugin/netgen_mesher.cxx +++ b/src/NETGENPlugin/netgen_mesher.cxx @@ -218,9 +218,9 @@ int netgen3d(const std::string input_mesh_file, std::cout << "Time for import_netgen_param: " << elapsed.count() * 1e-9 << std::endl; std::cout << "Meshing with netgen3d" << std::endl; - int ret = netgen3d(myShape, *myMesh, myParams, - new_element_file, element_orientation_file, - output_mesh); + int ret = netgen3d_internal(myShape, *myMesh, myParams, + new_element_file, element_orientation_file, + output_mesh); if(!ret){ @@ -249,9 +249,9 @@ int netgen3d(const std::string input_mesh_file, * * @return error code */ -int netgen3d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, - std::string new_element_file, std::string element_orientation_file, - bool output_mesh) +int netgen3d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, + std::string new_element_file, std::string element_orientation_file, + bool output_mesh) { auto time0 = std::chrono::high_resolution_clock::now(); @@ -659,9 +659,9 @@ int netgen2d(const std::string input_mesh_file, import_netgen_params(hypo_file, myParams); std::cout << "Meshing with netgen3d" << std::endl; - int ret = netgen2d(myShape, *myMesh, myParams, - new_element_file, element_orientation_file, - output_mesh); + int ret = netgen2d_internal(myShape, *myMesh, myParams, + new_element_file, element_orientation_file, + output_mesh); if(!ret){ std::cout << "Meshing failed" << std::endl; @@ -674,6 +674,8 @@ int netgen2d(const std::string input_mesh_file, return ret; } + +// TODO: Not working properly /** * @brief Compute aShape within aMesh using netgen2d * @@ -684,9 +686,9 @@ int netgen2d(const std::string input_mesh_file, * * @return error code */ -int netgen2d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, - std::string new_element_file, std::string element_orientation_file, - bool output_mesh) +int netgen2d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, + std::string new_element_file, std::string element_orientation_file, + bool output_mesh) { netgen::multithread.terminate = 0; netgen::multithread.task = "Surface meshing"; @@ -818,98 +820,6 @@ int netgen2d(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, vector< const SMDS_MeshNode* > nodeVec; - // TopExp_Explorer fExp( aShape, TopAbs_FACE ); - // for ( int iF = 0; fExp.More(); fExp.Next(), ++iF ) - // { - // TopoDS_Face F = TopoDS::Face( fExp.Current() /*.Oriented( TopAbs_FORWARD )*/); - // int faceID = meshDS->ShapeToIndex( F ); - // SMESH_ComputeErrorPtr& faceErr = aMesh.GetSubMesh( F )->GetComputeError(); - - // aParams._quadraticMesh = helper.IsQuadraticSubMesh( F ); - // const bool ignoreMediumNodes = aParams._quadraticMesh; - - // // build viscous layers if required - // if ( F.Orientation() != TopAbs_FORWARD && - // F.Orientation() != TopAbs_REVERSED ) - // F.Orientation( TopAbs_FORWARD ); // avoid pb with TopAbs_INTERNAL - // SMESH_ProxyMesh::Ptr proxyMesh = StdMeshers_ViscousLayers2D::Compute( aMesh, F ); - // if ( !proxyMesh ) - // continue; - - // // ------------------------ - // // get all EDGEs of a FACE - // // ------------------------ - // TSideVector wires = - // StdMeshers_FaceSide::GetFaceWires( F, aMesh, ignoreMediumNodes, faceErr, &helper, proxyMesh ); - // if ( faceErr && !faceErr->IsOK() ) - // continue; - // size_t nbWires = wires.size(); - // if ( nbWires == 0 ) - // { - // faceErr.reset - // ( new SMESH_ComputeError - // ( COMPERR_ALGO_FAILED, "Problem in StdMeshers_FaceSide::GetFaceWires()" )); - // continue; - // } - // if ( wires[0]->NbSegments() < 3 ) // ex: a circle with 2 segments - // { - // faceErr.reset - // ( new SMESH_ComputeError - // ( COMPERR_BAD_INPUT_MESH, SMESH_Comment("Too few segments: ")<NbSegments()) ); - // continue; - // } - - // // ---------------------- - // // compute maxh of a FACE - // // ---------------------- - - // if ( !aParams.has_netgen_param ) - // { - // double edgeLength = 0; - // if (aParams.has_LengthFromEdges_hyp ) - // { - // // compute edgeLength as an average segment length - // smIdType nbSegments = 0; - // for ( size_t iW = 0; iW < nbWires; ++iW ) - // { - // edgeLength += wires[ iW ]->Length(); - // nbSegments += wires[ iW ]->NbSegments(); - // } - // if ( nbSegments ) - // edgeLength /= double( nbSegments ); - // netgen::mparam.maxh = edgeLength; - // } - // else if ( isDefaultHyp ) - // { - // // set edgeLength by a longest segment - // double maxSeg2 = 0; - // for ( size_t iW = 0; iW < nbWires; ++iW ) - // { - // const UVPtStructVec& points = wires[ iW ]->GetUVPtStruct(); - // if ( points.empty() ) - // return error( COMPERR_BAD_INPUT_MESH ); - // gp_Pnt pPrev = SMESH_TNodeXYZ( points[0].node ); - // for ( size_t i = 1; i < points.size(); ++i ) - // { - // gp_Pnt p = SMESH_TNodeXYZ( points[i].node ); - // maxSeg2 = Max( maxSeg2, p.SquareDistance( pPrev )); - // pPrev = p; - // } - // } - // edgeLength = sqrt( maxSeg2 ) * 1.05; - // netgen::mparam.maxh = edgeLength; - // } - // if ( netgen::mparam.maxh < DBL_MIN ) - // netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam(); - - // if ( !isCommonLocalSize ) - // { - // netgen::mparam.minh = aMesher.GetDefaultMinSize( F, netgen::mparam.maxh ); - // } - // } - - - // prepare occgeom netgen::OCCGeometry occgeom; occgeom.shape = aShape; diff --git a/src/NETGENPlugin/netgen_mesher.hxx b/src/NETGENPlugin/netgen_mesher.hxx index 2cf7d36..b51066c 100644 --- a/src/NETGENPlugin/netgen_mesher.hxx +++ b/src/NETGENPlugin/netgen_mesher.hxx @@ -36,7 +36,7 @@ class SMESH_Mesh; class SMESH_Comment; class netgen_params; -int netgen2d(TopoDS_Shape &aShape, +int netgen2d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, std::string new_element_file, @@ -50,7 +50,7 @@ int netgen2d(const std::string input_mesh_file, bool output_mesh, const std::string output_mesh_file); -int netgen3d(TopoDS_Shape &aShape, +int netgen3d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, std::string new_element_file, From a71af09b16a712a987d182ca3533c5903076841d Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 13 Sep 2022 09:48:51 +0200 Subject: [PATCH 08/29] Adding support of number of thread for the mesher --- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 3 ++- src/NETGENPlugin/netgen_mesher.cxx | 13 ++++++++----- src/NETGENPlugin/netgen_mesher.hxx | 3 ++- src/NETGENPlugin/netgen_param.hxx | 3 +++ src/NETGENPlugin/run_mesher.cxx | 19 ++++++++++++------- 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index 45c8171..dbe1961 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -222,7 +222,7 @@ void NETGENPlugin_NETGEN_3D::FillParameters(const NETGENPlugin_Hypothesis* hyp, aParams.meshsizefilename = hyp->GetMeshSizeFile(); #else // const char* - aParams.meshsizefilename = hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str(); + aParams.meshsizefilename = hyp->GetMeshSizeFile(); #endif #ifdef NETGEN_V6 aParams.closeedgefac = 2; @@ -353,6 +353,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, + shape_file.string() + " " + param_file.string() + " " + element_orientation_file.string() + " " + + std::to_string(aMesh.GetMesherNbThreads()) + " " + new_element_file.string() + " " + std::to_string(0) + " " + output_mesh_file.string() + diff --git a/src/NETGENPlugin/netgen_mesher.cxx b/src/NETGENPlugin/netgen_mesher.cxx index 0f97a07..d5d1cf1 100644 --- a/src/NETGENPlugin/netgen_mesher.cxx +++ b/src/NETGENPlugin/netgen_mesher.cxx @@ -129,8 +129,8 @@ void set_netgen_parameters(netgen_params& aParams) #ifdef NETGEN_V6 //netgen::mparam.nthreads = std::thread::hardware_concurrency(); - netgen::mparam.nthreads = 2; - //netgen::mparam.parallel_meshing = false; + netgen::mparam.nthreads = aParams.nbThreads; + netgen::mparam.parallel_meshing = aParams.nbThreads > 1; if ( getenv( "SALOME_NETGEN_DISABLE_MULTITHREADING" )) @@ -165,7 +165,7 @@ void set_netgen_parameters(netgen_params& aParams) #else // const char* - netgen::mparam.meshsizefilename= aParams.meshsizefilename ? 0 : aParams.meshsizefilename.c_str(); + netgen::mparam.meshsizefilename= aParams.meshsizefilename.empty() ? 0 : aParams.meshsizefilename.c_str(); #endif } @@ -187,7 +187,8 @@ int netgen3d(const std::string input_mesh_file, const std::string element_orientation_file, const std::string new_element_file, bool output_mesh, - const std::string output_mesh_file) + const std::string output_mesh_file, + int nbThreads) { auto time0 = std::chrono::high_resolution_clock::now(); // Importing mesh @@ -216,6 +217,8 @@ int netgen3d(const std::string input_mesh_file, auto time3 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time3-time2); std::cout << "Time for import_netgen_param: " << elapsed.count() * 1e-9 << std::endl; + // Setting number of threads for netgen + myParams.nbThreads = nbThreads; std::cout << "Meshing with netgen3d" << std::endl; int ret = netgen3d_internal(myShape, *myMesh, myParams, @@ -1033,4 +1036,4 @@ int netgen2d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aP return true; -} \ No newline at end of file +} diff --git a/src/NETGENPlugin/netgen_mesher.hxx b/src/NETGENPlugin/netgen_mesher.hxx index b51066c..996b1ac 100644 --- a/src/NETGENPlugin/netgen_mesher.hxx +++ b/src/NETGENPlugin/netgen_mesher.hxx @@ -62,7 +62,8 @@ int netgen3d(const std::string input_mesh_file, const std::string element_orienation_file, const std::string new_element_file, bool output_mesh, - const std::string output_mesh_file); + const std::string output_mesh_file, + int nbThreads); //TODO: Tmp function replace by real error handling int error(int error_type, std::string msg); diff --git a/src/NETGENPlugin/netgen_param.hxx b/src/NETGENPlugin/netgen_param.hxx index 7919837..0958931 100644 --- a/src/NETGENPlugin/netgen_param.hxx +++ b/src/NETGENPlugin/netgen_param.hxx @@ -81,6 +81,9 @@ struct netgen_params{ // Params from NETGEN2D bool has_LengthFromEdges_hyp=false; + + // Number of threads for the mesher + int nbThreads; }; void print_netgen_params(netgen_params& aParams); diff --git a/src/NETGENPlugin/run_mesher.cxx b/src/NETGENPlugin/run_mesher.cxx index ae9c7a6..a1a1fbc 100644 --- a/src/NETGENPlugin/run_mesher.cxx +++ b/src/NETGENPlugin/run_mesher.cxx @@ -163,7 +163,8 @@ void test_netgen3d(){ "element_orient.dat", "new_element.dat", true, - "box_with3D.med"); + "box_with3D.med", + 1); // TODO: Check result } @@ -178,11 +179,12 @@ void test_netgen3d(){ */ int main(int argc, char *argv[]){ - if(argc!=9||(argc==2 && (argv[1] == "-h" || argv[1]=="--help"))){ + if(argc!=10||(argc==2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help")==0))){ std::cout << "Error in number of argument"<(end - begin); std::cout << "Time elapsed: " << elapsed.count()*1e-9 << std::endl; From 2e0b7c8b58748e44724084d2b89542ed17ffc0b9 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 13 Sep 2022 14:33:19 +0200 Subject: [PATCH 09/29] Using RAII to remove file.close --- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 133 ++++++++++---------- src/NETGENPlugin/netgen_mesher.cxx | 53 ++++---- 2 files changed, 92 insertions(+), 94 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index dbe1961..7bff3c7 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -279,15 +279,16 @@ void NETGENPlugin_NETGEN_3D::exportElementOrientation(SMESH_Mesh& aMesh, } // loop on elements on a face } // loop on faces of a SOLID or SHELL - std::ofstream df(output_file, ios::out|ios::binary); - int size=elemOrientation.size(); + { + std::ofstream df(output_file, ios::out|ios::binary); + int size=elemOrientation.size(); - df.write((char*)&size, sizeof(int)); - for(auto const& [id, orient]:elemOrientation){ - df.write((char*)&id, sizeof(vtkIdType)); - df.write((char*)&orient, sizeof(bool)); + df.write((char*)&size, sizeof(int)); + for(auto const& [id, orient]:elemOrientation){ + df.write((char*)&id, sizeof(vtkIdType)); + df.write((char*)&orient, sizeof(bool)); + } } - df.close(); } int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, @@ -363,10 +364,10 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, //std::cout << cmd << std::endl; // Writing command in log - std::ofstream flog(log_file.string()); - flog << cmd << endl; - flog.close(); - + { + std::ofstream flog(log_file.string()); + flog << cmd << endl; + } // TODO: Replace system by something else to handle redirection for windows int ret = system(cmd.c_str()); auto time5 = std::chrono::high_resolution_clock::now(); @@ -382,66 +383,62 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, } aMesh.Lock(); - std::ifstream df(new_element_file.string(), ios::binary); - - int Netgen_NbOfNodes; - int Netgen_NbOfNodesNew; - int Netgen_NbOfTetra; - double Netgen_point[3]; - int Netgen_tetrahedron[4]; - int nodeID; - - SMESH_MesherHelper helper(aMesh); - // This function - int _quadraticMesh = helper.IsQuadraticSubMesh(aShape); - helper.SetElementsOnShape( true ); - - // Number of nodes in intial mesh - df.read((char*) &Netgen_NbOfNodes, sizeof(int)); - // Number of nodes added by netgen - df.read((char*) &Netgen_NbOfNodesNew, sizeof(int)); - - // Filling nodevec (correspondence netgen numbering mesh numbering) - vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); - //vector nodeTmpVec ( Netgen_NbOfNodesNew + 1 ); - SMESHDS_Mesh * meshDS = helper.GetMeshDS(); - for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) { - //Id of the point - df.read((char*) &nodeID, sizeof(int)); - nodeVec.at(nodeIndex) = meshDS->FindNode(nodeID); + std::ifstream df(new_element_file.string(), ios::binary); + + int Netgen_NbOfNodes; + int Netgen_NbOfNodesNew; + int Netgen_NbOfTetra; + double Netgen_point[3]; + int Netgen_tetrahedron[4]; + int nodeID; + + SMESH_MesherHelper helper(aMesh); + // This function + int _quadraticMesh = helper.IsQuadraticSubMesh(aShape); + helper.SetElementsOnShape( true ); + + // Number of nodes in intial mesh + df.read((char*) &Netgen_NbOfNodes, sizeof(int)); + // Number of nodes added by netgen + df.read((char*) &Netgen_NbOfNodesNew, sizeof(int)); + + // Filling nodevec (correspondence netgen numbering mesh numbering) + vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); + //vector nodeTmpVec ( Netgen_NbOfNodesNew + 1 ); + SMESHDS_Mesh * meshDS = helper.GetMeshDS(); + for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) + { + //Id of the point + df.read((char*) &nodeID, sizeof(int)); + nodeVec.at(nodeIndex) = meshDS->FindNode(nodeID); + } + + // Add new points and update nodeVec + for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) + { + df.read((char *) &Netgen_point, sizeof(double)*3); + + nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], + Netgen_point[1], + Netgen_point[2]); + } + + // Add tetrahedrons + df.read((char*) &Netgen_NbOfTetra, sizeof(int)); + + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) + { + df.read((char*) &Netgen_tetrahedron, sizeof(int)*4); + helper.AddVolume( + nodeVec.at( Netgen_tetrahedron[0] ), + nodeVec.at( Netgen_tetrahedron[1] ), + nodeVec.at( Netgen_tetrahedron[2] ), + nodeVec.at( Netgen_tetrahedron[3] )); + } } - - auto time6 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time6-time5); - std::cout << "Time for exec of nodeVec: " << elapsed.count() * 1e-9 << std::endl; - - - // Add new points and update nodeVec - for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) - { - df.read((char *) &Netgen_point, sizeof(double)*3); - - nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], - Netgen_point[1], - Netgen_point[2]); - } - - // Add tetrahedrons - df.read((char*) &Netgen_NbOfTetra, sizeof(int)); - - for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) - { - df.read((char*) &Netgen_tetrahedron, sizeof(int)*4); - helper.AddVolume( - nodeVec.at( Netgen_tetrahedron[0] ), - nodeVec.at( Netgen_tetrahedron[1] ), - nodeVec.at( Netgen_tetrahedron[2] ), - nodeVec.at( Netgen_tetrahedron[3] )); - } - df.close(); auto time7 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time7-time6); + elapsed = std::chrono::duration_cast(time7-time5); std::cout << "Time for exec of add_in_mesh: " << elapsed.count() * 1e-9 << std::endl; fs::remove_all(tmp_folder); diff --git a/src/NETGENPlugin/netgen_mesher.cxx b/src/NETGENPlugin/netgen_mesher.cxx index d5d1cf1..d867f3b 100644 --- a/src/NETGENPlugin/netgen_mesher.cxx +++ b/src/NETGENPlugin/netgen_mesher.cxx @@ -315,23 +315,24 @@ int netgen3d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aP } // Get list of elements + their orientation from element_orientation file - std::ifstream df(element_orientation_file, ios::binary|ios::in); - int nbElement; - bool orient; - - // Warning of the use of vtkIdType (I had issue when run_mesher was compiled with internal vtk) and salome not - // Sizeof was the same but how he othered the type was different - // Maybe using another type (uint64_t) instead would be better - vtkIdType id; std::map elemOrientation; - df.read((char*)&nbElement, sizeof(int)); + { + std::ifstream df(element_orientation_file, ios::binary|ios::in); + int nbElement; + bool orient; - for(int ielem=0;ielemelementsIterator(SMDSAbs_Face); @@ -548,7 +549,7 @@ int netgen3d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aP double Netgen_point[3]; int Netgen_tetrahedron[4]; - // Writing nodevec (correspondance netgen numbering mesh numbering) + // Writing nodevec (correspondence netgen numbering mesh numbering) // Number of nodes df.write((char*) &Netgen_NbOfNodes, sizeof(int)); df.write((char*) &Netgen_NbOfNodesNew, sizeof(int)); @@ -574,7 +575,6 @@ int netgen3d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aP Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); df.write((char*) &Netgen_tetrahedron, sizeof(int)*4); } - df.close(); } auto time3 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time3-time2); @@ -775,18 +775,19 @@ int netgen2d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aP occgeoComm.vmap.Clear(); // Reading list of element to integrate into netgen mesh - std::ifstream df(element_orientation_file, ios::in|ios::binary); - int nbElement; - vtkIdType id; - bool orient; - df.read((char*)&nbElement, sizeof(int)); + { + std::ifstream df(element_orientation_file, ios::in|ios::binary); + int nbElement; + vtkIdType id; + bool orient; + df.read((char*)&nbElement, sizeof(int)); - for(int ielem=0;ielem Date: Tue, 13 Sep 2022 16:46:00 +0200 Subject: [PATCH 10/29] Renaming functions and files + minor corrections in runner_main to detect what to do --- src/NETGENPlugin/CMakeLists.txt | 19 +- ...param.cxx => NETGENPlugin_DriverParam.cxx} | 14 +- ...param.hxx => NETGENPlugin_DriverParam.hxx} | 16 +- .../NETGENPlugin_NETGEN_2D_ONLY.cxx | 15 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 26 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx | 3 +- src/NETGENPlugin/NETGENPlugin_Provider.hxx | 152 ----------- ...gen_mesher.cxx => NETGENPlugin_Runner.cxx} | 97 +++---- ...gen_mesher.hxx => NETGENPlugin_Runner.hxx} | 18 +- src/NETGENPlugin/NETGENPlugin_Runner_main.cxx | 105 ++++++++ src/NETGENPlugin/run_mesher.cxx | 242 ------------------ 11 files changed, 212 insertions(+), 495 deletions(-) rename src/NETGENPlugin/{netgen_param.cxx => NETGENPlugin_DriverParam.cxx} (95%) rename src/NETGENPlugin/{netgen_param.hxx => NETGENPlugin_DriverParam.hxx} (85%) delete mode 100644 src/NETGENPlugin/NETGENPlugin_Provider.hxx rename src/NETGENPlugin/{netgen_mesher.cxx => NETGENPlugin_Runner.cxx} (92%) rename src/NETGENPlugin/{netgen_mesher.hxx => NETGENPlugin_Runner.hxx} (85%) create mode 100644 src/NETGENPlugin/NETGENPlugin_Runner_main.cxx delete mode 100644 src/NETGENPlugin/run_mesher.cxx diff --git a/src/NETGENPlugin/CMakeLists.txt b/src/NETGENPlugin/CMakeLists.txt index 76f4e46..c97dd9b 100644 --- a/src/NETGENPlugin/CMakeLists.txt +++ b/src/NETGENPlugin/CMakeLists.txt @@ -93,9 +93,8 @@ SET(NETGENEngine_HEADERS NETGENPlugin_Mesher.hxx NETGENPlugin_Remesher_2D.hxx NETGENPlugin_Defs.hxx - NETGENPlugin_Provider.hxx - netgen_param.hxx - netgen_mesher.hxx + NETGENPlugin_DriverParam.hxx + NETGENPlugin_Runner.hxx ) # --- sources --- @@ -123,12 +122,12 @@ SET(NETGENEngine_SOURCES NETGENPlugin_SimpleHypothesis_3D_i.cxx NETGENPlugin_Remesher_2D.cxx NETGENPlugin_i.cxx - netgen_mesher.cxx - netgen_param.cxx + NETGENPlugin_Runner.cxx + NETGENPlugin_DriverParam.cxx ) -SET(Run_Mesher_SOURCES - run_mesher.cxx +SET(NetgenRunner_SOURCES + NETGENPlugin_Runner_main.cxx ) # --- scripts --- @@ -145,9 +144,9 @@ ADD_LIBRARY(NETGENEngine ${NETGENEngine_SOURCES}) TARGET_LINK_LIBRARIES(NETGENEngine ${_link_LIBRARIES} ) INSTALL(TARGETS NETGENEngine EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_LIBS}) -ADD_EXECUTABLE(run_mesher ${Run_Mesher_SOURCES}) -TARGET_LINK_LIBRARIES(run_mesher ${_link_LIBRARIES} NETGENEngine ) -INSTALL(TARGETS run_mesher EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) +ADD_EXECUTABLE(NETGENPlugin_Runner ${NetgenRunner_SOURCES}) +TARGET_LINK_LIBRARIES(NETGENPlugin_Runner ${_link_LIBRARIES} NETGENEngine ) +INSTALL(TARGETS NETGENPlugin_Runner EXPORT ${PROJECT_NAME}TargetGroup DESTINATION ${SALOME_INSTALL_BINS}) INSTALL(FILES ${NETGENEngine_HEADERS} DESTINATION ${SALOME_INSTALL_HEADERS}) diff --git a/src/NETGENPlugin/netgen_param.cxx b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx similarity index 95% rename from src/NETGENPlugin/netgen_param.cxx rename to src/NETGENPlugin/NETGENPlugin_DriverParam.cxx index 0c69081..2ddf398 100644 --- a/src/NETGENPlugin/netgen_param.cxx +++ b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx @@ -20,11 +20,11 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : netgen_param.hxx +// File : NETGENPlugin_DriverParam.hxx // Author : Yoann AUDOUIN, EDF -// Module : SMESH +// Module : NETGEN // -#include "netgen_param.hxx" +#include "NETGENPlugin_DriverParam.hxx" #include #include @@ -39,7 +39,7 @@ * * @param aParams The object to display */ -void print_netgen_params(netgen_params& aParams){ +void printNetgenParams(netgen_params& aParams){ // TODO: prettier print // TODO: Add call to print in log std::cout << "has_netgen_param: " << aParams.has_netgen_param << std::endl; @@ -76,7 +76,7 @@ void print_netgen_params(netgen_params& aParams){ * @param param_file Name of the file * @param aParams Structure to fill */ -void import_netgen_params(const std::string param_file, netgen_params& aParams){ +void importNetgenParams(const std::string param_file, netgen_params& aParams){ std::ifstream myfile(param_file); std::string line; @@ -142,7 +142,7 @@ void import_netgen_params(const std::string param_file, netgen_params& aParams){ * @param param_file the file * @param aParams the object */ -void export_netgen_params(const std::string param_file, netgen_params& aParams){ +void exportNetgenParams(const std::string param_file, netgen_params& aParams){ std::ofstream myfile(param_file); myfile << aParams.has_netgen_param << std::endl; myfile << aParams.maxh << std::endl; @@ -182,7 +182,7 @@ void export_netgen_params(const std::string param_file, netgen_params& aParams){ * @return true if the two object are identical */ -bool diff_netgen_params(netgen_params params1, netgen_params params2){ +bool diffNetgenParams(netgen_params params1, netgen_params params2){ bool ret = true; ret &= params1.maxh == params2.maxh; ret &= params1.minh == params2.minh; diff --git a/src/NETGENPlugin/netgen_param.hxx b/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx similarity index 85% rename from src/NETGENPlugin/netgen_param.hxx rename to src/NETGENPlugin/NETGENPlugin_DriverParam.hxx index 0958931..0f53512 100644 --- a/src/NETGENPlugin/netgen_param.hxx +++ b/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx @@ -20,13 +20,13 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : netgen_param.hxx +// File : NETGENPlugin_DriverParam.hxx // Author : Yoann AUDOUIN, EDF -// Module : SMESH +// Module : NETGEN // -#ifndef _NETGEN_PARAM_HXX_ -#define _NETGEN_PARAM_HXX_ +#ifndef _NETGENPLUGIN_DRIVERPARAM_HXX_ +#define _NETGENPLUGIN_DRIVERPARAM_HXX_ #include @@ -86,11 +86,11 @@ struct netgen_params{ int nbThreads; }; -void print_netgen_params(netgen_params& aParams); +void printNetgenParams(netgen_params& aParams); -void import_netgen_params(const std::string param_file, netgen_params& aParams); -void export_netgen_params(const std::string param_file, netgen_params& aParams); +void importNetgenParams(const std::string param_file, netgen_params& aParams); +void exportNetgenParams(const std::string param_file, netgen_params& aParams); -bool diff_netgen_params(netgen_params params1, netgen_params params2); +bool diffNetgenParams(netgen_params params1, netgen_params params2); #endif \ No newline at end of file diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx index 72a2e6c..36e0d84 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx @@ -25,8 +25,7 @@ #include "NETGENPlugin_Mesher.hxx" #include "NETGENPlugin_Hypothesis_2D.hxx" -#include "NETGENPlugin_Provider.hxx" -#include "netgen_param.hxx" +#include "NETGENPlugin_DriverParam.hxx" #include #include @@ -41,8 +40,8 @@ #include #include #include -#include "DriverStep.hxx" -#include "DriverMesh.hxx" +#include "SMESH_DriverStep.hxx" +#include "SMESH_DriverMesh.hxx" #include @@ -324,17 +323,17 @@ bool NETGENPlugin_NETGEN_2D_ONLY::RemoteCompute(SMESH_Mesh& aMesh, fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med"); fs::path shape_file=tmp_folder / fs::path("shape.step"); fs::path param_file=tmp_folder / fs::path("netgen2d_param.txt"); - fs::path log_file=tmp_folder / fs::path("run_mesher.log"); + fs::path log_file=tmp_folder / fs::path("run.log"); //TODO: Handle variable mesh_name std::string mesh_name = "Maillage_1"; //Writing Shape - export_shape(shape_file.string(), aShape); + exportShape(shape_file.string(), aShape); //Writing hypo netgen_params aParams; FillParameters(_hypParameters, aParams); - export_netgen_params(param_file.string(), aParams); + exportNetgenParams(param_file.string(), aParams); // Exporting element orientation exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); @@ -347,7 +346,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::RemoteCompute(SMESH_Mesh& aMesh, fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/ fs::path("bin")/ fs::path("salome")/ - fs::path("run_mesher"); + fs::path("NETGENPlugin_Runner"); cmd = run_mesher_exe.string() + " NETGEN2D " + mesh_file.string() + " " + shape_file.string() + " " diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index 7bff3c7..367c419 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -32,9 +32,7 @@ #include "NETGENPlugin_Hypothesis.hxx" -#include "DriverStep.hxx" -#include "DriverMesh.hxx" -#include "netgen_param.hxx" +#include "NETGENPlugin_DriverParam.hxx" #include #include @@ -50,6 +48,9 @@ #include #include #include +#include +#include + #include #include @@ -196,7 +197,7 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis (SMESH_Mesh& aMesh, } -void NETGENPlugin_NETGEN_3D::FillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams) +void NETGENPlugin_NETGEN_3D::fillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams) { aParams.maxh = hyp->GetMaxSize(); aParams.minh = hyp->GetMinSize(); @@ -315,21 +316,21 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med"); fs::path shape_file=tmp_folder / fs::path("shape.step"); fs::path param_file=tmp_folder / fs::path("netgen3d_param.txt"); - fs::path log_file=tmp_folder / fs::path("run_mesher.log"); + fs::path log_file=tmp_folder / fs::path("run.log"); //TODO: Handle variable mesh_name std::string mesh_name = "Maillage_1"; //Writing Shape - export_shape(shape_file.string(), aShape); + exportShape(shape_file.string(), aShape); auto time2 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time2-time1); - std::cout << "Time for export_shape: " << elapsed.count() * 1e-9 << std::endl; + std::cout << "Time for exportShape: " << elapsed.count() * 1e-9 << std::endl; //Writing hypo netgen_params aParams; - FillParameters(_hypParameters, aParams); + fillParameters(_hypParameters, aParams); - export_netgen_params(param_file.string(), aParams); + exportNetgenParams(param_file.string(), aParams); auto time3 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time3-time2); std::cout << "Time for fill+export param: " << elapsed.count() * 1e-9 << std::endl; @@ -338,7 +339,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); auto time4 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time4-time3); - std::cout << "Time for exportElemnOrient: " << elapsed.count() * 1e-9 << std::endl; + std::cout << "Time for exportElemOrient: " << elapsed.count() * 1e-9 << std::endl; aMesh.Unlock(); // Calling run_mesher @@ -348,7 +349,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/ fs::path("bin")/ fs::path("salome")/ - fs::path("run_mesher"); + fs::path("NETGENPlugin_Runner"); cmd = run_mesher_exe.string() + " NETGEN3D " + mesh_file.string() + " " + shape_file.string() + " " @@ -356,8 +357,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, + element_orientation_file.string() + " " + std::to_string(aMesh.GetMesherNbThreads()) + " " + new_element_file.string() + " " - + std::to_string(0) + " " - + output_mesh_file.string() + + + "NONE" + " >> " + log_file.string(); //std::cout << "Running command: " << std::endl; diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx index 4ae5666..9ce54df 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx @@ -31,7 +31,6 @@ #ifndef _NETGENPlugin_NETGEN_3D_HXX_ #define _NETGENPlugin_NETGEN_3D_HXX_ -#include "NETGENPlugin_Provider.hxx" #include "NETGENPlugin_Defs.hxx" #include "NETGENPlugin_Mesher.hxx" @@ -75,7 +74,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo netgen_params& aParams, const std::string output_file); - void FillParameters(const NETGENPlugin_Hypothesis* hyp, + void fillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams); int RemoteCompute(SMESH_Mesh& aMesh, diff --git a/src/NETGENPlugin/NETGENPlugin_Provider.hxx b/src/NETGENPlugin/NETGENPlugin_Provider.hxx deleted file mode 100644 index d262789..0000000 --- a/src/NETGENPlugin/NETGENPlugin_Provider.hxx +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : NETGENPlugin_Provider.hxx -// Author : Yoann AUDOUIN (EDF) -// Project : SALOME -// -#ifndef _NETGENPlugin_Provider_HXX_ -#define _NETGENPlugin_Provider_HXX_ - -#include -#include -#include -#include -#include -#include - -namespace nglib { -#include -} -#ifndef OCCGEOMETRY -#define OCCGEOMETRY -#endif -#include -#include - -template -class ProviderPtr{ - public: - - ProviderPtr(){ - for(int i=0;i_mydata[i] = nullptr; - this->_useddata[i] = false; - } - } - - int take(T** data){ - - this->_mymutex.lock(); - *data = nullptr; - for(int i=0;i_useddata[i]){ - if (this->_mydata[i] == nullptr) - this->_mydata[i] = new T(); - this->_useddata[i] = true; - *data = this->_mydata[i]; - this->_mymutex.unlock(); - return i; - } - } - this->_mymutex.unlock(); - return -1; - }; - - - bool release(int i, bool clean){ - - this->_mymutex.lock(); - - if(clean){ - delete this->_mydata[i]; - this->_mydata[i] = nullptr; - } - - this->_useddata[i] = false; - - this->_mymutex.unlock(); - - return true; - }; - - void dump(){ - std::cout << "Dumping provider:" << std::endl; - for(int i=0;i_useddata[i] << std::endl; - std::cout << " - adress: " << this->_mydata[i] << std::endl; - if (this->_mydata[i] != nullptr) - std::cout << " - i: " << this->_mydata[i]->i << " d: " << this->_mydata[i]->d << std::endl; - } - }; - - private: - std::array _mydata; - std::array _useddata; - std::mutex _mymutex; - -}; - -template -class Provider{ - public: - - Provider() = default; - - int take(T& data){ - - this->_mymutex.lock(); - for(int i=0;i_useddata[i]){ - this->_useddata[i] = true; - data = this->_mydata[i]; - this->_mymutex.unlock(); - return i; - } - } - this->_mymutex.unlock(); - return -1; - }; - - - bool release(int i){ - - this->_mymutex.lock(); - this->_useddata[i] = false; - this->_mymutex.unlock(); - - return true; - }; - - void dump(){ - std::cout << "Dumping provider:" << std::endl; - for(int i=0;i_useddata[i] << std::endl; - std::cout << " - i: " << this->_mydata[i].i << " d: " << this->_mydata[i].d << std::endl; - } - }; - - private: - std::array _mydata; - std::array _useddata; - std::mutex _mymutex; - -}; - -#endif \ No newline at end of file diff --git a/src/NETGENPlugin/netgen_mesher.cxx b/src/NETGENPlugin/NETGENPlugin_Runner.cxx similarity index 92% rename from src/NETGENPlugin/netgen_mesher.cxx rename to src/NETGENPlugin/NETGENPlugin_Runner.cxx index d867f3b..e69dcd5 100644 --- a/src/NETGENPlugin/netgen_mesher.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner.cxx @@ -20,21 +20,20 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : netgen_mesher.cxx +// File : NETGENPlugin_Runner.cxx // Author : Yoann AUDOUIN, EDF // Module : SMESH // -#include "netgen_mesher.hxx" +#include "NETGENPlugin_Runner.hxx" -#include "DriverStep.hxx" -#include "DriverMesh.hxx" -#include "netgen_param.hxx" + +#include "NETGENPlugin_DriverParam.hxx" #include #include -#include -namespace fs = std::filesystem; +#include +namespace fs = boost::filesystem; #include // SMESH include @@ -51,6 +50,8 @@ namespace fs = std::filesystem; #include #include #include +#include +#include // NETGENPlugin @@ -186,7 +187,6 @@ int netgen3d(const std::string input_mesh_file, const std::string hypo_file, const std::string element_orientation_file, const std::string new_element_file, - bool output_mesh, const std::string output_mesh_file, int nbThreads) { @@ -198,22 +198,22 @@ int netgen3d(const std::string input_mesh_file, //TODO: To define std::string mesh_name = "Maillage_1"; - import_mesh(input_mesh_file, *myMesh, mesh_name); + importMesh(input_mesh_file, *myMesh, mesh_name); auto time1 = std::chrono::high_resolution_clock::now(); auto elapsed = std::chrono::duration_cast(time1-time0); - std::cout << "Time for import_mesh: " << elapsed.count() * 1e-9 << std::endl; + std::cout << "Time for importMesh: " << elapsed.count() * 1e-9 << std::endl; // Importing shape TopoDS_Shape myShape; - import_shape(shape_file, myShape); + importShape(shape_file, myShape); auto time2 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time2-time1); - std::cout << "Time for import_shape: " << elapsed.count() * 1e-9 << std::endl; + std::cout << "Time for importShape: " << elapsed.count() * 1e-9 << std::endl; // Importing hypothesis netgen_params myParams; - import_netgen_params(hypo_file, myParams); + importNetgenParams(hypo_file, myParams); auto time3 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time3-time2); std::cout << "Time for import_netgen_param: " << elapsed.count() * 1e-9 << std::endl; @@ -221,9 +221,9 @@ int netgen3d(const std::string input_mesh_file, myParams.nbThreads = nbThreads; std::cout << "Meshing with netgen3d" << std::endl; - int ret = netgen3d_internal(myShape, *myMesh, myParams, + int ret = netgen3dInternal(myShape, *myMesh, myParams, new_element_file, element_orientation_file, - output_mesh); + !output_mesh_file.empty()); if(!ret){ @@ -231,12 +231,12 @@ int netgen3d(const std::string input_mesh_file, return ret; } - if(output_mesh){ + if(!output_mesh_file.empty()){ auto time4 = std::chrono::high_resolution_clock::now(); - export_mesh(output_mesh_file, *myMesh, mesh_name); + exportMesh(output_mesh_file, *myMesh, mesh_name); auto time5 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time5-time4); - std::cout << "Time for export_mesh: " << elapsed.count() * 1e-9 << std::endl; + std::cout << "Time for exportMesh: " << elapsed.count() * 1e-9 << std::endl; } return ret; @@ -249,10 +249,12 @@ int netgen3d(const std::string input_mesh_file, * @param aMesh the mesh * @param aParams the netgen parameters * @param new_element_file file containing data on the new point/tetra added by netgen + * @param element_orientation_file file containing data on the orientation of each element to add to netgen + * @param output_mesh if true add element created by netgen into aMesh * * @return error code */ -int netgen3d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, +int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, std::string new_element_file, std::string element_orientation_file, bool output_mesh) { @@ -317,20 +319,31 @@ int netgen3d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aP // Get list of elements + their orientation from element_orientation file std::map elemOrientation; { - std::ifstream df(element_orientation_file, ios::binary|ios::in); - int nbElement; - bool orient; + // Setting all element orientation to false if there no element orientation file + if(element_orientation_file.empty()){ + SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Face); + while ( iteratorElem->more() ) // loop on elements on a geom face + { + // check mesh face + const SMDS_MeshElement* elem = iteratorElem->next(); + elemOrientation[elem->GetID()] = false; + } + } else { + std::ifstream df(element_orientation_file, ios::binary|ios::in); + int nbElement; + bool orient; - // Warning of the use of vtkIdType (I had issue when run_mesher was compiled with internal vtk) and salome not - // Sizeof was the same but how he othered the type was different - // Maybe using another type (uint64_t) instead would be better - vtkIdType id; - df.read((char*)&nbElement, sizeof(int)); + // Warning of the use of vtkIdType (I had issue when run_mesher was compiled with internal vtk) and salome not + // Sizeof was the same but how he othered the type was different + // Maybe using another type (uint64_t) instead would be better + vtkIdType id; + df.read((char*)&nbElement, sizeof(int)); - for(int ielem=0;ielemGetID()]; @@ -542,7 +554,7 @@ int netgen3d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aP std::cout << "Time for netgen_compute: " << elapsed.count() * 1e-9 << std::endl; bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built - if ( isOK ) + if ( isOK && !new_element_file.empty() ) { std::ofstream df(new_element_file, ios::out|ios::binary); @@ -581,7 +593,7 @@ int netgen3d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aP std::cout << "Time for write_new_elem: " << elapsed.count() * 1e-9 << std::endl; - // Adding new files in aMesh as well + // Adding new elements in aMesh as well if ( output_mesh ) { double Netgen_point[3]; @@ -639,7 +651,6 @@ int netgen2d(const std::string input_mesh_file, const std::string hypo_file, const std::string element_orientation_file, const std::string new_element_file, - bool output_mesh, const std::string output_mesh_file) { @@ -650,29 +661,29 @@ int netgen2d(const std::string input_mesh_file, //TODO: To define std::string mesh_name = "Maillage_1"; - import_mesh(input_mesh_file, *myMesh, mesh_name); + importMesh(input_mesh_file, *myMesh, mesh_name); // Importing shape TopoDS_Shape myShape; - import_shape(shape_file, myShape); + importShape(shape_file, myShape); // Importing hypothesis netgen_params myParams; - import_netgen_params(hypo_file, myParams); + importNetgenParams(hypo_file, myParams); std::cout << "Meshing with netgen3d" << std::endl; - int ret = netgen2d_internal(myShape, *myMesh, myParams, + int ret = netgen2dInternal(myShape, *myMesh, myParams, new_element_file, element_orientation_file, - output_mesh); + !output_mesh_file.empty()); if(!ret){ std::cout << "Meshing failed" << std::endl; return ret; } - if(output_mesh) - export_mesh(output_mesh_file, *myMesh, mesh_name); + if(!output_mesh_file.empty()) + exportMesh(output_mesh_file, *myMesh, mesh_name); return ret; } @@ -689,7 +700,7 @@ int netgen2d(const std::string input_mesh_file, * * @return error code */ -int netgen2d_internal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, +int netgen2dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, std::string new_element_file, std::string element_orientation_file, bool output_mesh) { diff --git a/src/NETGENPlugin/netgen_mesher.hxx b/src/NETGENPlugin/NETGENPlugin_Runner.hxx similarity index 85% rename from src/NETGENPlugin/netgen_mesher.hxx rename to src/NETGENPlugin/NETGENPlugin_Runner.hxx index 996b1ac..fe4d6c9 100644 --- a/src/NETGENPlugin/netgen_mesher.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner.hxx @@ -20,13 +20,13 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// File : netgen_mesher.hxx +// File : NETGENPlugin_Runner.hxx // Author : Yoann AUDOUIN, EDF -// Module : SMESH +// Module : NETGEN // -#ifndef _NETGEN_MESHER_HXX_ -#define _NETGEN_MESHER_HXX_ +#ifndef _NETGENPLUGIN_RUNNER_HXX_ +#define _NETGENPLUGIN_RUNNER_HXX_ #include #include @@ -36,7 +36,7 @@ class SMESH_Mesh; class SMESH_Comment; class netgen_params; -int netgen2d_internal(TopoDS_Shape &aShape, +int netgen2dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, std::string new_element_file, @@ -45,12 +45,11 @@ int netgen2d_internal(TopoDS_Shape &aShape, int netgen2d(const std::string input_mesh_file, const std::string shape_file, const std::string hypo_file, - const std::string element_orienation_file, + const std::string element_orientation_file, const std::string new_element_file, - bool output_mesh, const std::string output_mesh_file); -int netgen3d_internal(TopoDS_Shape &aShape, +int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, std::string new_element_file, @@ -59,9 +58,8 @@ int netgen3d_internal(TopoDS_Shape &aShape, int netgen3d(const std::string input_mesh_file, const std::string shape_file, const std::string hypo_file, - const std::string element_orienation_file, + const std::string element_orientation_file, const std::string new_element_file, - bool output_mesh, const std::string output_mesh_file, int nbThreads); diff --git a/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx new file mode 100644 index 0000000..709e118 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx @@ -0,0 +1,105 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// File : NETGENplugin_Runnner_main.cxx +// Author : Yoann AUDOUIN, EDF +// Module : NETGEN +// + + +#include "NETGENPlugin_Runner.hxx" + +#include +#include +#include +#include + +/** + * @brief Main function + * + * @param argc Number of arguments + * @param argv Arguments + * + * @return error code + */ +int main(int argc, char *argv[]){ + + if(argc!=9||(argc==2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help")==0))){ + std::cout << "Error in number of arguments "<< argc<<" given expected 8" <(end - begin); + std::cout << "Time elapsed: " << elapsed.count()*1e-9 << std::endl; + } else if (mesher=="NETGEN2D"){ + netgen2d(input_mesh_file, + shape_file, + hypo_file, + element_orientation_file, + new_element_file, + output_mesh_file); + } else { + std::cerr << "Unknown mesher:" << mesher << std::endl; + } + return 0; +} diff --git a/src/NETGENPlugin/run_mesher.cxx b/src/NETGENPlugin/run_mesher.cxx deleted file mode 100644 index a1a1fbc..0000000 --- a/src/NETGENPlugin/run_mesher.cxx +++ /dev/null @@ -1,242 +0,0 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : run_mesher.cxx -// Author : Yoann AUDOUIN, EDF -// Module : SMESH -// - -#include "DriverStep.hxx" -#include "DriverMesh.hxx" -#include "netgen_param.hxx" -#include "netgen_mesher.hxx" - -#include -#include - -#include -#include - -#include - -/** - * @brief Test of shape Import/Export - * - * @param shape_file - */ -void test_shape(){ - - std::cout << "Testing Shape Import/Export" << std::endl; - std::string shape_file = "box.step"; - - TopoDS_Shape myShape; - - // Test 1 import -> export cmp files - std::string shape_file2 = "/tmp/shape.step"; - - import_shape(shape_file, myShape); - export_shape(shape_file2, myShape); - - assert(diff_step_file(shape_file, shape_file2)); - - // Test 2 import->export->import cmp TopoDS_Shape - std::string shape_file3 = "/tmp/shape2.step"; - TopoDS_Shape myShape1, myShape2; - - import_shape(shape_file, myShape1); - - export_shape(shape_file3, myShape1); - - import_shape(shape_file3, myShape2); - - // TODO: See why this does not work - // TShape seems to be different - //assert(myShape1.IsSame(myShape2)); - -} - -/** - * @brief test of mesh import/export - * - * @param mesh_file - */ -void test_mesh(){ - - std::cout << "Testing Mesh Import/Export" << std::endl; - std::string mesh_file = "box.med"; - SMESH_Gen gen; - - SMESH_Mesh *myMesh = gen.CreateMesh(false); - std::string mesh_name = "Maillage_1"; - - // Test 1 import -> export cmp files - std::string mesh_file2 = "/tmp/mesh.med"; - - import_mesh(mesh_file, *myMesh, mesh_name); - export_mesh(mesh_file2, *myMesh, mesh_name); - - assert(diff_med_file(mesh_file, mesh_file2, mesh_name)); - - // TODO: Compare the two med files via dump ? - - // Test 2 import->export->import cmp TopoDS_Shape - std::string mesh_file3 = "/tmp/mesh2.med"; - SMESH_Mesh *myMesh1 = gen.CreateMesh(false); - SMESH_Mesh *myMesh2 = gen.CreateMesh(false); - - import_mesh(mesh_file, *myMesh1, mesh_name); - - export_mesh(mesh_file3, *myMesh1, mesh_name); - - import_mesh(mesh_file3, *myMesh2, mesh_name); - - // TODO: Compare SMESH_Mesh - //assert(myMesh1==myMesh2); -} - -/** - * @brief Test of import/export of netgen param - * - */ -void test_netgen_params(){ - - std::string param_file = "/tmp/netgen_param.txt"; - netgen_params myParams, myParams2; - myParams.has_netgen_param = true; - myParams.maxh = 34.64; - myParams.minh = 0.14; - myParams.segmentsperedge = 15; - myParams.grading = 0.2; - myParams.curvaturesafety = 1.5; - myParams.secondorder = false; - myParams.quad = false; - myParams.optimize = true; - myParams.fineness = 5; - myParams.uselocalh = true; - myParams.merge_solids = true; - myParams.chordalError = -1; - myParams.optsteps2d = 3; - myParams.optsteps3d = 3; - myParams.elsizeweight = 0.2; - myParams.opterrpow = 2; - myParams.delaunay = true; - myParams.checkoverlap = true; - myParams.checkchartboundary = false; - myParams.closeedgefac = 2; - myParams.has_local_size = false; - myParams.meshsizefilename = ""; - myParams.has_maxelementvolume_hyp = false; - myParams.maxElementVolume = 0.0; - - export_netgen_params(param_file, myParams); - import_netgen_params(param_file, myParams2); - - assert(diff_netgen_params(myParams, myParams2)); - -}; - -void test_netgen3d(){ - - std::cout << "Testing NETGEN 3D mesher" << std::endl; - netgen3d("box_partial2D1D-2.med", - "box-2.step", - "box_param.txt", - "element_orient.dat", - "new_element.dat", - true, - "box_with3D.med", - 1); - - // TODO: Check result -} - -/** - * @brief Main function - * - * @param argc Number of arguments - * @param argv Arguments - * - * @return error code - */ -int main(int argc, char *argv[]){ - - if(argc!=10||(argc==2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help")==0))){ - std::cout << "Error in number of argument"<(end - begin); - std::cout << "Time elapsed: " << elapsed.count()*1e-9 << std::endl; - } else if (mesher=="NETGEN2D"){ - netgen2d(input_mesh_file, - shape_file, - hypo_file, - element_orientation_file, - new_element_file, - output_mesh, - output_mesh_file); - } else { - std::cerr << "Unknown mesher:" << mesher << std::endl; - } - return 0; -} From 2e8bc3b2b025120798d2d3178e949b9969f705f5 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Thu, 15 Sep 2022 11:01:41 +0200 Subject: [PATCH 11/29] Better handle of deletion of temporary folder + missing delete of temporary SMESH_Mesh --- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 1 - src/NETGENPlugin/NETGENPlugin_Runner.cxx | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index 367c419..347f4c3 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -441,7 +441,6 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, elapsed = std::chrono::duration_cast(time7-time5); std::cout << "Time for exec of add_in_mesh: " << elapsed.count() * 1e-9 << std::endl; - fs::remove_all(tmp_folder); aMesh.Unlock(); return true; diff --git a/src/NETGENPlugin/NETGENPlugin_Runner.cxx b/src/NETGENPlugin/NETGENPlugin_Runner.cxx index e69dcd5..a9b2a00 100644 --- a/src/NETGENPlugin/NETGENPlugin_Runner.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner.cxx @@ -194,7 +194,7 @@ int netgen3d(const std::string input_mesh_file, // Importing mesh SMESH_Gen gen; - SMESH_Mesh *myMesh = gen.CreateMesh(false); + std::unique_ptr myMesh(gen.CreateMesh(false)); //TODO: To define std::string mesh_name = "Maillage_1"; @@ -657,7 +657,8 @@ int netgen2d(const std::string input_mesh_file, // Importing mesh SMESH_Gen gen; - SMESH_Mesh *myMesh = gen.CreateMesh(false); + std::unique_ptr myMesh(gen.CreateMesh(false)); + //TODO: To define std::string mesh_name = "Maillage_1"; From 57061f40af4cd98d056a0d68e483ab17730333c3 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Thu, 15 Sep 2022 14:06:22 +0200 Subject: [PATCH 12/29] Switchin to QProcess instead of sytem for remote compute --- src/NETGENPlugin/CMakeLists.txt | 5 +++ src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 42 ++++++++++++++++----- 2 files changed, 37 insertions(+), 10 deletions(-) diff --git a/src/NETGENPlugin/CMakeLists.txt b/src/NETGENPlugin/CMakeLists.txt index c97dd9b..e28fea2 100644 --- a/src/NETGENPlugin/CMakeLists.txt +++ b/src/NETGENPlugin/CMakeLists.txt @@ -17,9 +17,12 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # +INCLUDE(UseQtExt) + # --- options --- # additional include directories INCLUDE_DIRECTORIES( + ${QT_INCLUDES} ${KERNEL_INCLUDE_DIRS} ${GUI_INCLUDE_DIRS} ${GEOM_INCLUDE_DIRS} @@ -35,6 +38,7 @@ INCLUDE_DIRECTORIES( # additional preprocessor / compiler flags ADD_DEFINITIONS( + ${QT_DEFINITIONS} ${OMNIORB_DEFINITIONS} ${OpenCASCADE_DEFINITIONS} ${BOOST_DEFINITIONS} @@ -66,6 +70,7 @@ SET(_link_LIBRARIES VTK::CommonCore VTK::CommonDataModel SalomeIDLNETGENPLUGIN + Qt5::Core ) # --- headers --- diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index 347f4c3..c69f50f 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -69,6 +69,9 @@ #include #include +#include +#include + #include #include namespace fs = boost::filesystem; @@ -350,6 +353,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, fs::path("bin")/ fs::path("salome")/ fs::path("NETGENPlugin_Runner"); + cmd = run_mesher_exe.string() + " NETGEN3D " + mesh_file.string() + " " + shape_file.string() + " " @@ -357,19 +361,36 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, + element_orientation_file.string() + " " + std::to_string(aMesh.GetMesherNbThreads()) + " " + new_element_file.string() + " " - + "NONE" + - " >> " + log_file.string(); - - //std::cout << "Running command: " << std::endl; - //std::cout << cmd << std::endl; - + + "NONE"; // Writing command in log { std::ofstream flog(log_file.string()); flog << cmd << endl; + flog << endl; } - // TODO: Replace system by something else to handle redirection for windows - int ret = system(cmd.c_str()); + //std::cout << "Running command: " << std::endl; + //std::cout << cmd << std::endl; + + + // Building arguments for QProcess + QString program = run_mesher_exe.c_str(); + QStringList arguments; + arguments << "NETGEN3D"; + arguments << mesh_file.c_str(); + arguments << shape_file.c_str(); + arguments << param_file.c_str(); + arguments << element_orientation_file.c_str(); + arguments << std::to_string(aMesh.GetMesherNbThreads()).c_str(); + arguments << new_element_file.c_str(); + arguments << "NONE"; + QString out_file = log_file.c_str(); + QProcess myProcess; + myProcess.setStandardOutputFile(out_file); + + myProcess.start(program, arguments); + myProcess.waitForFinished(); + int ret = myProcess.exitStatus(); + auto time5 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time5-time4); std::cout << "Time for exec of run_mesher: " << elapsed.count() * 1e-9 << std::endl; @@ -377,8 +398,9 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, // TODO: better error handling (display log ?) if(ret != 0){ // Run crahed - std::cerr << "Issue with command: " << std::endl; - std::cerr << cmd << std::endl; + std::cout << "Issue with command: " << std::endl; + std::cout << "See log for more detail: " << log_file.string() << std::endl; + std::cout << cmd << std::endl; return false; } From eb6fde768717d6141329680be7b46b05b1313394 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Thu, 15 Sep 2022 15:12:50 +0200 Subject: [PATCH 13/29] Adding support for BRep for shape --- src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx | 2 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 6 +++--- src/NETGENPlugin/NETGENPlugin_Runner.cxx | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx index 36e0d84..3212043 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx @@ -40,7 +40,7 @@ #include #include #include -#include "SMESH_DriverStep.hxx" +#include "SMESH_DriverShape.hxx" #include "SMESH_DriverMesh.hxx" diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index c69f50f..0937ca9 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include @@ -317,7 +317,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, fs::path tmp_mesh_file=tmp_folder / fs::path("tmp_mesh.med"); // TODO: Remove that file we do not use it fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med"); - fs::path shape_file=tmp_folder / fs::path("shape.step"); + fs::path shape_file=tmp_folder / fs::path("shape.brep"); fs::path param_file=tmp_folder / fs::path("netgen3d_param.txt"); fs::path log_file=tmp_folder / fs::path("run.log"); //TODO: Handle variable mesh_name @@ -399,7 +399,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, if(ret != 0){ // Run crahed std::cout << "Issue with command: " << std::endl; - std::cout << "See log for more detail: " << log_file.string() << std::endl; + std::cout << "See log for more details: " << log_file.string() << std::endl; std::cout << cmd << std::endl; return false; } diff --git a/src/NETGENPlugin/NETGENPlugin_Runner.cxx b/src/NETGENPlugin/NETGENPlugin_Runner.cxx index a9b2a00..24038db 100644 --- a/src/NETGENPlugin/NETGENPlugin_Runner.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner.cxx @@ -50,7 +50,7 @@ namespace fs = boost::filesystem; #include #include #include -#include +#include #include From 0de7ea3ca084a27f45c6f8ae66bbd316d5a5602f Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 19 Sep 2022 11:12:06 +0200 Subject: [PATCH 14/29] Now filling param _hypParameters and _stdMaxvolume --- src/NETGENPlugin/NETGENPlugin_DriverParam.cxx | 84 ++++++++----------- src/NETGENPlugin/NETGENPlugin_DriverParam.hxx | 17 ++-- src/NETGENPlugin/NETGENPlugin_Runner.cxx | 4 +- 3 files changed, 45 insertions(+), 60 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx index 2ddf398..dffeca8 100644 --- a/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx +++ b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx @@ -26,22 +26,22 @@ // #include "NETGENPlugin_DriverParam.hxx" +#include "NETGENPlugin_Hypothesis.hxx" + +#include +#include + #include #include #include #include - -// TODO: Error handling of read/write - /** * @brief Print content of a netgen_params * * @param aParams The object to display */ void printNetgenParams(netgen_params& aParams){ - // TODO: prettier print - // TODO: Add call to print in log std::cout << "has_netgen_param: " << aParams.has_netgen_param << std::endl; std::cout << "maxh: " << aParams.maxh << std::endl; std::cout << "minh: " << aParams.minh << std::endl; @@ -76,7 +76,7 @@ void printNetgenParams(netgen_params& aParams){ * @param param_file Name of the file * @param aParams Structure to fill */ -void importNetgenParams(const std::string param_file, netgen_params& aParams){ +void importNetgenParams(const std::string param_file, netgen_params& aParams, SMESH_Gen *gen){ std::ifstream myfile(param_file); std::string line; @@ -133,7 +133,36 @@ void importNetgenParams(const std::string param_file, netgen_params& aParams){ std::getline(myfile, line); aParams.maxElementVolume = std::stoi(line); - myfile.close(); + if(aParams.has_netgen_param){ + aParams._hypParameters = new NETGENPlugin_Hypothesis(0, gen); + + aParams._hypParameters->SetMaxSize(aParams.maxh); + aParams._hypParameters->SetMinSize(aParams.minh); + aParams._hypParameters->SetNbSegPerEdge(aParams.segmentsperedge); + aParams._hypParameters->SetGrowthRate(aParams.grading); + aParams._hypParameters->SetNbSegPerRadius(aParams.curvaturesafety); + aParams._hypParameters->SetSecondOrder(aParams.secondorder); + aParams._hypParameters->SetQuadAllowed(aParams.quad); + aParams._hypParameters->SetOptimize(aParams.optimize); + aParams._hypParameters->SetFineness((NETGENPlugin_Hypothesis::Fineness)aParams.fineness); + aParams._hypParameters->SetSurfaceCurvature(aParams.uselocalh); + aParams._hypParameters->SetFuseEdges(aParams.merge_solids); + aParams._hypParameters->SetChordalErrorEnabled(aParams.chordalError); + if(aParams.optimize){ + aParams._hypParameters->SetNbSurfOptSteps(aParams.optsteps2d); + aParams._hypParameters->SetNbVolOptSteps(aParams.optsteps3d); + } + aParams._hypParameters->SetElemSizeWeight(aParams.elsizeweight); + aParams._hypParameters->SetWorstElemMeasure(aParams.opterrpow); + aParams._hypParameters->SetUseDelauney(aParams.delaunay); + aParams._hypParameters->SetCheckOverlapping(aParams.checkoverlap); + aParams._hypParameters->SetCheckChartBoundary(aParams.checkchartboundary); + aParams._hypParameters->SetMeshSizeFile(aParams.meshsizefilename); + } + if(aParams.has_maxelementvolume_hyp){ + aParams._hypMaxElementVolume = new StdMeshers_MaxElementVolume(1, gen); + } + // TODO: Handle viscous layer }; /** @@ -170,45 +199,4 @@ void exportNetgenParams(const std::string param_file, netgen_params& aParams){ myfile << aParams.has_maxelementvolume_hyp << std::endl; myfile << aParams.maxElementVolume << std::endl; myfile << aParams.has_LengthFromEdges_hyp << std::endl; - - myfile.close(); }; - -/** - * @brief Compares two netgen_parms object - * - * @param params1 Object 1 - * @param params2 Object 2 - - * @return true if the two object are identical - */ -bool diffNetgenParams(netgen_params params1, netgen_params params2){ - bool ret = true; - ret &= params1.maxh == params2.maxh; - ret &= params1.minh == params2.minh; - ret &= params1.segmentsperedge == params2.segmentsperedge; - ret &= params1.grading == params2.grading; - ret &= params1.curvaturesafety == params2.curvaturesafety; - ret &= params1.secondorder == params2.secondorder; - ret &= params1.quad == params2.quad; - ret &= params1.optimize == params2.optimize; - ret &= params1.fineness == params2.fineness; - ret &= params1.uselocalh == params2.uselocalh; - ret &= params1.merge_solids == params2.merge_solids; - ret &= params1.chordalError == params2.chordalError; - ret &= params1.optsteps2d == params2.optsteps2d; - ret &= params1.optsteps3d == params2.optsteps3d; - ret &= params1.elsizeweight == params2.elsizeweight; - ret &= params1.opterrpow == params2.opterrpow; - ret &= params1.delaunay == params2.delaunay; - ret &= params1.checkoverlap == params2.checkoverlap; - ret &= params1.checkchartboundary == params2.checkchartboundary; - ret &= params1.closeedgefac == params2.closeedgefac; - ret &= params1.has_local_size == params2.has_local_size; - ret &= params1.meshsizefilename == params2.meshsizefilename; - ret &= params1.has_maxelementvolume_hyp == params2.has_maxelementvolume_hyp; - ret &= params1.maxElementVolume == params2.maxElementVolume; - ret &= params1.has_LengthFromEdges_hyp == params2.has_LengthFromEdges_hyp; - - return ret; -} diff --git a/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx b/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx index 0f53512..bc05229 100644 --- a/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx +++ b/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx @@ -33,6 +33,7 @@ class NETGENPlugin_Hypothesis; class StdMeshers_MaxElementVolume; class StdMeshers_ViscousLayers; +class SMESH_Gen; struct netgen_params{ // Params from NETGENPlugin_Mesher @@ -60,7 +61,6 @@ struct netgen_params{ int closeedgefac; - // TODO: add localsize (pass through local size file ?) // True if we have a mesh size file or local size info bool has_local_size = false; std::string meshsizefilename; @@ -70,14 +70,13 @@ struct netgen_params{ bool has_maxelementvolume_hyp=false; double maxElementVolume=0.0; - // to replace - //NETGENPlugin_Hypothesis * _hypParameters=nullptr; - // to remove ? + NETGENPlugin_Hypothesis * _hypParameters=nullptr; StdMeshers_MaxElementVolume* _hypMaxElementVolume=nullptr; - // to remove ? StdMeshers_ViscousLayers* _viscousLayersHyp=nullptr; - //double _progressByTic; + double _progressByTic; bool _quadraticMesh=false; + int _error=0; + std::string _comment; // Params from NETGEN2D bool has_LengthFromEdges_hyp=false; @@ -88,9 +87,7 @@ struct netgen_params{ void printNetgenParams(netgen_params& aParams); -void importNetgenParams(const std::string param_file, netgen_params& aParams); +void importNetgenParams(const std::string param_file, netgen_params& aParams, SMESH_Gen * gen); void exportNetgenParams(const std::string param_file, netgen_params& aParams); -bool diffNetgenParams(netgen_params params1, netgen_params params2); - -#endif \ No newline at end of file +#endif diff --git a/src/NETGENPlugin/NETGENPlugin_Runner.cxx b/src/NETGENPlugin/NETGENPlugin_Runner.cxx index 24038db..43faa50 100644 --- a/src/NETGENPlugin/NETGENPlugin_Runner.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner.cxx @@ -213,7 +213,7 @@ int netgen3d(const std::string input_mesh_file, // Importing hypothesis netgen_params myParams; - importNetgenParams(hypo_file, myParams); + importNetgenParams(hypo_file, myParams, &gen); auto time3 = std::chrono::high_resolution_clock::now(); elapsed = std::chrono::duration_cast(time3-time2); std::cout << "Time for import_netgen_param: " << elapsed.count() * 1e-9 << std::endl; @@ -671,7 +671,7 @@ int netgen2d(const std::string input_mesh_file, // Importing hypothesis netgen_params myParams; - importNetgenParams(hypo_file, myParams); + importNetgenParams(hypo_file, myParams, &gen); std::cout << "Meshing with netgen3d" << std::endl; int ret = netgen2dInternal(myShape, *myMesh, myParams, From 3c4eb540f819f43f02331119f38982315465748d Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 19 Sep 2022 11:18:08 +0200 Subject: [PATCH 15/29] Refactoring of normal Compute --- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 348 ++++++++++++++------ src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx | 35 ++ 2 files changed, 283 insertions(+), 100 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index 0937ca9..f1fae5e 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -315,11 +315,12 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, fs::path element_orientation_file=tmp_folder / fs::path("element_orientation.dat"); fs::path new_element_file=tmp_folder / fs::path("new_elements.dat"); fs::path tmp_mesh_file=tmp_folder / fs::path("tmp_mesh.med"); - // TODO: Remove that file we do not use it - fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med"); + // Not used kept for debug + //fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med"); fs::path shape_file=tmp_folder / fs::path("shape.brep"); fs::path param_file=tmp_folder / fs::path("netgen3d_param.txt"); fs::path log_file=tmp_folder / fs::path("run.log"); + fs::path cmd_file=tmp_folder / fs::path("cmd.log"); //TODO: Handle variable mesh_name std::string mesh_name = "Maillage_1"; @@ -364,7 +365,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, + "NONE"; // Writing command in log { - std::ofstream flog(log_file.string()); + std::ofstream flog(cmd_file.string()); flog << cmd << endl; flog << endl; } @@ -395,7 +396,6 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, elapsed = std::chrono::duration_cast(time5-time4); std::cout << "Time for exec of run_mesher: " << elapsed.count() * 1e-9 << std::endl; - // TODO: better error handling (display log ?) if(ret != 0){ // Run crahed std::cout << "Issue with command: " << std::endl; @@ -416,8 +416,8 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, int nodeID; SMESH_MesherHelper helper(aMesh); - // This function - int _quadraticMesh = helper.IsQuadraticSubMesh(aShape); + // This function is mandatory for setElementsOnShape to work + helper.IsQuadraticSubMesh(aShape); helper.SetElementsOnShape( true ); // Number of nodes in intial mesh @@ -474,32 +474,31 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, */ //============================================================================= -bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) -{ - if(aMesh.IsParallel()) - return RemoteCompute(aMesh, aShape); - auto time0 = std::chrono::high_resolution_clock::now(); +bool NETGENPlugin_NETGEN_3D::computeFillNgMesh( + SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + SMESH_MesherHelper &helper, + netgen_params &aParams, + int &Netgen_NbOfNodes) +{ netgen::multithread.terminate = 0; netgen::multithread.task = "Volume meshing"; - _progressByTic = -1.; + aParams._progressByTic = -1.; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - SMESH_MesherHelper helper(aMesh); - _quadraticMesh = helper.IsQuadraticSubMesh(aShape); + aParams._quadraticMesh = helper.IsQuadraticSubMesh(aShape); helper.SetElementsOnShape( true ); - int Netgen_NbOfNodes = 0; + Netgen_NbOfNodes = 0; double Netgen_point[3]; int Netgen_triangle[3]; - NETGENPlugin_NetgenLibWrapper ngLib; Ng_Mesh * Netgen_mesh = (Ng_Mesh*)ngLib._ngMesh; - // vector of nodes in which node index == netgen ID - vector< const SMDS_MeshNode* > nodeVec; { const int invalid_ID = -1; @@ -522,10 +521,10 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, bool checkReverse = ( mainType == TopAbs_COMPOUND || mainType == TopAbs_COMPSOLID ); SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); - if ( _viscousLayersHyp ) + if ( aParams._viscousLayersHyp ) { netgen::multithread.percent = 3; - proxyMesh = _viscousLayersHyp->Compute( aMesh, aShape ); + proxyMesh = aParams._viscousLayersHyp->Compute( aMesh, aShape ); if ( !proxyMesh ) return false; } @@ -553,7 +552,7 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, if ( !aSubMeshDSFace ) continue; SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - if ( _quadraticMesh && + if ( aParams._quadraticMesh && dynamic_cast< const SMESH_ProxyMesh::SubMesh*>( aSubMeshDSFace )) { // add medium nodes of proxy triangles to helper (#16843) @@ -566,10 +565,16 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, { // check mesh face const SMDS_MeshElement* elem = iteratorElem->next(); - if ( !elem ) - return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); - if ( elem->NbCornerNodes() != 3 ) - return error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); + if ( !elem ){ + aParams._error = COMPERR_BAD_INPUT_MESH; + aParams._comment = "Null element encounters"; + return true; + } + if ( elem->NbCornerNodes() != 3 ){ + aParams._error = COMPERR_BAD_INPUT_MESH; + aParams._comment = "Not triangle element encounters"; + return true; + } // Add nodes of triangles and triangles them-selves to netgen mesh @@ -630,88 +635,231 @@ bool NETGENPlugin_NETGEN_3D::Compute(SMESH_Mesh& aMesh, internals); } } - - // ------------------------- - // Generate the volume mesh - // ------------------------- - auto time1 = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(time1-time0); - std::cout << "Time for seq:fill_in_ngmesh: " << elapsed.count() * 1e-9 << std::endl; - - return (ngLib._isComputeOk = compute( aMesh, helper, nodeVec, ngLib )); + Netgen_NbOfNodes = Ng_GetNP( Netgen_mesh ); + return false; } -// namespace -// { -// void limitVolumeSize( netgen::Mesh* ngMesh, -// double maxh ) -// { -// // get average h of faces -// double faceh = 0; -// int nbh = 0; -// for (int i = 1; i <= ngMesh->GetNSE(); i++) -// { -// const netgen::Element2d& face = ngMesh->SurfaceElement(i); -// for (int j=1; j <= face.GetNP(); ++j) -// { -// const netgen::PointIndex & i1 = face.PNumMod(j); -// const netgen::PointIndex & i2 = face.PNumMod(j+1); -// if ( i1 < i2 ) -// { -// const netgen::Point3d & p1 = ngMesh->Point( i1 ); -// const netgen::Point3d & p2 = ngMesh->Point( i2 ); -// faceh += netgen::Dist2( p1, p2 ); -// nbh++; -// } -// } -// } -// faceh = Sqrt( faceh / nbh ); +bool NETGENPlugin_NETGEN_3D::computePrepareParam( + SMESH_Mesh& aMesh, + NETGENPlugin_NetgenLibWrapper &ngLib, + netgen::OCCGeometry &occgeo, + SMESH_MesherHelper &helper, + netgen_params &aParams, + int &endWith) -// double compareh; -// if ( faceh < 0.5 * maxh ) compareh = -1; -// else if ( faceh > 1.5 * maxh ) compareh = 1; -// else compareh = 0; -// // cerr << "faceh " << faceh << endl; -// // cerr << "init maxh " << maxh << endl; -// // cerr << "compareh " << compareh << endl; +{ + netgen::multithread.terminate = 0; -// if ( compareh > 0 ) -// maxh *= 1.2; -// else -// maxh *= 0.8; -// // cerr << "maxh " << maxh << endl; + netgen::Mesh* ngMesh = ngLib._ngMesh; -// // get bnd box -// netgen::Point3d pmin, pmax; -// ngMesh->GetBox( pmin, pmax, 0 ); -// const double dx = pmax.X() - pmin.X(); -// const double dy = pmax.Y() - pmin.Y(); -// const double dz = pmax.Z() - pmin.Z(); + NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true ); -// if ( ! & ngMesh->LocalHFunction() ) -// ngMesh->SetLocalH( pmin, pmax, compareh <= 0 ? 0.1 : 0.5 ); -// // adjusted by SALOME_TESTS/Grids/smesh/bugs_08/I8 -// const int nbX = Max( 2, int( dx / maxh * 2 )); -// const int nbY = Max( 2, int( dy / maxh * 2 )); -// const int nbZ = Max( 2, int( dz / maxh * 2 )); + if ( aParams._hypParameters ) + { + aMesher.SetParameters( aParams._hypParameters ); -// netgen::Point3d p; -// for ( int i = 0; i <= nbX; ++i ) -// { -// p.X() = pmin.X() + i * dx / nbX; -// for ( int j = 0; j <= nbY; ++j ) -// { -// p.Y() = pmin.Y() + j * dy / nbY; -// for ( int k = 0; k <= nbZ; ++k ) -// { -// p.Z() = pmin.Z() + k * dz / nbZ; -// ngMesh->RestrictLocalH( p, maxh ); -// } -// } -// } -// } -// } + if ( !aParams._hypParameters->GetLocalSizesAndEntries().empty() || + !aParams._hypParameters->GetMeshSizeFile().empty() ) + { + if ( ! &ngMesh->LocalHFunction() ) + { + netgen::Point3d pmin, pmax; + ngMesh->GetBox( pmin, pmax, 0 ); + ngMesh->SetLocalH( pmin, pmax, aParams._hypParameters->GetGrowthRate() ); + } + aMesher.SetLocalSize( occgeo, *ngMesh ); + + try { + ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); + } catch (netgen::NgException & ex) { + aParams._error = COMPERR_BAD_PARMETERS; + aParams._comment = ex.What(); + return false; + } + } + if ( !aParams._hypParameters->GetOptimize() ) + endWith = netgen::MESHCONST_MESHVOLUME; + } + else if ( aParams._hypMaxElementVolume ) + { + netgen::mparam.maxh = pow( 72, 1/6. ) * pow( aParams.maxElementVolume, 1/3. ); + // limitVolumeSize( ngMesh, mparam.maxh ); // result is unpredictable + } + else if ( aMesh.HasShapeToMesh() ) + { + aMesher.PrepareOCCgeometry( occgeo, helper.GetSubShape(), aMesh ); + netgen::mparam.maxh = occgeo.GetBoundingBox().Diam()/2; + } + else + { + netgen::Point3d pmin, pmax; + ngMesh->GetBox (pmin, pmax); + netgen::mparam.maxh = Dist(pmin, pmax)/2; + } + + if ( !aParams._hypParameters && aMesh.HasShapeToMesh() ) + { + netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh ); + } + return false; +} + +bool NETGENPlugin_NETGEN_3D::computeRunMesher( + netgen::OCCGeometry &occgeo, + vector< const SMDS_MeshNode* > &nodeVec, + netgen::Mesh* ngMesh, + NETGENPlugin_NetgenLibWrapper &ngLib, + netgen_params &aParams, + int &startWith, int &endWith) +{ + int err = 1; + + try + { + OCC_CATCH_SIGNALS; + + ngLib.CalcLocalH(ngMesh); + err = ngLib.GenerateMesh(occgeo, startWith, endWith); + + if(netgen::multithread.terminate) + return false; + if ( err ){ + aParams._comment = SMESH_Comment("Error in netgen::OCCGenerateMesh() at ") << netgen::multithread.task; + return true; + } + } + catch (Standard_Failure& ex) + { + SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); + str << " at " << netgen::multithread.task + << ": " << ex.DynamicType()->Name(); + if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) + str << ": " << ex.GetMessageString(); + aParams._comment = str; + return true; + } + catch (netgen::NgException& exc) + { + SMESH_Comment str("NgException"); + if ( strlen( netgen::multithread.task ) > 0 ) + str << " at " << netgen::multithread.task; + str << ": " << exc.What(); + aParams._comment = str; + return true; + } + catch (...) + { + SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); + if ( strlen( netgen::multithread.task ) > 0 ) + str << " at " << netgen::multithread.task; + aParams._comment = str; + return true; + } + + if ( err ) + { + SMESH_ComputeErrorPtr ce = NETGENPlugin_Mesher::ReadErrors(nodeVec); + if ( ce && ce->HasBadElems() ){ + aParams._error = ce->myName; + aParams._comment = ce->myComment; + return true; + } + } + + return false; +} + +bool NETGENPlugin_NETGEN_3D::computeFillMesh( + vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + SMESH_MesherHelper &helper, + int &Netgen_NbOfNodes + ) +{ + Ng_Mesh* Netgen_mesh = ngLib.ngMesh(); + + int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); + int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); + + bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built + if ( isOK ) + { + double Netgen_point[3]; + int Netgen_tetrahedron[4]; + + // create and insert new nodes into nodeVec + nodeVec.resize( Netgen_NbOfNodesNew + 1, 0 ); + int nodeIndex = Netgen_NbOfNodes + 1; + for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) + { + Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point ); + nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], Netgen_point[1], Netgen_point[2]); + } + + // create tetrahedrons + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) + { + Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); + try + { + helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), + nodeVec.at( Netgen_tetrahedron[1] ), + nodeVec.at( Netgen_tetrahedron[2] ), + nodeVec.at( Netgen_tetrahedron[3] )); + } + catch (...) + { + } + } + } + return false; +} + +bool NETGENPlugin_NETGEN_3D::Compute( + SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) +{ + if(aMesh.IsParallel()) + return RemoteCompute(aMesh, aShape); + + // vector of nodes in which node index == netgen ID + vector< const SMDS_MeshNode* > nodeVec; + NETGENPlugin_NetgenLibWrapper ngLib; + SMESH_MesherHelper helper(aMesh); + int startWith = netgen::MESHCONST_MESHVOLUME; + int endWith = netgen::MESHCONST_OPTVOLUME; + int Netgen_NbOfNodes; + + netgen_params aParams; + + aParams._hypParameters = const_cast(_hypParameters); + aParams._hypMaxElementVolume = const_cast(_hypMaxElementVolume); + aParams.maxElementVolume = _maxElementVolume; + aParams._progressByTic = _progressByTic; + aParams._quadraticMesh = _quadraticMesh; + aParams._viscousLayersHyp = const_cast(_viscousLayersHyp); + + bool ret; + ret = computeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, aParams, Netgen_NbOfNodes); + if(ret) + return error( aParams._error, aParams._comment); + + netgen::OCCGeometry occgeo; + computePrepareParam(aMesh, ngLib, occgeo, helper, aParams, endWith); + ret = computeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, aParams, startWith, endWith); + if(ret){ + if(aParams._error) + return error(aParams._error, aParams._comment); + + error(aParams._comment); + return true; + } + computeFillMesh(nodeVec, ngLib, helper, Netgen_NbOfNodes); + + return false; + +} //================================================================================ /*! diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx index 9ce54df..03df7fe 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx @@ -37,11 +37,14 @@ #include "SMESH_Algo.hxx" #include "Utils_SALOME_Exception.hxx" +#include + class StdMeshers_ViscousLayers; class StdMeshers_MaxElementVolume; class NETGENPlugin_Hypothesis; class NETGENPlugin_NetgenLibWrapper; class netgen_params; +class SMDS_MeshNode; class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo { @@ -67,6 +70,37 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo const TopoDS_Shape& aShape, MapShapeNbElems& aResMap); + static bool computeFillNgMesh( + SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + std::vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + SMESH_MesherHelper &helper, + netgen_params &aParams, + int &Netgen_NbOfNodes); + + static bool computePrepareParam( + SMESH_Mesh& aMesh, + NETGENPlugin_NetgenLibWrapper &ngLib, + netgen::OCCGeometry &occgeo, + SMESH_MesherHelper &helper, + netgen_params &aParams, + int &endWith); + + static bool computeRunMesher( + netgen::OCCGeometry &occgeo, + std::vector< const SMDS_MeshNode* > &nodeVec, + netgen::Mesh* ngMesh, + NETGENPlugin_NetgenLibWrapper &ngLib, + netgen_params &aParams, + int &startWith, int &endWith); + + static bool computeFillMesh( + std::vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + SMESH_MesherHelper &helper, + int &Netgen_NbOfNodes); + protected: void exportElementOrientation(SMESH_Mesh& aMesh, @@ -81,6 +115,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo const TopoDS_Shape& aShape); + bool compute(SMESH_Mesh& mesh, SMESH_MesherHelper& helper, std::vector< const SMDS_MeshNode* >& nodeVec, From 1b4859d13598b1d911bb8146e2b35c8995c396f4 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 19 Sep 2022 11:49:00 +0200 Subject: [PATCH 16/29] Refactor in runner --- src/NETGENPlugin/NETGENPlugin_Runner.cxx | 239 +++++++++++------- src/NETGENPlugin/NETGENPlugin_Runner.hxx | 47 ++++ src/NETGENPlugin/NETGENPlugin_Runner_main.cxx | 3 + 3 files changed, 198 insertions(+), 91 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_Runner.cxx b/src/NETGENPlugin/NETGENPlugin_Runner.cxx index 43faa50..26c90fc 100644 --- a/src/NETGENPlugin/NETGENPlugin_Runner.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner.cxx @@ -190,7 +190,6 @@ int netgen3d(const std::string input_mesh_file, const std::string output_mesh_file, int nbThreads) { - auto time0 = std::chrono::high_resolution_clock::now(); // Importing mesh SMESH_Gen gen; @@ -199,24 +198,15 @@ int netgen3d(const std::string input_mesh_file, std::string mesh_name = "Maillage_1"; importMesh(input_mesh_file, *myMesh, mesh_name); - auto time1 = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(time1-time0); - std::cout << "Time for importMesh: " << elapsed.count() * 1e-9 << std::endl; // Importing shape TopoDS_Shape myShape; importShape(shape_file, myShape); - auto time2 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time2-time1); - std::cout << "Time for importShape: " << elapsed.count() * 1e-9 << std::endl; // Importing hypothesis netgen_params myParams; importNetgenParams(hypo_file, myParams, &gen); - auto time3 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time3-time2); - std::cout << "Time for import_netgen_param: " << elapsed.count() * 1e-9 << std::endl; // Setting number of threads for netgen myParams.nbThreads = nbThreads; @@ -226,59 +216,41 @@ int netgen3d(const std::string input_mesh_file, !output_mesh_file.empty()); - if(!ret){ + if(ret){ std::cout << "Meshing failed" << std::endl; return ret; } if(!output_mesh_file.empty()){ - auto time4 = std::chrono::high_resolution_clock::now(); exportMesh(output_mesh_file, *myMesh, mesh_name); - auto time5 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time5-time4); - std::cout << "Time for exportMesh: " << elapsed.count() * 1e-9 << std::endl; } return ret; } -/** - * @brief Compute aShape within aMesh using netgen3d - * - * @param aShape the shape - * @param aMesh the mesh - * @param aParams the netgen parameters - * @param new_element_file file containing data on the new point/tetra added by netgen - * @param element_orientation_file file containing data on the orientation of each element to add to netgen - * @param output_mesh if true add element created by netgen into aMesh - * - * @return error code - */ -int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, - std::string new_element_file, std::string element_orientation_file, - bool output_mesh) +bool mycomputeFillNgMesh( + SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + std::vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + SMESH_MesherHelper &helper, + netgen_params &aParams, + std::string element_orientation_file, + int &Netgen_NbOfNodes) { - - auto time0 = std::chrono::high_resolution_clock::now(); - netgen::multithread.terminate = 0; netgen::multithread.task = "Volume meshing"; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - SMESH_MesherHelper helper(aMesh); aParams._quadraticMesh = helper.IsQuadraticSubMesh(aShape); helper.SetElementsOnShape( true ); - int Netgen_NbOfNodes = 0; double Netgen_point[3]; int Netgen_triangle[3]; - NETGENPlugin_NetgenLibWrapper ngLib; Ng_Mesh * Netgen_mesh = (Ng_Mesh*)ngLib._ngMesh; - // vector of nodes in which node index == netgen ID - vector< const SMDS_MeshNode* > nodeVec; { const int invalid_ID = -1; @@ -434,9 +406,20 @@ int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aPa // internals); //} } - auto time1 = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(time1-time0); - std::cout << "Time for fill_in_ngmesh: " << elapsed.count() * 1e-9 << std::endl; + Netgen_mesh = ngLib.ngMesh(); + Netgen_NbOfNodes = Ng_GetNP( Netgen_mesh ); + + return false; +} + +bool mycomputePrepareParam( + SMESH_Mesh& aMesh, + NETGENPlugin_NetgenLibWrapper &ngLib, + netgen::OCCGeometry &occgeo, + SMESH_MesherHelper &helper, + netgen_params &aParams, + int &endWith) +{ // ------------------------- // Generate the volume mesh @@ -444,16 +427,8 @@ int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aPa netgen::multithread.terminate = 0; netgen::Mesh* ngMesh = ngLib._ngMesh; - Netgen_mesh = ngLib.ngMesh(); - Netgen_NbOfNodes = Ng_GetNP( Netgen_mesh ); - - - int startWith = netgen::MESHCONST_MESHVOLUME; - int endWith = netgen::MESHCONST_OPTVOLUME; - int err = 1; NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true ); - netgen::OCCGeometry occgeo; set_netgen_parameters(aParams); if ( aParams.has_netgen_param ) @@ -499,6 +474,17 @@ int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aPa netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh ); } + return false; +} + +bool mycomputeRunMesher( + netgen::OCCGeometry &occgeo, + std::vector< const SMDS_MeshNode* > &nodeVec, + netgen::Mesh* ngMesh, + NETGENPlugin_NetgenLibWrapper &ngLib, + int &startWith, int &endWith) +{ + int err = 1; try { OCC_CATCH_SIGNALS; @@ -536,22 +522,28 @@ int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aPa return error(str); } - int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); - int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); - - // ------------------------------------------------------------------- - // Feed back the SMESHDS with the generated Nodes and Volume Elements - // ------------------------------------------------------------------- - if ( err ) { SMESH_ComputeErrorPtr ce = NETGENPlugin_Mesher::ReadErrors(nodeVec); if ( ce && ce->HasBadElems() ) return error( ce ); } - auto time2 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time2-time1); - std::cout << "Time for netgen_compute: " << elapsed.count() * 1e-9 << std::endl; + + return false; + +} + +bool mycomputeFillNewElementFile( + std::vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + std::string new_element_file, + int &Netgen_NbOfNodes +) +{ + Ng_Mesh* Netgen_mesh = ngLib.ngMesh(); + + int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); + int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built if ( isOK && !new_element_file.empty() ) @@ -588,50 +580,115 @@ int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aPa df.write((char*) &Netgen_tetrahedron, sizeof(int)*4); } } - auto time3 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time3-time2); - std::cout << "Time for write_new_elem: " << elapsed.count() * 1e-9 << std::endl; + return false; +} +bool mycomputeFillMesh( + std::vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + SMESH_MesherHelper &helper, + int &Netgen_NbOfNodes) +{ + + Ng_Mesh* Netgen_mesh = ngLib.ngMesh(); + + int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); + int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); + + // ------------------------------------------------------------------- + // Feed back the SMESHDS with the generated Nodes and Volume Elements + // ------------------------------------------------------------------- // Adding new elements in aMesh as well - if ( output_mesh ) + + double Netgen_point[3]; + int Netgen_tetrahedron[4]; + + // create and insert new nodes into nodeVec + nodeVec.resize( Netgen_NbOfNodesNew + 1, 0 ); + int nodeIndex = Netgen_NbOfNodes + 1; + for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) { - double Netgen_point[3]; - int Netgen_tetrahedron[4]; + Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point ); + nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], + Netgen_point[1], + Netgen_point[2]); + } - // create and insert new nodes into nodeVec - nodeVec.resize( Netgen_NbOfNodesNew + 1, 0 ); - int nodeIndex = Netgen_NbOfNodes + 1; - for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) + // create tetrahedrons + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) + { + Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); + try { - Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point ); - nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], - Netgen_point[1], - Netgen_point[2]); + helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), + nodeVec.at( Netgen_tetrahedron[1] ), + nodeVec.at( Netgen_tetrahedron[2] ), + nodeVec.at( Netgen_tetrahedron[3] )); } - - // create tetrahedrons - for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) + catch (...) { - Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); - try - { - helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), - nodeVec.at( Netgen_tetrahedron[1] ), - nodeVec.at( Netgen_tetrahedron[2] ), - nodeVec.at( Netgen_tetrahedron[3] )); - } - catch (...) - { - } } - auto time4 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time4-time3); - std::cout << "Time for add_element_to_smesh: " << elapsed.count() * 1e-9 << std::endl; } - return !err; + return false; +} + +/** + * @brief Compute aShape within aMesh using netgen3d + * + * @param aShape the shape + * @param aMesh the mesh + * @param aParams the netgen parameters + * @param new_element_file file containing data on the new point/tetra added by netgen + * @param element_orientation_file file containing data on the orientation of each element to add to netgen + * @param output_mesh if true add element created by netgen into aMesh + * + * @return error code + */ +int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, + std::string new_element_file, std::string element_orientation_file, + bool output_mesh) +{ +// vector of nodes in which node index == netgen ID + vector< const SMDS_MeshNode* > nodeVec; + NETGENPlugin_NetgenLibWrapper ngLib; + SMESH_MesherHelper helper(aMesh); + int startWith = netgen::MESHCONST_MESHVOLUME; + int endWith = netgen::MESHCONST_OPTVOLUME; + int Netgen_NbOfNodes=0; + + bool ret; + std::cout << "mycomputeFillNgMesh" << std::endl; + ret = mycomputeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, aParams, element_orientation_file, Netgen_NbOfNodes); + if(ret) + return error( aParams._error, aParams._comment); + std::cout << "mycomputePrepareParam" << std::endl; + + netgen::OCCGeometry occgeo; + mycomputePrepareParam(aMesh, ngLib, occgeo, helper, aParams, endWith); + std::cout << "mycomputeRunMesher" << std::endl; + + ret = mycomputeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, startWith, endWith); + if(ret){ + if(aParams._error) + return error(aParams._error, aParams._comment); + + error(aParams._comment); + return true; + } + std::cout << "mycomputeFillNewElementFile" << std::endl; + + mycomputeFillNewElementFile(nodeVec, ngLib, new_element_file, Netgen_NbOfNodes); + std::cout << "mycomputeFillMesh" << std::endl; + + if(output_mesh) + mycomputeFillMesh(nodeVec, ngLib, helper, Netgen_NbOfNodes); + std::cout << "Done" << std::endl; + + + return false; } /** diff --git a/src/NETGENPlugin/NETGENPlugin_Runner.hxx b/src/NETGENPlugin/NETGENPlugin_Runner.hxx index fe4d6c9..6b762ed 100644 --- a/src/NETGENPlugin/NETGENPlugin_Runner.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner.hxx @@ -31,11 +31,20 @@ #include #include +#include "NETGENPlugin_Defs.hxx" +#include "NETGENPlugin_Mesher.hxx" + +#include "SMESH_Algo.hxx" +#include "Utils_SALOME_Exception.hxx" + class TopoDS_Shape; class SMESH_Mesh; class SMESH_Comment; class netgen_params; +class NETGENPlugin_NetgenLibWrapper; +class SMDS_MeshNode; +// Netgen 2d functions int netgen2dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, @@ -49,6 +58,44 @@ int netgen2d(const std::string input_mesh_file, const std::string new_element_file, const std::string output_mesh_file); +// Netgen 3D functions +bool mycomputeFillNgMesh( + SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + std::vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + SMESH_MesherHelper &helper, + netgen_params &aParams, + std::string element_orientation_file, + int &Netgen_NbOfNodes); + +bool mycomputePrepareParam( + SMESH_Mesh& aMesh, + NETGENPlugin_NetgenLibWrapper &ngLib, + netgen::OCCGeometry &occgeo, + SMESH_MesherHelper &helper, + netgen_params &aParams, + int &endWith); + +bool mycomputeRunMesher( + netgen::OCCGeometry &occgeo, + std::vector< const SMDS_MeshNode* > &nodeVec, + netgen::Mesh* ngMesh, + NETGENPlugin_NetgenLibWrapper &ngLib, + int &startWith, int &endWith); + +bool mycomputeFillNewElementFile( + std::vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + std::string new_element_file, + int &Netgen_NbOfNodes); + +bool mycomputeFillMesh( + std::vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + SMESH_MesherHelper &helper, + int &Netgen_NbOfNodes); + int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, diff --git a/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx index 709e118..e4c20a2 100644 --- a/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx @@ -72,6 +72,9 @@ int main(int argc, char *argv[]){ std::string new_element_file=argv[7]; std::string output_mesh_file=argv[8]; + //std::string thing; + //std::cin >> thing; + if (output_mesh_file == "NONE") output_mesh_file = ""; if (element_orientation_file == "NONE") From d9a37018c54bfdf8a957b97ad991c2092d140490 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 19 Sep 2022 15:13:31 +0200 Subject: [PATCH 17/29] Refactoring of runner --- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 189 +++++---- src/NETGENPlugin/NETGENPlugin_Runner.cxx | 430 +++++++------------- 2 files changed, 248 insertions(+), 371 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index f1fae5e..d349265 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -474,6 +474,70 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, */ //============================================================================= +/** + * @brief Get an iterator on the Surface element with their orientation + * + */ + + bool getSurfaceElements( + SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_ProxyMesh::Ptr proxyMesh, + NETGENPlugin_Internals &internals, + SMESH_MesherHelper &helper, + netgen_params &aParams, + std::map>& listElements +) +{ + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + TopAbs_ShapeEnum mainType = aMesh.GetShapeToMesh().ShapeType(); + bool checkReverse = ( mainType == TopAbs_COMPOUND || mainType == TopAbs_COMPSOLID ); + + for ( TopExp_Explorer exFa( aShape, TopAbs_FACE ); exFa.More(); exFa.Next()) + { + const TopoDS_Shape& aShapeFace = exFa.Current(); + int faceID = meshDS->ShapeToIndex( aShapeFace ); + bool isInternalFace = internals.isInternalShape( faceID ); + bool isRev = false; + if ( checkReverse && !isInternalFace && + helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) + // IsReversedSubMesh() can work wrong on strongly curved faces, + // so we use it as less as possible + isRev = helper.IsReversedSubMesh( TopoDS::Face( aShapeFace )); + + const SMESHDS_SubMesh * aSubMeshDSFace = proxyMesh->GetSubMesh( aShapeFace ); + if ( !aSubMeshDSFace ) continue; + + SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); + if ( aParams._quadraticMesh && + dynamic_cast< const SMESH_ProxyMesh::SubMesh*>( aSubMeshDSFace )) + { + // add medium nodes of proxy triangles to helper (#16843) + while ( iteratorElem->more() ) + helper.AddTLinks( static_cast< const SMDS_MeshFace* >( iteratorElem->next() )); + + iteratorElem = aSubMeshDSFace->GetElements(); + } + while(iteratorElem->more()){ + const SMDS_MeshElement* elem = iteratorElem->next(); + // check mesh face + if ( !elem ){ + aParams._error = COMPERR_BAD_INPUT_MESH; + aParams._comment = "Null element encounters"; + return true; + } + if ( elem->NbCornerNodes() != 3 ){ + aParams._error = COMPERR_BAD_INPUT_MESH; + aParams._comment = "Not triangle element encounters"; + return true; + } + listElements[elem] = tuple(isRev, isInternalFace); + } + } + + return false; +} + bool NETGENPlugin_NETGEN_3D::computeFillNgMesh( SMESH_Mesh& aMesh, @@ -516,9 +580,8 @@ bool NETGENPlugin_NETGEN_3D::computeFillNgMesh( // --------------------------------- // Feed the Netgen with surface mesh // --------------------------------- - - TopAbs_ShapeEnum mainType = aMesh.GetShapeToMesh().ShapeType(); - bool checkReverse = ( mainType == TopAbs_COMPOUND || mainType == TopAbs_COMPSOLID ); + bool isRev=false; + bool isInternalFace=false; SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); if ( aParams._viscousLayersHyp ) @@ -536,88 +599,56 @@ bool NETGENPlugin_NETGEN_3D::computeFillNgMesh( proxyMesh.reset( Adaptor ); } - for ( TopExp_Explorer exFa( aShape, TopAbs_FACE ); exFa.More(); exFa.Next()) + std::map> listElements; + bool ret = getSurfaceElements(aMesh, aShape, proxyMesh, internals, helper, aParams, listElements); + if(ret) + return ret; + + for ( auto const& [elem, info] : listElements ) // loop on elements on a geom face { - const TopoDS_Shape& aShapeFace = exFa.Current(); - int faceID = meshDS->ShapeToIndex( aShapeFace ); - bool isInternalFace = internals.isInternalShape( faceID ); - bool isRev = false; - if ( checkReverse && !isInternalFace && - helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) - // IsReversedSubMesh() can work wrong on strongly curved faces, - // so we use it as less as possible - isRev = helper.IsReversedSubMesh( TopoDS::Face( aShapeFace )); + isRev = get<0>(info); + isInternalFace = get<1>(info); + // Add nodes of triangles and triangles them-selves to netgen mesh - const SMESHDS_SubMesh * aSubMeshDSFace = proxyMesh->GetSubMesh( aShapeFace ); - if ( !aSubMeshDSFace ) continue; - - SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - if ( aParams._quadraticMesh && - dynamic_cast< const SMESH_ProxyMesh::SubMesh*>( aSubMeshDSFace )) + // add three nodes of triangle + bool hasDegen = false; + for ( int iN = 0; iN < 3; ++iN ) { - // add medium nodes of proxy triangles to helper (#16843) - while ( iteratorElem->more() ) - helper.AddTLinks( static_cast< const SMDS_MeshFace* >( iteratorElem->next() )); - - iteratorElem = aSubMeshDSFace->GetElements(); + const SMDS_MeshNode* node = elem->GetNode( iN ); + const int shapeID = node->getshapeId(); + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && + helper.IsDegenShape( shapeID )) + { + // ignore all nodes on degeneraged edge and use node on its vertex instead + TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); + node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS ); + hasDegen = true; + } + int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; + if ( ngID == invalid_ID ) + { + ngID = ++Netgen_NbOfNodes; + Netgen_point [ 0 ] = node->X(); + Netgen_point [ 1 ] = node->Y(); + Netgen_point [ 2 ] = node->Z(); + Ng_AddPoint(Netgen_mesh, Netgen_point); + } + Netgen_triangle[ isRev ? 2-iN : iN ] = ngID; } - while ( iteratorElem->more() ) // loop on elements on a geom face + // add triangle + if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] || + Netgen_triangle[0] == Netgen_triangle[2] || + Netgen_triangle[2] == Netgen_triangle[1] )) + continue; + + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + + if ( isInternalFace && !proxyMesh->IsTemporary( elem )) { - // check mesh face - const SMDS_MeshElement* elem = iteratorElem->next(); - if ( !elem ){ - aParams._error = COMPERR_BAD_INPUT_MESH; - aParams._comment = "Null element encounters"; - return true; - } - if ( elem->NbCornerNodes() != 3 ){ - aParams._error = COMPERR_BAD_INPUT_MESH; - aParams._comment = "Not triangle element encounters"; - return true; - } - - // Add nodes of triangles and triangles them-selves to netgen mesh - - // add three nodes of triangle - bool hasDegen = false; - for ( int iN = 0; iN < 3; ++iN ) - { - const SMDS_MeshNode* node = elem->GetNode( iN ); - const int shapeID = node->getshapeId(); - if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && - helper.IsDegenShape( shapeID )) - { - // ignore all nodes on degeneraged edge and use node on its vertex instead - TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); - node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS ); - hasDegen = true; - } - int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; - if ( ngID == invalid_ID ) - { - ngID = ++Netgen_NbOfNodes; - Netgen_point [ 0 ] = node->X(); - Netgen_point [ 1 ] = node->Y(); - Netgen_point [ 2 ] = node->Z(); - Ng_AddPoint(Netgen_mesh, Netgen_point); - } - Netgen_triangle[ isRev ? 2-iN : iN ] = ngID; - } - // add triangle - if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] || - Netgen_triangle[0] == Netgen_triangle[2] || - Netgen_triangle[2] == Netgen_triangle[1] )) - continue; - + swap( Netgen_triangle[1], Netgen_triangle[2] ); Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); - - if ( isInternalFace && !proxyMesh->IsTemporary( elem )) - { - swap( Netgen_triangle[1], Netgen_triangle[2] ); - Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); - } - } // loop on elements on a face - } // loop on faces of a SOLID or SHELL + } + } // loop on elements on a face // insert old nodes into nodeVec nodeVec.resize( nodeToNetgenID.size() + 1, 0 ); diff --git a/src/NETGENPlugin/NETGENPlugin_Runner.cxx b/src/NETGENPlugin/NETGENPlugin_Runner.cxx index 26c90fc..2107247 100644 --- a/src/NETGENPlugin/NETGENPlugin_Runner.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner.cxx @@ -27,7 +27,7 @@ #include "NETGENPlugin_Runner.hxx" - +#include "NETGENPlugin_NETGEN_3D.hxx" #include "NETGENPlugin_DriverParam.hxx" #include @@ -228,6 +228,84 @@ int netgen3d(const std::string input_mesh_file, return ret; } + bool getSurfaceElements( + SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_ProxyMesh::Ptr proxyMesh, + NETGENPlugin_Internals &internals, + SMESH_MesherHelper &helper, + netgen_params &aParams, + std::string element_orientation_file, + std::map>& listElements +) +{ + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + + // Get list of elements + their orientation from element_orientation file + std::map elemOrientation; + { + // Setting all element orientation to false if there no element orientation file + if(element_orientation_file.empty()){ + SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Face); + while ( iteratorElem->more() ) // loop on elements on a geom face + { + // check mesh face + const SMDS_MeshElement* elem = iteratorElem->next(); + elemOrientation[elem->GetID()] = false; + } + } else { + std::ifstream df(element_orientation_file, ios::binary|ios::in); + int nbElement; + bool orient; + + // Warning of the use of vtkIdType (I had issue when run_mesher was compiled with internal vtk) and salome not + // Sizeof was the same but how he othered the type was different + // Maybe using another type (uint64_t) instead would be better + vtkIdType id; + df.read((char*)&nbElement, sizeof(int)); + + for(int ielem=0;ielemelementsIterator(SMDSAbs_Face); + bool isRev; + bool isInternalFace = false; + + bool isIn; + + while ( iteratorElem->more() ) // loop on elements on a geom face + { + // check mesh face + const SMDS_MeshElement* elem = iteratorElem->next(); + if ( !elem ){ + aParams._error = COMPERR_BAD_INPUT_MESH; + aParams._comment = "Null element encounters"; + return true; + } + if ( elem->NbCornerNodes() != 3 ){ + aParams._error = COMPERR_BAD_INPUT_MESH; + aParams._comment = "Not triangle element encounters"; + return true; + } + // Keeping only element that are in the element orientation file + isIn = elemOrientation.count(elem->GetID())==1; + if(!isIn) + continue; + // Get orientation + // Netgen requires that all the triangle point outside + isRev = elemOrientation[elem->GetID()]; + listElements[elem] = tuple(isRev, false); + } + + return false; +} + bool mycomputeFillNgMesh( SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, @@ -238,14 +316,16 @@ bool mycomputeFillNgMesh( std::string element_orientation_file, int &Netgen_NbOfNodes) { - netgen::multithread.terminate = 0; + netgen::multithread.terminate = 0; netgen::multithread.task = "Volume meshing"; + aParams._progressByTic = -1.; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); aParams._quadraticMesh = helper.IsQuadraticSubMesh(aShape); helper.SetElementsOnShape( true ); + Netgen_NbOfNodes = 0; double Netgen_point[3]; int Netgen_triangle[3]; @@ -268,9 +348,8 @@ bool mycomputeFillNgMesh( // --------------------------------- // Feed the Netgen with surface mesh // --------------------------------- - - TopAbs_ShapeEnum mainType = aMesh.GetShapeToMesh().ShapeType(); - bool checkReverse = ( mainType == TopAbs_COMPOUND || mainType == TopAbs_COMPSOLID ); + bool isRev=false; + bool isInternalFace=false; SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); if ( aParams._viscousLayersHyp ) @@ -288,106 +367,56 @@ bool mycomputeFillNgMesh( proxyMesh.reset( Adaptor ); } - // Get list of elements + their orientation from element_orientation file - std::map elemOrientation; + std::map> listElements; + bool ret = getSurfaceElements(aMesh, aShape, proxyMesh, internals, helper, aParams, element_orientation_file, listElements); + if(ret) + return ret; + + for ( auto const& [elem, info] : listElements ) // loop on elements on a geom face { - // Setting all element orientation to false if there no element orientation file - if(element_orientation_file.empty()){ - SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Face); - while ( iteratorElem->more() ) // loop on elements on a geom face - { - // check mesh face - const SMDS_MeshElement* elem = iteratorElem->next(); - elemOrientation[elem->GetID()] = false; - } - } else { - std::ifstream df(element_orientation_file, ios::binary|ios::in); - int nbElement; - bool orient; + isRev = get<0>(info); + isInternalFace = get<1>(info); + // Add nodes of triangles and triangles them-selves to netgen mesh - // Warning of the use of vtkIdType (I had issue when run_mesher was compiled with internal vtk) and salome not - // Sizeof was the same but how he othered the type was different - // Maybe using another type (uint64_t) instead would be better - vtkIdType id; - df.read((char*)&nbElement, sizeof(int)); - - for(int ielem=0;ielemelementsIterator(SMDSAbs_Face); - bool isRev; - bool isInternalFace = false; - - bool isIn; - - while ( iteratorElem->more() ) // loop on elements on a geom face + // add three nodes of triangle + bool hasDegen = false; + for ( int iN = 0; iN < 3; ++iN ) { - // check mesh face - const SMDS_MeshElement* elem = iteratorElem->next(); - if ( !elem ) - return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); - if ( elem->NbCornerNodes() != 3 ) - return error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); - - // Keeping only element that are in the element orientation file - isIn = elemOrientation.count(elem->GetID())==1; - - if(!isIn) - continue; - - // Get orientation - // Netgen requires that all the triangle point outside - isRev = elemOrientation[elem->GetID()]; - - // Add nodes of triangles and triangles them-selves to netgen mesh - - // add three nodes of triangle - bool hasDegen = false; - for ( int iN = 0; iN < 3; ++iN ) + const SMDS_MeshNode* node = elem->GetNode( iN ); + const int shapeID = node->getshapeId(); + if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && + helper.IsDegenShape( shapeID )) { - const SMDS_MeshNode* node = elem->GetNode( iN ); - const int shapeID = node->getshapeId(); - if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && - helper.IsDegenShape( shapeID )) - { - // ignore all nodes on degeneraged edge and use node on its vertex instead - TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); - node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS ); - hasDegen = true; - } - int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; - if ( ngID == invalid_ID ) - { - ngID = ++Netgen_NbOfNodes; - Netgen_point [ 0 ] = node->X(); - Netgen_point [ 1 ] = node->Y(); - Netgen_point [ 2 ] = node->Z(); - Ng_AddPoint(Netgen_mesh, Netgen_point); - } - - Netgen_triangle[ isRev ? 2-iN : iN ] = ngID; + // ignore all nodes on degeneraged edge and use node on its vertex instead + TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); + node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS ); + hasDegen = true; } - // add triangle - if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] || - Netgen_triangle[0] == Netgen_triangle[2] || - Netgen_triangle[2] == Netgen_triangle[1] )) - continue; - - Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); - - // TODO: Handle that case (quadrangle 2D) (isInternal is set to false) - if ( isInternalFace && !proxyMesh->IsTemporary( elem )) + int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; + if ( ngID == invalid_ID ) { - swap( Netgen_triangle[1], Netgen_triangle[2] ); - Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + ngID = ++Netgen_NbOfNodes; + Netgen_point [ 0 ] = node->X(); + Netgen_point [ 1 ] = node->Y(); + Netgen_point [ 2 ] = node->Z(); + Ng_AddPoint(Netgen_mesh, Netgen_point); } + Netgen_triangle[ isRev ? 2-iN : iN ] = ngID; } + // add triangle + if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] || + Netgen_triangle[0] == Netgen_triangle[2] || + Netgen_triangle[2] == Netgen_triangle[1] )) + continue; + + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + + if ( isInternalFace && !proxyMesh->IsTemporary( elem )) + { + swap( Netgen_triangle[1], Netgen_triangle[2] ); + Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); + } + } // loop on elements on a face // insert old nodes into nodeVec nodeVec.resize( nodeToNetgenID.size() + 1, 0 ); @@ -396,143 +425,19 @@ bool mycomputeFillNgMesh( nodeVec[ n_id->second ] = n_id->first; nodeToNetgenID.clear(); - // TODO: Handle internal vertex - //if ( internals.hasInternalVertexInSolid() ) - //{ - // netgen::OCCGeometry occgeo; - // NETGENPlugin_Mesher::AddIntVerticesInSolids( occgeo, - // (netgen::Mesh&) *Netgen_mesh, - // nodeVec, - // internals); - //} - } - Netgen_mesh = ngLib.ngMesh(); - Netgen_NbOfNodes = Ng_GetNP( Netgen_mesh ); - - return false; -} - -bool mycomputePrepareParam( - SMESH_Mesh& aMesh, - NETGENPlugin_NetgenLibWrapper &ngLib, - netgen::OCCGeometry &occgeo, - SMESH_MesherHelper &helper, - netgen_params &aParams, - int &endWith) -{ - - // ------------------------- - // Generate the volume mesh - // ------------------------- - netgen::multithread.terminate = 0; - - netgen::Mesh* ngMesh = ngLib._ngMesh; - - NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true ); - set_netgen_parameters(aParams); - - if ( aParams.has_netgen_param ) - { - if ( aParams.has_local_size) + if ( internals.hasInternalVertexInSolid() ) { - if ( ! &ngMesh->LocalHFunction() ) - { - netgen::Point3d pmin, pmax; - ngMesh->GetBox( pmin, pmax, 0 ); - ngMesh->SetLocalH( pmin, pmax, aParams.grading ); - } - aMesher.SetLocalSize( occgeo, *ngMesh ); - - try { - ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); - } catch (netgen::NgException & ex) { - return error( COMPERR_BAD_PARMETERS, ex.What() ); - } + netgen::OCCGeometry occgeo; + NETGENPlugin_Mesher::AddIntVerticesInSolids( occgeo, + (netgen::Mesh&) *Netgen_mesh, + nodeVec, + internals); } - if ( !aParams.optimize ) - endWith = netgen::MESHCONST_MESHVOLUME; } - else if ( aParams.has_maxelementvolume_hyp ) - { - netgen::mparam.maxh = pow( 72, 1/6. ) * pow( aParams.maxElementVolume, 1/3. ); - // limitVolumeSize( ngMesh, netgen::mparam.maxh ); // result is unpredictable - } - else if ( aMesh.HasShapeToMesh() ) - { - aMesher.PrepareOCCgeometry( occgeo, helper.GetSubShape(), aMesh ); - netgen::mparam.maxh = occgeo.GetBoundingBox().Diam()/2; - } - else - { - netgen::Point3d pmin, pmax; - ngMesh->GetBox (pmin, pmax); - netgen::mparam.maxh = Dist(pmin, pmax)/2; - } - - if ( !aParams.has_netgen_param && aMesh.HasShapeToMesh() ) - { - netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh ); - } - + Netgen_NbOfNodes = Ng_GetNP( Netgen_mesh ); return false; } -bool mycomputeRunMesher( - netgen::OCCGeometry &occgeo, - std::vector< const SMDS_MeshNode* > &nodeVec, - netgen::Mesh* ngMesh, - NETGENPlugin_NetgenLibWrapper &ngLib, - int &startWith, int &endWith) -{ - int err = 1; - try - { - OCC_CATCH_SIGNALS; - - ngLib.CalcLocalH(ngMesh); - err = ngLib.GenerateMesh(occgeo, startWith, endWith, ngMesh); - - if(netgen::multithread.terminate) - return false; - if ( err ) - return error(SMESH_Comment("Error in netgen::OCCGenerateMesh() at ") << netgen::multithread.task); - } - catch (Standard_Failure& ex) - { - SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); - str << " at " << netgen::multithread.task - << ": " << ex.DynamicType()->Name(); - if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) - str << ": " << ex.GetMessageString(); - return error(str); - } - catch (netgen::NgException& exc) - { - SMESH_Comment str("NgException"); - if ( strlen( netgen::multithread.task ) > 0 ) - str << " at " << netgen::multithread.task; - str << ": " << exc.What(); - return error(str); - } - catch (...) - { - SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); - if ( strlen( netgen::multithread.task ) > 0 ) - str << " at " << netgen::multithread.task; - return error(str); - } - - if ( err ) - { - SMESH_ComputeErrorPtr ce = NETGENPlugin_Mesher::ReadErrors(nodeVec); - if ( ce && ce->HasBadElems() ) - return error( ce ); - } - - return false; - -} - bool mycomputeFillNewElementFile( std::vector< const SMDS_MeshNode* > &nodeVec, NETGENPlugin_NetgenLibWrapper &ngLib, @@ -545,7 +450,7 @@ bool mycomputeFillNewElementFile( int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); - bool isOK = ( /*status == NG_OK &&*/ Netgen_NbOfTetra > 0 );// get whatever built + bool isOK = ( Netgen_NbOfTetra > 0 ); if ( isOK && !new_element_file.empty() ) { std::ofstream df(new_element_file, ios::out|ios::binary); @@ -583,58 +488,6 @@ bool mycomputeFillNewElementFile( return false; } -bool mycomputeFillMesh( - std::vector< const SMDS_MeshNode* > &nodeVec, - NETGENPlugin_NetgenLibWrapper &ngLib, - SMESH_MesherHelper &helper, - int &Netgen_NbOfNodes) -{ - - Ng_Mesh* Netgen_mesh = ngLib.ngMesh(); - - int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); - int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); - - // ------------------------------------------------------------------- - // Feed back the SMESHDS with the generated Nodes and Volume Elements - // ------------------------------------------------------------------- - - // Adding new elements in aMesh as well - - double Netgen_point[3]; - int Netgen_tetrahedron[4]; - - // create and insert new nodes into nodeVec - nodeVec.resize( Netgen_NbOfNodesNew + 1, 0 ); - int nodeIndex = Netgen_NbOfNodes + 1; - for ( ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) - { - Ng_GetPoint( Netgen_mesh, nodeIndex, Netgen_point ); - nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], - Netgen_point[1], - Netgen_point[2]); - } - - // create tetrahedrons - for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) - { - Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); - try - { - helper.AddVolume (nodeVec.at( Netgen_tetrahedron[0] ), - nodeVec.at( Netgen_tetrahedron[1] ), - nodeVec.at( Netgen_tetrahedron[2] ), - nodeVec.at( Netgen_tetrahedron[3] )); - } - catch (...) - { - } - - } - - return false; -} - /** * @brief Compute aShape within aMesh using netgen3d * @@ -651,7 +504,7 @@ int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aPa std::string new_element_file, std::string element_orientation_file, bool output_mesh) { -// vector of nodes in which node index == netgen ID + // vector of nodes in which node index == netgen ID vector< const SMDS_MeshNode* > nodeVec; NETGENPlugin_NetgenLibWrapper ngLib; SMESH_MesherHelper helper(aMesh); @@ -660,17 +513,14 @@ int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aPa int Netgen_NbOfNodes=0; bool ret; - std::cout << "mycomputeFillNgMesh" << std::endl; ret = mycomputeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, aParams, element_orientation_file, Netgen_NbOfNodes); if(ret) return error( aParams._error, aParams._comment); - std::cout << "mycomputePrepareParam" << std::endl; netgen::OCCGeometry occgeo; - mycomputePrepareParam(aMesh, ngLib, occgeo, helper, aParams, endWith); - std::cout << "mycomputeRunMesher" << std::endl; + NETGENPlugin_NETGEN_3D::computePrepareParam(aMesh, ngLib, occgeo, helper, aParams, endWith); - ret = mycomputeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, startWith, endWith); + ret = NETGENPlugin_NETGEN_3D::computeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, aParams, startWith, endWith); if(ret){ if(aParams._error) return error(aParams._error, aParams._comment); @@ -678,15 +528,11 @@ int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aPa error(aParams._comment); return true; } - std::cout << "mycomputeFillNewElementFile" << std::endl; mycomputeFillNewElementFile(nodeVec, ngLib, new_element_file, Netgen_NbOfNodes); - std::cout << "mycomputeFillMesh" << std::endl; if(output_mesh) - mycomputeFillMesh(nodeVec, ngLib, helper, Netgen_NbOfNodes); - std::cout << "Done" << std::endl; - + NETGENPlugin_NETGEN_3D::computeFillMesh(nodeVec, ngLib, helper, Netgen_NbOfNodes); return false; } From f6eaf8534d751d48fa0703b8e3e5a94419cb703d Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 21 Sep 2022 14:21:30 +0200 Subject: [PATCH 18/29] Creating Remote and SA NETGEN_3D plugins --- idl/NETGENPlugin_Algorithm.idl | 11 +- src/NETGENPlugin/CMakeLists.txt | 8 +- src/NETGENPlugin/NETGENPluginBuilder.py | 32 + src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 280 +---- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx | 29 +- .../NETGENPlugin_NETGEN_3D_Remote.cxx | 351 +++++++ .../NETGENPlugin_NETGEN_3D_Remote.hxx | 74 ++ .../NETGENPlugin_NETGEN_3D_Remote_i.cxx | 80 ++ .../NETGENPlugin_NETGEN_3D_Remote_i.hxx | 58 ++ .../NETGENPlugin_NETGEN_3D_SA.cxx | 314 ++++++ .../NETGENPlugin_NETGEN_3D_SA.hxx | 89 ++ src/NETGENPlugin/NETGENPlugin_Runner.cxx | 955 ------------------ src/NETGENPlugin/NETGENPlugin_Runner.hxx | 117 --- src/NETGENPlugin/NETGENPlugin_Runner_main.cxx | 13 +- src/NETGENPlugin/NETGENPlugin_i.cxx | 3 + 15 files changed, 1034 insertions(+), 1380 deletions(-) create mode 100644 src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx create mode 100644 src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx create mode 100644 src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.cxx create mode 100644 src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.hxx create mode 100644 src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx create mode 100644 src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx delete mode 100644 src/NETGENPlugin/NETGENPlugin_Runner.cxx delete mode 100644 src/NETGENPlugin/NETGENPlugin_Runner.hxx diff --git a/idl/NETGENPlugin_Algorithm.idl b/idl/NETGENPlugin_Algorithm.idl index 85a1ce8..01b0d19 100644 --- a/idl/NETGENPlugin_Algorithm.idl +++ b/idl/NETGENPlugin_Algorithm.idl @@ -44,6 +44,13 @@ module NETGENPlugin { }; + /*! + * NETGENPlugin_NETGEN_3D: interface of "Remote Tetrahedron (Netgen)" algorithm + */ + interface NETGENPlugin_NETGEN_3D_Remote : NETGENPlugin::NETGENPlugin_NETGEN_3D + { + }; + /*! * NETGENPlugin_NETGEN_2D: interface of "Netgen 1D-2D" algorithm */ @@ -111,10 +118,10 @@ module NETGENPlugin void SetQuadAllowed(in boolean value); boolean GetQuadAllowed(); - + void SetUseSurfaceCurvature(in boolean value); boolean GetUseSurfaceCurvature(); - + void SetFuseEdges(in boolean value); boolean GetFuseEdges(); diff --git a/src/NETGENPlugin/CMakeLists.txt b/src/NETGENPlugin/CMakeLists.txt index e28fea2..aa4746e 100644 --- a/src/NETGENPlugin/CMakeLists.txt +++ b/src/NETGENPlugin/CMakeLists.txt @@ -99,7 +99,9 @@ SET(NETGENEngine_HEADERS NETGENPlugin_Remesher_2D.hxx NETGENPlugin_Defs.hxx NETGENPlugin_DriverParam.hxx - NETGENPlugin_Runner.hxx + NETGENPlugin_NETGEN_3D_SA.hxx + NETGENPlugin_NETGEN_3D_Remote.hxx + NETGENPlugin_NETGEN_3D_Remote_i.hxx ) # --- sources --- @@ -127,8 +129,10 @@ SET(NETGENEngine_SOURCES NETGENPlugin_SimpleHypothesis_3D_i.cxx NETGENPlugin_Remesher_2D.cxx NETGENPlugin_i.cxx - NETGENPlugin_Runner.cxx NETGENPlugin_DriverParam.cxx + NETGENPlugin_NETGEN_3D_SA.cxx + NETGENPlugin_NETGEN_3D_Remote.cxx + NETGENPlugin_NETGEN_3D_Remote_i.cxx ) SET(NetgenRunner_SOURCES diff --git a/src/NETGENPlugin/NETGENPluginBuilder.py b/src/NETGENPlugin/NETGENPluginBuilder.py index 30adb63..8079f01 100644 --- a/src/NETGENPlugin/NETGENPluginBuilder.py +++ b/src/NETGENPlugin/NETGENPluginBuilder.py @@ -42,6 +42,7 @@ NETGEN_VERSION_MAJOR = NETGENPlugin.NETGEN_VERSION_MAJOR ## Algorithm type: Netgen tetrahedron 3D algorithm, see NETGEN_3D_Algorithm NETGEN_3D = "NETGEN_3D" +NETGEN_3D_Remote = "NETGEN_3D_Remote" ## Algorithm type: Netgen tetrahedron 1D-2D-3D algorithm, see NETGEN_1D2D3D_Algorithm NETGEN_1D2D3D = "NETGEN_2D3D" ## Algorithm type: Netgen triangle 1D-2D algorithm, see NETGEN_1D2D_Algorithm @@ -473,6 +474,37 @@ class NETGEN_3D_Algorithm(NETGEN_Algorithm): pass # end of NETGEN_3D_Algorithm class +## Tetrahedron 3D algorithm +# +# It can be created by calling smeshBuilder.Mesh.Tetrahedron() or smeshBuilder.Mesh.Tetrahedron( smeshBuilder.NETGEN, geom=0 ) +# +# This algorithm generates only 3D (volumes) elements for given geometrical shape +# and, in contrast to NETGEN_1D2D3D_Algorithm class, should be used in conjunction +# with other 1D and 2D meshing algorithms. +class NETGEN_3D_Remote_Algorithm(NETGEN_3D_Algorithm): + + ## type of algorithm used with helper function in smeshBuilder.Mesh class + # @internal + algoType = NETGEN_3D_Remote + ## flag pointing either this algorithm should be used by default in dynamic method + # of smeshBuilder.Mesh class + # @internal + isDefault = False + ## doc string of the method + # @internal + docHelper = "Remotely Creates tetrahedron 3D algorithm for solids" + + ## Private constructor. + # @param mesh parent mesh object algorithm is assigned to + # @param geom geometry (shape/sub-shape) algorithm is assigned to; + # if it is @c 0 (default), the algorithm is assigned to the main shape + def __init__(self, mesh, geom=0): + NETGEN_3D_Algorithm.__init__(self, mesh, geom) + pass + + pass # end of NETGEN_3D_Remote_Algorithm class + + ## Triangle (helper) 1D-2D algorithm # diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index d349265..8180d0b 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -32,6 +32,7 @@ #include "NETGENPlugin_Hypothesis.hxx" +// TODO: remove use of netgen_param #include "NETGENPlugin_DriverParam.hxx" #include @@ -48,8 +49,6 @@ #include #include #include -#include -#include #include @@ -69,12 +68,7 @@ #include #include -#include -#include - #include -#include -namespace fs = boost::filesystem; /* Netgen include files @@ -200,273 +194,6 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis (SMESH_Mesh& aMesh, } -void NETGENPlugin_NETGEN_3D::fillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams) -{ - aParams.maxh = hyp->GetMaxSize(); - aParams.minh = hyp->GetMinSize(); - aParams.segmentsperedge = hyp->GetNbSegPerEdge(); - aParams.grading = hyp->GetGrowthRate(); - aParams.curvaturesafety = hyp->GetNbSegPerRadius(); - aParams.secondorder = hyp->GetSecondOrder() ? 1 : 0; - aParams.quad = hyp->GetQuadAllowed() ? 1 : 0; - aParams.optimize = hyp->GetOptimize(); - aParams.fineness = hyp->GetFineness(); - aParams.uselocalh = hyp->GetSurfaceCurvature(); - aParams.merge_solids = hyp->GetFuseEdges(); - aParams.chordalError = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.; - aParams.optsteps2d = aParams.optimize ? hyp->GetNbSurfOptSteps() : 0; - aParams.optsteps3d = aParams.optimize ? hyp->GetNbVolOptSteps() : 0; - aParams.elsizeweight = hyp->GetElemSizeWeight(); - aParams.opterrpow = hyp->GetWorstElemMeasure(); - aParams.delaunay = hyp->GetUseDelauney(); - aParams.checkoverlap = hyp->GetCheckOverlapping(); - aParams.checkchartboundary = hyp->GetCheckChartBoundary(); -#ifdef NETGEN_V6 - // std::string - aParams.meshsizefilename = hyp->GetMeshSizeFile(); -#else - // const char* - aParams.meshsizefilename = hyp->GetMeshSizeFile(); -#endif -#ifdef NETGEN_V6 - aParams.closeedgefac = 2; -#else - aParams.closeedgefac = 0; -#endif -} - -// write in a binary file the orientation for each 2D element of the mesh -void NETGENPlugin_NETGEN_3D::exportElementOrientation(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - netgen_params& aParams, - const std::string output_file) -{ - SMESH_MesherHelper helper(aMesh); - NETGENPlugin_Internals internals( aMesh, aShape, /*is3D=*/true ); - SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); - std::map elemOrientation; - - for ( TopExp_Explorer exFa( aShape, TopAbs_FACE ); exFa.More(); exFa.Next()) - { - const TopoDS_Shape& aShapeFace = exFa.Current(); - int faceID = aMesh.GetMeshDS()->ShapeToIndex( aShapeFace ); - bool isInternalFace = internals.isInternalShape( faceID ); - bool isRev = false; - if ( !isInternalFace && - helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) - // IsReversedSubMesh() can work wrong on strongly curved faces, - // so we use it as less as possible - isRev = helper.IsReversedSubMesh( TopoDS::Face( aShapeFace )); - - const SMESHDS_SubMesh * aSubMeshDSFace = proxyMesh->GetSubMesh( aShapeFace ); - if ( !aSubMeshDSFace ) continue; - - SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - if ( aParams._quadraticMesh && - dynamic_cast< const SMESH_ProxyMesh::SubMesh*>( aSubMeshDSFace )) - { - // add medium nodes of proxy triangles to helper (#16843) - while ( iteratorElem->more() ) - helper.AddTLinks( static_cast< const SMDS_MeshFace* >( iteratorElem->next() )); - - iteratorElem = aSubMeshDSFace->GetElements(); - } - while ( iteratorElem->more() ) // loop on elements on a geom face - { - // check mesh face - const SMDS_MeshElement* elem = iteratorElem->next(); - if ( !elem ) - error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); - if ( elem->NbCornerNodes() != 3 ) - error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); - elemOrientation[elem->GetID()] = isRev; - } // loop on elements on a face - } // loop on faces of a SOLID or SHELL - - { - std::ofstream df(output_file, ios::out|ios::binary); - int size=elemOrientation.size(); - - df.write((char*)&size, sizeof(int)); - for(auto const& [id, orient]:elemOrientation){ - df.write((char*)&id, sizeof(vtkIdType)); - df.write((char*)&orient, sizeof(bool)); - } - } -} - -int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) -{ - aMesh.Lock(); - auto time0 = std::chrono::high_resolution_clock::now(); - SMESH_Hypothesis::Hypothesis_Status hypStatus; - CheckHypothesis(aMesh, aShape, hypStatus); - auto time1 = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(time1-time0); - std::cout << "Time for check_hypo: " << elapsed.count() * 1e-9 << std::endl; - - - // Temporary folder for run - fs::path tmp_folder = aMesh.tmp_folder / fs::unique_path(fs::path("Volume-%%%%-%%%%")); - fs::create_directories(tmp_folder); - // Using MESH2D generated after all triangles where created. - fs::path mesh_file=aMesh.tmp_folder / fs::path("Mesh2D.med"); - fs::path element_orientation_file=tmp_folder / fs::path("element_orientation.dat"); - fs::path new_element_file=tmp_folder / fs::path("new_elements.dat"); - fs::path tmp_mesh_file=tmp_folder / fs::path("tmp_mesh.med"); - // Not used kept for debug - //fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med"); - fs::path shape_file=tmp_folder / fs::path("shape.brep"); - fs::path param_file=tmp_folder / fs::path("netgen3d_param.txt"); - fs::path log_file=tmp_folder / fs::path("run.log"); - fs::path cmd_file=tmp_folder / fs::path("cmd.log"); - //TODO: Handle variable mesh_name - std::string mesh_name = "Maillage_1"; - - //Writing Shape - exportShape(shape_file.string(), aShape); - auto time2 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time2-time1); - std::cout << "Time for exportShape: " << elapsed.count() * 1e-9 << std::endl; - - //Writing hypo - netgen_params aParams; - fillParameters(_hypParameters, aParams); - - exportNetgenParams(param_file.string(), aParams); - auto time3 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time3-time2); - std::cout << "Time for fill+export param: " << elapsed.count() * 1e-9 << std::endl; - - // Exporting element orientation - exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); - auto time4 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time4-time3); - std::cout << "Time for exportElemOrient: " << elapsed.count() * 1e-9 << std::endl; - - aMesh.Unlock(); - // Calling run_mesher - // TODO: check if we need to handle the .exe for windows - std::string cmd; - fs::path run_mesher_exe = - fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/ - fs::path("bin")/ - fs::path("salome")/ - fs::path("NETGENPlugin_Runner"); - - cmd = run_mesher_exe.string() + - " NETGEN3D " + mesh_file.string() + " " - + shape_file.string() + " " - + param_file.string() + " " - + element_orientation_file.string() + " " - + std::to_string(aMesh.GetMesherNbThreads()) + " " - + new_element_file.string() + " " - + "NONE"; - // Writing command in log - { - std::ofstream flog(cmd_file.string()); - flog << cmd << endl; - flog << endl; - } - //std::cout << "Running command: " << std::endl; - //std::cout << cmd << std::endl; - - - // Building arguments for QProcess - QString program = run_mesher_exe.c_str(); - QStringList arguments; - arguments << "NETGEN3D"; - arguments << mesh_file.c_str(); - arguments << shape_file.c_str(); - arguments << param_file.c_str(); - arguments << element_orientation_file.c_str(); - arguments << std::to_string(aMesh.GetMesherNbThreads()).c_str(); - arguments << new_element_file.c_str(); - arguments << "NONE"; - QString out_file = log_file.c_str(); - QProcess myProcess; - myProcess.setStandardOutputFile(out_file); - - myProcess.start(program, arguments); - myProcess.waitForFinished(); - int ret = myProcess.exitStatus(); - - auto time5 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time5-time4); - std::cout << "Time for exec of run_mesher: " << elapsed.count() * 1e-9 << std::endl; - - if(ret != 0){ - // Run crahed - std::cout << "Issue with command: " << std::endl; - std::cout << "See log for more details: " << log_file.string() << std::endl; - std::cout << cmd << std::endl; - return false; - } - - aMesh.Lock(); - { - std::ifstream df(new_element_file.string(), ios::binary); - - int Netgen_NbOfNodes; - int Netgen_NbOfNodesNew; - int Netgen_NbOfTetra; - double Netgen_point[3]; - int Netgen_tetrahedron[4]; - int nodeID; - - SMESH_MesherHelper helper(aMesh); - // This function is mandatory for setElementsOnShape to work - helper.IsQuadraticSubMesh(aShape); - helper.SetElementsOnShape( true ); - - // Number of nodes in intial mesh - df.read((char*) &Netgen_NbOfNodes, sizeof(int)); - // Number of nodes added by netgen - df.read((char*) &Netgen_NbOfNodesNew, sizeof(int)); - - // Filling nodevec (correspondence netgen numbering mesh numbering) - vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); - //vector nodeTmpVec ( Netgen_NbOfNodesNew + 1 ); - SMESHDS_Mesh * meshDS = helper.GetMeshDS(); - for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) - { - //Id of the point - df.read((char*) &nodeID, sizeof(int)); - nodeVec.at(nodeIndex) = meshDS->FindNode(nodeID); - } - - // Add new points and update nodeVec - for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) - { - df.read((char *) &Netgen_point, sizeof(double)*3); - - nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], - Netgen_point[1], - Netgen_point[2]); - } - - // Add tetrahedrons - df.read((char*) &Netgen_NbOfTetra, sizeof(int)); - - for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) - { - df.read((char*) &Netgen_tetrahedron, sizeof(int)*4); - helper.AddVolume( - nodeVec.at( Netgen_tetrahedron[0] ), - nodeVec.at( Netgen_tetrahedron[1] ), - nodeVec.at( Netgen_tetrahedron[2] ), - nodeVec.at( Netgen_tetrahedron[3] )); - } - } - auto time7 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time7-time5); - std::cout << "Time for exec of add_in_mesh: " << elapsed.count() * 1e-9 << std::endl; - - aMesh.Unlock(); - - return true; -} //============================================================================= /*! @@ -479,7 +206,7 @@ int NETGENPlugin_NETGEN_3D::RemoteCompute(SMESH_Mesh& aMesh, * */ - bool getSurfaceElements( +bool NETGENPlugin_NETGEN_3D::getSurfaceElements( SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, SMESH_ProxyMesh::Ptr proxyMesh, @@ -851,9 +578,6 @@ bool NETGENPlugin_NETGEN_3D::Compute( SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { - if(aMesh.IsParallel()) - return RemoteCompute(aMesh, aShape); - // vector of nodes in which node index == netgen ID vector< const SMDS_MeshNode* > nodeVec; NETGENPlugin_NetgenLibWrapper ngLib; diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx index 03df7fe..69f7065 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx @@ -38,6 +38,7 @@ #include "Utils_SALOME_Exception.hxx" #include +#include class StdMeshers_ViscousLayers; class StdMeshers_MaxElementVolume; @@ -70,7 +71,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo const TopoDS_Shape& aShape, MapShapeNbElems& aResMap); - static bool computeFillNgMesh( + bool computeFillNgMesh( SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, std::vector< const SMDS_MeshNode* > &nodeVec, @@ -79,7 +80,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo netgen_params &aParams, int &Netgen_NbOfNodes); - static bool computePrepareParam( + bool computePrepareParam( SMESH_Mesh& aMesh, NETGENPlugin_NetgenLibWrapper &ngLib, netgen::OCCGeometry &occgeo, @@ -87,7 +88,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo netgen_params &aParams, int &endWith); - static bool computeRunMesher( + bool computeRunMesher( netgen::OCCGeometry &occgeo, std::vector< const SMDS_MeshNode* > &nodeVec, netgen::Mesh* ngMesh, @@ -95,7 +96,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo netgen_params &aParams, int &startWith, int &endWith); - static bool computeFillMesh( + bool computeFillMesh( std::vector< const SMDS_MeshNode* > &nodeVec, NETGENPlugin_NetgenLibWrapper &ngLib, SMESH_MesherHelper &helper, @@ -103,18 +104,14 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo protected: - void exportElementOrientation(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - netgen_params& aParams, - const std::string output_file); - - void fillParameters(const NETGENPlugin_Hypothesis* hyp, - netgen_params &aParams); - - int RemoteCompute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); - - + virtual bool getSurfaceElements( + SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_ProxyMesh::Ptr proxyMesh, + NETGENPlugin_Internals &internals, + SMESH_MesherHelper &helper, + netgen_params &aParams, + std::map>& listElements); bool compute(SMESH_Mesh& mesh, SMESH_MesherHelper& helper, diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx new file mode 100644 index 0000000..3b5d61c --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx @@ -0,0 +1,351 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +//============================================================================= +// File : NETGENPlugin_NETGEN_3D_Remote.cxx +// Created : lundi 19 Septembre 2022 +// Author : Yoann AUDOUIN (CEA) +// Project : SALOME +//============================================================================= +// +// +#include "NETGENPlugin_NETGEN_3D_Remote.hxx" + +#include "NETGENPlugin_NETGEN_3D.hxx" + +#include "NETGENPlugin_DriverParam.hxx" +#include "NETGENPlugin_Hypothesis.hxx" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +namespace fs = boost::filesystem; + +/* + Netgen include files +*/ + +#ifndef OCCGEOMETRY +#define OCCGEOMETRY +#endif +#include + +#ifdef NETGEN_V5 +#include +#endif +#ifdef NETGEN_V6 +#include +#endif + +namespace nglib { +#include +} +namespace netgen { + + NETGENPLUGIN_DLL_HEADER + extern MeshingParameters mparam; + + NETGENPLUGIN_DLL_HEADER + extern volatile multithreadt multithread; +} +using namespace nglib; + +//============================================================================= +/*! + * + */ +//============================================================================= + +NETGENPlugin_NETGEN_3D_Remote::NETGENPlugin_NETGEN_3D_Remote(int hypId, SMESH_Gen * gen) + : NETGENPlugin_NETGEN_3D(hypId, gen) +{ + _name = "NETGEN_3D_Remote"; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +NETGENPlugin_NETGEN_3D_Remote::~NETGENPlugin_NETGEN_3D_Remote() +{ +} + + +void NETGENPlugin_NETGEN_3D_Remote::fillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams) +{ + aParams.maxh = hyp->GetMaxSize(); + aParams.minh = hyp->GetMinSize(); + aParams.segmentsperedge = hyp->GetNbSegPerEdge(); + aParams.grading = hyp->GetGrowthRate(); + aParams.curvaturesafety = hyp->GetNbSegPerRadius(); + aParams.secondorder = hyp->GetSecondOrder() ? 1 : 0; + aParams.quad = hyp->GetQuadAllowed() ? 1 : 0; + aParams.optimize = hyp->GetOptimize(); + aParams.fineness = hyp->GetFineness(); + aParams.uselocalh = hyp->GetSurfaceCurvature(); + aParams.merge_solids = hyp->GetFuseEdges(); + aParams.chordalError = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.; + aParams.optsteps2d = aParams.optimize ? hyp->GetNbSurfOptSteps() : 0; + aParams.optsteps3d = aParams.optimize ? hyp->GetNbVolOptSteps() : 0; + aParams.elsizeweight = hyp->GetElemSizeWeight(); + aParams.opterrpow = hyp->GetWorstElemMeasure(); + aParams.delaunay = hyp->GetUseDelauney(); + aParams.checkoverlap = hyp->GetCheckOverlapping(); + aParams.checkchartboundary = hyp->GetCheckChartBoundary(); +#ifdef NETGEN_V6 + // std::string + aParams.meshsizefilename = hyp->GetMeshSizeFile(); +#else + // const char* + aParams.meshsizefilename = hyp->GetMeshSizeFile(); +#endif +#ifdef NETGEN_V6 + aParams.closeedgefac = 2; +#else + aParams.closeedgefac = 0; +#endif +} + +// write in a binary file the orientation for each 2D element of the mesh +void NETGENPlugin_NETGEN_3D_Remote::exportElementOrientation(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + netgen_params& aParams, + const std::string output_file) +{ + SMESH_MesherHelper helper(aMesh); + NETGENPlugin_Internals internals( aMesh, aShape, /*is3D=*/true ); + SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); + std::map elemOrientation; + + for ( TopExp_Explorer exFa( aShape, TopAbs_FACE ); exFa.More(); exFa.Next()) + { + const TopoDS_Shape& aShapeFace = exFa.Current(); + int faceID = aMesh.GetMeshDS()->ShapeToIndex( aShapeFace ); + bool isInternalFace = internals.isInternalShape( faceID ); + bool isRev = false; + if ( !isInternalFace && + helper.NbAncestors(aShapeFace, aMesh, aShape.ShapeType()) > 1 ) + // IsReversedSubMesh() can work wrong on strongly curved faces, + // so we use it as less as possible + isRev = helper.IsReversedSubMesh( TopoDS::Face( aShapeFace )); + + const SMESHDS_SubMesh * aSubMeshDSFace = proxyMesh->GetSubMesh( aShapeFace ); + if ( !aSubMeshDSFace ) continue; + + SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); + if ( aParams._quadraticMesh && + dynamic_cast< const SMESH_ProxyMesh::SubMesh*>( aSubMeshDSFace )) + { + // add medium nodes of proxy triangles to helper (#16843) + while ( iteratorElem->more() ) + helper.AddTLinks( static_cast< const SMDS_MeshFace* >( iteratorElem->next() )); + + iteratorElem = aSubMeshDSFace->GetElements(); + } + while ( iteratorElem->more() ) // loop on elements on a geom face + { + // check mesh face + const SMDS_MeshElement* elem = iteratorElem->next(); + if ( !elem ) + error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); + if ( elem->NbCornerNodes() != 3 ) + error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); + elemOrientation[elem->GetID()] = isRev; + } // loop on elements on a face + } // loop on faces of a SOLID or SHELL + + { + std::ofstream df(output_file, ios::out|ios::binary); + int size=elemOrientation.size(); + + df.write((char*)&size, sizeof(int)); + for(auto const& [id, orient]:elemOrientation){ + df.write((char*)&id, sizeof(vtkIdType)); + df.write((char*)&orient, sizeof(bool)); + } + } +} + + +bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape) +{ + aMesh.Lock(); + SMESH_Hypothesis::Hypothesis_Status hypStatus; + NETGENPlugin_NETGEN_3D::CheckHypothesis(aMesh, aShape, hypStatus); + + + // Temporary folder for run + fs::path tmp_folder = aMesh.tmp_folder / fs::unique_path(fs::path("Volume-%%%%-%%%%")); + fs::create_directories(tmp_folder); + // Using MESH2D generated after all triangles where created. + fs::path mesh_file=aMesh.tmp_folder / fs::path("Mesh2D.med"); + fs::path element_orientation_file=tmp_folder / fs::path("element_orientation.dat"); + fs::path new_element_file=tmp_folder / fs::path("new_elements.dat"); + fs::path tmp_mesh_file=tmp_folder / fs::path("tmp_mesh.med"); + // Not used kept for debug + //fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med"); + fs::path shape_file=tmp_folder / fs::path("shape.brep"); + fs::path param_file=tmp_folder / fs::path("netgen3d_param.txt"); + fs::path log_file=tmp_folder / fs::path("run.log"); + fs::path cmd_file=tmp_folder / fs::path("cmd.log"); + //TODO: Handle variable mesh_name + std::string mesh_name = "Maillage_1"; + + //Writing Shape + exportShape(shape_file.string(), aShape); + + //Writing hypo + netgen_params aParams; + std::cout << _hypParameters << std::endl; + fillParameters(_hypParameters, aParams); + + exportNetgenParams(param_file.string(), aParams); + + // Exporting element orientation + exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); + + aMesh.Unlock(); + // Calling run_mesher + // TODO: check if we need to handle the .exe for windows + std::string cmd; + fs::path run_mesher_exe = + fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/ + fs::path("bin")/ + fs::path("salome")/ + fs::path("NETGENPlugin_Runner"); + + cmd = run_mesher_exe.string() + + " NETGEN3D " + mesh_file.string() + " " + + shape_file.string() + " " + + param_file.string() + " " + + element_orientation_file.string() + " " + + std::to_string(aMesh.GetMesherNbThreads()) + " " + + new_element_file.string() + " " + + "NONE"; + // Writing command in log + { + std::ofstream flog(cmd_file.string()); + flog << cmd << endl; + flog << endl; + } + //std::cout << "Running command: " << std::endl; + //std::cout << cmd << std::endl; + + + // Building arguments for QProcess + QString program = run_mesher_exe.c_str(); + QStringList arguments; + arguments << "NETGEN3D"; + arguments << mesh_file.c_str(); + arguments << shape_file.c_str(); + arguments << param_file.c_str(); + arguments << element_orientation_file.c_str(); + arguments << std::to_string(aMesh.GetMesherNbThreads()).c_str(); + arguments << new_element_file.c_str(); + arguments << "NONE"; + QString out_file = log_file.c_str(); + QProcess myProcess; + myProcess.setStandardOutputFile(out_file); + + myProcess.start(program, arguments); + myProcess.waitForFinished(); + int ret = myProcess.exitStatus(); + + if(ret != 0){ + // Run crahed + std::cout << "Issue with command: " << std::endl; + std::cout << "See log for more details: " << log_file.string() << std::endl; + std::cout << cmd << std::endl; + return false; + } + + aMesh.Lock(); + { + std::ifstream df(new_element_file.string(), ios::binary); + + int Netgen_NbOfNodes; + int Netgen_NbOfNodesNew; + int Netgen_NbOfTetra; + double Netgen_point[3]; + int Netgen_tetrahedron[4]; + int nodeID; + + SMESH_MesherHelper helper(aMesh); + // This function is mandatory for setElementsOnShape to work + helper.IsQuadraticSubMesh(aShape); + helper.SetElementsOnShape( true ); + + // Number of nodes in intial mesh + df.read((char*) &Netgen_NbOfNodes, sizeof(int)); + // Number of nodes added by netgen + df.read((char*) &Netgen_NbOfNodesNew, sizeof(int)); + + // Filling nodevec (correspondence netgen numbering mesh numbering) + vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); + //vector nodeTmpVec ( Netgen_NbOfNodesNew + 1 ); + SMESHDS_Mesh * meshDS = helper.GetMeshDS(); + for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) + { + //Id of the point + df.read((char*) &nodeID, sizeof(int)); + nodeVec.at(nodeIndex) = meshDS->FindNode(nodeID); + } + + // Add new points and update nodeVec + for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) + { + df.read((char *) &Netgen_point, sizeof(double)*3); + + nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], + Netgen_point[1], + Netgen_point[2]); + } + + // Add tetrahedrons + df.read((char*) &Netgen_NbOfTetra, sizeof(int)); + + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) + { + df.read((char*) &Netgen_tetrahedron, sizeof(int)*4); + helper.AddVolume( + nodeVec.at( Netgen_tetrahedron[0] ), + nodeVec.at( Netgen_tetrahedron[1] ), + nodeVec.at( Netgen_tetrahedron[2] ), + nodeVec.at( Netgen_tetrahedron[3] )); + } + } + + aMesh.Unlock(); + + return true; +} \ No newline at end of file diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx new file mode 100644 index 0000000..bfa3bda --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx @@ -0,0 +1,74 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +//============================================================================= +// File : NETGENPlugin_NETGEN_3D_Remote.hxx +// Created : lundi 19 Septembre 2022 +// Author : Yoann AUDOUIN (EDF) +// Project : SALOME +//============================================================================= +// +#ifndef _NETGENPlugin_NETGEN_3D_REMOTE_HXX_ +#define _NETGENPlugin_NETGEN_3D_REMOTE_HXX_ + +#include "NETGENPlugin_NETGEN_3D.hxx" + +#include +#include + +class StdMeshers_ViscousLayers; +class StdMeshers_MaxElementVolume; +class NETGENPlugin_Hypothesis; +class NETGENPlugin_NetgenLibWrapper; +class netgen_params; +class SMDS_MeshNode; + +using namespace std; + +class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_Remote: public NETGENPlugin_NETGEN_3D +{ + public: + NETGENPlugin_NETGEN_3D_Remote(int hypId, SMESH_Gen* gen); + virtual ~NETGENPlugin_NETGEN_3D_Remote(); + + // Function whould not be used with remote Computing + bool CheckHypothesis (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + Hypothesis_Status& aStatus){aStatus = HYP_OK;return true;}; + + bool Compute(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape); + + + protected: + void exportElementOrientation(SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + netgen_params& aParams, + const std::string output_file); + + void fillParameters(const NETGENPlugin_Hypothesis* hyp, + netgen_params &aParams); + + +}; + +#endif diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.cxx new file mode 100644 index 0000000..5164fa0 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.cxx @@ -0,0 +1,80 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes +// File : NETGENPlugin_NETGEN_3D_Remote_i.cxx +// Author : Yoann AUDOUIN (EDF) +// Module : NETGENPlugin +// $Header$ +// +#include "NETGENPlugin_NETGEN_3D_Remote_i.hxx" +#include "SMESH_Gen.hxx" + +#include "Utils_CorbaException.hxx" +#include "utilities.h" + +using namespace std; + +//============================================================================= +/*! + * NETGENPlugin_NETGEN_3D_Remote_i::NETGENPlugin_NETGEN_3D_Remote_i + * + * Constructor + */ +//============================================================================= + +NETGENPlugin_NETGEN_3D_Remote_i::NETGENPlugin_NETGEN_3D_Remote_i( PortableServer::POA_ptr thePOA, + ::SMESH_Gen* theGenImpl ) + : SALOME::GenericObj_i( thePOA ), + SMESH_Hypothesis_i( thePOA ), + SMESH_Algo_i( thePOA ), + SMESH_3D_Algo_i( thePOA ) +{ + myBaseImpl = new ::NETGENPlugin_NETGEN_3D_Remote( theGenImpl->GetANewId(), + theGenImpl ); +} + +//============================================================================= +/*! + * NETGENPlugin_NETGEN_3D_Remote_i::~NETGENPlugin_NETGEN_3D_Remote_i + * + * Destructor + */ +//============================================================================= + +NETGENPlugin_NETGEN_3D_Remote_i::~NETGENPlugin_NETGEN_3D_Remote_i() +{ +} + +//============================================================================= +/*! + * NETGENPlugin_NETGEN_3D_Remote_i::GetImpl + * + * Get implementation + */ +//============================================================================= + +::NETGENPlugin_NETGEN_3D_Remote* NETGENPlugin_NETGEN_3D_Remote_i::GetImpl() +{ + return ( ::NETGENPlugin_NETGEN_3D_Remote* )myBaseImpl; +} + diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.hxx new file mode 100644 index 0000000..405d2a5 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.hxx @@ -0,0 +1,58 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +// SMESH SMESH_I : idl implementation based on 'SMESH' unit's classes +// File : NETGENPlugin_NETGEN_3D_Remote_i.hxx +// Author : Yoann AUDOUIN (EDF) +// Module : NETGENPlugin +// $Header$ +// +#ifndef _NETGENPlugin_NETGEN_3D_REMOTE_I_HXX_ +#define _NETGENPlugin_NETGEN_3D_REMOTE_I_HXX_ + +#include "NETGENPlugin_Defs.hxx" + +#include +#include CORBA_SERVER_HEADER(NETGENPlugin_Algorithm) + +#include "SMESH_3D_Algo_i.hxx" +#include "NETGENPlugin_NETGEN_3D_Remote.hxx" + +// ====================================================== +// NETGEN 3d algorithm +// ====================================================== +class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_Remote_i: + public virtual POA_NETGENPlugin::NETGENPlugin_NETGEN_3D_Remote, + public virtual SMESH_3D_Algo_i +{ +public: + // Constructor + NETGENPlugin_NETGEN_3D_Remote_i( PortableServer::POA_ptr thePOA, + ::SMESH_Gen* theGenImpl ); + // Destructor + virtual ~NETGENPlugin_NETGEN_3D_Remote_i(); + + // Get implementation + ::NETGENPlugin_NETGEN_3D_Remote* GetImpl(); +}; + +#endif diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx new file mode 100644 index 0000000..0ea8a20 --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx @@ -0,0 +1,314 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +//============================================================================= +// File : NETGENPlugin_NETGEN_3D_SA.cxx +// Created : lundi 19 Septembre 2022 +// Author : Yoann AUDOUIN (CEA) +// Project : SALOME +//============================================================================= +// +// +#include "NETGENPlugin_NETGEN_3D_SA.hxx" + +#include "NETGENPlugin_DriverParam.hxx" +#include "NETGENPlugin_Hypothesis.hxx" + +#include +#include +#include +#include +#include +#include + + +#include +namespace fs = boost::filesystem; + +/* + Netgen include files +*/ + +#ifndef OCCGEOMETRY +#define OCCGEOMETRY +#endif +#include + +#ifdef NETGEN_V5 +#include +#endif +#ifdef NETGEN_V6 +#include +#endif + +namespace nglib { +#include +} +namespace netgen { + + NETGENPLUGIN_DLL_HEADER + extern MeshingParameters mparam; + + NETGENPLUGIN_DLL_HEADER + extern volatile multithreadt multithread; +} +using namespace nglib; + +//============================================================================= +/*! + * + */ +//============================================================================= + +NETGENPlugin_NETGEN_3D_SA::NETGENPlugin_NETGEN_3D_SA() + : NETGENPlugin_NETGEN_3D(0, new SMESH_Gen()) +{ + _name = "NETGEN_3D_SA"; +} + +//============================================================================= +/*! + * + */ +//============================================================================= + +NETGENPlugin_NETGEN_3D_SA::~NETGENPlugin_NETGEN_3D_SA() +{ +} + + +bool NETGENPlugin_NETGEN_3D_SA::computeFillNewElementFile( + std::vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + std::string new_element_file, + int &Netgen_NbOfNodes +) +{ + Ng_Mesh* Netgen_mesh = ngLib.ngMesh(); + + int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); + int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); + + bool isOK = ( Netgen_NbOfTetra > 0 ); + if ( isOK && !new_element_file.empty() ) + { + std::ofstream df(new_element_file, ios::out|ios::binary); + + double Netgen_point[3]; + int Netgen_tetrahedron[4]; + + // Writing nodevec (correspondence netgen numbering mesh numbering) + // Number of nodes + df.write((char*) &Netgen_NbOfNodes, sizeof(int)); + df.write((char*) &Netgen_NbOfNodesNew, sizeof(int)); + for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) + { + //Id of the point + int id = nodeVec.at(nodeIndex)->GetID(); + df.write((char*) &id, sizeof(int)); + } + + // Writing info on new points + for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) + { + Ng_GetPoint(Netgen_mesh, nodeIndex, Netgen_point ); + // Coordinates of the point + df.write((char *) &Netgen_point, sizeof(double)*3); + } + + // create tetrahedrons + df.write((char*) &Netgen_NbOfTetra, sizeof(int)); + for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) + { + Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); + df.write((char*) &Netgen_tetrahedron, sizeof(int)*4); + } + } + return false; +} + + +bool NETGENPlugin_NETGEN_3D_SA::Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, + std::string new_element_file, std::string element_orientation_file, + bool output_mesh) +{ + // vector of nodes in which node index == netgen ID + vector< const SMDS_MeshNode* > nodeVec; + NETGENPlugin_NetgenLibWrapper ngLib; + SMESH_MesherHelper helper(aMesh); + int startWith = netgen::MESHCONST_MESHVOLUME; + int endWith = netgen::MESHCONST_OPTVOLUME; + int Netgen_NbOfNodes=0; + + bool ret; + ret = NETGENPlugin_NETGEN_3D::computeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, aParams, Netgen_NbOfNodes); + if(ret) + return error( aParams._error, aParams._comment); + + netgen::OCCGeometry occgeo; + NETGENPlugin_NETGEN_3D::computePrepareParam(aMesh, ngLib, occgeo, helper, aParams, endWith); + + ret = NETGENPlugin_NETGEN_3D::computeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, aParams, startWith, endWith); + if(ret){ + if(aParams._error) + return error(aParams._error, aParams._comment); + + error(aParams._comment); + return true; + } + + computeFillNewElementFile(nodeVec, ngLib, new_element_file, Netgen_NbOfNodes); + + if(output_mesh) + NETGENPlugin_NETGEN_3D::computeFillMesh(nodeVec, ngLib, helper, Netgen_NbOfNodes); + + return false; +} + +int NETGENPlugin_NETGEN_3D_SA::run(const std::string input_mesh_file, + const std::string shape_file, + const std::string hypo_file, + const std::string element_orientation_file, + const std::string new_element_file, + const std::string output_mesh_file, + int nbThreads) +{ + + _element_orientation_file = element_orientation_file; + // Importing mesh + SMESH_Gen gen; + + std::unique_ptr myMesh(gen.CreateMesh(false)); + //TODO: To define + std::string mesh_name = "Maillage_1"; + + importMesh(input_mesh_file, *myMesh, mesh_name); + + // Importing shape + TopoDS_Shape myShape; + importShape(shape_file, myShape); + + // Importing hypothesis + netgen_params myParams; + + importNetgenParams(hypo_file, myParams, &gen); + // Setting number of threads for netgen + myParams.nbThreads = nbThreads; + + std::cout << "Meshing with netgen3d" << std::endl; + int ret = Compute(myShape, *myMesh, myParams, + new_element_file, element_orientation_file, + !output_mesh_file.empty()); + + + if(ret){ + std::cout << "Meshing failed" << std::endl; + return ret; + } + + if(!output_mesh_file.empty()){ + exportMesh(output_mesh_file, *myMesh, mesh_name); + } + + return ret; +} + + +bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements( + SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_ProxyMesh::Ptr proxyMesh, + NETGENPlugin_Internals &internals, + SMESH_MesherHelper &helper, + netgen_params &aParams, + std::map>& listElements + ) +{ + SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); + + // Get list of elements + their orientation from element_orientation file + std::map elemOrientation; + { + // Setting all element orientation to false if there no element orientation file + if(_element_orientation_file.empty()){ + std::cout << "No element orientation file" << std::endl; + + SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Face); + while ( iteratorElem->more() ) // loop on elements on a geom face + { + // check mesh face + const SMDS_MeshElement* elem = iteratorElem->next(); + elemOrientation[elem->GetID()] = false; + } + } else { + std::cout << "Reading from elements from file: " << _element_orientation_file << std::endl; + std::ifstream df(_element_orientation_file, ios::binary|ios::in); + int nbElement; + bool orient; + + // Warning of the use of vtkIdType (I had issue when run_mesher was compiled with internal vtk) and salome not + // Sizeof was the same but how he othered the type was different + // Maybe using another type (uint64_t) instead would be better + vtkIdType id; + df.read((char*)&nbElement, sizeof(int)); + + for(int ielem=0;ielemelementsIterator(SMDSAbs_Face); + bool isRev; + bool isInternalFace = false; + + bool isIn; + + while ( iteratorElem->more() ) // loop on elements on a geom face + { + // check mesh face + const SMDS_MeshElement* elem = iteratorElem->next(); + if ( !elem ){ + aParams._error = COMPERR_BAD_INPUT_MESH; + aParams._comment = "Null element encounters"; + return true; + } + if ( elem->NbCornerNodes() != 3 ){ + aParams._error = COMPERR_BAD_INPUT_MESH; + aParams._comment = "Not triangle element encounters"; + return true; + } + // Keeping only element that are in the element orientation file + isIn = elemOrientation.count(elem->GetID())==1; + if(!isIn) + continue; + // Get orientation + // Netgen requires that all the triangle point outside + isRev = elemOrientation[elem->GetID()]; + listElements[elem] = tuple(isRev, false); + } + + return false; +} diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx new file mode 100644 index 0000000..818060a --- /dev/null +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx @@ -0,0 +1,89 @@ +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com +// + +//============================================================================= +// File : NETGENPlugin_NETGEN_3D_SA.hxx +// Created : lundi 19 Septembre 2022 +// Author : Yoann AUDOUIN (EDF) +// Project : SALOME +//============================================================================= +// +#ifndef _NETGENPlugin_NETGEN_3D_SA_HXX_ +#define _NETGENPlugin_NETGEN_3D_SA_HXX_ + +#include "NETGENPlugin_NETGEN_3D.hxx" + +#include +#include + +class StdMeshers_ViscousLayers; +class StdMeshers_MaxElementVolume; +class NETGENPlugin_Hypothesis; +class NETGENPlugin_NetgenLibWrapper; +class netgen_params; +class SMDS_MeshNode; + +using namespace std; + +class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_SA: public NETGENPlugin_NETGEN_3D +{ + public: + NETGENPlugin_NETGEN_3D_SA(); + virtual ~NETGENPlugin_NETGEN_3D_SA(); + + bool Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, + std::string new_element_file, std::string element_orientation_file, + bool output_mesh); + + int run(const std::string input_mesh_file, + const std::string shape_file, + const std::string hypo_file, + const std::string element_orientation_file, + const std::string new_element_file, + const std::string output_mesh_file, + int nbThreads); + + + + protected: + + bool computeFillNewElementFile( + std::vector< const SMDS_MeshNode* > &nodeVec, + NETGENPlugin_NetgenLibWrapper &ngLib, + std::string new_element_file, + int &Netgen_NbOfNodes); + + bool getSurfaceElements( + SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_ProxyMesh::Ptr proxyMesh, + NETGENPlugin_Internals &internals, + SMESH_MesherHelper &helper, + netgen_params &aParams, + std::map>& listElements + ); + + std::string _element_orientation_file=""; + +}; + +#endif diff --git a/src/NETGENPlugin/NETGENPlugin_Runner.cxx b/src/NETGENPlugin/NETGENPlugin_Runner.cxx deleted file mode 100644 index 2107247..0000000 --- a/src/NETGENPlugin/NETGENPlugin_Runner.cxx +++ /dev/null @@ -1,955 +0,0 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : NETGENPlugin_Runner.cxx -// Author : Yoann AUDOUIN, EDF -// Module : SMESH -// - -#include "NETGENPlugin_Runner.hxx" - -#include "NETGENPlugin_NETGEN_3D.hxx" -#include "NETGENPlugin_DriverParam.hxx" - -#include -#include -#include -namespace fs = boost::filesystem; -#include - -// SMESH include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -// NETGENPlugin -// #include -// #include -#include "NETGENPlugin_Mesher.hxx" -#include "NETGENPlugin_Hypothesis.hxx" - - -// OCC include -#include -#include -#include -#include - -#include -#include -/* - Netgen include files -*/ - -#ifndef OCCGEOMETRY -#define OCCGEOMETRY -#endif -#include -#include - -#ifdef NETGEN_V5 -#include -#endif -#ifdef NETGEN_V6 -#include -#endif - -namespace nglib { -#include -} -namespace netgen { - - NETGENPLUGIN_DLL_HEADER - extern MeshingParameters mparam; - - NETGENPLUGIN_DLL_HEADER - extern volatile multithreadt multithread; - - NETGENPLUGIN_DLL_HEADER - extern bool merge_solids; - -#ifdef NETGEN_V5 - extern void OCCSetLocalMeshSize(OCCGeometry & geom, Mesh & mesh); -#endif -} -using namespace nglib; - -int error(int error_type, std::string msg) -{ - std::cerr << msg << std::endl; - return error_type; -}; - -int error(const SMESH_Comment& comment) -{ - return error(1, "SMESH_Comment error: "+comment); -}; - -/** - * @brief Set the netgen parameters - * - * @param aParams Internal structure of parameters - * @param mparams Netgen strcuture of parameters - */ -void set_netgen_parameters(netgen_params& aParams) -{ - - // Default parameters -#ifdef NETGEN_V6 - - //netgen::mparam.nthreads = std::thread::hardware_concurrency(); - netgen::mparam.nthreads = aParams.nbThreads; - netgen::mparam.parallel_meshing = aParams.nbThreads > 1; - - - if ( getenv( "SALOME_NETGEN_DISABLE_MULTITHREADING" )) - { - netgen::mparam.nthreads = 1; - netgen::mparam.parallel_meshing = false; - } - -#endif - - // Initialize global NETGEN parameters: - netgen::mparam.maxh = aParams.maxh; - netgen::mparam.minh = aParams.minh; - netgen::mparam.segmentsperedge = aParams.segmentsperedge; - netgen::mparam.grading = aParams.grading; - netgen::mparam.curvaturesafety = aParams.curvaturesafety; - netgen::mparam.secondorder = aParams.secondorder; - netgen::mparam.quad = aParams.quad; - netgen::mparam.uselocalh = aParams.uselocalh; - netgen::merge_solids = aParams.merge_solids; - netgen::mparam.optsteps2d = aParams.optsteps2d; - netgen::mparam.optsteps3d = aParams.optsteps3d; - netgen::mparam.elsizeweight = aParams.elsizeweight; - netgen::mparam.opterrpow = aParams.opterrpow; - netgen::mparam.delaunay = aParams.delaunay; - netgen::mparam.checkoverlap = aParams.checkoverlap; - netgen::mparam.checkchartboundary = aParams.checkchartboundary; -#ifdef NETGEN_V6 - // std::string - netgen::mparam.meshsizefilename = aParams.meshsizefilename; - netgen::mparam.closeedgefac = aParams.closeedgefac; - -#else - // const char* - netgen::mparam.meshsizefilename= aParams.meshsizefilename.empty() ? 0 : aParams.meshsizefilename.c_str(); -#endif -} - -/** - * @brief compute mesh with netgen3d - * - * @param input_mesh_file Input Mesh file - * @param shape_file Shape file - * @param hypo_file Parameter file - * @param new_element_file Binary file containing new nodes and new element info - * @param output_mesh If true will export mesh into output_mesh_file - * @param output_mesh_file Output Mesh file - * - * @return error code - */ -int netgen3d(const std::string input_mesh_file, - const std::string shape_file, - const std::string hypo_file, - const std::string element_orientation_file, - const std::string new_element_file, - const std::string output_mesh_file, - int nbThreads) -{ - // Importing mesh - SMESH_Gen gen; - - std::unique_ptr myMesh(gen.CreateMesh(false)); - //TODO: To define - std::string mesh_name = "Maillage_1"; - - importMesh(input_mesh_file, *myMesh, mesh_name); - - // Importing shape - TopoDS_Shape myShape; - importShape(shape_file, myShape); - - // Importing hypothesis - netgen_params myParams; - - importNetgenParams(hypo_file, myParams, &gen); - // Setting number of threads for netgen - myParams.nbThreads = nbThreads; - - std::cout << "Meshing with netgen3d" << std::endl; - int ret = netgen3dInternal(myShape, *myMesh, myParams, - new_element_file, element_orientation_file, - !output_mesh_file.empty()); - - - if(ret){ - std::cout << "Meshing failed" << std::endl; - return ret; - } - - if(!output_mesh_file.empty()){ - exportMesh(output_mesh_file, *myMesh, mesh_name); - } - - return ret; -} - - bool getSurfaceElements( - SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - SMESH_ProxyMesh::Ptr proxyMesh, - NETGENPlugin_Internals &internals, - SMESH_MesherHelper &helper, - netgen_params &aParams, - std::string element_orientation_file, - std::map>& listElements -) -{ - SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - - // Get list of elements + their orientation from element_orientation file - std::map elemOrientation; - { - // Setting all element orientation to false if there no element orientation file - if(element_orientation_file.empty()){ - SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Face); - while ( iteratorElem->more() ) // loop on elements on a geom face - { - // check mesh face - const SMDS_MeshElement* elem = iteratorElem->next(); - elemOrientation[elem->GetID()] = false; - } - } else { - std::ifstream df(element_orientation_file, ios::binary|ios::in); - int nbElement; - bool orient; - - // Warning of the use of vtkIdType (I had issue when run_mesher was compiled with internal vtk) and salome not - // Sizeof was the same but how he othered the type was different - // Maybe using another type (uint64_t) instead would be better - vtkIdType id; - df.read((char*)&nbElement, sizeof(int)); - - for(int ielem=0;ielemelementsIterator(SMDSAbs_Face); - bool isRev; - bool isInternalFace = false; - - bool isIn; - - while ( iteratorElem->more() ) // loop on elements on a geom face - { - // check mesh face - const SMDS_MeshElement* elem = iteratorElem->next(); - if ( !elem ){ - aParams._error = COMPERR_BAD_INPUT_MESH; - aParams._comment = "Null element encounters"; - return true; - } - if ( elem->NbCornerNodes() != 3 ){ - aParams._error = COMPERR_BAD_INPUT_MESH; - aParams._comment = "Not triangle element encounters"; - return true; - } - // Keeping only element that are in the element orientation file - isIn = elemOrientation.count(elem->GetID())==1; - if(!isIn) - continue; - // Get orientation - // Netgen requires that all the triangle point outside - isRev = elemOrientation[elem->GetID()]; - listElements[elem] = tuple(isRev, false); - } - - return false; -} - -bool mycomputeFillNgMesh( - SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - std::vector< const SMDS_MeshNode* > &nodeVec, - NETGENPlugin_NetgenLibWrapper &ngLib, - SMESH_MesherHelper &helper, - netgen_params &aParams, - std::string element_orientation_file, - int &Netgen_NbOfNodes) -{ - netgen::multithread.terminate = 0; - netgen::multithread.task = "Volume meshing"; - aParams._progressByTic = -1.; - - SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - - aParams._quadraticMesh = helper.IsQuadraticSubMesh(aShape); - helper.SetElementsOnShape( true ); - - Netgen_NbOfNodes = 0; - double Netgen_point[3]; - int Netgen_triangle[3]; - - Ng_Mesh * Netgen_mesh = (Ng_Mesh*)ngLib._ngMesh; - - { - const int invalid_ID = -1; - - SMESH::Controls::Area areaControl; - SMESH::Controls::TSequenceOfXYZ nodesCoords; - - // maps nodes to ng ID - typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap; - typedef TNodeToIDMap::value_type TN2ID; - TNodeToIDMap nodeToNetgenID; - - // find internal shapes - NETGENPlugin_Internals internals( aMesh, aShape, /*is3D=*/true ); - - // --------------------------------- - // Feed the Netgen with surface mesh - // --------------------------------- - bool isRev=false; - bool isInternalFace=false; - - SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); - if ( aParams._viscousLayersHyp ) - { - netgen::multithread.percent = 3; - proxyMesh = aParams._viscousLayersHyp->Compute( aMesh, aShape ); - if ( !proxyMesh ) - return false; - } - if ( aMesh.NbQuadrangles() > 0 ) - { - netgen::multithread.percent = 6; - StdMeshers_QuadToTriaAdaptor* Adaptor = new StdMeshers_QuadToTriaAdaptor; - Adaptor->Compute(aMesh,aShape,proxyMesh.get()); - proxyMesh.reset( Adaptor ); - } - - std::map> listElements; - bool ret = getSurfaceElements(aMesh, aShape, proxyMesh, internals, helper, aParams, element_orientation_file, listElements); - if(ret) - return ret; - - for ( auto const& [elem, info] : listElements ) // loop on elements on a geom face - { - isRev = get<0>(info); - isInternalFace = get<1>(info); - // Add nodes of triangles and triangles them-selves to netgen mesh - - // add three nodes of triangle - bool hasDegen = false; - for ( int iN = 0; iN < 3; ++iN ) - { - const SMDS_MeshNode* node = elem->GetNode( iN ); - const int shapeID = node->getshapeId(); - if ( node->GetPosition()->GetTypeOfPosition() == SMDS_TOP_EDGE && - helper.IsDegenShape( shapeID )) - { - // ignore all nodes on degeneraged edge and use node on its vertex instead - TopoDS_Shape vertex = TopoDS_Iterator( meshDS->IndexToShape( shapeID )).Value(); - node = SMESH_Algo::VertexNode( TopoDS::Vertex( vertex ), meshDS ); - hasDegen = true; - } - int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; - if ( ngID == invalid_ID ) - { - ngID = ++Netgen_NbOfNodes; - Netgen_point [ 0 ] = node->X(); - Netgen_point [ 1 ] = node->Y(); - Netgen_point [ 2 ] = node->Z(); - Ng_AddPoint(Netgen_mesh, Netgen_point); - } - Netgen_triangle[ isRev ? 2-iN : iN ] = ngID; - } - // add triangle - if ( hasDegen && (Netgen_triangle[0] == Netgen_triangle[1] || - Netgen_triangle[0] == Netgen_triangle[2] || - Netgen_triangle[2] == Netgen_triangle[1] )) - continue; - - Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); - - if ( isInternalFace && !proxyMesh->IsTemporary( elem )) - { - swap( Netgen_triangle[1], Netgen_triangle[2] ); - Ng_AddSurfaceElement(Netgen_mesh, NG_TRIG, Netgen_triangle); - } - } // loop on elements on a face - - // insert old nodes into nodeVec - nodeVec.resize( nodeToNetgenID.size() + 1, 0 ); - TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); - for ( ; n_id != nodeToNetgenID.end(); ++n_id ) - nodeVec[ n_id->second ] = n_id->first; - nodeToNetgenID.clear(); - - if ( internals.hasInternalVertexInSolid() ) - { - netgen::OCCGeometry occgeo; - NETGENPlugin_Mesher::AddIntVerticesInSolids( occgeo, - (netgen::Mesh&) *Netgen_mesh, - nodeVec, - internals); - } - } - Netgen_NbOfNodes = Ng_GetNP( Netgen_mesh ); - return false; -} - -bool mycomputeFillNewElementFile( - std::vector< const SMDS_MeshNode* > &nodeVec, - NETGENPlugin_NetgenLibWrapper &ngLib, - std::string new_element_file, - int &Netgen_NbOfNodes -) -{ - Ng_Mesh* Netgen_mesh = ngLib.ngMesh(); - - int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); - int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); - - bool isOK = ( Netgen_NbOfTetra > 0 ); - if ( isOK && !new_element_file.empty() ) - { - std::ofstream df(new_element_file, ios::out|ios::binary); - - double Netgen_point[3]; - int Netgen_tetrahedron[4]; - - // Writing nodevec (correspondence netgen numbering mesh numbering) - // Number of nodes - df.write((char*) &Netgen_NbOfNodes, sizeof(int)); - df.write((char*) &Netgen_NbOfNodesNew, sizeof(int)); - for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) - { - //Id of the point - int id = nodeVec.at(nodeIndex)->GetID(); - df.write((char*) &id, sizeof(int)); - } - - // Writing info on new points - for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) - { - Ng_GetPoint(Netgen_mesh, nodeIndex, Netgen_point ); - // Coordinates of the point - df.write((char *) &Netgen_point, sizeof(double)*3); - } - - // create tetrahedrons - df.write((char*) &Netgen_NbOfTetra, sizeof(int)); - for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTetra; ++elemIndex ) - { - Ng_GetVolumeElement(Netgen_mesh, elemIndex, Netgen_tetrahedron); - df.write((char*) &Netgen_tetrahedron, sizeof(int)*4); - } - } - return false; -} - -/** - * @brief Compute aShape within aMesh using netgen3d - * - * @param aShape the shape - * @param aMesh the mesh - * @param aParams the netgen parameters - * @param new_element_file file containing data on the new point/tetra added by netgen - * @param element_orientation_file file containing data on the orientation of each element to add to netgen - * @param output_mesh if true add element created by netgen into aMesh - * - * @return error code - */ -int netgen3dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, - std::string new_element_file, std::string element_orientation_file, - bool output_mesh) -{ - // vector of nodes in which node index == netgen ID - vector< const SMDS_MeshNode* > nodeVec; - NETGENPlugin_NetgenLibWrapper ngLib; - SMESH_MesherHelper helper(aMesh); - int startWith = netgen::MESHCONST_MESHVOLUME; - int endWith = netgen::MESHCONST_OPTVOLUME; - int Netgen_NbOfNodes=0; - - bool ret; - ret = mycomputeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, aParams, element_orientation_file, Netgen_NbOfNodes); - if(ret) - return error( aParams._error, aParams._comment); - - netgen::OCCGeometry occgeo; - NETGENPlugin_NETGEN_3D::computePrepareParam(aMesh, ngLib, occgeo, helper, aParams, endWith); - - ret = NETGENPlugin_NETGEN_3D::computeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, aParams, startWith, endWith); - if(ret){ - if(aParams._error) - return error(aParams._error, aParams._comment); - - error(aParams._comment); - return true; - } - - mycomputeFillNewElementFile(nodeVec, ngLib, new_element_file, Netgen_NbOfNodes); - - if(output_mesh) - NETGENPlugin_NETGEN_3D::computeFillMesh(nodeVec, ngLib, helper, Netgen_NbOfNodes); - - return false; -} - -/** - * @brief compute mesh with netgen2d - * - * @param input_mesh_file Input Mesh file - * @param shape_file Shape file - * @param hypo_file Parameter file - * @param new_element_file Binary file containing new nodes and new element info - * @param output_mesh If true will export mesh into output_mesh_file - * @param output_mesh_file Output Mesh file - * - * @return error code - */ -int netgen2d(const std::string input_mesh_file, - const std::string shape_file, - const std::string hypo_file, - const std::string element_orientation_file, - const std::string new_element_file, - const std::string output_mesh_file) -{ - - // Importing mesh - SMESH_Gen gen; - - std::unique_ptr myMesh(gen.CreateMesh(false)); - - //TODO: To define - std::string mesh_name = "Maillage_1"; - - importMesh(input_mesh_file, *myMesh, mesh_name); - - // Importing shape - TopoDS_Shape myShape; - importShape(shape_file, myShape); - - // Importing hypothesis - netgen_params myParams; - - importNetgenParams(hypo_file, myParams, &gen); - - std::cout << "Meshing with netgen3d" << std::endl; - int ret = netgen2dInternal(myShape, *myMesh, myParams, - new_element_file, element_orientation_file, - !output_mesh_file.empty()); - - if(!ret){ - std::cout << "Meshing failed" << std::endl; - return ret; - } - - if(!output_mesh_file.empty()) - exportMesh(output_mesh_file, *myMesh, mesh_name); - - return ret; -} - - -// TODO: Not working properly -/** - * @brief Compute aShape within aMesh using netgen2d - * - * @param aShape the shape - * @param aMesh the mesh - * @param aParams the netgen parameters - * @param new_element_file file containing data on the new point/tetra added by netgen - * - * @return error code - */ -int netgen2dInternal(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, - std::string new_element_file, std::string element_orientation_file, - bool output_mesh) -{ - netgen::multithread.terminate = 0; - netgen::multithread.task = "Surface meshing"; - - SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - SMESH_MesherHelper helper(aMesh); - helper.SetElementsOnShape( true ); - - NETGENPlugin_NetgenLibWrapper ngLib; - ngLib._isComputeOk = false; - - netgen::Mesh ngMeshNoLocSize; - netgen::Mesh * ngMeshes[2] = { (netgen::Mesh*) ngLib._ngMesh, & ngMeshNoLocSize }; - netgen::OCCGeometry occgeoComm; - - std::map elemOrientation; - - typedef map< const SMDS_MeshNode*, int, TIDCompare > TNodeToIDMap; - typedef TNodeToIDMap::value_type TN2ID; - const int invalid_ID = -1; - int Netgen_NbOfNodes=0; - double Netgen_point[3]; - int Netgen_segment[2]; - int Netgen_triangle[3]; - - // min / max sizes are set as follows: - // if ( _hypParameters ) - // min and max are defined by the user - // else if ( aParams.has_LengthFromEdges_hyp ) - // min = aMesher.GetDefaultMinSize() - // max = average segment len of a FACE - // else if ( _hypMaxElementArea ) - // min = aMesher.GetDefaultMinSize() - // max = f( _hypMaxElementArea ) - // else - // min = aMesher.GetDefaultMinSize() - // max = max segment len of a FACE - NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false); - set_netgen_parameters( aParams ); - const bool toOptimize = aParams.optimize; - if ( aParams.has_maxelementvolume_hyp ) - { - netgen::mparam.maxh = sqrt( 2. * aParams.maxElementVolume / sqrt(3.0) ); - } - netgen::mparam.quad = aParams.quad; - - // local size is common for all FACEs in aShape? - const bool isCommonLocalSize = ( !aParams.has_LengthFromEdges_hyp && !aParams.has_maxelementvolume_hyp && netgen::mparam.uselocalh ); - const bool isDefaultHyp = ( !aParams.has_LengthFromEdges_hyp && !aParams.has_maxelementvolume_hyp && !aParams.has_netgen_param ); - - - if ( isCommonLocalSize ) // compute common local size in ngMeshes[0] - { - //list< SMESH_subMesh* > meshedSM[4]; --> all sub-shapes are added to occgeoComm - aMesher.PrepareOCCgeometry( occgeoComm, aShape, aMesh );//, meshedSM ); - - // local size set at MESHCONST_ANALYSE step depends on - // minh, face_maxh, grading and curvaturesafety; find minh if not set by the user - if ( !aParams.has_netgen_param || netgen::mparam.minh < DBL_MIN ) - { - if ( !aParams.has_netgen_param ) - netgen::mparam.maxh = occgeoComm.GetBoundingBox().Diam() / 3.; - netgen::mparam.minh = aMesher.GetDefaultMinSize( aShape, netgen::mparam.maxh ); - } - // set local size depending on curvature and NOT closeness of EDGEs -#ifdef NETGEN_V6 - const double factor = 2; //netgen::occparam.resthcloseedgefac; -#else - const double factor = netgen::occparam.resthcloseedgefac; - netgen::occparam.resthcloseedgeenable = false; - netgen::occparam.resthcloseedgefac = 1.0 + netgen::mparam.grading; -#endif - occgeoComm.face_maxh = netgen::mparam.maxh; -#ifdef NETGEN_V6 - netgen::OCCParameters occparam; - netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0], netgen::mparam, occparam ); -#else - netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] ); -#endif - occgeoComm.emap.Clear(); - occgeoComm.vmap.Clear(); - - // Reading list of element to integrate into netgen mesh - { - std::ifstream df(element_orientation_file, ios::in|ios::binary); - int nbElement; - vtkIdType id; - bool orient; - df.read((char*)&nbElement, sizeof(int)); - - for(int ielem=0;ielemelementsIterator(SMDSAbs_Edge); - while ( iteratorElem->more() ) // loop on elements on a geom face - { - const SMDS_MeshElement* seg = iteratorElem->next(); - // Keeping only element that are in the element orientation file - isIn = elemOrientation.count(seg->GetID())==1; - - if(!isIn) - continue; - - SMESH_TNodeXYZ n1 = seg->GetNode(0); - SMESH_TNodeXYZ n2 = seg->GetNode(1); - gp_XYZ p = 0.5 * ( n1 + n2 ); - netgen::Point3d pi(p.X(), p.Y(), p.Z()); - ngMeshes[0]->RestrictLocalH( pi, factor * ( n1 - n2 ).Modulus() ); - } - - // set local size defined on shapes - aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] ); - aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMeshes[0] ); - try { - ngMeshes[0]->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); - } catch (netgen::NgException & ex) { - return error( COMPERR_BAD_PARMETERS, ex.What() ); - } - } - netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization - // ================== - // Loop on all FACEs - // ================== - - vector< const SMDS_MeshNode* > nodeVec; - - // prepare occgeom - netgen::OCCGeometry occgeom; - occgeom.shape = aShape; - occgeom.fmap.Add( aShape ); - occgeom.CalcBoundingBox(); - occgeom.facemeshstatus.SetSize(1); - occgeom.facemeshstatus = 0; - occgeom.face_maxh_modified.SetSize(1); - occgeom.face_maxh_modified = 0; - occgeom.face_maxh.SetSize(1); - occgeom.face_maxh = netgen::mparam.maxh; - - // ------------------------- - // Fill netgen mesh - // ------------------------- - // maps nodes to ng ID - - - // MESHCONST_ANALYSE step may lead to a failure, so we make an attempt - // w/o MESHCONST_ANALYSE at the second loop - int err = 0; - enum { LOC_SIZE, NO_LOC_SIZE }; - int iLoop = isCommonLocalSize ? 0 : 1; - int faceID = occgeom.fmap.FindIndex(aShape); - int solidID = 0; - for ( ; iLoop < 2; iLoop++ ) - { - //bool isMESHCONST_ANALYSE = false; - //TODO: check how to replace that - //InitComputeError(); - - netgen::Mesh * ngMesh = ngMeshes[ iLoop ]; - ngMesh->DeleteMesh(); - - if ( iLoop == NO_LOC_SIZE ) - { - ngMesh->SetGlobalH ( netgen::mparam.maxh ); - ngMesh->SetMinimalH( netgen::mparam.minh ); - netgen::Box<3> bb = occgeom.GetBoundingBox(); - bb.Increase (bb.Diam()/10); - ngMesh->SetLocalH (bb.PMin(), bb.PMax(), netgen::mparam.grading); - aMesher.SetLocalSize( occgeom, *ngMesh ); - aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMesh ); - try { - ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); - } catch (netgen::NgException & ex) { - return error( COMPERR_BAD_PARMETERS, ex.What() ); - } - } - - TNodeToIDMap nodeToNetgenID; - - nodeVec.clear(); - ngMesh->AddFaceDescriptor( netgen::FaceDescriptor( faceID, solidID, solidID, 0 )); - // set local size according to size of existing segments - SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Edge); - while ( iteratorElem->more() ) // loop on elements on a geom face - { - const SMDS_MeshElement* elem = iteratorElem->next(); - // Keeping only element that are in the element orientation file - bool isIn = elemOrientation.count(elem->GetID())==1; - - if(!isIn) - continue; - - bool isRev = elemOrientation[elem->GetID()]; - std::cerr << isRev; - - - - for ( int iN = 0; iN < 2; ++iN ) - { - const SMDS_MeshNode* node = elem->GetNode( iN ); - const int shapeID = node->getshapeId(); - int& ngID = nodeToNetgenID.insert(TN2ID( node, invalid_ID )).first->second; - if ( ngID == invalid_ID ) - { - ngID = ++Netgen_NbOfNodes; - Netgen_point [ 0 ] = node->X(); - Netgen_point [ 1 ] = node->Y(); - Netgen_point [ 2 ] = node->Z(); - netgen::MeshPoint mp( netgen::Point<3> (node->X(), node->Y(), node->Z()) ); - ngMesh->AddPoint ( mp, 1, netgen::EDGEPOINT ); - } - Netgen_segment[ isRev ? 1-iN : iN ] = ngID; - } - // add segment - - netgen::Segment seg; - seg[0] = Netgen_segment[0]; - seg[1] = Netgen_segment[1]; - seg.edgenr = ngMesh->GetNSeg() +1; - seg.si = faceID; - - ngMesh->AddSegment(seg); - } - int nbNodes2 = ngMesh->GetNP(); - int nseg = ngMesh->GetNSeg(); - - // insert old nodes into nodeVec - nodeVec.resize( nodeToNetgenID.size() + 1, 0 ); - TNodeToIDMap::iterator n_id = nodeToNetgenID.begin(); - for ( ; n_id != nodeToNetgenID.end(); ++n_id ) - nodeVec[ n_id->second ] = n_id->first; - nodeToNetgenID.clear(); - - - //if ( !isCommonLocalSize ) - //limitSize( ngMesh, mparam.maxh * 0.8); - - // ------------------------- - // Generate surface mesh - // ------------------------- - - const int startWith = netgen::MESHCONST_MESHSURFACE; - const int endWith = toOptimize ? netgen::MESHCONST_OPTSURFACE : netgen::MESHCONST_MESHSURFACE; - - SMESH_Comment str; - try { - OCC_CATCH_SIGNALS; - err = ngLib.GenerateMesh(occgeom, startWith, endWith, ngMesh); - if ( netgen::multithread.terminate ) - return false; - if ( err ) - str << "Error in netgen::OCCGenerateMesh() at " << netgen::multithread.task; - } - catch (Standard_Failure& ex) - { - err = 1; - str << "Exception in netgen::OCCGenerateMesh()" - << " at " << netgen::multithread.task - << ": " << ex.DynamicType()->Name(); - if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) - str << ": " << ex.GetMessageString(); - } - catch (...) { - err = 1; - str << "Exception in netgen::OCCGenerateMesh()" - << " at " << netgen::multithread.task; - } - if ( err ) - { - if ( iLoop == LOC_SIZE ) - { - std::cout << "Need second run" << std::endl; - /*netgen::mparam.minh = netgen::mparam.maxh; - netgen::mparam.maxh = 0; - for ( size_t iW = 0; iW < wires.size(); ++iW ) - { - StdMeshers_FaceSidePtr wire = wires[ iW ]; - const vector& uvPtVec = wire->GetUVPtStruct(); - for ( size_t iP = 1; iP < uvPtVec.size(); ++iP ) - { - SMESH_TNodeXYZ p( uvPtVec[ iP ].node ); - netgen::Point3d np( p.X(),p.Y(),p.Z()); - double segLen = p.Distance( uvPtVec[ iP-1 ].node ); - double size = ngMesh->GetH( np ); - netgen::mparam.minh = Min( netgen::mparam.minh, size ); - netgen::mparam.maxh = Max( netgen::mparam.maxh, segLen ); - } - } - //cerr << "min " << mparam.minh << " max " << mparam.maxh << endl; - netgen::mparam.minh *= 0.9; - netgen::mparam.maxh *= 1.1; - */ - continue; - } - else - { - //faceErr.reset( new SMESH_ComputeError( COMPERR_ALGO_FAILED, str )); - } - } - - // ---------------------------------------------------- - // Fill the SMESHDS with the generated nodes and faces - // ---------------------------------------------------- - - if(output_mesh) - { - int nbNodes = ngMesh->GetNP(); - int nbFaces = ngMesh->GetNSE(); - std::cout << nbFaces << " " << nbNodes << std::endl; - - int nbInputNodes = (int) nodeVec.size()-1; - nodeVec.resize( nbNodes+1, 0 ); - - // add nodes - for ( int ngID = nbInputNodes + 1; ngID <= nbNodes; ++ngID ) - { - const netgen::MeshPoint& ngPoint = ngMesh->Point( ngID ); - SMDS_MeshNode * node = meshDS->AddNode(ngPoint(0), ngPoint(1), ngPoint(2)); - nodeVec[ ngID ] = node; - } - - // create faces - int i,j; - for ( i = 1; i <= nbFaces ; ++i ) - { - Ng_GetVolumeElement(ngLib.ngMesh(), i, Netgen_triangle); - - helper.AddFace (nodeVec.at( Netgen_triangle[0] ), - nodeVec.at( Netgen_triangle[1] ), - nodeVec.at( Netgen_triangle[2] )); - - } - } // output_mesh - - break; - } // two attempts - //} // loop on FACEs - - return true; - -} diff --git a/src/NETGENPlugin/NETGENPlugin_Runner.hxx b/src/NETGENPlugin/NETGENPlugin_Runner.hxx deleted file mode 100644 index 6b762ed..0000000 --- a/src/NETGENPlugin/NETGENPlugin_Runner.hxx +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE -// -// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License, or (at your option) any later version. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// - -// File : NETGENPlugin_Runner.hxx -// Author : Yoann AUDOUIN, EDF -// Module : NETGEN -// - -#ifndef _NETGENPLUGIN_RUNNER_HXX_ -#define _NETGENPLUGIN_RUNNER_HXX_ - -#include -#include - -#include "NETGENPlugin_Defs.hxx" -#include "NETGENPlugin_Mesher.hxx" - -#include "SMESH_Algo.hxx" -#include "Utils_SALOME_Exception.hxx" - -class TopoDS_Shape; -class SMESH_Mesh; -class SMESH_Comment; -class netgen_params; -class NETGENPlugin_NetgenLibWrapper; -class SMDS_MeshNode; - -// Netgen 2d functions -int netgen2dInternal(TopoDS_Shape &aShape, - SMESH_Mesh& aMesh, - netgen_params& aParams, - std::string new_element_file, - std::string element_orientation_file, - bool output_mesh); -int netgen2d(const std::string input_mesh_file, - const std::string shape_file, - const std::string hypo_file, - const std::string element_orientation_file, - const std::string new_element_file, - const std::string output_mesh_file); - -// Netgen 3D functions -bool mycomputeFillNgMesh( - SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - std::vector< const SMDS_MeshNode* > &nodeVec, - NETGENPlugin_NetgenLibWrapper &ngLib, - SMESH_MesherHelper &helper, - netgen_params &aParams, - std::string element_orientation_file, - int &Netgen_NbOfNodes); - -bool mycomputePrepareParam( - SMESH_Mesh& aMesh, - NETGENPlugin_NetgenLibWrapper &ngLib, - netgen::OCCGeometry &occgeo, - SMESH_MesherHelper &helper, - netgen_params &aParams, - int &endWith); - -bool mycomputeRunMesher( - netgen::OCCGeometry &occgeo, - std::vector< const SMDS_MeshNode* > &nodeVec, - netgen::Mesh* ngMesh, - NETGENPlugin_NetgenLibWrapper &ngLib, - int &startWith, int &endWith); - -bool mycomputeFillNewElementFile( - std::vector< const SMDS_MeshNode* > &nodeVec, - NETGENPlugin_NetgenLibWrapper &ngLib, - std::string new_element_file, - int &Netgen_NbOfNodes); - -bool mycomputeFillMesh( - std::vector< const SMDS_MeshNode* > &nodeVec, - NETGENPlugin_NetgenLibWrapper &ngLib, - SMESH_MesherHelper &helper, - int &Netgen_NbOfNodes); - -int netgen3dInternal(TopoDS_Shape &aShape, - SMESH_Mesh& aMesh, - netgen_params& aParams, - std::string new_element_file, - std::string element_orientation_file, - bool output_mesh); -int netgen3d(const std::string input_mesh_file, - const std::string shape_file, - const std::string hypo_file, - const std::string element_orientation_file, - const std::string new_element_file, - const std::string output_mesh_file, - int nbThreads); - -//TODO: Tmp function replace by real error handling -int error(int error_type, std::string msg); -int error(const SMESH_Comment& comment); - -#endif \ No newline at end of file diff --git a/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx index e4c20a2..00eb381 100644 --- a/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx @@ -25,8 +25,7 @@ // Module : NETGEN // - -#include "NETGENPlugin_Runner.hxx" +#include "NETGENPlugin_NETGEN_3D_SA.hxx" #include #include @@ -84,7 +83,8 @@ int main(int argc, char *argv[]){ if (mesher=="NETGEN3D"){ auto begin = std::chrono::high_resolution_clock::now(); - netgen3d(input_mesh_file, + NETGENPlugin_NETGEN_3D_SA myplugin; + myplugin.run(input_mesh_file, shape_file, hypo_file, element_orientation_file, @@ -94,13 +94,6 @@ int main(int argc, char *argv[]){ auto end = std::chrono::high_resolution_clock::now(); auto elapsed = std::chrono::duration_cast(end - begin); std::cout << "Time elapsed: " << elapsed.count()*1e-9 << std::endl; - } else if (mesher=="NETGEN2D"){ - netgen2d(input_mesh_file, - shape_file, - hypo_file, - element_orientation_file, - new_element_file, - output_mesh_file); } else { std::cerr << "Unknown mesher:" << mesher << std::endl; } diff --git a/src/NETGENPlugin/NETGENPlugin_i.cxx b/src/NETGENPlugin/NETGENPlugin_i.cxx index 2dfc421..5394607 100644 --- a/src/NETGENPlugin/NETGENPlugin_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_i.cxx @@ -36,6 +36,7 @@ #include "NETGENPlugin_NETGEN_2D_ONLY_i.hxx" #include "NETGENPlugin_NETGEN_2D_i.hxx" #include "NETGENPlugin_NETGEN_3D_i.hxx" +#include "NETGENPlugin_NETGEN_3D_Remote_i.hxx" #include "NETGENPlugin_SimpleHypothesis_2D_i.hxx" #include "NETGENPlugin_SimpleHypothesis_3D_i.hxx" @@ -63,6 +64,8 @@ extern "C" // Algorithms if (strcmp(aHypName, "NETGEN_3D") == 0) aCreator = new NETGENPlugin_Creator_i; + else if (strcmp(aHypName, "NETGEN_3D_Remote") == 0) + aCreator = new NETGENPlugin_Creator_i; else if (strcmp(aHypName, "NETGEN_2D") == 0) aCreator = new NETGENPlugin_Creator_i; else if (strcmp(aHypName, "NETGEN_2D_ONLY") == 0) From a99d4c8ed2567755945433fd410b13bafd84dd12 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 21 Sep 2022 15:15:31 +0200 Subject: [PATCH 19/29] Removing hard coded meshname from Mesh import --- src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx | 2 -- src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx | 2 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx | 8 ++++---- src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx | 5 ++--- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx index 3212043..8e954f8 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx @@ -324,8 +324,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::RemoteCompute(SMESH_Mesh& aMesh, fs::path shape_file=tmp_folder / fs::path("shape.step"); fs::path param_file=tmp_folder / fs::path("netgen2d_param.txt"); fs::path log_file=tmp_folder / fs::path("run.log"); - //TODO: Handle variable mesh_name - std::string mesh_name = "Maillage_1"; //Writing Shape exportShape(shape_file.string(), aShape); diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx index 3b5d61c..3729fc5 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx @@ -219,7 +219,7 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, fs::path log_file=tmp_folder / fs::path("run.log"); fs::path cmd_file=tmp_folder / fs::path("cmd.log"); //TODO: Handle variable mesh_name - std::string mesh_name = "Maillage_1"; + std::string mesh_name = "MESH"; //Writing Shape exportShape(shape_file.string(), aShape); diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx index 0ea8a20..da00345 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx @@ -80,7 +80,7 @@ using namespace nglib; //============================================================================= NETGENPlugin_NETGEN_3D_SA::NETGENPlugin_NETGEN_3D_SA() - : NETGENPlugin_NETGEN_3D(0, new SMESH_Gen()) + : NETGENPlugin_NETGEN_3D(0, _gen=new SMESH_Gen()) { _name = "NETGEN_3D_SA"; } @@ -93,6 +93,8 @@ NETGENPlugin_NETGEN_3D_SA::NETGENPlugin_NETGEN_3D_SA() NETGENPlugin_NETGEN_3D_SA::~NETGENPlugin_NETGEN_3D_SA() { + if(_gen) + delete _gen; } @@ -198,10 +200,8 @@ int NETGENPlugin_NETGEN_3D_SA::run(const std::string input_mesh_file, SMESH_Gen gen; std::unique_ptr myMesh(gen.CreateMesh(false)); - //TODO: To define - std::string mesh_name = "Maillage_1"; - importMesh(input_mesh_file, *myMesh, mesh_name); + importMesh(input_mesh_file, *myMesh); // Importing shape TopoDS_Shape myShape; diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx index 818060a..6c10fb0 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx @@ -35,12 +35,10 @@ #include #include -class StdMeshers_ViscousLayers; -class StdMeshers_MaxElementVolume; -class NETGENPlugin_Hypothesis; class NETGENPlugin_NetgenLibWrapper; class netgen_params; class SMDS_MeshNode; +class SMESH_Gen; using namespace std; @@ -83,6 +81,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_SA: public NETGENPlugin_NETGEN_ ); std::string _element_orientation_file=""; + SMESH_Gen *_gen=nullptr; }; From 08f1ef4cc3b3d07e5aa9f9185abbf9b54d3f177e Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 21 Sep 2022 16:36:10 +0200 Subject: [PATCH 20/29] cout replaced by MESSAGE + clean up --- src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx | 8 ++++---- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 12 ------------ src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx | 11 +++++------ src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx | 11 ++++++----- 4 files changed, 15 insertions(+), 27 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx index 8e954f8..296ecc7 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx @@ -355,8 +355,8 @@ bool NETGENPlugin_NETGEN_2D_ONLY::RemoteCompute(SMESH_Mesh& aMesh, + output_mesh_file.string() + " >> " + log_file.string(); - std::cout << "Running command: " << std::endl; - std::cout << cmd << std::endl; + MESSAGE("Running command: "); + MESSAGE(cmd); // Writing command in log std::ofstream flog(log_file.string()); @@ -411,8 +411,8 @@ bool NETGENPlugin_NETGEN_2D_ONLY::RemoteCompute(SMESH_Mesh& aMesh, } } if(nodeVec.at(nodeIndex) == nullptr){ - std::cout << "Error could not identify id"; - return false; + std::cerr << "Error could not identify id"; + return true; } } diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index 8180d0b..b7c6d28 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -627,8 +627,6 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, vector< const SMDS_MeshNode* >& nodeVec, NETGENPlugin_NetgenLibWrapper& ngLib) { - auto time0 = std::chrono::high_resolution_clock::now(); - netgen::multithread.terminate = 0; netgen::Mesh* ngMesh = ngLib._ngMesh; @@ -691,7 +689,6 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, try { OCC_CATCH_SIGNALS; - auto time0 = std::chrono::high_resolution_clock::now(); ngLib.CalcLocalH(ngMesh); err = ngLib.GenerateMesh(occgeo, startWith, endWith); @@ -725,9 +722,6 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, str << " at " << netgen::multithread.task; error(str); } - auto time1 = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(time1-time0); - std::cout << "Time for seq:compute: " << elapsed.count() * 1e-9 << std::endl; int Netgen_NbOfNodesNew = Ng_GetNP(Netgen_mesh); int Netgen_NbOfTetra = Ng_GetNE(Netgen_mesh); @@ -774,10 +768,6 @@ bool NETGENPlugin_NETGEN_3D::compute(SMESH_Mesh& aMesh, } } } - auto time2 = std::chrono::high_resolution_clock::now(); - elapsed = std::chrono::duration_cast(time2-time1); - std::cout << "Time for seq:compute: " << elapsed.count() * 1e-9 << std::endl; - return !err; } @@ -903,14 +893,12 @@ double NETGENPlugin_NETGEN_3D::GetProgress() const strncmp( netgen::multithread.task, volMeshing, 3 ) == 0 )) { res = 0.001 + meshingRatio * netgen::multithread.percent / 100.; - //cout << netgen::multithread.task << " " <<_progressTic << "-" << netgen::multithread.percent << endl; } else // different otimizations { if ( _progressByTic < 0. ) ((NETGENPlugin_NETGEN_3D*)this)->_progressByTic = meshingRatio / _progressTic; res = _progressByTic * _progressTic; - //cout << netgen::multithread.task << " " << _progressTic << " " << res << endl; } return Min ( res, 0.98 ); } diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx index 3729fc5..dc70cf4 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx @@ -226,7 +226,6 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, //Writing hypo netgen_params aParams; - std::cout << _hypParameters << std::endl; fillParameters(_hypParameters, aParams); exportNetgenParams(param_file.string(), aParams); @@ -258,8 +257,8 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, flog << cmd << endl; flog << endl; } - //std::cout << "Running command: " << std::endl; - //std::cout << cmd << std::endl; + MESSAGE("Running command: "); + MESSAGE(cmd); // Building arguments for QProcess @@ -283,9 +282,9 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, if(ret != 0){ // Run crahed - std::cout << "Issue with command: " << std::endl; - std::cout << "See log for more details: " << log_file.string() << std::endl; - std::cout << cmd << std::endl; + std::cerr << "Issue with command: " << std::endl; + std::cerr << "See log for more details: " << log_file.string() << std::endl; + std::cerr << cmd << std::endl; return false; } diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx index da00345..3953896 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx @@ -214,19 +214,20 @@ int NETGENPlugin_NETGEN_3D_SA::run(const std::string input_mesh_file, // Setting number of threads for netgen myParams.nbThreads = nbThreads; - std::cout << "Meshing with netgen3d" << std::endl; + MESSAGE("Meshing with netgen3d"); int ret = Compute(myShape, *myMesh, myParams, new_element_file, element_orientation_file, !output_mesh_file.empty()); if(ret){ - std::cout << "Meshing failed" << std::endl; + std::cerr << "Meshing failed" << std::endl; return ret; } if(!output_mesh_file.empty()){ - exportMesh(output_mesh_file, *myMesh, mesh_name); + std::string meshName = "MESH"; + exportMesh(output_mesh_file, *myMesh, meshName); } return ret; @@ -250,7 +251,7 @@ bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements( { // Setting all element orientation to false if there no element orientation file if(_element_orientation_file.empty()){ - std::cout << "No element orientation file" << std::endl; + MESSAGE("No element orientation file"); SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Face); while ( iteratorElem->more() ) // loop on elements on a geom face @@ -260,7 +261,7 @@ bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements( elemOrientation[elem->GetID()] = false; } } else { - std::cout << "Reading from elements from file: " << _element_orientation_file << std::endl; + MESSAGE("Reading from elements from file: " << _element_orientation_file); std::ifstream df(_element_orientation_file, ios::binary|ios::in); int nbElement; bool orient; From 9f2b637978667bbb381e26b976c5ca0d58ade7ac Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 28 Sep 2022 08:06:51 +0200 Subject: [PATCH 21/29] Cleanup of NETGEN_2D_Only --- src/NETGENPlugin/NETGENPlugin_Mesher.cxx | 121 +++++---- .../NETGENPlugin_NETGEN_2D_ONLY.cxx | 255 +----------------- .../NETGENPlugin_NETGEN_2D_ONLY.hxx | 12 - 3 files changed, 76 insertions(+), 312 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx index 56c8e1b..168cf55 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx @@ -572,7 +572,7 @@ void NETGENPlugin_Mesher::SetSelfPointer( NETGENPlugin_Mesher ** ptr ) //================================================================================ /*! - * \brief Initialize given NETGEN parameters with default values + * \brief Initialize global NETGEN parameters with default values */ //================================================================================ @@ -613,72 +613,75 @@ void NETGENPlugin_Mesher::SetDefaultParameters() #endif } -//================================================================================ +//============================================================================= /*! - * \brief Initialize global NETGEN parameters with default values + * Pass parameters to NETGEN */ -//================================================================================ - +//============================================================================= void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp) { - netgen::MeshingParameters& mparams = netgen::mparam; - // Initialize global NETGEN parameters: - // maximal mesh segment size - mparams.maxh = hyp->GetMaxSize(); - // maximal mesh element linear size - mparams.minh = hyp->GetMinSize(); - // minimal number of segments per edge - mparams.segmentsperedge = hyp->GetNbSegPerEdge(); - // rate of growth of size between elements - mparams.grading = hyp->GetGrowthRate(); - // safety factor for curvatures (elements per radius) - mparams.curvaturesafety = hyp->GetNbSegPerRadius(); - // create elements of second order - mparams.secondorder = hyp->GetSecondOrder() ? 1 : 0; - // quad-dominated surface meshing - mparams.quad = hyp->GetQuadAllowed() ? 1 : 0; - _optimize = hyp->GetOptimize(); - _fineness = hyp->GetFineness(); - mparams.uselocalh = hyp->GetSurfaceCurvature(); - netgen::merge_solids = hyp->GetFuseEdges(); - _chordalError = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.; - mparams.optsteps2d = _optimize ? hyp->GetNbSurfOptSteps() : 0; - mparams.optsteps3d = _optimize ? hyp->GetNbVolOptSteps() : 0; - mparams.elsizeweight = hyp->GetElemSizeWeight(); - mparams.opterrpow = hyp->GetWorstElemMeasure(); - mparams.delaunay = hyp->GetUseDelauney(); - mparams.checkoverlap = hyp->GetCheckOverlapping(); - mparams.checkchartboundary = hyp->GetCheckChartBoundary(); - _simpleHyp = NULL; - // mesh size file -#ifdef NETGEN_V6 - // std::string - mparams.meshsizefilename = hyp->GetMeshSizeFile(); -#else - // const char* - mparams.meshsizefilename= hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str(); -#endif - const NETGENPlugin_Hypothesis::TLocalSize& localSizes = hyp->GetLocalSizesAndEntries(); - if ( !localSizes.empty() ) + if (hyp) { - SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen(); - NETGENPlugin_Hypothesis::TLocalSize::const_iterator it = localSizes.begin(); - for ( ; it != localSizes.end() ; it++) + netgen::MeshingParameters& mparams = netgen::mparam; + // Initialize global NETGEN parameters: + // maximal mesh segment size + mparams.maxh = hyp->GetMaxSize(); + // maximal mesh element linear size + mparams.minh = hyp->GetMinSize(); + // minimal number of segments per edge + mparams.segmentsperedge = hyp->GetNbSegPerEdge(); + // rate of growth of size between elements + mparams.grading = hyp->GetGrowthRate(); + // safety factor for curvatures (elements per radius) + mparams.curvaturesafety = hyp->GetNbSegPerRadius(); + // create elements of second order + mparams.secondorder = hyp->GetSecondOrder() ? 1 : 0; + // quad-dominated surface meshing + mparams.quad = hyp->GetQuadAllowed() ? 1 : 0; + _optimize = hyp->GetOptimize(); + _fineness = hyp->GetFineness(); + mparams.uselocalh = hyp->GetSurfaceCurvature(); + netgen::merge_solids = hyp->GetFuseEdges(); + _chordalError = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.; + mparams.optsteps2d = _optimize ? hyp->GetNbSurfOptSteps() : 0; + mparams.optsteps3d = _optimize ? hyp->GetNbVolOptSteps() : 0; + mparams.elsizeweight = hyp->GetElemSizeWeight(); + mparams.opterrpow = hyp->GetWorstElemMeasure(); + mparams.delaunay = hyp->GetUseDelauney(); + mparams.checkoverlap = hyp->GetCheckOverlapping(); + mparams.checkchartboundary = hyp->GetCheckChartBoundary(); + _simpleHyp = NULL; + // mesh size file +#ifdef NETGEN_V6 + // std::string + mparams.meshsizefilename = hyp->GetMeshSizeFile(); +#else + // const char* + mparams.meshsizefilename= hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str(); +#endif + const NETGENPlugin_Hypothesis::TLocalSize& localSizes = hyp->GetLocalSizesAndEntries(); + if ( !localSizes.empty() ) { - std::string entry = (*it).first; - double val = (*it).second; - // -- - GEOM::GEOM_Object_var aGeomObj; - SALOMEDS::SObject_var aSObj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( entry.c_str() ); - if ( !aSObj->_is_nil() ) { - CORBA::Object_var obj = aSObj->GetObject(); - aGeomObj = GEOM::GEOM_Object::_narrow(obj); - aSObj->UnRegister(); + SMESH_Gen_i* smeshGen_i = SMESH_Gen_i::GetSMESHGen(); + NETGENPlugin_Hypothesis::TLocalSize::const_iterator it = localSizes.begin(); + for ( ; it != localSizes.end() ; it++) + { + std::string entry = (*it).first; + double val = (*it).second; + // -- + GEOM::GEOM_Object_var aGeomObj; + SALOMEDS::SObject_var aSObj = SMESH_Gen_i::GetSMESHGen()->getStudyServant()->FindObjectID( entry.c_str() ); + if ( !aSObj->_is_nil() ) { + CORBA::Object_var obj = aSObj->GetObject(); + aGeomObj = GEOM::GEOM_Object::_narrow(obj); + aSObj->UnRegister(); + } + TopoDS_Shape S = smeshGen_i->GeomObjectToShape( aGeomObj.in() ); + setLocalSize(S, val); } - TopoDS_Shape S = smeshGen_i->GeomObjectToShape( aGeomObj.in() ); - setLocalSize(S, val); } } + #ifdef NETGEN_V6 netgen::mparam.closeedgefac = 2; @@ -4498,7 +4501,7 @@ void NETGENPlugin_NetgenLibWrapper::setMesh( Ng_Mesh* mesh ) int NETGENPlugin_NetgenLibWrapper::GenerateMesh( netgen::OCCGeometry& occgeo, int startWith, int endWith, - netgen::Mesh* & ngMesh) + netgen::Mesh* & ngMesh ) { int err = 0; if ( !ngMesh ) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx index 296ecc7..9c122c3 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.cxx @@ -25,7 +25,6 @@ #include "NETGENPlugin_Mesher.hxx" #include "NETGENPlugin_Hypothesis_2D.hxx" -#include "NETGENPlugin_DriverParam.hxx" #include #include @@ -40,9 +39,6 @@ #include #include #include -#include "SMESH_DriverShape.hxx" -#include "SMESH_DriverMesh.hxx" - #include #include @@ -54,9 +50,6 @@ #include #include -#include -#include -namespace fs = boost::filesystem; /* Netgen include files */ @@ -81,7 +74,6 @@ using namespace std; using namespace netgen; using namespace nglib; - //============================================================================= /*! * @@ -136,7 +128,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh& aMesh, _hypParameters = 0; _progressByTic = -1; - const list& hyps = GetUsedHypothesis(aMesh, aShape, false); if (hyps.empty()) @@ -226,221 +217,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::CheckHypothesis (SMESH_Mesh& aMesh, // } // } - -// write in a binary file the orientation for each 2D element of the mesh -void NETGENPlugin_NETGEN_2D_ONLY::exportElementOrientation(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - netgen_params& aParams, - const std::string output_file) -{ - std::map elemOrientation; - - SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); - for ( TopExp_Explorer exEd( aShape, TopAbs_EDGE ); exEd.More(); exEd.Next()) - { - const TopoDS_Shape& aShapeEdge = exEd.Current(); - const SMESHDS_SubMesh * aSubMeshDSEdge = proxyMesh->GetSubMesh( aShapeEdge ); - if ( !aSubMeshDSEdge ) continue; - - SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSEdge->GetElements(); - while ( iteratorElem->more() ) // loop on elements on a geom face - { - const SMDS_MeshElement* elem = iteratorElem->next(); - elemOrientation[elem->GetID()] = aShapeEdge.Orientation() == TopAbs_INTERNAL; - } - } - - std::ofstream df(output_file, ios::out|ios::binary); - int size=elemOrientation.size(); - - df.write((char*)&size, sizeof(int)); - for(auto const& [id, orient]:elemOrientation){ - df.write((char*)&id, sizeof(vtkIdType)); - df.write((char*)&orient, sizeof(bool)); - } - df.close(); -} - -void NETGENPlugin_NETGEN_2D_ONLY::FillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams) -{ - //TODO: factorize code with the one from NETGEN3D - // Move in netgen_param ? - aParams.maxh = hyp->GetMaxSize(); - aParams.minh = hyp->GetMinSize(); - aParams.segmentsperedge = hyp->GetNbSegPerEdge(); - aParams.grading = hyp->GetGrowthRate(); - aParams.curvaturesafety = hyp->GetNbSegPerRadius(); - aParams.secondorder = hyp->GetSecondOrder() ? 1 : 0; - aParams.quad = hyp->GetQuadAllowed() ? 1 : 0; - aParams.optimize = hyp->GetOptimize(); - aParams.fineness = hyp->GetFineness(); - aParams.uselocalh = hyp->GetSurfaceCurvature(); - aParams.merge_solids = hyp->GetFuseEdges(); - aParams.chordalError = hyp->GetChordalErrorEnabled() ? hyp->GetChordalError() : -1.; - aParams.optsteps2d = aParams.optimize ? hyp->GetNbSurfOptSteps() : 0; - aParams.optsteps3d = aParams.optimize ? hyp->GetNbVolOptSteps() : 0; - aParams.elsizeweight = hyp->GetElemSizeWeight(); - aParams.opterrpow = hyp->GetWorstElemMeasure(); - aParams.delaunay = hyp->GetUseDelauney(); - aParams.checkoverlap = hyp->GetCheckOverlapping(); - aParams.checkchartboundary = hyp->GetCheckChartBoundary(); -#ifdef NETGEN_V6 - // std::string - aParams.meshsizefilename = hyp->GetMeshSizeFile(); -#else - // const char* - aParams.meshsizefilename = hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str(); -#endif -#ifdef NETGEN_V6 - aParams.closeedgefac = 2; -#else - aParams.closeedgefac = 0; -#endif - aParams.has_LengthFromEdges_hyp = _hypLengthFromEdges; -} -//============================================================================= -/*! - *Here we are going to use the NETGEN mesher remotely - */ -//============================================================================= - -bool NETGENPlugin_NETGEN_2D_ONLY::RemoteCompute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape) -{ - aMesh.Lock(); - SMESH_Hypothesis::Hypothesis_Status hypStatus; - CheckHypothesis(aMesh, aShape, hypStatus); - - // Temporary folder for run - fs::path tmp_folder = aMesh.tmp_folder / fs::unique_path(fs::path("Face-%%%%-%%%%")); - fs::create_directories(tmp_folder); - // Using MESH2D generated after all triangles where created. - fs::path mesh_file=aMesh.tmp_folder / fs::path("Mesh1D.med"); - fs::path element_orientation_file=tmp_folder / fs::path("element_orientation.dat"); - fs::path new_element_file=tmp_folder / fs::path("new_elements.dat"); - fs::path tmp_mesh_file=tmp_folder / fs::path("tmp_mesh.med"); - // TODO: Remove that file we do not use it - fs::path output_mesh_file=tmp_folder / fs::path("output_mesh.med"); - fs::path shape_file=tmp_folder / fs::path("shape.step"); - fs::path param_file=tmp_folder / fs::path("netgen2d_param.txt"); - fs::path log_file=tmp_folder / fs::path("run.log"); - - //Writing Shape - exportShape(shape_file.string(), aShape); - //Writing hypo - netgen_params aParams; - FillParameters(_hypParameters, aParams); - - exportNetgenParams(param_file.string(), aParams); - - // Exporting element orientation - exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); - - aMesh.Unlock(); - // Calling run_mesher - // TODO: check if we need to handle the .exe for windows - std::string cmd; - fs::path run_mesher_exe = - fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/ - fs::path("bin")/ - fs::path("salome")/ - fs::path("NETGENPlugin_Runner"); - cmd = run_mesher_exe.string() + - " NETGEN2D " + mesh_file.string() + " " - + shape_file.string() + " " - + param_file.string() + " " - + element_orientation_file.string() + " " - + new_element_file.string() + " " - + std::to_string(0) + " " - + output_mesh_file.string() + - " >> " + log_file.string(); - - MESSAGE("Running command: "); - MESSAGE(cmd); - - // Writing command in log - std::ofstream flog(log_file.string()); - flog << cmd << endl; - flog.close(); - - // TODO: Replace system by something else to handle redirection for windows - int ret = system(cmd.c_str()); - - // TODO: better error handling (display log ?) - if(ret != 0){ - // Run crahed - //throw Exception("Meshing failed"); - std::cerr << "Issue with command: " << std::endl; - std::cerr << cmd << std::endl; - return false; - } - - aMesh.Lock(); - std::ifstream df(new_element_file.string(), ios::binary); - - int Netgen_NbOfNodes; - int Netgen_NbOfNodesNew; - int Netgen_NbOfTria; - double Netgen_point[3]; - int Netgen_triangle[3]; - int nodeID; - - SMESH_MesherHelper helper(aMesh); - // This function is necessary so that SetElementOnShape works - int _quadraticMesh = helper.IsQuadraticSubMesh(aShape); - helper.SetElementsOnShape( true ); - - // Number of nodes in intial mesh - df.read((char*) &Netgen_NbOfNodes, sizeof(int)); - // Number of nodes added by netgen - df.read((char*) &Netgen_NbOfNodesNew, sizeof(int)); - - // Filling nodevec (correspondence netgen numbering mesh numbering) - vector< const SMDS_MeshNode* > nodeVec ( Netgen_NbOfNodesNew + 1 ); - for (int nodeIndex = 1 ; nodeIndex <= Netgen_NbOfNodes; ++nodeIndex ) - { - //Id of the point - df.read((char*) &nodeID, sizeof(int)); - nodeVec.at(nodeIndex) = nullptr; - SMDS_NodeIteratorPtr iteratorNode = aMesh.GetMeshDS()->nodesIterator(); - while(iteratorNode->more()){ - const SMDS_MeshNode* node = iteratorNode->next(); - if(node->GetID() == nodeID){ - nodeVec.at(nodeIndex) = node; - break; - } - } - if(nodeVec.at(nodeIndex) == nullptr){ - std::cerr << "Error could not identify id"; - return true; - } - } - - // Add new points and update nodeVec - for (int nodeIndex = Netgen_NbOfNodes +1 ; nodeIndex <= Netgen_NbOfNodesNew; ++nodeIndex ) - { - df.read((char *) &Netgen_point, sizeof(double)*3); - - nodeVec.at(nodeIndex) = helper.AddNode(Netgen_point[0], - Netgen_point[1], - Netgen_point[2]); - } - - // Add tetrahedrons - df.read((char*) &Netgen_NbOfTria, sizeof(int)); - for ( int elemIndex = 1; elemIndex <= Netgen_NbOfTria; ++elemIndex ) - { - df.read((char*) &Netgen_triangle, sizeof(int)*3); - helper.AddFace (nodeVec.at( Netgen_triangle[0] ), - nodeVec.at( Netgen_triangle[1] ), - nodeVec.at( Netgen_triangle[2] )); - } - df.close(); - - aMesh.Unlock(); - - return true; -} //============================================================================= /*! *Here we are going to use the NETGEN mesher @@ -450,12 +226,8 @@ bool NETGENPlugin_NETGEN_2D_ONLY::RemoteCompute(SMESH_Mesh& aMesh, bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { - - if(aMesh.IsParallel()) - return RemoteCompute(aMesh, aShape); - netgen::multithread.terminate = 0; - netgen::multithread.task = "Surface meshing"; + //netgen::multithread.task = "Surface meshing"; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); SMESH_MesherHelper helper(aMesh); @@ -480,6 +252,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, // else // min = aMesher.GetDefaultMinSize() // max = max segment len of a FACE + NETGENPlugin_Mesher aMesher( &aMesh, aShape, /*isVolume=*/false); aMesher.SetParameters( _hypParameters ); // _hypParameters -> netgen::mparam const bool toOptimize = _hypParameters ? _hypParameters->GetOptimize() : true; @@ -493,8 +266,6 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, // local size is common for all FACEs in aShape? const bool isCommonLocalSize = ( !_hypLengthFromEdges && !_hypMaxElementArea && netgen::mparam.uselocalh ); const bool isDefaultHyp = ( !_hypLengthFromEdges && !_hypMaxElementArea && !_hypParameters ); - aMesh.Unlock(); - if ( isCommonLocalSize ) // compute common local size in ngMeshes[0] { @@ -522,9 +293,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, netgen::OCCParameters occparam; netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0], netgen::mparam, occparam ); #else - aMesh.Lock(); netgen::OCCSetLocalMeshSize( occgeoComm, *ngMeshes[0] ); - aMesh.Unlock(); #endif occgeoComm.emap.Clear(); occgeoComm.vmap.Clear(); @@ -555,12 +324,13 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, aMesher.SetLocalSize( occgeoComm, *ngMeshes[0] ); aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMeshes[0] ); try { - ngMeshes[0]->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); + ngMeshes[0]->LoadLocalMeshSize( mparam.meshsizefilename ); } catch (NgException & ex) { return error( COMPERR_BAD_PARMETERS, ex.What() ); } } netgen::mparam.uselocalh = toOptimize; // restore as it is used at surface optimization + // ================== // Loop on all FACEs // ================== @@ -688,15 +458,15 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, if ( iLoop == NO_LOC_SIZE ) { - ngMesh->SetGlobalH ( netgen::mparam.maxh ); - ngMesh->SetMinimalH( netgen::mparam.minh ); + ngMesh->SetGlobalH ( mparam.maxh ); + ngMesh->SetMinimalH( mparam.minh ); Box<3> bb = occgeom.GetBoundingBox(); bb.Increase (bb.Diam()/10); - ngMesh->SetLocalH (bb.PMin(), bb.PMax(), netgen::mparam.grading); + ngMesh->SetLocalH (bb.PMin(), bb.PMax(), mparam.grading); aMesher.SetLocalSize( occgeom, *ngMesh ); aMesher.SetLocalSizeForChordalError( occgeoComm, *ngMesh ); try { - ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); + ngMesh->LoadLocalMeshSize( mparam.meshsizefilename ); } catch (NgException & ex) { return error( COMPERR_BAD_PARMETERS, ex.What() ); } @@ -709,7 +479,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, break; //if ( !isCommonLocalSize ) - //limitSize( ngMesh, netgen::mparam.maxh * 0.8); + //limitSize( ngMesh, mparam.maxh * 0.8); // ------------------------- // Generate surface mesh @@ -721,7 +491,9 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, SMESH_Comment str; try { OCC_CATCH_SIGNALS; + err = ngLib.GenerateMesh(occgeom, startWith, endWith, ngMesh); + if ( netgen::multithread.terminate ) return false; if ( err ) @@ -760,10 +532,10 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, double segLen = p.Distance( uvPtVec[ iP-1 ].node ); double size = ngMesh->GetH( np ); netgen::mparam.minh = Min( netgen::mparam.minh, size ); - netgen:: mparam.maxh = Max( netgen::mparam.maxh, segLen ); + netgen::mparam.maxh = Max( netgen::mparam.maxh, segLen ); } } - //cerr << "min " << mparam.minh << " max " << mparam.maxh << endl; + //cerr << "min " << netgen::mparam.minh << " max " << netgen::mparam.maxh << endl; netgen::mparam.minh *= 0.9; netgen::mparam.maxh *= 1.1; continue; @@ -774,6 +546,7 @@ bool NETGENPlugin_NETGEN_2D_ONLY::Compute(SMESH_Mesh& aMesh, } } + // ---------------------------------------------------- // Fill the SMESHDS with the generated nodes and faces // ---------------------------------------------------- diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx index b1361ed..b6402f9 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_2D_ONLY.hxx @@ -30,8 +30,6 @@ class StdMeshers_MaxElementArea; class StdMeshers_LengthFromEdges; class NETGENPlugin_Hypothesis_2D; -class NETGENPlugin_Hypothesis; -class netgen_params; /*! * \brief Mesher generating 2D elements on a geometrical face taking @@ -51,16 +49,6 @@ public: const TopoDS_Shape& aShape, Hypothesis_Status& aStatus); - void exportElementOrientation(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - netgen_params& aParams, - const std::string output_file); - - void FillParameters(const NETGENPlugin_Hypothesis* hyp, - netgen_params &aParams); - - virtual bool RemoteCompute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); virtual bool Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape); From 1a7929402906707448fcbf0e6c07a408647a8d12 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 3 Oct 2022 08:02:37 +0200 Subject: [PATCH 22/29] Using MeshLocker + implementing call to assign for remote plugin --- .../NETGENPlugin_NETGEN_3D_Remote.cxx | 52 ++++++++++++------- .../NETGENPlugin_NETGEN_3D_Remote.hxx | 6 ++- .../NETGENPlugin_NETGEN_3D_SA.hxx | 2 +- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx index dc70cf4..d0a1ad6 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx @@ -35,12 +35,15 @@ #include "NETGENPlugin_DriverParam.hxx" #include "NETGENPlugin_Hypothesis.hxx" +#include "Utils_SALOME_Exception.hxx" + #include #include #include #include #include #include +#include #include #include @@ -199,9 +202,11 @@ void NETGENPlugin_NETGEN_3D_Remote::exportElementOrientation(SMESH_Mesh& aMesh, bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { - aMesh.Lock(); - SMESH_Hypothesis::Hypothesis_Status hypStatus; - NETGENPlugin_NETGEN_3D::CheckHypothesis(aMesh, aShape, hypStatus); + { + SMESH_MeshLocker myLocker(&aMesh); + SMESH_Hypothesis::Hypothesis_Status hypStatus; + NETGENPlugin_NETGEN_3D::CheckHypothesis(aMesh, aShape, hypStatus); + } // Temporary folder for run @@ -221,19 +226,21 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, //TODO: Handle variable mesh_name std::string mesh_name = "MESH"; - //Writing Shape - exportShape(shape_file.string(), aShape); + { + SMESH_MeshLocker myLocker(&aMesh); + //Writing Shape + exportShape(shape_file.string(), aShape); - //Writing hypo - netgen_params aParams; - fillParameters(_hypParameters, aParams); + //Writing hypo + netgen_params aParams; + fillParameters(_hypParameters, aParams); - exportNetgenParams(param_file.string(), aParams); + exportNetgenParams(param_file.string(), aParams); - // Exporting element orientation - exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); + // Exporting element orientation + exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); + } - aMesh.Unlock(); // Calling run_mesher // TODO: check if we need to handle the .exe for windows std::string cmd; @@ -282,14 +289,14 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, if(ret != 0){ // Run crahed - std::cerr << "Issue with command: " << std::endl; - std::cerr << "See log for more details: " << log_file.string() << std::endl; - std::cerr << cmd << std::endl; - return false; + std::string msg = "Issue with command: \n"; + msg += "See log for more details: " + log_file.string() + "\n"; + msg += cmd + "\n"; + throw SALOME_Exception(msg); } - aMesh.Lock(); { + SMESH_MeshLocker myLocker(&aMesh); std::ifstream df(new_element_file.string(), ios::binary); int Netgen_NbOfNodes; @@ -344,7 +351,12 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, } } - aMesh.Unlock(); - return true; -} \ No newline at end of file +} + + +void NETGENPlugin_NETGEN_3D_Remote::setSubMeshesToCompute(SMESH_subMesh * aSubMesh) +{ + SMESH_MeshLocker myLocker(aSubMesh->GetFather()); + SMESH_Algo::setSubMeshesToCompute(aSubMesh); +} diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx index bfa3bda..210fa08 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx @@ -53,10 +53,12 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_Remote: public NETGENPlugin_NET // Function whould not be used with remote Computing bool CheckHypothesis (SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, - Hypothesis_Status& aStatus){aStatus = HYP_OK;return true;}; + Hypothesis_Status& aStatus) override {(void)aMesh;(void)aShape;aStatus = HYP_OK;return true;}; bool Compute(SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape); + const TopoDS_Shape& aShape) override; + + void setSubMeshesToCompute(SMESH_subMesh * aSubMesh) override; protected: diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx index 6c10fb0..b3ebe1a 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx @@ -78,7 +78,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_SA: public NETGENPlugin_NETGEN_ SMESH_MesherHelper &helper, netgen_params &aParams, std::map>& listElements - ); + ) override; std::string _element_orientation_file=""; SMESH_Gen *_gen=nullptr; From 15a5ceeea7596752fa86182dcf9f47329d4349b4 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 3 Oct 2022 08:04:00 +0200 Subject: [PATCH 23/29] Update of copyright --- src/NETGENPlugin/NETGENPlugin_DriverParam.cxx | 2 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx | 2 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.cxx | 2 +- src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx | 2 +- src/NETGENPlugin/NETGENPlugin_Runner_main.cxx | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx index dffeca8..183281d 100644 --- a/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx +++ b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx index d0a1ad6..199e406 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.cxx index 5164fa0..34bbe6d 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote_i.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx index 3953896..13fef9a 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS diff --git a/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx index 00eb381..8d2e11b 100644 --- a/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2021 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS From 54a50107a51a19801363d58ba573ccb1b8698fa0 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 3 Oct 2022 10:14:02 +0200 Subject: [PATCH 24/29] Cleanup use of netgen_params + restoring use of netgen error functions --- src/NETGENPlugin/NETGENPlugin_DriverParam.cxx | 36 +------- src/NETGENPlugin/NETGENPlugin_DriverParam.hxx | 19 +--- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 86 ++++++------------- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx | 4 - .../NETGENPlugin_NETGEN_3D_Remote.cxx | 5 +- .../NETGENPlugin_NETGEN_3D_Remote.hxx | 1 - .../NETGENPlugin_NETGEN_3D_SA.cxx | 81 +++++++++++------ .../NETGENPlugin_NETGEN_3D_SA.hxx | 5 +- 8 files changed, 90 insertions(+), 147 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx index 183281d..7369908 100644 --- a/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx +++ b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx @@ -26,10 +26,6 @@ // #include "NETGENPlugin_DriverParam.hxx" -#include "NETGENPlugin_Hypothesis.hxx" - -#include -#include #include #include @@ -76,7 +72,7 @@ void printNetgenParams(netgen_params& aParams){ * @param param_file Name of the file * @param aParams Structure to fill */ -void importNetgenParams(const std::string param_file, netgen_params& aParams, SMESH_Gen *gen){ +void importNetgenParams(const std::string param_file, netgen_params& aParams){ std::ifstream myfile(param_file); std::string line; @@ -133,36 +129,6 @@ void importNetgenParams(const std::string param_file, netgen_params& aParams, SM std::getline(myfile, line); aParams.maxElementVolume = std::stoi(line); - if(aParams.has_netgen_param){ - aParams._hypParameters = new NETGENPlugin_Hypothesis(0, gen); - - aParams._hypParameters->SetMaxSize(aParams.maxh); - aParams._hypParameters->SetMinSize(aParams.minh); - aParams._hypParameters->SetNbSegPerEdge(aParams.segmentsperedge); - aParams._hypParameters->SetGrowthRate(aParams.grading); - aParams._hypParameters->SetNbSegPerRadius(aParams.curvaturesafety); - aParams._hypParameters->SetSecondOrder(aParams.secondorder); - aParams._hypParameters->SetQuadAllowed(aParams.quad); - aParams._hypParameters->SetOptimize(aParams.optimize); - aParams._hypParameters->SetFineness((NETGENPlugin_Hypothesis::Fineness)aParams.fineness); - aParams._hypParameters->SetSurfaceCurvature(aParams.uselocalh); - aParams._hypParameters->SetFuseEdges(aParams.merge_solids); - aParams._hypParameters->SetChordalErrorEnabled(aParams.chordalError); - if(aParams.optimize){ - aParams._hypParameters->SetNbSurfOptSteps(aParams.optsteps2d); - aParams._hypParameters->SetNbVolOptSteps(aParams.optsteps3d); - } - aParams._hypParameters->SetElemSizeWeight(aParams.elsizeweight); - aParams._hypParameters->SetWorstElemMeasure(aParams.opterrpow); - aParams._hypParameters->SetUseDelauney(aParams.delaunay); - aParams._hypParameters->SetCheckOverlapping(aParams.checkoverlap); - aParams._hypParameters->SetCheckChartBoundary(aParams.checkchartboundary); - aParams._hypParameters->SetMeshSizeFile(aParams.meshsizefilename); - } - if(aParams.has_maxelementvolume_hyp){ - aParams._hypMaxElementVolume = new StdMeshers_MaxElementVolume(1, gen); - } - // TODO: Handle viscous layer }; /** diff --git a/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx b/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx index bc05229..ea134a2 100644 --- a/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx +++ b/src/NETGENPlugin/NETGENPlugin_DriverParam.hxx @@ -30,11 +30,6 @@ #include -class NETGENPlugin_Hypothesis; -class StdMeshers_MaxElementVolume; -class StdMeshers_ViscousLayers; -class SMESH_Gen; - struct netgen_params{ // Params from NETGENPlugin_Mesher // True if _hypParameters is not null @@ -60,6 +55,8 @@ struct netgen_params{ bool checkchartboundary; int closeedgefac; + // Number of threads for the mesher + int nbThreads; // True if we have a mesh size file or local size info bool has_local_size = false; @@ -70,24 +67,14 @@ struct netgen_params{ bool has_maxelementvolume_hyp=false; double maxElementVolume=0.0; - NETGENPlugin_Hypothesis * _hypParameters=nullptr; - StdMeshers_MaxElementVolume* _hypMaxElementVolume=nullptr; - StdMeshers_ViscousLayers* _viscousLayersHyp=nullptr; - double _progressByTic; - bool _quadraticMesh=false; - int _error=0; - std::string _comment; - // Params from NETGEN2D bool has_LengthFromEdges_hyp=false; - // Number of threads for the mesher - int nbThreads; }; void printNetgenParams(netgen_params& aParams); -void importNetgenParams(const std::string param_file, netgen_params& aParams, SMESH_Gen * gen); +void importNetgenParams(const std::string param_file, netgen_params& aParams); void exportNetgenParams(const std::string param_file, netgen_params& aParams); #endif diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index b7c6d28..b256eab 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -212,7 +212,6 @@ bool NETGENPlugin_NETGEN_3D::getSurfaceElements( SMESH_ProxyMesh::Ptr proxyMesh, NETGENPlugin_Internals &internals, SMESH_MesherHelper &helper, - netgen_params &aParams, std::map>& listElements ) { @@ -236,7 +235,7 @@ bool NETGENPlugin_NETGEN_3D::getSurfaceElements( if ( !aSubMeshDSFace ) continue; SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - if ( aParams._quadraticMesh && + if ( _quadraticMesh && dynamic_cast< const SMESH_ProxyMesh::SubMesh*>( aSubMeshDSFace )) { // add medium nodes of proxy triangles to helper (#16843) @@ -249,14 +248,10 @@ bool NETGENPlugin_NETGEN_3D::getSurfaceElements( const SMDS_MeshElement* elem = iteratorElem->next(); // check mesh face if ( !elem ){ - aParams._error = COMPERR_BAD_INPUT_MESH; - aParams._comment = "Null element encounters"; - return true; + return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); } if ( elem->NbCornerNodes() != 3 ){ - aParams._error = COMPERR_BAD_INPUT_MESH; - aParams._comment = "Not triangle element encounters"; - return true; + return error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); } listElements[elem] = tuple(isRev, isInternalFace); } @@ -272,16 +267,15 @@ bool NETGENPlugin_NETGEN_3D::computeFillNgMesh( vector< const SMDS_MeshNode* > &nodeVec, NETGENPlugin_NetgenLibWrapper &ngLib, SMESH_MesherHelper &helper, - netgen_params &aParams, int &Netgen_NbOfNodes) { netgen::multithread.terminate = 0; netgen::multithread.task = "Volume meshing"; - aParams._progressByTic = -1.; + _progressByTic = -1.; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); - aParams._quadraticMesh = helper.IsQuadraticSubMesh(aShape); + _quadraticMesh = helper.IsQuadraticSubMesh(aShape); helper.SetElementsOnShape( true ); Netgen_NbOfNodes = 0; @@ -311,10 +305,10 @@ bool NETGENPlugin_NETGEN_3D::computeFillNgMesh( bool isInternalFace=false; SMESH_ProxyMesh::Ptr proxyMesh( new SMESH_ProxyMesh( aMesh )); - if ( aParams._viscousLayersHyp ) + if ( _viscousLayersHyp ) { netgen::multithread.percent = 3; - proxyMesh = aParams._viscousLayersHyp->Compute( aMesh, aShape ); + proxyMesh = _viscousLayersHyp->Compute( aMesh, aShape ); if ( !proxyMesh ) return false; } @@ -327,7 +321,7 @@ bool NETGENPlugin_NETGEN_3D::computeFillNgMesh( } std::map> listElements; - bool ret = getSurfaceElements(aMesh, aShape, proxyMesh, internals, helper, aParams, listElements); + bool ret = getSurfaceElements(aMesh, aShape, proxyMesh, internals, helper, listElements); if(ret) return ret; @@ -402,7 +396,6 @@ bool NETGENPlugin_NETGEN_3D::computePrepareParam( NETGENPlugin_NetgenLibWrapper &ngLib, netgen::OCCGeometry &occgeo, SMESH_MesherHelper &helper, - netgen_params &aParams, int &endWith) { @@ -413,35 +406,33 @@ bool NETGENPlugin_NETGEN_3D::computePrepareParam( NETGENPlugin_Mesher aMesher( &aMesh, helper.GetSubShape(), /*isVolume=*/true ); - if ( aParams._hypParameters ) + if ( _hypParameters ) { - aMesher.SetParameters( aParams._hypParameters ); + aMesher.SetParameters( _hypParameters ); - if ( !aParams._hypParameters->GetLocalSizesAndEntries().empty() || - !aParams._hypParameters->GetMeshSizeFile().empty() ) + if ( !_hypParameters->GetLocalSizesAndEntries().empty() || + !_hypParameters->GetMeshSizeFile().empty() ) { if ( ! &ngMesh->LocalHFunction() ) { netgen::Point3d pmin, pmax; ngMesh->GetBox( pmin, pmax, 0 ); - ngMesh->SetLocalH( pmin, pmax, aParams._hypParameters->GetGrowthRate() ); + ngMesh->SetLocalH( pmin, pmax, _hypParameters->GetGrowthRate() ); } aMesher.SetLocalSize( occgeo, *ngMesh ); try { ngMesh->LoadLocalMeshSize( netgen::mparam.meshsizefilename ); } catch (netgen::NgException & ex) { - aParams._error = COMPERR_BAD_PARMETERS; - aParams._comment = ex.What(); - return false; + return error( COMPERR_BAD_PARMETERS, ex.What() ); } } - if ( !aParams._hypParameters->GetOptimize() ) + if ( !_hypParameters->GetOptimize() ) endWith = netgen::MESHCONST_MESHVOLUME; } - else if ( aParams._hypMaxElementVolume ) + else if ( _hypMaxElementVolume ) { - netgen::mparam.maxh = pow( 72, 1/6. ) * pow( aParams.maxElementVolume, 1/3. ); + netgen::mparam.maxh = pow( 72, 1/6. ) * pow( _maxElementVolume, 1/3. ); // limitVolumeSize( ngMesh, mparam.maxh ); // result is unpredictable } else if ( aMesh.HasShapeToMesh() ) @@ -456,7 +447,7 @@ bool NETGENPlugin_NETGEN_3D::computePrepareParam( netgen::mparam.maxh = Dist(pmin, pmax)/2; } - if ( !aParams._hypParameters && aMesh.HasShapeToMesh() ) + if ( !_hypParameters && aMesh.HasShapeToMesh() ) { netgen::mparam.minh = aMesher.GetDefaultMinSize( helper.GetSubShape(), netgen::mparam.maxh ); } @@ -468,7 +459,6 @@ bool NETGENPlugin_NETGEN_3D::computeRunMesher( vector< const SMDS_MeshNode* > &nodeVec, netgen::Mesh* ngMesh, NETGENPlugin_NetgenLibWrapper &ngLib, - netgen_params &aParams, int &startWith, int &endWith) { int err = 1; @@ -483,8 +473,7 @@ bool NETGENPlugin_NETGEN_3D::computeRunMesher( if(netgen::multithread.terminate) return false; if ( err ){ - aParams._comment = SMESH_Comment("Error in netgen::OCCGenerateMesh() at ") << netgen::multithread.task; - return true; + error(SMESH_Comment("Error in netgen::OCCGenerateMesh() at ") << netgen::multithread.task); } } catch (Standard_Failure& ex) @@ -494,8 +483,7 @@ bool NETGENPlugin_NETGEN_3D::computeRunMesher( << ": " << ex.DynamicType()->Name(); if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) str << ": " << ex.GetMessageString(); - aParams._comment = str; - return true; + error(str); } catch (netgen::NgException& exc) { @@ -503,25 +491,21 @@ bool NETGENPlugin_NETGEN_3D::computeRunMesher( if ( strlen( netgen::multithread.task ) > 0 ) str << " at " << netgen::multithread.task; str << ": " << exc.What(); - aParams._comment = str; - return true; + error(str); } catch (...) { SMESH_Comment str("Exception in netgen::OCCGenerateMesh()"); if ( strlen( netgen::multithread.task ) > 0 ) str << " at " << netgen::multithread.task; - aParams._comment = str; - return true; + error(str); } if ( err ) { SMESH_ComputeErrorPtr ce = NETGENPlugin_Mesher::ReadErrors(nodeVec); if ( ce && ce->HasBadElems() ){ - aParams._error = ce->myName; - aParams._comment = ce->myComment; - return true; + error( ce ); } } @@ -586,30 +570,12 @@ bool NETGENPlugin_NETGEN_3D::Compute( int endWith = netgen::MESHCONST_OPTVOLUME; int Netgen_NbOfNodes; - netgen_params aParams; - - aParams._hypParameters = const_cast(_hypParameters); - aParams._hypMaxElementVolume = const_cast(_hypMaxElementVolume); - aParams.maxElementVolume = _maxElementVolume; - aParams._progressByTic = _progressByTic; - aParams._quadraticMesh = _quadraticMesh; - aParams._viscousLayersHyp = const_cast(_viscousLayersHyp); - - bool ret; - ret = computeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, aParams, Netgen_NbOfNodes); - if(ret) - return error( aParams._error, aParams._comment); + computeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, Netgen_NbOfNodes); netgen::OCCGeometry occgeo; - computePrepareParam(aMesh, ngLib, occgeo, helper, aParams, endWith); - ret = computeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, aParams, startWith, endWith); - if(ret){ - if(aParams._error) - return error(aParams._error, aParams._comment); + computePrepareParam(aMesh, ngLib, occgeo, helper, endWith); + computeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, startWith, endWith); - error(aParams._comment); - return true; - } computeFillMesh(nodeVec, ngLib, helper, Netgen_NbOfNodes); return false; diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx index 69f7065..af98746 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.hxx @@ -77,7 +77,6 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo std::vector< const SMDS_MeshNode* > &nodeVec, NETGENPlugin_NetgenLibWrapper &ngLib, SMESH_MesherHelper &helper, - netgen_params &aParams, int &Netgen_NbOfNodes); bool computePrepareParam( @@ -85,7 +84,6 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo NETGENPlugin_NetgenLibWrapper &ngLib, netgen::OCCGeometry &occgeo, SMESH_MesherHelper &helper, - netgen_params &aParams, int &endWith); bool computeRunMesher( @@ -93,7 +91,6 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo std::vector< const SMDS_MeshNode* > &nodeVec, netgen::Mesh* ngMesh, NETGENPlugin_NetgenLibWrapper &ngLib, - netgen_params &aParams, int &startWith, int &endWith); bool computeFillMesh( @@ -110,7 +107,6 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D: public SMESH_3D_Algo SMESH_ProxyMesh::Ptr proxyMesh, NETGENPlugin_Internals &internals, SMESH_MesherHelper &helper, - netgen_params &aParams, std::map>& listElements); bool compute(SMESH_Mesh& mesh, diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx index 199e406..f05293a 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx @@ -141,7 +141,6 @@ void NETGENPlugin_NETGEN_3D_Remote::fillParameters(const NETGENPlugin_Hypothesis // write in a binary file the orientation for each 2D element of the mesh void NETGENPlugin_NETGEN_3D_Remote::exportElementOrientation(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, - netgen_params& aParams, const std::string output_file) { SMESH_MesherHelper helper(aMesh); @@ -165,7 +164,7 @@ void NETGENPlugin_NETGEN_3D_Remote::exportElementOrientation(SMESH_Mesh& aMesh, if ( !aSubMeshDSFace ) continue; SMDS_ElemIteratorPtr iteratorElem = aSubMeshDSFace->GetElements(); - if ( aParams._quadraticMesh && + if ( _quadraticMesh && dynamic_cast< const SMESH_ProxyMesh::SubMesh*>( aSubMeshDSFace )) { // add medium nodes of proxy triangles to helper (#16843) @@ -238,7 +237,7 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, exportNetgenParams(param_file.string(), aParams); // Exporting element orientation - exportElementOrientation(aMesh, aShape, aParams, element_orientation_file.string()); + exportElementOrientation(aMesh, aShape, element_orientation_file.string()); } // Calling run_mesher diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx index 210fa08..7a23d61 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.hxx @@ -64,7 +64,6 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_Remote: public NETGENPlugin_NET protected: void exportElementOrientation(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, - netgen_params& aParams, const std::string output_file); void fillParameters(const NETGENPlugin_Hypothesis* hyp, diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx index 13fef9a..bddb65c 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx @@ -32,6 +32,7 @@ #include "NETGENPlugin_DriverParam.hxx" #include "NETGENPlugin_Hypothesis.hxx" +#include "StdMeshers_MaxElementVolume.hxx" #include #include @@ -98,6 +99,47 @@ NETGENPlugin_NETGEN_3D_SA::~NETGENPlugin_NETGEN_3D_SA() } +/* + * + */ + +void NETGENPlugin_NETGEN_3D_SA::fillHyp(netgen_params aParams, SMESH_Gen* gen) +{ + if(aParams.has_netgen_param){ + NETGENPlugin_Hypothesis * hypParameters = new NETGENPlugin_Hypothesis(0, gen); + + hypParameters->SetMaxSize(aParams.maxh); + hypParameters->SetMinSize(aParams.minh); + hypParameters->SetNbSegPerEdge(aParams.segmentsperedge); + hypParameters->SetGrowthRate(aParams.grading); + hypParameters->SetNbSegPerRadius(aParams.curvaturesafety); + hypParameters->SetSecondOrder(aParams.secondorder); + hypParameters->SetQuadAllowed(aParams.quad); + hypParameters->SetOptimize(aParams.optimize); + hypParameters->SetFineness((NETGENPlugin_Hypothesis::Fineness)aParams.fineness); + hypParameters->SetSurfaceCurvature(aParams.uselocalh); + hypParameters->SetFuseEdges(aParams.merge_solids); + hypParameters->SetChordalErrorEnabled(aParams.chordalError); + if(aParams.optimize){ + hypParameters->SetNbSurfOptSteps(aParams.optsteps2d); + hypParameters->SetNbVolOptSteps(aParams.optsteps3d); + } + hypParameters->SetElemSizeWeight(aParams.elsizeweight); + hypParameters->SetWorstElemMeasure(aParams.opterrpow); + hypParameters->SetUseDelauney(aParams.delaunay); + hypParameters->SetCheckOverlapping(aParams.checkoverlap); + hypParameters->SetCheckChartBoundary(aParams.checkchartboundary); + hypParameters->SetMeshSizeFile(aParams.meshsizefilename); + + _hypParameters = dynamic_cast< const NETGENPlugin_Hypothesis *> (hypParameters); + } + if(aParams.has_maxelementvolume_hyp){ + _hypMaxElementVolume = new StdMeshers_MaxElementVolume(1, gen); + _maxElementVolume = aParams.maxElementVolume; + } + // TODO: Handle viscous layer +} + bool NETGENPlugin_NETGEN_3D_SA::computeFillNewElementFile( std::vector< const SMDS_MeshNode* > &nodeVec, NETGENPlugin_NetgenLibWrapper &ngLib, @@ -150,8 +192,7 @@ bool NETGENPlugin_NETGEN_3D_SA::computeFillNewElementFile( bool NETGENPlugin_NETGEN_3D_SA::Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, - std::string new_element_file, std::string element_orientation_file, - bool output_mesh) + std::string new_element_file, bool output_mesh) { // vector of nodes in which node index == netgen ID vector< const SMDS_MeshNode* > nodeVec; @@ -161,22 +202,12 @@ bool NETGENPlugin_NETGEN_3D_SA::Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, int endWith = netgen::MESHCONST_OPTVOLUME; int Netgen_NbOfNodes=0; - bool ret; - ret = NETGENPlugin_NETGEN_3D::computeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, aParams, Netgen_NbOfNodes); - if(ret) - return error( aParams._error, aParams._comment); + NETGENPlugin_NETGEN_3D::computeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, Netgen_NbOfNodes); netgen::OCCGeometry occgeo; - NETGENPlugin_NETGEN_3D::computePrepareParam(aMesh, ngLib, occgeo, helper, aParams, endWith); + NETGENPlugin_NETGEN_3D::computePrepareParam(aMesh, ngLib, occgeo, helper, endWith); - ret = NETGENPlugin_NETGEN_3D::computeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, aParams, startWith, endWith); - if(ret){ - if(aParams._error) - return error(aParams._error, aParams._comment); - - error(aParams._comment); - return true; - } + NETGENPlugin_NETGEN_3D::computeRunMesher(occgeo, nodeVec, ngLib._ngMesh, ngLib, startWith, endWith); computeFillNewElementFile(nodeVec, ngLib, new_element_file, Netgen_NbOfNodes); @@ -210,13 +241,14 @@ int NETGENPlugin_NETGEN_3D_SA::run(const std::string input_mesh_file, // Importing hypothesis netgen_params myParams; - importNetgenParams(hypo_file, myParams, &gen); + importNetgenParams(hypo_file, myParams); + fillHyp(myParams, &gen); // Setting number of threads for netgen myParams.nbThreads = nbThreads; MESSAGE("Meshing with netgen3d"); int ret = Compute(myShape, *myMesh, myParams, - new_element_file, element_orientation_file, + new_element_file, !output_mesh_file.empty()); @@ -240,10 +272,14 @@ bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements( SMESH_ProxyMesh::Ptr proxyMesh, NETGENPlugin_Internals &internals, SMESH_MesherHelper &helper, - netgen_params &aParams, std::map>& listElements ) { + // To remove compilation warnings + (void) aShape; + (void) proxyMesh; + (void) internals; + (void) helper; SMESHDS_Mesh* meshDS = aMesh.GetMeshDS(); // Get list of elements + their orientation from element_orientation file @@ -283,7 +319,6 @@ bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements( // Adding elements from Mesh SMDS_ElemIteratorPtr iteratorElem = meshDS->elementsIterator(SMDSAbs_Face); bool isRev; - bool isInternalFace = false; bool isIn; @@ -292,14 +327,10 @@ bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements( // check mesh face const SMDS_MeshElement* elem = iteratorElem->next(); if ( !elem ){ - aParams._error = COMPERR_BAD_INPUT_MESH; - aParams._comment = "Null element encounters"; - return true; + return error( COMPERR_BAD_INPUT_MESH, "Null element encounters"); } if ( elem->NbCornerNodes() != 3 ){ - aParams._error = COMPERR_BAD_INPUT_MESH; - aParams._comment = "Not triangle element encounters"; - return true; + return error( COMPERR_BAD_INPUT_MESH, "Not triangle element encounters"); } // Keeping only element that are in the element orientation file isIn = elemOrientation.count(elem->GetID())==1; diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx index b3ebe1a..36eb266 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx @@ -48,9 +48,9 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_SA: public NETGENPlugin_NETGEN_ NETGENPlugin_NETGEN_3D_SA(); virtual ~NETGENPlugin_NETGEN_3D_SA(); + void fillHyp(netgen_params aParams, SMESH_Gen* gen); bool Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, - std::string new_element_file, std::string element_orientation_file, - bool output_mesh); + std::string new_element_file, bool output_mesh); int run(const std::string input_mesh_file, const std::string shape_file, @@ -76,7 +76,6 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_SA: public NETGENPlugin_NETGEN_ SMESH_ProxyMesh::Ptr proxyMesh, NETGENPlugin_Internals &internals, SMESH_MesherHelper &helper, - netgen_params &aParams, std::map>& listElements ) override; From 61e4da3b0d1f506d05b4878285c92592256ef664 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 3 Oct 2022 15:46:12 +0200 Subject: [PATCH 25/29] Adding nnthreads as parameter for netgen --- idl/NETGENPlugin_Algorithm.idl | 3 + src/NETGENPlugin/NETGENPluginBuilder.py | 6 ++ src/NETGENPlugin/NETGENPlugin_DriverParam.cxx | 4 ++ src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx | 59 ++++++++++++------- src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx | 8 +++ .../NETGENPlugin_Hypothesis_i.cxx | 52 +++++++++++----- .../NETGENPlugin_Hypothesis_i.hxx | 5 +- src/NETGENPlugin/NETGENPlugin_Mesher.cxx | 4 +- .../NETGENPlugin_NETGEN_3D_Remote.cxx | 6 +- 9 files changed, 104 insertions(+), 43 deletions(-) diff --git a/idl/NETGENPlugin_Algorithm.idl b/idl/NETGENPlugin_Algorithm.idl index 01b0d19..b2d45fc 100644 --- a/idl/NETGENPlugin_Algorithm.idl +++ b/idl/NETGENPlugin_Algorithm.idl @@ -147,6 +147,9 @@ module NETGENPlugin void SetWorstElemMeasure(in short val ); short GetWorstElemMeasure(); + void SetNbThreads(in short val ); + short GetNbThreads(); + void SetUseDelauney(in boolean toUse); boolean GetUseDelauney(); diff --git a/src/NETGENPlugin/NETGENPluginBuilder.py b/src/NETGENPlugin/NETGENPluginBuilder.py index 8079f01..162bb25 100644 --- a/src/NETGENPlugin/NETGENPluginBuilder.py +++ b/src/NETGENPlugin/NETGENPluginBuilder.py @@ -148,6 +148,12 @@ class NETGEN_Algorithm(Mesh_Algorithm): if self.Parameters(): self.params.SetGrowthRate(theRate) pass + ## Sets @c NbThreads parameter + # @param theRate new value of the @c NbThreads parameter + def SetNbThreads(self, theNumber): + if self.Parameters(): self.params.SetNbThreads(theNumber) + pass + ## Creates meshing hypothesis according to the chosen algorithm type # and initializes it with default parameters # @param which hypothesis type; can be either @ref SOLE (default) or @ref SIMPLE diff --git a/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx index 7369908..c61b04c 100644 --- a/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx +++ b/src/NETGENPlugin/NETGENPlugin_DriverParam.cxx @@ -59,6 +59,7 @@ void printNetgenParams(netgen_params& aParams){ std::cout << "checkoverlap: " << aParams.checkoverlap << std::endl; std::cout << "checkchartboundary: " << aParams.checkchartboundary << std::endl; std::cout << "closeedgefac: " << aParams.closeedgefac << std::endl; + std::cout << "nbThreadMesher: " << aParams.nbThreads << std::endl; std::cout << "has_local_size: " << aParams.has_local_size << std::endl; std::cout << "meshsizefilename: " << aParams.meshsizefilename << std::endl; std::cout << "has_maxelementvolume_hyp: " << aParams.has_maxelementvolume_hyp << std::endl; @@ -119,6 +120,8 @@ void importNetgenParams(const std::string param_file, netgen_params& aParams){ std::getline(myfile, line); aParams.closeedgefac = std::stoi(line); std::getline(myfile, line); + aParams.nbThreads = std::stoi(line); + std::getline(myfile, line); aParams.has_local_size = std::stoi(line); std::getline(myfile, line); aParams.meshsizefilename = line; @@ -160,6 +163,7 @@ void exportNetgenParams(const std::string param_file, netgen_params& aParams){ myfile << aParams.checkoverlap << std::endl; myfile << aParams.checkchartboundary << std::endl; myfile << aParams.closeedgefac << std::endl; + myfile << aParams.nbThreads << std::endl; myfile << aParams.has_local_size << std::endl; myfile << aParams.meshsizefilename << std::endl; myfile << aParams.has_maxelementvolume_hyp << std::endl; diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx index 28c9c6e..2113c96 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis.cxx @@ -58,6 +58,7 @@ NETGENPlugin_Hypothesis::NETGENPlugin_Hypothesis (int hypId, SMESH_Gen * gen) _nbVolOptSteps (GetDefaultNbVolOptSteps()), _elemSizeWeight (GetDefaultElemSizeWeight()), _worstElemMeasure (GetDefaultWorstElemMeasure()), + _nbThreads (GetDefaultNbThreads()), _surfaceCurvature (GetDefaultSurfaceCurvature()), _useDelauney (GetDefaultUseDelauney()), _checkOverlapping (GetDefaultCheckOverlapping()), @@ -84,7 +85,7 @@ void NETGENPlugin_Hypothesis::SetMaxSize(double theSize) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetMinSize(double theSize) @@ -98,7 +99,7 @@ void NETGENPlugin_Hypothesis::SetMinSize(double theSize) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetSecondOrder(bool theVal) @@ -112,7 +113,7 @@ void NETGENPlugin_Hypothesis::SetSecondOrder(bool theVal) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetOptimize(bool theVal) @@ -126,7 +127,7 @@ void NETGENPlugin_Hypothesis::SetOptimize(bool theVal) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetFineness(Fineness theFineness) @@ -172,7 +173,7 @@ void NETGENPlugin_Hypothesis::SetFineness(Fineness theFineness) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetGrowthRate(double theRate) @@ -187,7 +188,7 @@ void NETGENPlugin_Hypothesis::SetGrowthRate(double theRate) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetNbSegPerEdge(double theVal) @@ -202,7 +203,7 @@ void NETGENPlugin_Hypothesis::SetNbSegPerEdge(double theVal) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetNbSegPerRadius(double theVal) @@ -217,7 +218,7 @@ void NETGENPlugin_Hypothesis::SetNbSegPerRadius(double theVal) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetChordalErrorEnabled(bool theVal) @@ -231,7 +232,7 @@ void NETGENPlugin_Hypothesis::SetChordalErrorEnabled(bool theVal) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetChordalError(double theVal) @@ -245,7 +246,7 @@ void NETGENPlugin_Hypothesis::SetChordalError(double theVal) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetLocalSizeOnEntry(const std::string& entry, double localSize) @@ -273,7 +274,7 @@ double NETGENPlugin_Hypothesis::GetLocalSizeOnEntry(const std::string& entry) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::UnsetLocalSizeOnEntry(const std::string& entry) @@ -284,7 +285,7 @@ void NETGENPlugin_Hypothesis::UnsetLocalSizeOnEntry(const std::string& entry) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetMeshSizeFile(const std::string& fileName) @@ -298,7 +299,7 @@ void NETGENPlugin_Hypothesis::SetMeshSizeFile(const std::string& fileName) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetQuadAllowed(bool theVal) @@ -312,7 +313,7 @@ void NETGENPlugin_Hypothesis::SetQuadAllowed(bool theVal) //============================================================================= /*! - * + * */ //============================================================================= void NETGENPlugin_Hypothesis::SetSurfaceCurvature(bool theVal) @@ -340,7 +341,7 @@ void NETGENPlugin_Hypothesis::SetFuseEdges(bool theVal) //======================================================================= //function : SetNbSurfOptSteps -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis::SetNbSurfOptSteps( int theVal ) @@ -354,7 +355,7 @@ void NETGENPlugin_Hypothesis::SetNbSurfOptSteps( int theVal ) //======================================================================= //function : SetNbVolOptSteps -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis::SetNbVolOptSteps( int theVal ) @@ -368,7 +369,7 @@ void NETGENPlugin_Hypothesis::SetNbVolOptSteps( int theVal ) //======================================================================= //function : SetElemSizeWeight -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis::SetElemSizeWeight( double theVal ) @@ -382,7 +383,7 @@ void NETGENPlugin_Hypothesis::SetElemSizeWeight( double theVal ) //======================================================================= //function : SetWorstElemMeasure -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis::SetWorstElemMeasure( int theVal ) @@ -396,7 +397,7 @@ void NETGENPlugin_Hypothesis::SetWorstElemMeasure( int theVal ) //======================================================================= //function : SetUseDelauney -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis::SetUseDelauney( bool theVal ) @@ -410,7 +411,7 @@ void NETGENPlugin_Hypothesis::SetUseDelauney( bool theVal ) //======================================================================= //function : SetCheckOverlapping -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis::SetCheckOverlapping( bool theVal ) @@ -424,7 +425,7 @@ void NETGENPlugin_Hypothesis::SetCheckOverlapping( bool theVal ) //======================================================================= //function : SetCheckChartBoundary -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis::SetCheckChartBoundary( bool theVal ) @@ -436,6 +437,20 @@ void NETGENPlugin_Hypothesis::SetCheckChartBoundary( bool theVal ) } } +//======================================================================= +//function : SetNbThreads +//purpose : +//======================================================================= + +void NETGENPlugin_Hypothesis::SetNbThreads( int theVal ) +{ + if (theVal != _nbThreads) + { + _nbThreads = theVal; + NotifySubMeshesHypothesisModification(); + } +} + //============================================================================= /*! * @@ -485,7 +500,7 @@ ostream & NETGENPlugin_Hypothesis::SaveTo(ostream & save) //============================================================================= /*! - * + * */ //============================================================================= istream & NETGENPlugin_Hypothesis::LoadFrom(istream & load) diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx index 133b774..e12b9ed 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis.hxx @@ -35,6 +35,7 @@ #include "Utils_SALOME_Exception.hxx" #include +#include // Parameters for work of NETGEN // @@ -125,6 +126,9 @@ public: void SetCheckChartBoundary( bool toCheck ); bool GetCheckChartBoundary() const { return _checkChartBoundary; } + void SetNbThreads( int val ); + int GetNbThreads() const { return _nbThreads; } + // the default values (taken from NETGEN 4.5 sources) static Fineness GetDefaultFineness() { return Moderate; } @@ -145,6 +149,7 @@ public: static bool GetDefaultCheckOverlapping() { return true; } static bool GetDefaultCheckChartBoundary(){ return true; } static bool GetDefaultFuseEdges() { return true; } + static int GetDefaultNbThreads() { return std::thread::hardware_concurrency(); } // Persistence virtual std::ostream & SaveTo (std::ostream & save); @@ -197,6 +202,9 @@ private: //bool _blockFilling; -- not used by netgen // (SALOME additions) bool _fuseEdges; + + // Parallelism parameters + int _nbThreads; }; #endif diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx index fd4c4fd..3af6b67 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.cxx @@ -60,7 +60,7 @@ bool NETGENPlugin_Hypothesis_i::isToSetParameter(double curValue, NETGENPlugin_Hypothesis_i:: NETGENPlugin_Hypothesis_i (PortableServer::POA_ptr thePOA, ::SMESH_Gen* theGenImpl) - : SALOME::GenericObj_i( thePOA ), + : SALOME::GenericObj_i( thePOA ), SMESH_Hypothesis_i( thePOA ), mySetMethodFlags(0) { @@ -471,7 +471,7 @@ CORBA::Boolean NETGENPlugin_Hypothesis_i::GetFuseEdges() //======================================================================= //function : SetNbSurfOptSteps -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis_i::SetNbSurfOptSteps(CORBA::Short nb ) @@ -495,7 +495,7 @@ CORBA::Short NETGENPlugin_Hypothesis_i::GetNbSurfOptSteps() //======================================================================= //function : SetNbVolOptSteps -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis_i::SetNbVolOptSteps(CORBA::Short nb ) @@ -520,7 +520,7 @@ CORBA::Short NETGENPlugin_Hypothesis_i::GetNbVolOptSteps() //======================================================================= //function : SetElemSizeWeight -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis_i::SetElemSizeWeight(CORBA::Double size ) @@ -544,7 +544,7 @@ CORBA::Double NETGENPlugin_Hypothesis_i::GetElemSizeWeight() //======================================================================= //function : SetWorstElemMeasure -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis_i::SetWorstElemMeasure(CORBA::Short val ) @@ -558,7 +558,7 @@ void NETGENPlugin_Hypothesis_i::SetWorstElemMeasure(CORBA::Short val ) //======================================================================= //function : GetWorstElemMeasure -//purpose : +//purpose : //======================================================================= CORBA::Short NETGENPlugin_Hypothesis_i::GetWorstElemMeasure() @@ -566,9 +566,33 @@ CORBA::Short NETGENPlugin_Hypothesis_i::GetWorstElemMeasure() return (CORBA::Short) GetImpl()->GetWorstElemMeasure(); } +//======================================================================= +//function : SetNbThreads +//purpose : +//======================================================================= + +void NETGENPlugin_Hypothesis_i::SetNbThreads(CORBA::Short val ) +{ + if ( GetNbThreads() != val ) + { + this->GetImpl()->SetNbThreads( val ); + SMESH::TPythonDump() << _this() << ".SetNbThreads( " << SMESH::TVar(val) << " )"; + } +} + +//======================================================================= +//function : GetNbThreads +//purpose : +//======================================================================= + +CORBA::Short NETGENPlugin_Hypothesis_i::GetNbThreads() +{ + return (CORBA::Short) GetImpl()->GetNbThreads(); +} + //======================================================================= //function : SetUseDelauney -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis_i::SetUseDelauney(CORBA::Boolean toUse) @@ -582,7 +606,7 @@ void NETGENPlugin_Hypothesis_i::SetUseDelauney(CORBA::Boolean toUse) //======================================================================= //function : GetUseDelauney -//purpose : +//purpose : //======================================================================= CORBA::Boolean NETGENPlugin_Hypothesis_i::GetUseDelauney() @@ -592,7 +616,7 @@ CORBA::Boolean NETGENPlugin_Hypothesis_i::GetUseDelauney() //======================================================================= //function : SetCheckOverlapping -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis_i::SetCheckOverlapping(CORBA::Boolean toCheck ) @@ -606,7 +630,7 @@ void NETGENPlugin_Hypothesis_i::SetCheckOverlapping(CORBA::Boolean toCheck ) //======================================================================= //function : GetCheckOverlapping -//purpose : +//purpose : //======================================================================= CORBA::Boolean NETGENPlugin_Hypothesis_i::GetCheckOverlapping() @@ -616,7 +640,7 @@ CORBA::Boolean NETGENPlugin_Hypothesis_i::GetCheckOverlapping() //======================================================================= //function : SetCheckChartBoundary -//purpose : +//purpose : //======================================================================= void NETGENPlugin_Hypothesis_i::SetCheckChartBoundary(CORBA::Boolean toCheck ) @@ -652,13 +676,13 @@ CORBA::Boolean NETGENPlugin_Hypothesis_i::GetCheckChartBoundary() //================================================================================ /*! - * \brief Verify whether hypothesis supports given entity type + * \brief Verify whether hypothesis supports given entity type * \param type - dimension (see SMESH::Dimension enumeration) * \retval CORBA::Boolean - TRUE if dimension is supported, FALSE otherwise - * + * * Verify whether hypothesis supports given entity type (see SMESH::Dimension enumeration) */ -//================================================================================ +//================================================================================ CORBA::Boolean NETGENPlugin_Hypothesis_i::IsDimSupported( SMESH::Dimension type ) { return type == SMESH::DIM_3D; diff --git a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx index 3f95357..5d728f0 100644 --- a/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Hypothesis_i.hxx @@ -113,6 +113,9 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Hypothesis_i: void SetWorstElemMeasure(CORBA::Short val ); CORBA::Short GetWorstElemMeasure(); + void SetNbThreads(CORBA::Short val ); + CORBA::Short GetNbThreads(); + void SetUseDelauney(CORBA::Boolean toUse); CORBA::Boolean GetUseDelauney(); @@ -125,7 +128,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_Hypothesis_i: // Get implementation ::NETGENPlugin_Hypothesis* GetImpl(); - // Verify whether hypothesis supports given entity type + // Verify whether hypothesis supports given entity type CORBA::Boolean IsDimSupported( SMESH::Dimension type ); diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx index 168cf55..615c970 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx @@ -602,14 +602,13 @@ void NETGENPlugin_Mesher::SetDefaultParameters() #ifdef NETGEN_V6 - mparams.nthreads = std::thread::hardware_concurrency(); + mparams.nthreads = NETGENPlugin_Hypothesis::GetDefaultNbThreads(); if ( getenv( "SALOME_NETGEN_DISABLE_MULTITHREADING" )) { mparams.nthreads = 1; mparams.parallel_meshing = false; } - #endif } @@ -655,6 +654,7 @@ void NETGENPlugin_Mesher::SetParameters(const NETGENPlugin_Hypothesis* hyp) #ifdef NETGEN_V6 // std::string mparams.meshsizefilename = hyp->GetMeshSizeFile(); + mparams.nthreads = hyp->GetNbThreads(); #else // const char* mparams.meshsizefilename= hyp->GetMeshSizeFile().empty() ? 0 : hyp->GetMeshSizeFile().c_str(); diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx index f05293a..bc81359 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx @@ -127,13 +127,11 @@ void NETGENPlugin_NETGEN_3D_Remote::fillParameters(const NETGENPlugin_Hypothesis #ifdef NETGEN_V6 // std::string aParams.meshsizefilename = hyp->GetMeshSizeFile(); + aParams.closeedgefac = 2; + aParams.nbThreads = hyp->GetNbThreads(); #else // const char* aParams.meshsizefilename = hyp->GetMeshSizeFile(); -#endif -#ifdef NETGEN_V6 - aParams.closeedgefac = 2; -#else aParams.closeedgefac = 0; #endif } From 3d82214289fb45a8d1298fda4e10f2b3701787f5 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 3 Oct 2022 16:15:33 +0200 Subject: [PATCH 26/29] Adding control of netgen log file --- src/NETGENPlugin/NETGENPlugin_Mesher.cxx | 34 ++++++++++++------- src/NETGENPlugin/NETGENPlugin_Mesher.hxx | 1 + .../NETGENPlugin_NETGEN_3D_SA.cxx | 5 +++ 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx index 615c970..44535f2 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.cxx @@ -4437,18 +4437,7 @@ NETGENPlugin_NetgenLibWrapper::NETGENPlugin_NetgenLibWrapper(): _ngcerr = NULL; if ( !getenv( "KEEP_NETGEN_OUTPUT" )) { - // redirect all netgen output (mycout,myerr,cout) to _outputFileName - _outputFileName = getOutputFileName(); - _ngcout = netgen::mycout; - _ngcerr = netgen::myerr; - netgen::mycout = new ofstream ( _outputFileName.c_str() ); - netgen::myerr = netgen::mycout; - _coutBuffer = std::cout.rdbuf(); -#ifdef _DEBUG_ - std::cout << "NOTE: netgen output is redirected to file " << _outputFileName << std::endl; -#else - std::cout.rdbuf( netgen::mycout->rdbuf() ); -#endif + setOutputFile(getOutputFileName()); } setMesh( Ng_NewMesh() ); @@ -4569,6 +4558,27 @@ std::string NETGENPlugin_NetgenLibWrapper::getOutputFileName() return aGenericName.ToCString(); } +//================================================================================ +/*! + * \brief Set output file name for netgen log + */ +//================================================================================ + +void NETGENPlugin_NetgenLibWrapper::setOutputFile(std::string outputfile) +{ + // redirect all netgen output (mycout,myerr,cout) to _outputFileName + _outputFileName = outputfile; + _ngcout = netgen::mycout; + _ngcerr = netgen::myerr; + netgen::mycout = new ofstream ( _outputFileName.c_str() ); + netgen::myerr = netgen::mycout; + _coutBuffer = std::cout.rdbuf(); +#ifdef _DEBUG_ + std::cout << "NOTE: netgen output is redirected to file " << _outputFileName << std::endl; +#else + std::cout.rdbuf( netgen::mycout->rdbuf() ); +#endif +} //================================================================================ /*! diff --git a/src/NETGENPlugin/NETGENPlugin_Mesher.hxx b/src/NETGENPlugin/NETGENPlugin_Mesher.hxx index 6d06f81..0a3f514 100644 --- a/src/NETGENPlugin/NETGENPlugin_Mesher.hxx +++ b/src/NETGENPlugin/NETGENPlugin_Mesher.hxx @@ -105,6 +105,7 @@ struct NETGENPLUGIN_EXPORT NETGENPlugin_NetgenLibWrapper static void RemoveTmpFiles(); static int& instanceCounter(); + void setOutputFile(std::string); private: std::string getOutputFileName(); diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx index bddb65c..6dfc100 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx @@ -202,6 +202,11 @@ bool NETGENPlugin_NETGEN_3D_SA::Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, int endWith = netgen::MESHCONST_OPTVOLUME; int Netgen_NbOfNodes=0; + // Changing netgen log_file putting it next to new_element_file + fs::path netgen_log_file = fs::path(new_element_file).remove_filename() / fs::path("NETGEN.out"); + + ngLib.setOutputFile(netgen_log_file.string()); + NETGENPlugin_NETGEN_3D::computeFillNgMesh(aMesh, aShape, nodeVec, ngLib, helper, Netgen_NbOfNodes); netgen::OCCGeometry occgeo; From fbfd90a1f8a25f69c70500cbd14aca9b37c4bff6 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Mon, 3 Oct 2022 18:11:35 +0200 Subject: [PATCH 27/29] Adding number of thread to netgen hypo + windows corrections --- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 3 --- .../NETGENPlugin_NETGEN_3D_Remote.cxx | 8 ++++---- .../NETGENPlugin_NETGEN_3D_SA.cxx | 5 +---- .../NETGENPlugin_NETGEN_3D_SA.hxx | 5 +---- src/NETGENPlugin/NETGENPlugin_Runner_main.cxx | 19 ++++++------------- 5 files changed, 12 insertions(+), 28 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index b256eab..dd20916 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -32,9 +32,6 @@ #include "NETGENPlugin_Hypothesis.hxx" -// TODO: remove use of netgen_param -#include "NETGENPlugin_DriverParam.hxx" - #include #include #include diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx index bc81359..a50073c 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx @@ -220,7 +220,6 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, fs::path param_file=tmp_folder / fs::path("netgen3d_param.txt"); fs::path log_file=tmp_folder / fs::path("run.log"); fs::path cmd_file=tmp_folder / fs::path("cmd.log"); - //TODO: Handle variable mesh_name std::string mesh_name = "MESH"; { @@ -239,20 +238,22 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, } // Calling run_mesher - // TODO: check if we need to handle the .exe for windows std::string cmd; fs::path run_mesher_exe = fs::path(std::getenv("NETGENPLUGIN_ROOT_DIR"))/ fs::path("bin")/ fs::path("salome")/ +#ifdef WIN32 + fs::path("NETGENPlugin_Runner.exe"); +#else fs::path("NETGENPlugin_Runner"); +#endif cmd = run_mesher_exe.string() + " NETGEN3D " + mesh_file.string() + " " + shape_file.string() + " " + param_file.string() + " " + element_orientation_file.string() + " " - + std::to_string(aMesh.GetMesherNbThreads()) + " " + new_element_file.string() + " " + "NONE"; // Writing command in log @@ -273,7 +274,6 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, arguments << shape_file.c_str(); arguments << param_file.c_str(); arguments << element_orientation_file.c_str(); - arguments << std::to_string(aMesh.GetMesherNbThreads()).c_str(); arguments << new_element_file.c_str(); arguments << "NONE"; QString out_file = log_file.c_str(); diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx index 6dfc100..9d2bf43 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx @@ -227,8 +227,7 @@ int NETGENPlugin_NETGEN_3D_SA::run(const std::string input_mesh_file, const std::string hypo_file, const std::string element_orientation_file, const std::string new_element_file, - const std::string output_mesh_file, - int nbThreads) + const std::string output_mesh_file) { _element_orientation_file = element_orientation_file; @@ -248,8 +247,6 @@ int NETGENPlugin_NETGEN_3D_SA::run(const std::string input_mesh_file, importNetgenParams(hypo_file, myParams); fillHyp(myParams, &gen); - // Setting number of threads for netgen - myParams.nbThreads = nbThreads; MESSAGE("Meshing with netgen3d"); int ret = Compute(myShape, *myMesh, myParams, diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx index 36eb266..62e9059 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx @@ -57,10 +57,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_SA: public NETGENPlugin_NETGEN_ const std::string hypo_file, const std::string element_orientation_file, const std::string new_element_file, - const std::string output_mesh_file, - int nbThreads); - - + const std::string output_mesh_file); protected: diff --git a/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx index 8d2e11b..95cc741 100644 --- a/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx +++ b/src/NETGENPlugin/NETGENPlugin_Runner_main.cxx @@ -42,11 +42,11 @@ */ int main(int argc, char *argv[]){ - if(argc!=9||(argc==2 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help")==0))){ - std::cout << "Error in number of arguments "<< argc<<" given expected 8" <> thing; @@ -82,18 +80,13 @@ int main(int argc, char *argv[]){ new_element_file = ""; if (mesher=="NETGEN3D"){ - auto begin = std::chrono::high_resolution_clock::now(); NETGENPlugin_NETGEN_3D_SA myplugin; myplugin.run(input_mesh_file, shape_file, hypo_file, element_orientation_file, new_element_file, - output_mesh_file, - nbThreads); - auto end = std::chrono::high_resolution_clock::now(); - auto elapsed = std::chrono::duration_cast(end - begin); - std::cout << "Time elapsed: " << elapsed.count()*1e-9 << std::endl; + output_mesh_file); } else { std::cerr << "Unknown mesher:" << mesher << std::endl; } From 75f2fd83a4ddc893ce59d9f3380f850e89e8a7e4 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 4 Oct 2022 14:32:49 +0200 Subject: [PATCH 28/29] Adding comments + removing SMESH_Gen argument --- src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx | 67 ++++++++++++++- .../NETGENPlugin_NETGEN_3D_Remote.cxx | 35 ++++++-- .../NETGENPlugin_NETGEN_3D_SA.cxx | 82 +++++++++++++++---- .../NETGENPlugin_NETGEN_3D_SA.hxx | 5 +- 4 files changed, 158 insertions(+), 31 deletions(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx index dd20916..d4712aa 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D.cxx @@ -198,11 +198,20 @@ bool NETGENPlugin_NETGEN_3D::CheckHypothesis (SMESH_Mesh& aMesh, */ //============================================================================= -/** - * @brief Get an iterator on the Surface element with their orientation - * - */ +/** + * @brief Compute the list of already meshed Surface elements and info + * on their orientation and if they are internal + * + * @param aMesh Global Mesh + * @param aShape Shape associated to the mesh + * @param proxyMesh pointer to mesh used fo find the elements + * @param internals information on internal sub shapes + * @param helper helper associated to the mesh + * @param listElements map of surface element associated with + * their orientation and internal status + * @return true if their was some error + */ bool NETGENPlugin_NETGEN_3D::getSurfaceElements( SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, @@ -257,6 +266,18 @@ bool NETGENPlugin_NETGEN_3D::getSurfaceElements( return false; } +/** + * @brief Part of Compute: adding already meshed elements + * into netgen structure + * + * @param aMesh Global mesh + * @param aShape Shape associated with the mesh + * @param nodeVec Mapping between nodes mesh id and netgen structure id + * @param ngLib Wrapper on netgen lib + * @param helper helper assocaited to the mesh + * @param Netgen_NbOfNodes Number of nodes in netge structure + * @return true if there was some error + */ bool NETGENPlugin_NETGEN_3D::computeFillNgMesh( SMESH_Mesh& aMesh, @@ -388,6 +409,16 @@ bool NETGENPlugin_NETGEN_3D::computeFillNgMesh( return false; } +/** + * @brief Part of Compute: Setting the netgen parameters from the Hypothesis + * + * @param aMesh Global mesh + * @param ngLib Wrapper on netgen lib + * @param occgeo Mapping between nodes mesh id and netgen structure id + * @param helper helper assocaited to the mesh + * @param endWith end step of netgen + * @return true if there was some error + */ bool NETGENPlugin_NETGEN_3D::computePrepareParam( SMESH_Mesh& aMesh, NETGENPlugin_NetgenLibWrapper &ngLib, @@ -451,6 +482,17 @@ bool NETGENPlugin_NETGEN_3D::computePrepareParam( return false; } +/** + * @brief Part of Compute: call to the netgen mesher + * + * @param occgeo netgen geometry structure + * @param nodeVec Mapping between nodes mesh id and netgen structure id + * @param ngMesh netgen mesh structure + * @param ngLib Wrapper on netgen lib + * @param startWith starting step of netgen + * @param endWith end step of netgen + * @return true if there was some error + */ bool NETGENPlugin_NETGEN_3D::computeRunMesher( netgen::OCCGeometry &occgeo, vector< const SMDS_MeshNode* > &nodeVec, @@ -509,6 +551,15 @@ bool NETGENPlugin_NETGEN_3D::computeRunMesher( return false; } +/** + * @brief Part of Compute: Adding new element created by mesher to SMESH_Mesh + * + * @param nodeVec Mapping between nodes mesh id and netgen structure id + * @param ngLib Wrapper on netgen lib + * @param helper tool associated to the mesh to add element + * @param Netgen_NbOfNodes Number of nodes in netgen structure + * @return true if there was some error + */ bool NETGENPlugin_NETGEN_3D::computeFillMesh( vector< const SMDS_MeshNode* > &nodeVec, NETGENPlugin_NetgenLibWrapper &ngLib, @@ -555,6 +606,14 @@ bool NETGENPlugin_NETGEN_3D::computeFillMesh( return false; } + +/** + * @brief Compute mesh associate to shape + * + * @param aMesh The mesh + * @param aShape The shape + * @return true fi there are some error + */ bool NETGENPlugin_NETGEN_3D::Compute( SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx index a50073c..f66cf75 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx @@ -82,7 +82,7 @@ using namespace nglib; //============================================================================= /*! - * + * Constructor */ //============================================================================= @@ -94,7 +94,7 @@ NETGENPlugin_NETGEN_3D_Remote::NETGENPlugin_NETGEN_3D_Remote(int hypId, SMESH_Ge //============================================================================= /*! - * + * Destructor */ //============================================================================= @@ -102,7 +102,12 @@ NETGENPlugin_NETGEN_3D_Remote::~NETGENPlugin_NETGEN_3D_Remote() { } - +/** + * @brief Fill the structure netgen_param with the information from the hypothesis + * + * @param hyp the hypothesis + * @param aParams the netgen_param structure + */ void NETGENPlugin_NETGEN_3D_Remote::fillParameters(const NETGENPlugin_Hypothesis* hyp, netgen_params &aParams) { aParams.maxh = hyp->GetMaxSize(); @@ -136,7 +141,15 @@ void NETGENPlugin_NETGEN_3D_Remote::fillParameters(const NETGENPlugin_Hypothesis #endif } -// write in a binary file the orientation for each 2D element of the mesh +// + +/** + * @brief write in a binary file the orientation for each surface element of the mesh + * + * @param aMesh The mesh + * @param aShape the shape associated to the mesh + * @param output_file name of the binary file + */ void NETGENPlugin_NETGEN_3D_Remote::exportElementOrientation(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, const std::string output_file) @@ -195,7 +208,13 @@ void NETGENPlugin_NETGEN_3D_Remote::exportElementOrientation(SMESH_Mesh& aMesh, } } - +/** + * @brief Compute mesh associate to shape + * + * @param aMesh The mesh + * @param aShape The shape + * @return true fi there are some error + */ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) { @@ -351,7 +370,11 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, return true; } - +/** + * @brief Assign submeshes to compute + * + * @param aSubMesh submesh to add + */ void NETGENPlugin_NETGEN_3D_Remote::setSubMeshesToCompute(SMESH_subMesh * aSubMesh) { SMESH_MeshLocker myLocker(aSubMesh->GetFather()); diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx index 9d2bf43..1ea0ad7 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.cxx @@ -76,19 +76,19 @@ using namespace nglib; //============================================================================= /*! - * + * Constructor */ //============================================================================= NETGENPlugin_NETGEN_3D_SA::NETGENPlugin_NETGEN_3D_SA() - : NETGENPlugin_NETGEN_3D(0, _gen=new SMESH_Gen()) + : NETGENPlugin_NETGEN_3D(0, new SMESH_Gen()) { _name = "NETGEN_3D_SA"; } //============================================================================= /*! - * + * Destructor */ //============================================================================= @@ -98,15 +98,18 @@ NETGENPlugin_NETGEN_3D_SA::~NETGENPlugin_NETGEN_3D_SA() delete _gen; } - -/* +/** + * @brief fill plugin hypothesis from the netgen_params structure * + * @param aParams the structure + * @param gen SMESH_Gen associate with the SA */ - -void NETGENPlugin_NETGEN_3D_SA::fillHyp(netgen_params aParams, SMESH_Gen* gen) +void NETGENPlugin_NETGEN_3D_SA::fillHyp(netgen_params aParams) { + if(_gen) + std::cout << "_gen is set" << std::endl; if(aParams.has_netgen_param){ - NETGENPlugin_Hypothesis * hypParameters = new NETGENPlugin_Hypothesis(0, gen); + NETGENPlugin_Hypothesis * hypParameters = new NETGENPlugin_Hypothesis(0, GetGen()); hypParameters->SetMaxSize(aParams.maxh); hypParameters->SetMinSize(aParams.minh); @@ -134,12 +137,22 @@ void NETGENPlugin_NETGEN_3D_SA::fillHyp(netgen_params aParams, SMESH_Gen* gen) _hypParameters = dynamic_cast< const NETGENPlugin_Hypothesis *> (hypParameters); } if(aParams.has_maxelementvolume_hyp){ - _hypMaxElementVolume = new StdMeshers_MaxElementVolume(1, gen); + _hypMaxElementVolume = new StdMeshers_MaxElementVolume(1, GetGen()); _maxElementVolume = aParams.maxElementVolume; } // TODO: Handle viscous layer } +/** + * @brief Write a binary file containing information on the elements/nodes + * created by the mesher + * + * @param nodeVec mapping between the mesh id and the netgen structure id + * @param ngLib Wrapper on netgen library + * @param new_element_file Name of the output file + * @param Netgen_NbOfNodes Number of nodes in the netgen structure + * @return true if there are some error + */ bool NETGENPlugin_NETGEN_3D_SA::computeFillNewElementFile( std::vector< const SMDS_MeshNode* > &nodeVec, NETGENPlugin_NetgenLibWrapper &ngLib, @@ -190,9 +203,22 @@ bool NETGENPlugin_NETGEN_3D_SA::computeFillNewElementFile( return false; } - -bool NETGENPlugin_NETGEN_3D_SA::Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, - std::string new_element_file, bool output_mesh) +/** + * @brief Compute mesh associated to shape + * + * @param aShape the shape + * @param aMesh the mesh + * @param aParams netgen_params structure + * @param new_element_file Name of the file containing new element + * @param output_mesh Name of the output mesh (if empty it will not be written) + * @return true if there are some error + */ +bool NETGENPlugin_NETGEN_3D_SA::Compute( + TopoDS_Shape &aShape, + SMESH_Mesh& aMesh, + netgen_params& aParams, + std::string new_element_file, + bool output_mesh) { // vector of nodes in which node index == netgen ID vector< const SMDS_MeshNode* > nodeVec; @@ -222,6 +248,18 @@ bool NETGENPlugin_NETGEN_3D_SA::Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, return false; } + +/** + * @brief Running the mesher on the given files + * + * @param input_mesh_file Mesh file (containing 2D elements) + * @param shape_file Shape file (BREP or STEP format) + * @param hypo_file Ascii file containing the netgen parameters + * @param element_orientation_file Binary file containing the orientation of surface elemnts + * @param new_element_file output file containing info the elements created by the mesher + * @param output_mesh_file output mesh file (if empty it will not be created) + * @return int + */ int NETGENPlugin_NETGEN_3D_SA::run(const std::string input_mesh_file, const std::string shape_file, const std::string hypo_file, @@ -231,10 +269,8 @@ int NETGENPlugin_NETGEN_3D_SA::run(const std::string input_mesh_file, { _element_orientation_file = element_orientation_file; - // Importing mesh - SMESH_Gen gen; - std::unique_ptr myMesh(gen.CreateMesh(false)); + std::unique_ptr myMesh(_gen->CreateMesh(false)); importMesh(input_mesh_file, *myMesh); @@ -246,7 +282,7 @@ int NETGENPlugin_NETGEN_3D_SA::run(const std::string input_mesh_file, netgen_params myParams; importNetgenParams(hypo_file, myParams); - fillHyp(myParams, &gen); + fillHyp(myParams); MESSAGE("Meshing with netgen3d"); int ret = Compute(myShape, *myMesh, myParams, @@ -267,7 +303,19 @@ int NETGENPlugin_NETGEN_3D_SA::run(const std::string input_mesh_file, return ret; } - +/** + * @brief Compute the list of already meshed Surface elements and info + * on their orientation and if they are internal + * + * @param aMesh Global Mesh + * @param aShape Shape associated to the mesh + * @param proxyMesh pointer to mesh used fo find the elements + * @param internals information on internal sub shapes + * @param helper helper associated to the mesh + * @param listElements map of surface element associated with + * their orientation and internal status + * @return true if their was some error + */ bool NETGENPlugin_NETGEN_3D_SA::getSurfaceElements( SMESH_Mesh& aMesh, const TopoDS_Shape& aShape, diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx index 62e9059..0a6a6fc 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_SA.hxx @@ -38,7 +38,6 @@ class NETGENPlugin_NetgenLibWrapper; class netgen_params; class SMDS_MeshNode; -class SMESH_Gen; using namespace std; @@ -48,7 +47,7 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_SA: public NETGENPlugin_NETGEN_ NETGENPlugin_NETGEN_3D_SA(); virtual ~NETGENPlugin_NETGEN_3D_SA(); - void fillHyp(netgen_params aParams, SMESH_Gen* gen); + void fillHyp(netgen_params aParams); bool Compute(TopoDS_Shape &aShape, SMESH_Mesh& aMesh, netgen_params& aParams, std::string new_element_file, bool output_mesh); @@ -77,8 +76,6 @@ class NETGENPLUGIN_EXPORT NETGENPlugin_NETGEN_3D_SA: public NETGENPlugin_NETGEN_ ) override; std::string _element_orientation_file=""; - SMESH_Gen *_gen=nullptr; - }; #endif From 9bfa36efab8c9847238524fbaeb7313859f19583 Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Wed, 12 Oct 2022 10:28:39 +0200 Subject: [PATCH 29/29] Removing 30s limit on QProcess --- src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx index f66cf75..16311c7 100644 --- a/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx +++ b/src/NETGENPlugin/NETGENPlugin_NETGEN_3D_Remote.cxx @@ -300,7 +300,9 @@ bool NETGENPlugin_NETGEN_3D_Remote::Compute(SMESH_Mesh& aMesh, myProcess.setStandardOutputFile(out_file); myProcess.start(program, arguments); - myProcess.waitForFinished(); + // Waiting for process to finish (argument -1 make it wait until the end of + // the process otherwise it just waits 30 seconds) + myProcess.waitForFinished(-1); int ret = myProcess.exitStatus(); if(ret != 0){