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