1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 // File : GHS3DPRLPlugin_GHS3DPRL.cxx
22 // Author : Christian VAN WAMBEKE (CEA) (from Hexotic plugin Lioka RAZAFINDRAZAKA)
25 #include "GHS3DPRLPlugin_GHS3DPRL.hxx"
26 #include "GHS3DPRLPlugin_Hypothesis.hxx"
28 #include <SMDS_MeshElement.hxx>
29 #include <SMDS_MeshNode.hxx>
30 #include <SMESH_subMesh.hxx>
32 #include <TopExp_Explorer.hxx>
33 #include <OSD_File.hxx>
35 #include "utilities.h"
38 #include <sys/sysinfo.h>
48 #include <SMESH_Gen.hxx>
49 #include <SMESHDS_Mesh.hxx>
50 #include <SMESH_ControlsDef.hxx>
53 #include <Standard_ProgramError.hxx>
54 #include <TCollection_AsciiString.hxx>
55 #include <TopTools_MapOfShape.hxx>
57 #include <BRepGProp.hxx>
58 #include <GProp_GProps.hxx>
62 //#include <med_config.h>
63 #include <med_utils.h>
64 //#include <med_misc.h>
66 using namespace med_2_2;*/
68 static void removeFile( const TCollection_AsciiString& fileName )
71 OSD_File( fileName ).Remove();
73 catch ( Standard_ProgramError ) {
74 MESSAGE("Can't remove file: " << fileName.ToCString() << " ; file does not exist or permission denied");
78 //=============================================================================
79 GHS3DPRLPlugin_GHS3DPRL::GHS3DPRLPlugin_GHS3DPRL(int hypId, int studyId, SMESH_Gen* gen)
80 : SMESH_3D_Algo(hypId, studyId, gen)
82 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::GHS3DPRLPlugin_GHS3DPRL");
83 _name = "MG-Tetra Parallel";
84 _shapeType = (1 << TopAbs_SHELL) | (1 << TopAbs_SOLID);// 1 bit /shape type
87 _compatibleHypothesis.push_back(GHS3DPRLPlugin_Hypothesis::GetHypType());
90 //=============================================================================
91 GHS3DPRLPlugin_GHS3DPRL::~GHS3DPRLPlugin_GHS3DPRL()
93 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::~GHS3DPRLPlugin_GHS3DPRL");
96 //=============================================================================
97 bool GHS3DPRLPlugin_GHS3DPRL::CheckHypothesis
99 const TopoDS_Shape& aShape,
100 SMESH_Hypothesis::Hypothesis_Status& aStatus)
102 //MESSAGE("GHS3DPRLPlugin_GHS3DPRL::CheckHypothesis");
105 list<const SMESHDS_Hypothesis*>::const_iterator itl;
106 const SMESHDS_Hypothesis* theHyp;
108 const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
109 int nbHyp = hyps.size();
112 aStatus = SMESH_Hypothesis::HYP_OK;
113 return true; // can work with no hypothesis
117 theHyp = (*itl); // use only the first hypothesis
119 string hypName = theHyp->GetName();
120 if (hypName == GHS3DPRLPlugin_Hypothesis::GetHypType())
122 _hypothesis = static_cast<const GHS3DPRLPlugin_Hypothesis*> (theHyp);
124 aStatus = SMESH_Hypothesis::HYP_OK;
127 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
129 return aStatus == SMESH_Hypothesis::HYP_OK;
132 //=======================================================================
133 static bool writeGHS3DPRLFiles (const TCollection_AsciiString & GHS3DPRL_In,
134 SMESHDS_Mesh * theMesh,
135 map <int,int> & theSmdsToGHS3DPRLIdMap,
136 map <int,const SMDS_MeshNode*> & theGHS3DPRLIdToNodeMap)
140 TCollection_AsciiString namefile(GHS3DPRL_In);
142 removeFile(namefile);
144 theFile.open(namefile.ToCString(),ios::out);
146 Ok = theFile.is_open();
148 Ok=theFile.rdbuf()->is_open();
152 INFOS("Can't write into "<<namefile.ToCString());
155 cout<<endl<<"writeGHS3DPRLFiles version 2.1 "<<endl;
156 cout<<endl<<"Creating GHS3DPRL processed mesh file : "<<namefile<<endl;
158 int nbVertices=theMesh->NbNodes();
159 int nbFaces=theMesh->NbFaces(); //triangles or quadrangles
160 const char* space=" ";
161 const int dummyint=1; //nrs,nsd,refnum=1 (for wrap)
163 // Writing SMESH points into GHS3DPRL File.points
164 theFile<<nbVertices<<endl;
167 const SMDS_MeshNode* node_2;
168 SMDS_NodeIteratorPtr itOnNode=theMesh->nodesIterator();
169 //int ifam=100;//test famille
170 theFile.precision(15); theFile.setf(ios::scientific,ios::floatfield);
171 //cout<<"set precision 15 on float\n";
172 while (itOnNode->more())
174 node_2 = itOnNode->next();
175 theSmdsToGHS3DPRLIdMap.insert(map <int,int>::value_type(node_2->GetID(),aSmdsNodeID));
176 theGHS3DPRLIdToNodeMap.insert(map <int,const SMDS_MeshNode*>::value_type(aSmdsNodeID,node_2));
177 theFile<<node_2->X()<<space<<node_2->Y()<<space<<node_2->Z()<<space<<ifam<<endl;
179 //if (aSmdsNodeID==11) ifam++;
181 //no specified points;
184 namefile=GHS3DPRL_In+".faces";
185 removeFile(namefile);
186 theFile.open(namefile.ToCString(),ios::out);
188 Ok=theFile.is_open();
190 Ok=theFile.rdbuf()->is_open();
194 INFOS("Can't write into "<<namefile.ToCString());
197 cout<<endl<<"Creating GHS3DPRL processed mesh file : "<<namefile<<endl;
199 // Writing SMESH faces into GHS3DPRL File.faces
200 theFile<<nbFaces<<" 0"<<endl; //NB_ELEMS DUMMY_INT
201 //" 0" is a reserved parameter
203 const SMDS_MeshElement* aFace;
204 map<int,int>::const_iterator itOnSmdsNode;
205 SMDS_ElemIteratorPtr itOnFaceNode;
206 SMDS_FaceIteratorPtr itOnSmdsFace = theMesh->facesIterator();
207 long nbNoTriangles=0;
210 while (itOnSmdsFace->more())
212 aFace=itOnSmdsFace->next();
213 itOnFaceNode=aFace->nodesIterator();
214 const int nbNodes=aFace->NbNodes();
215 if (nbNodes!=3) nbNoTriangles++;
217 theFile<<nbNodes<<space; // NB_NODES
218 while (itOnFaceNode->more())
220 aSmdsNodeID=itOnFaceNode->next()->GetID();
221 itOnSmdsNode=theSmdsToGHS3DPRLIdMap.find(aSmdsNodeID);
222 ASSERT(itOnSmdsNode!=theSmdsToGHS3DPRLIdMap.end());
223 theFile<<space<<(*itOnSmdsNode).second; //NODE_1 NODE_2 ...
225 //(NB_NODES+1) times: DUMMY_INT
226 //if (ifaces==11) ifam++;
227 theFile<<space<<ifam;
228 for ( int i=1; i<=nbNodes; i++) theFile<<space<<200+i;
233 cout<<"Processed mesh files created, they contains :\n";
234 cout<<" "<<nbVertices<<" vertices\n";
235 if (nbNoTriangles==0)
236 cout<<" "<<nbFaces<<" faces\n\n";
238 cout<<" "<<nbFaces<<" faces with "<<nbNoTriangles<<"faces no triangles\n\n";
242 //=======================================================================
243 static bool getInt( int & theValue, char * & theLine )
246 theValue = strtol( theLine, &ptr, 10 );
247 if ( ptr == theLine ||
248 // there must not be neither '.' nor ',' nor 'E' ...
249 (*ptr != ' ' && *ptr != '\n' && *ptr != '\0'))
252 DUMP( " " << theValue );
257 //=======================================================================
258 static bool getDouble( double & theValue, char * & theLine )
261 theValue = strtod( theLine, &ptr );
262 if ( ptr == theLine )
265 DUMP( " " << theValue );
270 //=======================================================================
272 #define GHS3DPRLPlugin_BUFLENGTH 256
273 #define GHS3DPRLPlugin_ReadLine(aPtr,aBuf,aFile,aLineNb) \
274 { aPtr = fgets( aBuf, GHS3DPRLPlugin_BUFLENGTH - 2, aFile ); aLineNb++; DUMP(endl); }
276 //=======================================================================
277 static bool readResult(FILE * theFile,
278 SMESHDS_Mesh * theMesh,
279 const TopoDS_Shape & theShape,
280 map <int,const SMDS_MeshNode*> & theGHS3DPRLIdToNodeMap,
281 const TCollection_AsciiString & GHS3DPRL_Out,
284 // ---------------------------------
285 // Read generated elements and nodes
286 // ---------------------------------
288 cout << "Reading GHS3DPRL output file : " << GHS3DPRL_Out << endl;
291 char aBuffer[ GHS3DPRLPlugin_BUFLENGTH ];
294 int shapeID = theMesh->ShapeToIndex( theShape );
296 int line = 1, EndOfFile = 0, nbElem = 0, nField = 10, nbRef = 0, aGHS3DPRLNodeID = 0;
297 const char * theField;
299 vector<const char*> tabField = vector<const char*>(nField);
300 vector<int> tabRef = vector<int>(nField);
302 tabField[0] = "MeshVersionFormatted"; tabRef[0] = 0;
303 tabField[1] = "Dimension"; tabRef[1] = 0;
304 tabField[2] = "Vertices"; tabRef[2] = 3;
305 tabField[3] = "Edges"; tabRef[3] = 2;
306 tabField[4] = "Triangles"; tabRef[4] = 3;
307 tabField[5] = "Quadrilaterals"; tabRef[5] = 4;
308 tabField[6] = "Hexahedra"; tabRef[6] = 8;
309 tabField[7] = "Corners"; tabRef[7] = 1;
310 tabField[8] = "Ridges"; tabRef[0] = 1;
311 tabField[9] = "End"; tabRef[0] = 0;
313 nodeRefNumber += theMesh->NbNodes();
315 SMDS_NodeIteratorPtr itOnGHS3DPRLInputNode = theMesh->nodesIterator();
316 while ( itOnGHS3DPRLInputNode->more() )
317 theMesh->RemoveNode( itOnGHS3DPRLInputNode->next() );
319 while ( EndOfFile == 0 ) {
320 GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
321 for ( int iField = 0; iField < nField; iField++ ) {
322 stringstream theMessage;
323 theField = tabField[iField];
324 if ( strncmp(aPtr, theField, strlen(theField)) == 0 ) {
325 if ( strcmp(theField, "End") == 0 ) {
327 theMessage << "End of GHS3DPRL output file has been reached";
330 GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb );
332 getInt( nbElem, aPtr );
334 if ( strcmp(theField, "MeshVersionFormatted") == 0 )
335 theMessage << "GHS3DPRL mesh descriptor : " << theField << " " << nbElem;
336 else if ( strcmp(theField, "Dimension") == 0 )
337 theMessage << "GHS3DPRL mesh of " << nbElem << "D dimension";
338 else if ( strcmp(theField, "Vertices") == 0 ||
339 strcmp(theField, "Edges") == 0 ||
340 strcmp(theField, "Quadrilaterals") == 0 ||
341 strcmp(theField, "Hexahedra") == 0 ) {
342 nbRef = tabRef[iField];
343 GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb ); // read blank line
345 if ( strcmp(theField, "Vertices") == 0 ) {
347 vector<double> coord = vector<double>(nbRef);
348 SMDS_MeshNode * aGHS3DPRLNode;
350 for ( int iElem = 0; iElem < nbElem; iElem++ ) {
351 aGHS3DPRLID = iElem + 1 + nodeRefNumber;
352 GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb ); // read file lines
353 for ( int iCoord = 0; iCoord < 3; iCoord++ )
354 getDouble ( coord[ iCoord ], aPtr );
355 aGHS3DPRLNode = theMesh->AddNode(coord[0], coord[1], coord[2]);
356 theMesh->SetNodeInVolume( aGHS3DPRLNode, shapeID );
357 theGHS3DPRLIdToNodeMap[ aGHS3DPRLID ] = aGHS3DPRLNode;
361 vector<const SMDS_MeshNode*> node = vector<const SMDS_MeshNode*>(nbRef);
362 SMDS_MeshElement* aGHS3DPRLElement;
363 map <int,const SMDS_MeshNode*>::iterator itOnGHS3DPRLNode;
365 for ( int iElem = 0; iElem < nbElem; iElem++ ) {
366 GHS3DPRLPlugin_ReadLine( aPtr, aBuffer, theFile, aLineNb ); // read file lines
367 for ( int iRef = 0; iRef < nbRef; iRef++ ) {
368 getInt ( aGHS3DPRLNodeID, aPtr ); // read nbRef aGHS3DPRLNodeID
369 aGHS3DPRLNodeID += nodeRefNumber;
370 itOnGHS3DPRLNode = theGHS3DPRLIdToNodeMap.find( aGHS3DPRLNodeID );
371 node[ iRef ] = itOnGHS3DPRLNode->second;
374 if ( strcmp(theField, "Edges") == 0 ) // create an element
375 aGHS3DPRLElement = theMesh->AddEdge( node[0], node[1] );
376 else if ( strcmp(theField, "Quadrilaterals") == 0 )
377 aGHS3DPRLElement = theMesh->AddFace( node[0], node[1], node[2], node[3] );
378 else if ( strcmp(theField, "Hexahedra") == 0 )
379 aGHS3DPRLElement = theMesh->AddVolume( node[0], node[1], node[2], node[3], node[4], node[5], node[6], node[7] );
381 theMesh->SetMeshElementOnShape( aGHS3DPRLElement, shapeID );
384 theMessage << nbElem << " " << theField << " created";
387 if ( theMessage.str().size() != 0 ) {
388 cout << theMessage.str() << endl;
398 //=============================================================================
399 // Pass parameters to GHS3DPRL
400 void GHS3DPRLPlugin_GHS3DPRL::SetParameters(const GHS3DPRLPlugin_Hypothesis* hyp)
403 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::SetParameters");
404 _MEDName = hyp->GetMEDName(); //"DOMAIN\0"
405 _NbPart = hyp->GetNbPart();
406 _KeepFiles = hyp->GetKeepFiles();
407 _Background = hyp->GetBackground();
408 _ToMergeSubdomains = hyp->GetToMergeSubdomains();
409 _ToTagSubdomains = hyp->GetToTagSubdomains();
410 _ToOutputInterfaces = hyp->GetToOutputInterfaces();
411 _ToDiscardSubdomains = hyp->GetToDiscardSubdomains();
415 //=======================================================================
416 //before launching salome
417 //SALOME_TMP_DIR (for keep tepal intermediates files) could be set in user's directories
418 static TCollection_AsciiString getTmpDir()
420 TCollection_AsciiString aTmpDir;
421 char *Tmp_dir = getenv("SALOME_TMP_DIR");
422 if (Tmp_dir == NULL) Tmp_dir = getenv("TMP");
427 if(aTmpDir.Value(aTmpDir.Length()) != '\\') aTmpDir+='\\';
429 if(aTmpDir.Value(aTmpDir.Length()) != '/') aTmpDir+='/';
435 aTmpDir = TCollection_AsciiString("C:\\");
437 aTmpDir = TCollection_AsciiString("/tmp/");
443 //=============================================================================
444 // Here we are going to use the GHS3DPRL mesher for tetra-hpc (formerly tepal in v3 (2014))
445 bool GHS3DPRLPlugin_GHS3DPRL::Compute(SMESH_Mesh& theMesh,
446 const TopoDS_Shape& theShape)
449 TCollection_AsciiString pluginerror("ghs3dprl: ");
450 SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
451 //cout<<"GetMeshDS done\n";
452 if (_countSubMesh==0){
453 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::Compute for tetra-hpc");
455 TopExp_Explorer expf(meshDS->ShapeToMesh(), TopAbs_SOLID);
456 for ( ; expf.More(); expf.Next() ) _countTotal++;
459 //cout<<"Compute _countSubMesh "<<_countSubMesh<<endl;
460 //no stuff if multiples submesh, multiple call compute
461 //mesh all in one pass tepal (the last)
462 if (_countSubMesh != _countTotal ) return true;
465 if (_hypothesis==NULL){
466 pluginerror += "No existing parameters/hypothesis for GHS3DPRL";
467 cout <<"\n"<<pluginerror<<"\n\n";
468 error(COMPERR_ALGO_FAILED, pluginerror.ToCString() );
471 SetParameters(_hypothesis);
472 cout << "\n" << _name << " parameters :\n" << endl;
473 cout << " generic path/name of MED Files = " << _MEDName << endl;
474 cout << " number of partitions = " << _NbPart << endl;
475 cout << " merge subdomains = " << _ToMergeSubdomains << endl;
476 cout << " tag subdomains = " << _ToTagSubdomains << endl;
477 cout << " output interfaces = " << _ToOutputInterfaces << endl;
478 cout << " discard dubdomains = " << _ToDiscardSubdomains << endl;
479 cout << " keep intermediates files (from tetra-hpc) = " << _KeepFiles << endl;
480 cout << " background (from tetra-hpc) = " << _Background << "\n\n";
482 //string tmpDir=getTmpDir_new();
483 TCollection_AsciiString
485 GHS3DPRL_In,GHS3DPRL_Out,GHS3DPRL_Outxml,
486 run_GHS3DPRL("tetrahpc2med "),rm("rm -f "),run_nokeep_files,
487 NbPart,fileskinmed(""),fileskinmesh(""),path,casenamemed; //_MEDName.c_str());
489 casenamemed += (char *)_MEDName.c_str();
490 int n=casenamemed.SearchFromEnd('/');
492 path=casenamemed.SubString(1,n);
493 casenamemed=casenamemed.SubString(n+1,casenamemed.Length());
498 if (casenamemed.Length()>20){
499 casenamemed=casenamemed.SubString(1,20);
500 cerr<<"MEDName truncated (no more 20 characters) = "<<casenamemed<<endl;
502 cout<<"path="<<path<<endl;
503 cout<<"casenamemed="<<casenamemed<<endl;
505 map <int,int> aSmdsToGHS3DPRLIdMap;
506 map <int,const SMDS_MeshNode*> aGHS3DPRLIdToNodeMap;
507 GHS3DPRL_In = path + "GHS3DPRL";
508 GHS3DPRL_Out = path + casenamemed;
509 GHS3DPRL_Outxml = path + casenamemed + ".xml"; //master file
511 //tepal2med --casename=/home/whoami/tmp/GHS3DPRL --number=5 --medname=DOMAIN
512 // --limitswap=1000 --verbose=0 --test=no --menu=no --launchtepal=yes;
514 run_GHS3DPRL = run_GHS3DPRL +
515 " --casename=" + GHS3DPRL_In +
516 " --number=" + NbPart +
517 " --medname=" + GHS3DPRL_Out +
518 " --launchtetra=yes";
519 //no more meshhole option
520 //if (_ToMeshHoles) run_GHS3DPRL += " --meshholes=yes"; else run_GHS3DPRL += " --meshholes=no";
521 if (_ToMergeSubdomains) run_GHS3DPRL += " --merge_subdomains=yes"; else run_GHS3DPRL += " --merge_subdomains=no";
522 if (_ToTagSubdomains) run_GHS3DPRL += " --tag_subdomains=yes"; else run_GHS3DPRL += " --tag_subdomains=no";
523 if (_ToOutputInterfaces) run_GHS3DPRL += " --output_interfaces=yes"; else run_GHS3DPRL += " --output_interfaces=no";
524 if (_ToDiscardSubdomains) run_GHS3DPRL += " --discard_subdomains=yes"; else run_GHS3DPRL += " --discard_subdomains=no";
525 if (_Background) run_GHS3DPRL += " --background=yes"; else run_GHS3DPRL += " --background=no";
526 run_nokeep_files = rm +GHS3DPRL_In + "* " + path + "tetrahpc.log";
527 system( run_nokeep_files.ToCString() ); //clean files
528 run_nokeep_files = rm + GHS3DPRL_In + "* ";
530 cout<<"GHS3DPRL command : "<<run_GHS3DPRL.ToCString()<<endl;
531 fileskinmesh=path + "GHS3DPRL.mesh";
532 cout<<"Write input file for tetra_hpc.exe "<<fileskinmesh<<"...";
533 GHS3DPRL_Out = path + casenamemed;
534 removeFile( GHS3DPRL_Outxml ); //only the master xml file
535 //Ok=writeGHS3DPRLFiles(GHS3DPRL_In, meshDS, aSmdsToGHS3DPRLIdMap, aGHS3DPRLIdToNodeMap);
536 bool toCreateGroups = false;
537 theMesh.ExportGMF(fileskinmesh.ToCString(), meshDS, toCreateGroups );
540 // cout<<" ...NOT done\n";
541 // pluginerror = pluginerror + "problem writing input tepal files " + GHS3DPRL_In + ".mesh";
543 //Ecriture dans un fichier MED ?v2.? meme si not Ok
544 //create empty file -> avoid warning message
545 //med_idt fid=MEDouvrir((const char *)fileskinmed.ToCString(),MED_CREATION);
546 //med_err ret=MEDfermer(fid);
547 //fileskinmed=fileskinmed + "cp /home/wambeke/empty.med "+ path + "GHS3DPRL_skin.med";
548 //system( fileskinmed.ToCString() );
549 fileskinmed=path + "GHS3DPRL_skin.med";
550 cout<<"Write file "<<fileskinmed<<"...";
551 theMesh.ExportMED(fileskinmed.ToCString(),"SKIN_INITIAL",true,1);
556 error(COMPERR_ALGO_FAILED, pluginerror.ToCString());
557 return false; //pb abandonne
560 //sometimes it is better to wait flushing files on slow filesystem...
562 system( run_GHS3DPRL.ToCString() );
565 //cout<<"!!!reprise plugin!!!"<<endl;
568 pluginerror = pluginerror + "backgrounding... plugin is not waiting for output files "+ casenamemed + "_*.med";
569 cout<<pluginerror<<endl;
570 error(COMPERR_ALGO_FAILED, pluginerror.ToCString());
571 return false; //but it is not a problem but if true my message is overwritten
572 //return true; //but it is not a problem,
575 // read a result, GHS3DPRL_Out is the name of master file (previous xml format)
576 FILE * aResultFile = fopen( GHS3DPRL_Outxml.ToCString(), "r" );
578 //Ok = readResult( aResultFile, meshDS, theShape, aGHS3DPRLIdToNodeMap, GHS3DPRL_Out, _nodeRefNumber );
580 Ok = false; //but it is not a problem but if true my message is overwritten
582 cout<<"GHS3DPRL OK output master file "<<casenamemed<<".xml exist !\n\n";
583 pluginerror = pluginerror + "new tetraedra not in memory, but stored in files "+ casenamemed + "_*.med";
584 cout<<pluginerror<<endl;
585 error(COMPERR_ALGO_FAILED, pluginerror.ToCString());
586 if (!_KeepFiles) system( run_nokeep_files.ToCString() );
589 Ok = false; //it is a problem AND my message is NOT overwritten
590 pluginerror = pluginerror + "output master file " + casenamemed + ".xml do not exist";
591 cout<<pluginerror<<endl;
592 error(COMPERR_ALGO_FAILED, pluginerror.ToCString() );
593 cout<<"GHS3DPRL KO output files "<<GHS3DPRL_Out<<" do not exist ! see intermediates files keeped:\n";
594 TCollection_AsciiString run_list_files("ls -alt ");
595 run_list_files += GHS3DPRL_Out + "* " + GHS3DPRL_In + "* " + path + "tetrahpc.log";
596 system( run_list_files.ToCString() );
605 //=============================================================================
606 // Here we are going to use the GHS3DPRL mesher (old obsolescent version tepal in v1 & v2 (before 2014))
607 bool GHS3DPRLPlugin_GHS3DPRL::ComputeForTepal(SMESH_Mesh& theMesh,
608 const TopoDS_Shape& theShape)
611 TCollection_AsciiString pluginerror("ghs3dprl: ");
612 SMESHDS_Mesh* meshDS = theMesh.GetMeshDS();
613 //cout<<"GetMeshDS done\n";
614 if (_countSubMesh==0){
615 MESSAGE("GHS3DPRLPlugin_GHS3DPRL::Compute");
617 TopExp_Explorer expf(meshDS->ShapeToMesh(), TopAbs_SOLID);
618 for ( ; expf.More(); expf.Next() ) _countTotal++;
621 //cout<<"Compute _countSubMesh "<<_countSubMesh<<endl;
622 //no stuff if multiples submesh, multiple call compute
623 //mesh all in one pass tepal (the last)
624 if (_countSubMesh != _countTotal ) return true;
627 if (_hypothesis==NULL){
628 pluginerror += "No existing parameters/hypothesis for GHS3DPRL";
629 cout <<"\n"<<pluginerror<<"\n\n";
630 error(COMPERR_ALGO_FAILED, pluginerror.ToCString() );
633 SetParameters(_hypothesis);
634 cout << "\n" << _name << " parameters :\n" << endl;
635 cout << " generic path/name of MED Files = " << _MEDName << endl;
636 cout << " number of partitions = " << _NbPart << endl;
637 //cout << " mesh holes = " << _ToMeshHoles << endl;
638 cout << " mesh holes = " << 1 << endl;
639 cout << " keep intermediates files (from tepal) = " << _KeepFiles << endl;
640 cout << " background (from tepal) = " << _Background << "\n\n";
642 //string tmpDir=getTmpDir_new();
643 TCollection_AsciiString
645 GHS3DPRL_In,GHS3DPRL_Out,GHS3DPRL_Outxml,
646 run_GHS3DPRL("tepal2med "),rm("rm "),run_nokeep_files,
647 NbPart,fileskinmed(""),path,casenamemed; //_MEDName.c_str());
649 casenamemed += (char *)_MEDName.c_str();
650 int n=casenamemed.SearchFromEnd('/');
652 path=casenamemed.SubString(1,n);
653 casenamemed=casenamemed.SubString(n+1,casenamemed.Length());
658 if (casenamemed.Length()>20){
659 casenamemed=casenamemed.SubString(1,20);
660 cerr<<"MEDName truncated (no more 20 characters) = "<<casenamemed<<endl;
662 cout<<"path="<<path<<endl;
663 cout<<"casenamemed="<<casenamemed<<endl;
665 map <int,int> aSmdsToGHS3DPRLIdMap;
666 map <int,const SMDS_MeshNode*> aGHS3DPRLIdToNodeMap;
667 GHS3DPRL_In = path + "GHS3DPRL";
668 GHS3DPRL_Out = path + casenamemed;
669 GHS3DPRL_Outxml = path + casenamemed + ".xml"; //master file
671 //tepal2med --casename=/home/whoami/tmp/GHS3DPRL --number=5 --medname=DOMAIN
672 // --limitswap=1000 --verbose=0 --test=no --menu=no --launchtepal=yes;
674 run_GHS3DPRL = run_GHS3DPRL +
675 " --casename=" + GHS3DPRL_In +
676 " --number=" + NbPart +
677 " --medname=" + GHS3DPRL_Out +
678 " --launchtepal=yes";
679 //if (_ToMeshHoles) run_GHS3DPRL += " --meshholes=yes"; else run_GHS3DPRL += " --meshholes=no";
680 if (1) run_GHS3DPRL += " --meshholes=yes"; else run_GHS3DPRL += " --meshholes=no";
681 if (_Background) run_GHS3DPRL += " --background=yes"; else run_GHS3DPRL += " --background=no";
682 run_nokeep_files = rm +GHS3DPRL_In + "* " + path + "tepal.log";
683 system( run_nokeep_files.ToCString() ); //clean files
684 run_nokeep_files = rm + GHS3DPRL_In + "* ";
686 cout<<"GHS3DPRL command : "<<run_GHS3DPRL.ToCString()<<endl;
687 cout<<"Write files .faces .point ...";
688 GHS3DPRL_Out = path + casenamemed;
689 removeFile( GHS3DPRL_Outxml ); //only the master xml file
690 Ok=writeGHS3DPRLFiles(GHS3DPRL_In, meshDS, aSmdsToGHS3DPRLIdMap, aGHS3DPRLIdToNodeMap);
691 if (Ok) {cout<<" ...done\n";}
693 cout<<" ...NOT done\n";
694 pluginerror = pluginerror + "problem writing input tepal files " + GHS3DPRL_In + "[.faces|.points]";
697 //Ecriture dans un fichier MED ?v2.? meme si not Ok
698 //create empty file -> avoid warning message
699 //med_idt fid=MEDouvrir((const char *)fileskinmed.ToCString(),MED_CREATION);
700 //med_err ret=MEDfermer(fid);
701 //fileskinmed=fileskinmed + "cp /home/wambeke/empty.med "+ path + "GHS3DPRL_skin.med";
702 //system( fileskinmed.ToCString() );
703 fileskinmed=path + "GHS3DPRL_skin.med";
704 cout<<"Write file "<<fileskinmed<<"...";
705 theMesh.ExportMED(fileskinmed.ToCString(),"SKIN_INITIAL",true,1);
709 error(COMPERR_ALGO_FAILED, pluginerror.ToCString());
710 return false; //pb abandonne
713 //sometimes it is better to wait flushing files on slow filesystem...
715 system( run_GHS3DPRL.ToCString() );
718 //cout<<"!!!reprise plugin!!!"<<endl;
721 pluginerror = pluginerror + "backgrounding... plugin is not waiting for output files "+ casenamemed + "_*.med";
722 cout<<pluginerror<<endl;
723 error(COMPERR_ALGO_FAILED, pluginerror.ToCString());
724 return false; //but it is not a problem but if true my message is overwritten
725 //return true; //but it is not a problem,
728 // read a result, GHS3DPRL_Out is the name of master file (previous xml format)
729 FILE * aResultFile = fopen( GHS3DPRL_Outxml.ToCString(), "r" );
731 //Ok = readResult( aResultFile, meshDS, theShape, aGHS3DPRLIdToNodeMap, GHS3DPRL_Out, _nodeRefNumber );
733 Ok = false; //but it is not a problem but if true my message is overwritten
735 cout<<"GHS3DPRL OK output master file "<<casenamemed<<".xml exist !\n\n";
736 pluginerror = pluginerror + "new tetraedra not in memory, but stored in files "+ casenamemed + "_*.med";
737 cout<<pluginerror<<endl;
738 error(COMPERR_ALGO_FAILED, pluginerror.ToCString());
739 if (!_KeepFiles) system( run_nokeep_files.ToCString() );
742 Ok = false; //it is a problem AND my message is NOT overwritten
743 pluginerror = pluginerror + "output master file " + casenamemed + ".xml do not exist";
744 cout<<pluginerror<<endl;
745 error(COMPERR_ALGO_FAILED, pluginerror.ToCString() );
746 cout<<"GHS3DPRL KO output files "<<GHS3DPRL_Out<<" do not exist ! see intermediates files keeped:\n";
747 TCollection_AsciiString run_list_files("ls -alt ");
748 run_list_files += GHS3DPRL_Out + "* " + GHS3DPRL_In + "* " + path + "tepal.log";
749 system( run_list_files.ToCString() );
756 /*pid_t pid = fork();
759 cout<<"le pere est la\n";
760 system("echo le pere > lepere.tmp");
762 system("ps -edf |grep wambeke > pslepere.tmp");
763 cout<<"le pere return 0\n";
766 } else if (pid == 0) {
768 cout<<"le fils est la\n";
769 //On rend le fils independant de tout terminal
772 system("echo le fils > lefils.tmp");
774 system("ps -edf |grep wambeke > pslefils.tmp");
775 cout<<"le fils return 0\n";
778 //Traitement d'erreur
779 cout<<"ya probleme sur fork()\n";
784 //=============================================================================
785 ostream & GHS3DPRLPlugin_GHS3DPRL::SaveTo(ostream & save)
790 //=============================================================================
791 istream & GHS3DPRLPlugin_GHS3DPRL::LoadFrom(istream & load)
796 //=============================================================================
797 ostream & operator << (ostream & save, GHS3DPRLPlugin_GHS3DPRL & hyp)
799 return hyp.SaveTo( save );
802 //=============================================================================
803 istream & operator >> (istream & load, GHS3DPRLPlugin_GHS3DPRL & hyp)
805 return hyp.LoadFrom( load );
809 //=============================================================================
813 //=============================================================================
814 bool GHS3DPRLPlugin_GHS3DPRL::Evaluate(SMESH_Mesh& aMesh,
815 const TopoDS_Shape& aShape,
816 MapShapeNbElems& aResMap)
818 int nbtri = 0, nbqua = 0;
819 double fullArea = 0.0;
820 for (TopExp_Explorer exp(aShape, TopAbs_FACE); exp.More(); exp.Next()) {
821 TopoDS_Face F = TopoDS::Face( exp.Current() );
822 SMESH_subMesh *sm = aMesh.GetSubMesh(F);
823 MapShapeNbElemsItr anIt = aResMap.find(sm);
824 if( anIt==aResMap.end() ) {
825 SMESH_ComputeErrorPtr& smError = sm->GetComputeError();
826 smError.reset( new SMESH_ComputeError(COMPERR_ALGO_FAILED,
827 "Submesh can not be evaluated",this));
830 std::vector<int> aVec = (*anIt).second;
831 nbtri += Max(aVec[SMDSEntity_Triangle],aVec[SMDSEntity_Quad_Triangle]);
832 nbqua += Max(aVec[SMDSEntity_Quadrangle],aVec[SMDSEntity_Quad_Quadrangle]);
834 BRepGProp::SurfaceProperties(F,G);
835 double anArea = G.Mass();
839 // collect info from edges
840 int nb0d_e = 0, nb1d_e = 0;
841 bool IsQuadratic = false;
843 TopTools_MapOfShape tmpMap;
844 for (TopExp_Explorer exp(aShape, TopAbs_EDGE); exp.More(); exp.Next()) {
845 TopoDS_Edge E = TopoDS::Edge(exp.Current());
846 if( tmpMap.Contains(E) )
849 SMESH_subMesh *aSubMesh = aMesh.GetSubMesh(exp.Current());
850 MapShapeNbElemsItr anIt = aResMap.find(aSubMesh);
851 std::vector<int> aVec = (*anIt).second;
852 nb0d_e += aVec[SMDSEntity_Node];
853 nb1d_e += Max(aVec[SMDSEntity_Edge],aVec[SMDSEntity_Quad_Edge]);
855 IsQuadratic = (aVec[SMDSEntity_Quad_Edge] > aVec[SMDSEntity_Edge]);
861 double ELen = sqrt(2.* ( fullArea/(nbtri+nbqua*2) ) / sqrt(3.0) );
864 BRepGProp::VolumeProperties(aShape,G);
865 double aVolume = G.Mass();
866 double tetrVol = 0.1179*ELen*ELen*ELen;
867 double CoeffQuality = 0.9;
868 int nbVols = (int)aVolume/tetrVol/CoeffQuality;
869 int nb1d_f = (nbtri*3 + nbqua*4 - nb1d_e) / 2;
870 int nb1d_in = (int) ( nbVols*6 - nb1d_e - nb1d_f ) / 5;
871 std::vector<int> aVec(SMDSEntity_Last);
872 for(int i=0; i<SMDSEntity_Last; i++) aVec[i]=0;
874 aVec[SMDSEntity_Node] = nb1d_in/6 + 1 + nb1d_in;
875 aVec[SMDSEntity_Quad_Tetra] = nbVols - nbqua*2;
876 aVec[SMDSEntity_Quad_Pyramid] = nbqua;
879 aVec[SMDSEntity_Node] = nb1d_in/6 + 1;
880 aVec[SMDSEntity_Tetra] = nbVols - nbqua*2;
881 aVec[SMDSEntity_Pyramid] = nbqua;
883 SMESH_subMesh *sm = aMesh.GetSubMesh(aShape);
884 aResMap.insert(std::make_pair(sm,aVec));