X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGHS3DPRLPlugin%2FGHS3DPRLPlugin_GHS3DPRL.cxx;h=eb92f305a1ed48d3831a05c7024d524546c548b8;hb=f90fb724f90e06b4a14dfc033acfe2a9aed67e1c;hp=6db5e048d2a6c6ae04545b2738afef5add5b3ad4;hpb=4e7a4044db62608ee8ae9fe0dc737a641d88bc23;p=plugins%2Fghs3dprlplugin.git diff --git a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx old mode 100755 new mode 100644 index 6db5e04..eb92f30 --- a/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx +++ b/src/GHS3DPRLPlugin/GHS3DPRLPlugin_GHS3DPRL.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 CEA/DEN, EDF R&D +// Copyright (C) 2007-2021 CEA/DEN, EDF R&D // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -24,38 +24,32 @@ // #include "GHS3DPRLPlugin_GHS3DPRL.hxx" #include "GHS3DPRLPlugin_Hypothesis.hxx" +#include "MG_TetraHPC_API.hxx" #include #include +#include #include - -#include -#include +#include #include "utilities.h" -#ifndef WIN32 -#include -#endif - -#ifdef _DEBUG_ -#define DUMP(txt) \ -// cout << txt -#else -#define DUMP(txt) -#endif - #include #include #include +#include #include #include +#include #include #include #include #include +#define GMFVERSION GmfDouble +#define GMFDIMENSION 3 + using namespace std; static void removeFile( const TCollection_AsciiString& fileName ) @@ -63,21 +57,23 @@ static void removeFile( const TCollection_AsciiString& fileName ) try { OSD_File( fileName ).Remove(); } - catch ( Standard_ProgramError ) { + catch ( Standard_ProgramError& ) { MESSAGE("Can't remove file: " << fileName.ToCString() << " ; file does not exist or permission denied"); } } //============================================================================= -GHS3DPRLPlugin_GHS3DPRL::GHS3DPRLPlugin_GHS3DPRL(int hypId, int studyId, SMESH_Gen* gen) - : SMESH_3D_Algo(hypId, studyId, gen) +GHS3DPRLPlugin_GHS3DPRL::GHS3DPRLPlugin_GHS3DPRL(int hypId, SMESH_Gen* gen) + : SMESH_3D_Algo(hypId, gen) { MESSAGE("GHS3DPRLPlugin_GHS3DPRL::GHS3DPRLPlugin_GHS3DPRL"); _name = "MG-Tetra Parallel"; _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type + _onlyUnaryInput = false; // Compute() will be called on a compound of solids _countSubMesh=0; _nodeRefNumber=0; _compatibleHypothesis.push_back(GHS3DPRLPlugin_Hypothesis::GetHypType()); + _requireShape=false; } //============================================================================= @@ -102,8 +98,8 @@ bool GHS3DPRLPlugin_GHS3DPRL::CheckHypothesis int nbHyp = hyps.size(); if (!nbHyp) { - aStatus = SMESH_Hypothesis::HYP_OK; - return true; // can work with no hypothesis + aStatus = SMESH_Hypothesis::HYP_MISSING; + return false; // can't work with no hypothesis } itl = hyps.begin(); @@ -122,139 +118,21 @@ bool GHS3DPRLPlugin_GHS3DPRL::CheckHypothesis return aStatus == SMESH_Hypothesis::HYP_OK; } -//======================================================================= -// static bool writeGHS3DPRLFiles (const TCollection_AsciiString & GHS3DPRL_In, -// SMESHDS_Mesh * theMesh, -// map & theSmdsToGHS3DPRLIdMap, -// map & theGHS3DPRLIdToNodeMap) -// { -// bool Ok; -// int ifam=0; -// TCollection_AsciiString namefile(GHS3DPRL_In); -// namefile+=".points"; -// removeFile(namefile); -// ofstream theFile; -// theFile.open(namefile.ToCString(),ios::out); -// #ifdef WIN32 -// Ok = theFile.is_open(); -// #else -// Ok=theFile.rdbuf()->is_open(); -// #endif -// if (!Ok) -// { -// INFOS("Can't write into "<NbNodes(); -// int nbFaces=theMesh->NbFaces(); //triangles or quadrangles -// const char* space=" "; -// //const int dummyint=1; //nrs,nsd,refnum=1 (for wrap) - -// // Writing SMESH points into GHS3DPRL File.points -// theFile<nodesIterator(); -// //int ifam=100;//test famille -// theFile.precision(15); theFile.setf(ios::scientific,ios::floatfield); -// //cout<<"set precision 15 on float\n"; -// while (itOnNode->more()) -// { -// node_2 = itOnNode->next(); -// theSmdsToGHS3DPRLIdMap.insert(map ::value_type(node_2->GetID(),aSmdsNodeID)); -// theGHS3DPRLIdToNodeMap.insert(map ::value_type(aSmdsNodeID,node_2)); -// theFile<X()<Y()<Z()<is_open(); -// #endif -// if (!Ok) -// { -// INFOS("Can't write into "<::const_iterator itOnSmdsNode; -// SMDS_ElemIteratorPtr itOnFaceNode; -// SMDS_FaceIteratorPtr itOnSmdsFace = theMesh->facesIterator(); -// long nbNoTriangles=0; -// int ifaces=0; -// //ifam=300; -// while (itOnSmdsFace->more()) -// { -// aFace=itOnSmdsFace->next(); -// itOnFaceNode=aFace->nodesIterator(); -// const int nbNodes=aFace->NbNodes(); -// if (nbNodes!=3) nbNoTriangles++; -// ifaces++; -// theFile<more()) -// { -// aSmdsNodeID=itOnFaceNode->next()->GetID(); -// itOnSmdsNode=theSmdsToGHS3DPRLIdMap.find(aSmdsNodeID); -// ASSERT(itOnSmdsNode!=theSmdsToGHS3DPRLIdMap.end()); -// theFile<GetMEDName(); //"DOMAIN\0" - _NbPart = hyp->GetNbPart(); - _KeepFiles = hyp->GetKeepFiles(); - _Background = hyp->GetBackground(); + _MEDName = hyp->GetMEDName(); //"DOMAIN\0" + _NbPart = hyp->GetNbPart(); + _KeepFiles = hyp->GetKeepFiles(); + _Background = hyp->GetBackground(); _Multithread = hyp->GetMultithread(); - //_ToMergeSubdomains = hyp->GetToMergeSubdomains(); - _Gradation = hyp->GetGradation(); - _MinSize = hyp->GetMinSize(); - _MaxSize = hyp->GetMaxSize(); + _Gradation = hyp->GetGradation(); + _MinSize = hyp->GetMinSize(); + _MaxSize = hyp->GetMaxSize(); + _AdvOptions = hyp->GetAdvancedOption(); } } @@ -286,190 +164,264 @@ static TCollection_AsciiString getTmpDir() return aTmpDir; } +//============================================================================= +// Write a skin mesh into a GMF file or pass it to MG-TetraHPC API +static void exportGMF(MG_TetraHPC_API* theTetraInput, + const char* theFile, + const SMESHDS_Mesh* theMeshDS) +{ + int meshID = theTetraInput->GmfOpenMesh( theFile, GmfWrite, GMFVERSION, GMFDIMENSION); + + // nodes + int iN = 0, nbNodes = theMeshDS->NbNodes(); + theTetraInput->GmfSetKwd( meshID, GmfVertices, nbNodes ); + std::map< const SMDS_MeshNode*, int, TIDCompare > node2IdMap; + SMDS_NodeIteratorPtr nodeIt = theMeshDS->nodesIterator(); + SMESH_TNodeXYZ n; + while ( nodeIt->more() ) + { + n.Set( nodeIt->next() ); + theTetraInput->GmfSetLin( meshID, GmfVertices, n.X(), n.Y(), n.Z(), n._node->getshapeId() ); + node2IdMap.insert( node2IdMap.end(), std::make_pair( n._node, ++iN )); + } + + // triangles + SMDS_ElemIteratorPtr elemIt = theMeshDS->elementGeomIterator( SMDSGeom_TRIANGLE ); + if ( elemIt->more() ) + { + int nbTria = theMeshDS->GetMeshInfo().NbElements( SMDSGeom_TRIANGLE ); + theTetraInput->GmfSetKwd(meshID, GmfTriangles, nbTria ); + for ( int gmfID = 1; elemIt->more(); ++gmfID ) + { + const SMDS_MeshElement* tria = elemIt->next(); + theTetraInput->GmfSetLin(meshID, GmfTriangles, + node2IdMap[ tria->GetNode( 0 )], + node2IdMap[ tria->GetNode( 1 )], + node2IdMap[ tria->GetNode( 2 )], + tria->getshapeId() ); + } + } + theTetraInput->GmfCloseMesh( meshID ); +} + //============================================================================= // Here we are going to use the GHS3DPRL mesher for tetra-hpc (formerly tepal in v3 (2014)) -bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh, - const TopoDS_Shape& theShape) +bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh, + const TopoDS_Shape& /*theShape*/) { - bool Ok=false; - TCollection_AsciiString pluginerror("ghs3dprl: "); - SMESHDS_Mesh* meshDS = theMesh.GetMeshDS(); - //cout<<"GetMeshDS done\n"; - if (_countSubMesh==0){ - MESSAGE("GHS3DPRLPlugin_GHS3DPRL::Compute for tetra-hpc"); - _countTotal=0; - TopExp_Explorer expf(meshDS->ShapeToMesh(), TopAbs_SOLID); - for ( ; expf.More(); expf.Next() ) _countTotal++; - } - _countSubMesh++; - //cout<<"Compute _countSubMesh "<<_countSubMesh<0) { - path=casenamemed.SubString(1,n); - casenamemed=casenamemed.SubString(n+1,casenamemed.Length()); - } - else - path=tmpDir; - - if (casenamemed.Length()>20){ - casenamemed=casenamemed.SubString(1,20); - cerr<<"MEDName truncated (no more 20 characters) = "< avoid warning message - //med_idt fid=MEDouvrir((const char *)fileskinmed.ToCString(),MED_CREATION); - //med_err ret=MEDfermer(fid); - //fileskinmed=fileskinmed + "cp /home/wambeke/empty.med "+ path + "GHS3DPRL_skin.med"; - //system( fileskinmed.ToCString() ); - fileskinmed=path + "GHS3DPRL_skin.med"; - cout<<" Write file "<0) { + path=casenamemed.SubString(1,n); + casenamemed=casenamemed.SubString(n+1,casenamemed.Length()); + } + else + path=tmpDir; + + if (casenamemed.Length()>20){ + casenamemed=casenamemed.SubString(1,20); + cerr<<"MEDName truncated (no more 20 characters) = "< aSmdsToGHS3DPRLIdMap; + map aGHS3DPRLIdToNodeMap; + GHS3DPRL_In = path + "GHS3DPRL"; + GHS3DPRL_Out = path + casenamemed; + GHS3DPRL_Out_Mesh = path + casenamemed + "_out.mesh"; + GHS3DPRL_Outxml = path + casenamemed + ".xml"; //master file + logFileName = path + casenamemed + ".log"; // MG library output + NbPart=_NbPart; + Gradation=_Gradation; + MinSize=_MinSize; + MaxSize=_MaxSize; + + //an example: + //tetrahpc2med --casename=/home/whoami/tmp/GHS3DPRL --number=5 --medname=DOMAIN + // --gradation=1.05 --min_size=1e-3 --max_size=1e-2 + // --verbose=0 --menu=no --launchtetra=yes; + + run_GHS3DPRL = run_GHS3DPRL + + " --casename=" + GHS3DPRL_In + + " --number=" + NbPart + + " --medname=" + GHS3DPRL_Out + + " --launchtetra=yes" + + " --gradation=" + Gradation + + " --min_size=" + MinSize + + " --max_size=" + MaxSize + + " --verbose=3" + + " " + _AdvOptions.c_str(); + if (_Background) run_GHS3DPRL += " --background=yes"; else run_GHS3DPRL += " --background=no"; + if (_Multithread) run_GHS3DPRL += " --multithread=yes"; else run_GHS3DPRL += " --multithread=no"; + run_nokeep_files = rm +GHS3DPRL_In + "* " + path + "tetrahpc.log"; + system( run_nokeep_files.ToCString() ); //clean files + run_nokeep_files = rm + GHS3DPRL_In + "* "; + + fileskinmesh=path + "GHS3DPRL.mesh"; + GHS3DPRL_Out = path + casenamemed; + removeFile( GHS3DPRL_Outxml ); //only the master xml file + + MG_TetraHPC_API mgTetraHPC( _computeCanceled, _progress ); + bool useLib = ( mgTetraHPC.IsLibrary() && !_Background && _Multithread ); + if ( !useLib ) + mgTetraHPC.SetUseExecutable(); + + exportGMF( &mgTetraHPC, fileskinmesh.ToCString(), meshDS ); + + if ( true /*useLib*/ ) + { + TCollection_AsciiString cmd = TCollection_AsciiString("mg-tetra_hpc.exe") + + " --number_of_subdomains=" + NbPart + + " --gradation=" + Gradation + + " --min_size=" + MinSize + + " --max_size=" + MaxSize + + " --verbose=3" + + " --out=" + GHS3DPRL_Out_Mesh + + " " + _AdvOptions.c_str(); + + cout << endl + << " Run mg-tetra_hpc as library. Creating a mesh file " << GHS3DPRL_Out_Mesh << endl + << " Creating a log file : " << logFileName << endl << endl; + mgTetraHPC.SetLogFile( logFileName.ToCString() ); + + std::string log; + mgTetraHPC.Compute( cmd.ToCString(), log ); + + if ( log.empty() ) + log = mgTetraHPC.GetLog(); + if ( log.find(" Dlim " ) != std::string::npos || + log.find(" license ") != std::string::npos ) + return error("License problem"); + + // set --launchtetra=no + int yesPos = run_GHS3DPRL.Search("launchtetra") + sizeof("launchtetra"); + run_GHS3DPRL.SetValue( yesPos+0, 'n' ); + run_GHS3DPRL.SetValue( yesPos+1, 'o' ); + run_GHS3DPRL.SetValue( yesPos+2, ' ' ); + } + else + { + cout<<" Write input file for mg-tetra_hpc "< 0) + { + pluginerror = pluginerror + "PROBLEM tetrahpc2med command"; + cout< aVec = (*anIt).second; - nbtri += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); - nbqua += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); + std::vector aVec = (*anIt).second; + nbtri += std::max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]); + nbqua += std::max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]); GProp_GProps G; BRepGProp::SurfaceProperties(F,G); double anArea = G.Mass(); @@ -491,7 +443,7 @@ bool GHS3DPRLPlugin_GHS3DPRL::Evaluate(SMESH_Mesh& aMesh, } // collect info from edges - int nb0d_e = 0, nb1d_e = 0; + smIdType nb0d_e = 0, nb1d_e = 0; bool IsQuadratic = false; bool IsFirst = true; TopTools_MapOfShape tmpMap; @@ -502,9 +454,9 @@ bool GHS3DPRLPlugin_GHS3DPRL::Evaluate(SMESH_Mesh& aMesh, tmpMap.Add(E); SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current()); MapShapeNbElemsItr anIt = aResMap.find(aSubMesh); - std::vector aVec = (*anIt).second; + std::vector aVec = (*anIt).second; nb0d_e += aVec[SMDSEntity_Node]; - nb1d_e += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); + nb1d_e += std::max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]); if(IsFirst) { IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]); IsFirst = false; @@ -519,11 +471,11 @@ bool GHS3DPRLPlugin_GHS3DPRL::Evaluate(SMESH_Mesh& aMesh, double aVolume = G.Mass(); double tetrVol = 0.1179*ELen*ELen*ELen; double CoeffQuality = 0.9; - int nbVols = (int)aVolume/tetrVol/CoeffQuality; - int nb1d_f = (nbtri*3 + nbqua*4 - nb1d_e) / 2; - int nb1d_in = (int) ( nbVols*6 - nb1d_e - nb1d_f ) / 5; - std::vector aVec(SMDSEntity_Last); - for(int i=0; i aVec(SMDSEntity_Last); + for(smIdType i=0; i