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