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.
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.
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
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
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"
33 using namespace MEDMEM;
34 using namespace MED_EN;
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]; };
40 void affiche_field_(FIELD_ * myField)
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;
51 cout << "- iteration :" << endl ;
52 cout << " - numero : " << myField->getIterationNumber()<< endl ;
53 cout << " - ordre : " << myField->getOrderNumber()<< endl ;
54 cout << " - temps : " << myField->getTime()<< endl ;
56 cout << "- Type : " << myField->getValueType()<< endl;
57 //PRESENCE DE POINTS DE GAUSS
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)
66 const double * value = 0;
67 affiche_field_((FIELD_ *) myField);
69 cout.setf(ios::fixed);
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
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;
92 cout << "- Valeurs :"<<endl;
93 for (int index=0; index < valueLength; index++) {
94 cout << "value["<<index<<"] = "<< value[index];
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
105 void affiche_fieldT(FIELD<double, FullInterlace> * myField)
107 const double * value = 0;
108 const int * number = 0;
110 affiche_field_((FIELD_ *) myField);
111 const SUPPORT * mySupport=myField->getSupport();
113 cout.setf(ios::fixed);
116 int numberOfComponents = myField->getNumberOfComponents() ;
117 int valueLength = myField->getValueLength();
118 const int * nbGaussPoints = myField->getNumberOfGaussPoints();
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();
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() );
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;
142 // On récupère la liste complète
143 if (!onAll) number = mySupport->getNumber(MED_ALL_ELEMENTS);
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] << " ";
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
167 void affiche_fieldT(FIELD<double, NoInterlace> * myField)
169 const double * value = 0;
170 const int * number = 0;
172 affiche_field_((FIELD_ *) myField);
173 const SUPPORT * mySupport=myField->getSupport();
175 cout.setf(ios::fixed);
178 int numberOfComponents = myField->getNumberOfComponents() ;
179 int valueLength = myField->getValueLength();
180 const int * nbGaussPoints = myField->getNumberOfGaussPoints();
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();
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() );
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;
206 int (* fct)(int,const int *);
209 number = mySupport->getNumber(MED_ALL_ELEMENTS);
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) ] << " ";
225 template <class T, class INTERLACING_TAG>
226 void affiche_fieldT2(FIELD< T, INTERLACING_TAG> * myField)
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
235 void affiche_fieldT2(FIELD<double, FullInterlace> * myField)
237 const int * number = 0;
239 affiche_field_((FIELD_ *) myField);
240 const SUPPORT * mySupport=myField->getSupport();
242 cout.setf(ios::fixed);
245 int numberOfComponents = myField->getNumberOfComponents() ;
246 int valueLength = myField->getValueLength();
247 const int * nbGaussPoints = myField->getNumberOfGaussPoints();
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();
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() );
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;
272 int (* fct)(int,const int *);
275 number = mySupport->getNumber(MED_ALL_ELEMENTS);
280 cout << "- Valeurs :"<<endl;
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);
295 assert((elemno-1) == numberOf);
300 int main (int argc, char ** argv) {
302 if ((argc !=3) && (argc != 5)) {
303 cerr << "Usage : " << argv[0]
304 << " filename fieldName [iterationNumber] [orderNumber]" << endl << endl;
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]);
314 string meshName="";//"MAILTRQU";
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.
327 FIELD<double,INTERLACING_MODE> * myField1 = new FIELD<double,INTERLACING_MODE>(MED_DRIVER,fileName,fieldName,
328 iterationNumber, orderNumber);
329 affiche_fieldT(myField1);
331 affiche_fieldT2(myField1);
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);
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);
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)
377 FIELD<double,INTERLACING_MODE> * myField2 = new FIELD<double,INTERLACING_MODE>(MED_DRIVER,fileName,fieldName,
378 iterationNumber, orderNumber);
380 meshName = myField2->getSupport()->getMeshName();
381 MESH * myMesh2 = new MESH(MED_DRIVER,fileName,meshName);
383 const SUPPORT * mySupport2=myField2->getSupport();
384 mySupport2->setMesh(myMesh2);
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);
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);
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.
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;
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;
431 err=med_2_3::MEDfermer(id);
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
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());
447 const_cast<SUPPORT*>(myField3->getSupport())->setProfilNames(pflNames);
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);
458 //ESSAYER AVEC MAILLAGE DS FICHIER ET LIEN SUPORT-MESH PRESENTS SIMULTANEMENT
459 //EN VERSION COHERENTE ET NON COHERENTE