Salome HOME
correct a small bug found by the EDF developpement team (PN and AT) :
[modules/smesh.git] / src / DriverMED / DriverMED_W_SMDS_Mesh.cxx
1 //  SMESH DriverMED : driver to read and write 'med' files
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
21 //
22 //
23 //
24 //  File   : DriverMED_W_SMDS_Mesh.cxx
25 //  Module : SMESH
26
27 using namespace std;
28 #include "DriverMED_W_SMDS_Mesh.h"
29
30 #include "SMDS_MeshElement.hxx"
31 #include "SMDS_MeshNode.hxx"
32
33
34
35
36 #include "utilities.h"
37 #include <vector>
38
39 DriverMED_W_SMDS_Mesh::DriverMED_W_SMDS_Mesh()
40 {
41         ;
42 }
43
44 DriverMED_W_SMDS_Mesh::~DriverMED_W_SMDS_Mesh()
45 {
46         ;
47 }
48
49 void DriverMED_W_SMDS_Mesh::SetMesh(SMDS_Mesh * aMesh)
50 {
51         myMesh = aMesh;
52 }
53
54 void DriverMED_W_SMDS_Mesh::SetFile(string aFile)
55 {
56         myFile = aFile;
57 }
58
59 void DriverMED_W_SMDS_Mesh::SetFileId(med_idt aFileId)
60 {
61         myFileId = aFileId;
62 }
63
64 void DriverMED_W_SMDS_Mesh::SetMeshId(int aMeshId)
65 {
66         myMeshId = aMeshId;
67 }
68
69 void DriverMED_W_SMDS_Mesh::Add()
70 {
71         ;
72 }
73
74 void DriverMED_W_SMDS_Mesh::Write()
75 {
76
77         med_err ret = 0;
78         int i, j, k, l;
79         int numero;
80         char message[200];
81         bool ok;
82         /* nombre d'objets MED */
83         char nom_universel[MED_TAILLE_LNOM + 1];
84         med_int long_fichier_en_tete;
85         char *fichier_en_tete;
86         char version_hdf[10];
87         char version_med[10];
88         med_int nmaa, mdim, nnoe;
89         med_int nmai[MED_NBR_GEOMETRIE_MAILLE], nfac[MED_NBR_GEOMETRIE_FACE];
90         med_int nare[MED_NBR_GEOMETRIE_ARETE];
91         /* nom du maillage */
92         char nommaa[MED_TAILLE_NOM + 1];
93         /* noeuds */
94         med_float *coo;
95         char nomcoo[3 * MED_TAILLE_PNOM + 1];
96         char unicoo[3 * MED_TAILLE_PNOM + 1];
97         char *nomnoe;
98         med_int *numnoe;
99         med_int *nufano;
100         med_repere rep;
101         med_booleen inonoe, inunoe;
102         med_mode_switch mode_coo;
103         char str[MED_TAILLE_PNOM + 1];
104         med_int nbNodes;
105         /* elements */
106         med_int nsup;
107         med_int edim;
108         med_int taille;
109         med_int elem_id, myId;
110         med_int *connectivite;
111         char *nomele;
112         med_int *numele;
113         med_int *nufael;
114         med_booleen inoele, inuele;
115         med_connectivite typ_con;
116         med_geometrie_element typgeo;
117         med_geometrie_element typmai[MED_NBR_GEOMETRIE_MAILLE] =
118                 { MED_POINT1, MED_SEG2,
119                 MED_SEG3, MED_TRIA3,
120                 MED_TRIA6, MED_QUAD4,
121                 MED_QUAD8, MED_TETRA4,
122                 MED_TETRA10, MED_HEXA8,
123                 MED_HEXA20, MED_PENTA6,
124                 MED_PENTA15, MED_PYRA5,
125                 MED_PYRA13
126         };
127         med_int desmai[MED_NBR_GEOMETRIE_MAILLE] =
128                 { 0, 2, 3, 3, 3, 4, 4, 4, 4, 6, 6, 5, 5, 5, 5 };
129         med_int nmailles[MED_NBR_GEOMETRIE_MAILLE];
130         char nommai[MED_NBR_GEOMETRIE_MAILLE][MED_TAILLE_NOM + 1] = { "MED_POINT1",
131                 "MED_SEG2",
132                 "MED_SEG3",
133                 "MED_TRIA3",
134                 "MED_TRIA6",
135                 "MED_QUAD4",
136                 "MED_QUAD8",
137                 "MED_TETRA4",
138                 "MED_TETRA10",
139                 "MED_HEXA8",
140                 "MED_HEXA20",
141                 "MED_PENTA6",
142                 "MED_PENTA15",
143                 "MED_PYRA5",
144                 "MED_PYRA13"
145         };
146         med_geometrie_element typfac[MED_NBR_GEOMETRIE_FACE] =
147                 { MED_TRIA3, MED_TRIA6,
148                 MED_QUAD4, MED_QUAD8
149         };
150         med_int desfac[MED_NBR_GEOMETRIE_FACE] = { 3, 3, 4, 4 };
151         med_int nfaces[MED_NBR_GEOMETRIE_FACE];
152         char nomfac[MED_NBR_GEOMETRIE_FACE][MED_TAILLE_NOM + 1] =
153                 { "MED_TRIA3", "MED_TRIA6",
154                 "MED_QUAD4", "MED_QUAD8"
155         };
156         med_geometrie_element typare[MED_NBR_GEOMETRIE_ARETE] =
157                 { MED_SEG2, MED_SEG3 };
158         med_int desare[MED_NBR_GEOMETRIE_ARETE] = { 2, 3 };
159         med_int naretes[MED_NBR_GEOMETRIE_ARETE];
160         char nomare[MED_NBR_GEOMETRIE_ARETE][MED_TAILLE_NOM + 1] =
161                 { "MED_SEG2", "MED_SEG3" };
162         /* familles */
163         med_int nfam;
164         med_int natt, ngro;
165         char *attdes, *gro;
166         med_int *attval, *attide;
167         char nomfam[MED_TAILLE_NOM + 1];
168         med_int numfam;
169         char str1[MED_TAILLE_DESC + 1];
170         char str2[MED_TAILLE_LNOM + 1];
171
172   /****************************************************************************
173   *                      OUVERTURE DU FICHIER EN ECRITURE                      *
174   ****************************************************************************/
175         /*!  char* file2Read = (char*)myFile.c_str();
176          * myFileId = MEDouvrir(file2Read,MED_REMP);
177          * if (myFileId < 0)
178          * {
179          * fprintf(stderr,">> ERREUR : ouverture du fichier %s \n",file2Read);
180          * exit(EXIT_FAILURE);
181          * }
182          */
183         typ_con = MED_NOD;
184         mode_coo = MED_FULL_INTERLACE;
185         numero = myMeshId;
186
187   /****************************************************************************
188   *                       NOMBRES D'OBJETS MED                                *
189   ****************************************************************************/
190         fprintf(stdout, "\n(****************************)\n");
191         fprintf(stdout, "(* INFORMATIONS GENERALES : *)\n");
192         fprintf(stdout, "(****************************)\n");
193
194         /* creation du maillage */
195         mdim = 3;
196         //nommaa = QString("Mesh "+myMeshId).latin1();
197         //nommaa = "";
198         //plutot recuperer le nom du maillage dans l'etude
199         if (ret == 0)
200                 ret = MEDmaaCr(myFileId, nommaa, mdim);
201         printf("%d\n", ret);
202
203         /* Combien de noeuds ? */
204         nnoe = myMesh->NbNodes();
205         //SCRUTE(nnoe);
206         /* Combien de mailles, faces ou aretes ? */
207         for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
208                 nmailles[i] = 0;
209
210         SMDS_Iterator<const SMDS_MeshFace *> * itFaces=myMesh->facesIterator();
211         int nb_of_nodes, nb_of_faces;
212         nb_of_faces = myMesh->NbFaces();
213         //SCRUTE(nb_of_faces);
214
215         //med_int elem_Id[MED_NBR_GEOMETRIE_FACE][nb_of_faces];
216         vector<int> elem_Id[MED_NBR_GEOMETRIE_MAILLE];
217         //typedef vector<int> Integer_vector;
218         //vector<Integer_vector> elem_Id;
219         //elem_Id.resize(MED_NBR_GEOMETRIE_MAILLE);
220
221         while(itFaces->more())
222         {
223                 const SMDS_MeshFace * elem = itFaces->next();
224
225                 nb_of_nodes = elem->NbNodes();
226
227                 switch (nb_of_nodes)
228                 {
229                 case 3:
230                 {
231                         //elem_Id[3][nmailles[3]] = elem->GetID();
232                         elem_Id[3].push_back(elem->GetID());
233                         nmailles[3]++;
234                         break;
235                 }
236                 case 4:
237                 {
238                         //elem_Id[5][nmailles[5]] = elem->GetID();
239                         elem_Id[5].push_back(elem->GetID());
240                         nmailles[5]++;
241                         break;
242                 }
243                 case 6:
244                 {
245                         //elem_Id[4][nmailles[4]] = elem->GetID();
246                         elem_Id[4].push_back(elem->GetID());
247                         nmailles[4]++;
248                         break;
249                 }
250                 }
251
252         }
253
254         SMDS_Iterator<const SMDS_MeshVolume*> * itVolumes=myMesh->volumesIterator();
255         while(itVolumes->more())
256         {
257                 const SMDS_MeshVolume * elem = itVolumes->next();
258
259                 nb_of_nodes = elem->NbNodes();
260                 switch (nb_of_nodes)
261                 {
262                 case 8:
263                 {
264                         //elem_Id[9][nmailles[9]] = elem->GetID();
265                         elem_Id[9].push_back(elem->GetID());
266                         nmailles[9]++;
267                         break;
268                 }
269                 case 4 :
270                 {
271                         elem_Id[7].push_back(elem->GetID());
272                         nmailles[7]++;
273                         break;
274                 }
275                 }
276         }
277
278   /****************************************************************************
279   *                       ECRITURE DES NOEUDS                                  *
280   ****************************************************************************/
281         fprintf(stdout, "\n(************************)\n");
282         fprintf(stdout, "(* NOEUDS DU MAILLAGE : *)\n");
283         fprintf(stdout, "(************************)\n");
284
285         /* Allocations memoires */
286         /* table des coordonnees 
287          * profil : (dimension * nombre de noeuds ) */
288         coo = (med_float *) malloc(sizeof(med_float) * nnoe * mdim);
289         /* table  des numeros, des numeros de familles des noeuds
290          * profil : (nombre de noeuds) */
291         numnoe = (med_int *) malloc(sizeof(med_int) * nnoe);
292         nufano = (med_int *) malloc(sizeof(med_int) * nnoe);
293         /* table des noms des noeuds 
294          * profil : (nnoe*MED_TAILLE_PNOM+1) */
295         nomnoe = "";
296
297         i = 0;
298         SMDS_Iterator<const SMDS_MeshNode *> * itNodes=myMesh->nodesIterator();
299         while(itNodes->more())
300         {               
301                 const SMDS_MeshNode * node = itNodes->next();
302                 coo[i * 3] = node->X();
303                 coo[i * 3 + 1] = node->Y();
304                 coo[i * 3 + 2] = node->Z();
305                 numnoe[i] = node->GetID();
306                 nufano[i] = 0;
307                 i++;
308         }
309
310         /* ecriture des noeuds : 
311          * - coordonnees
312          * - noms (optionnel dans un fichier MED) 
313          * - numeros (optionnel dans un fichier MED) 
314          * - numeros des familles */
315         ret = MEDnoeudsEcr(myFileId, nommaa, mdim, coo, mode_coo, MED_CART,
316                 nomcoo, unicoo, nomnoe, MED_FAUX, numnoe, MED_VRAI,
317                 nufano, nnoe, MED_REMP);
318
319         /* liberation memoire */
320         free(coo);
321         //free(nomnoe);
322         free(numnoe);
323         free(nufano);
324
325   /****************************************************************************
326   *                       ECRITURE DES ELEMENTS                                *
327   ****************************************************************************/
328         fprintf(stdout, "\n(**************************)\n");
329         fprintf(stdout, "(* ELEMENTS DU MAILLAGE : *)\n");
330         fprintf(stdout, "(**************************)");
331         //fprintf(Out,"CELLS\n");
332         /* Ecriture des connectivites, noms, numeros des mailles */
333
334         if (ret == 0)
335                 for (i = 0; i < MED_NBR_GEOMETRIE_MAILLE; i++)
336                 {
337                         if (nmailles[i] > 0 && ret == 0)
338                         {
339                                 MESSAGE(" Start " << typmai[i]);
340                                 /* dimension de la maille */
341                                 edim = typmai[i] / 100;
342                                 nsup = 0;
343                                 if (mdim == 2 || mdim == 3)
344                                         if (edim == 1)
345                                                 nsup = 1;
346                                 if (mdim == 3)
347                                         if (edim == 2)
348                                                 nsup = 1;
349
350                                 taille = nsup + typmai[i] % 100;
351                                 //taille = typmai[i]%100;
352
353                                 /* allocation memoire */
354                                 connectivite = (med_int *) malloc(sizeof(med_int) *
355                                         taille * nmailles[i]);
356                                 nomele = (char *)malloc(sizeof(char) * MED_TAILLE_PNOM *
357                                         nmailles[i] + 1);
358                                 numele = (med_int *) malloc(sizeof(med_int) * nmailles[i]);
359                                 nufael = (med_int *) malloc(sizeof(med_int) * nmailles[i]);
360                                 nomele = "";
361                                 nbNodes = typmai[i] % 100;
362
363                                 //penser a mater les (taille-nsup)
364                                 for (j = 0; j < nmailles[i]; j++)
365                                 {
366                                         myId = elem_Id[i][j];
367                                         const SMDS_MeshElement * elem =
368                                                 myMesh->FindElement(myId);
369                                         *(numele + j) = myId;
370                                         //elem_id=*(numele+j);
371                                         //fprintf(stdout,"%d \n",myId);
372
373                                         SMDS_Iterator<const SMDS_MeshElement *> * itNode=
374                                                 elem->nodesIterator();
375
376                                         while(itNode->more())
377                                         {
378                                                 //*(connectivite+j*(taille-1)+k)=cnx[k];
379                                                 *(connectivite + j * (taille - nsup) + k) =
380                                                         itNode->next()->GetID();
381                                                 //fprintf(stdout,"%d ",*(connectivite+j*(taille-nsup)+k));
382                                         }
383                                         nufael[j] = 0;
384                                         //fprintf(stdout,"\n");
385                                 }
386
387                                 /* ecriture des donnĂ©es */
388
389                                 ret =
390                                         MEDelementsEcr(myFileId, nommaa, mdim, connectivite,
391                                         mode_coo, nomele, MED_FAUX, numele, MED_VRAI, nufael,
392                                         nmailles[i], MED_MAILLE, typmai[i], typ_con, MED_REMP);
393
394                                 if (ret < 0)
395                                         MESSAGE(">> ERREUR : lecture des mailles \n");
396
397                                 /* liberation memoire */
398                                 free(connectivite);
399                                 //free(nomele);
400                                 free(numele);
401                                 free(nufael);
402                                 MESSAGE(" End " << typmai[i]);
403                         }
404                 }
405
406   /****************************************************************************
407   *                      FERMETURE DU FICHIER                                 *
408   ****************************************************************************/
409
410         /*!  ret = MEDfermer(myFileId);
411          * 
412          * if (ret != 0)
413          * fprintf(stderr,">> ERREUR : erreur a la fermeture du fichier %s\n",file2Read);
414          */
415
416 }