Salome HOME
Copyright update 2022
[modules/homard.git] / src / HOMARD_I / HomardMedCommun.cxx
1 // Copyright (C) 2011-2022  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include "HomardMedCommun.h"
21
22 #include <iostream>
23 #include <cstdlib>
24 #include <cmath>
25 #include <cstring>
26 #include <algorithm>
27
28 #include <med.h>
29
30 #include "utilities.h"
31 // =======================================================================
32 int MEDFileExist( const char * aFile )
33 // Retourne 1 si le fichier existe, 0 sinon
34 // =======================================================================
35 {
36   int existe ;
37   med_idt medIdt = MEDfileOpen(aFile,MED_ACC_RDONLY);
38   if ( medIdt < 0 ) { existe = 0 ; }
39   else              { MEDfileClose(medIdt);
40                       existe = 1 ; }
41   return existe ;
42 }
43 // =======================================================================
44 std::set<std::string> GetListeGroupesInMedFile(const char * aFile)
45 // =======================================================================
46 {
47   std::set<std::string> ListeGroupes;
48   med_err erreur = 0 ;
49   med_idt medIdt ;
50   while ( erreur == 0 )
51   {
52     //  Ouverture du fichier
53     medIdt = MEDfileOpen(aFile,MED_ACC_RDONLY);
54     if ( medIdt < 0 )
55     {
56       erreur = 1 ;
57       break ;
58     }
59     // Caracteristiques du maillage
60     char meshname[MED_NAME_SIZE+1];
61     med_int spacedim,meshdim;
62     med_mesh_type meshtype;
63     char descriptionription[MED_COMMENT_SIZE+1];
64     char dtunit[MED_SNAME_SIZE+1];
65     med_sorting_type sortingtype;
66     med_int nstep;
67     med_axis_type axistype;
68     int naxis = MEDmeshnAxis(medIdt,1);
69     char *axisname=new char[naxis*MED_SNAME_SIZE+1];
70     char *axisunit=new char[naxis*MED_SNAME_SIZE+1];
71     erreur = MEDmeshInfo(medIdt,
72                             1,
73                             meshname,
74                             &spacedim,
75                             &meshdim,
76                             &meshtype,
77                             descriptionription,
78                             dtunit,
79                             &sortingtype,
80                             &nstep,
81                             &axistype,
82                             axisname,
83                             axisunit);
84     delete[] axisname ;
85     delete[] axisunit ;
86     if ( erreur < 0 ) { break ; }
87     // Nombre de familles
88     med_int nfam ;
89     nfam = MEDnFamily(medIdt,meshname) ;
90     if ( nfam < 0 )
91     {
92       erreur = 2 ;
93       break ;
94     }
95   // Lecture des caracteristiques des familles
96     for (int i=0;i<nfam;i++)
97     {
98 //       Lecture du nombre de groupes
99       med_int ngro = MEDnFamilyGroup(medIdt,meshname,i+1);
100       if ( ngro < 0 )
101       {
102         erreur = 3 ;
103         break ;
104       }
105 //       Lecture de la famille
106       else if ( ngro > 0 )
107       {
108         char familyname[MED_NAME_SIZE+1];
109         med_int numfam;
110         char* gro = (char*) malloc(MED_LNAME_SIZE*ngro+1);
111         erreur = MEDfamilyInfo(medIdt,
112                                meshname,
113                                i+1,
114                                familyname,
115                                &numfam,
116                                gro);
117         if ( erreur < 0 )
118         {
119           free(gro);
120           break ;
121         }
122         // Lecture des groupes pour une famille de mailles
123         if ( numfam < 0)
124         {
125           for (int j=0;j<ngro;j++)
126           {
127             char str2[MED_LNAME_SIZE+1];
128             strncpy(str2,gro+j*MED_LNAME_SIZE,MED_LNAME_SIZE);
129             str2[MED_LNAME_SIZE] = '\0';
130             ListeGroupes.insert(std::string(str2));
131           }
132         }
133         free(gro);
134       }
135     }
136     break ;
137   }
138   // Fermeture du fichier
139   if ( medIdt > 0 ) MEDfileClose(medIdt);
140
141   return ListeGroupes;
142 }
143
144 // =======================================================================
145 std::vector<double> GetBoundingBoxInMedFile(const char * aFile)
146 // =======================================================================
147 {
148 // Le vecteur en retour contiendra les informations suivantes :
149 // en position 0 et 1 Xmin, Xmax et en position 2 Dx si < 0  2D
150 // en position 3 et 4 Ymin, Ymax et en position 5 Dy si < 0  2D
151 // en position 6 et 7 Zmin, Zmax et en position 8 Dz si < 0  2D
152 //  9 distance max dans le maillage
153
154   std::vector<double> LesExtremes;
155   med_err erreur = 0 ;
156   med_idt medIdt ;
157   while ( erreur == 0 )
158   {
159     //  Ouverture du fichier
160     medIdt = MEDfileOpen(aFile,MED_ACC_RDONLY);
161     if ( medIdt < 0 )
162     {
163       erreur = 1 ;
164       break ;
165     }
166     //Nombre de maillage : on ne peut en lire qu'un seul
167     med_int numberOfMeshes = MEDnMesh(medIdt) ;
168     if (numberOfMeshes != 1 )
169     {
170       erreur = 2 ;
171       break ;
172     }
173     // Caracteristiques du maillage
174     char meshname[MED_NAME_SIZE+1];
175     med_int spacedim,meshdim;
176     med_mesh_type meshtype;
177     char descriptionription[MED_COMMENT_SIZE+1];
178     char dtunit[MED_SNAME_SIZE+1];
179     med_sorting_type sortingtype;
180     med_int nstep;
181     med_axis_type axistype;
182     int naxis = MEDmeshnAxis(medIdt,1);
183     char *axisname=new char[naxis*MED_SNAME_SIZE+1];
184     char *axisunit=new char[naxis*MED_SNAME_SIZE+1];
185     erreur = MEDmeshInfo(medIdt,
186                             1,
187                             meshname,
188                             &spacedim,
189                             &meshdim,
190                             &meshtype,
191                             descriptionription,
192                             dtunit,
193                             &sortingtype,
194                             &nstep,
195                             &axistype,
196                             axisname,
197                             axisunit);
198     delete[] axisname ;
199     delete[] axisunit ;
200     if ( erreur < 0 ) { break ; }
201
202     // Nombre de noeuds
203     med_bool chgt,trsf;
204     med_int nnoe  = MEDmeshnEntity(medIdt,
205                               meshname,
206                               MED_NO_DT,
207                               MED_NO_IT,
208                               MED_NODE,
209                               MED_NO_GEOTYPE,
210                               MED_COORDINATE,
211                               MED_NO_CMODE,
212                               &chgt,
213                               &trsf);
214     if ( nnoe < 0 )
215     {
216       erreur =  4;
217       break ;
218     }
219
220     // Les coordonnees
221     med_float* coo    = (med_float*) malloc(sizeof(med_float)*nnoe*spacedim);
222
223     erreur = MEDmeshNodeCoordinateRd(medIdt,
224                                       meshname,
225                                       MED_NO_DT,
226                                       MED_NO_IT,
227                                       MED_NO_INTERLACE,
228                                       coo);
229     if ( erreur < 0 )
230     {
231       free(coo) ;
232       break ;
233     }
234
235     // Calcul des extremes
236     med_float xmin,xmax,ymin,ymax,zmin,zmax;
237
238     xmin=coo[0];
239     xmax=coo[0];
240     for (int i=1;i<nnoe;i++)
241     {
242         xmin = std::min(xmin,coo[i]);
243         xmax = std::max(xmax,coo[i]);
244     }
245   //
246     if (spacedim > 1)
247     {
248         ymin=coo[nnoe]; ymax=coo[nnoe];
249         for (int i=nnoe+1;i<2*nnoe;i++)
250         {
251             ymin = std::min(ymin,coo[i]);
252             ymax = std::max(ymax,coo[i]);
253         }
254     }
255     else
256     {
257         ymin=0;
258         ymax=0;
259         zmin=0;
260         zmax=0;
261     }
262 //
263     if (spacedim > 2)
264     {
265         zmin=coo[2*nnoe]; zmax=coo[2*nnoe];
266         for (int i=2*nnoe+1;i<3*nnoe;i++)
267         {
268             zmin = std::min(zmin,coo[i]);
269             zmax = std::max(zmax,coo[i]);
270         }
271     }
272     else
273     {
274         zmin=0;
275         zmax=0;
276     }
277
278     MESSAGE( "_______________________________________");
279     MESSAGE( "xmin : " << xmin << " xmax : " << xmax );
280     MESSAGE( "ymin : " << ymin << " ymax : " << ymax );
281     MESSAGE( "zmin : " << zmin << " zmax : " << zmax );
282     MESSAGE( "_______________________________________" );
283     double epsilon = 1.e-6 ;
284     LesExtremes.push_back(xmin);
285     LesExtremes.push_back(xmax);
286     LesExtremes.push_back(0);
287     LesExtremes.push_back(ymin);
288     LesExtremes.push_back(ymax);
289     LesExtremes.push_back(0);
290     LesExtremes.push_back(zmin);
291     LesExtremes.push_back(zmax);
292     LesExtremes.push_back(0);
293
294
295    double max1=std::max ( LesExtremes[1] - LesExtremes[0] , LesExtremes[4] - LesExtremes[3] ) ;
296    double max2=std::max ( max1 , LesExtremes[7] - LesExtremes[6] ) ;
297    LesExtremes.push_back(max2);
298
299 // LesExtremes[0] = Xmini du maillage
300 // LesExtremes[1] = Xmaxi du maillage
301 // LesExtremes[2] = increment de progression en X
302 // LesExtremes[3,4,5] : idem pour Y
303 // LesExtremes[6,7,8] : idem pour Z
304 // LesExtremes[9] = ecart maximal entre coordonnees
305 // On fait un traitement pour dans le cas d'une coordonnee constante
306 // inhiber ce cas en mettant un increment negatif
307 //
308     double diff = LesExtremes[1] - LesExtremes[0];
309     if ( fabs(diff) > epsilon*max2 ) { LesExtremes[2] = diff/100.; }
310     else                             { LesExtremes[2] = -1. ; }
311
312     diff = LesExtremes[4] - LesExtremes[3];
313     if ( fabs(diff) > epsilon*max2 ) { LesExtremes[5]=diff/100.; }
314     else                             { LesExtremes[5] = -1. ; }
315
316     diff = LesExtremes[7] - LesExtremes[6];
317     if ( fabs(diff) > epsilon*max2 ) { LesExtremes[8]=diff/100.; }
318     else                             { LesExtremes[8] = -1. ;  }
319
320     MESSAGE ( "_______________________________________" );
321     MESSAGE ( "xmin : " << LesExtremes[0] << " xmax : " << LesExtremes[1] << " xincr : " << LesExtremes[2] );
322     MESSAGE ( "ymin : " << LesExtremes[3] << " ymax : " << LesExtremes[4] << " yincr : " << LesExtremes[5] );
323     MESSAGE ( "zmin : " << LesExtremes[6] << " zmax : " << LesExtremes[7] << " zincr : " << LesExtremes[8] );
324     MESSAGE ( "dmax : " << LesExtremes[9] );
325     MESSAGE ( "_______________________________________" );
326
327     free(coo) ;
328     break ;
329   }
330   // Fermeture du fichier
331   if ( medIdt > 0 ) MEDfileClose(medIdt);
332
333    return  LesExtremes;
334 }
335