Salome HOME
ec9cbaadf166168a3a6dc65fda3e1a3e22d31c76
[modules/med.git] / src / MEDMEM / MEDMEM_Med.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 // 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either 
7 // version 2.1 of the License.
8 // 
9 // This library is distributed in the hope that it will be useful 
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public  
15 // License along with this library; if not, write to the Free Software 
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/
19 //
20 # include <string> 
21 # include <math.h>
22
23 # include "MEDMEM_Med.hxx"
24 # include "MEDMEM_DriverFactory.hxx" 
25 # include "MEDMEM_STRING.hxx"
26
27 # include "MEDMEM_Mesh.hxx"
28 # include "MEDMEM_Grid.hxx"
29 # include "MEDMEM_Field.hxx"
30 # include "MEDMEM_Group.hxx"
31 # include "MEDMEM_Family.hxx"
32
33 # include "MEDMEM_Exception.hxx"
34 # include "MEDMEM_Utilities.hxx"
35
36 using namespace std;
37 using namespace MEDMEM;
38 using namespace MED_EN;
39
40 #define MED_NOPDT -1
41
42 /*!
43   Constructor.
44 */
45 MED::MED() {
46   MESSAGE("MED::MED()");
47 };
48
49 /*!
50   Constructor.
51 */
52 MED::MED(driverTypes driverType, const string & fileName)
53 {
54   const char * LOC = "MED::MED(driverTypes driverType, const string & fileName) : ";
55   BEGIN_OF(LOC);
56
57   MESSAGE(LOC << "driverType = " << driverType);
58
59   int current = addDriver(driverType,fileName,MED_LECT);
60
61   _drivers[current]->open();
62   _drivers[current]->readFileStruct();
63   _drivers[current]->close();
64
65   END_OF(LOC);
66 };
67
68 /*!
69   Destructor.
70 */
71 MED::~MED()
72 {
73   const char * LOC = "MED::~MED() : ";
74   BEGIN_OF(LOC);
75
76   // Analysis of the object MED
77
78   int index;
79
80   map<FIELD_ *, MESH_NAME_>::const_iterator currentField;
81   index = 0;
82   for ( currentField=_meshName.begin();currentField != _meshName.end(); currentField++ ) {
83     if ( (*currentField).first != NULL) index++;
84   }
85
86   MESSAGE(LOC << " there is(are) " << index << " field(s):");
87   for ( currentField=_meshName.begin();currentField != _meshName.end(); currentField++ ) {
88     if ( (*currentField).first != NULL) MESSAGE("             " << ((*currentField).first)->getName().c_str());
89   }
90
91   map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::iterator itSupportOnMesh ;
92   index = 0;
93   for ( itSupportOnMesh=_support.begin();itSupportOnMesh != _support.end(); itSupportOnMesh++ ) {
94     map<MED_EN::medEntityMesh,SUPPORT *>::iterator itSupport ;
95     for ( itSupport=(*itSupportOnMesh).second.begin();itSupport!=(*itSupportOnMesh).second.end();itSupport++)
96       index++;
97   }
98
99   MESSAGE(LOC << " there is(are) " << index << " support(s):");
100
101   map<MESH_NAME_,MESH*>::const_iterator  currentMesh;
102   index =0;
103   for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
104     if ( (*currentMesh).second != NULL)
105       index++;
106   }
107
108   MESSAGE(LOC << " there is(are) " << index << " meshe(s):");
109 //   for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
110 //     if ( (*currentMesh).second != NULL)
111 //       {
112 //      SCRUTE((*currentMesh).second);
113
114 //      string meshName = ((*currentMesh).second)->getName();
115
116 //      MESSAGE("             " << meshName);
117 //       }
118 //   }
119
120   // delete all ? : PG : YES !
121   //  map<FIELD_ *, MESH_NAME_>::const_iterator currentField;
122   for ( currentField=_meshName.begin();currentField != _meshName.end(); currentField++ ) {
123     if ( (*currentField).first != NULL) {
124       // cast in right type to delete it !
125       switch ((*currentField).first->getValueType()) {
126       case MED_INT32 : 
127         delete (FIELD<int>*) (*currentField).first ;
128         break ;
129       case MED_REEL64 :
130         delete (FIELD<double>*) (*currentField).first ;
131         break ;
132       default : 
133         MESSAGE(LOC << "Field has type different of int or double, could not destroy its values array !") ;
134         delete (*currentField).first;
135       }
136     }
137   }
138   //  map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::iterator itSupportOnMesh ;
139   for ( itSupportOnMesh=_support.begin();itSupportOnMesh != _support.end(); itSupportOnMesh++ ) {
140     map<MED_EN::medEntityMesh,SUPPORT *>::iterator itSupport ;
141     for ( itSupport=(*itSupportOnMesh).second.begin();itSupport!=(*itSupportOnMesh).second.end();itSupport++)
142       if (! dynamic_cast<GROUP*>( (*itSupport).second ) &&
143           ! dynamic_cast<FAMILY*>( (*itSupport).second ) )
144         delete (*itSupport).second ;
145   }
146
147   //  map<MESH_NAME_,MESH*>::const_iterator  currentMesh;
148   for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
149     if ( (*currentMesh).second != NULL)
150       {
151         if (!((*currentMesh).second)->getIsAGrid())
152           delete (*currentMesh).second;
153         else
154           delete (GRID *) (*currentMesh).second;
155       }
156   }
157
158   index =_drivers.size();
159
160   MESSAGE(LOC << "In this object MED there is(are) " << index << " driver(s):");
161
162   for (unsigned int ind=0; ind < _drivers.size(); ind++ )
163     {
164       SCRUTE(_drivers[ind]);
165       if ( _drivers[ind] != NULL) delete _drivers[ind];
166     }
167
168
169
170   END_OF(LOC);
171 } ;
172
173
174 /*!
175   Create the specified driver and return its index reference to path to 
176   read or write methods.
177 */
178 int MED::addDriver(driverTypes driverType,
179                    const string & fileName="Default File Name.med",
180                    MED_EN::med_mode_acces access) {
181
182   const char * LOC = "MED::addDriver(driverTypes driverType, const string & fileName=\"Default File Name.med\") : ";
183
184   BEGIN_OF(LOC);
185
186   MESSAGE(LOC << " the file name is " << fileName);
187
188   SCRUTE(driverType);
189   SCRUTE(access);
190
191   GENDRIVER *driver = DRIVERFACTORY::buildDriverForMed(driverType,fileName,
192                                                        this,access);
193
194   _drivers.push_back(driver);
195
196   int current = _drivers.size()-1;
197
198   driver->setId(current); 
199
200   END_OF(LOC);
201
202   return current;
203 }
204
205 /*!
206   Duplicate the given driver and return its index reference to path to 
207   read or write methods.
208 */
209 int  MED::addDriver(GENDRIVER & driver) {
210   const char * LOC = "MED::addDriver(GENDRIVER &) : ";
211   int current;
212
213   BEGIN_OF(LOC);
214   
215   SCRUTE(_drivers.size());
216
217   _drivers.push_back(&driver);
218
219   SCRUTE(_drivers.size());
220
221   SCRUTE(_drivers[0]);
222   SCRUTE(driver);
223
224   current = _drivers.size()-1;
225   SCRUTE(current);
226   driver.setId(current); 
227
228   END_OF(LOC);
229
230   return current;
231   
232 }
233
234 /*!
235   Remove the driver referenced by its index.
236 */
237 void MED::rmDriver (int index/*=0*/)
238   throw (MED_EXCEPTION)
239 {
240   const char * LOC = "MED::rmDriver (int index=0): ";
241   BEGIN_OF(LOC);
242
243   if (_drivers[index])
244     //_drivers.erase(&_drivers[index]); 
245     {}
246   else
247     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
248                                      << "The index given is invalid, index must be between 0 and |" 
249                                      << _drivers.size()
250                                      )
251                           );   
252   END_OF(LOC);
253 }
254
255 /*!
256   ??? to do comment ???
257 */
258 void MED::writeFrom (int index/*=0*/)
259   throw (MED_EXCEPTION)
260 {
261   const char * LOC = "MED::write (int index=0): ";
262   BEGIN_OF(LOC);
263
264   if (_drivers[index]) {
265     // open and close are made by all objects !
266     _drivers[index]->writeFrom();
267   }
268   throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
269                                    << "The index given is invalid, index must be between 0 and |" 
270                                    << _drivers.size()
271                                    )
272                         ); 
273   END_OF(LOC);
274 }; 
275
276 /*!
277   Write all objects with the driver given by its index.
278 */
279 void MED::write (int index/*=0*/)
280   throw (MED_EXCEPTION)
281 {
282   const char * LOC = "MED::write (int index=0): ";
283   BEGIN_OF(LOC);
284
285   if (_drivers[index]) {
286     // open and close are made by the subsequent objects !
287     _drivers[index]->write(); 
288   }
289   else
290     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
291                                      << "The index given is invalid, index must be between  0 and |" 
292                                      << _drivers.size()
293                                      )
294                           ); 
295   END_OF(LOC);
296 }; 
297
298 /*!
299   Parse all the file and generate empty object.
300
301   All object must be read explicitly later with their own method read 
302   or use MED::read to read all.
303
304   This method is automaticaly call by constructor with driver information.
305 */
306 void MED::readFileStruct (int index/*=0*/)
307   throw (MED_EXCEPTION)
308 {
309   const char * LOC = "MED::readFileStruct (int index=0): ";
310   BEGIN_OF(LOC);
311   
312   if (_drivers[index]) {
313     _drivers[index]->open(); 
314     _drivers[index]->readFileStruct(); 
315     _drivers[index]->close(); 
316   }
317   else
318     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
319                                      << "The index given is invalid, index must be between 0 and |" 
320                                      << _drivers.size()
321                                      )
322                           );   
323 }
324
325 /*!
326   Read all objects in the file specified in the driver given by its index.
327 */
328 void MED::read  (int index/*=0*/)
329   throw (MED_EXCEPTION)
330 {
331   const char * LOC = "MED::read (int index=0): ";
332   BEGIN_OF(LOC);
333   
334   if (_drivers[index]) {
335     // open and close are made by all objects !
336     SCRUTE(index);
337     SCRUTE(_drivers[index]);
338     SCRUTE(&_drivers[index]);
339     //    _drivers[index]->open();
340     _drivers[index]->read();
341     //    _drivers[index]->close();
342   }
343   else
344     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
345                                      << "The index given is invalid, index must be between  >0 and < |" 
346                                      << _drivers.size()-1 
347                                      )
348                           );  
349   END_OF(LOC);
350   
351 };
352
353 // ------- End Of Drivers Management Part
354
355 /*!
356   Get the number of MESH objects.
357 */
358 int      MED::getNumberOfMeshes ( void ) const {
359
360   const char * LOC = "MED::getNumberOfMeshes ( void ) const : ";
361   BEGIN_OF(LOC);
362
363   return _meshes.size();
364 };   
365     
366 /*!
367   Get the number of FIELD objects.
368 */
369 int      MED::getNumberOfFields ( void ) const {
370
371   const char * LOC = "MED::getNumberOfFields ( void ) const : ";
372   BEGIN_OF(LOC);
373
374   return _fields.size(); // we get number of field with different name
375 };       
376
377 /*!
378   Get the names of all MESH objects.
379
380   meshNames is an in/out argument.
381
382   It is a string array of size the
383   number of MESH objects. It must be allocated before calling
384   this method. All names are put in it.
385 */
386 void MED::getMeshNames      ( string * meshNames ) const
387   throw (MED_EXCEPTION)
388 {
389   const char * LOC = "MED::getMeshNames ( string * ) const : ";
390   BEGIN_OF(LOC);
391   unsigned int meshNamesSize;
392   
393   if (  ( meshNamesSize = sizeof(meshNames) / sizeof(string *) )
394        != _meshes.size() )
395     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
396                                      << "Size of parameter meshNames is |" 
397                                      << meshNamesSize    << "| and should be |" 
398                                      << _meshes.size() << "| and should be |" 
399                                      )
400                           );   
401   
402   // REM : ALLOCATION D'UN TABLEAU DE POINTEURS SUR STRING FAITE PAR LE CLIENT
403   map<MESH_NAME_,MESH*>::const_iterator  currentMesh; // ??ITERATEUR CONST SUR UN OBJET NON CONST ??
404
405   int meshNamesIndex = 0;
406
407   for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
408     meshNames[meshNamesIndex]=(*currentMesh).first;
409     meshNamesIndex++;                               // CF OPTIMISATION
410   }
411
412   END_OF(LOC);
413 };
414
415 /*!
416   Get the names of all MESH objects.
417
418   Return a deque<string> object which contain the name of all MESH objects.
419 */
420 deque<string> MED::getMeshNames      () const {
421   
422   const char * LOC = "MED::getMeshNames () const : ";
423   BEGIN_OF(LOC);
424
425   deque<string> meshNames(_meshes.size());
426   
427   map<MESH_NAME_,MESH*>::const_iterator  currentMesh; // ??ITERATEUR CONST SUR UN OBJET NON CONST ??
428
429   int meshNamesIndex = 0;
430
431   for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
432     meshNames[meshNamesIndex]=(*currentMesh).first;
433     meshNamesIndex++;                               // CF OPTIMISATION
434   }
435
436   END_OF(LOC);
437   return meshNames ;
438 };
439
440
441 /*!
442   Return a reference to the MESH object named meshName.
443 */
444 MESH   * MED::getMesh           ( const string & meshName )  const
445   throw (MED_EXCEPTION)
446 {
447
448   const char * LOC = "MED::getMesh ( const string & meshName ) const : ";
449   BEGIN_OF(LOC);
450
451   map<MESH_NAME_,MESH*>::const_iterator itMeshes =  _meshes.find(meshName);
452
453   if ( itMeshes == _meshes.end() )
454     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
455                                      << "There is no known mesh named |" 
456                                      << meshName << "|"
457                                      )
458                           );
459   
460   return (*itMeshes).second;
461   
462   END_OF(LOC);
463 }
464
465 /*!
466  \internal Return a reference to the MESH object associated with 
467  field argument.
468 */
469 MESH   * MED::getMesh           (const FIELD_ * const field ) const
470   throw (MED_EXCEPTION)
471 {
472  
473   const char * LOC = "MED::getMesh ( const FIELD * field ) const : ";
474   BEGIN_OF(LOC);
475
476   FIELD_ * f = const_cast< FIELD_* > (field);     //  Comment faire mieux ?
477   map<FIELD_ *, MESH_NAME_>::const_iterator itMeshName = _meshName.find(f);
478
479   if ( itMeshName  == _meshName.end() )
480     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
481                                      << "There is no known mesh associated with |" 
482                                      << field << "| pointer"
483                                      )
484                           );   
485   
486   string meshName = (*itMeshName).second;
487   map<MESH_NAME_,MESH*>::const_iterator itMeshes =  _meshes.find(meshName);
488   if ( itMeshes == _meshes.end() )
489     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
490                                      << "There is no known mesh named |"
491                                      << meshName << " while it's associated with the found field |" 
492                                      << field << "| pointer"
493                                      )
494                           );   
495   
496   return (*itMeshes).second;
497   
498   END_OF(LOC);
499 };
500
501
502 /*!
503   Get the names of all FIELD objects.
504
505   fieldNames is an in/out argument.
506
507   It is an array of string of size the
508   number of FIELD objects. It must be allocated before calling
509   this method. All names are put in it.
510 */
511 void MED::getFieldNames     ( string * fieldNames ) const
512   throw (MED_EXCEPTION)
513 {
514   const char * LOC = "MED::getFieldNames ( string * ) const : ";
515   BEGIN_OF(LOC);
516
517 //  unsigned int fieldNamesSize =  sizeof(fieldNames) / sizeof(string *);
518  
519 //  if ( fieldNamesSize != _fields.size() )
520 //    throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
521 //                                     << "Size of parameter fieldNames is |" 
522 //                                     << fieldNamesSize     << "| and should be |" 
523 //                                     << _fields.size() << "| and should be |" 
524 //                                     )
525 //                         );   
526   
527   // REM : ALLOCATION D'UN TABLEAU DE POINTEURS SUR STRING FAITE PAR LE CLIENT
528   map<FIELD_NAME_,MAP_DT_IT_>::const_iterator  currentField;
529
530   int fieldNamesIndex = 0;
531   for ( currentField=_fields.begin();currentField != _fields.end(); currentField++ ) {
532     fieldNames[fieldNamesIndex]=(*currentField).first;
533     fieldNamesIndex++;                               // CF OPTIMISATION
534   }
535
536   END_OF(LOC);
537
538 };
539
540 /*!
541   Get the names of all FIELD objects.
542
543   Return a deque<string> object which contain the name of all FIELD objects.
544 */
545 deque<string> MED::getFieldNames     () const {
546
547   const char * LOC = "MED::getFieldNames ( ) const : ";
548   BEGIN_OF(LOC);
549
550   deque<string> fieldNames(_fields.size());
551
552   map<FIELD_NAME_,MAP_DT_IT_>::const_iterator  currentField;
553
554   int fieldNamesIndex = 0;
555
556   for ( currentField=_fields.begin();currentField != _fields.end(); currentField++ ) {
557     fieldNames[fieldNamesIndex]=(*currentField).first;
558     fieldNamesIndex++;                               // CF OPTIMISATION
559   }
560
561   END_OF(LOC);
562   return fieldNames ;
563 };
564
565 /*!
566   Return a deque<DT_IT_> which contain all iteration step for the FIELD 
567   identified by its name.
568 */
569 deque<DT_IT_> MED::getFieldIteration (const string & fieldName) const
570   throw (MED_EXCEPTION)
571 {
572
573   const char * LOC = "MED::getFieldIteration ( const string & ) const : ";
574   BEGIN_OF(LOC);
575
576   map<FIELD_NAME_,MAP_DT_IT_>::const_iterator itFields = _fields.find(fieldName);
577   
578   if ( itFields == _fields.end() ) 
579     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
580                                      << "There is no known field named |" 
581                                      << fieldName << "|"
582                                      )
583                           );   
584   //  const MAP_DT_IT_ & myIterationMap =  const_cast<const MAP_DT_IT_ & > ((*itFields).second);
585   const MAP_DT_IT_ & myIterationMap =  (*itFields).second ;
586   MAP_DT_IT_::const_iterator currentIterator ;
587
588   int iterationSize = myIterationMap.size();
589   
590   SCRUTE(iterationSize);
591
592   deque<DT_IT_> Iteration(iterationSize);
593   
594   int iterationIndex = 0;
595   
596   for (currentIterator = myIterationMap.begin();
597        currentIterator != myIterationMap.end(); currentIterator++ )
598     {
599       SCRUTE(((*currentIterator).first).dt);
600       SCRUTE(((*currentIterator).first).it);
601
602       Iteration[iterationIndex].dt = ((*currentIterator).first).dt;
603       Iteration[iterationIndex].it = ((*currentIterator).first).it;
604
605       //      Iteration[iterationIndex]=(*currentIterator).first;
606       SCRUTE(Iteration[iterationIndex].dt);
607       SCRUTE(Iteration[iterationIndex].it);
608       iterationIndex++;                               // CF OPTIMISATION
609     }
610
611   END_OF(LOC);
612   return Iteration ;
613 };
614
615 /*!
616  Return a reference to the FIELD object named fieldName with 
617  time step number dt and order number it.
618 */
619 FIELD_  * MED::getField          ( const string & fieldName, const int dt=MED_NOPDT, const int it=MED_NOPDT ) const
620   throw (MED_EXCEPTION)
621 {
622
623   const char * LOC = "MED::getField ( const string &, const int, const int ) const : ";
624   BEGIN_OF(LOC);
625
626   MESSAGE(LOC << "fieldName = "<<fieldName<<", dt ="<<dt<<", it = "<<it);
627
628   DT_IT_ dtIt;
629
630   dtIt.dt= dt;
631   dtIt.it= it;
632
633   map<FIELD_NAME_,MAP_DT_IT_>::const_iterator itFields = _fields.find(fieldName);
634
635   if ( itFields == _fields.end() ) 
636     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
637                                      << "There is no known field named |" 
638                                      << fieldName << "|"
639                                      )
640                           );   
641
642   const MAP_DT_IT_ & map_dtIt =  const_cast<const MAP_DT_IT_ & > ((*itFields).second);
643   MAP_DT_IT_::const_iterator itMap_dtIt =  map_dtIt.find(dtIt);
644
645   if ( itMap_dtIt == map_dtIt.end() )
646     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
647                                      << "There is no (dt,it) |("
648                                      << dt << "," << it << ")| associated with the found field |" 
649                                      << fieldName << "|"
650                                      )
651                           );   
652
653   END_OF(LOC);
654
655   //return _fields[fieldName][dtIt];
656   return (*itMap_dtIt).second;
657   
658 };
659
660 /*!
661  Return a reference to the FIELD object named fieldName with 
662  time and iteration nb it.
663 */
664 FIELD_  *MED::getField2(const string & fieldName, double time, int it) const throw (MEDEXCEPTION)
665 {
666   const char * LOC = "MED::getField2 ( const string &, const int, const int ) const : ";
667   const double eps=1e-9;
668   map<FIELD_NAME_,MAP_DT_IT_>::const_iterator itFields=_fields.find(fieldName);
669   if ( itFields == _fields.end() ) 
670     throw MED_EXCEPTION (LOCALIZED( STRING(LOC) << "There is no known field named |" << fieldName << "|"));
671   MAP_DT_IT_::const_iterator iters=(*itFields).second.begin();
672   bool found=false;
673   FIELD_  *ret;
674   for(;iters!=(*itFields).second.end() && !found;iters++)
675     if(fabs((*iters).second->getTime()-time)<eps)
676       //if(it==(*iters).first.it)
677         {
678           ret=(*iters).second;
679           found=true;
680         }
681   if(!found)
682     throw MED_EXCEPTION(LOCALIZED( STRING(LOC) << "There is no known field existing at specified time and iteration !!! "));
683   return ret;
684   END_OF(LOC);
685 }
686
687 // fiend ostream & MED::operator<<(ostream &os,const MED & med) const {
688 //   return os;
689 // };
690
691 /*!
692   Return a map<MED_EN::medEntityMesh,SUPPORT*> which contain 
693   foreach entity, a reference to the SUPPORT on all elements.
694 */
695 const map<MED_EN::medEntityMesh,SUPPORT*> & MED::getSupports(const string & meshName) const
696   throw (MED_EXCEPTION)
697 {
698   const char * LOC = "MED::getSupports ( const string ) const : ";
699   BEGIN_OF(LOC);
700
701   map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::const_iterator itSupportOnMesh = _support.find(meshName) ;
702   
703   if ( itSupportOnMesh == _support.end() )
704     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
705                                      << "There is no support on mesh named |" 
706                                      << meshName << "|"
707                                      )
708                           );
709   END_OF(LOC);
710   return (*itSupportOnMesh).second ;
711 }
712
713 /*!
714   Return a reference to the SUPPORT object on all elements of entity 
715   for the MESH named meshName.
716 */
717 SUPPORT *  MED::getSupport (const string & meshName,MED_EN::medEntityMesh entity) const 
718   throw (MED_EXCEPTION)
719 {
720   const char * LOC = "MED::getSupport ( const string, MED_EN::medEntityMesh ) const : ";
721   BEGIN_OF(LOC);
722
723   int index = 0;
724   for (map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::const_iterator const_itSupportOnMesh=_support.begin(); const_itSupportOnMesh != _support.end();
725        const_itSupportOnMesh++ )
726     {
727       map<MED_EN::medEntityMesh,SUPPORT *>::const_iterator const_itSupport ;
728       for (const_itSupport=(*const_itSupportOnMesh).second.begin();
729            const_itSupport!=(*const_itSupportOnMesh).second.end();const_itSupport++) index++;
730     }
731
732   MESSAGE(LOC << "In this MED object there is(are) " << index << " support(s):");
733
734   for (map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::const_iterator const_itSupportOnMesh=_support.begin();const_itSupportOnMesh != _support.end(); const_itSupportOnMesh++ )
735     {
736       map<MED_EN::medEntityMesh,SUPPORT *>::const_iterator const_itSupport ;
737       for (const_itSupport=(*const_itSupportOnMesh).second.begin();
738            const_itSupport!=(*const_itSupportOnMesh).second.end();const_itSupport++)
739         {
740           MESSAGE(LOC << "Support on mesh " << (*const_itSupportOnMesh).first << " on entity " << (*const_itSupport).first << " : " << *((*const_itSupport).second));
741         }
742   }
743
744
745   map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::const_iterator const_itSupportOnMesh = _support.find(meshName) ;
746   
747   if ( const_itSupportOnMesh == _support.end() )
748     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
749                                      << "There is no support on mesh named |" 
750                                      << meshName << "|"
751                                      )
752                           );
753  
754 //   map<MED_EN::medEntityMesh,SUPPORT *> & SupportOnMesh = (map<MED_EN::medEntityMesh,SUPPORT *>&) ((*itSupportOnMesh).second) ;
755 //   map<MED_EN::medEntityMesh,SUPPORT *>::const_iterator itSupport = SupportOnMesh.find(entity) ;
756   
757 //   if (itSupport == SupportOnMesh.end() )
758 //     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
759 //                                      << "There is no support on entity "
760 //                                   << entity << " in mesh named |" 
761 //                                      << meshName << "|"
762 //                                      )
763 //                           );
764
765
766   map<MED_EN::medEntityMesh,SUPPORT *> SupportOnMesh = ((*const_itSupportOnMesh).second);
767
768   map<MED_EN::medEntityMesh,SUPPORT *>::const_iterator itSupport = SupportOnMesh.find(entity) ;
769   
770   if (itSupport == SupportOnMesh.end() )
771     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
772                                      << "There is no support on entity "
773                                      << entity << " in mesh named |" 
774                                      << meshName << "|"
775                                      )
776                           );
777   END_OF(LOC);
778   return (*itSupport).second ;
779 };
780
781 /*!
782   Temporary method : when all MESH objects are read, this methods 
783   update all SUPPORT objects with the rigth dimension.
784 */
785 void MED::updateSupport ()
786 {
787  
788   const char * LOC = "MED::updateSupport () : ";
789   BEGIN_OF(LOC);
790
791   map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::iterator itSupportOnMesh ;
792   for ( itSupportOnMesh=_support.begin();itSupportOnMesh != _support.end(); itSupportOnMesh++ ) {
793     map<MED_EN::medEntityMesh,SUPPORT *>::iterator itSupport ;
794     for ( itSupport=(*itSupportOnMesh).second.begin();itSupport!=(*itSupportOnMesh).second.end();itSupport++)
795       try {
796         (*itSupport).second->update() ;
797       }
798       catch (MEDEXCEPTION & ex) {
799         // entity not defined in mesh -> we remove support on it !
800         MESSAGE(LOC<<ex.what());
801         delete (*itSupport).second ;
802         (*itSupportOnMesh).second.erase(itSupport) ; // that's rigth ????
803         itSupport-- ;
804       }
805   }
806
807   END_OF(LOC);
808 }
809
810 /*!
811   Add the given MESH object. MED object control it,
812   and destroy it, so you must not destroy it after.
813
814   The meshName is given by the MESH object.
815 */
816 void MED::addMesh( MESH * const ptrMesh)
817   throw (MED_EXCEPTION)
818 {
819   const char * LOC = "MED::addMesh(const MESH * ptrMesh): ";
820   BEGIN_OF(LOC);
821
822   if ( ! ptrMesh ) 
823     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrMesh must not be NULL !"));
824  
825   string meshName;
826   if ( ! ( meshName = ptrMesh->getName()).size() ) 
827     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrMesh->_name must not be NULL !"));
828
829 //   MESH * meshToMed = new MESH(*ptrMesh); DO WE HAVE TO COPY THE ENTRY MESH OR NOT ????? (NB)
830
831   _meshes[meshName] = ptrMesh; // if ptrMesh->meshName already exists it is modified
832
833 //   _meshes[meshName] = meshToMed;
834
835   END_OF(LOC);
836 }
837
838 /*!
839   Add the given FIELD object. MED object control it,
840   and destroy it, so you must not destroy it after.
841
842   The fieldName is given by the FIELD object.
843 */
844 void MED::addField( FIELD_ * const ptrField)
845   throw (MED_EXCEPTION)
846 {
847   const char * LOC = "MED::addField(const FIELD_ * const ptrField): ";
848   BEGIN_OF(LOC);
849   
850   if ( ! ptrField ) 
851     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField must not be NULL !"));
852
853   string fieldName;
854   if ( ! (fieldName = ptrField->getName()).size() ) 
855     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_name must not be NULL !"));
856   
857   SUPPORT * ptrSupport;
858   if ( ! ( ptrSupport = (SUPPORT * ) ptrField->getSupport()) ) 
859     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_support must not be NULL !"));
860   
861   MESH * ptrMesh;
862   if ( ! ( ptrMesh = ptrSupport->getMesh()) ) 
863     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_support->_mesh must not be NULL !"));
864
865   string meshName;
866   if ( ! ( meshName = ptrMesh->getName()).size() ) 
867     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_support->_mesh->_name must not be NULL !"));
868
869   DT_IT_ dtIt;
870   dtIt.dt  = ptrField->getIterationNumber();
871   dtIt.it  = ptrField->getOrderNumber();
872                 
873   _fields   [fieldName][dtIt] = ptrField; // if it already exists it is replaced
874   _meshName [ptrField]        = meshName; // if it already exists it is replaced
875   _meshes   [meshName]        = ptrMesh;  // if it already exists it is replaced
876
877   //  int  numberOfTypes = ptrSupport->getNumberOfTypes(); !! UNUSED VARIABLE !!
878   _support  [meshName][ptrSupport->getEntity()] = ptrSupport;// if it already exists it is replaced
879
880
881   END_OF(LOC);
882 }