Salome HOME
Replace oe by ?
[modules/smesh.git] / src / Tools / MeshCut / MeshCut_Maillage.cxx
1 #include "MeshCut_Maillage.hxx"
2 #include "MeshCut_Cube.hxx"
3
4 #include <iostream>
5 #include <sstream>
6 #include <list>
7 #include <algorithm>
8 #include <cmath>
9 #include <cstring>
10
11 using namespace MESHCUT;
12 using namespace std;
13
14 Maillage::Maillage(std::string _ID)
15 {
16   ID = _ID;
17   nombreNoeudsMaillage = 0;
18   nombreMaillesMaillage = 0;
19   //nPOI1=0; nSEG2=0; nSEG3=0; nTRIA3=0; nTRIA6=0; nQUAD4=0; nQUAD8=0; nTETRA4=0; nTETRA10=0; nPYRAM5=0; nPYRAM13=0; nPENTA6=0; nPENTA15=0; nHEXA8=0; nHEXA20=0;
20   GM.clear();
21   GN.clear();
22   for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
23     EFFECTIFS_TYPES[(TYPE_MAILLE) itm] = 0;
24 }
25
26 Maillage::~Maillage()
27 {
28 }
29
30 void Maillage::creationGMtype(TYPE_MAILLE tm, std::string nomGMtype)
31 {
32   //cout << "Creation GM type, groupe " << nomGMtype << endl;
33   for (int nl = 0; nl < EFFECTIFS_TYPES[tm]; nl++)
34     GM[nomGMtype][tm].push_back(nl);
35   GM[nomGMtype][tm].resize(EFFECTIFS_TYPES[tm]);
36   sort(GM[nomGMtype][tm].begin(), GM[nomGMtype][tm].end());
37 }
38
39 void Maillage::afficheMailles(TYPE_MAILLE tm)
40 {
41   cout << "Affichage des mailles du type " << TM2string(tm) << " (effectif " << EFFECTIFS_TYPES[tm] << "): " << endl;
42   if (EFFECTIFS_TYPES[tm])
43     {
44       // Boucle sur les connectivités d'un type tm
45       int nnoeuds = Nnoeuds(tm);
46       for (int i = 0; i < EFFECTIFS_TYPES[tm]; i++)
47         {
48           cout << "\tMaille " << i << " :" << endl;
49           //Boucle sur les noeuds de la maille de numéro local i dans le type tm
50           int * offset = CNX[tm] + nnoeuds * i;
51           for (int j = 0; j < nnoeuds; j++)
52             {
53               int ngnoeud = *(offset + j);
54               //cout << "\t\t" << X[ngnoeud-1] << " " << Y[ngnoeud-1] << " " << Z[ngnoeud-1] << endl;
55               cout << "\t" << ngnoeud << "\t" << *(XX + ngnoeud - 1) << " " << *(YY + ngnoeud - 1) << " " << *(ZZ + ngnoeud - 1) << endl;
56             }
57         }
58       cout << endl;
59     }
60 }
61
62 void Maillage::listeMaillesType(TYPE_MAILLE tm)
63 {
64   cout << "La fonction \"Restitution des mailles par type\" est obsolète " << endl;
65
66   //  cout << "Restitution des mailles du type " << TM2string(tm) << " (effectif " << EFFECTIFS_TYPES[tm] << "): " << endl;
67   //  if (EFFECTIFS_TYPES[tm])
68   //    for (int i = 0; i < IDS_MAILLES[tm].size(); i++)
69   //      cout << IDS_MAILLES[tm][i] << " ";
70   //  cout << endl;
71 }
72
73 void Maillage::listeMaillesTousTypes()
74 {
75   for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
76     {
77       TYPE_MAILLE tm = (TYPE_MAILLE) itm;
78       listeMaillesType(tm);
79     }
80 }
81
82 void Maillage::listeMaillesParGM()
83 {
84   cout << "Liste des mailles par GM : " << endl;
85   for (map<string, map<TYPE_MAILLE, vector<int> > >::iterator I = GM.begin(); I != GM.end(); I++)
86     listeMaillesGM(I->first);
87 }
88
89 void Maillage::listeMaillesGM(std::string nomGM)
90 {
91   cout << "Liste des mailles du groupe " << nomGM << " : " << endl;
92   for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
93     {
94       TYPE_MAILLE tm = (TYPE_MAILLE) itm;
95       if (GM[nomGM][tm].size())
96         {
97           cout << "\t" << TM2string(tm) << " : ";
98           for (unsigned int j = 0; j < GM[nomGM][tm].size(); j++)
99             cout << GM[nomGM][tm][j] << " ";
100           cout << endl;
101         }
102     }
103 }
104
105 //void Maillage::listeMaillesGMordonne(std::string nomGM)
106 //{
107 //  cout << "Liste ordonnée des mailles du groupe " << nomGM << " (" << GM[nomGM].size() << " mailles) : ";
108 //  sort(GM[nomGM].begin(), GM[nomGM].end());
109 //  for (int j = 0; j < GM[nomGM].size(); j++)
110 //    cout << GM[nomGM][j] << " ";
111 //  cout << endl;
112 //}
113
114 void Maillage::listeNoeuds()
115 {
116   cout << "Liste des noeuds du maillage : " << endl;
117   for (int i = 0; i < nombreNoeudsMaillage; i++)
118     cout << "\t" << *(XX + i) << " " << *(YY + i) << " " << *(ZZ + i) << endl;
119   cout << endl;
120 }
121
122 void Maillage::listeNoeudsGN(std::string nomGN)
123 {
124   cout << "Liste brute des noeuds du groupe " << nomGN << " (" << GN[nomGN].size() << " noeuds) : ";
125   for (unsigned int j = 0; j < GN[nomGN].size(); j++)
126     cout << GN[nomGN][j] << " ";
127   cout << endl;
128 }
129
130 void Maillage::listeNoeudsGNordonne(std::string nomGN)
131 {
132   cout << "Liste ordonnée des noeuds du groupe " << nomGN << " (" << GN[nomGN].size() << " noeuds) : ";
133   sort(GN[nomGN].begin(), GN[nomGN].end());
134   for (unsigned int j = 0; j < GN[nomGN].size(); j++)
135     cout << GN[nomGN][j] << " ";
136   cout << endl;
137 }
138
139 std::vector<float> Maillage::G(int i, TYPE_MAILLE tm)
140 {
141   vector<float> G;
142   float x = 0.0;
143   float y = 0.0;
144   float z = 0.0;
145   int nn = NnoeudsGeom(tm);
146   for (int j = 0; j < nn; j++)
147     {
148       int ng = CNX[tm][nn * i + j];
149       x += XX[ng - 1];
150       y += YY[ng - 1];
151       z += ZZ[ng - 1];
152     }
153   G.push_back(x / nn);
154   G.push_back(y / nn);
155   G.push_back(z / nn);
156   G.resize(3);
157   return G;
158 }
159
160 float Maillage::distanceNoeudMaille(int ngnoeud, int imaille, TYPE_MAILLE tm)
161 {
162   float x, y, z;
163   float x0 = XX[ngnoeud - 1];
164   float y0 = YY[ngnoeud - 1];
165   float z0 = ZZ[ngnoeud - 1];
166   int nn = NnoeudsGeom(tm);
167   float d1 = 1000000000000.0;
168   float d;
169   for (int j = 0; j < nn; j++)
170     {
171       int ng = CNX[tm][nn * imaille + j]; // Noeud courant dans la maille
172       x = XX[ng - 1];
173       y = YY[ng - 1];
174       z = ZZ[ng - 1];
175       d = sqrt((x - x0) * (x - x0) + (y - y0) * (y - y0) + (z - z0) * (z - z0));
176       if (d < d1)
177         d1 = d;
178     }
179   return d1;
180 }
181
182 /*!
183  *  Retourne le ng du noeud le plus proche de ngnoeud dans la maille imaille du type tm
184  */
185 int Maillage::noeudVoisin(int ngnoeud, int imaille, TYPE_MAILLE tm)
186 {
187   float x, y, z;
188   int ngv;
189   float x0 = XX[ngnoeud - 1];
190   float y0 = YY[ngnoeud - 1];
191   float z0 = ZZ[ngnoeud - 1];
192   int nn = NnoeudsGeom(tm);
193   float d1 = 1000000000000.0;
194   float d;
195   for (int j = 0; j < nn; j++)
196     {
197       int ng = CNX[tm][nn * imaille + j]; // Noeud courant dans la maille
198       x = XX[ng - 1];
199       y = YY[ng - 1];
200       z = ZZ[ng - 1];
201       d = sqrt((x - x0) * (x - x0) + (y - y0) * (y - y0) + (z - z0) * (z - z0));
202       if (d < d1)
203         {
204           d1 = d;
205           ngv = ng;
206         }
207     }
208   return ngv;
209 }
210
211 float Maillage::distanceNoeudNoeud(int ng1, int ng2)
212 {
213   float x1, x2, y1, y2, z1, z2;
214   x1 = XX[ng1 - 1];
215   y1 = YY[ng1 - 1];
216   z1 = ZZ[ng1 - 1];
217   x2 = XX[ng2 - 1];
218   y2 = YY[ng2 - 1];
219   z2 = ZZ[ng2 - 1];
220   return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2));
221 }
222
223 //void Maillage::encombrements()
224 //{
225 //  float ex = 0.0;
226 //  float ey = 0.0;
227 //  float ez = 0.0;
228 //
229 //  for (int itm = (int) SEG2; itm <= (int) HEXA20; itm++)
230 //    {
231 //      TYPE_MAILLE tm = (TYPE_MAILLE) itm;
232 //      if (MAILLAGE->EFFECTIFS_TYPES[tm])
233 //        {
234 //          int nnoeuds = Nnoeuds(tm);
235 //          for (int i = 0; i < CON[tm].size() / nnoeuds; i++)
236 //            {
237 //              //Boucle sur les noeuds de la maille de numéro local i dans le type tm
238 //              for (int j = 0; j < nnoeuds; j++)
239 //                {
240 //                  //..... CON[tm][nnoeuds*i+j];
241 //                }
242 //            }
243 //        }
244 //    }
245 //  // Boucle sur les connectivités d'un type tm
246 //}
247
248 void Maillage::inputMED(std::string fichierMED)
249 {
250   //cout << endl << "Début procédure inputMED, fichier "<< fichierMED << endl;
251
252   //  int i, j, k, ichamp, igauss, ipt, ival;
253   int j;
254   //  med_err ret = 0; // Code retour
255   med_idt fid; // Descripteur de fichier MED
256   char maa[MED_NAME_SIZE + 1]; // nom du maillage de longueur maxi MED_NAME_SIZE
257   med_int spacedim;
258   med_int mdim; // Dimension du maillage
259   med_mesh_type type;
260   char desc[MED_COMMENT_SIZE + 1]; // Description du maillage
261
262   // Profils
263   //  med_int nprofils;
264   //  int iprofil;
265   //  char nomprofil[MED_NAME_SIZE + 1] = "";
266   //  med_int nvalprofil, nvalprofil2;
267   //  med_int *pflval;
268
269   // Champs
270   //  med_int nChamps, nCompChamp, nval;
271   //  char *compChamp, *unitChamp, *nomChamp;
272   //char nomChamp [ MED_NAME_SIZE+1 ] = "";
273   //  med_field_type typeChamp;
274   //  med_int nGauss, ngpdt, numdt, numo;
275   med_int nPasTemps;
276   //  char locname[MED_NAME_SIZE + 1] = "";
277   //  med_geometry_type type_geo;
278   //  med_int ngauss;
279   char dtunit[MED_SNAME_SIZE + 1] = "";
280   //  med_float dt = 0.0;
281   //  med_bool local;
282   //  med_int nbrefmaa;
283
284   med_sorting_type sortingtype;
285   med_axis_type axistype;
286
287   // Initialisations
288   FAMILLES.clear();
289   FAM_TYPES.clear();
290   FAMILLES_NOEUDS.clear();
291   GROUPES_MAILLES.clear();
292   GROUPES_NOEUDS.clear();
293   RESIDU.clear(); // Sera initialisé à 1 par la routine acquisitionTYPE_inputMED
294   tailleFAMILLES.clear();
295   tailleGROUPES.clear();
296
297   // Ouverture du fichier MED en lecture seule
298   fid = MEDfileOpen(string2char(fichierMED), MED_ACC_RDONLY);
299   if (fid < 0)
300     {
301       ERREUR("Erreur a l'ouverture du fichier\n");
302     }
303   //cout << chrono() << " --- inputMED: MEDfileOpen: ouverture du maillage en lecture seule, OK" << endl;
304
305   // Lecture des infos concernant le premier maillage
306   if (MEDmeshInfo(fid, 1, maa, &spacedim, &mdim, &type, desc, dtunit, &sortingtype, &nPasTemps, &axistype, axisname,
307                   unitname) < 0)
308     ERREUR("Erreur a la lecture des informations sur le maillage ");
309   //cout << chrono() << " --- inputMED: MEDmeshInfo: OK" << endl;
310
311   cerr << "maa=" << maa << endl;
312   cerr << "spacedim=" << spacedim << endl;
313   cerr << "mdim=" << mdim << endl;
314   cerr << "type=" << type << endl;
315   cerr << "desc=" << desc << endl;
316   cerr << "dtunit=" << dtunit << endl;
317   cerr << "sortingtype=" << sortingtype << endl;
318   cerr << "nPasTemps=" << nPasTemps << endl;
319   cerr << "axistype=" << axistype << endl;
320   cerr << "axisname=" << axisname << endl;
321   cerr << "unitname=" << unitname << endl;
322
323   dimensionMaillage = mdim;
324   dimensionEspace = spacedim;
325
326   ID = (string) maa;
327
328   //  nGauss = MEDnGauss(fid);
329   //  if (debug > 0)
330   //    cout << "Nombre d'éléments portant des points de Gauss: " << (int) nGauss << endl;
331   //  map<string, int> REFGAUSS;
332   //  map<string, int>::iterator iterGAUSS;
333   //  for (igauss = 1; igauss <= nGauss; igauss++)
334   //    {
335   //      if (MEDgaussInfo(fid, igauss, locname, &type_geo, &ngauss) < 0)
336   //        ERREUR("Erreur MEDgaussInfo");
337   //      if (debug == 2)
338   //        {
339   //          cout << endl << "  Retour MEDgaussInfo, localisation gauss n°" << igauss << " : " << endl;
340   //          cout << "    locname  = " << locname << endl;
341   //          cout << "    type_geo = " << type_geo << endl;
342   //          cout << "    ngauss   = " << ngauss << endl;
343   //          cout << endl;
344   //        }
345   //      REFGAUSS[(string) locname] = (int) ngauss;
346   //    }
347   //
348   //  if (debug == 2)
349   //    {
350   //      cout << endl << "Restitution de la table REFGAUSS:" << endl;
351   //      for (iterGAUSS = REFGAUSS.begin(); iterGAUSS != REFGAUSS.end(); iterGAUSS++)
352   //        {
353   //          cout << iterGAUSS->first << " : " << iterGAUSS->second << endl;
354   //        }
355   //    }
356   //
357   //  nprofils = MEDnProfil(fid);
358   //  if (debug)
359   //    cout << endl << endl << "Nombre de profils: " << nprofils << endl;
360   //  for (iprofil = 1; iprofil <= nprofils; iprofil++)
361   //    {
362   //      if (MEDprofilInfo(fid, iprofil, nomprofil, &nvalprofil) < 0)
363   //        ERREUR("ERREUR MEDprofilInfo");
364   //      nvalprofil2 = MEDnValProfil(fid, nomprofil);
365   //      if (debug == 2)
366   //        {
367   //          cout << "Profil " << iprofil << " : " << endl;
368   //          cout << "    Nom profil : " << nomprofil << endl;
369   //          cout << "    Nombre de valeurs profil (par MEDprofilInfo) : " << nvalprofil << endl;
370   //          cout << "    Nombre de valeurs profil (par MEDnValProfil) : " << nvalprofil2 << endl;
371   //        }
372   //      if (nvalprofil != nvalprofil2)
373   //        ERREUR("Discordance nvalprofil (entre MEDprofilInfo et MEDnValProfil)");
374   //      pflval = (med_int*) malloc(sizeof(med_int) * nvalprofil);
375   //      if (MEDprofilLire(fid, pflval, nomprofil) < 0)
376   //        ERREUR("ERREUR MEDprofilLire");
377   //      //cout << "    Affichage des 100 premières valeurs:" << endl;
378   //      //for (ival=0;ival<min(100,nvalprofil);ival++) cout << " " << *(pflval+ival) ;
379   //      free(pflval);
380   //    }
381   //
382   //  nChamps = MEDnChamp(fid, 0);
383   //  cout << "Nombre de champs : " << (int) nChamps << endl;
384   //
385   //  if (nChamps > 0)
386   //    {
387   //
388   //      for (ichamp = 1; ichamp <= nChamps; ichamp++)
389   //        {
390   //          //for (ichamp=4; ichamp<=4; ichamp++ ) {
391   //          cout << endl << endl;
392   //          cout << endl << endl << " ====================================================================" << endl;
393   //          cout << endl << endl << "                             CHAMP " << ichamp << endl;
394   //          cout << endl << endl << " ====================================================================" << endl;
395   //          cout << endl << endl;
396   //
397   //          nCompChamp = MEDnChamp(fid, ichamp);
398   //          if (nCompChamp < 0)
399   //            ERREUR("Erreur Ncomposantes champ");
400   //          cout << "Nombre de composantes du champ " << ichamp << " : " << (int) nCompChamp << endl;
401   //
402   //          nomChamp = (char*) malloc(MED_NAME_SIZE + 1);
403   //          compChamp = (char*) malloc(nCompChamp * MED_SNAME_SIZE + 1);
404   //          unitChamp = (char*) malloc(nCompChamp * MED_SNAME_SIZE + 1);
405   //
406   //          if (MEDchampInfo(fid, ichamp, nomChamp, &typeChamp, compChamp, unitChamp, nCompChamp) < 0)
407   //            ERREUR("Erreur MEDchampInfo");
408   //
409   //          cout << "Infos sur le champ " << ichamp << " : " << endl;
410   //          cout << "  Nom:  " << (string) nomChamp << endl;
411   //          cout << "  Type:  " << typeChamp << endl;
412   //          cout << "  Noms des composantes:  " << (string) compChamp << endl;
413   //          cout << "  Unités des composantes:  " << (string) unitChamp << endl;
414   //
415   //          infoChamps((string) "NOEUDS", MED_NODE, MED_NONE, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
416   //          infoChamps((string) "POI1", MED_CELL, MED_POINT1, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
417   //          infoChamps((string) "SEG2", MED_CELL, MED_SEG2, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
418   //          infoChamps((string) "SEG3", MED_CELL, MED_SEG3, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
419   //          infoChamps((string) "TRIA3", MED_CELL, MED_TRIA3, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
420   //          infoChamps((string) "TRIA6", MED_CELL, MED_TRIA6, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
421   //          infoChamps((string) "QUAD4", MED_CELL, MED_QUAD4, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
422   //          infoChamps((string) "QUAD8", MED_CELL, MED_QUAD8, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
423   //          infoChamps((string) "TETRA4", MED_CELL, MED_TETRA4, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
424   //          infoChamps((string) "TETRA10", MED_CELL, MED_TETRA10, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
425   //          infoChamps((string) "PYRAM5", MED_CELL, MED_PYRA5, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
426   //          infoChamps((string) "PYRAM13", MED_CELL, MED_PYRA13, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
427   //          infoChamps((string) "PENTA6", MED_CELL, MED_PENTA6, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
428   //          infoChamps((string) "PENTA15", MED_CELL, MED_PENTA15, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
429   //          infoChamps((string) "HEXA8", MED_CELL, MED_HEXA8, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
430   //          infoChamps((string) "HEXA20", MED_CELL, MED_HEXA20, fid, maa, nomChamp, typeChamp, nCompChamp, REFGAUSS);
431   //
432   //        }
433   //
434   //      cout << endl << "Rappel des codes de géométries: " << endl;
435   //      cout << " TETRA4 = " << MED_TETRA4 << endl;
436   //      cout << " PENTA6 = " << MED_PENTA6 << endl;
437   //      cout << " HEXA8 = " << MED_HEXA8 << endl;
438   //
439   //    }
440   //  else
441   //    cout << "Pas de champs dans ce maillage" << endl;
442
443   // ##################################################################################################
444   // ##################################################################################################
445   //
446   //                  A C Q U I S I T I O N     D E S     F A M I L L E S
447   //
448   // ##################################################################################################
449   // ##################################################################################################
450
451
452   med_int nFamilles;
453   char nomGroupeChar[MED_LNAME_SIZE + 1];
454   if ((nFamilles = MEDnFamily(fid, maa)) < 0)
455     ERREUR("ERREUR MEDnFamily");
456
457   // Initialisation des tailles:   tailleFAMILLES  et  tailleGROUPES
458
459   //   for (int i = 0; i < nFamilles; i++)
460   //    {
461   //      char nomfam[MED_NAME_SIZE + 1];
462   //      char *attdes, *gro;
463   //      med_int numfam, *attide, *attval, natt, ngro;
464   //
465   //      if ((ngro = MEDnFamilyGroup(fid, maa, i + 1)) < 0)
466   //        ERREUR("ERREUR MEDnFamilyGroup");
467   //      if ((natt = MEDnFamily23Attribute(fid, maa, i + 1)) < 0)
468   //        ERREUR("ERREUR MEDnFamily23Attribute");
469   //
470   //      attide = (med_int *) malloc(sizeof(med_int) * natt);
471   //      attval = (med_int *) malloc(sizeof(med_int) * natt);
472   //      attdes = (char *) malloc(MED_COMMENT_SIZE * natt + 1);
473   //      gro = (char *) malloc(MED_LNAME_SIZE * ngro + 1);
474   //
475   //      if (MEDfamilyInfo(fid, maa, (med_int)(i + 1), nomfam, &numfam, attide, attval, attdes, &natt, gro, &ngro) < 0)
476   //        ERREUR("ERREUR MEDfamilyInfo");
477   //
478   //      free(attide);
479   //      free(attval);
480   //      free(attdes);
481   //      free(gro);
482   //    }
483
484   for (int i = 0; i < nFamilles; i++)
485     {
486       char nomfam[MED_NAME_SIZE + 1];
487       char *attdes, *gro;
488       med_int numfam, *attide, *attval, natt, ngro;
489
490       if ((ngro = MEDnFamilyGroup(fid, maa, i + 1)) < 0)
491         ERREUR("ERREUR MEDnFamilyGroup");
492       if ((natt = MEDnFamily23Attribute(fid, maa, i + 1)) < 0)
493         ERREUR("ERREUR MEDnFamily23Attribute");
494
495       attide = (med_int *) malloc(sizeof(med_int) * natt);
496       attval = (med_int *) malloc(sizeof(med_int) * natt);
497       attdes = (char *) malloc(MED_COMMENT_SIZE * natt + 1);
498       gro = (char *) malloc(MED_LNAME_SIZE * ngro + 1);
499
500       if (MEDfamilyInfo(fid, maa, (med_int) (i + 1), nomfam, &numfam, gro) < 0)
501         ERREUR("ERREUR MEDfamilyInfo");
502
503       for (int ig = 1; ig <= ngro; ig++)
504         {
505           for (j = 0; j < MED_LNAME_SIZE; j++)
506             nomGroupeChar[j] = gro[(ig - 1) * MED_LNAME_SIZE + j];
507           nomGroupeChar[MED_LNAME_SIZE] = '\0';
508           //cout << "Groupe lu : " << (string)nomGroupeChar << endl;
509           tailleGROUPES[strip((string) nomGroupeChar)]++;
510           if (numfam > 0)
511             GROUPES_NOEUDS[strip((string) nomGroupeChar)].push_back((int) numfam);
512           else if (numfam < 0)
513             GROUPES_MAILLES[strip((string) nomGroupeChar)].push_back((int) numfam);
514         }
515
516       free(attide);
517       free(attval);
518       free(attdes);
519       free(gro);
520     }
521
522   // ##################################################################################################
523   // ##################################################################################################
524   //
525   //                  A C Q U I S I T I O N     D E S     N O E U D S
526   //
527   // ##################################################################################################
528   // ##################################################################################################
529
530   //  class Noeud *n;
531   //  list<Noeud*> listeNoeuds;
532   //  float x, y, z, rx, ry, rz, tx, ty, tz;
533   string line, IDnoeud;
534   float x0, x1, y0, y1, z0, z1;
535
536   vector<int> RESIDU_NOEUDS; // Table de vérité du résidu des noeuds
537
538   ostringstream OSCOORD;
539
540   med_int nnoe = 0; // Nbre de noeuds
541   med_float *coo1; // Table des coordonnées
542   //  char nomcoo[mdim * MED_SNAME_SIZE + 1]; // Table des noms des coordonnées
543   //  char unicoo[mdim * MED_SNAME_SIZE + 1]; // Table des unités des coordonnées
544   char *nomnoe;
545
546   med_int *numnoe;
547   med_int *nufano;
548   //  med_grid_type rep;
549   //  med_bool inonoe, inunoe;
550   //  med_int profil[2] = { 2, 3 };
551   med_bool coordinatechangement;
552   med_bool geotransformation;
553
554   // Combien de noeuds a lire ?
555   nnoe = MEDmeshnEntity(fid, maa, MED_NO_DT, MED_NO_IT, MED_NODE, MED_NO_GEOTYPE, MED_COORDINATE, MED_NO_CMODE,
556                         &coordinatechangement, &geotransformation);
557
558   if (nnoe < 0)
559     ERREUR("Erreur a la lecture du nombre de noeuds");
560
561   nombreNoeudsMaillage = nnoe;
562
563   // Lecture des familles des noeuds
564   med_int *famNoeuds = (med_int*) malloc(sizeof(med_int) * nnoe);
565   if (nnoe > 0)
566     {
567       if (MEDmeshEntityFamilyNumberRd(fid, maa, MED_NO_DT, MED_NO_IT, MED_NODE, MED_NONE, famNoeuds) < 0)
568         ERREUR("Erreur a la lecture des familles de noeuds (MEDmeshEntityFamilyNumberRd)");
569     }
570
571   /* Allocations memoires */
572   if (nnoe > 0)
573     {
574       // table des coordonnees - profil : (dimension * nombre de noeuds )
575       coo1 = (med_float*) calloc(nnoe * mdim, sizeof(med_float));
576       // table des des numeros, des numeros de familles des noeuds - profil : (nombre de noeuds)
577       numnoe = (med_int*) malloc(sizeof(med_int) * nnoe);
578       nufano = (med_int*) malloc(sizeof(med_int) * nnoe);
579       // table des noms des noeuds - profil : (nnoe*MED_SNAME_SIZE+1)
580       nomnoe = (char*) malloc(MED_SNAME_SIZE * nnoe + 1);
581     }
582
583   // Lecture des composantes des coordonnees des noeuds
584   if (nnoe > 0)
585     if (MEDmeshNodeCoordinateRd(fid, maa, MED_NO_DT, MED_NO_IT, MED_FULL_INTERLACE, coo1) < 0)
586       ERREUR("Erreur a la lecture des coordonnees des noeuds");
587
588   //   // Les noeuds ont-ils un nom? un numéro?
589   //  if (nnoe > 0)
590   //    {
591   //      if (MEDnomLire(fid, maa, nomnoe, nnoe, MED_NODE, (med_geometry_type) 0) < 0)
592   //        inonoe = MED_FALSE;
593   //      else
594   //        inonoe = MED_TRUE;
595   //      if (MEDnumLire(fid, maa, numnoe, nnoe, MED_NODE, (med_geometry_type) 0) < 0)
596   //        inunoe = MED_FALSE;
597   //      else
598   //        inunoe = MED_TRUE;
599   //    }
600   //
601   //  if (inonoe)
602   //    cout << "WARNING input MED : les noms des noeuds sont ignorés" << endl;
603   //  if (inunoe)
604   //    cout << "WARNING input MED : les numéros des noeuds sont ignorés" << endl;
605   //
606   //  if (inonoe)
607   //    {
608   //      char str[MED_SNAME_SIZE + 1];
609   //      for (int inoeud = 0; inoeud < nnoe; inoeud++)
610   //        {
611   //          strncpy(str, nomnoe + inoeud * MED_SNAME_SIZE, MED_SNAME_SIZE);
612   //          str[MED_SNAME_SIZE] = '\0';
613   //          IDS_NOEUDS.push_back((string) str);
614   //        }
615   //    }
616   //  else if (inunoe)
617   //    {
618   //      for (int inoeud = 0; inoeud < nnoe; inoeud++)
619   //        {
620   //          int numnoeud = *(numnoe + inoeud);
621   //          IDS_NOEUDS.push_back((string) "N" + int2string(numnoeud));
622   //        }
623   //    }
624   //  else
625   //    for (int inoeud = 0; inoeud < nnoe; inoeud++)
626   //      IDS_NOEUDS.push_back((string) "N" + int2string(inoeud + 1));
627   //  IDS_NOEUDS.resize(nnoe);
628
629   /* ====================================================================== */
630   /*               BOUCLE SUR LES NOEUDS LUS DANS LE FICHIER MED            */
631   /* ====================================================================== */
632
633   //  X.resize(nnoe);
634   //  Y.resize(nnoe);
635   //  Z.resize(nnoe);
636
637   // Initialisation de l'enveloppe
638   x0 = coo1[0];
639   x1 = coo1[0];
640   y0 = coo1[1];
641   y1 = coo1[1];
642   if (mdim == 3)
643     {
644       z0 = coo1[2];
645       z1 = coo1[2];
646     }
647   else
648     {
649       z0 = 0.0;
650       z1 = 0.0;
651     }
652
653   // Allocation mémoire pour les coordonnées XX YY ZZ
654   XX = (float*) malloc(sizeof(float) * nombreNoeudsMaillage);
655   if (mdim > 1)
656     YY = (float*) malloc(sizeof(float) * nombreNoeudsMaillage);
657   if (mdim > 2)
658     ZZ = (float*) malloc(sizeof(float) * nombreNoeudsMaillage);
659
660   for (int i = 0; i < nnoe; i++)
661     {
662
663       // Chargement des coordonnées X, Y et Z
664       // Calcul de l'enveloppe du maillage
665
666       FAMILLES_NOEUDS[*(famNoeuds + i)].push_back(i + 1); // ATTENTION! Les num. de noeuds commencent à 1
667       tailleFAMILLES[*(famNoeuds + i)]++;
668
669       // IDnoeud = "N"+int2string(i+1);
670
671       float * XXi = XX + i;
672       float * YYi = YY + i;
673       float * ZZi = ZZ + i;
674
675       if (mdim == 3)
676         {
677           *XXi = (float) coo1[3 * i];
678           *YYi = (float) coo1[3 * i + 1];
679           *ZZi = (float) coo1[3 * i + 2];
680           if (*XXi < x0)
681             x0 = *XXi;
682           else if (*XXi > x1)
683             x1 = *XXi;
684           if (*YYi < y0)
685             y0 = *YYi;
686           else if (*YYi > y1)
687             y1 = *YYi;
688           if (*ZZi < z0)
689             z0 = *ZZi;
690           else if (*ZZi > z1)
691             z1 = *ZZi;
692         }
693       else if (mdim == 2)
694         {
695           *XXi = (float) coo1[2 * i];
696           *YYi = (float) coo1[2 * i + 1];
697           if (*XXi < x0)
698             x0 = *XXi;
699           else if (*XXi > x1)
700             x1 = *XXi;
701           if (*YYi < y0)
702             y0 = *YYi;
703           else if (*YYi > y1)
704             y1 = *YYi;
705         }
706       else if (mdim == 1)
707         {
708           *XXi = (float) coo1[1 * i];
709           if (*XXi < x0)
710             x0 = *XXi;
711           else if (*XXi > x1)
712             x1 = *XXi;
713         }
714
715       // Chargement des numéros de noeuds
716       //      if (inunoe)
717       //        NUM_NOEUDS.push_back(*(numnoe + i));
718       //      else
719       //        NUM_NOEUDS.push_back(i + 1);
720
721     } // boucle sur les noeuds
722
723   //  NUM_NOEUDS.resize(nnoe);
724
725   // Enveloppe du maillage
726   enveloppeMaillage = new Cube(x0, x1, y0, y1, z0, z1);
727
728   // Libération mémoire
729   if (nnoe > 0)
730     {
731       free(coo1);
732       free(nomnoe);
733       free(numnoe);
734       free(nufano);
735     }
736
737   // ##################################################################################################
738   // ##################################################################################################
739   //
740   //                  A C Q U I S I T I O N     D E S     M A I L L E S
741   //
742   // ##################################################################################################
743   // ##################################################################################################
744
745   for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
746     {
747       TYPE_MAILLE tm = (TYPE_MAILLE) itm;
748       EFFECTIFS_TYPES[tm] = MEDmeshnEntity(fid, maa, MED_NO_DT, MED_NO_IT, MED_CELL, InstanceMGE(tm), MED_CONNECTIVITY,
749                                            MED_NODAL, &coordinatechangement, &geotransformation);
750       if (EFFECTIFS_TYPES[tm])
751         acquisitionTYPE_inputMED(tm, EFFECTIFS_TYPES[tm], fid, maa, mdim);
752     }
753
754   // Resize des vecteurs des maps FAMILLES et FAM_TYPES
755   map<int, vector<int> >::iterator IF;
756   for (IF = FAMILLES.begin(); IF != FAMILLES.end(); IF++)
757     {
758       IF->second.resize(tailleFAMILLES[IF->first]);
759       FAM_TYPES[IF->first].resize(tailleFAMILLES[IF->first]);
760     }
761
762   for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
763     nombreMaillesMaillage += EFFECTIFS_TYPES[(TYPE_MAILLE) itm];
764
765   // ##################################################################################################
766   // ##################################################################################################
767   //
768   //          A C Q U I S I T I O N     D E S     G R O U P E S
769   //          D E    M A I L L E S    E T    D E    N O E U D S
770   //
771   // ##################################################################################################
772   // ##################################################################################################
773
774   // =============================================================================================
775   //                 Chargement des groupes dans GM et GN
776   // =============================================================================================
777
778   string nomGM;
779   vector<int> vfam;
780   map<string, vector<int> >::iterator iterGRO;
781
782   int cptGM = 0;
783   for (iterGRO = GROUPES_MAILLES.begin(); iterGRO != GROUPES_MAILLES.end(); iterGRO++)
784     {
785       nomGM = iterGRO->first;
786       vfam = iterGRO->second;
787       cptGM++;
788       map<TYPE_MAILLE, int> effectifGroupeType;
789       for (unsigned int i = 0; i < vfam.size(); i++)
790         {
791           int numf = vfam[i];
792           // Parcours simultané des vecteurs FAMILLES[numf] et FAM_TYPES[numfam] pour obtention du num local
793           // et du type des mailles de la famille numf
794           for (unsigned int imaille = 0; imaille < FAMILLES[numf].size(); imaille++)
795             {
796               TYPE_MAILLE tm = FAM_TYPES[numf][imaille];
797               int nl = FAMILLES[numf][imaille];
798               GM[nomGM][tm].push_back(nl);
799               effectifGroupeType[tm]++;
800             }
801         }
802
803       // Resize d'un GM
804       for (map<TYPE_MAILLE, vector<int> >::iterator I = GM[nomGM].begin(); I != GM[nomGM].end(); I++)
805         {
806           TYPE_MAILLE tm = I->first;
807           GM[nomGM][tm].resize(effectifGroupeType[tm]);
808           sort(GM[nomGM][tm].begin(), GM[nomGM][tm].end());
809         }
810     }
811
812   int cptGN = 0;
813   for (iterGRO = GROUPES_NOEUDS.begin(); iterGRO != GROUPES_NOEUDS.end(); iterGRO++)
814     {
815       nomGM = iterGRO->first;
816       vfam = iterGRO->second;
817       cptGN++;
818       int cptNoeudsGN = 0;
819       for (unsigned int i = 0; i < vfam.size(); i++)
820         {
821           int numf = vfam[i];
822           // Parcours vecteurs FAMILLES_NOEUDS[numf]
823           for (unsigned int inoeud = 0; inoeud < FAMILLES_NOEUDS[numf].size(); inoeud++)
824             {
825               GN[nomGM].push_back(FAMILLES_NOEUDS[numf][inoeud]);
826               cptNoeudsGN++;
827             }
828         }
829       GN[nomGM].resize(cptNoeudsGN);
830       sort(GN[nomGM].begin(), GN[nomGM].end());
831     }
832
833   MEDfileClose(fid);
834   //  cout << "Fin procédure inputMED" << endl << endl;
835 }
836
837 void Maillage::acquisitionTYPE_inputMED(TYPE_MAILLE TYPE, int nTYPE, med_idt fid, char maa[MED_NAME_SIZE + 1],
838                                         med_int mdim)
839 {
840
841   //  int taille, numeromaille, numeroFamille;
842   int numeroFamille;
843   string line, IDmaille, IDnoeud, typeMaille;
844   //  char str[MED_SNAME_SIZE + 1]; // Conteneur pour un nom de maille
845   //  bool rejetMaille;
846   med_int tTYPE = (med_int) Nnoeuds(TYPE);
847   char *nomTYPE = (char*) malloc(MED_SNAME_SIZE * nTYPE + 1);
848   med_int *numTYPE = (med_int*) malloc(sizeof(med_int) * nTYPE);
849   med_int *famTYPE = (med_int*) malloc(sizeof(med_int) * nTYPE);
850
851   //med_int *conTYPE = (med_int*) malloc(sizeof(med_int)*tTYPE*nTYPE);
852   CNX[TYPE] = (int*) malloc(sizeof(int) * tTYPE * nTYPE);
853
854   med_bool inomTYPE, inumTYPE, ifamTYPE;
855   med_geometry_type typeBanaliseMED = InstanceMGE(TYPE);
856
857   if (MEDmeshElementRd(fid, maa, MED_NO_DT, MED_NO_IT, MED_CELL, typeBanaliseMED, MED_NODAL, MED_FULL_INTERLACE,
858                        CNX[TYPE], &inomTYPE, nomTYPE, &inumTYPE, numTYPE, &ifamTYPE, famTYPE) < 0)
859     ERREUR("Erreur a la lecture des coordonnees des noeuds");
860
861   // Conversion HL
862   conversionCNX(CNX[TYPE], TYPE, nTYPE);
863
864   //  CON[TYPE].resize(tTYPE * nTYPE);
865   //  for (int i = 0; i < tTYPE * nTYPE; i++)
866   //    CON[TYPE][i] = (int) *(conTYPE + i);
867   //  CNX[TYPE] = (int*) malloc(sizeof(int) * tTYPE * nTYPE);
868   //  for (int i = 0; i < tTYPE * nTYPE; i++)
869   //    *(CNX[TYPE] + i) = (int) *(conTYPE + i);
870
871   for (int i = 0; i < nTYPE; i++)
872     {
873       numeroFamille = (int) *(famTYPE + i);
874       FAMILLES[numeroFamille].push_back(i);
875       tailleFAMILLES[numeroFamille]++;
876       FAM_TYPES[numeroFamille].push_back(TYPE);
877
878       // Chargement des numéros de mailles
879       //      if (inumTYPE)
880       //        NUM_MAILLES[TYPE].push_back(*(numTYPE + i));
881       //      else
882       //        NUM_MAILLES[TYPE].push_back(NGLOBAL(TYPE, i));
883
884     }
885   //  NUM_MAILLES[TYPE].resize(nTYPE);
886
887   //   if (inomTYPE)
888   //    {
889   //      char str[MED_SNAME_SIZE + 1];
890   //      for (int imaille = 0; imaille < nTYPE; imaille++)
891   //        {
892   //          strncpy(str, nomTYPE + imaille * MED_SNAME_SIZE, MED_SNAME_SIZE);
893   //          str[MED_SNAME_SIZE] = '\0';
894   //          IDS_MAILLES[TYPE].push_back((string) str);
895   //        }
896   //    }
897   //  else if (inumTYPE)
898   //    {
899   //      for (int imaille = 0; imaille < nTYPE; imaille++)
900   //        {
901   //          int nummaille = *(numTYPE + imaille);
902   //          IDS_MAILLES[TYPE].push_back((string) "M" + int2string(nummaille));
903   //        }
904   //    }
905   //  else
906   //    {
907   //      for (int imaille = 0; imaille < nTYPE; imaille++)
908   //        {
909   //          IDS_MAILLES[TYPE].push_back((string) "M" + int2string(imaille + 1));
910   //        }
911   //    }
912   //  IDS_MAILLES[TYPE].resize(nTYPE);
913 }
914
915 void Maillage::outputMED(std::string fichierMED)
916 {
917   // int i, j, k;
918   int nTYPE, tTYPE;
919   string line, s, stype, nomnoeud;
920   //  med_err ret = 0; // Code retour
921   //  int ig, jg;
922   //  cout << endl << endl << "Début procédure outputMED, fichier " << fichierMED << endl;
923
924   // Sortie sur erreur en cas de maillage sans noeuds
925   if (nombreNoeudsMaillage <= 0)
926     {
927       ERREUR("Ce maillage ne contient aucun noeud\n"); /* cout << "Maillage sans noeuds" << endl; */
928     }
929
930   // ########################################################################
931   //    Ouverture du fichier MED et création du maillage
932   // ########################################################################
933
934   // Ouverture du fichier MED en création
935   med_idt fid = MEDfileOpen(string2char(fichierMED), MED_ACC_CREAT);
936   if (fid < 0)
937     {
938       ERREUR("Erreur MEDfileOpen\n");
939       cout << "Erreur MEDfileOpen" << endl;
940     }
941
942   // Création du maillage
943   char maa[MED_NAME_SIZE + 1]; // Nom du maillage de longueur maxi MED_NAME_SIZE
944   strcpy(maa, string2char(ID));
945
946   med_int mdim; // Dimension du maillage
947   if (dimensionMaillage == 0)
948     {
949       mdim = 3;
950       cout << "ATTENTION, dimension 3 attribuée par défaut!" << endl;
951     }
952   else
953     mdim = dimensionMaillage;
954   med_int spacedim = 3;
955   if (dimensionEspace)
956     spacedim = dimensionEspace;
957
958   //med_int profil[2] = { 2, 3 };
959   char desc[MED_COMMENT_SIZE + 1]; // Description du maillage
960   strcpy(desc, string2char(ID));
961   med_mesh_type type = MED_UNSTRUCTURED_MESH;
962   cerr << "maa=" << maa << endl;
963   cerr << "spacedim=" << spacedim << endl;
964   cerr << "mdim=" << mdim << endl;
965   cerr << "type=" << type << endl;
966   cerr << "axisname=" << axisname << endl;
967   cerr << "unitname=" << unitname << endl;
968   if (MEDmeshCr(fid, maa, spacedim, mdim, type, desc, "s", MED_SORT_DTIT, MED_CARTESIAN, axisname, unitname) < 0)
969     {
970       ERREUR("Erreur MEDmeshCr");
971       cout << "Erreur MEDmeshCr" << endl;
972     }
973
974   // =============================  CREATION FAMILLE ZERO
975   char nomfam[MED_NAME_SIZE + 1];
976   med_int numfam;
977   //  char attdes[MED_COMMENT_SIZE + 1];
978   //  med_int natt, attide, attval;
979   int ngro;
980   //  char gro[MED_LNAME_SIZE + 1];
981
982   strcpy(nomfam, "FAMILLE_0");
983   numfam = 0;
984   if (MEDfamilyCr(fid, maa, nomfam, numfam, 0, MED_NO_GROUP) < 0)
985     ERREUR("Erreur MEDfamilyCr (creation famille 0)");
986
987   // ########################################################################
988   //          GROUPES DE NOEUDS
989   // ########################################################################
990
991   int nGroupesNoeuds = GN.size();
992
993   vector<vector<int> > ETIQUETTES_N;
994   ETIQUETTES_N.resize(nombreNoeudsMaillage);
995   vector<unsigned int> INDEX_N;
996   INDEX_N.resize(GN.size());
997   vector<string> NOMSFAM;
998   vector<vector<int> > ETIQFAM;
999   int cptNOMFAM = 0;
1000   map<string, int> NUMFAMETIQ; //  clé = étiquette  -  valeur = numéros de familles
1001
1002
1003   if (nGroupesNoeuds)
1004     {
1005
1006       // Pérennisation d'un ordre sur les GM dans le vecteur NOMS_GROUPES_MAILLES
1007       vector<string> NOMS_GROUPES_NOEUDS;
1008       for (map<string, vector<int> >::iterator ITGN = GN.begin(); ITGN != GN.end(); ITGN++)
1009         {
1010           string nomGN = ITGN->first;
1011           NOMS_GROUPES_NOEUDS.push_back(nomGN);
1012         }
1013       NOMS_GROUPES_NOEUDS.resize(GN.size());
1014
1015       // Tri des vecteurs de noeuds de GN
1016       for (unsigned int ig = 0; ig < NOMS_GROUPES_NOEUDS.size(); ig++)
1017         sort(GN[NOMS_GROUPES_NOEUDS[ig]].begin(), GN[NOMS_GROUPES_NOEUDS[ig]].end());
1018
1019       // Construction des étiquettes (familles)
1020
1021       // Initialisation des index de groupes
1022       for (unsigned int ig = 0; ig < NOMS_GROUPES_NOEUDS.size(); ig++)
1023         INDEX_N[ig] = 0;
1024
1025       for (int k = 1; k <= nombreNoeudsMaillage; k++)
1026         { // k: num. global de noeud
1027           int tailleEtiquette = 0;
1028           string etiq = (string) "";
1029           // Boucle sur les groupes
1030           for (unsigned int ig = 0; ig < NOMS_GROUPES_NOEUDS.size(); ig++)
1031             {
1032               if (INDEX_N[ig] < GN[NOMS_GROUPES_NOEUDS[ig]].size())
1033                 {
1034                   string nomgroupe = NOMS_GROUPES_NOEUDS[ig];
1035                   if (k == GN[nomgroupe][INDEX_N[ig]])
1036                     {
1037                       // Attention: l'indice 0 dans le vecteur ETIQUETTES correspond
1038                       // à l'élément (noeud ou maille) de num. global 1
1039                       // Par ailleurs, le numéro de groupe dans l'étiquette commence à 0
1040                       ETIQUETTES_N[k - 1].push_back(ig);
1041                       tailleEtiquette++;
1042                       etiq += int2string(ig);
1043                       INDEX_N[ig]++;
1044                     }
1045                 }
1046             }
1047           ETIQUETTES_N[k - 1].resize(tailleEtiquette);
1048           // Stockage de l'étiquette dans NOMSFAM ETIQFAM, si pas déjà stockée
1049           //          bool trouve = false;
1050           //          for (int i = 0; i < NOMSFAM.size(); i++)
1051           //            if (NOMSFAM[i] == ((string) "ETIQUETTE_" + etiq))
1052           //              {
1053           //                trouve = true;
1054           //                break;
1055           //              }
1056           if (!NUMFAMETIQ[etiq] && etiq != (string) "")
1057             {
1058               NOMSFAM.push_back((string) "ETIQN_" + etiq);
1059               ETIQFAM.push_back(ETIQUETTES_N[k - 1]);
1060               NUMFAMETIQ[etiq] = cptNOMFAM + 1; // Famille de noeuds, num>0
1061               cptNOMFAM++;
1062             }
1063         }
1064
1065       NOMSFAM.resize(cptNOMFAM);
1066       ETIQFAM.resize(cptNOMFAM);
1067
1068       // Création des familles de noeuds
1069       for (unsigned int ifam = 0; ifam < NOMSFAM.size(); ifam++)
1070         {
1071           strcpy(nomfam, string2char(NOMSFAM[ifam]));
1072           // Numéro de famille: ifam+1 (positif pour les noeuds + non nul)
1073           numfam = ifam + 1;
1074           ngro = ETIQFAM[ifam].size();
1075
1076           // Noms des groupes de la famille: variable nomsGN
1077           char gro[ngro * MED_LNAME_SIZE + 1];
1078           int cptGN = 0;
1079           for (unsigned int ign = 0; ign < ETIQFAM[ifam].size(); ign++)
1080             {
1081               string nomGNcourant = NOMS_GROUPES_NOEUDS[ETIQFAM[ifam][ign]];
1082               // ATTENTION! Il faut mettre à la fin de chaque segment un \0 qui est ensuite écrasé
1083               // par le premier caractère du champ suivant dans le strcat !!!!
1084               if (ign == 0)
1085                 {
1086                   // Premier groupe
1087                   strcpy(gro, string2char(nomGNcourant));
1088                   for (int jg = nomGNcourant.size(); jg < MED_LNAME_SIZE; jg++)
1089                     gro[jg] = ' ';
1090                   gro[MED_LNAME_SIZE] = '\0';
1091                 }
1092               else
1093                 {
1094                   strcat(gro, string2char(nomGNcourant));
1095                   for (int jg = nomGNcourant.size(); jg < MED_LNAME_SIZE; jg++)
1096                     gro[cptGN * MED_LNAME_SIZE + jg] = ' ';
1097                   gro[(cptGN + 1) * MED_LNAME_SIZE] = '\0';
1098                 }
1099               cptGN++;
1100             }
1101
1102           // Création de la famille
1103           if (MEDfamilyCr(fid, maa, nomfam, numfam, 0, MED_NO_GROUP) < 0)
1104             ERREUR("Erreur MEDfamilyCr");
1105
1106         }
1107
1108     }
1109
1110   // ########################################################################
1111   //          NOEUDS
1112   // ########################################################################
1113
1114   //  float x, y, z;
1115
1116   med_int nnoe = nombreNoeudsMaillage; // Nombre de noeuds
1117   med_float *coo; // Table des coordonnées
1118
1119   // Noms des coordonnées (variable nomcoo)
1120   char nomcoo[mdim * MED_SNAME_SIZE + 1];
1121   string strX = (string) "X";
1122   while (strX.size() < MED_SNAME_SIZE)
1123     strX += (string) " ";
1124   string strY = (string) "Y";
1125   while (strY.size() < MED_SNAME_SIZE)
1126     strY += (string) " ";
1127   string strZ = (string) "Z";
1128   while (strZ.size() < MED_SNAME_SIZE)
1129     strZ += (string) " ";
1130   if (mdim == 3)
1131     strcpy(nomcoo, string2char(strX + strY + strZ));
1132   else if (mdim == 2)
1133     strcpy(nomcoo, string2char(strX + strY));
1134   else
1135     strcpy(nomcoo, string2char(strX));
1136   nomcoo[mdim * MED_SNAME_SIZE] = '\0';
1137
1138   // Unités des coordonnées (variable unicoo)
1139   char unicoo[mdim * MED_SNAME_SIZE + 1];
1140   string strmesure = (string) "SI";
1141   while (strmesure.size() < MED_SNAME_SIZE)
1142     strmesure += (string) " ";
1143   if (mdim == 3)
1144     strcpy(unicoo, string2char(strmesure + strmesure + strmesure));
1145   else if (mdim == 2)
1146     strcpy(unicoo, string2char(strmesure + strmesure));
1147   else
1148     strcpy(unicoo, string2char(strmesure));
1149   unicoo[mdim * MED_SNAME_SIZE] = '\0';
1150
1151   // Tables des noms, numeros, numeros de familles des noeuds
1152   //    autant d'elements que de noeuds - les noms ont pout longueur MED_SNAME_SIZE
1153   char *nomnoe;
1154   med_int *numnoe = NULL;
1155   med_int *nufano;
1156   med_bool inonoe = MED_FALSE;
1157   med_bool inunoe = MED_FALSE;
1158
1159   // Allocations memoire
1160   if (nnoe > 0)
1161     {
1162       // table des coordonnees - profil : (dimension * nombre de noeuds )
1163       coo = (med_float*) calloc(nnoe * mdim, sizeof(med_float));
1164
1165       // table des des numeros, des numeros de familles des noeuds - profil : (nombre de noeuds)
1166       //      numnoe = (med_int*) malloc(sizeof(med_int) * nnoe);
1167       nufano = (med_int*) malloc(sizeof(med_int) * nnoe);
1168
1169       // table des noms des noeuds - profil : (nnoe*MED_SNAME_SIZE+1)
1170       nomnoe = (char*) ""; // ATTENTION!
1171
1172       //      nomnoe = (char*) malloc(MED_SNAME_SIZE * nnoe + 1);
1173       //      for (int inoeud = 0; inoeud < IDS_NOEUDS.size(); inoeud++)
1174       //        {
1175       //          string nomNoeud = IDS_NOEUDS[inoeud];
1176       //          if (inoeud == 0)
1177       //            {
1178       //              // Premier groupe
1179       //              strcpy(nomnoe, string2char(nomNoeud));
1180       //              for (int jg = nomNoeud.size(); jg < MED_SNAME_SIZE; jg++)
1181       //                nomnoe[jg] = ' ';
1182       //              nomnoe[MED_SNAME_SIZE] = '\0';
1183       //            }
1184       //          else
1185       //            {
1186       //              strcat(nomnoe, string2char(nomNoeud));
1187       //              for (int jg = nomNoeud.size(); jg < MED_SNAME_SIZE; jg++)
1188       //                nomnoe[inoeud * MED_SNAME_SIZE + jg] = ' ';
1189       //              nomnoe[(inoeud + 1) * MED_SNAME_SIZE] = '\0';
1190       //            }
1191       //        }
1192     }
1193
1194   // Chargement des coordonnées, numéros de familles et numéros de noeuds
1195   if (dimensionMaillage == 3)
1196     {
1197       int i3 = 0;
1198       for (int i = 0; i < nnoe; i++)
1199         {
1200           //          coo[i3] = X[i];
1201           //          coo[i3 + 1] = Y[i];
1202           //          coo[i3 + 2] = Z[i];
1203           //          i3 = i3 + 3;
1204           coo[i3] = *(XX + i);
1205           coo[i3 + 1] = *(YY + i);
1206           coo[i3 + 2] = *(ZZ + i);
1207           i3 = i3 + 3;
1208
1209           // Numéros de familles  -  Le num. global de noeud est i+1
1210           if (nGroupesNoeuds)
1211             {
1212               vector<int> v = ETIQUETTES_N[i];
1213               string sv = (string) "";
1214               for (unsigned int j = 0; j < v.size(); j++)
1215                 sv += int2string(v[j]); // Etiquette du noeud au format string
1216               // cout << "Noeud " << i + 1 << " : sv=" << sv << endl;
1217               *(nufano + i) = (med_int) NUMFAMETIQ[sv];
1218             }
1219           else
1220             *(nufano + i) = (med_int) 0;
1221
1222           // Numéros de noeuds
1223           // *(numnoe + i) = (med_int) NUM_NOEUDS[i];
1224         }
1225     }
1226   else /* dimension 2 */
1227     {
1228       int i2 = 0;
1229       for (int i = 0; i < nnoe; i++)
1230         {
1231           coo[i2] = *(XX + i);
1232           coo[i2 + 1] = *(YY + i);
1233           i2 = i2 + 2;
1234           // Numéros de familles  -  Le num. global de noeud est i+1
1235           if (nGroupesNoeuds)
1236             {
1237               vector<int> v = ETIQUETTES_N[i];
1238               string sv = (string) "";
1239               for (unsigned int j = 0; j < v.size(); j++)
1240                 sv += int2string(v[j]); // Etiquette du noeud au format string
1241               // cout << "Noeud " << i + 1 << " : sv=" << sv << endl;
1242               *(nufano + i) = (med_int) NUMFAMETIQ[sv];
1243             }
1244           else
1245             *(nufano + i) = (med_int) 0;
1246           // Numéros de noeuds
1247           // *(numnoe + i) = (med_int) NUM_NOEUDS[i];
1248         }
1249     }
1250
1251   //   // Restitution coo
1252   //  int i3 = 0;
1253   //  for (int i = 0; i < nnoe; i++)
1254   //    {
1255   //      cout << "Noeud " << i << " : " << coo[i3] << " " << coo[i3 + 1] << " " << coo[i3 + 2] << endl;
1256   //      i3 = i3 + 3;
1257   //    }
1258
1259   if (MEDmeshNodeWr(fid, maa, MED_NO_DT, MED_NO_IT, MED_UNDEF_DT, MED_FULL_INTERLACE, nnoe, coo, inonoe, nomnoe,
1260                     inunoe, numnoe, MED_TRUE, nufano) < 0)
1261     {
1262       ERREUR("Erreur MEDmeshNodeWr");
1263       cout << "Erreur MEDmeshNodeWr" << endl;
1264     }
1265
1266   // ########################################################################
1267   //          GROUPES DE MAILLES
1268   // ########################################################################
1269
1270   int nGroupesMailles = GM.size();
1271
1272   map<TYPE_MAILLE, vector<vector<int> > > ETIQUETTES_M; // [ tm => [ nl => [ig1, ig2, ... ] ] ]
1273   // INDEX_M :
1274   //  Clé :       tm
1275   //  Valeur :    vect. des compteurs par indice de GM dans NOMS_GROUPES_MAILLES
1276   map<TYPE_MAILLE, vector<unsigned int> > INDEX_M;
1277   NOMSFAM.clear();
1278   ETIQFAM.clear();
1279   NUMFAMETIQ.clear(); //  clé = étiquette  -  valeur = numéros de familles
1280   cptNOMFAM = 0;
1281
1282   if (nGroupesMailles)
1283     {
1284
1285       // Pérennisation d'un ordre sur les GM dans le vecteur NOMS_GROUPES_MAILLES
1286       vector<string> NOMS_GROUPES_MAILLES;
1287       for (map<string, map<TYPE_MAILLE, vector<int> > >::iterator ITGM = GM.begin(); ITGM != GM.end(); ITGM++)
1288         {
1289           string nomGM = ITGM->first;
1290           NOMS_GROUPES_MAILLES.push_back(nomGM);
1291         }
1292       NOMS_GROUPES_MAILLES.resize(GM.size());
1293       // Tri des vecteurs d'entiers de GM
1294       for (unsigned int ig = 0; ig < NOMS_GROUPES_MAILLES.size(); ig++)
1295         {
1296           string nomGM = NOMS_GROUPES_MAILLES[ig];
1297           for (map<TYPE_MAILLE, vector<int> >::iterator I = GM[nomGM].begin(); I != GM[nomGM].end(); I++)
1298             {
1299               TYPE_MAILLE tm = I->first;
1300               sort(GM[nomGM][tm].begin(), GM[nomGM][tm].end());
1301             }
1302         }
1303
1304       // Construction des étiquettes (familles)
1305
1306       // Initialisation 0 des index de groupes, et resize ETIQUETTES_M[tm]
1307       for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
1308         {
1309           TYPE_MAILLE tm = (TYPE_MAILLE) itm;
1310           if (EFFECTIFS_TYPES[tm])
1311             {
1312               for (unsigned int ig = 0; ig < NOMS_GROUPES_MAILLES.size(); ig++)
1313                 INDEX_M[tm].push_back(0);
1314               ETIQUETTES_M[tm].resize(EFFECTIFS_TYPES[tm]);
1315             }
1316         }
1317
1318       for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
1319         {
1320           TYPE_MAILLE tm = (TYPE_MAILLE) itm;
1321           int efftm = EFFECTIFS_TYPES[tm];
1322           // cout << endl << "*************** coucou ***************" << endl;
1323           // cout << "*************** Type " << TM2string(tm) << " effectif = " << efftm << endl;
1324           if (efftm)
1325             {
1326               // cout << "Traitement du type " << TM2string(tm) << endl;
1327               for (int nl = 0; nl < efftm; nl++)
1328                 {
1329                   // nl = num. local de la maille dans son type
1330                   // cout << "\tMaille " << TM2string(tm) << " n° " << nl << endl;
1331
1332                   int tailleEtiquette = 0;
1333                   string etiq = (string) "";
1334                   // Boucle sur les groupes
1335                   for (unsigned int ig = 0; ig < NOMS_GROUPES_MAILLES.size(); ig++)
1336                     {
1337                       string nomGM = NOMS_GROUPES_MAILLES[ig];
1338                       // cout << "\t\t" << "Groupe " << nomGM << endl;
1339
1340                       if (INDEX_M[tm][ig] < GM[nomGM][tm].size())
1341                         {
1342                           if (nl == GM[nomGM][tm][INDEX_M[tm][ig]])
1343                             {
1344                               // Attention: l'indice 0 dans le vecteur ETIQUETTES correspond
1345                               // à l'élément (noeud ou maille) de num. global 1
1346                               // Par ailleurs, le numéro de groupe dans l'étiquette commence à 0
1347                               // cout << "\t\t\t" << "La maille est dans le groupe " << nomGM << endl;
1348                               ETIQUETTES_M[tm][nl].push_back(ig);
1349                               tailleEtiquette++;
1350                               etiq += int2string(ig);
1351                               INDEX_M[tm][ig]++;
1352                               // cout << "\t\t\t  OK" << endl;
1353                             }
1354                         }
1355                     }
1356
1357                   ETIQUETTES_M[tm][nl].resize(tailleEtiquette);
1358                   // Stockage de l'étiquette dans NOMSFAM ETIQFAM, si pas déjà stockée
1359                   //                  bool trouve = false;
1360                   //                  for (int i = 0; i < NOMSFAM.size(); i++)
1361                   //                    if (NOMSFAM[i] == ((string) "ETIQUETTE_" + etiq))
1362                   //                      {
1363                   //                        trouve = true;
1364                   //                        break;
1365                   //                      }
1366
1367                   if (!NUMFAMETIQ[etiq] && etiq != (string) "")
1368                     {
1369                       NOMSFAM.push_back((string) "ETIQM_" + etiq);
1370                       ETIQFAM.push_back(ETIQUETTES_M[tm][nl]);
1371                       NUMFAMETIQ[etiq] = -cptNOMFAM - 1; // Famille de mailles, num<0
1372                       cptNOMFAM++;
1373                     }
1374
1375                 }
1376
1377             } // if (efftm)
1378         }
1379
1380       NOMSFAM.resize(cptNOMFAM);
1381       ETIQFAM.resize(cptNOMFAM);
1382
1383       // Création des familles de mailles
1384       for (unsigned int ifam = 0; ifam < NOMSFAM.size(); ifam++)
1385         {
1386           strcpy(nomfam, string2char(NOMSFAM[ifam]));
1387           // Numéro de famille: -ifam-1 (négatif pour les mailles, et non nul)
1388           numfam = -ifam - 1;
1389           ngro = ETIQFAM[ifam].size();
1390
1391           // Noms des groupes de la famille
1392           char gro[ngro * MED_LNAME_SIZE + 1];
1393           int cptGM = 0;
1394           for (unsigned int ign = 0; ign < ETIQFAM[ifam].size(); ign++)
1395             {
1396               string nomGMcourant = NOMS_GROUPES_MAILLES[ETIQFAM[ifam][ign]];
1397               // ATTENTION! Il faut mettre à la fin de chaque segment un \0 qui est ensuite écrasé
1398               // par le premier caractère du champ suivant dans le strcat !!!!
1399               if (ign == 0)
1400                 {
1401                   // Premier groupe
1402                   strcpy(gro, string2char(nomGMcourant));
1403                   for (int jg = nomGMcourant.size(); jg < MED_LNAME_SIZE; jg++)
1404                     gro[jg] = ' ';
1405                   gro[MED_LNAME_SIZE] = '\0';
1406                 }
1407               else
1408                 {
1409                   strcat(gro, string2char(nomGMcourant));
1410                   for (int jg = nomGMcourant.size(); jg < MED_LNAME_SIZE; jg++)
1411                     gro[cptGM * MED_LNAME_SIZE + jg] = ' ';
1412                   gro[(cptGM + 1) * MED_LNAME_SIZE] = '\0';
1413                 }
1414               cptGM++;
1415             }
1416
1417           // Création de la famille
1418           if (MEDfamilyCr(fid, maa, nomfam, numfam, 1, gro) < 0)
1419             ERREUR("Erreur MEDfamilyCr");
1420         }
1421
1422     }
1423
1424   // ########################################################################
1425   //                                MAILLES
1426   // ########################################################################
1427   //               Appel de la routine ecritureTypeNew
1428
1429   med_bool inomTYPE = MED_FALSE;
1430   med_bool inumTYPE = MED_FALSE;
1431
1432   med_geometry_type MGE;
1433
1434   for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
1435     {
1436       TYPE_MAILLE tm = (TYPE_MAILLE) itm;
1437       if (EFFECTIFS_TYPES[tm])
1438         {
1439           nTYPE = EFFECTIFS_TYPES[tm];
1440           tTYPE = Nnoeuds(tm);
1441           MGE = InstanceMGE(tm);
1442           stype = TM2string(tm);
1443
1444           // Noms des mailles
1445           //          char *nomTYPE = (char*) malloc(MED_SNAME_SIZE * nTYPE + 1);
1446           //          strcpy(nomTYPE, ""); // ATTENTION!
1447
1448           char *nomTYPE = (char*)""; // Attention! Ne pas faire strcpy !
1449
1450           //           for (int imaille = 0; imaille < IDS_MAILLES[tm].size(); imaille++)
1451           //            {
1452           //              string nomMaille = IDS_MAILLES[tm][imaille];
1453           //              if (imaille == 0)
1454           //                {
1455           //                  // Premier groupe
1456           //                  strcpy(nomTYPE, string2char(nomMaille));
1457           //                  for (int jg = nomMaille.size(); jg < MED_SNAME_SIZE; jg++)
1458           //                    nomTYPE[jg] = ' ';
1459           //                  nomTYPE[MED_SNAME_SIZE] = '\0';
1460           //                }
1461           //              else
1462           //                {
1463           //                  strcat(nomTYPE, string2char(nomMaille));
1464           //                  for (int jg = nomMaille.size(); jg < MED_SNAME_SIZE; jg++)
1465           //                    nomTYPE[imaille * MED_SNAME_SIZE + jg] = ' ';
1466           //                  nomTYPE[(imaille + 1) * MED_SNAME_SIZE] = '\0';
1467           //                }
1468           //            }
1469
1470           med_int *numTYPE = NULL; //  (med_int*) malloc(sizeof(med_int)*nTYPE);
1471
1472           med_int *famTYPE = (med_int*) malloc(sizeof(med_int) * nTYPE);
1473
1474           //          med_int *conTYPE = (med_int*) malloc(sizeof(med_int) * tTYPE * nTYPE);
1475           //          for (int i = 0; i < nTYPE * tTYPE; i++)
1476           //            *(conTYPE + i) = (med_int) CON[tm][i];
1477
1478           // Chargement famTYPE
1479           if (nGroupesMailles)
1480             {
1481               // Boucle sur les mailles du type (indice = num. local)
1482               for (int nl = 0; nl < nTYPE; nl++)
1483                 {
1484                   // Construction de l'étiquette de la maille au format string
1485                   vector<int> v = ETIQUETTES_M[tm][nl];
1486                   string sv = (string) "";
1487                   for (unsigned int j = 0; j < v.size(); j++)
1488                     sv += int2string(v[j]);
1489                   // Accès au num. de la famille
1490                   *(famTYPE + nl) = (med_int) NUMFAMETIQ[sv];
1491                 } // Boucle sur les mailles du type
1492             } // if (nGroupesMailles)
1493           else
1494             for (int nl = 0; nl < nTYPE; nl++)
1495               *(famTYPE + nl) = (med_int) 0;
1496
1497           // Formatage MED des CNX
1498           conversionCNX(CNX[tm], tm, nTYPE);
1499
1500           // Chargement numTYPE
1501           //for (int nl=0; nl<nTYPE; nl++)    *(numTYPE+nl) = (med_int) ( NUM_MAILLES[tm][nl] );
1502           cerr << "maa=" << maa << endl;
1503           cerr << "MGE=" << MGE << endl;
1504           cerr << "nTYPE=" << nTYPE << endl;
1505           cerr << "inomTYPE=" << inomTYPE << endl;
1506           //cerr << "nomTYPE=" << nomTYPE << endl;
1507           cerr << "inumTYPE=" << inumTYPE << endl;
1508           this->afficheMailles(tm);
1509           if (MEDmeshElementWr(fid, maa, MED_NO_DT, MED_NO_IT, MED_UNDEF_DT, MED_CELL, MGE, MED_NODAL,
1510                                MED_FULL_INTERLACE, nTYPE, CNX[tm], inomTYPE, nomTYPE, inumTYPE, numTYPE, MED_FALSE,
1511                                famTYPE) < 0)
1512             {
1513               ERREUR("Erreur MEDmeshElementWr");
1514               cout << "Erreur MEDmeshElementWr, type " << stype << endl;
1515             }
1516           if (MEDmeshEntityFamilyNumberWr(fid, maa, MED_NO_DT, MED_NO_IT,
1517                                           MED_CELL, MGE, nTYPE, famTYPE) < 0)
1518             {
1519               ERREUR("Erreur MEDmeshEntityFamilyNumberWr");
1520               cout << "Erreur MEDmeshEntityFamilyNumberWr, type " << stype << endl;
1521             }
1522
1523           // free(nomTYPE);
1524           // free(numTYPE);
1525           free(famTYPE);
1526           // free(conTYPE);
1527
1528         } // Effectif non vide
1529     }
1530
1531   // ########################################################################
1532   //                            Fermeture du fichier MED
1533   // ########################################################################
1534
1535   if (MEDfileClose(fid) < 0)
1536     {
1537       ERREUR("Erreur a la fermeture du fichier MED\n");
1538       cout << "Erreur a la fermeture du fichier MED" << endl;
1539     }
1540
1541   // cout << endl << endl << "Fin procédure outputMED" << endl;
1542 } // outputMED
1543
1544
1545 int Maillage::NGLOBAL(TYPE_MAILLE typeMaille, int nlocal)
1546 {
1547   // Attention, les num. globaux commencent à 1, les num. locaux à 0
1548   int cpt = 1 + nlocal;
1549   for (int itm = (int) POI1; itm < (int) typeMaille; itm++)
1550     { // Attention! inférieur strict!
1551       TYPE_MAILLE tm = (TYPE_MAILLE) itm;
1552       cpt += EFFECTIFS_TYPES[tm];
1553     }
1554   return cpt;
1555 }
1556
1557 TYPE_MAILLE Maillage::TYPE(int nglobal)
1558 {
1559   // Attention, les num. globaux commencent à 1, les num. locaux à 0
1560   TYPE_MAILLE resultat;
1561   int cpt = 0;
1562   for (int itm = (int) POI1; itm <= (int) HEXA20; itm++)
1563     {
1564       TYPE_MAILLE tm = (TYPE_MAILLE) itm;
1565       cpt += EFFECTIFS_TYPES[tm];
1566       if (nglobal <= cpt)
1567         {
1568           resultat = tm;
1569           break;
1570         }
1571     }
1572   return resultat;
1573 }
1574
1575 int Maillage::NLOCAL(int nglobal, TYPE_MAILLE tm)
1576 {
1577   // Attention, les num. globaux commencent à 1, les num. locaux à 0
1578   int nPOI1 = EFFECTIFS_TYPES[POI1];
1579   int nSEG2 = EFFECTIFS_TYPES[SEG2];
1580   int nSEG3 = EFFECTIFS_TYPES[SEG3];
1581   int nTRIA3 = EFFECTIFS_TYPES[TRIA3];
1582   int nTRIA6 = EFFECTIFS_TYPES[TRIA6];
1583   int nQUAD4 = EFFECTIFS_TYPES[QUAD4];
1584   int nQUAD8 = EFFECTIFS_TYPES[QUAD8];
1585   int nTETRA4 = EFFECTIFS_TYPES[TETRA4];
1586   int nTETRA10 = EFFECTIFS_TYPES[TETRA10];
1587   int nPYRAM5 = EFFECTIFS_TYPES[PYRAM5];
1588   int nPYRAM13 = EFFECTIFS_TYPES[PYRAM13];
1589   int nPENTA6 = EFFECTIFS_TYPES[PENTA6];
1590   int nPENTA15 = EFFECTIFS_TYPES[PENTA15];
1591   int nHEXA8 = EFFECTIFS_TYPES[HEXA8];
1592   int nHEXA20 = EFFECTIFS_TYPES[HEXA20];
1593
1594   if (nglobal <= nPOI1)
1595     {
1596       return nglobal - 1;
1597     }
1598   else if (nglobal <= nPOI1 + nSEG2)
1599     {
1600       return nglobal - nPOI1 - 1;
1601     }
1602   else if (nglobal <= nPOI1 + nSEG2 + nSEG3)
1603     {
1604       return nglobal - nPOI1 - nSEG2 - 1;
1605     }
1606   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3)
1607     {
1608       return nglobal - nPOI1 - nSEG2 - nSEG3 - 1;
1609     }
1610   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6)
1611     {
1612       return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - 1;
1613     }
1614   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4)
1615     {
1616       return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - 1;
1617     }
1618   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8)
1619     {
1620       return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - 1;
1621     }
1622   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4)
1623     {
1624       return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - 1;
1625     }
1626   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10)
1627     {
1628       return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - 1;
1629     }
1630   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5)
1631     {
1632       return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - 1;
1633     }
1634   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5
1635       + nPYRAM13)
1636     {
1637       return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - nPYRAM5 - 1;
1638     }
1639   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5
1640       + nPYRAM13 + nPENTA6)
1641     {
1642       return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - nPYRAM5
1643           - nPYRAM13 - 1;
1644     }
1645   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5
1646       + nPYRAM13 + nPENTA6 + nPENTA15)
1647     {
1648       return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - nPYRAM5
1649           - nPYRAM13 - nPENTA6 - 1;
1650     }
1651   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5
1652       + nPYRAM13 + nPENTA6 + nPENTA15 + nHEXA8)
1653     {
1654       return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - nPYRAM5
1655           - nPYRAM13 - nPENTA6 - nPENTA15 - 1;
1656     }
1657   else if (nglobal <= nPOI1 + nSEG2 + nSEG3 + nTRIA3 + nTRIA6 + nQUAD4 + nQUAD8 + nTETRA4 + nTETRA10 + nPYRAM5
1658       + nPYRAM13 + nPENTA6 + nPENTA15 + nHEXA8 + nHEXA20)
1659     {
1660       return nglobal - nPOI1 - nSEG2 - nSEG3 - nTRIA3 - nTRIA6 - nQUAD4 - nQUAD8 - nTETRA4 - nTETRA10 - nPYRAM5
1661           - nPYRAM13 - nPENTA6 - nPENTA15 - nHEXA8 - 1;
1662     }
1663   else
1664     ERREUR("Routine NLOCAL: type non reconnu");
1665   return 0;
1666 }
1667
1668 /*!
1669  *  Suppression de mailles dans un type :
1670  *
1671  *  - Contraction de la connectivité concernée
1672  *  - Réécriture des GM avec les nouveaux numéros locaux des éléments du type concerné
1673  *  - Mise à jour nombreMaillesMaillage
1674  *
1675  *  Les noeuds ne sont pas affectés.
1676  */
1677 void Maillage::eliminationMailles(TYPE_MAILLE tm, vector<int> listeMaillesSuppr)
1678 {
1679   map<int, int> TABLE_NL; // Table des num. locaux dans le type tm
1680
1681   // cout << "Fonction eliminationMailles, listeMaillesSuppr.size()=" << listeMaillesSuppr.size() << endl;
1682
1683   // ************* Modification de la connectivité du type concerné
1684
1685   int* CNX2;
1686   int nNoeudsType = Nnoeuds(tm);
1687   int tailleCNX2 = nNoeudsType * (EFFECTIFS_TYPES[tm] - listeMaillesSuppr.size());
1688   CNX2 = (int*) malloc(sizeof(int) * tailleCNX2);
1689   // Recopie sélective des connectivités
1690   int isuppr = 0; // indice dans listeMaillesSuppr
1691   int ih2 = 0; // nouveau numéro local ( remarque: ih2 = ih1 - isuppr )
1692   for (int ih1 = 0; ih1 < EFFECTIFS_TYPES[tm]; ih1++)
1693     {
1694       if (listeMaillesSuppr[isuppr] != ih1)
1695         {
1696           for (int jh1 = 0; jh1 < nNoeudsType; jh1++)
1697             *(CNX2 + nNoeudsType * ih2 + jh1) = *(CNX[tm] + nNoeudsType * ih1 + jh1);
1698           ih2++;
1699         }
1700       else
1701         isuppr++;
1702     }
1703   free(CNX[tm]);
1704   CNX[tm] = CNX2;
1705
1706   // ************* Construction de la table de correspondance des NL dans le type concerné
1707   unsigned int offset = 0;
1708   for (int i = 0; i < EFFECTIFS_TYPES[tm]; i++)
1709     {
1710       if (offset < listeMaillesSuppr.size())
1711         {
1712           if (i < listeMaillesSuppr[offset])
1713             TABLE_NL[i] = i - offset;
1714           else if (i == listeMaillesSuppr[offset])
1715             {
1716               TABLE_NL[i] = -1; // Element à supprimer
1717               offset++;
1718             }
1719         }
1720       else
1721         TABLE_NL[i] = i - offset;
1722     }
1723
1724   // Contrôle
1725   if (offset != listeMaillesSuppr.size())
1726     {
1727       ERREUR("Incohérence offset, fonction eliminationMailles");
1728       exit(0);
1729     }
1730
1731   // ************* Mise à jour du type concerné dans les GM
1732   for (map<string, map<TYPE_MAILLE, vector<int> > >::iterator I = GM.begin(); I != GM.end(); I++)
1733     {
1734       string nomGM = I->first;
1735
1736       if (GM[nomGM][tm].size())
1737         {
1738
1739           vector<int> mailles = GM[nomGM][tm];
1740           vector<int> mailles2; //mailles2.resize(mailles.size()-listeMaillesSuppr.size());
1741           unsigned int cptMailles = 0;
1742           for (unsigned int i = 0; i < mailles.size(); i++)
1743             {
1744               int nl2 = TABLE_NL[mailles[i]];
1745               if (nl2 != -1)
1746                 {
1747                   mailles2.push_back(nl2);
1748                   cptMailles++;
1749                 }
1750             }
1751           // Vérification
1752           if (cptMailles != mailles.size() - listeMaillesSuppr.size())
1753             {
1754               int delta = mailles.size() - listeMaillesSuppr.size();
1755               cout << "mailles.size() = " << mailles.size() << endl;
1756               cout << "cptMailles = " << cptMailles << endl;
1757               cout << "delta = " << delta << endl;
1758               ERREUR("Incohérence sur le nombre de mailles conservées, fonction eliminationMailles");
1759               exit(0);
1760             }
1761
1762           GM[nomGM][tm].clear();
1763           mailles2.resize(cptMailles);
1764           GM[nomGM][tm] = mailles2;
1765
1766         }
1767     }
1768
1769   // ************* Mise à jour des effectifs
1770   EFFECTIFS_TYPES[tm] = EFFECTIFS_TYPES[tm] - listeMaillesSuppr.size();
1771   nombreMaillesMaillage = nombreMaillesMaillage - listeMaillesSuppr.size();
1772
1773   TABLE_NL.clear();
1774 }
1775