Salome HOME
Updated copyright comment
[plugins/ghs3dprlplugin.git] / src / tepal2med / ghs3dprl_mesh_wrap.cxx
1 // Copyright (C) 2007-2024  CEA, EDF
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",(int)fam1);
257       it1=fam.find(nom1);
258       nom2=nom2.sprintf("%d",(int)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 maxline;
563
564    if (!Ff.is_open())
565    {
566       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
567       return false;
568    }
569
570    //Lit les donnees au debut du fichier, 1 lignes maxi:
571    maxline=1;
572    if (!CVW_FindStringInFirstLines("MeshVersionFormatted",Ff,maxline)) return false;
573    if (verbose>2) std::cout<<"MeshVersionFormatted_"<<this->nofile<<" ok"<<std::endl;
574
575    //Ferme le fichier :
576    Ff.close();
577    this->nbfiles++;
578    return true;
579 }
580
581 ///************************************
582 bool ghs3dprl_mesh_wrap::ReadFileGLO(const QString FileName)
583 //read file .glo with no parser xml because big file (volume)
584 {
585    QString tmp;
586    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
587    std::string line;
588    long count;
589    //bool ok;
590
591    if (!Ff.is_open())
592    {
593       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
594       return false;
595    }
596
597    //Lit les donnees :
598    if (!CVW_FindString("<vertices count=",Ff,count)) return false;
599    if (verbose>3) std::cout<<"GloVerticesCount="<<count<<std::endl;
600    if (count>0)
601    {
602       med_int *tmint=new med_int[count];
603       for (int i=0; i<count; i++) Ff>>tmint[i];
604       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
605
606       CVWtab *montab=new CVWtab(count,tmint);
607       tmp=tmp.sprintf("GL%ld VE",this->nofile);
608       /*ok=*/this->insert_key(tmp,montab);
609    }
610
611    if (!CVW_FindString("<edges count=",Ff,count)) return false;
612    if (verbose>3) std::cout<<"GloEdgesCount="<<count<<std::endl;
613    if (count>0)
614    {
615       med_int *tmint=new med_int[count];
616       for (int i=0; i<count; i++) Ff>>tmint[i];
617       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
618
619       CVWtab *montab=new CVWtab(count,tmint);
620       tmp=tmp.sprintf("GL%ld ED",this->nofile);
621       /*ok=*/this->insert_key(tmp,montab);
622    }
623
624    if (!CVW_FindString("<faces count=",Ff,count)) return false;
625    if (verbose>3) std::cout<<"GloFacesCount="<<count<<std::endl;
626    if (count>0)
627    {
628       med_int *tmint=new med_int[count];
629       for (int i=0; i<count; i++) Ff>>tmint[i];
630       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
631
632       CVWtab *montab=new CVWtab(count,tmint);
633       tmp=tmp.sprintf("GL%ld FA",this->nofile);
634       /*ok=*/this->insert_key(tmp,montab);
635    }
636
637    if (!CVW_FindString("<elements count=",Ff,count)) return false;
638    if (verbose>3) std::cout<<"GloElementsCount="<<count<<std::endl;
639    if (count>0)
640    {
641       med_int *tmint=new med_int[count];
642       for (int i=0; i<count; i++) Ff>>tmint[i];
643       if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
644
645       CVWtab *montab=new CVWtab(count,tmint);
646       tmp=tmp.sprintf("GL%ld EL",this->nofile);
647       /*ok=*/this->insert_key(tmp,montab);
648    }
649    //Ferme le fichier :
650    Ff.close();
651    this->nbfiles++;
652    return true;
653 }
654
655 ///************************************
656 bool ghs3dprl_mesh_wrap::ReadFileGLOBAL(const QString FileName)
657 //read file .global ascii (no xml)
658 //first line: Vertices Edges Triangles Tetrahedra
659 {
660    std::string line("                                            ");
661    QString tmp;
662    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
663    long vert=0,edge=0,tria=0,tetr=0,count=0;
664    med_int *tmint;
665    CVWtab *montab;
666    //bool ok;
667    
668    if (verbose>=6) std::cout<<"Read file '"<<FileName.toLatin1().constData()<<std::endl;
669    if (!Ff.is_open())
670    {
671       std::cerr<<"Problem file '"<<FileName.toLatin1().constData()<<"' not open"<<std::endl;
672       // std::cout<<"Default global numerotation nb verts "<<vert<<" nb edges "<<edge<<" nb trias "<<tria<<" nb tetras "<<tetr<<std::endl;
673       return false;
674    }
675    else
676    {
677      //Lit les donnees :
678      Ff>>vert>>edge>>tria>>tetr;
679      std::cout<<"Global numerotation nb verts "<<vert<<" nb edges "<<edge<<" nb trias "<<tria<<" nb tetras "<<tetr<<std::endl;
680    }
681    
682    if (vert<0)
683    {
684       std::cerr<<"Problem Vertices: a positive integer is expected"<<std::endl;
685       return false;
686    }
687
688    if (edge<0)
689    {
690       std::cerr<<"Problem Edges: a positive integer is expected"<<std::endl;
691       return false;
692    }
693
694    if (tria<0)
695    {
696       std::cerr<<"Problem Triangles: a positive integer is expected"<<std::endl;
697       return false;
698    }
699
700    if (tetr<0)
701    {
702       std::cerr<<"Problem Tetrahedra: a positive integer is expected"<<std::endl;
703       return false;
704    }
705
706    count=vert;
707    tmint=new med_int[count];
708    for (long i=0; i<count; i++) Ff>>tmint[i];
709    if (verbose>4) std::cout<<"Vertices ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
710
711    montab=new CVWtab(count,tmint);
712    tmp=tmp.sprintf("GL%ld VE",this->nofile);
713    /*ok=*/this->insert_key(tmp,montab);
714
715    count=edge;
716    tmint=new med_int[count];
717    for (long i=0; i<count; i++) Ff>>tmint[i];
718    if (verbose>4) std::cout<<"Edges ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
719
720    montab=new CVWtab(count,tmint);
721    tmp=tmp.sprintf("GL%ld ED",this->nofile);
722    /*ok=*/this->insert_key(tmp,montab);
723
724    count=tria;
725    tmint=new med_int[count];
726    for (long i=0; i<count; i++) Ff>>tmint[i];
727    if (verbose>4) std::cout<<"Triangles ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
728
729    montab=new CVWtab(count,tmint);
730    tmp=tmp.sprintf("GL%ld FA",this->nofile);
731    /*ok=*/this->insert_key(tmp,montab);
732
733    count=tetr;
734    tmint=new med_int[count];
735    for (long i=0; i<count; i++) Ff>>tmint[i];
736    if (verbose>4) std::cout<<"Tetrahedra ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
737
738    montab=new CVWtab(count,tmint);
739    tmp=tmp.sprintf("GL%ld EL",this->nofile);
740    /*ok=*/this->insert_key(tmp,montab);
741
742    //Ferme le fichier :
743    Ff.close();
744    this->nbfiles++;
745    return true;
746 }
747
748 ///************************************
749 bool ghs3dprl_mesh_wrap::ReadFileDefaultGLOBAL(long vert, long edge, long tria, long tetr)
750 //default like read file .global ascii (no xml) when inexisting when multithread
751 {
752    QString tmp;
753    long count=0;
754    med_int *tmint;
755    CVWtab *montab;
756    //bool ok;
757    
758    //Simule les donnees :
759    std::cout<<"Default Global numerotation nb verts "<<vert<<" nb edges "<<edge<<" nb trias "<<tria<<" nb tetras "<<tetr<<std::endl;
760    
761    count=vert;
762    tmint=new med_int[count];
763    for (long i=0; i<count; i++) tmint[i] = i+1;
764    if (verbose>4) std::cout<<"Default Vertices ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
765
766    montab=new CVWtab(count,tmint);
767    tmp=tmp.sprintf("GL%ld VE",this->nofile);
768    /*ok=*/this->insert_key(tmp,montab);
769
770    count=edge;
771    tmint=new med_int[count];
772    for (long i=0; i<count; i++) tmint[i] = i+1;
773    if (verbose>4) std::cout<<"Default Edges ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
774
775    montab=new CVWtab(count,tmint);
776    tmp=tmp.sprintf("GL%ld ED",this->nofile);
777    /*ok=*/this->insert_key(tmp,montab);
778
779    count=tria;
780    tmint=new med_int[count];
781    for (long i=0; i<count; i++) tmint[i] = i+1;
782    if (verbose>4) std::cout<<"Default Triangles ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
783
784    montab=new CVWtab(count,tmint);
785    tmp=tmp.sprintf("GL%ld FA",this->nofile);
786    /*ok=*/this->insert_key(tmp,montab);
787
788    count=tetr;
789    tmint=new med_int[count];
790    for (long i=0; i<count; i++) tmint[i] = i+1;
791    if (verbose>4) std::cout<<"Default Tetrahedra ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count-1]<<std::endl;
792
793    montab=new CVWtab(count,tmint);
794    tmp=tmp.sprintf("GL%ld EL",this->nofile);
795    /*ok=*/this->insert_key(tmp,montab);
796
797    return true;
798 }
799
800 //************************************
801 bool ghs3dprl_mesh_wrap::ReadFileFACES(const QString FileName)
802 //read file .faces (wrap)
803 {
804    QString tmp;
805    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
806    std::string line;
807    long nbelem,ntype;
808    bool ok;
809
810    if (!Ff.is_open())
811    {
812       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
813       return false;
814    }
815
816    //Lit les donnees :
817    //Replace le pointeur de fichier au debut :f.seekg(0);
818    if (getline(Ff,line))
819    {
820       tmp=line.c_str();
821       nbelem=tmp.section(' ',0,0).toLong(&ok);
822    }
823    else
824    {
825       std::cerr<<"Problem on first line of file"<<std::endl;
826       return false;
827    }
828    if (verbose>3) std::cout<<"FacesNumberOfElements="<<nbelem<<std::endl;
829    med_int *tmint=new med_int[nbelem*7];
830    for (int i=0; i<nbelem*7; i=i+7)
831    {
832       Ff>>ntype;
833       if (ntype!=3) //only triangles
834       {
835          std::cerr<<"Problem on ntype != 3"<<std::endl;
836          return false;
837       }
838       for (int j=0; j<7; j++) Ff>>tmint[i+j];
839       //for (int j=0; j<7; j++) std::cout<<tmint[i+j]<<' '; std::cout<<std::endl;
840    }
841    if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[nbelem*7-1]<<std::endl;
842
843    CVWtab *montab=new CVWtab(nbelem*7,tmint);
844    tmp=tmp.sprintf("FC%ld",this->nofile);
845    ok=this->insert_key(tmp,montab);
846
847    Ff.close();
848    this->nbfiles++;
849    return true;
850 }
851
852 //************************************
853 bool ghs3dprl_mesh_wrap::ReadFileMESH(const QString FileName)
854 //read file .mesh from tetra_hpc (with volume)
855 {
856    std::string line("                                            ");
857    QString tmp;
858    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
859    long Mversion=0,Mdim=0,Mvert=0,Mtria=0,Medge=0,Mtetra=0,count=0;
860    med_int garbage;
861    med_int *tmint;
862    bool ok;
863    
864    if (verbose>=6)std::cout<<"Read file '"<<FileName.toLatin1().constData()<<std::endl;
865    if (!Ff.is_open()){
866       std::cerr<<"Problem file '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
867       return false;
868    }
869
870    //lit les données :
871    if (getline(Ff,line) && (line.find("MeshVersionFormatted")==0))
872    {
873       tmp=line.c_str();
874       Mversion=tmp.section(' ',1,1).toLong(&ok);
875    }
876    else
877    {
878       std::cerr<<"Problem on line 1 of file: 'MeshVersionFormatted' expected"<<std::endl;
879       return false;
880    }
881    
882    getline(Ff,line);
883
884    if (getline(Ff,line) && (line.find("Dimension 3")==0))
885    {
886       tmp=line.c_str();
887       Mdim=tmp.section(' ',1,1).toLong(&ok);
888    }
889    else
890    {
891       std::cerr<<"Problem on line 3 of file: Dimension 3 expected"<<std::endl;
892       return false;
893    }
894    
895    getline(Ff,line);
896
897    if (!(getline(Ff,line) && (line.find("Vertices")==0)))
898    {
899       std::cerr<<"Problem on line 5 of file: 'Vertices' expected"<<std::endl;
900       return false;
901    }
902    if (getline(Ff,line))
903    {
904       tmp=line.c_str();
905       Mvert=tmp.toLong(&ok);
906    }
907    else
908    {
909       std::cerr<<"Problem Vertices: a positive integer is expected"<<std::endl;
910       return false;
911    }
912    if (Mvert<=0)
913    {
914       std::cerr<<"Problem Vertices: a positive integer is expected"<<std::endl;
915       return false;
916    }
917
918    count=Mvert;
919    med_float *tmflo=new med_float[count*3];
920    for (int i=0; i<count*3; i=i+3) Ff>>tmflo[i]>>tmflo[i+1]>>tmflo[i+2]>>garbage;
921    if (verbose>4) std::cout<<"Vertices ("<<count<<") "<<tmflo[0]<<" "<<tmflo[1]<<"... "<<tmflo[count*3-1]<<std::endl;
922
923    CVWtab *montab=new CVWtab(count*3,tmflo);
924    tmp=tmp.sprintf("NB%ld VC",this->nofile);
925    ok=this->insert_key(tmp,montab);
926
927    getline(Ff,line);
928    getline(Ff,line);
929   
930    getline(Ff,line); // get Edges or Triangle, because sometimes Edges absent
931    
932    if (!line.find("Edges")==0)
933    {
934       std::cerr<<"absent line 'Edges' of file '"<<FileName.toLatin1().constData()<<"' :found '"<<line<<"' instead"<<std::endl;
935    }
936    else 
937    {
938      if (getline(Ff,line))
939      {
940         tmp=line.c_str();
941         Medge=tmp.toLong(&ok);
942      }
943      else
944      {
945         std::cerr<<"Problem on line 'Edges' of file: a positive integer is expected"<<std::endl;
946         return false;
947      }
948      if (Medge<=0)
949      {
950         std::cerr<<"Problem on line 'Edges' of file: a positive integer is expected"<<std::endl;
951         return false;
952      }
953
954      count=Medge;
955      tmint=new med_int[count*2]; //*3
956      for (int i=0; i<count*2; i=i+2) {
957        Ff>>tmint[i]>>tmint[i+1]>>garbage;
958      }
959      if (verbose>4) std::cout<<"Edges ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count*2-1]<<std::endl;
960      montab=new CVWtab(count*2,tmint);
961      tmp=tmp.sprintf("NB%ld ED",this->nofile); //TODO see if it could serve
962      ok=this->insert_key(tmp,montab);
963      
964      getline(Ff,line);
965      getline(Ff,line);
966      getline(Ff,line);
967    }
968
969    if (!line.find("Triangles")==0)
970    {
971       std::cerr<<"Problem on line 'Triangles' of file '"<<FileName.toLatin1().constData()<<"' :found '"<<line<<"' instead"<<std::endl;
972       return false;
973    }
974    if (getline(Ff,line))
975    {
976       tmp=line.c_str();
977       Mtria=tmp.toLong(&ok);
978    }
979    else
980    {
981       std::cerr<<"Problem on line 'Triangles' of file: a positive integer is expected"<<std::endl;
982       return false;
983    }
984    if (Mtria<=0)
985    {
986       std::cerr<<"Problem on line 'Triangles' of file: a positive integer is expected"<<std::endl;
987       return false;
988    }
989
990    count=Mtria;
991    tmint=new med_int[count*3]; //*7 as older files .faces, obsolete
992    for (int i=0; i<count*3; i=i+3) {
993      Ff>>tmint[i]>>tmint[i+1]>>tmint[i+2]>>garbage;
994    }
995    if (verbose>4) std::cout<<"Triangles ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<
996        tmint[count*3-5]<<" "<<tmint[count*3-4]<<" "<<tmint[count*3-3]<<" "<<
997        tmint[count*3-2]<<" "<<tmint[count*3-1]<<std::endl;
998
999    montab=new CVWtab(count*3,tmint);
1000    tmp=tmp.sprintf("FC%ld",this->nofile);
1001    ok=this->insert_key(tmp,montab);
1002    
1003    getline(Ff,line);
1004    getline(Ff,line);
1005
1006    if (!(getline(Ff,line) && (line.find("Tetrahedra")==0)))
1007    {
1008       std::cerr<<"Problem on line 'Tetrahedra' of file: not found"<<std::endl;
1009       return false;
1010    }
1011    if (getline(Ff,line))
1012    {
1013       tmp=line.c_str();
1014       Mtetra=tmp.toLong(&ok);
1015    }
1016    else
1017    {
1018       std::cerr<<"Problem on line 'Tetrahedra' of file: a positive integer is expected"<<std::endl;
1019       return false;
1020    }
1021    if (Mtetra<=0)
1022    {
1023       std::cerr<<"Problem on line 'Tetrahedra' of file: a positive integer is expected"<<std::endl;
1024       return false;
1025    }
1026
1027    if (verbose>=2)
1028    {
1029       std::cout<<"MeshVersionFormatted="<<Mversion<<std::endl;
1030       std::cout<<"MeshDimension="<<Mdim<<std::endl;
1031       std::cout<<"MeshNumberOfVertices="<<Mvert<<std::endl;
1032       std::cout<<"MeshNumberOfEdges="<<Medge<<std::endl;
1033       std::cout<<"MeshNumberOfTriangles="<<Mtria<<std::endl;
1034       std::cout<<"MeshNumberOfTetrahedra="<<Mtetra<<std::endl;
1035    }
1036
1037    this->nbvert=Mvert; // for current idom
1038    this->nbedge=Medge; 
1039    this->nbtria=Mtria; 
1040    this->nbtetr=Mtetra; 
1041
1042    count=Mtetra;
1043    tmint=new med_int[count*4];
1044    for (int i=0; i<count*4; i=i+4) Ff>>tmint[i]>>tmint[i+1]>>tmint[i+2]>>tmint[i+3]>>garbage;
1045    if (verbose>4) std::cout<<"Tetrahedra ("<<count<<") "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[count*4-1]<<std::endl;
1046
1047    montab=new CVWtab(count*4,tmint);
1048    tmp=tmp.sprintf("NB%ld EV",this->nofile);
1049    ok=this->insert_key(tmp,montab);
1050
1051    //swap on file if too big for memory in one cpu
1052    //default 1GOctet/8(for double)/10(for arrays in memory at the same time)
1053    if (Mvert*3>this->nbelem_limit_swap)
1054      this->SwapOutOfMemory_key_mesh_wrap(QRegExp("NB",Qt::CaseSensitive,QRegExp::RegExp));
1055    //beware record 6 lenght 1
1056    //ferme le fichier :
1057    Ff.close();
1058    this->nbfiles++;
1059    return true;
1060 }
1061
1062 //************************************
1063 bool ghs3dprl_mesh_wrap::ReadFileNOBOITE(const QString FileName)
1064 //read file .noboite (volume)
1065 //for huge files it could be better use ReadFileNOBOITEB (B=binary format)
1066 //(parameter option of ghs3d but NOT tepal)
1067 {
1068    QString tmp;
1069    std::fstream Ff(FileName.toLatin1().constData(),std::ios_base::in);
1070    long ne,np,npfixe,subnumber,reste;
1071    //bool ok;
1072
1073    if (!Ff.is_open()){
1074       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
1075       return false;
1076    }
1077
1078    //lit les donnees :
1079    Ff>>ne>>np>>npfixe;
1080    if (verbose>3){
1081       std::cout<<"NoboiteNumberOfElements="<<ne<<std::endl;
1082       std::cout<<"NoboiteNumberOfVertices="<<np<<std::endl;
1083       std::cout<<"NoboiteNumberOfSpecifiedPoints="<<npfixe<<std::endl;
1084    }
1085
1086    for (int i=1; i<=17-3; i++) Ff>>reste;
1087    //printf("reste %ld\n",reste);
1088    med_int *tmint=new med_int[ne*4];
1089    for (int i=0; i<ne*4; i++) Ff>>tmint[i];
1090    if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[ne*4-1]<<std::endl;
1091
1092    CVWtab *montab=new CVWtab(ne*4,tmint);
1093    tmp=tmp.sprintf("NB%ld EV",this->nofile);
1094    /*ok=*/this->insert_key(tmp,montab);
1095
1096    med_float *tmflo=new med_float[np*3];
1097    for (int i=0; i<np*3; i++) Ff>>tmflo[i];
1098    if (verbose>4) std::cout<<"Vertices "<<tmflo[0]<<" "<<tmflo[1]<<"... "<<tmflo[np*3-1]<<std::endl;
1099
1100    montab=new CVWtab(np*3,tmflo);
1101    tmp=tmp.sprintf("NB%ld VC",this->nofile);
1102    /*ok=*/this->insert_key(tmp,montab);
1103
1104    Ff>>subnumber;
1105    if (verbose>2) std::cout<<"NumberOfSubdomains="<<subnumber<<std::endl;
1106    //tmint=new med_int[subnumber*3];
1107    tmint=new  med_int[subnumber*3];
1108    long onelong,maxint;
1109    maxint=std::numeric_limits<int>::max();
1110    //pb from tepalv2
1111    bool isproblem=true;
1112    for (int i=0; i<subnumber*3; i++) {
1113      Ff>>onelong;
1114      //pb from tepalv2
1115      if (onelong<0) {
1116       if (isproblem && verbose>1) std::cout<<"There is one or more negative med_int value in NumberOfSubdomains "<<onelong<<std::endl;
1117       isproblem=false;
1118       onelong=-1;
1119       }
1120      if (onelong>maxint) {
1121       if (isproblem && verbose>1) std::cout<<"There is one or more truncated med_int value in NumberOfSubdomains "<<onelong<<std::endl;
1122       isproblem=false;
1123       onelong=-2;
1124       }
1125      tmint[i]=(int)onelong;
1126      }
1127    if (verbose>4) std::cout<<"Subdomains "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[subnumber*3-1]<<std::endl;
1128
1129    montab=new CVWtab(subnumber*3,tmint);
1130    tmp=tmp.sprintf("NB%ld SN",this->nofile);
1131    /*ok=*/this->insert_key(tmp,montab);
1132
1133    //swap on file if too big for memory in one cpu
1134    //default 1GOctet/8(for double)/10(for arrays in memory at the same time)
1135    if (np*3>this->nbelem_limit_swap)
1136      this->SwapOutOfMemory_key_mesh_wrap(QRegExp("NB",Qt::CaseSensitive,QRegExp::RegExp));
1137    //beware record 6 lenght 1
1138    //ferme le fichier :
1139    Ff.close();
1140    this->nbfiles++;
1141    return true;
1142 }
1143
1144 //************************************
1145 bool ghs3dprl_mesh_wrap::ReadFileNOBOITEB(const QString FileName)
1146 //read file .noboiteb (volume)
1147 //for huge files it could be better use ReadFileNOBOITEB (B=binary format)
1148 //but NOT parameter option of tepal
1149 //idem ReadFileNOBOITE with read unformatted
1150 {
1151    //bool ok;
1152    QString tmp;
1153    std::cerr<<"Problem function ReadFileNOBOITEB\n"
1154        <<"(no FORTRAN binary format files in tepal)\n\n";
1155    //file binary
1156    FILE *Ff=fopen(FileName.toLatin1().constData(),"rb");
1157    long ne,np,npfixe,reste,subnumber;
1158
1159    //http://www.math.utah.edu/software/c-with-fortran.html
1160    //record 1 from format FORTRAN begins and ends with lengh of record
1161    //=> 2*long(68)     (68=17*4octets)
1162    long r1[17+2];
1163    if (!Ff){
1164       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
1165       return false;
1166    }
1167    //read datas :
1168    fread(&r1,sizeof(long),17+2,Ff);
1169    for (long i=1; i<18; i++) std::cout<<"R1("<<i<<")="<<r1[i]<<std::endl;
1170
1171    if (r1[0]!=68){
1172       std::cerr<<"First FORTRAN record of File '"<<FileName.toLatin1().constData()<<"' not length 17*long"<<std::endl;
1173       return false;
1174    }
1175    ne=r1[1];
1176    np=r1[2];
1177    npfixe=r1[3];
1178    if (verbose>3){
1179       std::cout<<"NoboitebNumberOfElements="<<ne<<std::endl;
1180       std::cout<<"NoboitebNumberOfVertices="<<np<<std::endl;
1181       std::cout<<"NoboitebNumberOfSpecifiedPoints="<<npfixe<<std::endl;
1182    }
1183    //etc...could be done if necessary not debugged
1184    fread(&reste,sizeof(long),1,Ff);
1185    long *tlong=new long[ne*4];
1186    med_int *tmint=new med_int[ne*4];
1187    fread(tlong,sizeof(long),ne*4,Ff);
1188    fread(&reste,sizeof(long),1,Ff);
1189    for (long i=0; i<ne*4; i++) tmint[i]=tlong[i];
1190    delete tlong;
1191    if (verbose>4) std::cout<<"Elements "<<tmint[0]<<" "<<tmint[1]<<"... "<<tmint[ne*4-1]<<std::endl;
1192
1193    CVWtab *montab=new CVWtab(ne*4,tmint);
1194    tmp=tmp.sprintf("NB%ld EV",this->nofile);
1195    /*ok=*/this->insert_key(tmp,montab);
1196
1197    fread(&reste,sizeof(long),1,Ff);
1198    //std::cout<<"info "<<reste<<" "<<np*3<<" "<<sizeof(med_float)<<std::endl;
1199    float *tfloat=new float[np*3];
1200    med_float *tmflo=new med_float[np*3];
1201    fread(tfloat,sizeof(float),np*3,Ff);
1202    fread(&reste,sizeof(long),1,Ff);
1203    for (long i=0; i<np*3; i++) tmflo[i]=tfloat[i];
1204    delete tfloat;
1205    if (verbose>4) printf("Vertices %g %g ... %g \n",tmflo[0],tmflo[1],tmflo[np*3-1]);
1206
1207    montab=new CVWtab(np*3,tmflo);
1208    tmp=tmp.sprintf("NB%ld VC",this->nofile);
1209    /*ok=*/this->insert_key(tmp,montab);
1210
1211    fread(&reste,sizeof(long),1,Ff);
1212    fread(&subnumber,sizeof(long),1,Ff);
1213    fread(&reste,sizeof(long),1,Ff);
1214    if (verbose>2) std::cout<<"NumberOfSubdomains="<<subnumber<<std::endl;
1215    fread(&reste,sizeof(long),1,Ff);
1216    tlong=new long[subnumber*3];
1217    fread(tlong,sizeof(long),subnumber*3,Ff);
1218    fread(&reste,sizeof(long),1,Ff);
1219    if (verbose>4) printf("Subdomains %ld %ld ... %ld \n",tlong[0],tlong[1],tlong[subnumber*3-1]);
1220
1221    tmint=new med_int[subnumber*3];
1222    for (long i=0; i<subnumber*3; i++) tmint[i]=tlong[i];
1223    delete tlong;
1224    montab=new CVWtab(subnumber*3,tmint);
1225    tmp=tmp.sprintf("NB%ld SN",this->nofile);
1226    /*ok=*/this->insert_key(tmp,montab);
1227
1228    //swap on file if too big for memory in one cpu
1229    //default 1GOctet/8(for double)/10(for arrays in memory at the same time)
1230    if (np*3>this->nbelem_limit_swap)
1231      this->SwapOutOfMemory_key_mesh_wrap(QRegExp("NB",Qt::CaseSensitive,QRegExp::RegExp));
1232
1233    //beware record 6 lenght 1
1234    //ferme le fichier :
1235    fclose(Ff);
1236    this->nbfiles++;
1237    return true;
1238 }
1239
1240 //************************************
1241 bool ghs3dprl_mesh_wrap::ReadFilePOINTS(const QString FileName)
1242 //read file .points (wrap)
1243 {
1244    QString tmp;
1245    long nb;
1246    long maxlen=128;
1247    bool ok=true;
1248
1249    //Lit les donnees :
1250    QFile Ff(FileName);
1251    //NOT Raw because Raw=non-buffered file access
1252    //qt3 ok=Ff.open(IO_ReadOnly|IO_Translate);
1253    ok=Ff.open(QIODevice::ReadOnly|QIODevice::Text);
1254    if (!ok){
1255       std::cerr<<"Problem File '"<<FileName.toLatin1().constData()<<"' not open\n"<<std::endl;
1256       return false;
1257    }
1258    tmp=Ff.readLine(maxlen);
1259    tmp=tmp.simplified();
1260    nb=tmp.toLong(&ok);
1261    if (!ok){
1262       std::cerr<<"Problem conversion File '"<<FileName.toLatin1().constData()<<"\n"<<std::endl;
1263       return false;
1264    }
1265    if (verbose>2) std::cout<<"NumberOfVertices="<<nb<<std::endl;
1266    med_float *tmflo=new med_float[3*nb]; //coordinates
1267    med_int *tmint=new med_int[nb];         //nrs (attribute of point)
1268    long il3=0;
1269    for ( long il=0; il<nb; il++ ){
1270       tmp=Ff.readLine(maxlen);
1271       tmp=tmp.simplified();
1272       for ( int j=0; j<3; j++ ){
1273          tmflo[il3]=tmp.section(' ',j,j).toDouble(&ok);
1274          //std::cout<<"cv '"<<tmflo[il3]<<"' "<<il3<<std::endl;
1275          il3++;
1276          if (!ok){
1277             std::cerr<<"Problem conversion File '"<<FileName.toLatin1().constData()<<"\n"<<std::endl;
1278             return false;
1279          }
1280       }
1281       //nrs is vertex attribute
1282       tmint[il]=tmp.section(' ',3,3).toLong(&ok);
1283       if (!ok){
1284          std::cerr<<"Problem conversion File '"<<FileName.toLatin1().constData()<<"\n"<<std::endl;
1285          return false;
1286       }
1287    }
1288    //beware no examples with each specified points (if any) here
1289    CVWtab *montab=new CVWtab(nb,tmint); //init montab->tmint nrs
1290    tmp=tmp.sprintf("PO%ld NRS",this->nofile);
1291    ok=this->insert_key(tmp,montab);
1292
1293    montab=new CVWtab(nb,tmflo); //init montab->tmflo xyz
1294    tmp=tmp.sprintf("PO%ld XYZ",this->nofile);
1295    ok=this->insert_key(tmp,montab);
1296
1297    //Ferme le fichier :
1298    Ff.close();
1299    this->nbfiles++;
1300    return true;
1301 }
1302
1303 //************************************
1304 bool ghs3dprl_mesh_wrap::list_keys_mesh_wrap()
1305 {
1306    QHashIterator<QString,CVWtab*> it( this->mestab);
1307    while ( it.hasNext() ) {
1308      it.next();
1309      QString nom = it.key().leftJustified(32,' ');
1310      std::cout<<nom.toLatin1().constData()<<"-> size="<<it.value()->size<<std::endl;
1311    }
1312    return true;
1313 }
1314
1315 //************************************
1316 long ghs3dprl_mesh_wrap::remove_all_keys_mesh_wrap()
1317 {
1318    long nb=this->remove_key_mesh_wrap(QRegExp(".",Qt::CaseSensitive,QRegExp::RegExp));
1319    return nb;
1320 }
1321
1322 //************************************
1323 long ghs3dprl_mesh_wrap::remove_key_mesh_wrap(const QRegExp &rxp)
1324 {
1325    long nbremove=0;
1326    QMutableHashIterator<QString,CVWtab*> it(this->mestab);
1327    while ( it.hasNext() ){
1328      it.next();
1329      if (it.key().contains(rxp)) {
1330         nbremove++;
1331         if (this->verbose>6) std::cout<<"remove key "<<it.key().toLatin1().constData()<<std::endl;
1332         delete it.value();
1333         it.remove();
1334      }
1335    }
1336    return nbremove;
1337 }
1338
1339 //************************************
1340 long ghs3dprl_mesh_wrap::nb_key_mesh_wrap(const QRegExp &rxp)
1341 {
1342    long nbremove=0;
1343    //std::cout<<"nb_key_mesh_wrap on "<<std::endl;
1344    QMutableHashIterator<QString,CVWtab*> it(this->mestab);
1345    while ( it.hasNext() ){
1346      it.next();
1347      if (it.key().contains(rxp)) nbremove++;
1348    }
1349    //std::cout<<"nb_key_mesh_wrap found "<<nbremove<<std::endl;
1350    return nbremove;
1351 }
1352
1353 //************************************
1354 bool SwapOnFile(const QString &key,const QString &path,CVWtab *tab,int verbose)
1355 //
1356 {
1357    //return true;
1358    if (tab->filename=="_NO_FILE"){
1359       tab->filename=path+key+".tmp";
1360       tab->filename.replace(" ","_"); //replace " " by "_"
1361
1362       //swap disque binaire
1363       //montab->tmint=new long[10]; //for test
1364       //for (int i=0; i<10; i++) montab->tmint[i]=i*2;
1365       FILE *fichier=fopen(tab->filename.toLatin1().constData(),"wb");
1366       long taille;
1367       taille=tab->size;
1368       fwrite(&taille,sizeof(taille),1,fichier);
1369       if (tab->tmint){
1370          if (verbose>3)
1371          std::cout<<"SwapOnFile_binary "<<tab->filename.toLatin1().constData()<<
1372          " NbElements "<<taille<<
1373          " SizeElement_med_int   "<<sizeof(med_int)<<
1374          " TotalSizeBinary " <<taille*sizeof(med_int)<<std::endl;
1375          fwrite(tab->tmint,sizeof(med_int),taille,fichier);
1376          //fread(&gagnants,sizeof(gagnants),1,fichier);
1377       }
1378       if (tab->tmflo){
1379          if (verbose>3)
1380          std::cout<<"SwapOnFile_binary "<<tab->filename.toLatin1().constData()<<
1381          " NbElements "<<taille<<
1382          " SizeElement_med_float "<<sizeof(med_float)<<
1383          " TotalSizeBinary " <<taille*sizeof(med_float)<<std::endl;
1384          fwrite(tab->tmflo,sizeof(med_float),taille,fichier);
1385       }
1386       fclose(fichier);
1387    }
1388    else{
1389       if (verbose>3) std::cout<<"SwapOnFile in binary file done yet "<<
1390          tab->filename.toLatin1().constData()<<std::endl;
1391    }
1392    //deallocate because swap disk binary mode
1393    tab->CVWtab_deallocate(); //free memory
1394    return true;
1395 }
1396
1397 //************************************
1398 long ghs3dprl_mesh_wrap::SwapOutOfMemory_key_mesh_wrap(const QRegExp &rxp,
1399                                                        long ifgreaterthan)
1400 //swap on file if not yet and if size greater than ifgreaterthan
1401 {
1402    long nb=0;
1403    //bool ok;
1404    QHashIterator<QString,CVWtab*> it(this->mestab);
1405    while ( it.hasNext() ) {
1406      it.next();
1407      if (it.key().contains(rxp)) {
1408         nb++;
1409         if ((it.value()->size>0)&&(it.value()->size>ifgreaterthan)){
1410            if (verbose>3)
1411               std::cout<<"SwapOutOfMemory_key_mesh_wrap on demand "<<
1412                    it.key().toLatin1().constData()<<
1413                    " size "<<it.value()->size<<">"<<ifgreaterthan<<std::endl;
1414            //free memory
1415            /*ok=*/SwapOnFile(it.key(),this->path,it.value(),this->verbose);
1416        }
1417      }
1418    }
1419    return nb;
1420 }
1421 //************************************
1422 bool ghs3dprl_mesh_wrap::list_onekey_mesh_wrap(const QString &key)
1423 {
1424    CVWtab *montab=this->mestab[key];
1425    if (montab){
1426       //std::cout<<"key "<<key<<"trouvee -> size="<<montab->size<<std::endl;
1427       if (montab->type==1)
1428          for ( long i=0; i<montab->size; i++ )
1429             std::cout<<montab->tmint[i]<<" ";
1430       if (montab->type==2)
1431          for ( long i=0; i<montab->size; i++ )
1432             std::cout<<montab->tmflo[i]<<" ";
1433       std::cout<<std::endl;
1434    }
1435    else
1436       std::cout<<"key "<<key.toLatin1().constData()<<" not found"<<std::endl;
1437    return true;
1438 }
1439
1440 //************************************
1441 bool ghs3dprl_mesh_wrap::insert_key(const QString &key,CVWtab *tab)
1442 //insertion conditionnee par limite this->nbelem_limit_swap
1443 //si tableaux contenus on dimension superieure
1444 //alors swap disque dans getenv(tmp) fichier temporaire binaire
1445 {
1446    //bool ok;
1447    if (verbose>4)
1448       std::cout<<"insert key "<<key.toLatin1().constData()<<
1449             " size="<<tab->size<<std::endl;
1450    tab->filename="_NO_FILE";
1451    if (this->nbelem_limit_swap<tab->size) {
1452       if (verbose>3) std::cout<<"insert key automatic SwapOnFile "<<
1453                            key.toLatin1().constData()<<std::endl;
1454       /*ok=*/SwapOnFile(key,this->path,tab,this->verbose);
1455    }
1456    this->mestab.insert(key,tab);
1457    return true;
1458 }
1459 //************************************
1460 CVWtab* ghs3dprl_mesh_wrap::restore_key(const QString &key)
1461 //retauration conditionnee par limite nbelem
1462 //si tableaux contenus on dimension superieure a nbelem
1463 //alors swap disque dans getenv(tmp) fichier temporaire
1464 //alors lecture du fichier (et reallocate memory)
1465 {
1466    CVWtab *tab=NULL;
1467    tab=this->mestab[key];
1468    /*if (tab) std::cout<<" -> size in proc "<<tab->size<<std::endl;
1469    else std::cout<<" -> tab NULL\n";*/
1470    if (!tab) //it is NOT a problem
1471    {
1472       if (verbose>6) std::cout<<"restore key not found "<<key.toLatin1().constData()<<std::endl;
1473       return NULL;
1474    }
1475    if (tab->size > 0){
1476       if (verbose>5) std::cout<<"restore key direct from memory "<<key.toLatin1().constData()<<" size="<<tab->size<<std::endl;
1477       return tab;
1478    }
1479    //restore from binary file
1480    if ((tab->type<1)||(tab->type>2)){
1481       std::cerr<<"Problem restore key from binary file "<<tab->filename.toLatin1().constData()<<
1482                " type unexpexted "<<tab->type<<std::endl;
1483       return NULL;
1484    }
1485    //std::cout<<"restore_key from binary file "<<tab->filename<<std::endl;
1486
1487    //swap disque binaire
1488    FILE *fichier=fopen(tab->filename.toLatin1().constData(),"rb");
1489    long taille;
1490    fread(&taille,sizeof(long),1,fichier);
1491    if (taille!=-tab->size){
1492       std::cerr<<"Problem restore_key from binary file "<<tab->filename.toLatin1().constData()<<
1493             " size unexpexted "<<taille<<" expected "<<-tab->size<<std::endl;
1494       fclose(fichier);
1495       return NULL;
1496    }
1497    if (tab->type==1){
1498       if (verbose>5)
1499       std::cout<<"restore key from binary file "<<tab->filename.toLatin1().constData()<<
1500             " number of elements "<<taille<<
1501             " size_element med_float "<<sizeof(med_float)<<
1502             " total_size_binary " <<taille*sizeof(med_float)<<std::endl;
1503
1504       //allocate because swap disque binaire
1505       tab->tmint=new med_int[taille]; //allocate memory
1506       fread(tab->tmint,sizeof(med_int),taille,fichier);
1507    }
1508    if (tab->type==2){
1509       if (verbose>5)
1510       std::cout<<"restore key from binary file "<<tab->filename.toLatin1().constData()<<
1511             " number of elements "<<taille<<
1512             " size_element med_float "<<sizeof(med_float)<<
1513             " total_size_binary " <<taille*sizeof(med_float)<<std::endl;
1514       //allocate because swap disque binaire
1515       tab->tmflo=new med_float[taille]; //allocate memory
1516       for (int i=0; i<taille ; i++) tab->tmflo[i]=-1e0;
1517       fread(tab->tmflo,sizeof(med_float),taille,fichier);
1518       /*for (int i=0; i<taille ; i++) std::cout<<tab->tmflo[i]<<"/";
1519       std::cout<<std::endl;*/
1520    }
1521    fclose(fichier);
1522    tab->size=-tab->size;
1523    return tab;
1524 }
1525
1526 //************************************
1527 bool ghs3dprl_mesh_wrap::test_msg_wrap()
1528 //tests sur resultats fichiers msg
1529 {
1530    QString key1,key2,typ="FA VE ED EL"; //pour faces vertice edges elements
1531    CVWtab *tab1,*tab2;
1532    bool ok=true;
1533    //test send=receive
1534    //numerotations locales sont identiques
1535    long nb=typ.count(' ',Qt::CaseSensitive) + 1; //nb chiffres detectes
1536    for (long i=0; i < nb; i++)
1537    for (long ifile=1; ifile <= this->nbfiles; ifile++)
1538    for (long ineig=1; ineig <= this->nbfiles; ineig++)
1539    {
1540       if (ifile==ineig) continue; //impossible
1541       key1=key1.sprintf("MS%ld NE%ld ",ifile,ineig)+typ.section(' ',i,i)+" SE";
1542       key2=key2.sprintf("MS%ld NE%ld ",ifile,ineig)+typ.section(' ',i,i)+" RE";
1543       //std::cout<<"key "<<key1<<" et key "<<key2<<std::endl;
1544       tab1=this->restore_key(key1);
1545       //tab1=this->mestab[key1];
1546       tab2=this->restore_key(key2);
1547       //tab2=this->mestab[key2];
1548       //std::cout<<"sortie key "<<key1<<" et key "<<key2<<std::endl;
1549       if (!tab1 && !tab2) continue; //case not neighbours
1550       if (!tab1)
1551       {  std::cout<<"key "<<key1.toLatin1().constData()<<" inexistante avec key "<<key2.toLatin1().constData()<<" existante"<<std::endl;
1552          ok=false;
1553       }
1554       else
1555       {
1556        if (!tab2)
1557        {  std::cout<<"key "<<key2.toLatin1().constData()<<" inexistante avec key "<<key1.toLatin1().constData()<<" existante"<<std::endl;
1558           ok=false;
1559        }
1560        else
1561         if (!tab1->is_equal(tab2))
1562         {  std::cout<<"key "<<key1.toLatin1().constData()<<" et key "<<key2.toLatin1().constData()<<" de contenu differents"<<std::endl;
1563            ok=false;
1564         }
1565       }
1566       /*else
1567          printf("key '%s' et key '%s' identiques \n",
1568                            (const char *)key2,(const char *)key1);*/
1569    }
1570
1571    //test size neighbourg=ifile
1572    //numerotations locales sont differentes mais de tailles identiques
1573    //pas besoin de verifier " RE " car deja fait au dessus
1574    for (long i=0; i < nb; i++)
1575    for (long ifile=1; ifile <= this->nbfiles; ifile++)
1576    for (long ineig=ifile+1; ineig <= this->nbfiles; ineig++)
1577    {
1578       if (ifile==ineig) continue; //cas impossible
1579       key1=key1.sprintf("MS%ld NE%ld ",ifile,ineig)+typ.section(' ',i,i)+" SE";
1580       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
1581       key2=key2.sprintf("MS%ld NE%ld ",ineig,ifile)+typ.section(' ',i,i)+" SE";
1582       tab2=this->restore_key(key2); //tab2=this->mestab[key2];
1583       if (!tab1 && !tab2) continue; //case not neighbours
1584       if (!tab1)
1585       {  std::cout<<"key "<<key1.toLatin1().constData()<<" inexistante avec key "<<key2.toLatin1().constData()<<" existante"<<std::endl;
1586          ok=false;
1587       }
1588       else
1589       {
1590        if (!tab2)
1591        {  std::cout<<"key "<<key2.toLatin1().constData()<<" inexistante avec key "<<key1.toLatin1().constData()<<" existante"<<std::endl;
1592           ok=false;
1593        }
1594        else
1595         if ((tab1->type!=tab2->type)||(tab1->size!=tab2->size))
1596         {  std::cout<<"key "<<key1.toLatin1().constData()<<" et key "<<key2.toLatin1().constData()<<" de type ou tailles differents"<<std::endl;
1597            ok=false;
1598         }
1599       }
1600    }
1601    return ok;
1602 }
1603
1604 //************************************
1605 bool ghs3dprl_mesh_wrap::test_vertices_wrap()
1606 //tests sur vertices
1607 {
1608    QString key1,key2,key11,key22,key11old,key22old;
1609    CVWtab *tab1,*tab2,*tab11,*tab22;
1610    bool ok=true;
1611    key11old="_NO_KEY";key22old="_NO_KEY";
1612    //test size neighbourg=ifile
1613    //numerotations locales sont differentes mais de tailles identiques
1614    //pas besoin de verifier " RE " car deja fait au dessus
1615    //for (int ifile=1; ifile <= this->nbfiles; ifile++)
1616    //for (int ineig=ifile+1; ineig <= this->nbfiles; ineig++)
1617    bool swap=false;
1618    if (verbose>4)std::cout<<"test_vertices_wrap on nb files "<<this->nbfiles<<std::endl;
1619    for (int ifile=this->nbfiles; ifile >= 1; ifile--)
1620    for (int ineig=this->nbfiles; ineig >= ifile+1; ineig--)
1621    {
1622       if (ifile==ineig) continue; //cas impossible
1623       key1=key1.sprintf("MS%d NE%d VE SE",ifile,ineig);
1624       key11=key11.sprintf("NB%d VC",ifile);
1625       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
1626       key2=key2.sprintf("MS%d NE%d VE SE",ineig,ifile);
1627       key22=key22.sprintf("NB%d VC",ineig);
1628       tab2=this->restore_key(key2); //tab2=this->mestab[key2];
1629       if (!tab1 && !tab2) continue; //cas non voisins
1630       if (!tab1)
1631       {
1632          std::cerr<<"TestEqualityCoordinates key "<<key1.toLatin1().constData()<<
1633                " NOT existing but key "<<key2.toLatin1().constData()<<" existing"<<std::endl;
1634          ok=false; continue;
1635       }
1636       if (!tab2)
1637       {
1638          std::cerr<<"TestEqualityCoordinates key "<<key2.toLatin1().constData()<<
1639                " NOT existing but key "<<key1.toLatin1().constData()<<" existing"<<std::endl;
1640          ok=false; continue;
1641       }
1642       if (tab1->size!=tab2->size)
1643       {
1644          std::cerr<<"TestEqualityCoordinates key "<<key1.toLatin1().constData()<<
1645                " and key "<<key2.toLatin1().constData()<<" NOT same size"<<std::endl;
1646          ok=false; continue;
1647       }
1648       if (ok)
1649       {
1650          if (swap) {
1651             //Swap out of memory if no use
1652             if ((key11old!=key11)&&(key11old!=key22))
1653                this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key11old,Qt::CaseSensitive,QRegExp::RegExp));
1654             if ((key22old!=key11)&&(key22old!=key22))
1655                this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key22old,Qt::CaseSensitive,QRegExp::RegExp));
1656          }
1657          tab11=this->restore_key(key11); //tab11=this->mestab[key11];
1658          tab22=this->restore_key(key22); //tab22=this->mestab[key22];
1659          if (tab11->size>this->nbelem_limit_swap ||
1660              tab22->size>this->nbelem_limit_swap) swap=true ;
1661          long i1,i2;
1662          bool ok1=true;
1663          //test on equality of xyz_coordinates of commons vertices
1664          for  (long j=0; j < tab1->size-1; j++)
1665          {
1666             i1=tab1->tmint[j];
1667             i2=tab2->tmint[j];
1668             //1 for print vertices not equals
1669             if (!CVW_is_equal_vertices(tab11,i1,tab22,i2,1))
1670             {
1671                std::cerr<<j<<" Vertice "<<i1<<" != Vertice "<<i2<<"\n"<<std::endl;
1672                ok=false; ok1=false;
1673             }
1674          }
1675          if ((verbose>2)&&(ok1))
1676             std::cout<<"TestEqualityCoordinates "<<tab1->size<<
1677                   " Vertices "<<key1.toLatin1().constData()<<" and "<<key2.toLatin1().constData()<<" ok"<<std::endl;
1678          if (!ok1)
1679             std::cerr<<"TestEqualityCoordinates "<<tab1->size<<
1680                   " Vertices "<<key1.toLatin1().constData()<<" and "<<key2.toLatin1().constData()<<" NO_OK"<<std::endl;
1681          key11old=key11; key22old=key22;
1682       }
1683    }
1684    //Swap out of memory (supposed no use?)
1685    //NO because NB1&NB2 VC supposed future use
1686    //YES precaution
1687    if (swap) {
1688       this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key11old,Qt::CaseSensitive,QRegExp::RegExp));
1689       this->SwapOutOfMemory_key_mesh_wrap(QRegExp(key22old,Qt::CaseSensitive,QRegExp::RegExp));
1690    }
1691    return ok;
1692 }
1693
1694 //************************************
1695 bool ghs3dprl_mesh_wrap::Find_VerticesDomainToVerticesSkin()
1696 //initialise correspondances vertice skin et vertices locaux pour chaque domaine
1697 //calcule un med_int new tab[nb_vertices_of_domain]
1698 //avec nieme vertice of skin=tab[ieme vertice de domain]
1699 //apres verification tepal garde bien dans la global numbering "GLi VE"
1700 //les indices initiaux des noeuds (attention: de 1 a nbNodes) 
1701 {
1702    QString key1,key2,tmp;
1703    CVWtab *cooskin,*coodom,*glodom,*montab;
1704    bool ok=true;
1705    med_float *p1,*p2;
1706    med_int i,nb,jd,js;
1707
1708    cooskin=this->restore_key(QString("SKIN_VERTICES_COORDINATES"));
1709    if (!cooskin) return false;
1710    if (verbose>4)std::cout<<"NumberVerticesSKIN="<<cooskin->size/3<<std::endl;
1711    //ici pourrait creer BBtree sur skin
1712    for (long ifile=1; ifile<=this->nbfiles; ifile++)
1713    {
1714       key1=key1.sprintf("NB%ld VC",ifile);
1715       coodom=this->restore_key(key1);
1716       if (!coodom) continue; //Problem
1717       key2=key2.sprintf("GL%ld VE",ifile);
1718       glodom=this->restore_key(key2);
1719       if (verbose>4)
1720          std::cout<<"NumberVerticesDOMAIN_"<<ifile<<"="<<glodom->size<<std::endl;
1721       if (coodom->size!=glodom->size*3)
1722       {
1723          std::cerr<<"Find_VerticesDomainToVerticesSkin key "<<key1.toLatin1().constData()<<
1724                " and key "<<key2.toLatin1().constData()<<" NOT coherent sizes"<<std::endl;
1725          ok=false; continue;
1726       }
1727       //test on equality of xyz_coordinates of commons vertices
1728       med_int *tab=new med_int[glodom->size];
1729       i=0;
1730       nb=0; //nb equals vertices
1731     if (verbose>8){
1732       std::cout<<"\nglobal numbering nodes: no iglo\n";
1733       for  (jd=0; jd < glodom->size; jd++) 
1734            std::cout<<"\t"<<jd<<"\t"<<glodom->tmint[jd]<<std::endl;
1735       std::cout<<"\nresults: no i js iglo\n";
1736       for  (jd=0; jd < coodom->size; jd=jd+3)
1737       {
1738          p2=(coodom->tmflo+jd);
1739          tab[i]=0;
1740          //ici pourrait utiliser BBtree
1741          for  (js=0; js < cooskin->size; js=js+3)
1742          {
1743             p1=(cooskin->tmflo+js);
1744             if (p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2]) 
1745             {
1746                std::cout<<"\t"<<nb<<"\t"<<i<<"\t"<<js/3<<"\t"<<glodom->tmint[i]-1<<
1747                  key2.sprintf("\t%13.5e%13.5e%13.5e",p1[0],p1[1],p1[2]).toLatin1().constData()<<std::endl;
1748                tab[i]=js/3; nb++; continue;
1749             }
1750          }
1751          i++;
1752       }
1753       montab=new CVWtab(glodom->size,tab);
1754       tmp=tmp.sprintf("NB%ld GL_SKIN",ifile);
1755       ok=this->insert_key(tmp,montab);
1756       if (verbose>4){
1757          std::cout<<"NumberOfEqualsVerticesDOMAIN_"<<ifile<<"="<<nb<<std::endl;
1758       }
1759     }
1760    }
1761    return ok;
1762 }
1763
1764 //fin utils procedures
1765
1766 //************************************
1767 bool ghs3dprl_mesh_wrap::Write_masterxmlMEDfile()
1768 {
1769    QString tmp;
1770
1771    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!first call create xml doc node
1772    if (idom==1)
1773    {
1774    //define master file (.xml) in memory
1775    tmp=path+medname+".xml";
1776    filemaster=tmp.toLatin1().constData();
1777    domainname=medname.toLatin1().constData();
1778    char buff[256];
1779
1780    //Creating the XML document
1781    master_doc = xmlNewDoc(BAD_CAST "1.0");
1782    root_node = xmlNewNode(0, BAD_CAST "root");
1783    xmlDocSetRootElement(master_doc,root_node);
1784
1785    //Creating child nodes
1786    //Version tag
1787    med_int majeur,mineur,release;
1788    //Quelle version de MED est utilisee
1789    MEDlibraryNumVersion(&majeur,&mineur,&release);
1790    if (verbose>0) fprintf(stdout,"File write %s with MED V%d.%d.%d\n",filemaster.c_str(),(int)majeur,(int)mineur,(int)release);
1791    node = xmlNewChild(root_node, 0, BAD_CAST "version",0);
1792    //xmlNewProp(node, BAD_CAST "maj", BAD_CAST int2string2(majeur).c_str());
1793    xmlNewProp(node, BAD_CAST "maj", BAD_CAST i2a(majeur).c_str());
1794    xmlNewProp(node, BAD_CAST "min", BAD_CAST i2a(mineur).c_str());
1795    xmlNewProp(node, BAD_CAST "ver", BAD_CAST i2a(release).c_str());
1796
1797    //Description tag
1798    node = xmlNewChild(root_node,0, BAD_CAST "description",0);
1799    // .../INSTALL/MeshGems/include/meshgems/meshgems.h:11:#define MESHGEMS_VERSION_LONG "2.9-6"
1800    xmlNewProp(node, BAD_CAST "what", BAD_CAST "tetrahedral mesh by MeshGems-Tetra-hpc 2.9-6 2019");
1801 #ifdef WIN32
1802   SYSTEMTIME  present;
1803   GetLocalTime ( &present );
1804   sprintf(buff,"%04d/%02d/%02d %02dh%02dm",
1805           present.wYear,present.wMonth,present.wDay,
1806           present.wHour,present.wMinute);
1807 #else
1808    time_t present;
1809    time(&present);
1810    struct tm *time_asc = localtime(&present);
1811    sprintf(buff,"%04d/%02d/%02d %02dh%02dm",
1812            time_asc->tm_year+1900,time_asc->tm_mon+1,time_asc->tm_mday,
1813            time_asc->tm_hour,time_asc->tm_min);
1814 #endif
1815    xmlNewProp(node, BAD_CAST "when", BAD_CAST buff);
1816    xmlNewProp(node, BAD_CAST "from", BAD_CAST "tepal2med");
1817
1818    //Content tag
1819    node =xmlNewChild(root_node,0, BAD_CAST "content",0);
1820    node2 = xmlNewChild(node, 0, BAD_CAST "mesh",0);
1821    xmlNewProp(node2, BAD_CAST "name", BAD_CAST domainname.c_str());
1822    info_node = xmlNewChild(node, 0, BAD_CAST "tepal2med_info",0);
1823
1824    //Splitting tag
1825    node=xmlNewChild(root_node,0,BAD_CAST "splitting",0);
1826    node2=xmlNewChild(node,0,BAD_CAST "subdomain",0);
1827    xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbfilestot).c_str());
1828    node2=xmlNewChild(node,0,BAD_CAST "global_numbering",0);
1829    xmlNewProp(node2, BAD_CAST "present", BAD_CAST "yes");
1830
1831    //Files tag
1832    files_node=xmlNewChild(root_node,0,BAD_CAST "files",0);
1833
1834    //Mapping tag
1835    node = xmlNewChild(root_node,0,BAD_CAST "mapping",0);
1836    mesh_node = xmlNewChild(node, 0, BAD_CAST "mesh",0);
1837    xmlNewProp(mesh_node, BAD_CAST "name", BAD_CAST domainname.c_str());
1838    }
1839
1840    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!all calls add xml idom node
1841    {
1842    fprintf(stdout,"Xml node write %s idom %d\n",filemaster.c_str(), (int)idom);
1843    char *hostname = getenv("HOSTNAME");
1844    node = xmlNewChild(files_node,0,BAD_CAST "subfile",0);
1845    xmlNewProp(node, BAD_CAST "id", BAD_CAST i2a(idom).c_str());
1846    node2 = xmlNewChild(node, 0, BAD_CAST "name", BAD_CAST distfilename);
1847    
1848    if (hostname == NULL)
1849       node2 = xmlNewChild(node, 0, BAD_CAST "machine",BAD_CAST "localhost");
1850    else
1851       node2 = xmlNewChild(node, 0, BAD_CAST "machine",BAD_CAST hostname);
1852
1853    node = xmlNewChild(mesh_node,0,BAD_CAST "chunk",0);
1854    xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST i2a(idom).c_str());
1855    node2 = xmlNewChild(node, 0, BAD_CAST "name", BAD_CAST nomfinal);
1856
1857    //tepal2med_info
1858    node = xmlNewChild(info_node, 0, BAD_CAST "chunk",0);
1859    xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST i2a(idom).c_str());
1860    xmlNewProp(node, BAD_CAST "nodes_number", BAD_CAST i2a(nbnodes).c_str());
1861    xmlNewProp(node, BAD_CAST "faces_number", BAD_CAST i2a(nbtria3).c_str());
1862    xmlNewProp(node, BAD_CAST "tetrahedra_number", BAD_CAST i2a(nbtetra4).c_str());
1863    //node2 = xmlNewChild(node, 0, BAD_CAST "name", BAD_CAST nomfinal);
1864
1865    //node2 = xmlNewChild(node, 0, BAD_CAST "nodes", 0);
1866    //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbnodes).c_str());
1867    //node2 = xmlNewChild(node, 0, BAD_CAST "faces", 0);
1868    //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbtria3).c_str());
1869    //node2 = xmlNewChild(node, 0, BAD_CAST "tetrahedra", 0);
1870    //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbtetra4).c_str());
1871
1872    //tepal2med_info about joints of one subdomain
1873    fprintf(stdout,"MeshGems 2.9-6 tetra-hpc joints are not implemented\n");  //MeshGems 2.9-6 Salome 9.5.0 jan 2020
1874    // not implemented ... empty joints ... does NOT work ... xmlAddChild(node,joints_node);
1875    //tepal2med_info about groups and families of one subdomain
1876    xmlAddChild(node,families.xml_groups());
1877    }
1878
1879    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!last call
1880    fprintf(stdout,"xml node idom %d/%ld nb tetras total %ld\n", (int)idom, nbfilestot, nbtetrastotal);
1881    if (idom==nbfilestot)
1882    {
1883    fprintf(stdout,"File write %s as last idom nb tetras total %ld\n",filemaster.c_str(), nbtetrastotal);
1884    node2 = xmlNewChild(info_node, 0, BAD_CAST "global",0);
1885    xmlNewProp(node2, BAD_CAST "tetrahedra_number", BAD_CAST i2a(nbtetrastotal).c_str());
1886    //save masterfile
1887    xmlSaveFormatFileEnc(filemaster.c_str(), master_doc, "UTF-8", 1);
1888    xmlFreeDoc(master_doc);
1889    xmlCleanupParser();
1890    }
1891    return true;
1892 }
1893
1894
1895 //************************************
1896 bool ghs3dprl_mesh_wrap::Write_MEDfiles_v2(bool /*deletekeys*/)
1897 //deletekeys=true to delete non utils keys and arrays "au fur et a mesure"
1898 {
1899    bool ok=true/*,oktmp*/;
1900    QString tmp,cmd;
1901    char description[MED_COMMENT_SIZE];
1902    char dtunit[MED_SNAME_SIZE+1]="_NO_UNIT";
1903    char axisname[MED_SNAME_SIZE*3+1]="x               y               z               ";
1904    char axisunit[MED_SNAME_SIZE*3+1]="_NO_UNIT        _NO_UNIT        _NO_UNIT        ";
1905    med_int nb;
1906    
1907    //remove path
1908    //precaution because casename->med_nomfinal no more 32 character
1909    //if path, in this->path.
1910    //20 preserve for add postfixes "_idom" etc...
1911    if (verbose>0)std::cout<<"\nWrite_MEDfiles_v2\n";
1912    if (verbose>6){std::cout<<"\nInitialFamilies\n"; families.write();}
1913
1914    medname=medname.section('/',-1);
1915    if (medname.length()>20) {
1916       std::cerr<<"CaseNameMed truncated (no more 20 characters)"<<std::endl;
1917       medname.truncate(20);
1918    }
1919
1920    //create file resume DOMAIN.joints.med of all joints for quick display (...may be...)
1921    if (! for_multithread)
1922    {
1923     tmp=path+medname+tmp.sprintf("_joints.med");
1924     charendnull(distfilename,tmp,MED_COMMENT_SIZE);
1925     fidjoint=MEDfileOpen(distfilename,MED_ACC_CREAT);
1926     if (fidjoint<0) std::cerr<<"Problem MEDfileOpen "<<distfilename<<std::endl;
1927     if (verbose>0) std::cout<<"CreateMEDFile for all joints <"<<distfilename<<">\n";
1928    }
1929
1930    //copy file source/GHS3DPRL_skin.med as destination/DOMAIN.skin.med
1931    tmp=path+medname+"_skin.med";
1932    cmd=pathini+casename+"_skin.med";
1933    int ret = access(cmd.toLatin1().constData(),F_OK); //on regarde si le fichier existe
1934    if (ret >= 0) {
1935 #ifdef WIN32
1936       cmd="copy ";
1937 #else 
1938       cmd="cp ";
1939 #endif
1940       cmd = cmd+pathini+casename+"_skin.med "+tmp;
1941       //std::cout<<"Copy skin.med Command = "<<cmd<<std::endl;
1942       system(cmd.toLatin1().constData()); 
1943       if (verbose>0) std::cout<<"CreateMEDFile for initial skin <"<<tmp.toLatin1().constData()<<">\n"; }
1944    else {
1945       if (verbose>0) std::cout<<"No CreateMEDFile <"<<tmp.toLatin1().constData()<<"> for initial skin because <"<<
1946                                                 cmd.toLatin1().constData()<<"> does not exist\n"; }
1947
1948    //define family 0 if not existing, no groups
1949    //La famille FAMILLE_ZERO n'a pas été trouvée, elle est obligatoire
1950    families.add("0","FAMILLE_ZERO");
1951    //define family Group_of_New_Nodes (which not exists before tetrahedra)
1952    famallnodes=0;
1953    if (QString("All_Nodes").contains(deletegroups)==0){
1954       /*oktmp=*/families.get_number_of_new_family(1,&famallnodes,&tmp);
1955       families.add(tmp,"All_Nodes");
1956    }
1957    else if (verbose>3) std::cout<<"--deletegroups matches \"All_Nodes\"\n";
1958    
1959    famalltria3=0;
1960    if (QString("All_Faces").contains(deletegroups)==0){
1961       /*oktmp=*/families.get_number_of_new_family(-1,&famalltria3,&tmp);
1962       families.add(tmp,"All_Faces");
1963    }
1964    else if (verbose>3) std::cout<<"--deletegroups matches \"All_Faces\"\n";
1965
1966    famalltetra4=0;
1967    if (QString("All_Tetrahedra").contains(deletegroups)==0){
1968       /*oktmp=*/families.get_number_of_new_family(-1,&famalltetra4,&tmp);
1969       families.add(tmp,"All_Tetrahedra");
1970    }
1971    else if (verbose>3) std::cout<<"--deletegroups matches \"All_Tetrahedra\"\n";
1972
1973    famnewnodes=0;
1974    if (QString("New_Nodes").contains(deletegroups)==0){
1975       /*oktmp=*/families.get_number_of_new_family(1,&famnewnodes,&tmp);
1976       families.add(tmp,"New_Nodes");
1977    }
1978    else if (verbose>3) std::cout<<"--deletegroups matches \"New_Nodes\"\n";
1979    
1980    famnewtria3=0;
1981    if (QString("New_Faces").contains(deletegroups)==0){
1982       /*oktmp=*/families.get_number_of_new_family(-1,&famnewtria3,&tmp);
1983       families.add(tmp,"New_Faces");
1984    }
1985    else if (verbose>3) std::cout<<"--deletegroups matches \"New_Faces\"\n";
1986    
1987    famnewtetra4=0;
1988    if (QString("New_Tetrahedra").contains(deletegroups)==0){
1989       /*oktmp=*/families.get_number_of_new_family(-1,&famnewtetra4,&tmp);
1990       families.add(tmp,"New_Tetrahedra");
1991    }
1992    else if (verbose>3) std::cout<<"--deletegroups matches \"New_Tetrahedra\"\n";
1993
1994    if (verbose>6){std::cout<<"\nIntermediatesFamilies\n"; families.write();}
1995    //if (verbose>6) std::cout<<"\nNumber0fFiles="<<nbfilestot<<std::endl;
1996    familles intermediatesfamilies=families;
1997    //initialisations on all domains
1998    nbtetrastotal=0;
1999
2000    //loop on the domains
2001    //for (idom=1; idom<=nbfilestot; idom++) {
2002    if (for_multithread) {
2003      nbfilestot=1;
2004      std::cout<<"\nset NumberOfFiles only one domain file as multithread="<<nbfilestot<<std::endl;
2005    }
2006
2007    // if (verbose>6) 
2008    std::cout<<"\nNumberOfFiles="<<nbfilestot<<std::endl;
2009
2010    for (idom=1; idom<=nbfilestot; idom++) {
2011    
2012       this->nbvert=0;  // will be set for current loop idom
2013       this->nbedge=0;
2014       this->nbtria=0;
2015       this->nbtetr=0;
2016
2017       this->nofile=idom;
2018       //restore initial context of families
2019       if (idom>1) families=intermediatesfamilies;
2020       //if (idom>1) continue;
2021       tmp=path+medname+tmp.sprintf("_%d.med",(int)idom);
2022       charendnull(distfilename,tmp,MED_COMMENT_SIZE);
2023
2024       //std::cout<<"<"<<distfilename<<">"<<std::endl;
2025       fid=MEDfileOpen(distfilename,MED_ACC_CREAT);
2026       if (fid<0) {std::cerr<<"Problem MEDfileOpen "<<distfilename<<std::endl; goto erreur;}
2027       if (verbose>2) {
2028          std::cout<<std::endl;
2029          std::cout<<"CreateMEDFile "<<idom<<" <"<<distfilename<<">\n";
2030       }
2031  
2032       //create mesh
2033       tmp=medname+tmp.sprintf("_%d",(int)idom);
2034       charendnull(nomfinal,tmp,MED_NAME_SIZE);
2035       tmp=tmp.sprintf("domain %d among %ld",(int)idom,nbfilestot);
2036       charendnull(description,tmp,MED_COMMENT_SIZE);
2037
2038       if (verbose>4) std::cout<<"Description : "<<description<<std::endl;
2039       err=MEDmeshCr(fid,nomfinal,3,3,MED_UNSTRUCTURED_MESH,description,dtunit,MED_SORT_DTIT,MED_CARTESIAN,axisname,axisunit);
2040       if (err<0) {std::cerr<<"Problem MEDmeshCr"<<nomfinal<<std::endl; goto erreur;}
2041
2042       if (!idom_nodes()) {std::cerr<<"Problem on Nodes"<<std::endl; goto erreur;}
2043       if (verbose>4) std::cout<<"\nEnd of Nodes ***\n"<<std::endl;
2044       if (!idom_edges()) {std::cerr<<"Problem on Edges"<<std::endl; goto erreur;}
2045       if (verbose>4) std::cout<<"\nEnd of Edges ***\n"<<std::endl;
2046       if (!idom_faces()) {std::cerr<<"Problem on Faces"<<std::endl; goto erreur;}
2047       if (verbose>4) std::cout<<"\nEnd of Faces ***\n"<<std::endl;
2048       if (!idom_tetras()) {std::cerr<<"Problem on tetrahedra"<<std::endl; goto erreur;}
2049       if (verbose>4) std::cout<<"\nEnd of Tetrahedra ***\n"<<std::endl;
2050       
2051       //non existing files msg mh-tetra_hpc v2.1.11
2052       //if (!idom_joints()) {std::cerr<<"Problem on Joints"<<std::endl; goto erreur;}
2053
2054       // if (!for_multithread) 
2055       {
2056         if (verbose>6){std::cout<<"\nFinalsFamilies\n"; families.write();}
2057         //for nodes families
2058         nb=create_families(fid,1);
2059         if (verbose>5)std::cout<<"NumberOfFamiliesNodes="<<nb<<" name "<<nomfinal<<std::endl;
2060
2061         if (verbose>8)
2062           std::cout<<"MEDmeshEntityFamilyNumberWr nodes "<<nbnodes<<":"<<
2063                 famnodes[0]<<"..."<<famnodes[nbnodes-1]<<" "<<std::endl;
2064
2065         err=MEDmeshEntityFamilyNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodes,famnodes);
2066         delete[] famnodes;
2067         
2068         if (err<0) std::cerr<<"Problem MEDmeshEntityFamilyNumberWr nodes"<<std::endl;
2069
2070         //for others families
2071         nb=create_families(fid,-1);
2072         if (verbose>5)std::cout<<"NumberOfFamiliesFacesAndEdgesEtc="<<nb<<std::endl;
2073
2074         err=MEDmeshEntityFamilyNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,nbtria3,famtria3);
2075         if (verbose>8)
2076           std::cout<<"MEDmeshEntityFamilyNumberWr tria3 "<<nbtria3<<":"<<
2077                 famtria3[0]<<"..."<<famtria3[nbtria3-1]<<" "<<std::endl;
2078         delete[] famtria3;
2079         if (err<0) std::cerr<<"Problem MEDmeshEntityFamilyNumberWr tria3"<<std::endl;
2080
2081         err=MEDmeshEntityFamilyNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TETRA4,nbtetra4,famtetra4);
2082         if (verbose>8)
2083           std::cout<<"MEDmeshEntityFamilyNumberWr tetra4 "<<nbtetra4<<":"<<
2084                 famtetra4[0]<<"..."<<famtetra4[nbtria3-1]<<" "<<std::endl;
2085         delete[] famtetra4;
2086         if (err<0) std::cerr<<"Problem MEDmeshEntityFamilyNumberWr tria3"<<std::endl;
2087       }
2088     
2089       MEDfileClose(fid); //no error
2090       //master.xml writings if mpi mode
2091       if (!for_multithread)
2092         /*oktmp=*/Write_masterxmlMEDfile();
2093       continue;       //and loop on others domains
2094
2095       erreur:         //error
2096       ok=false;
2097       MEDfileClose(fid); //but loop on others domains
2098
2099    }
2100    
2101    if (! for_multithread)
2102      MEDfileClose(fidjoint); //no error
2103    if (verbose>0)std::cout<<"\nTotalNumberOftetrahedra="<<nbtetrastotal<<std::endl;
2104    ok = true;
2105    
2106    return ok;
2107 }
2108
2109 //************************************
2110 bool ghs3dprl_mesh_wrap::idom_nodes()
2111 {
2112    bool ok=true;
2113    QString tmp,key,key1,key2,key3;
2114    CVWtab *tab,*tab1,*tab2/*,*tab3*/;
2115    med_int i,j,*arrayi;
2116    //int xx;
2117
2118       //writing node(vertices) coordinates
2119       //NBx VC=files.NoBoite Vertex Coordinates
2120       key=key.sprintf("NB%d VC",(int)idom); //files.NoBoite Vertex Coordinates
2121       tab=this->restore_key(key); //tab1=this->mestab[key1];
2122       if (!tab) {
2123          if (!for_tetrahpc) {
2124             tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".noboite";
2125             ok=this->ReadFileNOBOITE(tmp);
2126          }
2127          if (for_tetrahpc) {
2128             tmp=pathini+casename+"_out"+tmp.sprintf(format_tetra.toLatin1().constData(),idom)+".mesh";
2129             ok=this->ReadFileMESH(tmp);
2130             if (for_multithread) { // inexisting file GHS3DPRL_out.000001.global
2131                this->ReadFileDefaultGLOBAL(this->nbvert, this->nbedge, this->nbtria, this->nbtetr);
2132             }
2133          }
2134          tab=this->restore_key(key); //tab1=this->mestab[key1];
2135          if (!tab) return false;
2136       }
2137       tmp=tmp.sprintf("NB%d SN",(int)idom);
2138       //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2139       /*xx=*/this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2140       nbnodes=this->nbvert; // for current idom
2141       
2142       err=MEDmeshNodeCoordinateWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,0.,MED_FULL_INTERLACE,nbnodes,tab->tmflo);
2143       if (err<0) {std::cerr<<"Problem MEDmeshNodeCoordinateWr"<<std::endl; return false;}
2144       if (verbose>4) std::cout<<"NumberOfNodes="<<nbnodes<<std::endl;
2145
2146       //writing indices of nodes
2147       arrayi=new med_int[nbnodes];
2148       for (i=0; i<nbnodes ; i++) arrayi[i]=i+1;
2149       err=MEDmeshEntityNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodes,arrayi);
2150       delete[] arrayi;
2151       if (err<0) {std::cerr<<"Problem MEDmeshEntityNumberWr of nodes"<<std::endl; return false;}
2152
2153     // if (!for_multithread) 
2154     {
2155       key1=key1.sprintf("GL%d VE",(int)idom); //global numerotation 
2156       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2157       if (!tab1) {
2158          if (!for_tetrahpc) {
2159             tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".glo";
2160             ok=this->ReadFileGLO(tmp);
2161          }
2162          if (for_tetrahpc) {
2163             tmp=pathini+casename+"_out"+tmp.sprintf(format_tetra.toLatin1().constData(),idom)+".global";
2164             ok=this->ReadFileGLOBAL(tmp);
2165          }
2166          if (!ok) {std::cerr<<"Problem file "<<tmp.toLatin1().constData()<<std::endl; return false;}
2167          tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2168          if (!tab1) return false;
2169       }
2170       if (nbnodes!=tab1->size){std::cerr<<"Problem size GLi VE!=nbnodes!"<<std::endl; return false;}
2171
2172       key2=key2.sprintf("SKIN_VERTICES_FAMILIES"); //on global numerotation 
2173       tab2=this->restore_key(key2); //tab1=this->mestab[key1];
2174       med_int nbskin=0; 
2175       if (tab2) nbskin=tab2->size;
2176       //for (i=0; i<nbskin; i++) std::cout<<i<<" "<<tab2->tmint[i]<<std::endl;
2177
2178       //set families of nodes existing in GHS3DPRL_skin.med
2179       med_int nb=nbnodes;
2180       famnodes=new med_int[nb];
2181       for (i=0; i<nb ; i++) famnodes[i]=famallnodes;
2182       med_int * fammore=new med_int[nb];
2183       for (i=0; i<nb ; i++) fammore[i]=famnewnodes;
2184
2185       //set families of nodes of skin
2186       for (i=0; i<nb ; i++){
2187          j=tab1->tmint[i]-1; //
2188          if (j<nbskin){
2189             fammore[i]=tab2->tmint[j];
2190          }
2191       }
2192       ok=set_one_more_family(famnodes,fammore,nb);
2193       delete[] fammore;
2194
2195       //std::cout<<"nodes loc "<<i<<" = gl "<<j<<"\t << "<<tab2->tmint[j]<<
2196       //      tmp.sprintf("\t%23.15e%23.15e%23.15e",tab3->tmflo[i*3],
2197       //      tab3->tmflo[i*3+1],tab3->tmflo[i*3+2])<<std::endl;
2198
2199       //writing nodes(vertices) global numbering
2200       err=MEDmeshGlobalNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodes,tab1->tmint);
2201       if (err<0){std::cerr<<"Problem MEDmeshGlobalNumberWr nodes"<<std::endl; return false;}
2202     }
2203     
2204    return ok;
2205 }
2206
2207 //************************************
2208 /*
2209 bool ghs3dprl_mesh_wrap::set_one_more_family_old(med_int *fami, med_int *more, med_int nb)
2210 //fuse array of med_int families more et fami as kind of groups 
2211 //because there are possibilities of intersections
2212 {
2213    QString tmp;
2214    med_int i,newfam,morfam,oldfam;
2215    for (i=0; i<nb ; i++) {
2216       if (more[i]==0) continue;
2217       if (fami[i]==0) {
2218          fami[i]=more[i];
2219          //std::cout<<"sur "<<i<<" en plus "<<more[i]<<std::endl;
2220       }
2221       else { //intersection
2222          if (fami[i]==more[i]) continue; //same families
2223          oldfam=fami[i];
2224          morfam=more[i];
2225          //create new family intersection if needed
2226          newfam=families.find_family_on_groups(oldfam,morfam);
2227          //std::cout<<"oldfam "<<oldfam<<" morfam "<<morfam<<" -> newfam "<<newfam<<std::endl;
2228          fami[i]=newfam;
2229       }
2230    }
2231    return true;
2232 }*/
2233
2234 //************************************
2235 bool ghs3dprl_mesh_wrap::set_one_more_family(med_int *fami, med_int *more, med_int nb)
2236 //fuse array of med_int families more et fami as kind of groups 
2237 //because there are possibilities of intersections
2238 {
2239    QString tmp;
2240    med_int i,ii,newfam,morfam,oldfam,morfami,oldfami,i_zero,nb_fam,nb_max,nb_tot,nb_mess;
2241    med_int *newfami;
2242
2243    nb_fam=families.fam.size(); //on families negative and positive
2244    //std::cout<<"size families "<<nb_fam<<std::endl;
2245    if (nb_fam<=0) nb_fam=5;    //precaution
2246    i_zero=nb_fam*2;            //offset for negative indices of families
2247    nb_max=nb_fam*4;
2248    if (nb_fam>300) std::cout<<
2249       "***set_one_more_family*** warning many initial families could decrease speed "<<nb_fam<<std::endl;
2250    nb_tot=nb_max*nb_max;       //max oversizing *2 on families
2251    //newfami is for speed (avoid calls find_family_on_groups)
2252    //it is an array[nb_fam*4][nb_fam*4] implemented on vector[nb_max]
2253    //to memorize newfam in array[oldfam][morfam]
2254    newfami=new med_int[nb_tot];
2255    for (i=0; i<nb_tot ; i++) newfami[i]=0; //not yet met!
2256
2257    nb_mess=0;
2258    for (i=0; i<nb ; i++) {
2259       if (more[i]==0) continue;
2260       if (fami[i]==0) {
2261          fami[i]=more[i];
2262          //std::cout<<"sur "<<i<<" en plus "<<more[i]<<std::endl;
2263       }
2264       else { //intersection
2265          if (fami[i]==more[i]) continue; //same families
2266          oldfam=fami[i]; oldfami=oldfam+i_zero;
2267          morfam=more[i]; morfami=morfam+i_zero;
2268          //not yet met?
2269          ii=oldfami+morfami*nb_max; //array 2d on vector
2270          if ((ii>=0)&&(ii<nb_tot)) {
2271             newfam=newfami[ii];
2272          }
2273          else {
2274             if (nb_mess<3) {
2275                nb_mess++;
2276                std::cout<<"***set_one_more_family*** warning many new families decrease speed "<<nb_fam<<std::endl;
2277             }
2278             ii=-1;
2279             newfam=0;
2280          }
2281          if (newfam==0) {
2282             //create new family intersection if needed
2283             newfam=families.find_family_on_groups(oldfam,morfam);
2284             //std::cout<<"new oldfam "<<oldfam<<" morfam "<<morfam<<" -> newfam "<<newfam<<std::endl;
2285             if (ii>=0) newfami[ii]=newfam;
2286          }
2287          /*else {
2288             std::cout<<"!!! oldfam "<<oldfam<<" morfam "<<morfam<<" -> newfam "<<newfam<<std::endl;
2289          }*/
2290          fami[i]=newfam;
2291       }
2292    }
2293    delete[] newfami;
2294    return true;
2295 }
2296
2297 //************************************
2298 bool ghs3dprl_mesh_wrap::idom_edges()
2299 {
2300    bool ok=true;
2301    QString tmp;
2302    nbseg2=0;
2303    this->nbedge=0;
2304    return ok;
2305 }
2306
2307 //************************************
2308 bool ghs3dprl_mesh_wrap::idom_faces()
2309 {
2310    bool ok=true;
2311    QString tmp,key,key1,key2,key3;
2312    CVWtab *tab1,*tab2;
2313    med_int /*ii,*/i,j,*arrayi;
2314    //int xx;
2315
2316       //writing connectivity of faces triangles of wrap by nodes
2317    key1=key1.sprintf("FC%d",(int)idom); //files.FaCes faces (wrap and triangles only)
2318       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2319       if (!tab1) {
2320          tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".faces";
2321          ok=this->ReadFileFACES(tmp);
2322          tab1=this->restore_key(key1);
2323          if (!tab1) return false;
2324       }
2325       nbtria3=tab1->size/3;
2326       this->nbtria=nbtria3; // for current idom
2327
2328       if (verbose>4) std::cout<<"NumberOfTriangles="<<nbtria3<<std::endl;
2329       //arrayi=new med_int[nbtria3*3];
2330       //ii=0,i=0 ;
2331       //for (j=0; j<nbtria3 ; j++){
2332       //   arrayi[ii]=tab1->tmint[i]; ii++;
2333       //   arrayi[ii]=tab1->tmint[i+1]; ii++;
2334       //   arrayi[ii]=tab1->tmint[i+2]; ii++;
2335       //   i=i+7;
2336       //}
2337       //err=MEDmeshElementConnectivityWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,0.,MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,nbtria3,arrayi);
2338       err=MEDmeshElementConnectivityWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,0.,MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,nbtria3,tab1->tmint);
2339       //delete[] arrayi; //need immediately more little array
2340       if (err<0){std::cerr<<"Problem MEDmeshElementConnectivityWr for triangles connectivity"<<std::endl; return false;}
2341       
2342       //writing indices of faces triangles of wrap
2343       //caution!
2344       //generate "overlapping of numbers of elements" in "import med file" in salome
2345       //if not in "//writing indices of tetrahedra" -> arrayi[i]=!NBFACES!+i+1
2346       arrayi=new med_int[nbtria3]; 
2347       for (i=0; i<nbtria3 ; i++) arrayi[i]=nbseg2+i+1;
2348       err=MEDmeshEntityNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,nbtria3,arrayi);
2349       delete[] arrayi;
2350       if (err<0){std::cerr<<"Problem MEDmeshEntityNumberWr of triangles"<<std::endl; return false;}
2351
2352       //GLx FA=files.GLo FAces
2353       // if (!for_multithread) 
2354       {
2355         key1=key1.sprintf("GL%d FA",(int)idom);
2356         tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2357         if (nbtria3!=tab1->size){std::cerr<<"Problem size GLi FA!=nbtria3!"<<std::endl; return false;}
2358       
2359       
2360         key2=key2.sprintf("SKIN_TRIA3_FAMILIES"); //on global numerotation 
2361         tab2=this->restore_key(key2); //tab1=this->mestab[key1];
2362         med_int nbskin=0; 
2363         if (tab2) nbskin=tab2->size;
2364         
2365         //set families of faces existing in GHS3DPRL_skin.med
2366         med_int nb=nbtria3;
2367         famtria3=new med_int[nb];
2368         for (i=0; i<nb ; i++) famtria3[i]=famalltria3;
2369         med_int * fammore=new med_int[nb];
2370         for (i=0; i<nb ; i++) fammore[i]=famnewtria3;
2371
2372         //set families of faces of skin
2373         for (i=0; i<nb ; i++){
2374           j=tab1->tmint[i]-1; //
2375           if (j<nbskin){
2376               fammore[i]=tab2->tmint[j];
2377           }
2378         }
2379         ok=set_one_more_family(famtria3,fammore,nb);
2380         delete[] fammore;
2381         
2382         //writing faces(triangles) global numbering
2383         if (verbose>2)
2384           std::cout<<"CreateMEDglobalNumerotation_Faces "<<key1.toLatin1().constData()<<" "<<tab1->size<<std::endl;
2385         err=MEDmeshGlobalNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,tab1->size,tab1->tmint);
2386         if (err<0){std::cerr<<"Problem MEDmeshGlobalNumberWr faces"<<std::endl; return false;}
2387
2388         ///*xx=*/this->remove_key_mesh_wrap(QRegExp("FC*",true,true));
2389         tmp=tmp.sprintf("GL%d FA",(int)idom);
2390         //qt3 /*xx=*/this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2391         /*xx=*/this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2392         tmp=tmp.sprintf("GL%d VE",(int)idom);
2393         //qt3 /*xx=*/this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2394         /*xx=*/this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2395       }
2396
2397    return ok;
2398 }
2399
2400 //************************************
2401 bool ghs3dprl_mesh_wrap::idom_joints()
2402 {
2403    bool ok=true;
2404    QString tmp,namejoint,key,key1,key2;
2405    CVWtab *tab,*tab1,*tab2;
2406    med_int ineig,ii,jj,i,j,k,*arrayi,nb,famjoint,*inodes,*arrayfaces;
2407    med_float *arraynodes;
2408    char namejnt[MED_NAME_SIZE+1];  //no more 32
2409    char namedist[MED_NAME_SIZE+1];
2410    char descjnt[MED_COMMENT_SIZE+1];
2411    //med_int numfam_ini_wrap=100;
2412    joints_node=xmlNewNode(NULL, BAD_CAST "joints");  //masterfile.xml
2413    med_int nbjoints=0,nbnodesneig,nbtria3neig;
2414    std::string sjoints=""; //which domains are neighbourg
2415    //int xx;
2416    char dtunit[MED_SNAME_SIZE+1]="_NO_UNIT";
2417    char axisname[MED_SNAME_SIZE*3+1]="x               y               z               ";
2418    char axisunit[MED_SNAME_SIZE*3+1]="_NO_UNIT        _NO_UNIT        _NO_UNIT        ";
2419
2420       tmp=tmp.sprintf("MS%d *",(int)idom);
2421       //read file .msg if not done
2422       //qt3 if (this->nb_key_mesh_wrap(QRegExp(tmp,true,true))<=0) {
2423       if (this->nb_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp))<=0) {
2424          this->nofile=idom;
2425          
2426          if (!for_tetrahpc) {
2427             tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".msg";
2428          }
2429          if (for_tetrahpc) {
2430             tmp=pathini+casename+tmp.sprintf(format_tetra.toLatin1().constData(),idom)+".msg";
2431          }
2432
2433          ok=this->ReadFileMSGnew(tmp);
2434          if (!ok) {
2435             std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<std::endl;
2436             return false;
2437          }
2438       }
2439
2440       //writing joints
2441       for (ineig=1; ineig <= nbfilestot; ineig++) {
2442          if (idom==ineig) continue; //impossible
2443
2444          //!*************nodes
2445          //std::cout<<"\n    nodes joints\n";
2446          key1=key1.sprintf("MS%d NE%d VE SE",(int)idom,(int)ineig); //SE or RE identicals
2447          tab1=restore_key(key1);
2448          if (!tab1) continue; //case (ifile,ineig) are not neighbours=>no joints
2449          key1=key1.sprintf("MS%d NE%d VE SE",(int)ineig,(int)idom); //SE or RE identicals
2450          tab2=this->restore_key(key1);
2451          //if not yet loaded (first time) try to load necessary file msg of neighbourg
2452          if (!tab2) {
2453             
2454             if (!for_tetrahpc) {
2455                tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,ineig)+".msg";
2456             }
2457             if (for_tetrahpc) {
2458                tmp=pathini+casename+tmp.sprintf(format_tetra.toLatin1().constData(),ineig)+".msg";
2459             }
2460             
2461             this->nofile=ineig; //neighbourg file
2462             ok=this->ReadFileMSGnew(tmp);
2463             this->nofile=idom;  //restaure initial domain
2464             if (!ok) {
2465                std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<std::endl;
2466                continue;
2467             }
2468             tab2=this->restore_key(key1);
2469          }
2470          if (!tab2) std::cerr<<"Problem existing nodes joint in domain "<<idom<<
2471                           " with none in neighbourg "<<ineig<<" files .msg"<<std::endl;
2472          nb=tab1->size; nbnodesneig=tab2->size;
2473          if (nb!=nbnodesneig) {
2474             std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<
2475                   " number of nodes of joint "<<idom<<"<->"<<ineig<<" not equals"<<std::endl;
2476             continue;
2477          }
2478
2479          nbjoints++; //one more joint for this domain
2480          sjoints=sjoints+" "+i2a(ineig);
2481          if (verbose>4)
2482             std::cout<<"NumberOfNodesOfJoint_"<<idom<<"_"<<ineig<<"="<<nb<<std::endl;
2483          namejoint=namejoint.sprintf("JOINT_%d_%d_Nodes",(int)idom,(int)ineig);
2484          strcpy(namejnt,namejoint.toLatin1().constData());
2485          tmp=tmp.sprintf("JOINT_%d_%d among %ld domains of ",(int)idom,(int)ineig,nbfilestot)+nomfinal;
2486          strcpy(descjnt,tmp.toLatin1().constData());
2487          tmp=medname+tmp.sprintf("_%d",(int)ineig);
2488          strcpy(namedist,tmp.toLatin1().constData());
2489          err=MEDsubdomainJointCr(fid,nomfinal,namejnt,descjnt,ineig,namedist);
2490          if (err<0) std::cerr<<"Problem MEDsubdomainJointCr"<<std::endl;
2491
2492          famjoint=0;
2493          if (namejoint.contains(deletegroups)==0){
2494             ok=families.get_number_of_new_family(1,&famjoint,&tmp);
2495             families.add(tmp,namejoint);
2496          }
2497
2498          key=key.sprintf("NB%d VC",(int)idom); //files.NoBoite Vertex Coordinates
2499          tab=this->restore_key(key); //tab1=this->mestab[key1];
2500          nbnodes=tab->size/3;
2501
2502          //writing correspondence nodes-nodes
2503          //two indices for one correspondence
2504          arrayi=new med_int[nb*2];
2505          arraynodes=new med_float[nbnodesneig*3];  //for file DOMAIN_join.med
2506          inodes=new med_int[nbnodes];              //for file DOMAIN_join.med
2507          med_int * fammore=new med_int[nbnodes];
2508          for (i=0; i<nbnodes ; i++) {fammore[i]=0; inodes[i]=-2;}  //precautions
2509          ii=0; jj=0; k=1;
2510          for (i=0; i<nb ; i++){
2511             //no need because <send> equals <receive> tab1->tmint[i]==tab2->tmint[i]
2512             j=tab1->tmint[i]-1; //contents of tab1 1->nb, j 0->nb-1
2513             inodes[j]=k; k++;   //contents of inodes 1->n ,nodes of joint from nodes of domain
2514             arraynodes[jj]=tab->tmflo[j*3]; jj++;
2515             arraynodes[jj]=tab->tmflo[j*3+1]; jj++;
2516             arraynodes[jj]=tab->tmflo[j*3+2]; jj++;
2517
2518             fammore[j]=famjoint;
2519             arrayi[ii]=tab1->tmint[i]; ii++;
2520             arrayi[ii]=tab2->tmint[i]; ii++;
2521          }
2522          if (namejoint.contains(deletegroups)==0){
2523             ok=set_one_more_family(famnodes,fammore,nbnodes);
2524          }
2525          delete[] fammore;
2526
2527          err=MEDsubdomainCorrespondenceWr(fid,nomfinal,namejnt,MED_NO_DT,MED_NO_IT,
2528                  MED_NODE,MED_UNDEF_GEOMETRY_TYPE,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nb,arrayi);
2529          if (err<0) std::cerr<<"Problem MEDsubdomainCorrespondenceWr nodes"<<std::endl;
2530          delete[] arrayi;
2531
2532          //!*************TRIA3
2533          //writing correspondence triangles-triangles
2534          //std::cout<<"\n    faces joints\n";
2535          nbtria3neig=0;
2536          key1=key1.sprintf("MS%d NE%d FA SE",(int)idom,(int)ineig); //SE or RE identicals
2537          tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2538          if (!tab1){
2539             if (verbose>4)
2540                std::cout<<"NumberOfTrianglesOfJoint_"<<idom<<"_"<<ineig<<"=0"<<std::endl;
2541             //continue; //case (ifile,ineig) are not neighbours=>no joints
2542          }
2543          else //have to set xml may be no faces but nodes in a joint!
2544          {
2545          key1=key1.sprintf("MS%d NE%d FA SE",(int)ineig,(int)idom); //SE or RE identicals
2546          tab2=this->restore_key(key1);
2547          if (!tab2) std::cerr<<"Problem existing triangles of joint in domain "<<idom<<
2548                                " with none in neighbourg "<<ineig<<" files .msg"<<std::endl;
2549          nb=tab1->size; nbtria3neig=tab2->size;
2550          if (nb!=nbtria3neig) {
2551             std::cerr<<"Problem in file "<<tmp.toLatin1().constData()<<
2552                   " number of triangles of joint "<<idom<<"<->"<<ineig<<" not equals"<<std::endl;
2553             continue;
2554          }
2555          namejoint=namejoint.sprintf("JOINT_%d_%d_Faces",(int)idom,(int)ineig);
2556          
2557          famjoint=0;
2558          if (namejoint.contains(deletegroups)==0){
2559             ok=families.get_number_of_new_family(-1,&famjoint,&tmp);
2560             families.add(tmp,namejoint);
2561          }
2562
2563          key=key.sprintf("FC%d",(int)idom); //files.FaCes faces (wrap and triangles only)
2564          tab=this->restore_key(key); //tab1=this->mestab[key1];
2565
2566          med_int nb=tab1->size; nbtria3neig=nb;
2567          //if (verbose>=0) std::cout<<"NumberOfTrianglesOfJoint_"<<idom<<"_"<<ineig<<"="<<nb<<std::endl;
2568          arrayi=new med_int[nb*2]; //correspondance indices triangles in 2 domains
2569          arrayfaces=new med_int[nbtria3neig*3];  //for file DOMAIN_join.med
2570          for (i=0; i<nbtria3neig*3 ; i++) arrayfaces[i]=-1; //precaution
2571          fammore=new med_int[nbtria3];
2572          for (i=0; i<nbtria3 ; i++) fammore[i]=0;
2573          ii=0; jj=0;
2574          for (i=0; i<nb ; i++){
2575             arrayi[ii]=tab1->tmint[i]; ii++;
2576             arrayi[ii]=tab2->tmint[i]; ii++; //correspondance indices triangles in 2 domains
2577        
2578             fammore[tab1->tmint[i]-1]=famjoint;
2579             //famtria3[tab1->tmint[i]-1]=famjoint;
2580             
2581             k=tab1->tmint[i]-1; //indice of node connectivity
2582             //std::cout<<"k="<<k<<std::endl;
2583             k=k*7; //indice of node connectivity in tab of triangles
2584             
2585             arrayfaces[jj]=inodes[tab->tmint[k]-1]; jj++;
2586             arrayfaces[jj]=inodes[tab->tmint[k+1]-1]; jj++;
2587             arrayfaces[jj]=inodes[tab->tmint[k+2]-1]; jj++;
2588          }
2589          //int happens=0;
2590          for (i=0; i<nbtria3neig*3 ; i++) {
2591            if (arrayfaces[i]<=0) {
2592              std::cerr<<"Problem file X_joints.med unknown node in joint "<<idom<<"_"<<ineig<<" face "<<i/3+1<<std::endl; //precaution
2593              //happens=1;
2594            }
2595          }
2596          /*TODO DEBUG may be bug distene?
2597          if (happens==1) {
2598             std::cout<<"\nNumberOfTrianglesOfJoint_"<<idom<<"_"<<ineig<<"="<<nb<<std::endl;
2599             for (i=0; i<nbnodes ; i++) std::cout<<"inode i "<<i+1<<" "<<inodes[i]<<std::endl;
2600             for (i=0; i<tab1->size ; i++) std::cout<<"triangle i "<<i+1<<" "<<tab1->tmint[i]<<std::endl;
2601             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;
2602          }
2603          */
2604          if (namejoint.contains(deletegroups)==0){
2605             ok=set_one_more_family(famtria3,fammore,nbtria3);
2606          }
2607          delete[] fammore;
2608
2609          err=MEDsubdomainCorrespondenceWr(fid,nomfinal,namejnt,MED_NO_DT,MED_NO_IT,
2610                  MED_CELL,MED_TRIA3,MED_CELL,MED_TRIA3,nb,arrayi);
2611          if (err<0) std::cerr<<"Problem MEDsubdomainCorrespondenceWr triangles"<<std::endl;
2612          delete[] arrayi;
2613          }
2614
2615          //!write in file resume DOMAIN.joints.med of all joints for quick display (...may be...)
2616          if (idom<=ineig) { //no duplicate joint_1_2 and joint_2_1
2617           //create mesh
2618           namejoint=namejoint.sprintf("JOINT_%d_%d",(int)idom,(int)ineig);
2619           charendnull(namejnt,namejoint,MED_NAME_SIZE);
2620           tmp=tmp.sprintf("joint between %d and %d",(int)idom,(int)ineig);
2621           charendnull(descjnt,tmp,MED_COMMENT_SIZE);
2622           err=MEDmeshCr(fidjoint,namejnt,3,3,MED_UNSTRUCTURED_MESH,descjnt,dtunit,MED_SORT_DTIT,MED_CARTESIAN,axisname,axisunit);
2623           if (err<0) std::cerr<<"Problem MEDmeshCr "<<namejnt<<std::endl;
2624           //write nodes
2625           err=MEDmeshNodeCoordinateWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,0.,MED_FULL_INTERLACE,nbnodesneig,arraynodes);
2626           if (err<0) std::cerr<<"Problem MEDmeshNodeCoordinateWr "<<namejnt<<std::endl;
2627           arrayi=new med_int[nbnodesneig];
2628           for (i=0; i<nbnodesneig ; i++) arrayi[i]=i+1;
2629           err=MEDmeshEntityNumberWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,MED_NODE,MED_UNDEF_GEOMETRY_TYPE,nbnodesneig,arrayi);
2630           delete[] arrayi;
2631           if (err<0) std::cerr<<"Problem MEDmeshEntityNumberWr of nodes "<<namejnt<<std::endl;
2632           //families zero in file fidjoint ???
2633           //La famille FAMILLE_ZERO n'a pas été trouvée, elle est obligatoire
2634           nb=create_family_zero(fidjoint,namejnt);
2635           
2636           //write tria3
2637           if (nbtria3neig>0) {
2638            //for (i=0; i<nbtria3neig ; i++) std::cout<<i+1<<" "<<
2639            //    arrayfaces[i*3]<<" "<<arrayfaces[i*3+1]<<" "<<arrayfaces[i*3+2]<<std::endl;
2640            err=MEDmeshElementConnectivityWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,0.,
2641                    MED_CELL,MED_TRIA3,MED_NODAL,MED_FULL_INTERLACE,nbtria3neig,arrayfaces); // todo: arrayfaces may be used uninitialized
2642            if (err<0) std::cerr<<"Problem MEDmeshElementConnectivityWr for triangles connectivity "<<namejnt<<std::endl;
2643            //writing indices of faces triangles of joint
2644            arrayi=new med_int[nbtria3neig]; 
2645            for (i=0; i<nbtria3neig ; i++) arrayi[i]=i+1;
2646            err=MEDmeshEntityNumberWr(fidjoint,namejnt,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TRIA3,nbtria3neig,arrayi);
2647            delete[] arrayi;
2648            if (err<0) std::cerr<<"Problem MEDmeshEntityNumberWr of triangles "<<namejnt<<std::endl;
2649           }
2650          }
2651
2652          delete[] arraynodes;
2653          if (nbtria3neig>0) delete[] arrayfaces; // todo: arrayfaces may be used uninitialized
2654          delete[] inodes;
2655
2656          //!masterfile.xml
2657          node=xmlNewChild(joints_node, 0, BAD_CAST "joint", 0);
2658          xmlNewProp(node, BAD_CAST "id", BAD_CAST i2a(ineig).c_str());
2659          xmlNewProp(node, BAD_CAST "nodes_number", BAD_CAST i2a(nbnodesneig).c_str());
2660          xmlNewProp(node, BAD_CAST "faces_number", BAD_CAST i2a(nbtria3neig).c_str());
2661          //node2 = xmlNewChild(node, 0, BAD_CAST "nodes", 0);
2662          //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbnodesneig).c_str());
2663          //node2 = xmlNewChild(node, 0, BAD_CAST "faces", 0);
2664          //xmlNewProp(node2, BAD_CAST "number", BAD_CAST i2a(nbtria3neig).c_str());
2665       }
2666
2667    //masterfile.xml
2668    xmlNewProp(joints_node, BAD_CAST "number", BAD_CAST i2a(nbjoints).c_str());
2669    xmlNewChild(joints_node, 0, BAD_CAST "id_neighbours", BAD_CAST sjoints.substr(1).c_str());
2670    
2671    tmp=tmp.sprintf("NB%d VC",(int)idom);
2672    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2673    /*xx=*/this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2674    //tmp=tmp.sprintf("MS%d NE*",idom);
2675    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2676    ///*xx=*/this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2677    tmp=tmp.sprintf("FC%d",(int)idom);
2678    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2679    /*xx=*/this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2680    tmp=tmp.sprintf("GL%d *",(int)idom);
2681    //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2682    /*xx=*/this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2683    return ok;
2684 }
2685
2686 //************************************
2687 bool ghs3dprl_mesh_wrap::idom_tetras()
2688 {
2689    bool ok=true;
2690    QString tmp,key1;
2691    CVWtab *tab1;
2692    med_int i,*arrayi;
2693    //int xx;
2694
2695       //writing connectivity of tetrahedra by nodes
2696       key1=key1.sprintf("NB%d EV",(int)idom); //files.NoBoite Elements Vertices (tetra only)
2697       tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2698       nbtetra4=tab1->size/4;
2699       this->nbtetr=nbtetra4; // for current idom
2700
2701       nbtetrastotal=nbtetrastotal + nbtetra4;
2702       if (verbose>5)std::cout<<"NumberOftetrahedra="<<nbtetra4<<std::endl;
2703       err=MEDmeshElementConnectivityWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,0.,MED_CELL,MED_TETRA4,MED_NODAL,MED_FULL_INTERLACE,nbtetra4,tab1->tmint);
2704       if (err<0){std::cerr<<"Problem MEDmeshElementConnectivityWr for tetra connectivity"<<std::endl; return false;}
2705
2706       //writing indices of tetrahedra
2707       arrayi=new med_int[nbtetra4];
2708       for (i=0; i<nbtetra4 ; i++) arrayi[i]=nbseg2+nbtria3+i+1;
2709       //for (i=0; i<nbtria3 ; i++) std::cout<<i<<" "<<arrayi[i]<<std::endl;
2710       err=MEDmeshEntityNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TETRA4,nbtetra4,arrayi);
2711       delete[] arrayi;
2712       if (err<0){std::cerr<<"Problem MEDmeshEntityNumberWr of tetrahedra"<<std::endl; return false;}
2713
2714       famtetra4=new med_int[nbtetra4];
2715       for (i=0; i<nbtetra4 ; i++) famtetra4[i]=famnewtetra4;
2716
2717       // if (!for_multithread) 
2718       {
2719         //writing tetrahedra global numbering
2720         //GLx EL=files.GLo ELements
2721         key1=key1.sprintf("GL%d EL",(int)idom);
2722         tab1=this->restore_key(key1); //tab1=this->mestab[key1];
2723         if (!tab1) {
2724           //tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".glo";
2725           //ok=this->ReadFileGLO(tmp);
2726           //tab1=this->restore_key(key1);
2727           //if (!tab1) return false;
2728
2729           if (!for_tetrahpc) {
2730               tmp=pathini+casename+tmp.sprintf(format.toLatin1().constData(),nbfilestot,idom)+".glo";
2731               ok=this->ReadFileGLO(tmp);
2732           }
2733           if (for_tetrahpc) {
2734               tmp=pathini+casename+"_out"+tmp.sprintf(format_tetra.toLatin1().constData(),idom)+".global";
2735               ok=this->ReadFileGLOBAL(tmp);
2736           }
2737           tab1=this->restore_key(key1);
2738           if (!tab1) return false;
2739
2740         }
2741
2742         if (tab1->size!=nbtetra4){
2743           std::cerr<<"Problem incorrect size of tetrahedra global numbering"<<std::endl; return false;}
2744         if (verbose>2)
2745           std::cout<<"CreateMEDglobalNumerotation_tetrahedra "<<key1.toLatin1().constData()<<" "<<tab1->size<<std::endl;
2746         err=MEDmeshGlobalNumberWr(fid,nomfinal,MED_NO_DT,MED_NO_IT,MED_CELL,MED_TETRA4,tab1->size,tab1->tmint);
2747         if (err<0){std::cerr<<"Problem MEDmeshGlobalNumberWr tetrahedra"<<std::endl; return false;}
2748       }
2749
2750       tmp=tmp.sprintf("NB%d EV", (int)idom);
2751       //qt3 xx=this->remove_key_mesh_wrap(QRegExp(tmp,true,true));
2752       /*xx=*/this->remove_key_mesh_wrap(QRegExp(tmp,Qt::CaseSensitive,QRegExp::RegExp));
2753    return ok;
2754 }
2755
2756 //************************************
2757 med_int ghs3dprl_mesh_wrap::create_families(med_idt fid, int sign)
2758 //if sign < 0 families faces or tria3 etc...
2759 //if sign >= 0 family zero and family nodes
2760 {
2761    med_int pas,ires;
2762    char nomfam[MED_NAME_SIZE+1];  //it.current()->name;
2763    //char attdes[MED_COMMENT_SIZE+1]="_NO_DESCRIPTION";
2764    char *gro;
2765    med_int i,/*attide=1,*//*attval=1,*//*natt=1,*/num,ngro;
2766    
2767    if (sign>=0) pas=1; else pas=-1;
2768    ires=0;
2769    fend gb;
2770    fagr::iterator it1;
2771    fend::iterator it2;
2772    for (it1=families.fam.begin(); it1!=families.fam.end(); ++it1){
2773       num=(*it1).first.toLong();
2774       if ((pas==-1) && (num>=0)) continue; //not good families
2775       if ((pas== 1) && (num< 0)) continue; //not good families
2776       charendnull(nomfam,(*it1).first,MED_NAME_SIZE);
2777       ires++;
2778       //med_int natt=0;
2779       ngro=(*it1).second.size();
2780       if (verbose>5) 
2781          std::cout<<"CreateFamilyInMEDFile <"<<nomfam<<">\tNbGroups="<<ngro;
2782       gro=new char[MED_LNAME_SIZE*ngro+2];
2783       gb=(*it1).second;
2784       i=0;
2785       for (it2=gb.begin(); it2!=gb.end(); ++it2){
2786          charendnull(&gro[i*MED_LNAME_SIZE],(*it2).first,MED_LNAME_SIZE);
2787          if (verbose>5)std::cout<<" <"<<&gro[i*MED_LNAME_SIZE]<<"> ";
2788          i++;
2789       }
2790       if (verbose>5)std::cout<<std::endl;
2791       err=MEDfamilyCr(fid,nomfinal,nomfam,num,ngro,gro);
2792       delete[] gro;
2793       if (err<0) std::cerr<<"Problem MEDfamilyCr of "<<nomfam<<std::endl;
2794    }
2795    return ires;
2796 }
2797
2798 med_int ghs3dprl_mesh_wrap::create_family_zero(med_idt fid, QString nameMesh)
2799 {
2800    med_int /*pas,*/ires;
2801    ires=0;
2802    char nomfam[MED_NAME_SIZE+1]="FAMILLE_ZERO";  //it.current()->name;
2803    //char attdes[MED_COMMENT_SIZE+1]="_NO_DESCRIPTION";
2804    
2805    char *gro;
2806    med_int /*attide=1,*//*attval=1,*//*natt=1,*/num=0,ngro=0;
2807    
2808    gro=new char[MED_LNAME_SIZE*ngro+2];
2809    if (verbose>3)std::cout<<"\ncreate_family_ZERO "<<nameMesh.toLatin1().constData()<<std::endl;
2810    err=MEDfamilyCr(fid,nameMesh.toLatin1().constData(),nomfam,num,ngro,gro);
2811    if (err<0) std::cerr<<"Problem MEDfamilyCr FAMILLE_ZERO of "<<nameMesh.toLatin1().constData()<<std::endl;
2812    delete[] gro;
2813    return ires;
2814 }
2815
2816
2817