1 // Copyright (C) 2007-2019 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 : tetrahpc2med.cxx
22 // Author : Christian VAN WAMBEKE (CEA)
26 ** prog principal de ghs3dprl
29 #include <stdio.h> /* printf clrscr fopen fread fwrite fclose */
43 #include <QXmlSimpleReader>
44 #include <QXmlInputSource>
45 #include <QApplication>
47 #include "ghs3dprl_msg_parser.h"
48 //#include "dlg_ghs3dmain.h"
56 //#include "MEDMEM_Exception.hxx"
57 //#include "MEDMEM_define.hxx"
60 //#include <med_config.h>
61 //#include <med_utils.h>
62 //#include <med_misc.h>
64 //************************************
65 med_idt ouvre_fichier_MED(char *fichier,int verbose)
69 med_int majeur,mineur,release;
71 /* on regarde si le fichier existe */
72 ret = (int) access(fichier,F_OK);
73 if (ret < 0) return fid;
75 /* on regarde s'il s'agit d'un fichier au format HDF5 */
77 ret = MEDfileCompatibility(fichier,&hdfok,&medok);
79 std::cerr<<"File "<<fichier<<" not MED or HDF V5 formatted\n";
83 /* Quelle version de MED est utilise par mdump ? */
84 MEDlibraryNumVersion(&majeur,&mineur,&release);
85 if (verbose>0)fprintf(stdout,"\nReading %s with MED V%d.%d.%d",
86 fichier,majeur,mineur,release);
88 /* Ouverture du fichier MED en lecture seule */
89 fid = MEDfileOpen(fichier,MED_ACC_RDONLY);
90 if (ret < 0) return fid;
92 MEDfileNumVersionRd(fid, &majeur, &mineur, &release);
93 if (( majeur < 2 ) || ( majeur == 2 && mineur < 2 )) {
94 fprintf(stderr,"File %s from MED V%d.%d.%d not assumed\n",
95 fichier,majeur,mineur,release);
96 //" version est ant�ieure �la version 2.2";
97 ret = MEDfileClose(fid);
100 if (verbose>0)fprintf(stdout,", file from MED V%d.%d.%d\n",majeur,mineur,release); }
105 //************************************
106 bool ReadFileMED(QString nomfilemed,ghs3dprl_mesh_wrap *mymailw)
110 med_int i,j,sdim,mdim,nmaa,/*edim,majeur_lu,mineur_lu,release_lu,nprofils,*/nstep;
111 med_mesh_type type_maillage;
112 char dtunit[MED_SNAME_SIZE+1];
113 char axisname[MED_SNAME_SIZE+1];
114 char axisunit[MED_SNAME_SIZE*3+1];
115 med_sorting_type sortingtype;
116 med_axis_type axistype;
123 char* chaine = (char*)malloc((nomfilemed.length()+1)*sizeof(char));
124 strncpy(chaine,nomfilemed.toLatin1().constData(),nomfilemed.length()+1);
125 //std::cout<<"*** ReadFileMED *** "<<chaine<<"\n";
127 fid=ouvre_fichier_MED(chaine,mymailw->verbose);
130 std::cerr<<"Problem opening file "<<nomfilemed.toLatin1().constData()<<"\n";
134 nmaa = MEDnMesh(fid);
136 std::cerr<<"No meshes in "<<nomfilemed.toLatin1().constData()<<"\n";
137 ret = MEDfileClose(fid);
140 if (nmaa > 1) std::cout<<"More than one mesh in "<<nomfilemed.toLatin1().constData()<<", first one taken\n";
141 ret = MEDmeshInfo(fid,numero,mymailw->nommaa,&sdim,&mdim,&type_maillage,mymailw->maillage_description,
142 dtunit,&sortingtype,&nstep,&axistype,axisname,axisunit);
144 std::cerr<<"Problem MEDmeshInfo in "<<nomfilemed.toLatin1().constData()<<"\n";
145 ret = MEDfileClose(fid);
148 //changed with version med: a triangles mesh in 3d is dim 2 now and 3 before 2014
149 if (mdim != 2 && mdim != 3){
150 std::cerr<<"Problem mesh dimension should be 2 or 3: "<<mdim<<"\n";
151 ret = MEDfileClose(fid);
155 std::cerr<<"Problem space dimension should be 3: "<<sdim<<"\n";
156 ret = MEDfileClose(fid);
159 if (type_maillage != MED_UNSTRUCTURED_MESH){
160 std::cerr<<"Problem type mesh should be MED_NON_STRUCTURE: "<<type_maillage<<std::endl;
161 ret = MEDfileClose(fid);
165 //lecture nb de noeuds
166 //cf med-3.0.0_install/share/doc/html/maillage_utilisateur.html
167 med_int nnoe=MEDmeshnEntity(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,
168 MED_NODE,MED_NO_GEOTYPE,MED_COORDINATE,MED_NO_CMODE,&chan,&tran);
169 //(med_geometrie_element)0,(med_connectivite)0);
171 std::cerr<<"Problem number of Vertices < 1\n";
172 ret = MEDfileClose(fid);
176 //nombre d'objets MED : mailles, faces, aretes , ...
177 med_int /*nmailles[MED_N_CELL_GEO],*/nbtria3;
178 //med_int nfaces[MED_N_FACE_GEO];
179 med_int /*naretes[MED_N_EDGE_FIXED_GEO],*/nbseg2;
180 //med_int nmailles[MED_NBR_GEOMETRIE_MAILLE],nbtria3;
181 //med_int nfaces[MED_NBR_GEOMETRIE_FACE];
182 //med_int naretes[MED_NBR_GEOMETRIE_ARETE],nbseg2;
183 //polygones et polyedres familles equivalences joints
184 med_int /*nmpolygones,npolyedres,nfpolygones,*/nfam/*,nequ,njnt*/;
186 //Combien de mailles, faces ou aretes pour chaque type geometrique ?
187 /*for (i=0;i<MED_NBR_GEOMETRIE_MAILLE;i++){
188 nmailles[i]=MEDnEntMaa(fid,mymailw->nommaa,MED_CONN,MED_MAILLE,typmai[i],typ_con);
189 //lecture_nombre_mailles_standards(fid,nommaa,typmai[i],typ_con,i);
190 if (mymailw->verbose>6) std::cout<<"NumberOf"<<nommai[i]<<"="<<nmailles[i]<<std::endl;
193 nbtria3=MEDmeshnEntity(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,
194 MED_CELL,MED_TRIA3,MED_CONNECTIVITY,MED_NODAL,&chan,&tran);
195 nbseg2=MEDmeshnEntity(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,
196 MED_CELL,MED_SEG2,MED_CONNECTIVITY,MED_NODAL,&chan,&tran);
198 //combien de familles ?
199 nfam=MEDnFamily(fid,mymailw->nommaa);
200 if (mymailw->verbose>2) {
201 std::cout<<"\nNumberOfFamilies="<<nfam<<std::endl;
202 std::cout<<"NumberOfVertices="<<nnoe<<std::endl;
203 std::cout<<"NumberOfMED_SEG2="<<nbseg2<<std::endl;
204 std::cout<<"NumberOfMED_TRIA3="<<nbtria3<<"\n\n";
207 std::cerr<<"Problem number of MED_TRIA3 < 3, not a skin of a volume\n";
208 ret = MEDfileClose(fid);
212 med_int ifamdelete=0,idelete;
213 std::vector<med_int> famdelete = std::vector<med_int>(nfam);
217 char nomfam[MED_NAME_SIZE+1];
219 //char str1[MED_COMMENT_SIZE+1];
220 char str2[MED_LNAME_SIZE+1];
223 for (i=0;i<nfam;i++) famdelete[i]=0;
224 for (i=0;i<nfam;i++) {
227 ngro = MEDnFamilyGroup(fid,mymailw->nommaa,i+1);
229 std::cerr<<"Problem reading number of groups of family\n";
233 //atributs obsolete MED3
234 //allocation memoire par exces
235 gro = (char*) malloc(MED_LNAME_SIZE*(ngro+1));
237 ret = MEDfamilyInfo(fid,mymailw->nommaa,i+1,nomfam,&numfam,gro);
239 std::cerr<<"Problem reading informations of family\n";
243 if (mymailw->verbose>8) {
244 std::cout<<"Family "<<numfam<<" have "<<ngro<<" groups\n";
245 //affichage des resultats
246 for (j=0;j<ngro;j++) {
247 if (j==0) std::cout<<" Groups :\n";
248 strncpy(str2,gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
249 str2[MED_LNAME_SIZE] = '\0';
250 fprintf(stdout," name = %s\n",str2);
252 if (i==nfam-1) std::cout<<std::endl;
255 sfam=sfam.sprintf("%d",numfam);
257 for (j=0;j<ngro;j++){
258 strncpy(str2,gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
259 str2[MED_LNAME_SIZE]='\0';
261 if (sgro.contains(mymailw->deletegroups)>0) {
262 //std::cout<<"idelete++ "<<sgro<<std::endl;
267 if (idelete==ngro && ngro>0) { //only delete family whith all delete groups
268 //std::cout<<"famdelete++ "<<numfam<<" "<<ifamdelete<<" "<<ngro<<std::endl;
269 famdelete[ifamdelete]=numfam;
274 for (j=0;j<ngro;j++){
275 strncpy(str2,gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
276 str2[MED_LNAME_SIZE]='\0';
278 QRegExp qgroup=QRegExp("Group_Of_All",Qt::CaseSensitive,QRegExp::RegExp);
279 if (sgro.contains(mymailw->deletegroups)==0){
280 if (sgro.contains(qgroup)>0) {
281 sgro="Skin_"+sgro; //pas sur que ce soit pertinent
283 if (mymailw->verbose>8) std::cout<<"families.add("<<sfam.toLatin1().constData()<<
284 ","<<sgro.toLatin1().constData()<<")\n";
285 mymailw->families.add(sfam,sgro);
288 //sgro="Skin_"+sgro; //pas sur que ce soit pertinent
289 //std::cout<<"--deletegroups matches \""<<sfam<<","<<sgro<<"\"\n";
290 if (mymailw->verbose>3) std::cout<<"--deletegroups matches \""<<
291 sgro.toLatin1().constData()<<
292 "\" in family "<<numfam<<std::endl;
297 /*for (j=0;j<ngro;j++){
298 strncpy(str2,gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
299 str2[MED_LNAME_SIZE]='\0';
301 //std::cout<<"families.add("<<sfam<<","<<sgro<<")\n";
302 if (sgro.contains(mymailw->deletegroups)==0){
303 //sgro="Skin_"+sgro; //pas sur que ce soit pertinent
304 std::cout<<"families.add("<<sfam<<","<<sgro<<")\n";
305 mymailw->families.add(sfam,sgro);
308 std::cout<<"--deletegroups matches \""<<sgro<<"\"\n";
309 famdelete[ifamdelete]=numfam
314 //on libere la memoire
319 //std::cout<<"famdelete"; for (j=0;j<ifamdelete;j++) std::cout<<" "<<famdelete[j]; std::cout<<std::endl;
321 if (mymailw->verbose>3){
322 std::cout<<"\nFamiliesAndGroupsOf "<<nomfilemed.toLatin1().constData()<<std::endl;
323 mymailw->families.write();
325 /* Allocations memoires */
326 /* table des coordonnees profil : (space dimension * nombre de noeuds ) */
327 med_float *coo=new med_float[nnoe*sdim];
328 /* table des numeros de familles des noeuds profil : (nombre de noeuds) */
329 med_int *famnodesskin=new med_int[nnoe];
330 //med_int *pfltab=new med_int[1]; //inutilise car on lit tout
331 //lecture des noeuds : coordonnees
332 ret=MEDmeshNodeCoordinateRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_FULL_INTERLACE,coo);
333 //mdim,coo,mode_coo,MED_ALL,pfltab,0,&rep,mymailw->nomcoo,mymailw->unicoo);
335 std::cerr<<"Problem reading nodes\n";
336 ret = MEDfileClose(fid);
339 ret=MEDmeshEntityFamilyNumberRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_NODE,MED_NONE,famnodesskin);
340 //famnodesskin,nnoe,MED_NOEUD,(med_geometrie_element) 0);
342 std::cerr<<"Problem reading families of nodes\n";
343 ret = MEDfileClose(fid);
346 if (mymailw->verbose>9) {
347 std::cout<<"\nVertices: no x y z family\n";
348 for (i=0;i<nnoe*mdim;i=i+3) {
349 fprintf(stdout,"%5d %13.5e %13.5e %13.5e %5d \n",
350 (i/3+1), coo[i], coo[i+1], coo[i+2], famnodesskin[i/3]);
352 std::cout<<std::endl;
355 med_int *conn2=new med_int[nbseg2*2];
356 ret=MEDmeshElementConnectivityRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,
357 MED_CELL,MED_SEG2,MED_NODAL,MED_FULL_INTERLACE,conn2);
358 //mdim,conn2,mode_coo,pfltab,0,MED_MAILLE,MED_SEG2,MED_NOD);
360 std::cerr<<"Problem reading MED_SEG2\n";
361 ret = MEDfileClose(fid);
364 med_int *famseg2skin=new med_int[nbseg2];
365 ret=MEDmeshEntityFamilyNumberRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_CELL,MED_SEG2,famseg2skin);
366 //MEDfamLire(fid,mymailw->nommaa,famseg2skin,nbseg2,MED_MAILLE,MED_SEG2);
368 std::cerr<<"Problem reading families of MED_SEG2\n";
369 ret = MEDfileClose(fid);
372 if (mymailw->verbose>9) {
373 std::cout<<"\nConnectivity MED_SEG2: no node1 node2 family\n";
374 for (i=0;i<nbseg2*2;i=i+2) {
375 fprintf(stdout,"%5d %5d %5d %5d \n",
376 (i/2+1), conn2[i], conn2[i+1], famseg2skin[i/2]);
378 std::cout<<std::endl;
380 //std::cout<<"\ncvw1 conn nbtria3 "<<nbtria3<<"dt "<<MED_NO_DT<<"it "<<MED_NO_IT<<"cell "<<MED_CELL<<"tria3 "<<MED_TRIA3<<std::endl;
381 med_int *conn3=new med_int[nbtria3*3];
382 ret=MEDmeshElementConnectivityRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,
383 MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,conn3);
384 //MEDconnLire(fid,mymailw->nommaa,mdim,conn3,mode_coo,pfltab,0,MED_MAILLE,MED_TRIA3,MED_NOD);
386 std::cerr<<"Problem reading MED_TRIA3\n";
387 ret = MEDfileClose(fid);
390 med_int *famtria3skin=new med_int[nbtria3];
391 ret=MEDmeshEntityFamilyNumberRd(fid,mymailw->nommaa,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,famtria3skin);
392 //MEDfamLire(fid,mymailw->nommaa,famtria3skin,nbtria3,MED_MAILLE,MED_TRIA3);
394 std::cerr<<"Problem reading families of MED_TRIA3\n";
395 ret = MEDfileClose(fid);
398 if (mymailw->verbose>9) {
399 std::cout<<"\nConnectivity MED_TRIA3: no node1 node2 node3 family\n";
400 for (i=0;i<nbtria3*3;i=i+3) {
401 fprintf(stdout,"%5d %5d %5d %5d %5d \n",
402 (i/3+1), conn3[i], conn3[i+1], conn3[i+2], famtria3skin[i/3]);
404 std::cout<<std::endl;
407 /*liberation memoire?
414 //std::cout<<"!!!!!!!!nodes "<<famnodesskin[0]<<" "<<nnoe<<famdelete[1]<<std::endl;
415 for (i=0;i<nnoe;i++) {
416 for (j=0;j<ifamdelete;j++) {
417 if (famnodesskin[i]==famdelete[j]) {
418 //std::cout<<"nodes "<<famnodesskin[i]<<" "<<i<<" "<<famdelete[j]<<std::endl;
422 for (i=0;i<nbseg2;i++) {
423 for (j=0;j<ifamdelete;j++) {
424 if (famseg2skin[i]==famdelete[j]) famseg2skin[i]=0;
427 for (i=0;i<nbtria3;i++) {
428 for (j=0;j<ifamdelete;j++) {
429 if (famtria3skin[i]==famdelete[j]) famtria3skin[i]=0;
433 //stocks data for future use
437 montab=new CVWtab(nnoe*mdim,coo);
438 tmp="SKIN_VERTICES_COORDINATES";
439 ok=mymailw->insert_key(tmp,montab);
441 montab=new CVWtab(nnoe,famnodesskin);
442 tmp="SKIN_VERTICES_FAMILIES";
443 ok=mymailw->insert_key(tmp,montab);
445 montab=new CVWtab(nbseg2*2,conn2);
446 tmp="SKIN_SEG2_CONNECTIVITIES";
447 ok=mymailw->insert_key(tmp,montab);
449 montab=new CVWtab(nbtria3,famseg2skin);
450 tmp="SKIN_SEG2_FAMILIES";
451 ok=mymailw->insert_key(tmp,montab);
453 montab=new CVWtab(nbtria3*3,conn3);
454 tmp="SKIN_TRIA3_CONNECTIVITIES";
455 ok=mymailw->insert_key(tmp,montab);
457 montab=new CVWtab(nbtria3,famtria3skin);
458 tmp="SKIN_TRIA3_FAMILIES";
459 ok=mymailw->insert_key(tmp,montab);
461 //if (mymailw->verbose>6) ok=mymailw->list_keys_mesh_wrap();
463 ret = MEDfileClose(fid);
465 std::cerr<<"Problem closing "<<nomfilemed.toLatin1().constData()<<"\n";
472 mg-tetra_hpc_mpi.exe --help
474 =============================================
475 MG-Tetra_HPC -- MeshGems 2.9-6 (August, 2019)
476 =============================================
480 2, rue de la Piquetterie
481 91680 Bruyeres le Chatel
483 Phone: +33(0)970-650-219 Fax: +33(0)169-269-033
484 EMail: <support@distene.com>
486 Running MG-Tetra_HPC (Copyright 2014-2019 by Distene SAS)
487 date of run: 25-Feb-2020 AT 08:47:20
488 running on : Linux 3.10.0-1062.9.1.el7.x86_64 x86_64
492 MeshGems is a Registered Trademark of Distene SAS
496 Usage: tetra_hpc_mpi.exe [options]
500 Short option (if it exists)
506 --components <components>
507 Selects which mesh components to process.
509 all : all components are to be meshed.
510 outside_components : only the main (outermost) component is to be
515 Sets the size gradation value.
516 <gradation> is the desired maximum ratio between 2 adjacent
517 tetrahedron edges. The closer it is to 1.0, the more uniform the mesh
521 --gradation_mode <mode>
522 Sets the gradation behaviour.
523 Possible values for <mode> are :
524 without_size: apply gradation only when no size is provided by
526 always: always apply the gradation. This can partially smooth the
527 provided input sizemap(s)
528 Default: without_size
533 --in <input mesh file name>
537 --max_edge_length <maximum edge length>
538 Sets the desired maximum accepted edge length.
539 Default: 0 (no maximum length).
541 --max_size <maximum size>
542 Sets the desired maximum cell size value.
543 Default: 0 (no maximum size).
546 Sets the type of metric governing the mesh generation.
547 Possible values for <type> are :
548 isotropic: the metric induces the same size in all directions.
549 anisotropic: the metric induces different sizes depending on the
553 --min_edge_length <minimum edge length>
554 Sets the desired minimum accepted edge length.
555 Default: 0 (no minimum length).
557 --min_size <minimum size>
558 Sets the desired minimum cell size value.
559 Default: 0 (no minimum size).
561 --optimisation <boolean>
562 Sets whether to optimise mesh quality or not.
565 --optimisation_level <level>
566 Sets the desired optimisation level for mesh quality.
567 Possible values for <level> are (in increasing order of quality vs
568 speed ratio): light, standard, strong
571 --out <output mesh file name>
572 Sets the output file.
573 Using an existing file is not allowed.
574 Using the same file as --in is not allowed.
575 If unset, _tetra_hpc is appended to the input file basename.
577 --parallel_strategy <strategy>
578 Sets the desired parallel strategy, influencing the level of
579 reproducibility of the result and the potential performances.
580 Possible values for <strategy> are (in decreasing order for
581 reproducibility and increasing order for performances):
582 reproducible: result is entirely reproducible but performances
584 aggressive: result may not be reproducible but all parallel
585 optimizations are allowed.
586 Default: reproducible.
588 --sizemap <input sizemap file name>
589 Sets the optional input sizemap file. The sizemap must provide the
590 requested size at the input surface or volume mesh vertices.
593 --split_overconstrained_edges <boolean>
594 Sets whether to split over-constrained edges or not. An edge is
595 considered as over-constrained when its two vertices belong to the
598 yes: correction is applied upon mesh generation/optimisation
599 no: no correction is applied.
602 --split_overconstrained_elements <boolean>
603 Sets whether to split over-constrained elements or not. An edge is
604 considered as over-constrained when its two vertices belong to the
605 surface. A tetrahedron is considered as over-constrained when at
606 least two of its faces belong to the surface.
608 yes: correction is applied upon mesh generation/optimisation
609 no: no correction is applied.
612 --split_overconstrained_tetrahedra <boolean>
613 Sets whether to split over-constrained tetrahedra or not. A
614 tetrahedron is considered as over-constrained when at least two of
615 its faces belong to the surface.
617 yes: correction is applied upon mesh generation/optimisation
618 no: no correction is applied.
622 Set the verbosity level, increasing from 0 to 10.
623 Possible <verbose> values are increasing from 0 to 10 :
628 --volume_proximity_layers <minimum number of layers>
629 Sets the desired minimum number of tetrahedra layers inside the
631 Default: 0 (no minimum).
633 --write_sizemap <output sizemap file name>
634 Sets the optional output sizemap file.
635 Using an existing file is not allowed.
636 If unset, the output sizemap will not be written.
639 ================================================================================
640 MG-Tetra_HPC -- MeshGems 2.9-6 (August, 2019)
641 END OF SESSION - MG-Tetra_HPC (Copyright 2014-2019 by Distene SAS)
642 compiled Sep 2 2019 09:58:40 on Linux_64
643 MeshGems is a Registered Trademark of Distene SAS
644 ================================================================================
646 Phone: +33(0)970-650-219 Fax: +33(0)169-269-033
647 EMail: <support@distene.com> )
651 //************************************
652 int main(int argc, char *argv[])
655 int i,nb,nbfiles,limit_swap,nbelem_limit_swap,limit_swap_defaut,verbose,res;
656 float gradation,min_size,max_size;
657 QString path,pathini,casename,casenamemed,fileskinmed,
658 tmp,cmd,format,format_tetra,
659 test,launchtetra,background,multithread,deletegroups,
660 version="V4.0 (MED3 + tetra-hpc v2.3 Sept 2016)";
676 for (i = 0; i < argc; i++){
677 if (!strncmp (argv[i], "--help", sizeof ("--help"))) chelp = &(argv[i][0]);
678 else if (!strncmp (argv[i], "--casename=", sizeof ("--casename"))) ccasename = &(argv[i][sizeof ("--casename")]);
679 else if (!strncmp (argv[i], "--number=", sizeof ("--number"))) cnumber = &(argv[i][sizeof ("--number")]);
680 else if (!strncmp (argv[i], "--limitswap=", sizeof ("--limitswap"))) climitswap = &(argv[i][sizeof ("--limitswap")]);
681 else if (!strncmp (argv[i], "--medname=", sizeof ("--medname"))) cmedname = &(argv[i][sizeof ("--medname")]);
682 else if (!strncmp (argv[i], "--verbose=", sizeof ("--verbose"))) cverbose = &(argv[i][sizeof ("--verbose")]);
683 else if (!strncmp (argv[i], "--launchtetra=", sizeof ("--launchtetra"))) claunchtetra = &(argv[i][sizeof ("--launchtetra")]);
684 else if (!strncmp (argv[i], "--gradation=", sizeof ("--gradation"))) cgradation = &(argv[i][sizeof ("--gradation")]);
685 else if (!strncmp (argv[i], "--min_size=", sizeof ("--min_size"))) cmin_size = &(argv[i][sizeof ("--min_size")]);
686 else if (!strncmp (argv[i], "--max_size=", sizeof ("--max_size"))) cmax_size = &(argv[i][sizeof ("--max_size")]);
687 else if (!strncmp (argv[i], "--background=", sizeof ("--background"))) cbackground = &(argv[i][sizeof ("--background")]);
688 else if (!strncmp (argv[i], "--multithread=", sizeof ("--multithread"))) cmultithread = &(argv[i][sizeof ("--multithread")]);
689 else if (!strncmp (argv[i], "--deletegroups=", sizeof ("--deletegroups"))) cdeletegroups = &(argv[i][sizeof ("--deletegroups")]);
692 if (argc < 2 || chelp){
693 std::cout<<"tetrahpc2med "<<version.toLatin1().constData()<<" Available options:\n"
694 " --help : produces this help message\n"<<
695 " --casename : path and name of input tetrahpc2med files which are\n"<<
696 " - output files of GHS3DPRL_Plugin .mesh\n"<<
697 " - output file of GHS3DPRL_Plugin casename_skin.med (optional)\n"<<
698 " with initial skin and its initial groups\n"<<
699 " --number : number of partitions\n"<<
700 " --medname : path and name of output MED files\n"<<
701 " --limitswap : max size of working cpu memory (Mo) (before swapping on .temp files)\n"<<
702 " --verbose : trace of execution (0->6)\n"<<
703 " --launchtetra : launch mg_tetra_hpc on files casename.mesh and option number,\n"<<
704 " else only use existing input/output files\n"<<
705 " --gradation : the desired maximum ratio between 2 adjacent tetrahedron edges (Default 1.05). The closer it is to 1.0\n"<<
706 " --min_size : the desired maximum cell size value (Default: 0 no maximum size)\n"<<
707 " --max_size : the desired minimum cell size value (Default: 0 no minimum size)\n"<<
708 " --background : force background mode from launch tetra-hpc and generation of final MED files (big meshes)\n"<<
709 " --multithread : launch mg_tetra_hpc multithread version, else mpi version\n"<<
710 " --deletegroups : regular expression (see QRegExp) which matches unwanted groups in final MED files\n"<<
711 " (try --deletegroups=\"(\\bJOINT)\"\n"<<
712 " (try --deletegroups=\"(\\bAll_Nodes|\\bAll_Faces)\"\n"<<
713 " (try --deletegroups=\"((\\bAll_|\\bNew_)(N|F|T))\"\n";
714 std::cout<<"example:\n tetrahpc2med --casename=/tmp/GHS3DPRL --number=2 --medname=DOMAIN "<<
715 "--verbose=0 --launchtetra=no\n\n";
716 return 1; //no output files
720 std::cerr<<"--casename: a path/name is expected\n\n";
725 std::cerr<<"--number: an integer is expected\n\n";
729 nbfiles=tmp.toLong(&ok,10);
731 std::cerr<<"--number: an integer is expected\n\n";
735 std::cerr<<"--number: a positive integer is expected\n\n";
738 if (nbfiles>2048){ //delirium in 2016
739 std::cerr<<"--number: a positive integer <= 2048 is expected\n\n";
742 if (!cmedname) cmedname=ccasename;
743 casenamemed=cmedname;
745 limit_swap_defaut=1000; //1000Mo
746 limit_swap=limit_swap_defaut;
749 limit_swap=tmp.toLong(&ok,10);
751 std::cerr<<"--limitswap: an integer is expected. try 1000\n\n";
754 if (limit_swap<1 || limit_swap>32000){
755 std::cerr<<"--limitswap: [1->32000] expected. try 1000\n\n";
763 verbose=tmp.toLong(&ok,10);
765 std::cerr<<"--verbose: an integer is expected\n\n";
769 std::cerr<<"--verbose: a positive integer is expected\n\n";
774 launchtetra="no"; //default
777 if (tmp=="yes") launchtetra="yes";
780 gradation=1.05; //default
783 gradation=tmp.toFloat(&ok);
785 std::cerr<<"--gradation: a float { 0; ]1,3] } is expected\n\n";
789 std::cerr<<"--gradation: a float <= 3. is expected\n\n";
793 std::cerr<<"--gradation: a float >= 0. is expected\n\n";
800 min_size=tmp.toFloat(&ok);
802 std::cerr<<"--min_size: a float >= 0. is expected\n\n";
806 std::cerr<<"--min_size: a float >= 0. is expected\n\n";
813 max_size=tmp.toFloat(&ok);
815 std::cerr<<"--max_size: a float >= 0. is expected\n\n";
819 std::cerr<<"--max_size: a float >= 0. is expected\n\n";
824 background="no"; //default
827 if (tmp=="yes") background="yes";
830 multithread="no"; //default
833 if (tmp=="yes") multithread="yes";
837 int n=casenamemed.count('/');
839 path=casenamemed.section('/',-n-1,-2)+"/";
842 casenamemed=casenamemed.section('/',-1);
843 if (casenamemed.length()>20){
844 std::cerr<<"--medname truncated (no more 20 characters)"<<std::endl;
845 casenamemed.truncate(20);
848 n=casename.count('/');
850 pathini=casename.section('/',-n-1,-2)+"/";
853 casename=casename.section('/',-1);
854 if (casename.length()>20){
855 std::cerr<<"--casename truncated (no more 20 characters)"<<std::endl;
856 casename.truncate(20);
859 //std::cout<<"CaseNameMed="<<casenamemed.toLatin1().constData()<<std::endl;
860 //std::cout<<"PathMed="<<path.toLatin1().constData()<<std::endl;
862 deletegroups="(\\bxyz)"; //default improbable name
864 deletegroups=cdeletegroups;
870 "tetrahpc2med "<<version.toLatin1().constData()<<" parameters:"<<
871 "\n --casename="<<pathini.toLatin1().constData()<<casename.toLatin1().constData()<<
872 "\n --number="<<nbfiles<<
873 "\n --medname="<<path.toLatin1().constData()<<casenamemed.toLatin1().constData()<<
874 "\n --verbose="<<verbose<<
875 "\n --launchtetra="<<launchtetra.toLatin1().constData()<<
876 "\n --gradation="<<gradation<<
877 "\n --min_size="<<min_size<<
878 "\n --max_size="<<max_size<<
879 "\n --background="<<background.toLatin1().constData()<<
880 "\n --multithread="<<multithread.toLatin1().constData()<<
881 "\n --deletegroups=\""<<deletegroups.toLatin1().constData()<<"\"\n";
883 if (launchtetra=="yes"){
885 //call tetra_hpc.py is python script which assumes mpirun or else if no multithread
886 //after compilation openmpi or else acrobatic DISTENE_LICENCE change...
888 cmd="mg-tetra_hpc.py --number=" + QString::number(nbfiles)+
889 " --in=" + pathini+casename + ".mesh" +
890 " --out=" + pathini+casename + "_out.mesh" +
891 " --gradation=" + QString::number(gradation) +
892 " --min_size=" + QString::number(min_size) +
893 " --max_size=" + QString::number(max_size) +
894 " --multithread=" + multithread.toLatin1().constData() +
895 " > " + path + "tetrahpc.log";
896 std::cout<<"\nlaunch tetra_hpc command:"<<
897 "\n "<<cmd.toLatin1().constData()<<"\n"<<std::endl;
899 else if ( std::ifstream(( pathini+casename + "_out.mesh").toLatin1().constData() ).is_open() )
901 // mesh file exists (created by using MG as a library), copy it to *.000001.mesh
902 QString copyCmd = ( QString("cp -f %1_out.mesh %2_out.000001.mesh")
903 .arg( pathini+casename ).arg( pathini+casename ));
904 system( copyCmd.toLatin1().constData()); // run
907 //utile si appel par plugin ghs3dprl sur big meshes et tetra_hpc sur plusieurs jours
909 if (background=="yes"){
913 exit(0); //temporary ok for plugin
916 //On rend le fils independant de tout terminal
917 //from here everything in background: tetrahpc AND generation of final MED files
919 system("sleep 10"); //for debug
922 printf("background mode is not supported on win32 platform !\n");
925 if (launchtetra=="yes"){
926 //sometimes it is better to wait flushing files on slow filesystem...
928 res = system(cmd.toLatin1().constData()); // run
931 std::cout<<std::endl<<"===end KO PROBLEM of "<<argv[0]<<"==="<<std::endl;
936 ghs3dprl_mesh_wrap *mymailw=new ghs3dprl_mesh_wrap;
937 //no constructor, later maybe
939 mymailw->nbfilestot=nbfiles;
940 //for huge cases big array swap in huge binary files
941 mymailw->verbose=verbose;
942 mymailw->casename=casename;
943 mymailw->medname=casenamemed;
945 mymailw->pathini=pathini;
946 mymailw->deletegroups=QRegExp(deletegroups,Qt::CaseSensitive,QRegExp::RegExp);
947 mymailw->for_multithread=false;
948 if (multithread=="yes") mymailw->for_multithread=true;
949 ghs3dprl_msg_parser handler;
950 //constructor later maybe
951 //handler.verbose=true;
952 handler.mailw=mymailw;
953 mymailw->families.no=1;
954 //std::cout<<"coucou1 "<<mymailw->families.no<<std::endl;
955 //mymailw->families.add(casename,casenamemed);
956 format=format.sprintf("%d",nbfiles);
957 int nbf=format.length();
958 format=format.sprintf(".%%0%dd.%%0%dd",nbf,nbf);
959 format_tetra=".%06d";
960 if (verbose>10)std::cout<<"format "<<format.toLatin1().constData()<<std::endl;
961 if (verbose>10)std::cout<<"format_tetra "<<format_tetra.toLatin1().constData()<<std::endl;
962 mymailw->format=format;
963 mymailw->format_tetra=format_tetra;
964 mymailw->for_tetrahpc=true; //to know what files to read: .noboite or .mesh
966 //default 1GOctet/8(for float)
967 nbelem_limit_swap=limit_swap*1000000; //100%
968 CVWtab::memorymax=nbelem_limit_swap;
969 mymailw->nbelem_limit_swap=nbelem_limit_swap;
972 //something like "/home/wambeke/tmp/GHS3DPRL_skin.med"
973 fileskinmed=pathini+casename+"_skin.med";
974 //fileskinmed="/home/wambeke/tmp/GHS3DPRL_skin.med";
977 char ctmp[fileskinmed.length()+1] ; strcpy(ctmp,fileskinmed);
978 int res=dumpMED(&ctmp[0],1);
980 int ret = access(fileskinmed.toLatin1().constData(),F_OK); //on regarde si le fichier existe
982 ok=ReadFileMED(fileskinmed,mymailw); }
984 if (verbose>0)std::cout<<"Initial skin file <"<<fileskinmed.toLatin1().constData()<<"> does not exist\n"; }
987 //if test quickly read all files before (or only small files)
989 if (verbose>0) std::cout<<"\nReading output files of tetrahpc as input files of tetrahpc2med...\n";
990 //only read beginning of files .xxxxx.mesh
991 //supposed big files big arrays so only see first lines
993 for (int i=1; i<=nbfiles; i++){
995 tmp=pathini+casename+tmp.sprintf(format_tetra.toLatin1().constData(),i)+".mesh";
996 if (verbose>0) std::cout<<"FileName="<<tmp.toLatin1().constData()<<std::endl;
997 ok=mymailw->TestExistingFileMESHnew(tmp);
1000 std::cout<<"NumberOfFilesMESHTested="<<mymailw->nbfiles<<": ok\n\n";
1001 if (mymailw->nbfiles != nbfiles){
1002 std::cerr<<"NumberOfFiles != NumberOfFilesTested is unexpected\n\n";
1007 ok=mymailw->Write_MEDfiles_v2(true); //deletekeys=true
1009 nb=mymailw->remove_all_keys_mesh_wrap();
1010 if (verbose>3)std::cout<<"***remove_all_key_mesh_wrap*** "<<nb<<" keys removed\n";
1012 if (verbose>=0)std::cout<<std::endl<<"===end OK of "<<argv[0]<<"==="<<std::endl;
1015 //int res=dumpMED("/home/wambeke/tmp/DOMAIN_1.med",1);