Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[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/ or email : webmaster.salome@opencascade.com
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   SCRUTE(index);
335
336   if (_drivers[index]) {
337     // open and close are made by all objects !
338     SCRUTE(index);
339     SCRUTE(_drivers[index]);
340     SCRUTE(&_drivers[index]);
341     //    _drivers[index]->open();
342     _drivers[index]->read();
343     //    _drivers[index]->close();
344   }
345   else
346     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
347                                      << "The index given is invalid, index must be between  >0 and < |" 
348                                      << _drivers.size()-1 
349                                      )
350                           );  
351   END_OF(LOC);
352   
353 };
354
355 // ------- End Of Drivers Management Part
356
357 /*!
358   Get the number of MESH objects.
359 */
360 int      MED::getNumberOfMeshes ( void ) const {
361
362   const char * LOC = "MED::getNumberOfMeshes ( void ) const : ";
363   BEGIN_OF(LOC);
364
365   return _meshes.size();
366 };   
367     
368 /*!
369   Get the number of FIELD objects.
370 */
371 int      MED::getNumberOfFields ( void ) const {
372
373   const char * LOC = "MED::getNumberOfFields ( void ) const : ";
374   BEGIN_OF(LOC);
375
376   return _fields.size(); // we get number of field with different name
377 };       
378
379 /*!
380   Get the names of all MESH objects.
381
382   meshNames is an in/out argument.
383
384   It is a string array of size the
385   number of MESH objects. It must be allocated before calling
386   this method. All names are put in it.
387 */
388 void MED::getMeshNames      ( string * meshNames ) const
389   throw (MED_EXCEPTION)
390 {
391   const char * LOC = "MED::getMeshNames ( string * ) const : ";
392   BEGIN_OF(LOC);
393
394   // REM : ALLOCATION D'UN TABLEAU DE POINTEURS SUR STRING FAITE PAR LE CLIENT
395   map<MESH_NAME_,MESH*>::const_iterator  currentMesh; // ??ITERATEUR CONST SUR UN OBJET NON CONST ??
396
397   int meshNamesIndex = 0;
398
399   for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
400     meshNames[meshNamesIndex]=(*currentMesh).first;
401     meshNamesIndex++;                               // CF OPTIMISATION
402   }
403
404   END_OF(LOC);
405 };
406
407 /*!
408   Get the names of all MESH objects.
409
410   Return a deque<string> object which contain the name of all MESH objects.
411 */
412 deque<string> MED::getMeshNames      () const {
413   
414   const char * LOC = "MED::getMeshNames () const : ";
415   BEGIN_OF(LOC);
416
417   deque<string> meshNames(_meshes.size());
418   
419   map<MESH_NAME_,MESH*>::const_iterator  currentMesh; // ??ITERATEUR CONST SUR UN OBJET NON CONST ??
420
421   int meshNamesIndex = 0;
422
423   for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
424     meshNames[meshNamesIndex]=(*currentMesh).first;
425     meshNamesIndex++;                               // CF OPTIMISATION
426   }
427
428   END_OF(LOC);
429   return meshNames ;
430 };
431
432
433 /*!
434   Return a reference to the MESH object named meshName.
435 */
436 MESH   * MED::getMesh           ( const string & meshName )  const
437   throw (MED_EXCEPTION)
438 {
439
440   const char * LOC = "MED::getMesh ( const string & meshName ) const : ";
441   BEGIN_OF(LOC);
442
443   map<MESH_NAME_,MESH*>::const_iterator itMeshes =  _meshes.find(meshName);
444
445   if ( itMeshes == _meshes.end() )
446     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
447                                      << "There is no known mesh named |" 
448                                      << meshName << "|"
449                                      )
450                           );
451   
452   return (*itMeshes).second;
453   
454   END_OF(LOC);
455 }
456
457 /*!
458  \internal Return a reference to the MESH object associated with 
459  field argument.
460 */
461 MESH   * MED::getMesh           (const FIELD_ * const field ) const
462   throw (MED_EXCEPTION)
463 {
464  
465   const char * LOC = "MED::getMesh ( const FIELD * field ) const : ";
466   BEGIN_OF(LOC);
467
468   FIELD_ * f = const_cast< FIELD_* > (field);     //  Comment faire mieux ?
469   map<FIELD_ *, MESH_NAME_>::const_iterator itMeshName = _meshName.find(f);
470
471   if ( itMeshName  == _meshName.end() )
472     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
473                                      << "There is no known mesh associated with |" 
474                                      << field << "| pointer"
475                                      )
476                           );
477
478   string meshName = (*itMeshName).second;
479   map<MESH_NAME_,MESH*>::const_iterator itMeshes =  _meshes.find(meshName);
480   if ( itMeshes == _meshes.end() )
481     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
482                                      << "There is no known mesh named |"
483                                      << meshName << " while it's associated with the found field |"
484                                      << field << "| pointer"
485                                      )
486                           );
487
488   END_OF(LOC);
489
490   return (*itMeshes).second;
491 };
492
493
494 /*!
495   Get the names of all FIELD objects.
496
497   fieldNames is an in/out argument.
498
499   It is an array of string of size the
500   number of FIELD objects. It must be allocated before calling
501   this method. All names are put in it.
502 */
503 void MED::getFieldNames     ( string * fieldNames ) const
504   throw (MED_EXCEPTION)
505 {
506   const char * LOC = "MED::getFieldNames ( string * ) const : ";
507   BEGIN_OF(LOC);
508
509 //  unsigned int fieldNamesSize =  sizeof(fieldNames) / sizeof(string *);
510  
511 //  if ( fieldNamesSize != _fields.size() )
512 //    throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
513 //                                     << "Size of parameter fieldNames is |" 
514 //                                     << fieldNamesSize     << "| and should be |" 
515 //                                     << _fields.size() << "| and should be |" 
516 //                                     )
517 //                         );   
518   
519   // REM : ALLOCATION D'UN TABLEAU DE POINTEURS SUR STRING FAITE PAR LE CLIENT
520   map<FIELD_NAME_,MAP_DT_IT_>::const_iterator  currentField;
521
522   int fieldNamesIndex = 0;
523   for ( currentField=_fields.begin();currentField != _fields.end(); currentField++ ) {
524     fieldNames[fieldNamesIndex]=(*currentField).first;
525     fieldNamesIndex++;                               // CF OPTIMISATION
526   }
527
528   END_OF(LOC);
529
530 };
531
532 /*!
533   Get the names of all FIELD objects.
534
535   Return a deque<string> object which contain the name of all FIELD objects.
536 */
537 deque<string> MED::getFieldNames     () const {
538
539   const char * LOC = "MED::getFieldNames ( ) const : ";
540   BEGIN_OF(LOC);
541
542   deque<string> fieldNames(_fields.size());
543
544   map<FIELD_NAME_,MAP_DT_IT_>::const_iterator  currentField;
545
546   int fieldNamesIndex = 0;
547
548   for ( currentField=_fields.begin();currentField != _fields.end(); currentField++ ) {
549     fieldNames[fieldNamesIndex]=(*currentField).first;
550     fieldNamesIndex++;                               // CF OPTIMISATION
551   }
552
553   END_OF(LOC);
554   return fieldNames ;
555 };
556
557 /*!
558   Return a deque<DT_IT_> which contain all iteration step for the FIELD 
559   identified by its name.
560 */
561 deque<DT_IT_> MED::getFieldIteration (const string & fieldName) const
562   throw (MED_EXCEPTION)
563 {
564
565   const char * LOC = "MED::getFieldIteration ( const string & ) const : ";
566   BEGIN_OF(LOC);
567
568   map<FIELD_NAME_,MAP_DT_IT_>::const_iterator itFields = _fields.find(fieldName);
569   
570   if ( itFields == _fields.end() ) 
571     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
572                                      << "There is no known field named |" 
573                                      << fieldName << "|"
574                                      )
575                           );   
576   //  const MAP_DT_IT_ & myIterationMap =  const_cast<const MAP_DT_IT_ & > ((*itFields).second);
577   const MAP_DT_IT_ & myIterationMap =  (*itFields).second ;
578   MAP_DT_IT_::const_iterator currentIterator ;
579
580   int iterationSize = myIterationMap.size();
581   
582   SCRUTE(iterationSize);
583
584   deque<DT_IT_> Iteration(iterationSize);
585   
586   int iterationIndex = 0;
587   
588   for (currentIterator = myIterationMap.begin();
589        currentIterator != myIterationMap.end(); currentIterator++ )
590     {
591       SCRUTE(((*currentIterator).first).dt);
592       SCRUTE(((*currentIterator).first).it);
593
594       Iteration[iterationIndex].dt = ((*currentIterator).first).dt;
595       Iteration[iterationIndex].it = ((*currentIterator).first).it;
596
597       //      Iteration[iterationIndex]=(*currentIterator).first;
598       SCRUTE(Iteration[iterationIndex].dt);
599       SCRUTE(Iteration[iterationIndex].it);
600       iterationIndex++;                               // CF OPTIMISATION
601     }
602
603   END_OF(LOC);
604   return Iteration ;
605 };
606
607 /*!
608  Return a reference to the FIELD object named fieldName with 
609  time step number dt and order number it.
610 */
611 FIELD_  * MED::getField          ( const string & fieldName, const int dt=MED_NOPDT, const int it=MED_NOPDT ) const
612   throw (MED_EXCEPTION)
613 {
614
615   const char * LOC = "MED::getField ( const string &, const int, const int ) const : ";
616   BEGIN_OF(LOC);
617
618   MESSAGE(LOC << "fieldName = "<<fieldName<<", dt ="<<dt<<", it = "<<it);
619
620   DT_IT_ dtIt;
621
622   dtIt.dt= dt;
623   dtIt.it= it;
624
625   map<FIELD_NAME_,MAP_DT_IT_>::const_iterator itFields = _fields.find(fieldName);
626
627   if ( itFields == _fields.end() ) 
628     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
629                                      << "There is no known field named |" 
630                                      << fieldName << "|"
631                                      )
632                           );   
633
634   const MAP_DT_IT_ & map_dtIt =  const_cast<const MAP_DT_IT_ & > ((*itFields).second);
635   MAP_DT_IT_::const_iterator itMap_dtIt =  map_dtIt.find(dtIt);
636
637   if ( itMap_dtIt == map_dtIt.end() )
638     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
639                                      << "There is no (dt,it) |("
640                                      << dt << "," << it << ")| associated with the found field |" 
641                                      << fieldName << "|"
642                                      )
643                           );   
644
645   END_OF(LOC);
646
647   //return _fields[fieldName][dtIt];
648   return (*itMap_dtIt).second;
649   
650 };
651
652 /*!
653  Return a reference to the FIELD object named fieldName with 
654  time and iteration nb it.
655 */
656 FIELD_  *MED::getField2(const string & fieldName, double time, int it) const throw (MEDEXCEPTION)
657 {
658   const char * LOC = "MED::getField2 ( const string &, const int, const int ) const : ";
659   const double eps=1e-9;
660   map<FIELD_NAME_,MAP_DT_IT_>::const_iterator itFields=_fields.find(fieldName);
661   if ( itFields == _fields.end() ) 
662     throw MED_EXCEPTION (LOCALIZED( STRING(LOC) << "There is no known field named |" << fieldName << "|"));
663   MAP_DT_IT_::const_iterator iters=(*itFields).second.begin();
664   bool found=false;
665   FIELD_  *ret;
666   for(;iters!=(*itFields).second.end() && !found;iters++)
667     if(fabs((*iters).second->getTime()-time)<eps)
668       //if(it==(*iters).first.it)
669         {
670           ret=(*iters).second;
671           found=true;
672         }
673   if(!found)
674     throw MED_EXCEPTION(LOCALIZED( STRING(LOC) << "There is no known field existing at specified time and iteration !!! "));
675   return ret;
676   END_OF(LOC);
677 }
678
679 // fiend ostream & MED::operator<<(ostream &os,const MED & med) const {
680 //   return os;
681 // };
682
683 /*!
684   Return a map<MED_EN::medEntityMesh,SUPPORT*> which contain 
685   foreach entity, a reference to the SUPPORT on all elements.
686 */
687 const map<MED_EN::medEntityMesh,SUPPORT*> & MED::getSupports(const string & meshName) const
688   throw (MED_EXCEPTION)
689 {
690   const char * LOC = "MED::getSupports ( const string ) const : ";
691   BEGIN_OF(LOC);
692
693   map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::const_iterator itSupportOnMesh = _support.find(meshName) ;
694   
695   if ( itSupportOnMesh == _support.end() )
696     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
697                                      << "There is no support on mesh named |" 
698                                      << meshName << "|"
699                                      )
700                           );
701   END_OF(LOC);
702   return (*itSupportOnMesh).second ;
703 }
704
705 /*!
706   Return a reference to the SUPPORT object on all elements of entity 
707   for the MESH named meshName.
708 */
709 SUPPORT *  MED::getSupport (const string & meshName,MED_EN::medEntityMesh entity) const 
710   throw (MED_EXCEPTION)
711 {
712   const char * LOC = "MED::getSupport ( const string, MED_EN::medEntityMesh ) const : ";
713   BEGIN_OF(LOC);
714
715   int index = 0;
716   map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::const_iterator const_itSupportOnMesh;
717
718   for (const_itSupportOnMesh=_support.begin(); const_itSupportOnMesh != _support.end();
719        const_itSupportOnMesh++ )
720     {
721       map<MED_EN::medEntityMesh,SUPPORT *>::const_iterator const_itSupport ;
722       for (const_itSupport=(*const_itSupportOnMesh).second.begin();
723            const_itSupport!=(*const_itSupportOnMesh).second.end();const_itSupport++) index++;
724     }
725
726   MESSAGE(LOC << "In this MED object there is(are) " << index << " support(s):");
727
728   for (const_itSupportOnMesh=_support.begin();const_itSupportOnMesh != _support.end(); const_itSupportOnMesh++ )
729     {
730       map<MED_EN::medEntityMesh,SUPPORT *>::const_iterator const_itSupport ;
731       for (const_itSupport=(*const_itSupportOnMesh).second.begin();
732            const_itSupport!=(*const_itSupportOnMesh).second.end();const_itSupport++)
733         {
734           MESSAGE(LOC << "Support on mesh " << (*const_itSupportOnMesh).first << " on entity " << (*const_itSupport).first << " : " << *((*const_itSupport).second));
735         }
736   }
737
738   const_itSupportOnMesh = _support.find(meshName) ;
739   
740   if ( const_itSupportOnMesh == _support.end() )
741     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
742                                      << "There is no support on mesh named |" 
743                                      << meshName << "|"
744                                      )
745                           );
746  
747 //   map<MED_EN::medEntityMesh,SUPPORT *> & SupportOnMesh = (map<MED_EN::medEntityMesh,SUPPORT *>&) ((*itSupportOnMesh).second) ;
748 //   map<MED_EN::medEntityMesh,SUPPORT *>::const_iterator itSupport = SupportOnMesh.find(entity) ;
749   
750 //   if (itSupport == SupportOnMesh.end() )
751 //     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
752 //                                      << "There is no support on entity "
753 //                                   << entity << " in mesh named |" 
754 //                                      << meshName << "|"
755 //                                      )
756 //                           );
757
758
759   map<MED_EN::medEntityMesh,SUPPORT *> SupportOnMesh = ((*const_itSupportOnMesh).second);
760
761   map<MED_EN::medEntityMesh,SUPPORT *>::const_iterator itSupport = SupportOnMesh.find(entity) ;
762   
763   if (itSupport == SupportOnMesh.end() )
764     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
765                                      << "There is no support on entity "
766                                      << entity << " in mesh named |" 
767                                      << meshName << "|"
768                                      )
769                           );
770   END_OF(LOC);
771   return (*itSupport).second ;
772 };
773
774 /*!
775   Temporary method : when all MESH objects are read, this methods 
776   update all SUPPORT objects with the rigth dimension.
777 */
778 void MED::updateSupport ()
779 {
780   const char * LOC = "MED::updateSupport () : ";
781   BEGIN_OF(LOC);
782
783   map<MESH_NAME_, map<MED_EN::medEntityMesh,SUPPORT *> >::iterator itSupportOnMesh ;
784   for ( itSupportOnMesh=_support.begin();itSupportOnMesh != _support.end(); itSupportOnMesh++ ) {
785     map<MED_EN::medEntityMesh,SUPPORT *>& anEntity2Support = (*itSupportOnMesh).second;
786     map<MED_EN::medEntityMesh,SUPPORT *> anEntity2SupportTmp;
787     map<MED_EN::medEntityMesh,SUPPORT *>::iterator itSupport ;
788     for ( itSupport=anEntity2Support.begin();itSupport!=anEntity2Support.end();itSupport++)
789     {
790       MED_EN::medEntityMesh aKey = (*itSupport).first;
791       SUPPORT* aData = (*itSupport).second;
792       try {
793         aData->update() ;
794         anEntity2SupportTmp[aKey] = aData;
795       }
796       catch (MEDEXCEPTION & ex) {
797         // entity not defined in mesh -> we remove support on it !
798         MESSAGE(LOC<<ex.what());
799         delete (*itSupport).second ;
800         //(*itSupportOnMesh).second.erase(itSupport) ; // that's right ????
801         //itSupport-- ;
802         map<MED_EN::medEntityMesh,SUPPORT *>::iterator itSupportCurr = itSupport;
803         itSupport--; // decrement before erase()
804         (*itSupportOnMesh).second.erase(itSupportCurr);
805       }
806     }
807
808     // some entities has not defined in mesh -> we should remove their supports!
809     anEntity2Support.swap( anEntity2SupportTmp );
810
811     for ( itSupport=anEntity2SupportTmp.begin();itSupport!=anEntity2SupportTmp.end();itSupport++)
812     {
813       MED_EN::medEntityMesh aKey = (*itSupport).first;
814       SUPPORT* aData = (*itSupport).second;
815       if( anEntity2Support.find( aKey ) == anEntity2Support.end() )
816         delete aData;
817     }
818   }
819
820   END_OF(LOC);
821 }
822
823 /*!
824   Add the given MESH object. MED object control it,
825   and destroy it, so you must not destroy it after.
826
827   The meshName is given by the MESH object.
828 */
829 void MED::addMesh( MESH * const ptrMesh)
830   throw (MED_EXCEPTION)
831 {
832   const char * LOC = "MED::addMesh(const MESH * ptrMesh): ";
833   BEGIN_OF(LOC);
834
835   if ( ! ptrMesh ) 
836     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrMesh must not be NULL !"));
837  
838   string meshName;
839   if ( ! ( meshName = ptrMesh->getName()).size() ) 
840     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrMesh->_name must not be NULL !"));
841
842 //   MESH * meshToMed = new MESH(*ptrMesh); DO WE HAVE TO COPY THE ENTRY MESH OR NOT ????? (NB)
843
844   _meshes[meshName] = ptrMesh; // if ptrMesh->meshName already exists it is modified
845
846 //   _meshes[meshName] = meshToMed;
847
848   END_OF(LOC);
849 }
850
851 /*!
852   Add the given FIELD object. MED object control it,
853   and destroy it, so you must not destroy it after.
854
855   The fieldName is given by the FIELD object.
856 */
857 void MED::addField( FIELD_ * const ptrField)
858   throw (MED_EXCEPTION)
859 {
860   const char * LOC = "MED::addField(const FIELD_ * const ptrField): ";
861   BEGIN_OF(LOC);
862   
863   if ( ! ptrField ) 
864     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField must not be NULL !"));
865
866   string fieldName;
867   if ( ! (fieldName = ptrField->getName()).size() ) 
868     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_name must not be NULL !"));
869   
870   SUPPORT * ptrSupport;
871   if ( ! ( ptrSupport = (SUPPORT * ) ptrField->getSupport()) ) 
872     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_support must not be NULL !"));
873   
874   MESH * ptrMesh;
875   if ( ! ( ptrMesh = ptrSupport->getMesh()) ) 
876     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_support->_mesh must not be NULL !"));
877
878   string meshName;
879   if ( ! ( meshName = ptrMesh->getName()).size() ) 
880     throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_support->_mesh->_name must not be NULL !"));
881
882   DT_IT_ dtIt;
883   dtIt.dt  = ptrField->getIterationNumber();
884   dtIt.it  = ptrField->getOrderNumber();
885                 
886   _fields   [fieldName][dtIt] = ptrField; // if it already exists it is replaced
887   _meshName [ptrField]        = meshName; // if it already exists it is replaced
888   _meshes   [meshName]        = ptrMesh;  // if it already exists it is replaced
889
890   //  int  numberOfTypes = ptrSupport->getNumberOfTypes(); !! UNUSED VARIABLE !!
891   _support  [meshName][ptrSupport->getEntity()] = ptrSupport;// if it already exists it is replaced
892
893
894   END_OF(LOC);
895 }