Salome HOME
Final version V2_0_1 which works with Med File V2.1 and the KERNEL
[modules/med.git] / src / MEDMEM / MEDMEM_MedFieldDriver.hxx
1 #ifndef MED_FIELD_DRIVER_HXX
2 #define MED_FIELD_DRIVER_HXX
3
4 #include <string>
5
6 #include "MEDMEM_define.hxx"
7
8 #include "MEDMEM_GenDriver.hxx"
9 #include "utilities.h"
10
11 #include "MEDMEM_STRING.hxx"
12 #include "MEDMEM_Exception.hxx"
13 #include "MEDMEM_Unit.hxx"
14 #include "MEDMEM_Array.hxx"
15 #include "MEDMEM_Support.hxx"
16 //#include "MEDMEM_Field.hxx"
17 #include "MEDMEM_Mesh.hxx"
18
19 //using namespace MED_FR ;
20
21 namespace MEDMEM {
22 template <class T> class FIELD;
23
24 // A QD LA CLASSE MED_ALL_ELEMENTS_DRIVER.... :) pour mutualiser le open ..... avec led _medIdt...
25
26 /*!
27
28   Driver Med for FIELD.
29
30   Generic part : implement open and close methods.
31
32 */
33
34 template <class T> class MED_FIELD_DRIVER : public GENDRIVER
35 {
36 protected:
37   
38   FIELD<T> *     _ptrField;
39   MED_FR::med_idt        _medIdt;
40   string         _fieldName;
41   int            _fieldNum;
42  
43   void search_field() ;
44   
45 public :
46
47   // all MED cell type ?? Classe de Définition ??
48   //   static const medGeometryElement all_cell_type[MED_NBR_GEOMETRIE_MAILLE];
49   
50   //   static const char * const all_cell_type_tab [MED_NBR_GEOMETRIE_MAILLE];
51   
52   /*!
53     Constructor.
54   */
55   MED_FIELD_DRIVER():GENDRIVER(),
56                      _ptrField((FIELD<T> *)MED_NULL),_medIdt(MED_INVALID),
57                      _fieldName(""),_fieldNum(MED_INVALID) {}
58   /*!
59     Constructor.
60   */
61   MED_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField, 
62                    med_mode_acces accessMode)
63     : GENDRIVER(fileName,accessMode),
64       _ptrField((FIELD<T> *) ptrField),_medIdt(MED_INVALID), 
65       _fieldName(fileName),_fieldNum(MED_INVALID) 
66   {
67   }
68
69   /*!
70     Copy constructor.
71   */
72   MED_FIELD_DRIVER(const MED_FIELD_DRIVER & fieldDriver):
73     GENDRIVER(fieldDriver),
74     _ptrField(fieldDriver._ptrField),
75     _medIdt(MED_INVALID),
76     _fieldName(fieldDriver._fieldName),
77     _fieldNum(fieldDriver._fieldNum) 
78   {
79   }
80
81   /*!
82     Destructor.
83   */
84   virtual ~MED_FIELD_DRIVER() { 
85   }
86
87   void open() throw (MEDEXCEPTION)
88   {
89     const char * LOC = "MED_FIELD_DRIVER::open() ";
90     BEGIN_OF(LOC);
91
92     // we must set fieldname before open, because we must find field number in file (if it exist !!!)
93     if ( _fileName == "" )
94       throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
95                                        << "_fileName is |\"\"|, please set a correct fileName before calling open()"
96                                        )
97                             );
98
99     MESSAGE(LOC<<"_fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
100     _medIdt = MED_FR::MEDouvrir( (const_cast <char *> (_fileName.c_str())),(MED_FR::med_mode_acces) _accessMode);
101     MESSAGE(LOC<<"_medIdt : "<< _medIdt );
102     if (_medIdt > 0) 
103       _status=MED_OPENED;
104     else {
105       _status = MED_INVALID;
106       _medIdt = MED_INVALID;
107       throw MED_EXCEPTION (LOCALIZED( STRING(LOC) 
108                                       << "Can't open |"  << _fileName 
109                                       << "|, _medIdt : " << _medIdt
110                                       )
111                            );
112     }
113
114     END_OF(LOC);
115   }
116   
117   void close() {
118     BEGIN_OF("MED_FIELD_DRIVER::close()");
119     MED_FR::med_int err = 0;
120     if (_status == MED_OPENED) {
121       err=MED_FR::MEDfermer(_medIdt);
122       //H5close(); // If we call H5close() all the files are closed.
123       _status = MED_CLOSED;
124       _medIdt = MED_INVALID;
125       MESSAGE(" MED_FIELD_DRIVER::close() : MEDfermer : _medIdt= " << _medIdt );
126       MESSAGE(" MED_FIELD_DRIVER::close() : MEDfermer : err    = " << err );
127     }
128     END_OF("MED_FIELD_DRIVER::close()");
129   }
130
131   virtual void write( void ) const = 0 ;
132   virtual void read ( void ) = 0 ;
133
134   /*!
135     Set the name of the FIELD asked in file.
136
137     It could be different than the name of the FIELD object.
138   */
139   void   setFieldName(const string & fieldName) ;
140   /*!
141     Get the name of the FIELD asked in file.
142   */
143   string getFieldName() const ;
144
145 private:
146   virtual GENDRIVER * copy ( void ) const = 0 ;
147
148 };
149
150 /*!
151
152   Driver Med for FIELD : Read only.
153
154   Implement read method.
155
156 */
157
158 template <class T> class MED_FIELD_RDONLY_DRIVER : public virtual MED_FIELD_DRIVER<T>
159 {
160  
161 public :
162   
163   /*!
164     Constructor.
165   */
166   MED_FIELD_RDONLY_DRIVER():MED_FIELD_DRIVER<T>() {};
167   
168   /*!
169     Constructor.
170   */
171   MED_FIELD_RDONLY_DRIVER(const string & fileName,  FIELD<T> * ptrField):
172     MED_FIELD_DRIVER<T>(fileName,ptrField,MED_RDONLY) { 
173     BEGIN_OF("MED_FIELD_RDONLY_DRIVER::MED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
174     END_OF("MED_FIELD_RDONLY_DRIVER::MED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
175   }
176   
177   /*!
178     Copy constructor.
179   */
180   MED_FIELD_RDONLY_DRIVER(const MED_FIELD_RDONLY_DRIVER & fieldDriver):
181     MED_FIELD_DRIVER<T>(fieldDriver) {};
182   
183   /*!
184     Destructor.
185   */
186   virtual ~MED_FIELD_RDONLY_DRIVER() {};
187
188   // CREER UNE METHODE POUR LIRE LA LISTE DES MAILLAGES .....
189
190   /*!
191     Return a MEDEXCEPTION : it is the read-only driver.
192   */
193   void write( void ) const throw (MEDEXCEPTION) ;
194   /*!
195     Read FIELD in the specified file.
196   */
197   void read ( void ) throw (MEDEXCEPTION) ;
198
199 private:
200   GENDRIVER * copy( void ) const ;
201
202 };
203
204 /*!
205
206   Driver Med for FIELD : Write only.
207
208   Implement write method.
209
210 */
211
212 template <class T> class MED_FIELD_WRONLY_DRIVER : public virtual MED_FIELD_DRIVER<T> {
213   
214 public :
215   
216   /*!
217     Constructor.
218   */
219   MED_FIELD_WRONLY_DRIVER():MED_FIELD_DRIVER<T>() {}
220   
221   /*!
222     Constructor.
223   */
224   MED_FIELD_WRONLY_DRIVER(const string & fileName, FIELD<T> * ptrField):
225     MED_FIELD_DRIVER<T>(fileName,ptrField,MED_WRONLY)
226   {
227     BEGIN_OF("MED_FIELD_WRONLY_DRIVER::MED_FIELD_WRONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
228     END_OF("MED_FIELD_WRONLY_DRIVER::MED_FIELD_WRONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
229   };
230
231   /*!
232     Copy constructor.
233   */
234   MED_FIELD_WRONLY_DRIVER(const MED_FIELD_WRONLY_DRIVER & fieldDriver):
235     MED_FIELD_DRIVER<T>(fieldDriver) {};
236   
237   /*!
238     Destructor.
239   */
240   virtual ~MED_FIELD_WRONLY_DRIVER() {};
241
242   /*!
243     Write FIELD in the specified file.
244   */
245   void write( void ) const throw (MEDEXCEPTION) ;
246   /*!
247     Return a MEDEXCEPTION : it is the write-only driver.
248   */
249   void read ( void ) throw (MEDEXCEPTION) ;
250
251 private:
252   GENDRIVER * copy( void ) const ;
253
254 };
255
256
257 /*!
258
259   Driver Med for FIELD : Read write.
260   - Use read method from MED_FIELD_RDONLY_DRIVER
261   - Use write method from MED_FIELD_WDONLY_DRIVER
262
263 */
264
265 template <class T> class MED_FIELD_RDWR_DRIVER : public MED_FIELD_RDONLY_DRIVER<T>, public MED_FIELD_WRONLY_DRIVER<T> {
266   
267 public :
268   
269   /*!
270     Constructor.
271   */
272   MED_FIELD_RDWR_DRIVER():MED_FIELD_DRIVER<T>() {}
273   
274   /*!
275     Constructor.
276   */
277   MED_FIELD_RDWR_DRIVER(const string & fileName, FIELD<T> * ptrField):
278     MED_FIELD_DRIVER<T>(fileName,ptrField,MED_RDWR)
279   {
280     BEGIN_OF("MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
281     //_accessMode = MED_RDWR ;
282     END_OF("MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
283   };
284
285   /*!
286     Copy constructor.
287   */
288   MED_FIELD_RDWR_DRIVER(const MED_FIELD_RDWR_DRIVER & fieldDriver):
289     MED_FIELD_DRIVER<T>(fieldDriver) {};
290   
291   /*!
292     Destructor.
293   */
294   ~MED_FIELD_RDWR_DRIVER() {};
295
296   /*!
297     Write FIELD in the specified file.
298   */
299   void write(void) const throw (MEDEXCEPTION) ;
300   /*!
301     Read FIELD in the specified file.
302   */
303   void read (void) throw (MEDEXCEPTION) ;
304
305 private:
306   GENDRIVER * copy( void ) const ;
307
308 };
309 }
310
311
312 /*-------------------------*/
313 /* template implementation */
314 /*-------------------------*/
315
316 using namespace MEDMEM;
317 /*--------------------- DRIVER PART -------------------------------*/
318
319 template <class T> void MED_FIELD_DRIVER<T>::setFieldName(const string & fieldName)
320 {
321   _fieldName = fieldName; 
322 }
323
324 template <class T> string  MED_FIELD_DRIVER<T>::getFieldName() const
325 {
326   return _fieldName;
327 }
328
329 //  template <class T> void MED_FIELD_DRIVER<T>::search_field() {
330 //    const char * LOC = "template <class T> class MED_FIELD_DRIVER::search_field() :";
331     
332 //    // we search the field number !!!!
333 //    if (_status==MED_OPENED)
334 //      if (_fieldNum==MED_INVALID) {
335 //        int err ;
336 //        int    numberOfFields              = 0;      //MED_INVALID
337 //        //    char   fieldName[MED_TAILLE_NOM+1] = "";
338 //        char   fieldName[MED_TAILLE_NOM+1] ;
339 //        int    numberOfComponents          = 0;
340 //        char * componentName               = (char *) MED_NULL;
341 //        char * unitName                    = (char *) MED_NULL;
342 //        MED_FR::med_type_champ type ;
343 //        numberOfFields = MED_FR::MEDnChamp(_medIdt,0) ;
344 //        if ( numberOfFields <= 0 ) 
345 //      throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": No Field found !"));
346 //        for (int i=1;i<=numberOfFields;i++) {
347           
348 //      numberOfComponents = MED_FR::MEDnChamp(_medIdt,i) ;
349 //      if ( numberOfComponents <= 0 ) 
350 //        throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
351 //                                         <<  "Be careful there is no compound for field n°" 
352 //                                         << i << "in file |"<<_fileName<<"| !"));
353           
354 //      componentName = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;
355 //      unitName      = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;   
356           
357 //      err = MED_FR::MEDchampInfo(_medIdt, i, fieldName, &type, componentName, 
358 //                                 unitName, numberOfComponents) ;
359           
360 //      delete[] componentName ;
361 //      delete[] unitName ;
362 //      MESSAGE("Champ "<<i<<" : #" << fieldName <<"# et recherche #"<<_fieldName.c_str()<<"#");
363 //      if ( !strcmp(fieldName,_fieldName.c_str()) ) {
364 //        MESSAGE("FOUND FIELD "<< fieldName <<" : "<<i);
365 //        _fieldNum = i ;
366 //        break ;
367 //      }
368 //        }
369 //      }
370 //  }
371   
372 /*--------------------- RDONLY PART -------------------------------*/
373
374 template <class T> GENDRIVER * MED_FIELD_RDONLY_DRIVER<T>::copy(void) const
375 {
376   MED_FIELD_RDONLY_DRIVER<T> * myDriver = 
377     new MED_FIELD_RDONLY_DRIVER<T>(*this);
378   return myDriver ;
379 }
380
381 template <class T> void MED_FIELD_RDONLY_DRIVER<T>::read(void)
382   throw (MEDEXCEPTION)
383 {
384   const char * LOC = " MED_FIELD_RDONLY_DRIVER::read() " ;
385   BEGIN_OF(LOC);
386
387   if (MED_FIELD_DRIVER<T>::_ptrField->_name=="")
388     MED_FIELD_DRIVER<T>::_ptrField->_name = MED_FIELD_DRIVER<T>::_fieldName ; 
389   else
390     MED_FIELD_DRIVER<T>::_fieldName = MED_FIELD_DRIVER<T>::_ptrField->_name; // bug indetermine ! apres avoir fait readfilestruct, lorsque je recupere le champ, tout est bon sauf le nom du champ dans le driver !!!!!
391
392   MESSAGE("###### "<<LOC<<" fieldNameDRIVER : "<<MED_FIELD_DRIVER<T>::_fieldName<<" fieldName : "<<MED_FIELD_DRIVER<T>::_ptrField->_name);
393
394   string MeshName =  MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getMesh()->getName() ;
395
396   if (MED_FIELD_DRIVER<T>::_status==MED_OPENED)
397     {
398
399       //        search_field() ;
400
401       char *  fieldName ;
402       fieldName = new char[MED_TAILLE_NOM+1] ;
403       int err ;
404       int    numberOfComponents          = 0;
405       char * componentName               = (char *) MED_NULL;
406       char * unitName                    = (char *) MED_NULL;
407       MED_FR::med_type_champ type ;
408
409       // we search the field number !!!!
410       if (MED_FIELD_DRIVER<T>::_fieldNum==MED_INVALID) {
411         int    numberOfFields              = 0;      //MED_INVALID
412         numberOfFields = MED_FR::MEDnChamp(MED_FIELD_DRIVER<T>::_medIdt,0) ;
413         if ( numberOfFields <= 0 ) 
414           throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": No Field found !"));
415         for (int i=1;i<=numberOfFields;i++) {
416             
417           numberOfComponents = MED_FR::MEDnChamp(MED_FIELD_DRIVER<T>::_medIdt,i) ;
418           if ( numberOfComponents <= 0 ) 
419             //                throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
420             //                                                 <<  "Be careful there is no compound for field n°" 
421             //                                                 << i << "in file |"<<_fileName<<"| !"));
422             MESSAGE(LOC<<"Be careful there is no compound for field n°"<<i<<"in file |"<<_fileName<<"| !");
423
424           componentName = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;
425           unitName      = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;   
426             
427           err = MED_FR::MEDchampInfo(MED_FIELD_DRIVER<T>::_medIdt, i, fieldName, &type, componentName, 
428                                      unitName, numberOfComponents) ;
429             
430           MESSAGE("Champ "<<i<<" : #" << fieldName <<"# et recherche #"<<MED_FIELD_DRIVER<T>::_fieldName.c_str()<<"#");
431           if ( !strcmp(fieldName,MED_FIELD_DRIVER<T>::_fieldName.c_str()) ) {
432             MESSAGE("FOUND FIELD "<< fieldName <<" : "<<i);
433             MED_FIELD_DRIVER<T>::_fieldNum = i ;
434             break ;
435           }
436           // not found : release memory and search next field !
437           delete[] componentName ;
438           delete[] unitName ;
439         }
440       }
441       
442       delete[] fieldName ;
443
444       if (MED_FIELD_DRIVER<T>::_fieldNum==MED_INVALID)
445         throw MEDEXCEPTION(LOCALIZED( STRING(LOC) << ": Field "<<MED_FIELD_DRIVER<T>::_fieldName << " not found in file " << MED_FIELD_DRIVER<T>::_fileName ) );
446       MESSAGE ("FieldNum : "<<MED_FIELD_DRIVER<T>::_fieldNum);
447
448       //        int err ;
449       //        int NumberOfComponents = MED_FR::MEDnChamp(MED_FIELD_DRIVER<T>::_medIdt,MED_FIELD_DRIVER<T>::_fieldNum) ;
450       if (numberOfComponents < 1) 
451         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"no component")) ; // use iostring !
452       // test type to check if it is rigth !!!???
453       MED_FIELD_DRIVER<T>::_ptrField->_numberOfComponents = numberOfComponents ;
454       MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = new int[numberOfComponents] ;
455       MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = new string[numberOfComponents] ;
456       MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = new UNIT[numberOfComponents] ;
457       MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = new string[numberOfComponents] ;
458       MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = new string[numberOfComponents] ;
459       for (int i=0; i<numberOfComponents; i++) {
460         MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes[i] = 1 ;
461
462         // PG : what about space !!!
463         MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i] = string(componentName,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM) ;
464         SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i]);
465         MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i] = string(unitName,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM) ;
466         SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i]);
467       }
468       delete[] componentName;
469       delete[] unitName;
470
471       // read values for each geometric type in _support
472       int NumberOfTypes = MED_FIELD_DRIVER<T>::_ptrField->_support->getNumberOfTypes() ;
473       const medGeometryElement *Types = MED_FIELD_DRIVER<T>::_ptrField->_support->getTypes() ;
474       T ** myValues = new T*[NumberOfTypes] ;
475       int * NumberOfValues = new int[NumberOfTypes] ;
476       int TotalNumberOfValues = 0 ;
477       MESSAGE ("NumberOfTypes :"<< NumberOfTypes);
478       _ptrField->_numberOfValues=0 ;
479       for (int i=0; i<NumberOfTypes; i++) {
480         MESSAGE ("Type["<<i+1<<"] :"<< Types[i]);
481         MESSAGE ("Entity :"<<MED_FIELD_DRIVER<T>::_ptrField->_support->getEntity());
482         NumberOfValues[i] = 
483           MEDnVal(MED_FIELD_DRIVER<T>::_medIdt,
484                   const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
485                   (MED_FR::med_entite_maillage)MED_FIELD_DRIVER<T>::_ptrField->_support->getEntity(),
486                   (MED_FR::med_geometrie_element)Types[i],
487                   MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber,
488                   MED_FIELD_DRIVER<T>::_ptrField->_orderNumber) ; // no time step ! prend en compte le nbre de pt de gauss
489         // test if NumberOfValues is the same in _support !!! TODO that !!
490         // we suppose it is
491         // we could allocate array
492         myValues[i] = new T[ NumberOfValues[i]*numberOfComponents ] ;
493         TotalNumberOfValues+=NumberOfValues[i] ;// diviser par le nombre de point de gauss 
494         char * ProfilName = new char[MED_TAILLE_NOM+1];
495         MESSAGE ("NumberOfValues :"<< NumberOfValues[i]);
496         MESSAGE ("NumberOfComponents :"<< numberOfComponents);
497         MESSAGE ("MESH_NAME :"<< MeshName.c_str());
498         MESSAGE ("FIELD_NAME :"<< MED_FIELD_DRIVER<T>::_fieldName.c_str());
499         MESSAGE ("MED_ENTITE :"<< (MED_FR::med_entite_maillage) MED_FIELD_DRIVER<T>::_ptrField->_support->getEntity());
500         MESSAGE("MED_GEOM :"<<(MED_FR::med_geometrie_element)Types[i]);
501         MESSAGE("Iteration :"<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber());
502         MESSAGE("Order :"<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber());
503         MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues+=NumberOfValues[i]; // problem with gauss point : _numberOfValues != TotalNumberOfValues !!!!!!!
504         if ( MED_FR::MEDchampLire(MED_FIELD_DRIVER<T>::_medIdt,const_cast <char*> (MeshName.c_str()),
505                                   const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
506                                   (unsigned char*) myValues[i],
507                                   MED_FR::MED_NO_INTERLACE,
508                                   MED_ALL,
509                                   ProfilName,
510                                   (MED_FR::med_entite_maillage) MED_FIELD_DRIVER<T>::_ptrField->_support->getEntity(),(MED_FR::med_geometrie_element)Types[i],
511                                   MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
512                                   MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
513                                   ) < 0) {
514           // we must do some delete !!!
515           for(int j=0; j<=i;j++)
516             delete[] myValues[j];
517           delete[] myValues;
518           delete[] NumberOfValues ;
519           delete[] ProfilName;
520           delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes ;
521           delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsNames ;
522           delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits ;
523           delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions ;
524           delete[] MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits ;
525           MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = NULL ;
526           MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = NULL ;
527           MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = NULL ;
528           MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = NULL ;
529           MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = NULL ;
530           MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ; // we have not found right field, so reset the field number 
531           throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": ERROR when read value")) ;
532         }
533
534         delete[] ProfilName ;
535       }
536       // allocate _value
537       // probleme avec les points de gauss : voir lorsqu-il y en a (!= 1)
538       //      MEDARRAY<T> * Values = new MEDARRAY<T>(MED_FIELD_DRIVER<T>::_ptrField->getNumberOfComponents(),TotalNumberOfValues/MED_FIELD_DRIVER<T>::_ptrField->getNumberOfComponents(),MED_EN::MED_NO_INTERLACE);
539
540       if (MED_FIELD_DRIVER<T>::_ptrField->_value==NULL)
541         MED_FIELD_DRIVER<T>::_ptrField->_value=new MEDARRAY<T>(numberOfComponents,TotalNumberOfValues,MED_EN::MED_NO_INTERLACE);
542
543       MEDARRAY<T> * Values = MED_FIELD_DRIVER<T>::_ptrField->_value ; // create by constructor ???
544       // check if dimensions are right : inutile : c'est dans le constructeur !!!
545       //if (Values->getLeadingValue() != numberOfComponents)
546       //  throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": leading dimension are false : "<<Values->getLeadingValue()<<" and "<<numberOfComponents) ) ;
547       //if (Values->getLengthValue() != TotalNumberOfValues)
548       //  throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": length dimension are false : "<<Values->getLengthValue()<<" and "<<TotalNumberOfValues) ) ;
549
550       for (int i=0; i<numberOfComponents; i++) {
551         //T * ValuesT = Values->getRow(i+1) ;
552         int Count = 1 ;
553         for (int j=0; j<NumberOfTypes; j++) {
554           T * myValue = myValues[j] ;
555           int NumberOf = NumberOfValues[j] ;
556 //        MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues+=NumberOf; // problem with gauss point : _numberOfValues != TotalNumberOfValues !!!!!!!
557           int offset = NumberOf*i ;
558           for (int k=0 ; k<NumberOf; k++) {
559             //ValuesT[Count]=myValue[k+offset] ;
560             Values->setIJ(Count,i+1,myValue[k+offset]);
561             SCRUTE(Count);
562             SCRUTE(Values->getIJ(Count,i+1));
563             Count++;
564           }
565         }
566       }
567       
568       for (int j=0; j<NumberOfTypes; j++)
569         delete[] myValues[j] ;
570       delete[] myValues ;
571       delete[] NumberOfValues ;
572
573       MED_FIELD_DRIVER<T>::_ptrField->_isRead = true ;
574     }
575
576   END_OF(LOC);
577 }
578
579 template <class T> void MED_FIELD_RDONLY_DRIVER<T>::write( void ) const
580   throw (MEDEXCEPTION)
581 {
582   throw MEDEXCEPTION("MED_FIELD_RDONLY_DRIVER::write : Can't write with a RDONLY driver !");
583 }
584
585 /*--------------------- WRONLY PART -------------------------------*/
586
587 template <class T> GENDRIVER * MED_FIELD_WRONLY_DRIVER<T>::copy(void) const
588 {
589   MED_FIELD_WRONLY_DRIVER<T> * myDriver = 
590     new MED_FIELD_WRONLY_DRIVER<T>(*this);
591   return myDriver ;
592 }
593
594 template <class T> void MED_FIELD_WRONLY_DRIVER<T>::read (void)
595   throw (MEDEXCEPTION)
596 {
597   throw MEDEXCEPTION("MED_FIELD_WRONLY_DRIVER::read : Can't read with a WRONLY driver !");
598 }
599
600 template <class T> void MED_FIELD_WRONLY_DRIVER<T>::write(void) const
601   throw (MEDEXCEPTION)
602 {
603   const char * LOC = "MED_FIELD_WRONLY_DRIVER::write(void) const " ;
604   BEGIN_OF(LOC);
605   if (MED_FIELD_DRIVER<T>::_status==MED_OPENED)
606     {
607       int err ;
608
609       int component_count=MED_FIELD_DRIVER<T>::_ptrField->getNumberOfComponents();
610       string   component_name(component_count*MED_TAILLE_PNOM,' ') ;
611       string   component_unit(component_count*MED_TAILLE_PNOM,' ') ;
612
613       const string * listcomponent_name=MED_FIELD_DRIVER<T>::_ptrField->getComponentsNames() ;
614       const string * listcomponent_unit=MED_FIELD_DRIVER<T>::_ptrField->getMEDComponentsUnits() ;
615       int length ;
616       for (int i=0; i < component_count ; i++) {
617         length = min(MED_TAILLE_PNOM,(int)listcomponent_name[i].size());
618         component_name.replace(i*MED_TAILLE_PNOM,length,
619                                listcomponent_name[i],0,length);
620         length = min(MED_TAILLE_PNOM,(int)listcomponent_unit[i].size());
621         component_unit.replace(i*MED_TAILLE_PNOM,length,
622                                listcomponent_unit[i],0,length);
623       }
624
625       MESSAGE("component_name=|"<<component_name<<"|");
626       MESSAGE("component_unit=|"<<component_unit<<"|");
627
628       MED_EN::med_type_champ ValueType=MED_FIELD_DRIVER<T>::_ptrField->getValueType() ;
629       
630       MESSAGE("Template Type =|"<<ValueType<<"|");
631       
632       // le champ existe deja ???
633       char * champName = new char[MED_TAILLE_NOM+1] ;
634       MED_FR::med_type_champ type ;
635       char * compName ;
636       char * compUnit ;
637       bool Find = false ;
638       int n = MED_FR::MEDnChamp(MED_FIELD_DRIVER<T>::_medIdt,0);
639       int nbComp ;
640       for (int i=1; i<=n; i++) {
641         nbComp = MED_FR::MEDnChamp(MED_FIELD_DRIVER<T>::_medIdt,i);
642         compName = new char[MED_TAILLE_PNOM*nbComp+1];
643         compUnit = new char[MED_TAILLE_PNOM*nbComp+1];
644         err = MED_FR::MEDchampInfo(MED_FIELD_DRIVER<T>::_medIdt,i,champName,&type,compName,compUnit,nbComp);
645         if (err == 0)
646           if (strcmp(champName,MED_FIELD_DRIVER<T>::_ptrField->getName().c_str())==0) { // Found !
647             Find = true ;
648             break ;
649           }
650         delete[] compName ;
651         delete[] compUnit ;
652       }
653       delete[] champName ;
654       if (Find) {
655         // the same ?
656         if (nbComp != component_count)
657           throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
658                                          <<": Field exist in file, but number of component are different : "<<nbComp<<" in file and "<<component_count<<" in memory."
659                                          )
660                               );
661         // component name and unit
662         MESSAGE(LOC<<" Component name in file : "<<compName);
663         MESSAGE(LOC<<" Component name in memory : "<<component_name);
664         MESSAGE(LOC<<" Component unit in file : "<<compUnit);
665         MESSAGE(LOC<<" Component unit in memory : "<<component_unit);
666         delete[] compName ;
667         delete[] compUnit ;
668
669       } else {
670         // Verify the field doesn't exist
671
672         string dataGroupName =  "/CHA/";
673         dataGroupName        += MED_FIELD_DRIVER<T>::_ptrField->getName();
674         MESSAGE(LOC << "|" << dataGroupName << "|" );
675         med_idt gid =  H5Gopen(MED_FIELD_DRIVER<T>::_medIdt, dataGroupName.c_str() );
676         
677         if ( gid < 0 ) {
678           // create field :
679           err=MED_FR::MEDchampCr(MED_FIELD_DRIVER<T>::_medIdt, 
680                                  const_cast <char*> ((MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()),
681                                  (MED_FR::med_type_champ) ValueType,
682                                  const_cast <char*> ( component_name.c_str() ),
683                                  const_cast <char*> ( component_unit.c_str() ),
684                                  component_count);
685           if ( err < 0 )
686             throw MEDEXCEPTION( LOCALIZED (STRING(LOC) 
687                                            << ": Error MEDchampCr : "<<err
688                                            )
689                                 );
690         }
691         else H5Gclose(gid);
692       }
693
694       const SUPPORT * mySupport = MED_FIELD_DRIVER<T>::_ptrField->getSupport() ;
695
696       if (! mySupport->isOnAllElements())
697         throw MEDEXCEPTION( LOCALIZED (STRING(LOC) 
698                                        <<": Field must be on all entity"
699                                        )
700                             );
701       
702       MESH * myMesh = mySupport->getMesh() ;
703       string MeshName = myMesh->getName() ;
704       //MED_EN::medModeSwitch Mode = MED_FIELD_DRIVER<T>::_ptrField->_value->getMode() ;
705       // on boucle sur tout les types pour ecrire les tableaux de valeur
706       int NumberOfType = mySupport->getNumberOfTypes() ;
707       int Index = 1 ;
708       const medGeometryElement * Types = mySupport->getTypes() ;
709       const int * NumberOfGaussPoint = mySupport->getNumberOfGaussPoint() ;
710       for (int i=0;i<NumberOfType;i++) {
711         int NumberOfElements = mySupport->getNumberOfElements(Types[i]) ;
712         
713         const T * value = MED_FIELD_DRIVER<T>::_ptrField->getValueI(MED_EN::MED_FULL_INTERLACE,Index) ;
714         
715         MESSAGE("MED_FIELD_DRIVER<T>::_medIdt                         : "<<MED_FIELD_DRIVER<T>::_medIdt);
716         MESSAGE("MeshName.c_str()                : "<<MeshName.c_str());
717         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getName()            : "<<MED_FIELD_DRIVER<T>::_ptrField->getName());
718         MESSAGE("value                           : "<<value);
719         MESSAGE("NumberOfElements                : "<<NumberOfElements);
720         MESSAGE("NumberOfGaussPoint[i]           : "<<NumberOfGaussPoint[i]);
721         MESSAGE("mySupport->getEntity()          : "<<mySupport->getEntity());
722         MESSAGE("Types[i]                        : "<<Types[i]);
723         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber());
724         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getTime()            : "<<MED_FIELD_DRIVER<T>::_ptrField->getTime());
725         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()     : "<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber());
726         
727 /*      char chanom[MED_TAILLE_NOM+1];
728         char chacomp[MED_TAILLE_NOM+1];
729         char chaunit[MED_TAILLE_NOM+1];
730         MED_FR::med_type_champ chatype;
731         med_int chancomp=1;
732         
733         err=MED_FR::MEDchampInfo(MED_FIELD_DRIVER<T>::_medIdt,1,chanom,&chatype,chacomp,chaunit,chancomp);
734
735         if (err<0) 
736                 {
737                 cout<<"=======================================================================> gros probleme"<<endl;
738                 exit(-1);
739                 }
740         cout<<"==================> nom lu            = "<<chanom<<endl;
741         cout<<"==================> type lu           = "<<chatype<<endl;
742         cout<<"==================> nom composante lu = "<<chacomp<<endl;
743         cout<<"==================> nom unit lu       = "<<chaunit<<endl;
744         cout<<"==================> valeur de MED_FR::MED_REEL64 = "<<MED_FR::MED_REEL64<<endl;
745 */      
746
747         err=MED_FR::MEDchampEcr(MED_FIELD_DRIVER<T>::_medIdt, 
748                                 const_cast <char*> ( MeshName.c_str()) ,                         //( string(mesh_name).resize(MED_TAILLE_NOM).c_str())
749                                 const_cast <char*> ( (MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()),
750                                 (unsigned char*)value, 
751                                 MED_FR::MED_FULL_INTERLACE,
752                                 NumberOfElements,
753                                 NumberOfGaussPoint[i],
754                                 MED_ALL,
755                                 MED_NOPFL,
756                                 MED_FR::MED_REMP,  // PROFIL NON GERE, mode de remplacement non géré
757                                 (MED_FR::med_entite_maillage)mySupport->getEntity(),
758                                 (MED_FR::med_geometrie_element)Types[i],
759                                 MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
760                                 "        ",
761                                 MED_FIELD_DRIVER<T>::_ptrField->getTime(),
762                                 MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
763                                 );
764         if (err < MED_VALID )
765           throw MEDEXCEPTION(LOCALIZED( STRING(LOC)
766                                         <<": Error in writing Field "<< MED_FIELD_DRIVER<T>::_ptrField->getName() <<", type "<<Types[i]
767                                         )
768                              );
769
770         Index += NumberOfElements ;
771         
772       }
773     }
774   
775   END_OF(LOC);
776 }
777
778 /*--------------------- RDWR PART -------------------------------*/
779
780 template <class T> GENDRIVER * MED_FIELD_RDWR_DRIVER<T>::copy(void) const
781 {
782   MED_FIELD_RDWR_DRIVER<T> * myDriver = 
783     new MED_FIELD_RDWR_DRIVER<T>(*this);
784   return myDriver ;
785 }
786
787 template <class T> void MED_FIELD_RDWR_DRIVER<T>::write(void) const
788   throw (MEDEXCEPTION)
789 {
790   BEGIN_OF("MED_FIELD_RDWR_DRIVER::write(void)");
791   MED_FIELD_WRONLY_DRIVER<T>::write(); 
792   END_OF("MED_FIELD_RDWR_DRIVER::write(void)");
793
794
795 template <class T> void MED_FIELD_RDWR_DRIVER<T>::read (void)
796   throw (MEDEXCEPTION)
797 {
798   BEGIN_OF("MED_FIELD_RDWR_DRIVER::read(void)");
799   MED_FIELD_RDONLY_DRIVER<T>::read();
800   END_OF("MED_FIELD_RDWR_DRIVER::read(void)");
801 }
802 /*-----------------------------------------------------------------*/
803
804 #endif /* MED_FIELD_DRIVER_HXX */
805