Salome HOME
Merge branch 'V9_4_BR'
[plugins/ghs3dprlplugin.git] / src / tepal2med / ghs3dprl_mesh_wrap.cxx
1 // Copyright (C) 2007-2019  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 // ---
21 // File   : ghs3dprl_mesh_wrap.cxx
22 // Author : Christian VAN WAMBEKE (CEA) 
23 // ---
24 //
25 #include "ghs3dprl_mesh_wrap.h"
26
27 #include <string>
28 #include <iostream>
29 #include <sstream>
30 #include <fstream>
31 #ifndef WIN32
32 #include <unistd.h>
33 #endif
34
35 #include <libxml/tree.h>
36 #include <libxml/parser.h>
37 #include <libxml/xpath.h>
38 #include <libxml/xpathInternals.h>
39 #ifdef WIN32
40 #include <io.h>
41 #include <windows.h>
42 #include <time.h>
43 #define F_OK 0
44 #undef max
45 #undef min
46 #endif
47
48 #include <QFile>
49 #include <QRegExp>
50 #include <limits>
51
52 #include <med.h>
53 //#include <med_config.h>
54 //#include <med_utils.h>
55 //#include <med_misc.h>
56
57 //utils procedures
58
59 //************************************
60 std::string i2a(const int &v)
61 {
62    std::ostringstream ss;
63    ss<<v;
64    return ss.str();
65 }
66
67 //************************************
68 QString endspace(QString deb,int lg)
69 //better fill by spaces for char unicoo[3*MED_TAILLE_PNOM+1]; etc...
70 {
71    QString fin,spa;
72    //spa.fill(' ',lg);
73    //fin=deb+spa;
74    //fin.truncate(lg);
75    fin=deb.leftJustified(lg,' ',true);
76    return fin;
77 }
78
79 //************************************
80 void charendnull(char *p, QString deb, int lg)
81 {
82    QString fin;
83    fin=deb;
84    fin.truncate(lg-1);
85    strcpy(p,fin.toLatin1().constData()); // 0 at end
86    for (int i=fin.length();i<lg-1;i++){
87        p[i]='\0';
88    }
89 }
90
91 //class familles
92 //************************************
93    void familles::newfam(QString nom){
94       //std::cout<<"newfam "<<nom<<std::endl;
95       if (fam.find(nom)!=fam.end()){
96          std::cout<<"***newfam*** "<<nom.toLatin1().constData()<<" deja present\n";
97          return;
98       }
99       fend gb;
100       fam[nom]=gb;
101    }
102
103 //************************************
104    void familles::newgro(QString nom){
105       //std::cout<<"newgro "<<nom<<std::endl;
106       if (gro.find(nom)!=gro.end()){
107          std::cout<<"***newgro*** "<<nom.toLatin1().constData()<<" deja present\n";
108          return;
109       }
110       fend gb;
111       gro[nom]=gb;
112    }
113    
114 //************************************
115    void familles::write(){
116       fend gb;
117       fagr::iterator it1;
118       fend::iterator it2;
119       int nbf=0,nbg=0;
120       for (it1=fam.begin(); it1!=fam.end(); ++it1){
121          nbf++;
122          std::cout<<"Family=<"<<(*it1).first.toLatin1().constData()<<">\tGroups=";
123          gb=(*it1).second;
124          for (it2=gb.begin(); it2!=gb.end(); ++it2){
125             std::cout<<"<"<<(*it2).first.toLatin1().constData()<<"> ";
126          }
127          std::cout<<std::endl;
128       }
129       if (nbf==0) std::cout<<"no families"<<std::endl;
130       for (it1=gro.begin(); it1!=gro.end(); ++it1){
131          nbg++;
132          std::cout<<"Group=<"<<(*it1).first.toLatin1().constData()<<">\tFamilies=";
133          gb=(*it1).second;
134          for (it2=gb.begin(); it2!=gb.end(); ++it2){
135             std::cout<<"<"<<(*it2).first.toLatin1().constData()<<"> ";
136          }
137          std::cout<<std::endl;
138       }
139       if (nbg==0) std::cout<<"no groups"<<std::endl;
140    }
141
142 //************************************
143    xmlNodePtr familles::xml_groups(){
144       fend gb;
145       fagr::iterator it1;
146       fend::iterator it2;
147       int nb=0,nbf;
148       std::string ss;
149       xmlNodePtr res,node;
150       res=xmlNewNode(NULL, BAD_CAST "groups");
151       for (it1=gro.begin(); it1!=gro.end(); ++it1){
152          node = xmlNewChild(res, 0, BAD_CAST "group",0);
153          ss=(*it1).first.toLatin1().constData();
154          xmlNewProp(node, BAD_CAST "name", BAD_CAST ss.c_str());
155          nb++;
156          gb=(*it1).second;
157          nbf=0; ss="";
158          for (it2=gb.begin(); it2!=gb.end(); ++it2){
159             ss=ss+" "+(*it2).first.toLatin1().constData();
160             nbf++;
161          }
162          xmlNewProp(node, BAD_CAST "families_number", BAD_CAST i2a(nbf).c_str());
163          xmlNewProp(node, BAD_CAST "families", BAD_CAST ss.substr(1).c_str());
164          //std::cout<<std::endl;
165       }
166       xmlNewProp(res, BAD_CAST "number", BAD_CAST i2a(nb).c_str());
167       return res;
168    }
169
170 //************************************
171    void familles::add(QString nomfam, QString nomgro)
172    {
173       //std::cout<<"add family <"<<nomfam<<">\t<"<<nomgro<<">\n";
174       fagr::iterator it;
175       it=fam.find(nomfam);
176       if (it==fam.end()){
177          //std::cout<<"add new family <"<<nomfam<<">\t<"<<nomgro<<">\n";
178          newfam(nomfam);
179          it=fam.find(nomfam);
180       }
181       if (nomgro=="") return; //no group
182       (*it).second[nomgro]=0;
183       it=gro.find(nomgro);
184       if (it==gro.end()){
185          //std::cout<<"***new*** "<<nomgro<<" non present\n";
186          newgro(nomgro);
187          it=gro.find(nomgro);
188       }
189       (*it).second[nomfam]=0;
190
191    }
192
193
194 //************************************
195 bool familles::get_number_of_new_family(int sign, med_int *ires, QString *tmp)
196 //if sign < 0 families faces or tria3 etc...
197 //if sign >= 0 family zero and family nodes
198 //outputs in *ires and *tmp
199 {
200    int pas,i,ii;
201    QString nomfam;
202    fagr::iterator it;
203    if (sign>=0) pas=1; else pas=-1;
204    *tmp="0"; *ires=0;
205    ii=pas;
206    for (i=0;i<10000;i++) { //mefiance
207       nomfam=nomfam.sprintf("%d",ii);
208       it=fam.find(nomfam);
209       if (it==fam.end()) {
210          *tmp=nomfam; *ires=ii;
211          //std::cout<<"NewFamily Found<"<<*ires<<"><"<<*tmp<<">\n";
212          return true;
213       }
214       ii=ii+pas;
215    }
216    std::cerr<<"***get_number_of_new_family*** Problem new family not found"<<std::endl;
217    return false;
218 }
219
220 //************************************
221    med_int familles::find_family_on_groups(med_int fam1, med_int fam2)
222    {
223       med_int ires=0;
224       if (fam1==fam2) {ires=fam1; return ires;}
225       //find one family whith groups of fam1 and groups of fam2
226       fend gb=fuse_goups(fam1,fam2);
227       //find if one family have theses groups
228       fagr::iterator it1;
229       fend::iterator it2;
230       for (it1=fam.begin(); it1!=fam.end(); ++it1){
231          if (gb==(*it1).second){
232             ires=(*it1).first.toLong();
233             //std::cout<<"find_family_on_groups old <"<<ires<<"> from <"<<
234             //       fam1<<"><"<<fam2<<">\n";
235             return ires;
236          }
237       }
238       //std::cout<<"no family found!!! - groups of "<<fam1<<" and "<<fam2<<std::endl;
239       QString tmp;
240       //fam1 positive for nodes negative faces & mailles
241       bool oktmp=get_number_of_new_family(fam1,&ires,&tmp);
242       fend::iterator it;
243       for (it=gb.begin(); it!=gb.end(); ++it){
244           this->add(tmp,(*it).first);
245       }
246       //std::cout<<"new family <"<<ires<<"> intersection of <"<<fam1<<"><"<<fam2<<">\n";
247       return ires;
248    }
249    
250 //************************************
251    fend familles::fuse_goups(med_int fam1, med_int fam2)
252    //concatenation/fusion deux map groupes
253    {
254       QString nom1,nom2;
255       fagr::iterator it1,it2;
256       nom1=nom1.sprintf("%d",fam1);
257       it1=fam.find(nom1);
258       nom2=nom2.sprintf("%d",fam2);
259       it2=fam.find(nom2);
260       if ( (it1==fam.end())||(it2==fam.end()) ) {
261          std::cerr<<"***fuse_goups*** non existing family "<<fam1<<" or "<<fam2<<std::endl;
262          fend gb;
263          return gb; //empty
264       }
265       fend gb=(*it1).second; //firt groups
266       gb.insert((*it2).second.begin(),(*it2).second.end()); //other groups
267       return gb;
268       //for debug
269       std::cout<<"fuse_goups "<<fam1<<" "<<fam2<<" ";
270       fend::iterator it;
271       for (it=gb.begin(); it!=gb.end(); ++it){
272             std::cout<<"<"<<(*it).first.toLatin1().constData()<<"> ";
273       }
274       std::cout<<std::endl;
275       return gb;
276    }
277
278 long CVWtab::memoryuse=0; //static
279 long CVWtab::memorymax=1000*1000000; //static
280
281 //************************************
282 CVWtab::CVWtab(long nb, med_int *pmint)
283 //constructor with pmint allocated yet with new
284 {
285    //std::cout"***constructor med_int CVWtab***\n";
286    size=nb;
287    type=1;  //only tmint valide
288    tmint=pmint;
289    tmflo=NULL;
290    memoryuse=memoryuse+sizeof(med_int)*nb;
291    //std::cout<<"memoryuse int "<<sizeof(med_int)<<" "<<nb<<" "<<memoryuse<<" "<<memorymax<<std::endl;
292    if (memoryuse>memorymax) {
293       std::cout<<"***WARNING*** memory max reached "<<memorymax<<std::endl;
294       //std::cout<<"memoryuse int "<<sizeof(med_int)<<" "<<nb<<" "<<memoryuse<<std::endl;
295    }
296 }
297
298 //************************************
299 CVWtab::CVWtab(long nb, med_float *pmflo)
300 //constructor with pmflo allocated yet with new
301 {
302    //std::cout<<"***constructor med_float CVWtab***\n";
303    size=nb;
304    type=2;   //only tmflo valide
305    tmint=NULL;
306    tmflo=pmflo;
307    memoryuse=memoryuse+sizeof(med_float)*nb;
308    //std::cout<<"memoryuse float "<<sizeof(med_float)<<" "<<nb<<" "<<memoryuse<<" "<<memorymax<<std::endl;
309    if (memoryuse>memorymax) {
310       std::cout<<"***WARNING*** memory max reached "<<memorymax<<std::endl;
311       //std::cout<<"memoryuse float "<<sizeof(med_float)<<" "<<nb<<" "<<memoryuse<<std::endl;
312    }
313 }
314
315 //************************************
316 CVWtab::~CVWtab()
317 {
318    bool ok;
319    //std::cout<<"   destructor CVWtab *** "<<this->filename<<std::endl;
320    ok=this->CVWtab_deallocate();
321    //remove temporary file
322    if (this->filename!="_NO_FILE")
323    {
324       remove(this->filename.toLatin1().constData()); //#include <stdio.h>
325       //std::cout<<this->filename<<" successfully deleted\n";
326    }
327
328 }
329
330 //************************************
331 bool CVWtab::CVWtab_deallocate()
332 {
333    //std::cout<<"   deallocate CVWtab*** "<<size<<std::endl;
334    if (size <= 0) return false;
335    if (tmint)
336    {
337       delete[] tmint;
338       memoryuse=memoryuse-sizeof(med_int)*size;
339       size=-size; //precaution
340    }
341    if (tmflo)
342    {
343       delete[] tmflo;
344       memoryuse=memoryuse-sizeof(med_float)*size;
345       size=-size; //precaution
346    }
347    if (memoryuse<0) std::cout<<"ERROR: on arrays deallocate memory use < 0 "<<memoryuse<<std::endl;
348    if (memoryuse==0) std::cout<<"WARNING: on arrays deallocate memory use = 0 "<<std::endl;
349    return true;
350 }
351
352 //************************************
353 bool CVWtab::is_equal(CVWtab *tab2)
354 {
355    //std::cout<<"is_equal tab1 tab2 type="<<this->type<<"  size="<<this->size<<" "<<tab2->size<<std::endl;
356    //if (this->type==1) std::cout<<"med_int tab1[0]="<<this->tmint[0]<<std::endl;
357    //if (this->type==2) std::cout<<"med_float tab1[0]="<<this->tmflo[0]<<std::endl;
358    if (this->size!=tab2->size) return false;
359    if (this->type!=tab2->type) return false;
360    if (this->type==1)
361    {
362       if (!this->tmint)
363       {  std::cout<<"***is_equal*** pb pointer NULL with tmint size="<<this->size<<std::endl;
364          return false;
365       }
366       for (long i=0; i < this->size; i++)
367          if (this->tmint[i]!=tab2->tmint[i]) return false;
368    }
369    if (this->type==2)
370    {
371       if (!this->tmflo)
372       {  std::cout<<"***is_equal*** pb pointer NULL with tmflo size="<<this->size<<std::endl;
373          return false;
374       }
375       for (long i=0; i < this->size; i++)
376          if (this->tmflo[i]!=tab2->tmflo[i]) return false;
377    }
378    return true;
379 }
380
381 //************************************
382 bool CVW_is_equal_vertices(CVWtab *tab1, long i1,
383                        CVWtab *tab2, long i2, int verbose)
384 //verbose 0 for no prints
385 //verbose 1 for print vertices not equals
386 //verbose 2 for print also vertices equals (debug)
387 {
388    //std::cout<<"is_equal_vertice size="<<tab1->size<<" "<<tab2->size<<std::endl;
389    bool ok=false;
390    med_float *p1,*p2;
391    //vertices indices from 1 not 0!
392    long di1=(i1-1)*3, di2=(i2-1)*3;
393    if (di1<0 || di1>=tab1->size)
394    {
395       std::cerr<<"BadIndice tab1 in is_equal_vertices "<<
396             di1<<" not in "<<tab1->size<<std::endl;
397       return false;
398    }
399    if (di2<0 || di2>=tab2->size)
400    {
401       std::cerr<<"BadIndice tab2 in is_equal_vertices "<<
402             di2<<" not in "<<tab2->size<<std::endl;
403       return false;
404    }
405    p1=(tab1->tmflo+di1);
406    p2=(tab2->tmflo+di2);
407    if (p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2]) ok=true ;
408    if (!ok && verbose>0) printf(
409       "Vertices differents (%.16g %.16g %.16g) (%.16g %.16g %.16g)\n",
410       p1[0],p1[1],p1[2],p2[0],p2[1],p2[2]);
411    else
412       if (verbose>1) printf(
413       "Vertices equals     (%.16g %.16g %.16g)\n",
414       p1[0],p1[1],p1[2]);
415    return ok;
416 }
417
418 //************************************
419 bool CVW_FindString(const std::string &str,std::fstream &Ff, long &count)
420 //find in file first line with string str in first position of line
421 //converts count value expected after "='" in line found
422 {
423    std::string line;
424    QString tmp;
425    do
426    {
427       if (getline(Ff,line))
428       {
429          if (line[0]==str[0]) //faster
430          {
431             if (line.find(str)==0)
432             {
433             tmp=line.c_str();
434             bool ok;
435             count=tmp.section('\'',1,1).toLong(&ok);
436             return ok;
437             }
438          }
439       }
440       else
441       {
442          std::cerr<<"Problem line '"<<str<<"' not found in file\n"<<std::endl;
443          return false;
444       }
445    } while (1);
446    return true;
447 }
448
449 //************************************
450 bool CVW_FindStringInFirstLines(const std::string &str,std::fstream &Ff, long &maxline)
451 //find in file maximum maxline first lines with string str in first position of line
452 //converts count value expected after " " in line found
453 {
454    std::string line;
455    long nbLine=0;
456    do
457    {
458       if (getline(Ff,line))
459       {
460          nbLine++;
461          if (line[0]==str[0]) //faster
462          {
463             if (line.find(str)==0)
464             {
465             return true;
466             }
467          }
468          if (nbLine>=maxline)
469          {
470             std::cerr<<"Problem line '"<<str<<"' not found in first "<<maxline<<" lines of file\n"<<std::endl;
471             return false;
472          }
473       }
474       else
475       {
476          std::cerr<<"Problem line '"<<str<<"' not found in all file\n"<<std::endl;
477          return false;
478       }
479    } while (1);
480    return true;
481 }
482
483 //************************************
484 bool ghs3dprl_mesh_wrap::ReadFileMSGnew(const QString FileName)
485 //read file .glo with no parser xml because big file (volume)
486 //no read of <receive> for speed (and so no test)
487 {
488    QString tmp;
489    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
490    std::string line;
491    long i,count,nbneighbour,ineighbour;
492    bool ok;
493
494    if (!Ff.is_open())
495    {
496       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
497       return false;
498    }
499
500    //Lit les donnees :
501    if (!CVW_FindString("<neighbours count=",Ff,nbneighbour)) return false;
502    if (verbose>2) std::cout<<"NeighboursCountDomain_"<<this->nofile<<"="<<nbneighbour<<std::endl;
503    for (i=1; i<=nbneighbour; i++)
504    {
505       if (!CVW_FindString("<neighbour indice=",Ff,ineighbour)) return false;
506       if (!CVW_FindString("<vertices count=",Ff,count)) return false;
507       if (count>0){
508          med_int *tmint=new med_int[count];
509          for (int i=0; i<count; i++) Ff>>tmint[i];
510          if (verbose>4) std::cout<<"Vertices "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
511
512          CVWtab *montab=new CVWtab(count,tmint);
513          tmp=tmp.sprintf("MS%ld NE%ld VE SE",this->nofile,ineighbour);
514          ok=this->insert_key(tmp,montab);
515       }
516       if (!CVW_FindString("<edges count=",Ff,count)) return false;
517       if (count>0){
518          med_int *tmint=new med_int[count];
519          for (int i=0; i<count; i++) Ff>>tmint[i];
520          if (verbose>4) std::cout<<"Edges "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
521
522          CVWtab *montab=new CVWtab(count,tmint);
523          tmp=tmp.sprintf("MS%ld NE%ld ED SE",this->nofile,ineighbour);
524          ok=this->insert_key(tmp,montab);
525       }
526       if (!CVW_FindString("<faces count=",Ff,count)) return false;
527       if (count>0){
528          med_int *tmint=new med_int[count];
529          for (int i=0; i<count; i++) Ff>>tmint[i];
530          if (verbose>4) std::cout<<"Faces "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
531
532          CVWtab *montab=new CVWtab(count,tmint);
533          tmp=tmp.sprintf("MS%ld NE%ld FA SE",this->nofile,ineighbour);
534          ok=this->insert_key(tmp,montab);
535       }
536       if (!CVW_FindString("<elements count=",Ff,count)) return false;
537       if (count>0){
538          med_int *tmint=new med_int[count];
539          for (int i=0; i<count; i++) Ff>>tmint[i];
540          if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
541
542          CVWtab *montab=new CVWtab(count,tmint);
543          tmp=tmp.sprintf("MS%ld NE%ld EL SE",this->nofile,ineighbour);
544          ok=this->insert_key(tmp,montab);
545       }
546    }
547
548    //Ferme le fichier :
549    Ff.close();
550    this->nbfiles++;
551    return true;
552 }
553
554 //************************************
555 bool ghs3dprl_mesh_wrap::TestExistingFileMESHnew(const QString FileName)
556 //read file .glo with no parser xml because big file (volume)
557 //no read of <receive> for speed (and so no test)
558 {
559    QString tmp;
560    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
561    std::string line;
562    long i,count,meshversion,maxline;
563    bool ok;
564
565    if (!Ff.is_open())
566    {
567       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
568       return false;
569    }
570
571    //Lit les donnees au debut du fichier, 1 lignes maxi:
572    maxline=1;
573    if (!CVW_FindStringInFirstLines("MeshVersionFormatted",Ff,maxline)) return false;
574    if (verbose>2) std::cout<<"MeshVersionFormatted_"<<this->nofile<<" ok"<<std::endl;
575
576    //Ferme le fichier :
577    Ff.close();
578    this->nbfiles++;
579    return true;
580 }
581
582 ///************************************
583 bool ghs3dprl_mesh_wrap::ReadFileGLO(const QString FileName)
584 //read file .glo with no parser xml because big file (volume)
585 {
586    QString tmp;
587    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
588    std::string line;
589    long count;
590    bool ok;
591
592    if (!Ff.is_open())
593    {
594       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
595       return false;
596    }
597
598    //Lit les donnees :
599    if (!CVW_FindString("<vertices count=",Ff,count)) return false;
600    if (verbose>3) std::cout<<"GloVerticesCount="<<count<<std::endl;
601    if (count>0)
602    {
603       med_int *tmint=new med_int[count];
604       for (int i=0; i<count; i++) Ff>>tmint[i];
605       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
606
607       CVWtab *montab=new CVWtab(count,tmint);
608       tmp=tmp.sprintf("GL%ld VE",this->nofile);
609       ok=this->insert_key(tmp,montab);
610    }
611
612    if (!CVW_FindString("<edges count=",Ff,count)) return false;
613    if (verbose>3) std::cout<<"GloEdgesCount="<<count<<std::endl;
614    if (count>0)
615    {
616       med_int *tmint=new med_int[count];
617       for (int i=0; i<count; i++) Ff>>tmint[i];
618       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
619
620       CVWtab *montab=new CVWtab(count,tmint);
621       tmp=tmp.sprintf("GL%ld ED",this->nofile);
622       ok=this->insert_key(tmp,montab);
623    }
624
625    if (!CVW_FindString("<faces count=",Ff,count)) return false;
626    if (verbose>3) std::cout<<"GloFacesCount="<<count<<std::endl;
627    if (count>0)
628    {
629       med_int *tmint=new med_int[count];
630       for (int i=0; i<count; i++) Ff>>tmint[i];
631       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
632
633       CVWtab *montab=new CVWtab(count,tmint);
634       tmp=tmp.sprintf("GL%ld FA",this->nofile);
635       ok=this->insert_key(tmp,montab);
636    }
637
638    if (!CVW_FindString("<elements count=",Ff,count)) return false;
639    if (verbose>3) std::cout<<"GloElementsCount="<<count<<std::endl;
640    if (count>0)
641    {
642       med_int *tmint=new med_int[count];
643       for (int i=0; i<count; i++) Ff>>tmint[i];
644       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
645
646       CVWtab *montab=new CVWtab(count,tmint);
647       tmp=tmp.sprintf("GL%ld EL",this->nofile);
648       ok=this->insert_key(tmp,montab);
649    }
650    //Ferme le fichier :
651    Ff.close();
652    this->nbfiles++;
653    return true;
654 }
655
656 ///************************************
657 bool ghs3dprl_mesh_wrap::ReadFileGLOBAL(const QString FileName)
658 //read file .global ascii (no xml)
659 //first line: Vertices Edges Triangles Tetrahedra
660 {
661    std::string line("                                            ");
662    QString tmp;
663    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
664    long vert=0,edge=0,tria=0,tetr=0,count=0;
665    med_int *tmint;
666    CVWtab *montab;
667    bool ok;
668    
669    if (verbose>=6)std::cout<<"Read file '"<<FileName.toLatin1().constData()<<std::endl;
670    if (!Ff.is_open()){
671       std::cerr<<"Problem file '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
672       return false;
673    }
674    
675    //Lit les donnees :
676    Ff>>vert>>edge>>tria>>tetr;
677    std::cout<<"First line "<<vert<<" "<<edge<<" "<<tria<<" "<<tetr<<std::endl;
678    
679    if (vert<0)
680    {
681       std::cerr<<"Problem Vertices: a positive integer is expected"<<std::endl;
682       return false;
683    }
684
685    if (edge<0)
686    {
687       std::cerr<<"Problem Edges: a positive integer is expected"<<std::endl;
688       return false;
689    }
690
691    if (tria<0)
692    {
693       std::cerr<<"Problem Triangles: a positive integer is expected"<<std::endl;
694       return false;
695    }
696
697    if (tetr<0)
698    {
699       std::cerr<<"Problem Tetrahedra: a positive integer is expected"<<std::endl;
700       return false;
701    }
702
703    count=vert;
704    tmint=new med_int[count];
705    for (int i=0; i<count; i++) Ff>>tmint[i];
706    if (verbose>4) std::cout<<"Vertices ("<<count<<" ) "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
707
708    montab=new CVWtab(count,tmint);
709    tmp=tmp.sprintf("GL%ld VE",this->nofile);
710    ok=this->insert_key(tmp,montab);
711
712    count=edge;
713    tmint=new med_int[count];
714    for (int i=0; i<count; i++) Ff>>tmint[i];
715    if (verbose>4) std::cout<<"Edges ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
716
717    montab=new CVWtab(count,tmint);
718    tmp=tmp.sprintf("GL%ld ED",this->nofile);
719    ok=this->insert_key(tmp,montab);
720
721    count=tria;
722    tmint=new med_int[count];
723    for (int i=0; i<count; i++) Ff>>tmint[i];
724    if (verbose>4) std::cout<<"Triangles ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
725
726    montab=new CVWtab(count,tmint);
727    tmp=tmp.sprintf("GL%ld FA",this->nofile);
728    ok=this->insert_key(tmp,montab);
729
730    count=tetr;
731    tmint=new med_int[count];
732    for (int i=0; i<count; i++) Ff>>tmint[i];
733    if (verbose>4) std::cout<<"Tetrahedra ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
734
735    montab=new CVWtab(count,tmint);
736    tmp=tmp.sprintf("GL%ld EL",this->nofile);
737    ok=this->insert_key(tmp,montab);
738
739    //Ferme le fichier :
740    Ff.close();
741    this->nbfiles++;
742    return true;
743 }
744
745 //************************************
746 bool ghs3dprl_mesh_wrap::ReadFileFACES(const QString FileName)
747 //read file .faces (wrap)
748 {
749    QString tmp;
750    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
751    std::string line;
752    long nbelem,ntype;
753    bool ok;
754
755    if (!Ff.is_open())
756    {
757       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
758       return false;
759    }
760
761    //Lit les donnees :
762    //Replace le pointeur de fichier au debut :f.seekg(0);
763    if (getline(Ff,line))
764    {
765       tmp=line.c_str();
766       nbelem=tmp.section(' ',0,0).toLong(&ok);
767    }
768    else
769    {
770       std::cerr<<"Problem on first line of file"<<std::endl;
771       return false;
772    }
773    if (verbose>3) std::cout<<"FacesNumberOfElements="<<nbelem<<std::endl;
774    med_int *tmint=new med_int[nbelem*7];
775    for (int i=0; i<nbelem*7; i=i+7)
776    {
777       Ff>>ntype;
778       if (ntype!=3) //only triangles
779       {
780          std::cerr<<"Problem on ntype != 3"<<std::endl;
781          return false;
782       }
783       for (int j=0; j<7; j++) Ff>>tmint[i+j];
784       //for (int j=0; j<7; j++) std::cout<<tmint[i+j]<<' '; std::cout<<std::endl;
785    }
786    if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[nbelem*7-1]<<std::endl;
787
788    CVWtab *montab=new CVWtab(nbelem*7,tmint);
789    tmp=tmp.sprintf("FC%ld",this->nofile);
790    ok=this->insert_key(tmp,montab);
791
792    Ff.close();
793    this->nbfiles++;
794    return true;
795 }
796
797 //************************************
798 bool ghs3dprl_mesh_wrap::ReadFileMESH(const QString FileName)
799 //read file .mesh from tetra_hpc (with volume)
800 {
801    std::string line("                                            ");
802    QString tmp;
803    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
804    long Mversion=0,Mdim=0,Mvert=0,Mtria=0,Medge=0,Mtetra=0,count=0;
805    med_int garbage;
806    med_int *tmint;
807    bool ok;
808    
809    if (verbose>=6)std::cout<<"Read file '"<<FileName.toLatin1().constData()<<std::endl;
810    if (!Ff.is_open()){
811       std::cerr<<"Problem file '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
812       return false;
813    }
814
815    //lit les données :
816    if (getline(Ff,line) && (line.find("MeshVersionFormatted")==0))
817    {
818       tmp=line.c_str();
819       Mversion=tmp.section(' ',1,1).toLong(&ok);
820    }
821    else
822    {
823       std::cerr<<"Problem on line 1 of file: 'MeshVersionFormatted' expected"<<std::endl;
824       return false;
825    }
826    
827    getline(Ff,line);
828
829    if (getline(Ff,line) && (line.find("Dimension 3")==0))
830    {
831       tmp=line.c_str();
832       Mdim=tmp.section(' ',1,1).toLong(&ok);
833    }
834    else
835    {
836       std::cerr<<"Problem on line 3 of file: Dimension 3 expected"<<std::endl;
837       return false;
838    }
839    
840    getline(Ff,line);
841
842    if (!(getline(Ff,line) && (line.find("Vertices")==0)))
843    {
844       std::cerr<<"Problem on line 5 of file: 'Vertices' expected"<<std::endl;
845       return false;
846    }
847    if (getline(Ff,line))
848    {
849       tmp=line.c_str();
850       Mvert=tmp.toLong(&ok);
851    }
852    else
853    {
854       std::cerr<<"Problem Vertices: a positive integer is expected"<<std::endl;
855       return false;
856    }
857    if (Mvert<=0)
858    {
859       std::cerr<<"Problem Vertices: a positive integer is expected"<<std::endl;
860       return false;
861    }
862
863    count=Mvert;
864    med_float *tmflo=new med_float[count*3];
865    for (int i=0; i<count*3; i=i+3) Ff>>tmflo[i]>>tmflo[i+1]>>tmflo[i+2]>>garbage;
866    if (verbose>4) std::cout<<"Vertices ("<<count<<") "<<tmflo[0]<<" "<<tmflo[1]<<"... "<<tmflo[count*3-1]<<std::endl;
867
868    CVWtab *montab=new CVWtab(count*3,tmflo);
869    tmp=tmp.sprintf("NB%ld VC",this->nofile);
870    ok=this->insert_key(tmp,montab);
871
872    getline(Ff,line);
873    getline(Ff,line);
874    
875    if (!(getline(Ff,line) && (line.find("Edges")==0)))
876    {
877       std::cerr<<"Problem on line 'Edges' of file '"<<FileName.toLatin1().constData()<<"' :found '"<<line<<"' instead"<<std::endl;
878       return false;
879    }
880    if (getline(Ff,line))
881    {
882       tmp=line.c_str();
883       Medge=tmp.toLong(&ok);
884    }
885    else
886    {
887       std::cerr<<"Problem on line 'Edges' of file: a positive integer is expected"<<std::endl;
888       return false;
889    }
890    if (Medge<=0)
891    {
892       std::cerr<<"Problem on line 'Edges' of file: a positive integer is expected"<<std::endl;
893       return false;
894    }
895
896    count=Medge;
897    tmint=new med_int[count*2]; //*3
898    for (int i=0; i<count*2; i=i+2) {
899      Ff>>tmint[i]>>tmint[i+1]>>garbage;
900    }
901    if (verbose>4) std::cout<<"Edges ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count*2-1]<<std::endl;
902    montab=new CVWtab(count*2,tmint);
903    tmp=tmp.sprintf("NB%ld ED",this->nofile); //TODO see if it could serve
904    ok=this->insert_key(tmp,montab);
905    
906    getline(Ff,line);
907    getline(Ff,line);
908
909    if (!(getline(Ff,line) && (line.find("Triangles")==0)))
910    {
911       std::cerr<<"Problem on line 'Triangles' of file '"<<FileName.toLatin1().constData()<<"' :found '"<<line<<"' instead"<<std::endl;
912       return false;
913    }
914    if (getline(Ff,line))
915    {
916       tmp=line.c_str();
917       Mtria=tmp.toLong(&ok);
918    }
919    else
920    {
921       std::cerr<<"Problem on line 'Triangles' of file: a positive integer is expected"<<std::endl;
922       return false;
923    }
924    if (Mtria<=0)
925    {
926       std::cerr<<"Problem on line 'Triangles' of file: a positive integer is expected"<<std::endl;
927       return false;
928    }
929
930    count=Mtria;
931    tmint=new med_int[count*3]; //*7 as older files .faces, obsolete
932    for (int i=0; i<count*3; i=i+3) {
933      Ff>>tmint[i]>>tmint[i+1]>>tmint[i+2]>>garbage;
934    }
935    if (verbose>4) std::cout<<"Triangles ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<
936        tmint[count*3-5]<<" "<<tmint[count*3-4]<<" "<<tmint[count*3-3]<<" "<<
937        tmint[count*3-2]<<" "<<tmint[count*3-1]<<std::endl;
938
939    montab=new CVWtab(count*3,tmint);
940    tmp=tmp.sprintf("FC%ld",this->nofile);
941    ok=this->insert_key(tmp,montab);
942    
943    getline(Ff,line);
944    getline(Ff,line);
945
946    if (!(getline(Ff,line) && (line.find("Tetrahedra")==0)))
947    {
948       std::cerr<<"Problem on line 'Tetrahedra' of file: not found"<<std::endl;
949       return false;
950    }
951    if (getline(Ff,line))
952    {
953       tmp=line.c_str();
954       Mtetra=tmp.toLong(&ok);
955    }
956    else
957    {
958       std::cerr<<"Problem on line 'Tetrahedra' of file: a positive integer is expected"<<std::endl;
959       return false;
960    }
961    if (Mtetra<=0)
962    {
963       std::cerr<<"Problem on line 'Tetrahedra' of file: a positive integer is expected"<<std::endl;
964       return false;
965    }
966
967    if (verbose>=2)
968    {
969       std::cout<<"MeshVersionFormatted="<<Mversion<<std::endl;
970       std::cout<<"MeshDimension="<<Mdim<<std::endl;
971       std::cout<<"MeshNumberOfVertices="<<Mvert<<std::endl;
972       std::cout<<"MeshNumberOfEdges="<<Medge<<std::endl;
973       std::cout<<"MeshNumberOfTriangles="<<Mtria<<std::endl;
974       std::cout<<"MeshNumberOfTetrahedra="<<Mtetra<<std::endl;
975    }
976
977    count=Mtetra;
978    tmint=new med_int[count*4];
979    for (int i=0; i<count*4; i=i+4) Ff>>tmint[i]>>tmint[i+1]>>tmint[i+2]>>tmint[i+3]>>garbage;
980    if (verbose>4) std::cout<<"Tetrahedra ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count*4-1]<<std::endl;
981
982    montab=new CVWtab(count*4,tmint);
983    tmp=tmp.sprintf("NB%ld EV",this->nofile);
984    ok=this->insert_key(tmp,montab);
985
986    //swap on file if too big for memory in one cpu
987    //default 1GOctet/8(for double)/10(for arrays in memory at the same time)
988    if (Mvert*3>this->nbelem_limit_swap)
989      this->SwapOutOfMemory_key_mesh_wrap(QRegExp("NB",Qt::CaseSensitive,QRegExp::RegExp));
990    //beware record 6 lenght 1
991    //ferme le fichier :
992    Ff.close();
993    this->nbfiles++;
994    return true;
995 }
996
997 //************************************
998 bool ghs3dprl_mesh_wrap::ReadFileNOBOITE(const QString FileName)
999 //read file .noboite (volume)
1000 //for huge files it could be better use ReadFileNOBOITEB (B=binary format)
1001 //(parameter option of ghs3d but NOT tepal)
1002 {
1003    QString tmp;
1004    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
1005    long ne,np,npfixe,subnumber,reste;
1006    bool ok;
1007
1008    if (!Ff.is_open()){
1009       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
1010       return false;
1011    }
1012
1013    //lit les donnees :
1014    Ff>>ne>>np>>npfixe;
1015    if (verbose>3){
1016       std::cout<<"NoboiteNumberOfElements="<<ne<<std::endl;
1017       std::cout<<"NoboiteNumberOfVertices="<<np<<std::endl;
1018       std::cout<<"NoboiteNumberOfSpecifiedPoints="<<npfixe<<std::endl;
1019    }
1020
1021    for (int i=1; i<=17-3; i++) Ff>>reste;
1022    //printf("reste %ld\n",reste);
1023    med_int *tmint=new med_int[ne*4];
1024    for (int i=0; i<ne*4; i++) Ff>>tmint[i];
1025    if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[ne*4-1]<<std::endl;
1026
1027    CVWtab *montab=new CVWtab(ne*4,tmint);
1028    tmp=tmp.sprintf("NB%ld EV",this->nofile);
1029    ok=this->insert_key(tmp,montab);
1030
1031    med_float *tmflo=new med_float[np*3];
1032    for (int i=0; i<np*3; i++) Ff>>tmflo[i];
1033    if (verbose>4) std::cout<<"Vertices "<<tmflo[0]<<" "<<tmflo[1]<<"... "<<tmflo[np*3-1]<<std::endl;
1034
1035    montab=new CVWtab(np*3,tmflo);
1036    tmp=tmp.sprintf("NB%ld VC",this->nofile);
1037    ok=this->insert_key(tmp,montab);
1038
1039    Ff>>subnumber;
1040    if (verbose>2) std::cout<<"NumberOfSubdomains="<<subnumber<<std::endl;
1041    //tmint=new med_int[subnumber*3];
1042    tmint=new  med_int[subnumber*3];
1043    long onelong,maxint;
1044    maxint=std::numeric_limits<int>::max();
1045    //pb from tepalv2
1046    bool isproblem=true;
1047    for (int i=0; i<subnumber*3; i++) {
1048      Ff>>onelong;
1049      //pb from tepalv2
1050      if (onelong<0) {
1051       if (isproblem && verbose>1) std::cout<<"There is one or more negative med_int value in NumberOfSubdomains "<<onelong<<std::endl;
1052       isproblem=false;
1053       onelong=-1;
1054       }
1055      if (onelong>maxint) {
1056       if (isproblem && verbose>1) std::cout<<"There is one or more truncated med_int value in NumberOfSubdomains "<<onelong<<std::endl;
1057       isproblem=false;
1058       onelong=-2;
1059       }
1060      tmint[i]=(int)onelong;
1061      }
1062    if (verbose>4) std::cout<<"Subdomains "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[subnumber*3-1]<<std::endl;
1063
1064    montab=new CVWtab(subnumber*3,tmint);
1065    tmp=tmp.sprintf("NB%ld SN",this->nofile);
1066    ok=this->insert_key(tmp,montab);
1067
1068    //swap on file if too big for memory in one cpu
1069    //default 1GOctet/8(for double)/10(for arrays in memory at the same time)
1070    if (np*3>this->nbelem_limit_swap)
1071      this->SwapOutOfMemory_key_mesh_wrap(QRegExp("NB",Qt::CaseSensitive,QRegExp::RegExp));
1072    //beware record 6 lenght 1
1073    //ferme le fichier :
1074    Ff.close();
1075    this->nbfiles++;
1076    return true;
1077 }
1078
1079 //************************************
1080 bool ghs3dprl_mesh_wrap::ReadFileNOBOITEB(const QString FileName)
1081 //read file .noboiteb (volume)
1082 //for huge files it could be better use ReadFileNOBOITEB (B=binary format)
1083 //but NOT parameter option of tepal
1084 //idem ReadFileNOBOITE with read unformatted
1085 {
1086    bool ok;
1087    QString tmp;
1088    std::cerr<<"Problem function ReadFileNOBOITEB\n"
1089        <<"(no FORTRAN binary format files in tepal)\n\n";
1090    //file binary
1091    FILE *Ff=fopen(FileName.toLatin1().constData(),"rb");
1092    long ne,np,npfixe,reste,subnumber;
1093
1094    //http://www.math.utah.edu/software/c-with-fortran.html
1095    //record 1 from format FORTRAN begins and ends with lengh of record
1096    //=> 2*long(68)     (68=17*4octets)
1097    long r1[17+2];
1098    if (!Ff){
1099       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
1100       return false;
1101    }
1102    //read datas :
1103    fread(&r1,sizeof(long),17+2,Ff);
1104    for (long i=1; i<18; i++) std::cout<<"R1("<<i<<")="<<r1[i]<<std::endl;
1105
1106    if (r1[0]!=68){
1107       std::cerr<<"First FORTRAN record of File '"<<FileName.toLatin1().constData()<<"' not length 17*long"<<std::endl;
1108       return false;
1109    }
1110    ne=r1[1];
1111    np=r1[2];
1112    npfixe=r1[3];
1113    if (verbose>3){
1114       std::cout<<"NoboitebNumberOfElements="<<ne<<std::endl;
1115       std::cout<<"NoboitebNumberOfVertices="<<np<<std::endl;
1116       std::cout<<"NoboitebNumberOfSpecifiedPoints="<<npfixe<<std::endl;
1117    }
1118    //etc...could be done if necessary not debugged
1119    fread(&reste,sizeof(long),1,Ff);
1120    long *tlong=new long[ne*4];
1121    med_int *tmint=new med_int[ne*4];
1122    fread(tlong,sizeof(long),ne*4,Ff);
1123    fread(&reste,sizeof(long),1,Ff);
1124    for (long i=0; i<ne*4; i++) tmint[i]=tlong[i];
1125    delete tlong;
1126    if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[ne*4-1]<<std::endl;
1127
1128    CVWtab *montab=new CVWtab(ne*4,tmint);
1129    tmp=tmp.sprintf("NB%ld EV",this->nofile);
1130    ok=this->insert_key(tmp,montab);
1131
1132    fread(&reste,sizeof(long),1,Ff);
1133    //std::cout<<"info "<<reste<<" "<<np*3<<" "<<sizeof(med_float)<<std::endl;
1134    float *tfloat=new float[np*3];
1135    med_float *tmflo=new med_float[np*3];
1136    fread(tfloat,sizeof(float),np*3,Ff);
1137    fread(&reste,sizeof(long),1,Ff);
1138    for (long i=0; i<np*3; i++) tmflo[i]=tfloat[i];
1139    delete tfloat;
1140    if (verbose>4) printf("Vertices %g %g ... %g \n",tmflo[0],tmflo[1],tmflo[np*3-1]);
1141
1142    montab=new CVWtab(np*3,tmflo);
1143    tmp=tmp.sprintf("NB%ld VC",this->nofile);
1144    ok=this->insert_key(tmp,montab);
1145
1146    fread(&reste,sizeof(long),1,Ff);
1147    fread(&subnumber,sizeof(long),1,Ff);
1148    fread(&reste,sizeof(long),1,Ff);
1149    if (verbose>2) std::cout<<"NumberOfSubdomains="<<subnumber<<std::endl;
1150    fread(&reste,sizeof(long),1,Ff);
1151    tlong=new long[subnumber*3];
1152    fread(tlong,sizeof(long),subnumber*3,Ff);
1153    fread(&reste,sizeof(long),1,Ff);
1154    if (verbose>4) printf("Subdomains %ld %ld ... %ld \n",tlong[0],tlong[1],tlong[subnumber*3-1]);
1155
1156    tmint=new med_int[subnumber*3];
1157    for (long i=0; i<subnumber*3; i++) tmint[i]=tlong[i];
1158    delete tlong;
1159    montab=new CVWtab(subnumber*3,tmint);
1160    tmp=tmp.sprintf("NB%ld SN",this->nofile);
1161    ok=this->insert_key(tmp,montab);
1162
1163    //swap on file if too big for memory in one cpu
1164    //default 1GOctet/8(for double)/10(for arrays in memory at the same time)
1165    if (np*3>this->nbelem_limit_swap)
1166      this->SwapOutOfMemory_key_mesh_wrap(QRegExp("NB",Qt::CaseSensitive,QRegExp::RegExp));
1167
1168    //beware record 6 lenght 1
1169    //ferme le fichier :
1170    fclose(Ff);
1171    this->nbfiles++;
1172    return true;
1173 }
1174
1175 //************************************
1176 bool ghs3dprl_mesh_wrap::ReadFilePOINTS(const QString FileName)
1177 //read file .points (wrap)
1178 {
1179    QString tmp;
1180    long nb;
1181    long maxlen=128;
1182    bool ok=true;
1183
1184    //Lit les donnees :
1185    QFile Ff(FileName);
1186    //NOT Raw because Raw=non-buffered file access
1187    //qt3 ok=Ff.open(IO_ReadOnly|IO_Translate);
1188    ok=Ff.open(QIODevice::ReadOnly|QIODevice::Text);
1189    if (!ok){
1190       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
1191       return false;
1192    }
1193    tmp=Ff.readLine(maxlen);
1194    tmp=tmp.simplified();
1195    nb=tmp.toLong(&ok);
1196    if (!ok){
1197       std::cerr<<"Problem conversion File '"<<FileName.toLatin1().constData()<<"\n"<<std::endl;
1198       return false;
1199    }
1200    if (verbose>2) std::cout<<"NumberOfVertices="<<nb<<std::endl;
1201    med_float *tmflo=new med_float[3*nb]; //coordinates
1202    med_int *tmint=new med_int[nb];         //nrs (attribute of point)
1203    long il3=0;
1204    for ( long il=0; il<nb; il++ ){
1205       tmp=Ff.readLine(maxlen);
1206       tmp=tmp.simplified();
1207       for ( int j=0; j<3; j++ ){
1208          tmflo[il3]=tmp.section(' ',j,j).toDouble(&ok);
1209          //std::cout<<"cv '"<<tmflo[il3]<<"' "<<il3<<std::endl;
1210          il3++;
1211          if (!ok){
1212             std::cerr<<"Problem conversion File '"<<FileName.toLatin1().constData()<<"\n"<<std::endl;
1213             return false;
1214          }
1215       }
1216       //nrs is vertex attribute
1217       tmint[il]=tmp.section(' ',3,3).toLong(&ok);
1218       if (!ok){
1219          std::cerr<<"Problem conversion File '"<<FileName.toLatin1().constData()<<"\n"<<std::endl;
1220          return false;
1221       }
1222    }
1223    //beware no examples with each specified points (if any) here
1224    CVWtab *montab=new CVWtab(nb,tmint); //init montab->tmint nrs
1225    tmp=tmp.sprintf("PO%ld NRS",this->nofile);
1226    ok=this->insert_key(tmp,montab);
1227
1228    montab=new CVWtab(nb,tmflo); //init montab->tmflo xyz
1229    tmp=tmp.sprintf("PO%ld XYZ",this->nofile);
1230    ok=this->insert_key(tmp,montab);
1231
1232    //Ferme le fichier :
1233    Ff.close();
1234    this->nbfiles++;
1235    return true;
1236 }
1237
1238 //************************************
1239 bool ghs3dprl_mesh_wrap::list_keys_mesh_wrap()
1240 {
1241    QHashIterator<QString,CVWtab*> it( this->mestab);
1242    while ( it.hasNext() ) {
1243      it.next();
1244      QString nom = it.key().leftJustified(32,' ');
1245      std::cout<<nom.toLatin1().constData()<<"-> size="<<it.value()->size<<std::endl;
1246    }
1247    return true;
1248 }
1249
1250 //************************************
1251 long ghs3dprl_mesh_wrap::remove_all_keys_mesh_wrap()
1252 {
1253    long nb=this->remove_key_mesh_wrap(QRegExp(".",Qt::CaseSensitive,QRegExp::RegExp));
1254    return nb;
1255 }
1256
1257 //************************************
1258 long ghs3dprl_mesh_wrap::remove_key_mesh_wrap(const QRegExp &rxp)
1259 {
1260    long nbremove=0;
1261    QMutableHashIterator<QString,CVWtab*> it(this->mestab);
1262    while ( it.hasNext() ){
1263      it.next();
1264      if (it.key().contains(rxp)) {
1265         nbremove++;
1266         if (this->verbose>6) std::cout<<"remove key "<<it.key().toLatin1().constData()<<std::endl;
1267         delete it.value();
1268         it.remove();
1269      }
1270    }
1271    return nbremove;
1272 }
1273
1274 //************************************
1275 long ghs3dprl_mesh_wrap::nb_key_mesh_wrap(const QRegExp &rxp)
1276 {
1277    long nbremove=0;
1278    //std::cout<<"nb_key_mesh_wrap on "<<std::endl;
1279    QMutableHashIterator<QString,CVWtab*> it(this->mestab);
1280    while ( it.hasNext() ){
1281      it.next();
1282      if (it.key().contains(rxp)) nbremove++;
1283    }
1284    //std::cout<<"nb_key_mesh_wrap found "<<nbremove<<std::endl;
1285    return nbremove;
1286 }
1287
1288 //************************************
1289 bool SwapOnFile(const QString &key,const QString &path,CVWtab *tab,int verbose)
1290 //
1291 {
1292    //return true;
1293    if (tab->filename=="_NO_FILE"){
1294       tab->filename=path+key+".tmp";
1295       tab->filename.replace(" ","_"); //replace " " by "_"
1296
1297       //swap disque binaire
1298       //montab->tmint=new long[10]; //for test
1299       //for (int i=0; i<10; i++) montab->tmint[i]=i*2;
1300       FILE *fichier=fopen(tab->filename.toLatin1().constData(),"wb");
1301       long taille;
1302       taille=tab->size;
1303       fwrite(&taille,sizeof(taille),1,fichier);
1304       if (tab->tmint){
1305          if (verbose>3)
1306          std::cout<<"SwapOnFile_binary "<<tab->filename.toLatin1().constData()<<
1307          " NbElements "<<taille<<
1308          " SizeElement_med_int   "<<sizeof(med_int)<<
1309          " TotalSizeBinary " <<taille*sizeof(med_int)<<std::endl;
1310          fwrite(tab->tmint,sizeof(med_int),taille,fichier);
1311          //fread(&gagnants,sizeof(gagnants),1,fichier);
1312       }
1313       if (tab->tmflo){
1314          if (verbose>3)
1315          std::cout<<"SwapOnFile_binary "<<tab->filename.toLatin1().constData()<<
1316          " NbElements "<<taille<<
1317          " SizeElement_med_float "<<sizeof(med_float)<<
1318          " TotalSizeBinary " <<taille*sizeof(med_float)<<std::endl;
1319          fwrite(tab->tmflo,sizeof(med_float),taille,fichier);
1320       }
1321       fclose(fichier);
1322    }
1323    else{
1324       if (verbose>3) std::cout<<"SwapOnFile in binary file done yet "<<
1325          tab->filename.toLatin1().constData()<<std::endl;
1326    }
1327    //deallocate because swap disk binary mode
1328    tab->CVWtab_deallocate(); //free memory
1329    return true;
1330 }
1331
1332 //************************************
1333 long ghs3dprl_mesh_wrap::SwapOutOfMemory_key_mesh_wrap(const QRegExp &rxp,
1334                                                        long ifgreaterthan)
1335 //swap on file if not yet and if size greater than ifgreaterthan
1336 {
1337    long nb=0;
1338    bool ok;
1339    QHashIterator<QString,CVWtab*> it(this->mestab);
1340    while ( it.hasNext() ) {
1341      it.next();
1342      if (it.key().contains(rxp)) {
1343         nb++;
1344         if ((it.value()->size>0)&&(it.value()->size>ifgreaterthan)){
1345            if (verbose>3)
1346               std::cout<<"SwapOutOfMemory_key_mesh_wrap on demand "<<
1347                    it.key().toLatin1().constData()<<
1348                    " size "<<it.value()->size<<">"<<ifgreaterthan<<std::endl;
1349            //free memory
1350            ok=SwapOnFile(it.key(),this->path,it.value(),this->verbose);
1351        }
1352      }
1353    }
1354    return nb;
1355 }
1356 //************************************
1357 bool ghs3dprl_mesh_wrap::list_onekey_mesh_wrap(const QString &key)
1358 {
1359    CVWtab *montab=this->mestab[key];
1360    if (montab){
1361       //std::cout<<"key "<<key<<"trouvee -> size="<<montab->size<<std::endl;
1362       if (montab->type==1)
1363          for ( long i=0; i<montab->size; i++ )
1364             std::cout<<montab->tmint[i]<<" ";
1365       if (montab->type==2)
1366          for ( long i=0; i<montab->size; i++ )
1367             std::cout<<montab->tmflo[i]<<" ";
1368       std::cout<<std::endl;
1369    }
1370    else
1371       std::cout<<"key "<<key.toLatin1().constData()<<" not found"<<std::endl;
1372    return true;
1373 }
1374
1375 //************************************
1376 bool ghs3dprl_mesh_wrap::insert_key(const QString &key,CVWtab *tab)
1377 //insertion conditionnee par limite this->nbelem_limit_swap
1378 //si tableaux contenus on dimension superieure
1379 //alors swap disque dans getenv(tmp) fichier temporaire binaire
1380 {
1381    bool ok;
1382    if (verbose>4)
1383       std::cout<<"insert key "<<key.toLatin1().constData()<<
1384             " size="<<tab->size<<std::endl;
1385    tab->filename="_NO_FILE";
1386    if (this->nbelem_limit_swap<tab->size) {
1387       if (verbose>3) std::cout<<"insert key automatic SwapOnFile "<<
1388                            key.toLatin1().constData()<<std::endl;
1389       ok=SwapOnFile(key,this->path,tab,this->verbose);
1390    }
1391    this->mestab.insert(key,tab);
1392    return true;
1393 }
1394 //************************************
1395 CVWtab* ghs3dprl_mesh_wrap::restore_key(const QString &key)
1396 //retauration conditionnee par limite nbelem
1397 //si tableaux contenus on dimension superieure a nbelem
1398 //alors swap disque dans getenv(tmp) fichier temporaire
1399 //alors lecture du fichier (et reallocate memory)
1400 {
1401    CVWtab *tab=NULL;
1402    tab=this->mestab[key];
1403    /*if (tab) std::cout<<" -> size in proc "<<tab->size<<std::endl;
1404    else std::cout<<" -> tab NULL\n";*/
1405    if (!tab) //it is NOT a problem
1406    {
1407       if (verbose>6) std::cout<<"restore key not found "<<key.toLatin1().constData()<<std::endl;
1408       return NULL;
1409    }
1410    if (tab->size > 0){
1411       if (verbose>5) std::cout<<"restore key direct from memory "<<key.toLatin1().constData()<<" size="<<tab->size<<std::endl;
1412       return tab;
1413    }
1414    //restore from binary file
1415    if ((tab->type<1)||(tab->type>2)){
1416       std::cerr<<"Problem restore key from binary file "<<tab->filename.toLatin1().constData()<<
1417                " type unexpexted "<<tab->type<<std::endl;
1418       return NULL;
1419    }
1420    //std::cout<<"restore_key from binary file "<<tab->filename<<std::endl;
1421
1422    //swap disque binaire
1423    FILE *fichier=fopen(tab->filename.toLatin1().constData(),"rb");
1424    long taille;
1425    fread(&taille,sizeof(long),1,fichier);
1426    if (taille!=-tab->size){
1427       std::cerr<<"Problem restore_key from binary file "<<tab->filename.toLatin1().constData()<<
1428             " size unexpexted "<<taille<<" expected "<<-tab->size<<std::endl;
1429       fclose(fichier);
1430       return NULL;
1431    }
1432    if (tab->type==1){
1433       if (verbose>5)
1434       std::cout<<"restore key from binary file "<<tab->filename.toLatin1().constData()<<
1435             " number of elements "<<taille<<
1436             " size_element med_float "<<sizeof(med_float)<<
1437             " total_size_binary " <<taille*sizeof(med_float)<<std::endl;
1438
1439       //allocate because swap disque binaire
1440       tab->tmint=new med_int[taille]; //allocate memory
1441       fread(tab->tmint,sizeof(med_int),taille,fichier);
1442    }
1443    if (tab->type==2){
1444       if (verbose>5)
1445       std::cout<<"restore key from binary file "<<tab->filename.toLatin1().constData()<<
1446             " number of elements "<<taille<<
1447             " size_element med_float "<<sizeof(med_float)<<
1448             " total_size_binary " <<taille*sizeof(med_float)<<std::endl;
1449       //allocate because swap disque binaire
1450       tab->tmflo=new med_float[taille]; //allocate memory
1451       for (int i=0; i<taille ; i++) tab->tmflo[i]=-1e0;
1452       fread(tab->tmflo,sizeof(med_float),taille,fichier);
1453       /*for (int i=0; i<taille ; i++) std::cout<<tab->tmflo[i]<<"/";
1454       std::cout<<std::endl;*/
1455    }
1456    fclose(fichier);
1457    tab->size=-tab->size;
1458    return tab;
1459 }
1460
1461 //************************************
1462 bool ghs3dprl_mesh_wrap::test_msg_wrap()
1463 //tests sur resultats fichiers msg
1464 {
1465    QString key1,key2,typ="FA VE ED EL"; //pour faces vertice edges elements
1466    CVWtab *tab1,*tab2;
1467    bool ok=true;
1468    //test send=receive
1469    //numerotations locales sont identiques
1470    long nb=typ.count(' ',Qt::CaseSensitive) + 1; //nb chiffres detectes
1471    for (long i=0; i < nb; i++)
1472    for (long ifile=1; ifile <= this->nbfiles; ifile++)
1473    for (long ineig=1; ineig <= this->nbfiles; ineig++)
1474    {
1475       if (ifile==ineig) continue; //impossible
1476       key1=key1.sprintf("MS%ld NE%ld ",ifile,ineig)+typ.section(' ',i,i)+" SE";
1477       key2=key2.sprintf("MS%ld NE%ld ",ifile,ineig)+typ.section(' ',i,i)+" RE";
1478       //std::cout<<"key "<<key1<<" et key "<<key2<<std::endl;
1479       tab1=this->restore_key(key1);
1480       //tab1=this->mestab[key1];
1481       tab2=this->restore_key(key2);
1482       //tab2=this->mestab[key2];
1483       //std::cout<<"sortie key "<<key1<<" et key "<<key2<<std::endl;
1484       if (!tab1 && !tab2) continue; //case not neighbours
1485       if (!tab1)
1486       {  std::cout<<"key "<<key1.toLatin1().constData()<<" inexistante avec key "<<key2.toLatin1().constData()<<" existante"<<std::endl;
1487          ok=false;
1488       }
1489       else
1490       {
1491        if (!tab2)
1492        {  std::cout<<"key "<<key2.toLatin1().constData()<<" inexistante avec key "<<key1.toLatin1().constData()<<" existante"<<std::endl;
1493           ok=false;
1494        }
1495        else
1496         if (!tab1->is_equal(tab2))
1497         {  std::cout<<"key "<<key1.toLatin1().constData()<<" et key "<<key2.toLatin1().constData()<<" de contenu differents"<<std::endl;
1498            ok=false;
1499         }
1500       }
1501       /*else
1502          printf("key '%s' et key '%s' identiques \n",
1503                            (const char *)key2,(const char *)key1);*/
1504    }
1505
1506    //test size neighbourg=ifile
1507    //numerotations locales sont differentes mais de tailles identiques
1508    //pas besoin de verifier " RE " car deja fait au dessus
1509    for (long i=0; i < nb; i++)
1510    for (long ifile=1; ifile <= this->nbfiles; ifile++)
1511    for (long ineig=ifile+1; ineig <= this->nbfiles; ineig++)
1512    {
1513       if (ifile==ineig) continue; //cas impossible
1514       key1=key1.sprintf("MS%ld NE%ld ",ifile,ineig)+typ.section(' ',i,i)+" SE";
1515       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
1516       key2=key2.sprintf("MS%ld NE%ld ",ineig,ifile)+typ.section(' ',i,i)+" SE";
1517       tab2=this->restore_key(key2); //tab2=this->mestab[key2];
1518       if (!tab1 && !tab2) continue; //case not neighbours
1519       if (!tab1)
1520       {  std::cout<<"key "<<key1.toLatin1().constData()<<" inexistante avec key "<<key2.toLatin1().constData()<<" existante"<<std::endl;
1521          ok=false;
1522       }
1523       else
1524       {
1525        if (!tab2)
1526        {  std::cout<<"key "<<key2.toLatin1().constData()<<" inexistante avec key "<<key1.toLatin1().constData()<<" existante"<<std::endl;
1527           ok=false;
1528        }
1529        else
1530         if ((tab1->type!=tab2->type)||(tab1->size!=tab2->size))
1531         {  std::cout<<"key "<<key1.toLatin1().constData()<<" et key "<<key2.toLatin1().constData()<<" de type ou tailles differents"<<std::endl;
1532            ok=false;
1533         }
1534       }
1535    }
1536    return ok;
1537 }
1538
1539 //************************************
1540 bool ghs3dprl_mesh_wrap::test_vertices_wrap()
1541 //tests sur vertices
1542 {
1543    QString key1,key2,key11,key22,key11old,key22old;
1544    CVWtab *tab1,*tab2,*tab11,*tab22;
1545    bool ok=true;
1546    key11old="_NO_KEY";key22old="_NO_KEY";
1547    //test size neighbourg=ifile
1548    //numerotations locales sont differentes mais de tailles identiques
1549    //pas besoin de verifier " RE " car deja fait au dessus
1550    //for (int ifile=1; ifile <= this->nbfiles; ifile++)
1551    //for (int ineig=ifile+1; ineig <= this->nbfiles; ineig++)
1552    bool swap=false;
1553    for (int ifile=this->nbfiles; ifile >= 1; ifile--)
1554    for (int ineig=this->nbfiles; ineig >= ifile+1; ineig--)
1555    {
1556       if (ifile==ineig) continue; //cas impossible
1557       key1=key1.sprintf("MS%d NE%d VE SE",ifile,ineig);
1558       key11=key11.sprintf("NB%d VC",ifile);
1559       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
1560       key2=key2.sprintf("MS%d NE%d VE SE",ineig,ifile);
1561       key22=key22.sprintf("NB%d VC",ineig);
1562       tab2=this->restore_key(key2); //tab2=this->mestab[key2];
1563       if (!tab1 && !tab2) continue; //cas non voisins
1564       if (!tab1)
1565       {
1566          std::cerr<<"TestEqualityCoordinates key "<<key1.toLatin1().constData()<<
1567                " NOT existing but key "<<key2.toLatin1().constData()<<" existing"<<std::endl;
1568          ok=false; continue;
1569       }
1570       if (!tab2)
1571       {
1572          std::cerr<<"TestEqualityCoordinates key "<<key2.toLatin1().constData()<<
1573                " NOT existing but key "<<key1.toLatin1().constData()<<" existing"<<std::endl;
1574          ok=false; continue;
1575       }
1576       if (tab1->size!=tab2->size)
1577       {
1578          std::cerr<<"TestEqualityCoordinates key "<<key1.toLatin1().constData()<<
1579                " and key "<<key2.toLatin1().constData()<<" NOT same size"<<std::endl;
1580          ok=false; continue;
1581       }
1582       if (ok)
1583       {
1584          if (swap) {
1585             //Swap out of memory if no use
1586             if ((key11old!=key11)&&(key11old!=key22))
1587                this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key11old,Qt::CaseSensitive,QRegExp::RegExp));
1588             if ((key22old!=key11)&&(key22old!=key22))
1589                this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key22old,Qt::CaseSensitive,QRegExp::RegExp));
1590          }
1591          tab11=this->restore_key(key11); //tab11=this->mestab[key11];
1592          tab22=this->restore_key(key22); //tab22=this->mestab[key22];
1593          if (tab11->size>this->nbelem_limit_swap ||
1594              tab22->size>this->nbelem_limit_swap) swap=true ;
1595          long i1,i2;
1596          bool ok1=true;
1597          //test on equality of xyz_coordinates of commons vertices
1598          for  (long j=0; j < tab1->size-1; j++)
1599          {
1600             i1=tab1->tmint[j];
1601             i2=tab2->tmint[j];
1602             //1 for print vertices not equals
1603             if (!CVW_is_equal_vertices(tab11,i1,tab22,i2,1))
1604             {
1605                std::cerr<<j<<" Vertice "<<i1<<" != Vertice "<<i2<<"\n"<<std::endl;
1606                ok=false; ok1=false;
1607             }
1608          }
1609          if ((verbose>2)&&(ok1))
1610             std::cout<<"TestEqualityCoordinates "<<tab1->size<<
1611                   " Vertices "<<key1.toLatin1().constData()<<" and "<<key2.toLatin1().constData()<<" ok"<<std::endl;
1612          if (!ok1)
1613             std::cerr<<"TestEqualityCoordinates "<<tab1->size<<
1614                   " Vertices "<<key1.toLatin1().constData()<<" and "<<key2.toLatin1().constData()<<" NO_OK"<<std::endl;
1615          key11old=key11; key22old=key22;
1616       }
1617    }
1618    //Swap out of memory (supposed no use?)
1619    //NO because NB1&NB2 VC supposed future use
1620    //YES precaution
1621    if (swap) {
1622       this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key11old,Qt::CaseSensitive,QRegExp::RegExp));
1623       this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key22old,Qt::CaseSensitive,QRegExp::RegExp));
1624    }
1625    return ok;
1626 }
1627
1628 //************************************
1629 bool ghs3dprl_mesh_wrap::Find_VerticesDomainToVerticesSkin()
1630 //initialise correspondances vertice skin et vertices locaux pour chaque domaine
1631 //calcule un med_int new tab[nb_vertices_of_domain]
1632 //avec nieme vertice of skin=tab[ieme vertice de domain]
1633 //apres verification tepal garde bien dans la global numbering "GLi VE"
1634 //les indices initiaux des noeuds (attention: de 1 a nbNodes) 
1635 {
1636    QString key1,key2,tmp;
1637    CVWtab *cooskin,*coodom,*glodom,*montab;
1638    bool ok=true;
1639    med_float *p1,*p2;
1640    med_int i,nb,jd,js;
1641
1642    cooskin=this->restore_key(QString("SKIN_VERTICES_COORDINATES"));
1643    if (!cooskin) return false;
1644    if (verbose>4)std::cout<<"NumberVerticesSKIN="<<cooskin->size/3<<std::endl;
1645    //ici pourrait creer BBtree sur skin
1646    for (int ifile=1; ifile<=this->nbfiles; ifile++)
1647    {
1648       key1=key1.sprintf("NB%ld VC",ifile);
1649       coodom=this->restore_key(key1);
1650       if (!coodom) continue; //Problem
1651       key2=key2.sprintf("GL%ld VE",ifile);
1652       glodom=this->restore_key(key2);
1653       if (verbose>4)
1654          std::cout<<"NumberVerticesDOMAIN_"<<ifile<<"="<<glodom->size<<std::endl;
1655       if (coodom->size!=glodom->size*3)
1656       {
1657          std::cerr<<"Find_VerticesDomainToVerticesSkin key "<<key1.toLatin1().constData()<<
1658                " and key "<<key2.toLatin1().constData()<<" NOT coherent sizes"<<std::endl;
1659          ok=false; continue;
1660       }
1661       //test on equality of xyz_coordinates of commons vertices
1662       med_int *tab=new med_int[glodom->size];
1663       i=0;
1664       nb=0; //nb equals vertices
1665     if (verbose>8){
1666       std::cout<<"\nglobal numbering nodes: no iglo\n";
1667       for  (jd=0; jd < glodom->size; jd++) 
1668            std::cout<<"\t"<<jd<<"\t"<<glodom->tmint[jd]<<std::endl;
1669       std::cout<<"\nresults: no i js iglo\n";
1670       for  (jd=0; jd < coodom->size; jd=jd+3)
1671       {
1672          p2=(coodom->tmflo+jd);
1673          tab[i]=0;
1674          //ici pourrait utiliser BBtree
1675          for  (js=0; js < cooskin->size; js=js+3)
1676          {
1677             p1=(cooskin->tmflo+js);
1678             if (p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2]) 
1679             {
1680                std::cout<<"\t"<<nb<<"\t"<<i<<"\t"<<js/3<<"\t"<<glodom->tmint[i]-1<<
1681                  key2.sprintf("\t%13.5e%13.5e%13.5e",p1[0],p1[1],p1[2]).toLatin1().constData()<<std::endl;
1682                tab[i]=js/3; nb++; continue;
1683             }
1684          }
1685          i++;
1686       }
1687       montab=new CVWtab(glodom->size,tab);
1688       tmp=tmp.sprintf("NB%ld GL_SKIN",ifile);
1689       ok=this->insert_key(tmp,montab);
1690       if (verbose>4){
1691          std::cout<<"NumberOfEqualsVerticesDOMAIN_"<<ifile<<"="<<nb<<std::endl;
1692       }
1693     }
1694    }
1695    return ok;
1696 }
1697
1698 //fin utils procedures
1699
1700 //************************************
1701 bool ghs3dprl_mesh_wrap::Write_masterxmlMEDfile()
1702 {
1703    QString tmp;
1704
1705    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!first call
1706    if (idom==1)
1707    {
1708    //define master file (.xml) in memory
1709    tmp=path+medname+".xml";
1710    filemaster=tmp.toLatin1().constData();
1711    domainname=medname.toLatin1().constData();
1712    char buff[256];
1713
1714    //Creating the XML document
1715    master_doc = xmlNewDoc(BAD_CAST "1.0");
1716    root_node = xmlNewNode(0, BAD_CAST "root");
1717    xmlDocSetRootElement(master_doc,root_node);
1718
1719    //Creating child nodes
1720    //Version tag
1721    med_int majeur,mineur,release;
1722    //Quelle version de MED est utilisee
1723    MEDlibraryNumVersion(&majeur,&mineur,&release);
1724    if (verbose>0) fprintf(stdout,"Files write with MED V%d.%d.%d\n",majeur,mineur,release);
1725    node = xmlNewChild(root_node, 0, BAD_CAST "version",0);
1726    //xmlNewProp(node, BAD_CAST "maj", BAD_CAST int2string2(majeur).c_str());
1727    xmlNewProp(node, BAD_CAST "maj", BAD_CAST i2a(majeur).c_str());
1728    xmlNewProp(node, BAD_CAST "min", BAD_CAST i2a(mineur).c_str());
1729    xmlNewProp(node, BAD_CAST "ver", BAD_CAST i2a(release).c_str());
1730
1731    //Description tag
1732    node = xmlNewChild(root_node,0, BAD_CAST "description",0);
1733    xmlNewProp(node, BAD_CAST "what", BAD_CAST "tetrahedral mesh by MeshGems-Tetra-hpc (formerly tepal)");
1734 #ifdef WIN32
1735   SYSTEMTIME  present;
1736   GetLocalTime ( &present );
1737   sprintf(buff,"%04d/%02d/%02d %02dh%02dm",
1738           present.wYear,present.wMonth,present.wDay,
1739           present.wHour,present.wMinute);
1740 #else
1741    time_t present;
1742    time(&present);
1743    struct tm *time_asc = localtime(&present);
1744    sprintf(buff,"%04d/%02d/%02d %02dh%02dm",
1745            time_asc->tm_year+1900,time_asc->tm_mon+1,time_asc->tm_mday,
1746            time_asc->tm_hour,time_asc->tm_min);
1747 #endif
1748    xmlNewProp(node, BAD_CAST "when", BAD_CAST buff);
1749    xmlNewProp(node, BAD_CAST "from", BAD_CAST "tepal2med");
1750
1751    //Content tag
1752    node =xmlNewChild(root_node,0, BAD_CAST "content",0);
1753    node2 = xmlNewChild(node, 0, BAD_CAST "mesh",0);
1754    xmlNewProp(node2, BAD_CAST "name", BAD_CAST domainname.c_str());
1755    info_node = xmlNewChild(node, 0, BAD_CAST "tepal2med_info",0);
1756
1757    //Splitting tag
1758    node=xmlNewChild(root_node,0,BAD_CAST "splitting",0);
1759    node2=xmlNewChild(node,0,BAD_CAST "subdomain",0);
1760    xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbfilestot).c_str());
1761    node2=xmlNewChild(node,0,BAD_CAST "global_numbering",0);
1762    xmlNewProp(node2, BAD_CAST "present", BAD_CAST "yes");
1763
1764    //Files tag
1765    files_node=xmlNewChild(root_node,0,BAD_CAST "files",0);
1766
1767    //Mapping tag
1768    node = xmlNewChild(root_node,0,BAD_CAST "mapping",0);
1769    mesh_node = xmlNewChild(node, 0, BAD_CAST "mesh",0);
1770    xmlNewProp(mesh_node, BAD_CAST "name", BAD_CAST domainname.c_str());
1771    }
1772
1773    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!all calls
1774    {
1775    char *hostname = getenv("HOSTNAME");
1776    node = xmlNewChild(files_node,0,BAD_CAST "subfile",0);
1777    xmlNewProp(node, BAD_CAST "id", BAD_CAST i2a(idom).c_str());
1778    node2 = xmlNewChild(node, 0, BAD_CAST "name", BAD_CAST distfilename);
1779    if (hostname == NULL)
1780       node2 = xmlNewChild(node, 0, BAD_CAST "machine",BAD_CAST "localhost");
1781    else
1782       node2 = xmlNewChild(node, 0, BAD_CAST "machine",BAD_CAST hostname);
1783
1784    node = xmlNewChild(mesh_node,0,BAD_CAST "chunk",0);
1785    xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST i2a(idom).c_str());
1786    node2 = xmlNewChild(node, 0, BAD_CAST "name", BAD_CAST nomfinal);
1787
1788    //tepal2med_info
1789    node = xmlNewChild(info_node, 0, BAD_CAST "chunk",0);
1790    xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST i2a(idom).c_str());
1791    xmlNewProp(node, BAD_CAST "nodes_number", BAD_CAST i2a(nbnodes).c_str());
1792    xmlNewProp(node, BAD_CAST "faces_number", BAD_CAST i2a(nbtria3).c_str());
1793    xmlNewProp(node, BAD_CAST "tetrahedra_number", BAD_CAST i2a(nbtetra4).c_str());
1794    //node2 = xmlNewChild(node, 0, BAD_CAST "name", BAD_CAST nomfinal);
1795
1796    //node2 = xmlNewChild(node, 0, BAD_CAST "nodes", 0);
1797    //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbnodes).c_str());
1798    //node2 = xmlNewChild(node, 0, BAD_CAST "faces", 0);
1799    //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbtria3).c_str());
1800    //node2 = xmlNewChild(node, 0, BAD_CAST "tetrahedra", 0);
1801    //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbtetra4).c_str());
1802
1803    //tepal2med_info about joints of one subdomain
1804    xmlAddChild(node,joints_node);
1805    //tepal2med_info about groups and families of one subdomain
1806    xmlAddChild(node,families.xml_groups());
1807    }
1808
1809    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!last call
1810    if (idom==nbfilestot)
1811    {
1812    node2 = xmlNewChild(info_node, 0, BAD_CAST "global",0);
1813    xmlNewProp(node2, BAD_CAST "tetrahedra_number", BAD_CAST i2a(nbtetrastotal).c_str());
1814    //save masterfile
1815    xmlSaveFormatFileEnc(filemaster.c_str(), master_doc, "UTF-8", 1);
1816    xmlFreeDoc(master_doc);
1817    xmlCleanupParser();
1818    }
1819    return true;
1820 }
1821
1822
1823 //************************************
1824 bool ghs3dprl_mesh_wrap::Write_MEDfiles_v2(bool deletekeys)
1825 //deletekeys=true to delete non utils keys and arrays "au fur et a mesure"
1826 {
1827    bool ok=true,oktmp;
1828    QString tmp,cmd;
1829    char description[MED_COMMENT_SIZE];
1830    char dtunit[MED_SNAME_SIZE+1]="_NO_UNIT";
1831    char axisname[MED_SNAME_SIZE*3+1]="x               y               z               ";
1832    char axisunit[MED_SNAME_SIZE*3+1]="_NO_UNIT        _NO_UNIT        _NO_UNIT        ";
1833    med_int nb;
1834    
1835    //remove path
1836    //precaution because casename->med_nomfinal no more 32 character
1837    //if path, in this->path.
1838    //20 preserve for add postfixes "_idom" etc...
1839    if (verbose>0)std::cout<<"\nWrite_MEDfiles_v2\n";
1840    if (verbose>6){std::cout<<"\nInitialFamilies\n"; families.write();}
1841
1842    medname=medname.section('/',-1);
1843    if (medname.length()>20) {
1844       std::cerr<<"CaseNameMed truncated (no more 20 characters)"<<std::endl;
1845       medname.truncate(20);
1846    }
1847
1848    //create file resume DOMAIN.joints.med of all joints for quick display (...may be...)
1849    tmp=path+medname+tmp.sprintf("_joints.med",idom);
1850    charendnull(distfilename,tmp,MED_COMMENT_SIZE);
1851    fidjoint=MEDfileOpen(distfilename,MED_ACC_CREAT);
1852    if (fidjoint<0) std::cerr<<"Problem MEDfileOpen "<<distfilename<<std::endl;
1853    if (verbose>0) std::cout<<"CreateMEDFile for all joints <"<<distfilename<<">\n";
1854
1855    //copy file source/GHS3DPRL_skin.med as destination/DOMAIN.skin.med
1856    tmp=path+medname+"_skin.med";
1857    cmd=pathini+casename+"_skin.med";
1858    int ret = access(cmd.toLatin1().constData(),F_OK); //on regarde si le fichier existe
1859    if (ret >= 0) {
1860 #ifdef WIN32
1861       cmd="copy ";
1862 #else 
1863       cmd="cp ";
1864 #endif
1865       cmd = cmd+pathini+casename+"_skin.med "+tmp;
1866       //std::cout<<"Copy skin.med Command = "<<cmd<<std::endl;
1867       system(cmd.toLatin1().constData()); 
1868       if (verbose>0) std::cout<<"CreateMEDFile for initial skin <"<<tmp.toLatin1().constData()<<">\n"; }
1869    else {
1870       if (verbose>0) std::cout<<"No CreateMEDFile <"<<tmp.toLatin1().constData()<<"> for initial skin because <"<<
1871                                                 cmd.toLatin1().constData()<<"> does not exist\n"; }
1872
1873    //define family 0 if not existing, no groups
1874    //La famille FAMILLE_ZERO n'a pas Ã©té trouvée, elle est obligatoire
1875    families.add("0","FAMILLE_ZERO");
1876    //define family Group_of_New_Nodes (which not exists before tetrahedra)
1877    famallnodes=0;
1878    if (QString("All_Nodes").contains(deletegroups)==0){
1879       oktmp=families.get_number_of_new_family(1,&famallnodes,&tmp);
1880       families.add(tmp,"All_Nodes");
1881    }
1882    else if (verbose>3) std::cout<<"--deletegroups matches \"All_Nodes\"\n";
1883    
1884    famalltria3=0;
1885    if (QString("All_Faces").contains(deletegroups)==0){
1886       oktmp=families.get_number_of_new_family(-1,&famalltria3,&tmp);
1887       families.add(tmp,"All_Faces");
1888    }
1889    else if (verbose>3) std::cout<<"--deletegroups matches \"All_Faces\"\n";
1890
1891    famalltetra4=0;
1892    if (QString("All_Tetrahedra").contains(deletegroups)==0){
1893       oktmp=families.get_number_of_new_family(-1,&famalltetra4,&tmp);
1894       families.add(tmp,"All_Tetrahedra");
1895    }
1896    else if (verbose>3) std::cout<<"--deletegroups matches \"All_Tetrahedra\"\n";
1897
1898    famnewnodes=0;
1899    if (QString("New_Nodes").contains(deletegroups)==0){
1900       oktmp=families.get_number_of_new_family(1,&famnewnodes,&tmp);
1901       families.add(tmp,"New_Nodes");
1902    }
1903    else if (verbose>3) std::cout<<"--deletegroups matches \"New_Nodes\"\n";
1904    
1905    famnewtria3=0;
1906    if (QString("New_Faces").contains(deletegroups)==0){
1907       oktmp=families.get_number_of_new_family(-1,&famnewtria3,&tmp);
1908       families.add(tmp,"New_Faces");
1909    }
1910    else if (verbose>3) std::cout<<"--deletegroups matches \"New_Faces\"\n";
1911    
1912    famnewtetra4=0;
1913    if (QString("New_Tetrahedra").contains(deletegroups)==0){
1914       oktmp=families.get_number_of_new_family(-1,&famnewtetra4,&tmp);
1915       families.add(tmp,"New_Tetrahedra");
1916    }
1917    else if (verbose>3) std::cout<<"--deletegroups matches \"New_Tetrahedra\"\n";
1918
1919    if (verbose>6){std::cout<<"\nIntermediatesFamilies\n"; families.write();}
1920    //if (verbose>6) std::cout<<"\nNumber0fFiles="<<nbfilestot<<std::endl;
1921    familles intermediatesfamilies=families;
1922    //initialisations on all domains
1923    nbtetrastotal=0;
1924
1925    //loop on the domains
1926    //for (idom=1; idom<=nbfilestot; idom++) {
1927    if (for_multithread) {
1928      nbfilestot=1;
1929      std::cout<<"\nset Number0fFiles as multithread="<<nbfilestot<<std::endl;
1930    }
1931    if (verbose>6) std::cout<<"\nNumber0fFiles="<<nbfilestot<<std::endl;
1932    for (idom=1; idom<=nbfilestot; idom++) {
1933    
1934       this->nofile=idom;
1935       //restore initial context of families
1936       if (idom>1) families=intermediatesfamilies;
1937       //if (idom>1) continue;
1938       tmp=path+medname+tmp.sprintf("_%d.med",idom);
1939       charendnull(distfilename,tmp,MED_COMMENT_SIZE);
1940
1941       //std::cout<<"<"<<distfilename<<">"<<std::endl;
1942       fid=MEDfileOpen(distfilename,MED_ACC_CREAT);
1943       if (fid<0) {std::cerr<<"Problem MEDfileOpen "<<distfilename<<std::endl; goto erreur;}
1944       if (verbose>0){
1945          if (verbose>2) std::cout<<std::endl;
1946          std::cout<<"CreateMEDFile "<<idom<<" <"<<distfilename<<">\n";
1947       }
1948  
1949       //create mesh
1950       tmp=medname+tmp.sprintf("_%d",idom);
1951       charendnull(nomfinal,tmp,MED_NAME_SIZE);
1952       tmp=tmp.sprintf("domain %d among %d",idom,nbfilestot);
1953       charendnull(description,tmp,MED_COMMENT_SIZE);
1954
1955       if (verbose>4) std::cout<<"Description : "<<description<<std::endl;
1956       err=MEDmeshCr(fid,nomfinal,3,3,MED_UNSTRUCTURED_MESH,description,dtunit,MED_SORT_DTIT,MED_CARTESIAN,axisname,axisunit);
1957       if (err<0) {std::cerr<<"Problem MEDmeshCr"<<nomfinal<<std::endl; goto erreur;}
1958
1959       if (!idom_nodes()) {std::cerr<<"Problem on Nodes"<<std::endl; goto erreur;}
1960       if (verbose>4) std::cout<<"\nEnd of Nodes ***\n"<<std::endl;
1961       if (!idom_edges()) {std::cerr<<"Problem on Edges"<<std::endl; goto erreur;}
1962       if (verbose>4) std::cout<<"\nEnd of Edges ***\n"<<std::endl;
1963       if (!idom_faces()) {std::cerr<<"Problem on Faces"<<std::endl; goto erreur;}
1964       if (verbose>4) std::cout<<"\nEnd of Faces ***\n"<<std::endl;
1965       if (!idom_tetras()) {std::cerr<<"Problem on tetrahedra"<<std::endl; goto erreur;}
1966       if (verbose>4) std::cout<<"\nEnd of Tetrahedra ***\n"<<std::endl;
1967       //non existing files msg mh-tetra_hpc v2.1.11
1968       //if (!idom_joints()) {std::cerr<<"Problem on Joints"<<std::endl; goto erreur;}
1969
1970       if (!for_multithread) {
1971         if (verbose>6){std::cout<<"\nFinalsFamilies\n"; families.write();}
1972         //for nodes families
1973         nb=create_families(fid,1);
1974         if (verbose>5)std::cout<<"NumberOfFamiliesNodes="<<nb<<std::endl;
1975
1976         err=MEDmeshEntityFamilyNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodes,famnodes);
1977         if (verbose>8)
1978           std::cout<<"MEDmeshEntityFamilyNumberWr nodes "<<nbnodes<<":"<<
1979                 famnodes[0]<<"..."<<famnodes[nbnodes-1]<<" "<<std::endl;
1980         delete[] famnodes;
1981         if (err<0) std::cerr<<"Problem MEDmeshEntityFamilyNumberWr nodes"<<std::endl;
1982
1983         //for others families
1984         nb=create_families(fid,-1);
1985         if (verbose>5)std::cout<<"NumberOfFamiliesFacesAndEdgesEtc="<<nb<<std::endl;
1986
1987         err=MEDmeshEntityFamilyNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,nbtria3,famtria3);
1988         if (verbose>8)
1989           std::cout<<"MEDmeshEntityFamilyNumberWr tria3 "<<nbtria3<<":"<<
1990                 famtria3[0]<<"..."<<famtria3[nbtria3-1]<<" "<<std::endl;
1991         delete[] famtria3;
1992         if (err<0) std::cerr<<"Problem MEDmeshEntityFamilyNumberWr tria3"<<std::endl;
1993
1994         err=MEDmeshEntityFamilyNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TETRA4,nbtetra4,famtetra4);
1995         if (verbose>8)
1996           std::cout<<"MEDmeshEntityFamilyNumberWr tetra4 "<<nbtetra4<<":"<<
1997                 famtetra4[0]<<"..."<<famtetra4[nbtria3-1]<<" "<<std::endl;
1998         delete[] famtetra4;
1999         if (err<0) std::cerr<<"Problem MEDmeshEntityFamilyNumberWr tria3"<<std::endl;
2000       }
2001     
2002       MEDfileClose(fid); //no error
2003       //master.xml writings
2004       //oktmp=Write_masterxmlMEDfile();
2005       continue;       //and loop on others domains
2006
2007       erreur:         //error
2008       ok=false;
2009       MEDfileClose(fid); //but loop on others domains
2010
2011    }
2012    
2013    MEDfileClose(fidjoint); //no error
2014    if (verbose>0)std::cout<<"\nTotalNumberOftetrahedra="<<nbtetrastotal<<std::endl;
2015    ok = true;
2016    
2017    return ok;
2018 }
2019
2020 //************************************
2021 bool ghs3dprl_mesh_wrap::idom_nodes()
2022 {
2023    bool ok=true;
2024    QString tmp,key,key1,key2,key3;
2025    CVWtab *tab,*tab1,*tab2,*tab3;
2026    med_int i,j,*arrayi;
2027    int xx;
2028
2029       //writing node(vertices) coordinates
2030       //NBx VC=files.NoBoite Vertex Coordinates
2031       key=key.sprintf("NB%d VC",idom); //files.NoBoite Vertex Coordinates
2032       tab=this->restore_key(key); //tab1=this->mestab[key1];
2033       if (!tab) {
2034          if (!for_tetrahpc) {
2035             tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".noboite";
2036             ok=this->ReadFileNOBOITE(tmp);
2037          }
2038          if (for_tetrahpc) {
2039             tmp=pathini+casename+"_out"+tmp.sprintf(format_tetra.toLatin1().constData(),idom)+".mesh";
2040             ok=this->ReadFileMESH(tmp);
2041          }
2042          tab=this->restore_key(key); //tab1=this->mestab[key1];
2043          if (!tab) return false;
2044       }
2045       tmp=tmp.sprintf("NB%d SN",idom);
2046       //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2047       xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2048       nbnodes=tab->size/3;
2049       err=MEDmeshNodeCoordinateWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,0.,MED_FULL_INTERLACE,nbnodes,tab->tmflo);
2050       if (err<0) {std::cerr<<"Problem MEDmeshNodeCoordinateWr"<<std::endl; return false;}
2051       if (verbose>4) std::cout<<"NumberOfNodes="<<nbnodes<<std::endl;
2052
2053       //writing indices of nodes
2054       arrayi=new med_int[nbnodes];
2055       for (i=0; i<nbnodes ; i++) arrayi[i]=i+1;
2056       err=MEDmeshEntityNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodes,arrayi);
2057       delete[] arrayi;
2058       if (err<0) {std::cerr<<"Problem MEDmeshEntityNumberWr of nodes"<<std::endl; return false;}
2059
2060     if (!for_multithread) {
2061       key1=key1.sprintf("GL%d VE",idom); //global numerotation 
2062       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2063       if (!tab1) {
2064          if (!for_tetrahpc) {
2065             tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".glo";
2066             ok=this->ReadFileGLO(tmp);
2067          }
2068          if (for_tetrahpc) {
2069             tmp=pathini+casename+"_out"+tmp.sprintf(format_tetra.toLatin1().constData(),idom)+".global";
2070             ok=this->ReadFileGLOBAL(tmp);
2071          }
2072          if (!ok) {std::cerr<<"Problem file "<<tmp.toLatin1().constData()<<std::endl; return false;}
2073          tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2074          if (!tab1) return false;
2075       }
2076       if (nbnodes!=tab1->size){std::cerr<<"Problem size GLi VE!=nbnodes!"<<std::endl; return false;}
2077
2078       key2=key2.sprintf("SKIN_VERTICES_FAMILIES",idom); //on global numerotation 
2079       tab2=this->restore_key(key2); //tab1=this->mestab[key1];
2080       med_int nbskin=0; 
2081       if (tab2) med_int nbskin=tab2->size;
2082       //for (i=0; i<nbskin; i++) std::cout<<i<<" "<<tab2->tmint[i]<<std::endl;
2083
2084       //set families of nodes existing in GHS3DPRL_skin.med
2085       med_int nb=nbnodes;
2086       famnodes=new med_int[nb];
2087       for (i=0; i<nb ; i++) famnodes[i]=famallnodes;
2088       med_int * fammore=new med_int[nb];
2089       for (i=0; i<nb ; i++) fammore[i]=famnewnodes;
2090
2091       //set families of nodes of skin
2092       for (i=0; i<nb ; i++){
2093          j=tab1->tmint[i]-1; //
2094          if (j<nbskin){
2095             fammore[i]=tab2->tmint[j];
2096          }
2097       }
2098       ok=set_one_more_family(famnodes,fammore,nb);
2099       delete[] fammore;
2100
2101       //std::cout<<"nodes loc "<<i<<" = gl "<<j<<"\t << "<<tab2->tmint[j]<<
2102       //      tmp.sprintf("\t%23.15e%23.15e%23.15e",tab3->tmflo[i*3],
2103       //      tab3->tmflo[i*3+1],tab3->tmflo[i*3+2])<<std::endl;
2104
2105       //writing nodes(vertices) global numbering
2106       err=MEDmeshGlobalNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodes,tab1->tmint);
2107       if (err<0){std::cerr<<"Problem MEDmeshGlobalNumberWr nodes"<<std::endl; return false;}
2108     }
2109     
2110    return ok;
2111 }
2112
2113 /*
2114 //************************************
2115 bool ghs3dprl_mesh_wrap::set_one_more_family_old(med_int *fami, med_int *more, med_int nb)
2116 //fuse array of med_int families more et fami as kind of groups 
2117 //because there are possibilities of intersections
2118 {
2119    QString tmp;
2120    med_int i,newfam,morfam,oldfam;
2121    for (i=0; i<nb ; i++) {
2122       if (more[i]==0) continue;
2123       if (fami[i]==0) {
2124          fami[i]=more[i];
2125          //std::cout<<"sur "<<i<<" en plus "<<more[i]<<std::endl;
2126       }
2127       else { //intersection
2128          if (fami[i]==more[i]) continue; //same families
2129          oldfam=fami[i];
2130          morfam=more[i];
2131          //create new family intersection if needed
2132          newfam=families.find_family_on_groups(oldfam,morfam);
2133          //std::cout<<"oldfam "<<oldfam<<" morfam "<<morfam<<" -> newfam "<<newfam<<std::endl;
2134          fami[i]=newfam;
2135       }
2136    }
2137    return true;
2138 }*/
2139
2140 //************************************
2141 bool ghs3dprl_mesh_wrap::set_one_more_family(med_int *fami, med_int *more, med_int nb)
2142 //fuse array of med_int families more et fami as kind of groups 
2143 //because there are possibilities of intersections
2144 {
2145    QString tmp;
2146    med_int i,ii,j,newfam,morfam,oldfam,morfami,oldfami,i_zero,nb_fam,nb_max,nb_tot,nb_mess;
2147    med_int *newfami;
2148
2149    nb_fam=families.fam.size(); //on families negative and positive
2150    //std::cout<<"size families "<<nb_fam<<std::endl;
2151    if (nb_fam<=0) nb_fam=5;    //precaution
2152    i_zero=nb_fam*2;            //offset for negative indices of families
2153    nb_max=nb_fam*4;
2154    if (nb_fam>300) std::cout<<
2155       "***set_one_more_family*** warning many initial families could decrease speed "<<nb_fam<<std::endl;
2156    nb_tot=nb_max*nb_max;       //max oversizing *2 on families
2157    //newfami is for speed (avoid calls find_family_on_groups)
2158    //it is an array[nb_fam*4][nb_fam*4] implemented on vector[nb_max]
2159    //to memorize newfam in array[oldfam][morfam]
2160    newfami=new med_int[nb_tot];
2161    for (i=0; i<nb_tot ; i++) newfami[i]=0; //not yet met!
2162
2163    nb_mess=0;
2164    for (i=0; i<nb ; i++) {
2165       if (more[i]==0) continue;
2166       if (fami[i]==0) {
2167          fami[i]=more[i];
2168          //std::cout<<"sur "<<i<<" en plus "<<more[i]<<std::endl;
2169       }
2170       else { //intersection
2171          if (fami[i]==more[i]) continue; //same families
2172          oldfam=fami[i]; oldfami=oldfam+i_zero;
2173          morfam=more[i]; morfami=morfam+i_zero;
2174          //not yet met?
2175          ii=oldfami+morfami*nb_max; //array 2d on vector
2176          if ((ii>=0)&&(ii<nb_tot)) {
2177             newfam=newfami[ii];
2178          }
2179          else {
2180             if (nb_mess<3) {
2181                nb_mess++;
2182                std::cout<<"***set_one_more_family*** warning many new families decrease speed "<<nb_fam<<std::endl;
2183             }
2184             ii=-1;
2185             newfam=0;
2186          }
2187          if (newfam==0) {
2188             //create new family intersection if needed
2189             newfam=families.find_family_on_groups(oldfam,morfam);
2190             //std::cout<<"new oldfam "<<oldfam<<" morfam "<<morfam<<" -> newfam "<<newfam<<std::endl;
2191             if (ii>=0) newfami[ii]=newfam;
2192          }
2193          /*else {
2194             std::cout<<"!!! oldfam "<<oldfam<<" morfam "<<morfam<<" -> newfam "<<newfam<<std::endl;
2195          }*/
2196          fami[i]=newfam;
2197       }
2198    }
2199    delete[] newfami;
2200    return true;
2201 }
2202
2203 //************************************
2204 bool ghs3dprl_mesh_wrap::idom_edges()
2205 {
2206    bool ok=true;
2207    QString tmp;
2208    nbseg2=0;
2209    return ok;
2210 }
2211
2212 //************************************
2213 bool ghs3dprl_mesh_wrap::idom_faces()
2214 {
2215    bool ok=true;
2216    QString tmp,key,key1,key2,key3;
2217    CVWtab *tab,*tab1,*tab2,*tab3;
2218    med_int ii,i,j,*arrayi;
2219    int xx;
2220
2221       //writing connectivity of faces triangles of wrap by nodes
2222       key1=key1.sprintf("FC%d",idom); //files.FaCes faces (wrap and triangles only)
2223       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2224       if (!tab1) {
2225          tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".faces";
2226          ok=this->ReadFileFACES(tmp);
2227          tab1=this->restore_key(key1);
2228          if (!tab1) return false;
2229       }
2230       nbtria3=tab1->size/3;
2231       if (verbose>4) std::cout<<"NumberOfTriangles="<<nbtria3<<std::endl;
2232       //arrayi=new med_int[nbtria3*3];
2233       //ii=0,i=0 ;
2234       //for (j=0; j<nbtria3 ; j++){
2235       //   arrayi[ii]=tab1->tmint[i]; ii++;
2236       //   arrayi[ii]=tab1->tmint[i+1]; ii++;
2237       //   arrayi[ii]=tab1->tmint[i+2]; ii++;
2238       //   i=i+7;
2239       //}
2240       //err=MEDmeshElementConnectivityWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,0.,MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,nbtria3,arrayi);
2241       err=MEDmeshElementConnectivityWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,0.,MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,nbtria3,tab1->tmint);
2242       //delete[] arrayi; //need immediately more little array
2243       if (err<0){std::cerr<<"Problem MEDmeshElementConnectivityWr for triangles connectivity"<<std::endl; return false;}
2244       
2245       //writing indices of faces triangles of wrap
2246       //caution!
2247       //generate "overlapping of numbers of elements" in "import med file" in salome
2248       //if not in "//writing indices of tetrahedra" -> arrayi[i]=!NBFACES!+i+1
2249       arrayi=new med_int[nbtria3]; 
2250       for (i=0; i<nbtria3 ; i++) arrayi[i]=nbseg2+i+1;
2251       err=MEDmeshEntityNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,nbtria3,arrayi);
2252       delete[] arrayi;
2253       if (err<0){std::cerr<<"Problem MEDmeshEntityNumberWr of triangles"<<std::endl; return false;}
2254
2255       //GLx FA=files.GLo FAces
2256       if (!for_multithread) {
2257         key1=key1.sprintf("GL%d FA",idom);
2258         tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2259         if (nbtria3!=tab1->size){std::cerr<<"Problem size GLi FA!=nbtria3!"<<std::endl; return false;}
2260       
2261       
2262         key2=key2.sprintf("SKIN_TRIA3_FAMILIES",idom); //on global numerotation 
2263         tab2=this->restore_key(key2); //tab1=this->mestab[key1];
2264         med_int nbskin=0; 
2265         if (tab2) nbskin=tab2->size;
2266         
2267         //set families of faces existing in GHS3DPRL_skin.med
2268         med_int nb=nbtria3;
2269         famtria3=new med_int[nb];
2270         for (i=0; i<nb ; i++) famtria3[i]=famalltria3;
2271         med_int * fammore=new med_int[nb];
2272         for (i=0; i<nb ; i++) fammore[i]=famnewtria3;
2273
2274         //set families of faces of skin
2275         for (i=0; i<nb ; i++){
2276           j=tab1->tmint[i]-1; //
2277           if (j<nbskin){
2278               fammore[i]=tab2->tmint[j];
2279           }
2280         }
2281         ok=set_one_more_family(famtria3,fammore,nb);
2282         delete[] fammore;
2283         
2284         //writing faces(triangles) global numbering
2285         if (verbose>2)
2286           std::cout<<"CreateMEDglobalNumerotation_Faces "<<key1.toLatin1().constData()<<" "<<tab1->size<<std::endl;
2287         err=MEDmeshGlobalNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,tab1->size,tab1->tmint);
2288         if (err<0){std::cerr<<"Problem MEDmeshGlobalNumberWr faces"<<std::endl; return false;}
2289
2290         //xx=this->remove_key_mesh_wrap(QRegExp("FC*",true,true));
2291         tmp=tmp.sprintf("GL%d FA",idom);
2292         //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2293         xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2294         tmp=tmp.sprintf("GL%d VE",idom);
2295         //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2296         xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2297       }
2298
2299    return ok;
2300 }
2301
2302 //************************************
2303 bool ghs3dprl_mesh_wrap::idom_joints()
2304 {
2305    bool ok=true;
2306    QString tmp,namejoint,key,key1,key2;
2307    CVWtab *tab,*tab1,*tab2;
2308    med_int ineig,ii,jj,i,j,k,*arrayi,nb,famjoint,*fammore,*inodes,*arrayfaces;
2309    med_float *arraynodes;
2310    char namejnt[MED_NAME_SIZE+1];  //no more 32
2311    char namedist[MED_NAME_SIZE+1];
2312    char descjnt[MED_COMMENT_SIZE+1];
2313    med_int numfam_ini_wrap=100;
2314    joints_node=xmlNewNode(NULL, BAD_CAST "joints");  //masterfile.xml
2315    med_int nbjoints=0,nbnodesneig,nbtria3neig;
2316    std::string sjoints=""; //which domains are neighbourg
2317    int xx;
2318    char dtunit[MED_SNAME_SIZE+1]="_NO_UNIT";
2319    char axisname[MED_SNAME_SIZE*3+1]="x               y               z               ";
2320    char axisunit[MED_SNAME_SIZE*3+1]="_NO_UNIT        _NO_UNIT        _NO_UNIT        ";
2321
2322       tmp=tmp.sprintf("MS%d *",idom);
2323       //read file .msg if not done
2324       //qt3 if (this->nb_key_mesh_wrap(QRegExp(tmp,true,true))<=0) {
2325       if (this->nb_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp))<=0) {
2326          this->nofile=idom;
2327          
2328          if (!for_tetrahpc) {
2329             tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".msg";
2330          }
2331          if (for_tetrahpc) {
2332             tmp=pathini+casename+tmp.sprintf(format_tetra.toLatin1().constData(),idom)+".msg";
2333          }
2334
2335          ok=this->ReadFileMSGnew(tmp);
2336          if (!ok) {
2337             std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<std::endl;
2338             return false;
2339          }
2340       }
2341
2342       //writing joints
2343       for (ineig=1; ineig <= nbfilestot; ineig++) {
2344          if (idom==ineig) continue; //impossible
2345
2346          //!*************nodes
2347          //std::cout<<"\n    nodes joints\n";
2348          key1=key1.sprintf("MS%d NE%d VE SE",idom,ineig); //SE or RE identicals
2349          tab1=restore_key(key1);
2350          if (!tab1) continue; //case (ifile,ineig) are not neighbours=>no joints
2351          key1=key1.sprintf("MS%d NE%d VE SE",ineig,idom); //SE or RE identicals
2352          tab2=this->restore_key(key1);
2353          //if not yet loaded (first time) try to load necessary file msg of neighbourg
2354          if (!tab2) {
2355             
2356             if (!for_tetrahpc) {
2357                tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,ineig)+".msg";
2358             }
2359             if (for_tetrahpc) {
2360                tmp=pathini+casename+tmp.sprintf(format_tetra.toLatin1().constData(),ineig)+".msg";
2361             }
2362             
2363             this->nofile=ineig; //neighbourg file
2364             ok=this->ReadFileMSGnew(tmp);
2365             this->nofile=idom;  //restaure initial domain
2366             if (!ok) {
2367                std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<std::endl;
2368                continue;
2369             }
2370             tab2=this->restore_key(key1);
2371          }
2372          if (!tab2) std::cerr<<"Problem existing nodes joint in domain "<<idom<<
2373                           " with none in neighbourg "<<ineig<<" files .msg"<<std::endl;
2374          nb=tab1->size; nbnodesneig=tab2->size;
2375          if (nb!=nbnodesneig) {
2376             std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<
2377                   " number of nodes of joint "<<idom<<"<->"<<ineig<<" not equals"<<std::endl;
2378             continue;
2379          }
2380
2381          nbjoints++; //one more joint for this domain
2382          sjoints=sjoints+" "+i2a(ineig);
2383          if (verbose>4)
2384             std::cout<<"NumberOfNodesOfJoint_"<<idom<<"_"<<ineig<<"="<<nb<<std::endl;
2385          namejoint=namejoint.sprintf("JOINT_%d_%d_Nodes",idom,ineig);
2386          strcpy(namejnt,namejoint.toLatin1().constData());
2387          tmp=tmp.sprintf("JOINT_%d_%d among %d domains of ",idom,ineig,nbfilestot)+nomfinal;
2388          strcpy(descjnt,tmp.toLatin1().constData());
2389          tmp=medname+tmp.sprintf("_%d",ineig);
2390          strcpy(namedist,tmp.toLatin1().constData());
2391          err=MEDsubdomainJointCr(fid,nomfinal,namejnt,descjnt,ineig,namedist);
2392          if (err<0) std::cerr<<"Problem MEDsubdomainJointCr"<<std::endl;
2393
2394          famjoint=0;
2395          if (namejoint.contains(deletegroups)==0){
2396             ok=families.get_number_of_new_family(1,&famjoint,&tmp);
2397             families.add(tmp,namejoint);
2398          }
2399
2400          key=key.sprintf("NB%d VC",idom); //files.NoBoite Vertex Coordinates
2401          tab=this->restore_key(key); //tab1=this->mestab[key1];
2402          //nbnodes=tab->size/3;
2403
2404          //writing correspondence nodes-nodes
2405          //two indices for one correspondence
2406          arrayi=new med_int[nb*2];
2407          arraynodes=new med_float[nbnodesneig*3];  //for file DOMAIN_join.med
2408          inodes=new med_int[nbnodes];              //for file DOMAIN_join.med
2409          med_int * fammore=new med_int[nbnodes];
2410          for (i=0; i<nbnodes ; i++) {fammore[i]=0; inodes[i]=-2;}  //precautions
2411          ii=0; jj=0; k=1;
2412          for (i=0; i<nb ; i++){
2413             //no need because <send> equals <receive> tab1->tmint[i]==tab2->tmint[i]
2414             j=tab1->tmint[i]-1; //contents of tab1 1->nb, j 0->nb-1
2415             inodes[j]=k; k++;   //contents of inodes 1->n ,nodes of joint from nodes of domain
2416             arraynodes[jj]=tab->tmflo[j*3]; jj++;
2417             arraynodes[jj]=tab->tmflo[j*3+1]; jj++;
2418             arraynodes[jj]=tab->tmflo[j*3+2]; jj++;
2419
2420             fammore[j]=famjoint;
2421             arrayi[ii]=tab1->tmint[i]; ii++;
2422             arrayi[ii]=tab2->tmint[i]; ii++;
2423          }
2424          if (namejoint.contains(deletegroups)==0){
2425             ok=set_one_more_family(famnodes,fammore,nbnodes);
2426          }
2427          delete[] fammore;
2428
2429          err=MEDsubdomainCorrespondenceWr(fid,nomfinal,namejnt,MED_NO_DT,MED_NO_IT,
2430                  MED_NODE,MED_UNDEF_GEOMETRY_TYPE,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nb,arrayi);
2431          if (err<0) std::cerr<<"Problem MEDsubdomainCorrespondenceWr nodes"<<std::endl;
2432          delete[] arrayi;
2433
2434          //!*************TRIA3
2435          //writing correspondence triangles-triangles
2436          //std::cout<<"\n    faces joints\n";
2437          nbtria3neig=0;
2438          key1=key1.sprintf("MS%d NE%d FA SE",idom,ineig); //SE or RE identicals
2439          tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2440          if (!tab1){
2441             if (verbose>4)
2442                std::cout<<"NumberOfTrianglesOfJoint_"<<idom<<"_"<<ineig<<"=0"<<std::endl;
2443             //continue; //case (ifile,ineig) are not neighbours=>no joints
2444          }
2445          else //have to set xml may be no faces but nodes in a joint!
2446          {
2447          key1=key1.sprintf("MS%d NE%d FA SE",ineig,idom); //SE or RE identicals
2448          tab2=this->restore_key(key1);
2449          if (!tab2) std::cerr<<"Problem existing triangles of joint in domain "<<idom<<
2450                                " with none in neighbourg "<<ineig<<" files .msg"<<std::endl;
2451          nb=tab1->size; nbtria3neig=tab2->size;
2452          if (nb!=nbtria3neig) {
2453             std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<
2454                   " number of triangles of joint "<<idom<<"<->"<<ineig<<" not equals"<<std::endl;
2455             continue;
2456          }
2457          namejoint=namejoint.sprintf("JOINT_%d_%d_Faces",idom,ineig);
2458          
2459          famjoint=0;
2460          if (namejoint.contains(deletegroups)==0){
2461             ok=families.get_number_of_new_family(-1,&famjoint,&tmp);
2462             families.add(tmp,namejoint);
2463          }
2464
2465          key=key.sprintf("FC%d",idom); //files.FaCes faces (wrap and triangles only)
2466          tab=this->restore_key(key); //tab1=this->mestab[key1];
2467
2468          med_int nb=tab1->size; nbtria3neig=nb;
2469          //if (verbose>=0) std::cout<<"NumberOfTrianglesOfJoint_"<<idom<<"_"<<ineig<<"="<<nb<<std::endl;
2470          arrayi=new med_int[nb*2]; //correspondance indices triangles in 2 domains
2471          arrayfaces=new med_int[nbtria3neig*3];  //for file DOMAIN_join.med
2472          for (i=0; i<nbtria3neig*3 ; i++) arrayfaces[i]=-1; //precaution
2473          fammore=new med_int[nbtria3];
2474          for (i=0; i<nbtria3 ; i++) fammore[i]=0;
2475          ii=0; jj=0;
2476          for (i=0; i<nb ; i++){
2477             arrayi[ii]=tab1->tmint[i]; ii++;
2478             arrayi[ii]=tab2->tmint[i]; ii++; //correspondance indices triangles in 2 domains
2479        
2480             fammore[tab1->tmint[i]-1]=famjoint;
2481             //famtria3[tab1->tmint[i]-1]=famjoint;
2482             
2483             k=tab1->tmint[i]-1; //indice of node connectivity
2484             //std::cout<<"k="<<k<<std::endl;
2485             k=k*7; //indice of node connectivity in tab of triangles
2486             
2487             arrayfaces[jj]=inodes[tab->tmint[k]-1]; jj++;
2488             arrayfaces[jj]=inodes[tab->tmint[k+1]-1]; jj++;
2489             arrayfaces[jj]=inodes[tab->tmint[k+2]-1]; jj++;
2490          }
2491          int happens=0;
2492          for (i=0; i<nbtria3neig*3 ; i++) {
2493            if (arrayfaces[i]<=0) {
2494              std::cerr<<"Problem file X_joints.med unknown node in joint "<<idom<<"_"<<ineig<<" face "<<i/3+1<<std::endl; //precaution
2495              happens=1;
2496            }
2497          }
2498          /*TODO DEBUG may be bug distene?
2499          if (happens==1) {
2500             std::cout<<"\nNumberOfTrianglesOfJoint_"<<idom<<"_"<<ineig<<"="<<nb<<std::endl;
2501             for (i=0; i<nbnodes ; i++) std::cout<<"inode i "<<i+1<<" "<<inodes[i]<<std::endl;
2502             for (i=0; i<tab1->size ; i++) std::cout<<"triangle i "<<i+1<<" "<<tab1->tmint[i]<<std::endl;
2503             for (i=0; i<tab->size ; i=i+7) std::cout<<"conn i "<<i/7+1<<" : "<<tab->tmint[i]<<" "<<tab->tmint[i+1]<<" "<<tab->tmint[i+2]<<std::endl;
2504          }
2505          */
2506          if (namejoint.contains(deletegroups)==0){
2507             ok=set_one_more_family(famtria3,fammore,nbtria3);
2508          }
2509          delete[] fammore;
2510
2511          err=MEDsubdomainCorrespondenceWr(fid,nomfinal,namejnt,MED_NO_DT,MED_NO_IT,
2512                  MED_CELL,MED_TRIA3,MED_CELL,MED_TRIA3,nb,arrayi);
2513          if (err<0) std::cerr<<"Problem MEDsubdomainCorrespondenceWr triangles"<<std::endl;
2514          delete[] arrayi;
2515          }
2516
2517          //!write in file resume DOMAIN.joints.med of all joints for quick display (...may be...)
2518          if (idom<=ineig) { //no duplicate joint_1_2 and joint_2_1
2519           //create mesh
2520           namejoint=namejoint.sprintf("JOINT_%d_%d",idom,ineig);
2521           charendnull(namejnt,namejoint,MED_NAME_SIZE);
2522           tmp=tmp.sprintf("joint between %d and %d",idom,ineig);
2523           charendnull(descjnt,tmp,MED_COMMENT_SIZE);
2524           err=MEDmeshCr(fidjoint,namejnt,3,3,MED_UNSTRUCTURED_MESH,descjnt,dtunit,MED_SORT_DTIT,MED_CARTESIAN,axisname,axisunit);
2525           if (err<0) std::cerr<<"Problem MEDmeshCr "<<namejnt<<std::endl;
2526           //write nodes
2527           err=MEDmeshNodeCoordinateWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,0.,MED_FULL_INTERLACE,nbnodesneig,arraynodes);
2528           if (err<0) std::cerr<<"Problem MEDmeshNodeCoordinateWr "<<namejnt<<std::endl;
2529           arrayi=new med_int[nbnodesneig];
2530           for (i=0; i<nbnodesneig ; i++) arrayi[i]=i+1;
2531           err=MEDmeshEntityNumberWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodesneig,arrayi);
2532           delete[] arrayi;
2533           if (err<0) std::cerr<<"Problem MEDmeshEntityNumberWr of nodes "<<namejnt<<std::endl;
2534           //families zero in file fidjoint ???
2535           //La famille FAMILLE_ZERO n'a pas Ã©té trouvée, elle est obligatoire
2536           nb=create_family_zero(fidjoint,namejnt);
2537           
2538           //write tria3
2539           if (nbtria3neig>0) {
2540            //for (i=0; i<nbtria3neig ; i++) std::cout<<i+1<<" "<<
2541            //    arrayfaces[i*3]<<" "<<arrayfaces[i*3+1]<<" "<<arrayfaces[i*3+2]<<std::endl;
2542            err=MEDmeshElementConnectivityWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,0.,
2543                    MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,nbtria3neig,arrayfaces);
2544            if (err<0) std::cerr<<"Problem MEDmeshElementConnectivityWr for triangles connectivity "<<namejnt<<std::endl;
2545            //writing indices of faces triangles of joint
2546            arrayi=new med_int[nbtria3neig]; 
2547            for (i=0; i<nbtria3neig ; i++) arrayi[i]=i+1;
2548            err=MEDmeshEntityNumberWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,nbtria3neig,arrayi);
2549            delete[] arrayi;
2550            if (err<0) std::cerr<<"Problem MEDmeshEntityNumberWr of triangles "<<namejnt<<std::endl;
2551           }
2552          }
2553
2554          delete[] arraynodes;
2555          if (nbtria3neig>0) delete[] arrayfaces;
2556          delete[] inodes;
2557
2558          //!masterfile.xml
2559          node=xmlNewChild(joints_node, 0, BAD_CAST "joint", 0);
2560          xmlNewProp(node, BAD_CAST "id", BAD_CAST i2a(ineig).c_str());
2561          xmlNewProp(node, BAD_CAST "nodes_number", BAD_CAST i2a(nbnodesneig).c_str());
2562          xmlNewProp(node, BAD_CAST "faces_number", BAD_CAST i2a(nbtria3neig).c_str());
2563          //node2 = xmlNewChild(node, 0, BAD_CAST "nodes", 0);
2564          //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbnodesneig).c_str());
2565          //node2 = xmlNewChild(node, 0, BAD_CAST "faces", 0);
2566          //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbtria3neig).c_str());
2567       }
2568
2569    //masterfile.xml
2570    xmlNewProp(joints_node, BAD_CAST "number", BAD_CAST i2a(nbjoints).c_str());
2571    xmlNewChild(joints_node, 0, BAD_CAST "id_neighbours", BAD_CAST sjoints.substr(1).c_str());
2572    
2573    tmp=tmp.sprintf("NB%d VC",idom);
2574    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2575    xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2576    //tmp=tmp.sprintf("MS%d NE*",idom);
2577    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2578    //xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2579    tmp=tmp.sprintf("FC%d",idom);
2580    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2581    xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2582    tmp=tmp.sprintf("GL%d *",idom);
2583    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2584    xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2585    return ok;
2586 }
2587
2588 //************************************
2589 bool ghs3dprl_mesh_wrap::idom_tetras()
2590 {
2591    bool ok=true;
2592    QString tmp,key1;
2593    CVWtab *tab1;
2594    med_int i,*arrayi;
2595    int xx;
2596
2597       //writing connectivity of tetrahedra by nodes
2598       key1=key1.sprintf("NB%d EV",idom); //files.NoBoite Elements Vertices (tetra only)
2599       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2600       nbtetra4=tab1->size/4;
2601       nbtetrastotal=nbtetrastotal + nbtetra4;
2602       if (verbose>5)std::cout<<"NumberOftetrahedra="<<nbtetra4<<std::endl;
2603       err=MEDmeshElementConnectivityWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,0.,MED_CELL,MED_TETRA4,MED_NODAL,MED_FULL_INTERLACE,nbtetra4,tab1->tmint);
2604       if (err<0){std::cerr<<"Problem MEDmeshElementConnectivityWr for tetra connectivity"<<std::endl; return false;}
2605
2606       //writing indices of tetrahedra
2607       arrayi=new med_int[nbtetra4];
2608       for (i=0; i<nbtetra4 ; i++) arrayi[i]=nbseg2+nbtria3+i+1;
2609       //for (i=0; i<nbtria3 ; i++) std::cout<<i<<" "<<arrayi[i]<<std::endl;
2610       err=MEDmeshEntityNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TETRA4,nbtetra4,arrayi);
2611       delete[] arrayi;
2612       if (err<0){std::cerr<<"Problem MEDmeshEntityNumberWr of tetrahedra"<<std::endl; return false;}
2613
2614       famtetra4=new med_int[nbtetra4];
2615       for (i=0; i<nbtetra4 ; i++) famtetra4[i]=famnewtetra4;
2616
2617       if (!for_multithread) {
2618         //writing tetrahedra global numbering
2619         //GLx EL=files.GLo ELements
2620         key1=key1.sprintf("GL%d EL",idom);
2621         tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2622         if (!tab1) {
2623           //tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".glo";
2624           //ok=this->ReadFileGLO(tmp);
2625           //tab1=this->restore_key(key1);
2626           //if (!tab1) return false;
2627
2628           if (!for_tetrahpc) {
2629               tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".glo";
2630               ok=this->ReadFileGLO(tmp);
2631           }
2632           if (for_tetrahpc) {
2633               tmp=pathini+casename+"_out"+tmp.sprintf(format_tetra.toLatin1().constData(),idom)+".global";
2634               ok=this->ReadFileGLOBAL(tmp);
2635           }
2636           tab1=this->restore_key(key1);
2637           if (!tab1) return false;
2638
2639         }
2640
2641         if (tab1->size!=nbtetra4){
2642           std::cerr<<"Problem incorrect size of tetrahedra global numbering"<<std::endl; return false;}
2643         if (verbose>2)
2644           std::cout<<"CreateMEDglobalNumerotation_tetrahedra "<<key1.toLatin1().constData()<<" "<<tab1->size<<std::endl;
2645         err=MEDmeshGlobalNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TETRA4,tab1->size,tab1->tmint);
2646         if (err<0){std::cerr<<"Problem MEDmeshGlobalNumberWr tetrahedra"<<std::endl; return false;}
2647       }
2648
2649       tmp=tmp.sprintf("NB%d EV",idom);
2650       //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2651       xx=this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2652    return ok;
2653 }
2654
2655 //************************************
2656 med_int ghs3dprl_mesh_wrap::create_families(med_idt fid, int sign)
2657 //if sign < 0 families faces or tria3 etc...
2658 //if sign >= 0 family zero and family nodes
2659 {
2660    med_int pas,ires;
2661    char nomfam[MED_NAME_SIZE+1];  //it.current()->name;
2662    char attdes[MED_COMMENT_SIZE+1]="_NO_DESCRIPTION";
2663    char *gro;
2664    med_int i,attide=1,attval=1,natt=1,num,ngro;
2665    
2666    if (sign>=0) pas=1; else pas=-1;
2667    ires=0;
2668    fend gb;
2669    fagr::iterator it1;
2670    fend::iterator it2;
2671    for (it1=families.fam.begin(); it1!=families.fam.end(); ++it1){
2672       num=(*it1).first.toLong();
2673       if ((pas==-1) && (num>=0)) continue; //not good families
2674       if ((pas== 1) && (num< 0)) continue; //not good families
2675       charendnull(nomfam,(*it1).first,MED_NAME_SIZE);
2676       ires++;
2677       //med_int natt=0;
2678       ngro=(*it1).second.size();
2679       if (verbose>5) 
2680          std::cout<<"CreateFamilyInMEDFile <"<<nomfam<<">\tNbGroups="<<ngro;
2681       gro=new char[MED_LNAME_SIZE*ngro+2];
2682       gb=(*it1).second;
2683       i=0;
2684       for (it2=gb.begin(); it2!=gb.end(); ++it2){
2685          charendnull(&gro[i*MED_LNAME_SIZE],(*it2).first,MED_LNAME_SIZE);
2686          if (verbose>5)std::cout<<" <"<<&gro[i*MED_LNAME_SIZE]<<"> ";
2687          i++;
2688       }
2689       if (verbose>5)std::cout<<std::endl;
2690       err=MEDfamilyCr(fid,nomfinal,nomfam,num,ngro,gro);
2691       delete[] gro;
2692       if (err<0) std::cerr<<"Problem MEDfamilyCr of "<<nomfam<<std::endl;
2693    }
2694    return ires;
2695 }
2696
2697 med_int ghs3dprl_mesh_wrap::create_family_zero(med_idt fid, QString nameMesh)
2698 {
2699    med_int pas,ires;
2700    ires=0;
2701    char nomfam[MED_NAME_SIZE+1]="FAMILLE_ZERO";  //it.current()->name;
2702    char attdes[MED_COMMENT_SIZE+1]="_NO_DESCRIPTION";
2703    
2704    char *gro;
2705    med_int i,attide=1,attval=1,natt=1,num=0,ngro=0;
2706    
2707    gro=new char[MED_LNAME_SIZE*ngro+2];
2708    if (verbose>3)std::cout<<"\ncreate_family_ZERO "<<nameMesh.toLatin1().constData()<<std::endl;
2709    err=MEDfamilyCr(fid,nameMesh.toLatin1().constData(),nomfam,num,ngro,gro);
2710    if (err<0) std::cerr<<"Problem MEDfamilyCr FAMILLE_ZERO of "<<nameMesh.toLatin1().constData()<<std::endl;
2711    delete[] gro;
2712    return ires;
2713 }
2714
2715
2716