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