Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/med.git] / src / MEDMEM / test_profil_gauss_MedFieldDriver.cxx
1 // Copyright (C) 2005  OPEN CASCADE, CEA, EDF R&D, LEG
2 //           PRINCIPIA R&D, EADS CCR, Lip6, BV, CEDRAT
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.
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 <stdlib.h>
21 #include<string>
22
23 #include "MEDMEM_Exception.hxx"
24 #include "MEDMEM_Mesh.hxx"
25 #include "MEDMEM_MedMeshDriver.hxx"
26 #include "MEDMEM_Field.hxx"
27 #include "MEDMEM_MedFieldDriver.hxx"
28 #include "MEDMEM_Support.hxx"
29 #include "MEDMEM_define.hxx"
30 #include "MEDMEM_GaussLocalization.hxx"
31
32 using namespace std;
33 using namespace MEDMEM;
34 using namespace MED_EN;
35
36 #define INTERLACING_MODE FullInterlace
37 int fct2(int i,const int * number) { return i;};
38 int fct1(int i,const int * number) { return number[i]; };
39
40 void affiche_field_(FIELD_ * myField)
41 {
42   cout << "Field "<< myField->getName() << " : " <<myField->getDescription() <<  endl ;
43   int NumberOfComponents = myField->getNumberOfComponents() ;
44   cout << "- Nombre de composantes : "<< NumberOfComponents << endl ;
45   for (int i=1; i<NumberOfComponents+1; i++) {
46     cout << "  - composante "<<i<<" :"<<endl ;
47     cout << "      - nom         : "<<myField->getComponentName(i)<< endl;
48     cout << "      - description : "<<myField->getComponentDescription(i) << endl;
49     cout << "      - units       : "<<myField->getMEDComponentUnit(i) << endl;
50   }
51   cout << "- iteration :" << endl ;
52   cout << "    - numero : " << myField->getIterationNumber()<< endl  ;
53   cout << "    - ordre  : " << myField->getOrderNumber()<< endl  ;
54   cout << "    - temps  : " << myField->getTime()<< endl  ;
55
56   cout << "- Type : " << myField->getValueType()<< endl;
57   //PRESENCE DE POINTS DE GAUSS
58 }
59
60 // Cas de traitement des valeurs sans spécificité concernant
61 // les points de Gauss ou les profils
62 // Pas de spécificité concernant le type géométrique
63 template <class INTERLACING_TAG>
64 void affiche_fieldT(FIELD<double,INTERLACING_TAG> * myField)
65 {
66   const double * value = 0;
67   affiche_field_((FIELD_ *) myField);
68
69   cout.setf(ios::fixed);
70
71   int numberOf              = myField->getNumberOfValues();
72   int numberOfComponents    = myField->getNumberOfComponents() ;
73   int valueLength           = myField->getValueLength();
74   int numberOfGeometricType = myField->getNumberOfGeometricTypes();
75   const int * nbOfElements  = myField->getNumberOfElements();
76   const MED_EN::medGeometryElement * typeList      = myField->getGeometricTypes();
77   // Suivant le traitement, on peut faire sortir  si il y a des points de Gauss
78   // ou des profils
79
80   cout << "myField->getValueLength        (MED_ALL_ELEMENTS) : " << valueLength << endl;
81   cout << "myField->getNumberOfElements   (MED_ALL_ELEMENTS) : " << numberOf   << endl;
82   cout << "myField->getNumberOfComponents ()                 : " << numberOfComponents << endl;
83   cout << "myField->getNumberOfGeometricType ()              : " << numberOfGeometricType << endl;
84   for (int i=0; i < numberOfGeometricType; i++) {
85     cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]]
86          <<" : "<< nbOfElements[i] << endl;
87     cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]]
88          <<" : "<< myField->getNumberOfGaussPoints(typeList[i]) << endl;
89     cout << "Localization description : " << endl << myField->getGaussLocalization(typeList[i]) << endl;
90   }
91
92   cout << "- Valeurs :"<<endl;
93   for (int index=0; index < valueLength; index++) {
94     cout << "value["<<index<<"] = "<< value[index];
95     cout<<endl;
96   }
97
98 }
99
100 // Spécialisation du traitement pour le mode FullInterlace
101 // Spécifité de traitement par rapport aux profils (utilisation du SUPPORT)
102 // Pas de spécificité concernant le type géométrique
103 // Pas de spécificité concernant les points de Gauss
104 template <>
105 void affiche_fieldT(FIELD<double, FullInterlace> * myField)
106 {
107   const double * value = 0;
108   const int    * number = 0;
109
110   affiche_field_((FIELD_ *) myField);
111   const SUPPORT * mySupport=myField->getSupport();
112
113   cout.setf(ios::fixed);
114
115
116   int numberOfComponents    = myField->getNumberOfComponents() ;
117   int valueLength           = myField->getValueLength();
118   const int * nbGaussPoints = myField->getNumberOfGaussPoints();
119
120   int numberOf              = mySupport->getNumberOfElements(MED_ALL_ELEMENTS);
121   int numberOfGeometricType = mySupport->getNumberOfTypes();
122   const int * nbOfElements  = mySupport->getNumberOfElements();
123   const MED_EN::medGeometryElement * typeList      = mySupport->getTypes();
124   bool  onAll               = mySupport->isOnAllElements();
125
126   cout << "mySupport->getValueLength           (MED_ALL_ELEMENTS) : " << valueLength << endl;
127   cout << "mySupport->getNumberOfElements      (MED_ALL_ELEMENTS) : " << numberOf   << endl;
128   cout << "mySupport->getNumberOfComponents    ()                 : " << numberOfComponents << endl;
129   cout << "mySupport->getNumberOfGeometricType ()                 : " << numberOfGeometricType << endl;
130   assert(numberOf == myField->getNumberOfValues() );
131
132   // S'il existe des profils, je récupère la liste des numéros d'éléments
133   // pour tous les types géométriques
134   for (int i=0; i < numberOfGeometricType; i++) {
135     cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]]
136          <<" : "<< nbOfElements[i] << endl;
137     cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]]
138          <<" : "<< nbGaussPoints[i] << endl;
139     cout << "Localization description : " << endl << myField->getGaussLocalization(typeList[i]) << endl;
140   }
141
142   // On récupère la liste complète
143   if (!onAll) number = mySupport->getNumber(MED_ALL_ELEMENTS);
144
145   int elNo = -1;
146   cout << "- Valeurs :" << endl;
147   for (int i=1; i<=numberOf; i++) {
148     if (onAll) elNo = i; else elNo = number[i-1];
149     //cout << endl << "myField->getRow("<<elNo<<") : "<< myField->getRow(elNo) << endl;
150     value = myField->getRow(elNo) ;
151     //UP: getRow prend un numéro d'élément qui existe, getRow(1) n'existe pas forcément si il y a un profil
152     //qui ne défini pas cet indice
153     //cout << endl << " Valeur de getNbGaussI("<<elNo<<") :" << myField->getNbGaussI(elNo) << endl;
154     for (int j=0; j<numberOfComponents*myField->getNbGaussI(elNo); j++)
155       //UP : Prend en compte le nombre de points de Gauss de l'élément elNo
156       cout << "value["<< elNo << "] = " << value[j] << " ";
157     cout<<endl;
158   }
159
160 }
161
162 // Spécialisation du traitement pour le mode NoInterlace
163 // Spécifité de traitement par rapport aux profils (utilisation du SUPPORT)
164 // Pas de spécificité concernant le type géométrique
165 // Pas de spécificité concernant les points de Gauss
166 template <>
167 void affiche_fieldT(FIELD<double, NoInterlace> * myField)
168 {
169   const double * value = 0;
170   const int    * number = 0;
171
172   affiche_field_((FIELD_ *) myField);
173   const SUPPORT * mySupport=myField->getSupport();
174
175   cout.setf(ios::fixed);
176
177
178   int numberOfComponents    = myField->getNumberOfComponents() ;
179   int valueLength           = myField->getValueLength();
180   const int * nbGaussPoints = myField->getNumberOfGaussPoints();
181
182   int numberOf              = mySupport->getNumberOfElements(MED_ALL_ELEMENTS);
183   int numberOfGeometricType = mySupport->getNumberOfTypes();
184   const int * nbOfElements  = mySupport->getNumberOfElements();
185   const MED_EN::medGeometryElement * typeList      = mySupport->getTypes();
186   bool  onAll               = mySupport->isOnAllElements();
187
188   cout << "mySupport->getValueLength           (MED_ALL_ELEMENTS) : " << valueLength << endl;
189   cout << "mySupport->getNumberOfElements      (MED_ALL_ELEMENTS) : " << numberOf   << endl;
190   cout << "mySupport->getNumberOfComponents    ()                 : " << numberOfComponents << endl;
191   cout << "mySupport->getNumberOfGeometricType ()                 : " << numberOfGeometricType << endl;
192   cout << "mySupport->getNumberOfElements(MED_ALL_ELEMENTS)       : " << numberOf << endl;
193   assert(numberOf == myField->getNumberOfValues() );
194
195   // S'il existe des profils, je récupère la liste des numéros d'éléments
196   // pour tous les types géométriques
197   for (int i=0; i < numberOfGeometricType; i++) {
198     cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]]
199          <<" : "<< nbOfElements[i] << endl;
200     cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]]
201          <<" : "<< nbGaussPoints[i] << endl;
202     cout << "Localization description : " << endl << myField->getGaussLocalization(typeList[i]) << endl;
203   }
204
205
206   int (* fct)(int,const int *);
207
208   if (!onAll) {
209     number = mySupport->getNumber(MED_ALL_ELEMENTS);
210     fct=fct1;
211   } else
212     fct=fct2;
213
214   int oneDimlength = valueLength/numberOfComponents;
215   for (int j=1; j<=numberOfComponents; j++) {
216     value = myField->getColumn(j) ;
217     for (int i=0; i<oneDimlength; i++)
218       cout << "value["<< fct(i,number) << ","<<j<<"]" << value[ fct(i,number) ] << " ";
219     cout<<endl;
220   }
221
222 }
223
224
225 template <class T, class INTERLACING_TAG>
226 void affiche_fieldT2(FIELD< T,  INTERLACING_TAG> * myField)
227 {};
228
229
230 // Spécialisation du traitement pour le mode FullInterlace
231 // Spécifité de traitement par rapport aux profils (utilisation du SUPPORT)
232 // Spécificité concernant le type géométrique
233 // Spécificité concernant les points de Gauss
234 template <>
235 void affiche_fieldT2(FIELD<double, FullInterlace> * myField)
236 {
237   const int    * number = 0;
238
239   affiche_field_((FIELD_ *) myField);
240   const SUPPORT * mySupport=myField->getSupport();
241
242   cout.setf(ios::fixed);
243
244
245   int numberOfComponents    = myField->getNumberOfComponents() ;
246   int valueLength           = myField->getValueLength();
247   const int * nbGaussPoints = myField->getNumberOfGaussPoints();
248
249   int numberOf              = mySupport->getNumberOfElements(MED_ALL_ELEMENTS);
250   int numberOfGeometricType = mySupport->getNumberOfTypes();
251   const int * nbOfElements  = mySupport->getNumberOfElements();
252   const MED_EN::medGeometryElement * typeList      = mySupport->getTypes();
253   bool  onAll               = mySupport->isOnAllElements();
254
255   cout << "mySupport->getValueLength           (MED_ALL_ELEMENTS) : " << valueLength << endl;
256   cout << "mySupport->getNumberOfElements      (MED_ALL_ELEMENTS) : " << numberOf   << endl;
257   cout << "mySupport->getNumberOfComponents    ()                 : " << numberOfComponents << endl;
258   cout << "mySupport->getNumberOfGeometricType ()                 : " << numberOfGeometricType << endl;
259   cout << "mySupport->getNumberOfElements(MED_ALL_ELEMENTS)       : " << numberOf << endl;
260   assert(numberOf == myField->getNumberOfValues() );
261
262   // S'il existe des profils, je récupère la liste des numéros d'éléments
263   // pour tous les types géométriques
264   for (int i=0; i < numberOfGeometricType; i++) {
265     cout << "Number Of Elements on type "<< MED_EN::geoNames[typeList[i]]
266          <<" : "<< nbOfElements[i] << endl;
267     cout << "Number Of Gauss Points on type "<< MED_EN::geoNames[typeList[i]]
268          <<" : "<< nbGaussPoints[i] << endl;
269   }
270
271
272   int (* fct)(int,const int *);
273
274   if (!onAll) {
275     number = mySupport->getNumber(MED_ALL_ELEMENTS);
276     fct=fct1;
277   } else
278     fct=fct2;
279
280   cout << "- Valeurs :"<<endl;
281
282   int elemno = 1;
283   for (int ntyp=1; ntyp <= numberOfGeometricType; ntyp++ ) {
284     for (int  i=0; i < nbOfElements[ntyp-1] ; i++ ) {
285       for (int k=1; k <= nbGaussPoints[ntyp-1]; k++)
286         for (int j=1; j <= numberOfComponents; j++) {
287           cout << " value["<< fct(elemno-1,number) << "," <<j<<","<<k<<"] = "
288           << myField->getValueIJK(fct(elemno-1,number),j,k);
289         }
290       elemno++;
291       cout << endl;
292     }
293   }
294
295   assert((elemno-1) == numberOf);
296
297 }
298
299
300 int main (int argc, char ** argv) {
301
302   if ((argc !=3) && (argc != 5)) {
303     cerr << "Usage : " << argv[0]
304          << " filename fieldName [iterationNumber] [orderNumber]" << endl << endl;
305     exit(-1);
306   }
307
308   string fileName  = argv[1] ;
309   string fieldName = argv[2] ;
310   int  iterationNumber=-1,orderNumber=-1;
311   if ( argv[3] )  iterationNumber = atoi(argv[3]);
312   if ( argv[4] )  orderNumber     = atoi(argv[4]);
313
314   string meshName="";//"MAILTRQU";
315   //goto mode2;
316   /////////////////////////////////////////////////////////////////////////////////////////
317     // TEST PREMIER MODE :
318     // Le fichier MED lu contient le maillage associé au champ demandé (qui contient des profils )
319     // Le driver du FIELD automatiquement crée est capable de lire les profils MEDFICHIER
320     // (le SUPPORT est crée automatiquement, le nom du maillage associé est disponible dans
321     // le SUPPORT mais la relation SUPPORT-MESH est non initialisée car le MESH n'est pas chargé).
322     // Le driver utilise les informations du maillage dans le fichier pour transcrire les profils
323     // de la numérotation locale MEDFICHIER à la numérotation globale MEDMEMOIRE).
324     // A l'écriture, il se repose également sur le maillage contenu dans le fichier
325     // pour effecuter la renumérotation.
326     {
327       FIELD<double,INTERLACING_MODE> * myField1  = new FIELD<double,INTERLACING_MODE>(MED_DRIVER,fileName,fieldName,
328                                                                                       iterationNumber, orderNumber);
329       affiche_fieldT(myField1);
330       cout << endl;
331       affiche_fieldT2(myField1);
332
333       // Pour éviter de modifier le fichier d'origine,
334       // on en crée une copie avec uniquement le maillage.
335       // Rem : Pour le test, le chargement du maillage n'est pas nécessaire
336       //       On pourrait réécrire le Champ dans le fichier d'origine
337       //       sous un autre nom.
338       // Attention si le driver MED_MESH modifie le nombre d'éléments d'un type géométrique :
339       // le calcul de renumérotation à l'écriture du champ risque d'être faux !
340       meshName = myField1->getSupport()->getMeshName();
341       MESH * myMesh = new MESH(MED_DRIVER,fileName,meshName);
342       MED_MESH_WRONLY_DRIVER myMeshDriver1("Copy_withmesh_"+fileName,myMesh);
343       int current=myMesh->addDriver(myMeshDriver1);
344       myMesh->write(current);
345       delete myMesh;
346
347       // On ajoute un driver en écriture, comme la relation SUPPORT-MESH n'est pas
348       // initialisée, le driver doit trouver le maillage dans le fichier cible
349       // pour réaliser la transcription des profils MEDMEMOIRE à MEDFICHIER.
350       MED_FIELD_WRONLY_DRIVER<double> myFieldDriver2("Copy_withmesh_"+fileName,myField1) ;
351       current = myField1->addDriver(myFieldDriver2);
352       myField1->write(current);
353       delete myField1;
354     }
355
356  mode2:
357     /////////////////////////////////////////////////////////////////////////////
358       // TEST DEUXIEME MODE :
359       // Lecture idem 1er mode
360       // A l'écriture, le fichier cible ne contient pas le maillage mais la
361       // relation SUPPORT-MESH est établie, le driver peut donc utiliser les informations
362       // dans le maillage pour transcrire les profils.
363       // Selon le modèle MED FICHIER, ce mode est interdit : le fichier doit au moins
364       // contenir un lien sur le maillage (information pas encore exploitée dans MEDMEMOIRE
365       // : pas de gestion de montage/démontage des fichiers )
366       // Attention si le driver MED_MESH modifie le nombre d'éléments d'un type géométrique :
367       // le calcul de renumérotation à l'écriture du champ risque d'être faux car les
368       // profils crées à la lecture sont basés sur le nombre d'éléments par type géoémtrique
369       // du maillage contenu dans le fichier à la lecture.
370       // Une solution consisterait à prendre en compte le montage de fichiers distants
371       // et de prendre en compte la différence de nombre d'éléments par type géométrique
372       // entre le maillage MEDMEM et le maillage MEDFICHIER
373       // (Hum ! : Il serait plus simple que MEDMEMOIRE ne recalcule pas systématiquement
374       //  ce que l'on ne lui demande pas, ce qui permettrait aussi de réécrire à l'identique
375       // un fichier que l'on vient de lire)
376    {
377      FIELD<double,INTERLACING_MODE> * myField2  = new FIELD<double,INTERLACING_MODE>(MED_DRIVER,fileName,fieldName,
378                                                                                      iterationNumber, orderNumber);
379
380      meshName = myField2->getSupport()->getMeshName();
381      MESH * myMesh2 = new MESH(MED_DRIVER,fileName,meshName);
382
383      const SUPPORT * mySupport2=myField2->getSupport();
384      mySupport2->setMesh(myMesh2);
385
386      // On ajoute un driver en écriture, comme la relation SUPPORT-MESH est
387      // initialisée, le driver utilise le maillage en mémoire
388      // pour réaliser la transcription des profils MEDMEMOIRE à MEDFICHIER.
389      MED_FIELD_WRONLY_DRIVER<double> myFieldDriver3("Copy_nomesh_"+fileName,myField2) ;
390      int current = myField2->addDriver(myFieldDriver3);
391      myField2->write(current);
392
393      //Pour regarder le fichier produit avec MDUMP decommenter ces trois lignes
394      //car le fichier qui est produit n'est pas à la norme MED
395      //Il doit contenir soit le maillage associé soit un lien vers le maillage associé.
396      //MED_MESH_WRONLY_DRIVER myMeshDriver2("Copy_nomesh_"+fileName,myMesh2);
397      //current=myMesh2->addDriver(myMeshDriver2);
398      //myMesh2->write(current);
399
400      delete myField2;
401      delete myMesh2;
402
403
404    }
405  mode3:
406    // TEST TROISIEME MODE  :
407    // A la lecture, le fichier MED lu ne contient pas le maillage  associé au champ demandé
408    // (mais un lien MEDFICHIER qui n'est pas exploité à ce jour).
409    // Cependant avant sa lecture le FIELD a été associé à un SUPPORT
410    // avec le lien au MESH préalablement chargé.
411    // Le driver du FIELD (automatiquement crée) est capable de lire les profils MEDFICHIER
412    //   et utilise la relation SUPPORT-MESH initialisée pour transcrire les profils
413    //   de la numérotation locale MEDFICHIER à la numérotation globale MEDMEMOIRE).
414    // REM: Une fois le champ chargé, il possède un nouveau support, le premier peut être libéré.
415    //      En effet le driver du FIELD se fit uniquement au type géométriques définis dans le champ MEDFICHIER
416    //      pour créer son SUPPORT car un SUPPORT crée "onAll" à partir d'un MESH repose sur tous
417    //      les types géométriques du MESH ce qui n'est pas forcément le cas d'un champ MEDFICHIER
418    //      (même sans profil) lu à posteriori.
419    {
420      med_2_3::med_err err=-1;
421      med_2_3::med_idt id = med_2_3::MEDouvrir(const_cast<char *> ( ("Copy_nomesh_"+fileName).c_str()),
422                                               med_2_3::MED_LECTURE_ECRITURE);
423      if (id <=0) cout << "Erreur dans MEDouvrir pour le fichier " << "Copy_nomesh_"+fileName <<endl;
424
425      err=med_2_3::MEDlienEcr(id, const_cast<char *> ( ("Copy_withmesh_"+fileName).c_str()),
426                              const_cast<char *> (meshName.c_str()) );
427      if (err !=0) cout << "Erreur dans MEDlienEcr pour le maillage distant " << meshName
428                        <<" contenu dans le fichier " << "Copy_withmesh_"+fileName <<endl;
429
430
431      err=med_2_3::MEDfermer(id);
432
433      MESH * myMesh3 = new MESH(MED_DRIVER,fileName,meshName);
434      const SUPPORT * mySupport3= new SUPPORT(myMesh3,"Temporary Support",MED_CELL);
435      FIELD<double,INTERLACING_MODE> * myField3  = new FIELD<double,INTERLACING_MODE>(mySupport3,MED_DRIVER,"Copy_nomesh_"+fileName,fieldName, iterationNumber, orderNumber);
436      delete mySupport3; // Il est déjà possible de libérer ce SUPPORT
437
438      //TEST à la réecriture (renommage des profils
439      // à cause de MEDprofilEcr qui ne prend pas en compte le mode
440      // MED_LECTURE_AJOUT) ):
441      string cpy("__Copy");
442      vector < string > pflNames = myField3->getSupport()->getProfilNames();
443      for (int i=0; i< pflNames.size(); ++i) {
444        pflNames[i].resize(pflNames[i].size()-cpy.size());
445        pflNames[i]+=cpy;
446      }
447      const_cast<SUPPORT*>(myField3->getSupport())->setProfilNames(pflNames);
448
449      MED_FIELD_WRONLY_DRIVER<double> myFieldDriver4("Copy_nomesh_"+fileName,myField3) ;
450      myFieldDriver4.setFieldName(myField3->getName()+"__Copy");
451      int current = myField3->addDriver(myFieldDriver4);
452      myField3->write(current);
453
454      delete myMesh3;
455      delete myField3;
456
457
458      //ESSAYER AVEC MAILLAGE DS FICHIER ET LIEN SUPORT-MESH PRESENTS SIMULTANEMENT
459      //EN VERSION COHERENTE ET NON COHERENTE
460    }
461 }