Salome HOME
fea7fd134f112f8388734aee62530058abdd09f3
[modules/med.git] / src / MEDMEM / MEDMEM_MedFieldDriver21.hxx
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 #ifndef MED_FIELD_DRIVER21_HXX
21 #define MED_FIELD_DRIVER21_HXX
22
23 #include <string>
24
25 #include "MEDMEM_define.hxx"
26
27 #include "MEDMEM_DriversDef.hxx"
28 #include "MEDMEM_Utilities.hxx"
29 #include "MEDMEM_MedFieldDriver.hxx"
30 #include "MEDMEM_STRING.hxx"
31 #include "MEDMEM_Exception.hxx"
32 #include "MEDMEM_Unit.hxx"
33
34 #include "MEDMEM_ArrayInterface.hxx"
35 #include "MEDMEM_ArrayConvert.hxx"
36
37 #include "MEDMEM_Support.hxx"
38 #include "MEDMEM_Mesh.hxx"
39
40 namespace MEDMEM {
41
42 /*!
43
44   Driver Med for FIELD.
45
46   Generic part : implement open and close methods.
47
48 */
49
50 template <class T> class MED_FIELD_DRIVER21 : public virtual MED_FIELD_DRIVER<T>
51 {
52 protected:
53   med_2_1::med_idt        _medIdt;
54  
55   bool createFieldSupport(med_2_1::med_idt id,
56                           string & fieldName,
57                           med_2_1::med_int ndt,
58                           med_2_1::med_int od,
59                           SUPPORT & support,
60                           string & meshName) const throw (MEDEXCEPTION);
61
62   void getMeshGeometricType(med_2_1::med_idt id,
63                             string & meshName,
64                             MED_EN::medEntityMesh  entite,
65                             vector<MED_EN::medGeometryElement> & geoType,
66                             vector<int> &nbOfElOfType) const;
67
68 public :
69   
70   /*!
71     Constructor.
72   */
73   MED_FIELD_DRIVER21():MED_FIELD_DRIVER<T>(),_medIdt(MED_INVALID)
74   {}
75   /*!
76     Constructor.
77   */
78   template <class INTERLACING_TAG>
79   MED_FIELD_DRIVER21(const string & fileName,
80                      FIELD<T, INTERLACING_TAG> * ptrField, 
81                      MED_EN::med_mode_acces accessMode)
82     : MED_FIELD_DRIVER<T>(fileName,ptrField,accessMode),_medIdt(MED_INVALID)
83   {
84   }
85
86   /*!
87     Copy constructor.
88   */
89   MED_FIELD_DRIVER21(const MED_FIELD_DRIVER21 & fieldDriver):
90     MED_FIELD_DRIVER<T>(fieldDriver), _medIdt(fieldDriver._medIdt)
91   {
92   }
93
94   /*!
95     Destructor.
96   */
97   virtual ~MED_FIELD_DRIVER21() { 
98   }
99
100   void open() throw (MEDEXCEPTION)
101   {
102     const char * LOC = "MED_FIELD_DRIVER21::open() ";
103     BEGIN_OF(LOC);
104
105     // we must set fieldname before open, because we must find field number in file (if it exist !!!)
106     if ( MED_FIELD_DRIVER<T>::_fileName == "" )
107       throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
108                                        << "_fileName is |\"\"|, please set a correct fileName before calling open()"
109                                        )
110                             );
111
112     MESSAGE(LOC<<"_fileName.c_str : "<< MED_FIELD_DRIVER<T>::_fileName.c_str()<<",mode : "<< MED_FIELD_DRIVER<T>::_accessMode);
113     _medIdt = med_2_1::MEDouvrir( (const_cast <char *> (MED_FIELD_DRIVER<T>::_fileName.c_str())),(med_2_1::med_mode_acces) MED_FIELD_DRIVER<T>::_accessMode);
114     MESSAGE(LOC<<"_medIdt : "<< _medIdt );
115     if (_medIdt > 0) 
116       MED_FIELD_DRIVER<T>::_status=MED_OPENED;
117     else {
118       MED_FIELD_DRIVER<T>::_status = MED_INVALID;
119       MED_FIELD_DRIVER21<T>::_medIdt = MED_INVALID;
120       throw MED_EXCEPTION (LOCALIZED( STRING(LOC) 
121                                       << "Can't open |"  << MED_FIELD_DRIVER<T>::_fileName 
122                                       << "|, _medIdt : " << MED_FIELD_DRIVER21<T>::_medIdt
123                                       )
124                            );
125     }
126
127     END_OF(LOC);
128   }
129   
130   void close() {
131     BEGIN_OF("MED_FIELD_DRIVER21::close()");
132     med_2_1::med_int err = 0;
133     if (MED_FIELD_DRIVER<T>::_status == MED_OPENED) {
134       err=med_2_1::MEDfermer(MED_FIELD_DRIVER21<T>::_medIdt);
135       //H5close(); // If we call H5close() all the files are closed.
136       MED_FIELD_DRIVER<T>::_status = MED_CLOSED;
137       MED_FIELD_DRIVER21<T>::_medIdt = MED_INVALID;
138       MESSAGE(" MED_FIELD_DRIVER21::close() : MEDfermer : MED_FIELD_DRIVER21<T>::_medIdt= " << _medIdt );
139       MESSAGE(" MED_FIELD_DRIVER21::close() : MEDfermer : err    = " << err );
140     }
141     END_OF("MED_FIELD_DRIVER21::close()");
142   }
143
144
145 };
146
147 /*!
148
149   Driver Med for FIELD : Read only.
150
151   Implement read method.
152
153 */
154
155   template <class T> class MED_FIELD_RDONLY_DRIVER21 : public virtual MED_FIELD_DRIVER21<T>, public virtual IMED_FIELD_RDONLY_DRIVER<T>
156 {
157  
158 public :
159   
160   /*!
161     Constructor.
162   */
163   MED_FIELD_RDONLY_DRIVER21():MED_FIELD_DRIVER<T>() {};
164   
165   /*!
166     Constructor.
167   */
168   template <class INTERLACING_TAG>
169   MED_FIELD_RDONLY_DRIVER21(const string & fileName,
170                             FIELD<T, INTERLACING_TAG> * ptrField):
171     MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_RDONLY),
172     MED_FIELD_DRIVER21<T>(fileName,ptrField,MED_EN::MED_RDONLY),
173     IMED_FIELD_RDONLY_DRIVER<T>(fileName,ptrField)
174   { 
175     BEGIN_OF("MED_FIELD_RDONLY_DRIVER21::MED_FIELD_RDONLY_DRIVER21(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)");
176     END_OF("MED_FIELD_RDONLY_DRIVER21::MED_FIELD_RDONLY_DRIVER21(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)");
177   }
178   
179   /*!
180     Copy constructor.
181   */
182   MED_FIELD_RDONLY_DRIVER21(const MED_FIELD_RDONLY_DRIVER21 & fieldDriver):
183     IMED_FIELD_RDONLY_DRIVER<T>(fieldDriver),
184     MED_FIELD_DRIVER21<T>(fieldDriver),
185     MED_FIELD_DRIVER<T>(fieldDriver)
186   {};
187   
188   /*!
189     Destructor.
190   */
191   virtual ~MED_FIELD_RDONLY_DRIVER21() {};
192
193   // CREER UNE METHODE POUR LIRE LA LISTE DES MAILLAGES .....
194
195   /*!
196     Return a MEDEXCEPTION : it is the read-only driver.
197   */
198   void write( void ) const throw (MEDEXCEPTION) ;
199   /*!
200     Read FIELD in the specified file.
201   */
202   void read ( void ) throw (MEDEXCEPTION) ;
203
204 private:
205   GENDRIVER * copy( void ) const ;
206
207 };
208
209 /*!
210
211   Driver Med for FIELD : Write only.
212
213   Implement write method.
214
215 */
216
217 template <class T> class MED_FIELD_WRONLY_DRIVER21 : public virtual MED_FIELD_DRIVER21<T>, public virtual IMED_FIELD_WRONLY_DRIVER<T> {
218   
219 public :
220   
221   /*!
222     Constructor.
223   */
224   MED_FIELD_WRONLY_DRIVER21():MED_FIELD_DRIVER<T>() {}
225   
226   /*!
227     Constructor.
228   */
229   template <class INTERLACING_TAG>
230   MED_FIELD_WRONLY_DRIVER21(const string & fileName,
231                             FIELD<T, INTERLACING_TAG> * ptrField):
232     IMED_FIELD_WRONLY_DRIVER<T>(fileName,ptrField),
233     MED_FIELD_DRIVER21<T>(fileName,ptrField,MED_EN::MED_WRONLY),
234     MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_WRONLY)
235   {
236     BEGIN_OF("MED_FIELD_WRONLY_DRIVER21::MED_FIELD_WRONLY_DRIVER21(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)");
237     END_OF("MED_FIELD_WRONLY_DRIVER21::MED_FIELD_WRONLY_DRIVER21(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)");
238   }
239
240   /*!
241     Copy constructor.
242   */
243   MED_FIELD_WRONLY_DRIVER21(const MED_FIELD_WRONLY_DRIVER21 & fieldDriver):
244     IMED_FIELD_WRONLY_DRIVER<T>(fieldDriver),
245     MED_FIELD_DRIVER21<T>(fieldDriver),
246     MED_FIELD_DRIVER<T>(fieldDriver)
247   {}
248   
249   /*!
250     Destructor.
251   */
252   virtual ~MED_FIELD_WRONLY_DRIVER21() {};
253
254   /*!
255     Write FIELD in the specified file.
256   */
257   void write( void ) const throw (MEDEXCEPTION) ;
258   /*!
259     Return a MEDEXCEPTION : it is the write-only driver.
260   */
261   void read ( void ) throw (MEDEXCEPTION) ;
262
263 private:
264   GENDRIVER * copy( void ) const ;
265
266 };
267
268
269 /*!
270
271   Driver Med for FIELD : Read write.
272   - Use read method from MED_FIELD_RDONLY_DRIVER
273   - Use write method from MED_FIELD_WDONLY_DRIVER
274
275 */
276
277 template <class T> class MED_FIELD_RDWR_DRIVER21 : public MED_FIELD_RDONLY_DRIVER21<T>, public MED_FIELD_WRONLY_DRIVER21<T>, public IMED_FIELD_RDWR_DRIVER<T> {
278   
279 public :
280   
281   /*!
282     Constructor.
283   */
284   MED_FIELD_RDWR_DRIVER21():MED_FIELD_DRIVER21<T>() {}
285   
286   /*!
287     Constructor.
288   */
289   template <class INTERLACING_TAG>
290   MED_FIELD_RDWR_DRIVER21(const string & fileName,
291                           FIELD<T, INTERLACING_TAG> * ptrField):
292     MED_FIELD_WRONLY_DRIVER21<T>(fileName,ptrField),
293     MED_FIELD_RDONLY_DRIVER21<T>(fileName,ptrField),
294     IMED_FIELD_RDONLY_DRIVER<T>(fileName,ptrField),
295     IMED_FIELD_WRONLY_DRIVER<T>(fileName,ptrField),
296     MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_RDWR),
297     IMED_FIELD_RDWR_DRIVER<T>(fileName,ptrField)
298   {
299     BEGIN_OF("MED_FIELD_RDWR_DRIVER21::MED_FIELD_RDWR_DRIVER21(const string & fileName, const FIELD<T> * ptrField)");
300     //_accessMode = MED_RDWR ;
301     END_OF("MED_FIELD_RDWR_DRIVER21::MED_FIELD_RDWR_DRIVER21(const string & fileName, const FIELD<T> * ptrField)");
302   };
303
304   /*!
305     Copy constructor.
306   */
307   MED_FIELD_RDWR_DRIVER21(const MED_FIELD_RDWR_DRIVER21 & fieldDriver):
308     MED_FIELD_WRONLY_DRIVER21<T>(fieldDriver),
309     MED_FIELD_RDONLY_DRIVER21<T>(fieldDriver),
310     IMED_FIELD_RDWR_DRIVER<T>(fieldDriver),
311     IMED_FIELD_RDONLY_DRIVER<T>(fieldDriver),
312     IMED_FIELD_WRONLY_DRIVER<T>(fieldDriver),
313     MED_FIELD_DRIVER<T>(fieldDriver)
314   {};
315   
316   /*!
317     Destructor.
318   */
319   ~MED_FIELD_RDWR_DRIVER21() {};
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 /*--------------------- DRIVER PART -------------------------------*/
336
337 template <class T> bool
338 MED_FIELD_DRIVER21<T>::createFieldSupport(med_2_1::med_idt id,
339                                         string & fieldName,
340                                         med_2_1::med_int ndt,
341                                         med_2_1::med_int od,
342                                         SUPPORT & support,
343                                         string & meshName) const throw (MEDEXCEPTION)
344 {
345
346   //EF : Gérer le meshName pour le driver 2.2
347   const char * LOC="MED_FIELD_DRIVER<T>::search_field(...)";
348
349   map<int, list<MED_EN::medGeometryElement> > CellAndNodeEntities;
350   map<int, list<MED_EN::medGeometryElement> >::iterator currentEntity;
351   CellAndNodeEntities[MED_EN::MED_CELL]  = MED_EN::meshEntities[MED_EN::MED_CELL];
352   CellAndNodeEntities[MED_EN::MED_NODE] = MED_EN::meshEntities[MED_EN::MED_NODE];
353   list< MED_EN::medGeometryElement >::const_iterator currentGeometry;
354
355   //med_2_1::med_entite_maillage
356   MED_EN::medEntityMesh entity;
357   bool alreadyFoundAnEntity=false, alreadyFoundPdtIt = false, anyGauss=false;
358   int  numberOfElements = 0;
359   int  numberOfGeometricType = 0;
360   //med_2_1::med_geometrie_element..
361   MED_EN::medGeometryElement geometricType[MED_NBR_GEOMETRIE_MAILLE];
362   int numberOfElementsOfType[MED_NBR_GEOMETRIE_MAILLE];
363   int numberOfGaussPoints[MED_NBR_GEOMETRIE_MAILLE];
364
365   med_2_1::med_int ngauss=0, numdt=-1, numo=-1, nbPdtIt=0; //nmaa=0
366   char dtunit[MED_TAILLE_PNOM21+1], maa[MED_TAILLE_NOM+1];
367   med_2_1::med_float   dt=-1.0;
368   //med_2_1::med_booleen local;
369   med_2_1::med_err     ret=1;
370
371   for (currentEntity = CellAndNodeEntities.begin();
372        currentEntity != CellAndNodeEntities.end(); currentEntity++) {
373     for (currentGeometry  = (*currentEntity).second.begin();
374          currentGeometry != (*currentEntity).second.end(); currentGeometry++) {
375
376       if ( (numberOfElements =  med_2_1::MEDnVal(id, const_cast <char*> ( fieldName.c_str() ),
377                                                 (med_2_1::med_entite_maillage)   (*currentEntity).first,
378                                                 (med_2_1::med_geometrie_element) *currentGeometry,
379                                                 ndt, od))  <=  0 )
380         continue;
381
382       if ( alreadyFoundAnEntity ) {
383         if (entity != (*currentEntity).first )
384           throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |"  << fieldName
385                                        << "| with (ndt,or) = (" << ndt << ","
386                                        << od << ") must not be defined on nodes and cells" ));
387
388       } else { entity=(*currentEntity).first; alreadyFoundAnEntity = true; };
389
390       nbPdtIt = med_2_1::MEDnPasdetemps(id, const_cast <char*> ( fieldName.c_str() ),
391                                         (med_2_1::med_entite_maillage)   (*currentEntity).first,
392                                         (med_2_1::med_geometrie_element)  *currentGeometry );
393       if ( nbPdtIt < 0 )
394         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = ("
395                                      << ndt << "," << od << ") should be defined for (entityType,geometricType)=("
396                                      << MED_EN::entNames[(*currentEntity).first] << ","
397                                      << MED_EN::geoNames[*currentGeometry] << ")" ));
398
399       ret = 0; alreadyFoundPdtIt = false; ngauss =0;
400       for ( med_2_1::med_int j=1; j <= nbPdtIt; j++ ) {
401
402         // Search how many <ngauss> (<fieldName>,<ndt>,<ot>) has
403         ret = med_2_1::MEDpasdetempsInfo(id, const_cast <char*> ( fieldName.c_str() ),
404                                          (med_2_1::med_entite_maillage)   (*currentEntity).first,
405                                          (med_2_1::med_geometrie_element)  *currentGeometry,
406                                          j,maa,&ngauss,&numdt,dtunit,&dt,&numo);
407
408         //          ret = med_2_2::MEDpasdetempsInfo(id, const_cast <char*> ( fieldName.c_str() ),
409         //                                  (med_2_1::med_entite_maillage)   (*currentEntity).first,
410         //                                  (med_2_1::med_geometrie_element)  *currentGeometry,
411         //                                  j, &ngauss,  &numdt,  &numo, &dtunit, &dt, &maa, &local, &nmaa)
412
413         if ( ndt == numdt && numo == od ) {
414           alreadyFoundPdtIt = true;
415           if ( ! meshName.empty() )
416             if ( meshName != maa ) {
417
418               //                  if ( nmaa > 1 )
419               {
420                 //EF : Gérer le meshName pour le driver 2.2
421                 //                    MESSAGE(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = (" << ndt << ","
422                 //                            << ot << ") is  defined on " << nmaa << " meshes, using mesh |"
423                 //                            << maa << "|");
424                 //                  }
425                 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = ("
426                                              << ndt << "," << od << ") for (entityType,geometricType)=("
427                                              << MED_EN::entNames[(*currentEntity).first] << ","
428                                              << MED_EN::geoNames[*currentGeometry] << ")"
429                                              << "is defined on mesh |" << maa << "| not on mesh |" << meshName ));
430               }
431             }
432           break;
433         }
434       }
435
436       if ( !alreadyFoundPdtIt )
437         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = ("
438                                      << ndt << "," << od << ") should be defined for (entityType,geometricType)=("
439                                      << MED_EN::entNames[(*currentEntity).first] << ","
440                                      << MED_EN::geoNames[*currentGeometry] << ")" ));
441
442       if ( (ret != 0)  || (ngauss < 1 ) )
443         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Error in MEDpasdetempsInfo for  Field |" << fieldName 
444                                      << "| with (ndt,or) = ("
445                                      << ndt << "," << od << ") for (entityType,geometricType)=("
446                                      << MED_EN::entNames[(*currentEntity).first] << ","
447                                      << MED_EN::geoNames[*currentGeometry] << ")" )); ;
448
449       //totalNumberOfElements+=numberOfElements;
450       numberOfElementsOfType[numberOfGeometricType] = numberOfElements/ngauss;
451       numberOfGaussPoints[numberOfGeometricType] = ngauss;
452       anyGauss = (anyGauss || (ngauss-1) );
453       geometricType[numberOfGeometricType]= *currentGeometry;
454       numberOfGeometricType++;
455
456     } // End Second For
457
458   } // End Premier For
459
460   if ( alreadyFoundAnEntity) {
461     support.setName(fieldName+"Support");
462     support.setMeshName(string(maa)); // Vérifier que les différents noms de maillages lus soient identiques
463     support.setEntity(entity);
464     // REM : Signification précédente erronée pour un champ qui ne repose pas sur toutes les entités géométriques 
465     // du maillage mais dont le SUPPORT a été crée à partir des informations d'un maillage, comme
466     // celà fût la plupart du temps.
467     support.setNumberOfGeometricType(numberOfGeometricType);
468     support.setGeometricType(geometricType); // Utile uniquement si setAll == false
469     support.setNumberOfElements(numberOfElementsOfType);    //setNumberOfElements effectue une copie
470     support.setAll(true);
471
472     return alreadyFoundAnEntity;
473   } else
474     return false;
475 }
476
477 template <class T> void
478 MED_FIELD_DRIVER21<T>::getMeshGeometricType(med_2_1::med_idt id,
479                                           string & meshName,
480                                           MED_EN::medEntityMesh  entity,
481                                           vector<MED_EN::medGeometryElement> & geoType,
482                                           vector<int> &nbOfElOfType) const
483 {
484   const char LOC[] = "MED_FIELD_DRIVER<T>::getMeshGeometricType(...)";
485
486   int numberOfGeometricType=0;
487   MED_EN::medGeometryElement geometricType[MED_NBR_GEOMETRIE_MAILLE];
488   int numberOfElementsOfType[MED_NBR_GEOMETRIE_MAILLE];
489   med_2_1::med_int   numberOfElements=0;
490   med_2_1::med_table quoi;
491   if (entity == MED_EN::MED_CELL) quoi=med_2_1::MED_CONN;
492   else
493     if (entity == MED_EN::MED_NODE) quoi=med_2_1::MED_COOR;
494     else
495       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Support Creation from Mesh |"  << meshName
496                                    << "| on entity " << MED_EN::entNames[entity]
497                                    << "| is impossible,  must be  on MED_NODE or MED_CELL" ));
498
499   list<MED_EN::medGeometryElement>::const_iterator currentGeometry;
500   bool alreadyFoundAnEntity = false;
501
502   for (currentGeometry  = (MED_EN::meshEntities[entity]).begin();
503        currentGeometry != (MED_EN::meshEntities[entity]).end(); currentGeometry++) {
504
505
506     if ( (numberOfElements =
507           med_2_1::MEDnEntMaa(id,
508                               const_cast<char*> (meshName.c_str()),
509                               quoi,
510                               (med_2_1::med_entite_maillage)   entity,
511                               (med_2_1::med_geometrie_element)  *currentGeometry,
512                               med_2_1::MED_NOD) ) <= 0)
513       continue;
514
515     alreadyFoundAnEntity = true;
516     numberOfElementsOfType[numberOfGeometricType] = numberOfElements;
517     geometricType[numberOfGeometricType] = *currentGeometry;
518     numberOfGeometricType++;
519
520   }
521   
522   geoType = vector<MED_EN::medGeometryElement>(geometricType,geometricType+numberOfGeometricType);
523   nbOfElOfType = vector<int> (numberOfElementsOfType,numberOfElementsOfType+numberOfGeometricType);
524
525 }
526
527 /*--------------------- RDONLY PART -------------------------------*/
528
529 template <class T> GENDRIVER * MED_FIELD_RDONLY_DRIVER21<T>::copy(void) const
530 {
531   return new MED_FIELD_RDONLY_DRIVER21<T>(*this);
532 }
533
534 template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
535   throw (MEDEXCEPTION)
536 {
537   const char * LOC = " MED_FIELD_RDONLY_DRIVER21::read() " ;
538   BEGIN_OF(LOC);
539
540   typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array   ArrayNo;
541   typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull;
542
543   if ( ( MED_FIELD_DRIVER<T>::_fieldName.empty()       ) &&
544        ( MED_FIELD_DRIVER<T>::_ptrField->_name.empty() )    )
545     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
546                                  <<" neither <fieldName> is set in driver nor in object FIELD.")) ;
547
548   // If _fieldName is not set in driver, try to use _ptrfield->_fieldName
549   if ( ( MED_FIELD_DRIVER<T>::_fieldName.empty()       ) &&
550        ( !MED_FIELD_DRIVER<T>::_ptrField->_name.empty() )    )
551     MED_FIELD_DRIVER<T>::_fieldName=MED_FIELD_DRIVER<T>::_ptrField->_name;
552
553   if ( MED_FIELD_DRIVER<T>::_fieldName.size() > MED_TAILLE_NOM )
554     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
555                                  <<" <fieldName> size in object driver FIELD is > MED_TAILLE_NOM ."));
556
557
558   MESSAGE("###### "<<LOC<<" fieldNameDRIVER : "<< MED_FIELD_DRIVER<T>::_fieldName << 
559           " fieldName : "<<MED_FIELD_DRIVER<T>::_fieldName);
560
561
562   if (MED_FIELD_DRIVER<T>::_status!=MED_OPENED)
563     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": Method open must be called before method read.")) ;
564
565 // EF :
566 //   Si un support a été donnée au champ, pour des raisons de compatibilité avec
567 //   les versions précédentes, ce support sera utilisé pour
568 //   - Obtenir le nom du maillage sur lequel on veut lire le champ
569 //     (eventuellement on pourrait l'utiliser pour selectionner un champ qui
570 //      repose sur plusieurs maillages cf HOMARD-ASTER)
571 //   -  vérifier le type d'entité (MED_NOEUD xor  MED_MAILLE xor MED_FACE xor MED_ARETE ) sur lequel
572 //      il faut lire le champ qui est également  retouvé.
573 //   - Si le support défini une liste d'entité ( différente de MED_ALL_ELEMENTS), celle-ci est ignorée
574 //     à la lecture et écrasé par les listes de profils lus s'il en existe
575
576 //   Si aucun support n'a été donné au champ :
577 //   - A la lecture : Un support est crée et le type d'entité unique est lu
578 //                    (cf decision gt MED qu'un champ repose sur une entité unique ?),
579 //                    l'ensemble des types géométriques est lu,
580 //                    l'ensemble des profils par type géométrique est lu
581 //                    Le nom du maillage associé est lu mais le pointeur SUPPORT-MESH non initialisé
582
583   char * fieldName = new char[MED_TAILLE_NOM+1] ;
584
585   int err ;
586   int    numberOfComponents          = 0;
587   char * componentName               = (char *) MED_NULL;
588   char * unitName                    = (char *) MED_NULL;
589   med_2_1::med_type_champ type ;
590   med_2_1::med_idt id = MED_FIELD_DRIVER21<T>::_medIdt;
591
592   // we search for the field med number of <fieldName>
593   // Having found <fieldName> variables <numberOfComponents>,
594   // <componentName>, <unitname>, <type> and attribute <_fieldNum> are set.
595   if (MED_FIELD_DRIVER<T>::_fieldNum==MED_INVALID)
596     {
597       int    numberOfFields              = 0;      //MED_INVALID
598       numberOfFields = med_2_1::MEDnChamp(id,0) ;
599       if ( numberOfFields <= 0 ) 
600         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": No Field found !"));
601
602       for (int i=1;i<=numberOfFields;i++)
603         {
604           numberOfComponents = med_2_1::MEDnChamp(id,i) ;
605           if ( numberOfComponents <= 0 ) 
606             //                throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
607             //                                                 <<  "Be careful there is no compound for field n°" 
608             //                                                 << i << "in file |"<<_fileName<<"| !"));
609             MESSAGE(LOC<<"Be careful there is no compound for field n°"<<i<<"in file |"<<MED_FIELD_DRIVER<T>::_fileName<<"| !");
610
611           componentName = new char[numberOfComponents*MED_TAILLE_PNOM21+1] ;
612           unitName      = new char[numberOfComponents*MED_TAILLE_PNOM21+1] ;   
613             
614           err = med_2_1::MEDchampInfo(id, i, fieldName, &type, componentName, 
615                                       unitName, numberOfComponents) ;
616
617           MESSAGE("Champ "<<i<<" : #" << fieldName <<"# et recherche #"<<MED_FIELD_DRIVER<T>::_fieldName.c_str()<<"#");
618           if ( !strcmp(fieldName,MED_FIELD_DRIVER<T>::_fieldName.c_str()) )
619             {
620               MESSAGE("FOUND FIELD "<< fieldName <<" : "<<i);
621               MED_FIELD_DRIVER<T>::_fieldNum = i ;
622               break ;
623             }
624           // not found : release memory and search next field !
625           delete[] componentName ;
626           delete[] unitName ;
627         }
628     }
629       
630   delete[] fieldName ;
631
632   if (MED_FIELD_DRIVER<T>::_fieldNum==MED_INVALID)
633     throw MEDEXCEPTION(LOCALIZED( STRING(LOC) << ": Field "<<MED_FIELD_DRIVER<T>::_fieldName << " not found in file " << MED_FIELD_DRIVER<T>::_fileName ) );
634
635   MESSAGE ("FieldNum : "<<MED_FIELD_DRIVER<T>::_fieldNum);
636
637   if (numberOfComponents < 1)
638     {
639       delete[] componentName; delete[] unitName;
640       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"no component found for field "
641                                    << MED_FIELD_DRIVER<T>::_fieldName)) ;
642     }
643
644   // Pourquoi _ptrField est toujour null et non MED_FIELD_DRIVER<T>::_ptrField
645   switch ( (med_2_1::med_type_champ) MED_FIELD_DRIVER<T>::_ptrField->_valueType ) {
646   case  med_2_1::MED_INT :
647   case  med_2_1::MED_INT32 :
648   case  med_2_1::MED_INT64 :
649     if ( type == ( med_2_1::MED_REEL64 ) ) {
650       delete[] componentName; delete[] unitName;
651       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field Type in file (" << type
652                                    <<") differs from FIELD object type (" <<
653                                    MED_FIELD_DRIVER<T>::_ptrField->_valueType << ")" )) ;
654     }
655     break;
656   default:
657     break;
658   }
659
660
661   string meshName="";
662   bool   haveSupport = false;
663   if ( MED_FIELD_DRIVER<T>::_ptrField->getSupport() ) {
664     // Verif sur la taille du meshName
665     meshName =  MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getMesh()->getName() ;
666     haveSupport = true;
667   }
668
669   // Cherche le type d'entité, le nombre d'entité  par type géométrique sur le type d'entité
670   // (MED_MAILLE ou MED_NOEUD uniquement car MEDMEMOIRE ne gère pas la connectivité descendante).
671   // et crée le support correspondant.
672   SUPPORT * mySupport = new SUPPORT();
673   bool found = createFieldSupport(id,MED_FIELD_DRIVER<T>::_fieldName,
674                                   MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber,
675                                   MED_FIELD_DRIVER<T>::_ptrField->_orderNumber,
676                                   *mySupport, meshName) ;
677   if ( !found ) {
678     delete mySupport; delete[] componentName; delete[] unitName;
679     MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ;
680      throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"  Can't find any entity for field |"
681                                  << MED_FIELD_DRIVER<T>::_fieldName
682                                  << "| with (it,or) = ("
683                                   << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
684                                  << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), on mesh "
685                                  << meshName << "|" ));
686   }
687
688   if (! haveSupport)
689     meshName = mySupport->getMeshName();
690   else {
691     if ( mySupport->getEntity() != MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getEntity() ) {
692       MED_EN::medEntityMesh ent = mySupport->getEntity();
693       delete mySupport; delete[] componentName; delete[] unitName;
694       MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ;
695       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"  Given entity |"
696                                    << MED_EN::entNames[MED_FIELD_DRIVER<T>::_ptrField->
697                                                        getSupport()->getEntity()]
698                                    << "| for field |"
699                                    << MED_FIELD_DRIVER<T>::_fieldName
700                                    << "| with (it,or) = ("
701                                    << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
702                                    << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), on mesh "
703                                    << meshName << "| differs from found entity |"
704                                    << MED_EN::entNames[ent] << "|."
705                                    ));
706     }
707     mySupport->setName( MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getName() );
708     mySupport->setMesh( MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getMesh() );
709     mySupport->setDescription(MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getDescription());
710   }
711
712   // Test si le Support du Champ repose ou non sur toutes les entités géométriques du maillage.
713   // Pour tester les profils aussi ?
714   vector< MED_EN::medGeometryElement >  meshGeoType;
715   vector< int >  meshNbOfElOfType;
716   getMeshGeometricType(id,meshName,mySupport->getEntity(),meshGeoType,meshNbOfElOfType);
717   vector < MED_EN::medGeometryElement > v1(  mySupport->getTypes(),
718                                              mySupport->getTypes()+mySupport->getNumberOfTypes() );
719   vector < int > v2(mySupport->getNumberOfElements(),
720                     mySupport->getNumberOfElements()+mySupport->getNumberOfTypes() );
721   if ( ( meshGeoType != v1 )  || meshNbOfElOfType != v2  ) {
722     mySupport->setAll(false);
723   }
724
725   //??support->setNumber(MEDSKYLINEARRAY * Number);
726   //??support->setNumber(const int * index, const int* value, bool shallowCopy=false);
727
728   // If an error occurs while reading the field, these allocated FIELD member will be deleted
729   MED_FIELD_DRIVER<T>::_ptrField->_name =  MED_FIELD_DRIVER<T>::_fieldName;
730   MED_FIELD_DRIVER<T>::_ptrField->_numberOfComponents = numberOfComponents ;
731   MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = new int[numberOfComponents] ;
732   MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = new string[numberOfComponents] ;
733   MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = new UNIT[numberOfComponents] ;
734   MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = new string[numberOfComponents] ;
735   MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = new string[numberOfComponents] ;
736
737   for (int i=0; i<numberOfComponents; i++)
738     {
739       MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes[i] = 1 ;
740       MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i] = string(componentName,i*MED_TAILLE_PNOM21,MED_TAILLE_PNOM21) ;
741       SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i]);
742       MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i] = string(unitName,i*MED_TAILLE_PNOM21,MED_TAILLE_PNOM21) ;
743       SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i]);
744     }
745
746   delete[] componentName;
747   delete[] unitName;
748
749   // read values for each geometric type in _support
750   int NumberOfTypes = mySupport->getNumberOfTypes() ;
751   const MED_EN::medGeometryElement *Types = mySupport->getTypes() ;
752   T ** myValues = new T*[NumberOfTypes] ;
753   int * NumberOfValues = new int[NumberOfTypes] ;
754   int TotalNumberOfValues = 0 ; // Profils a gerer en 2.2 Rmq from EF
755   MESSAGE ("NumberOfTypes :"<< NumberOfTypes);
756   MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues=0 ;
757
758   for (int i=0; i<NumberOfTypes; i++) {
759     MESSAGE ("Type["<<i+1<<"] :"<< Types[i]);
760     MESSAGE ("Entity :"<< mySupport->getEntity());
761
762 //     NumberOfValues[i] = 
763 //       MEDnVal(MED_FIELD_DRIVER21<T>::_medIdt,
764 //            const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
765 //            (med_2_1::med_entite_maillage)MED_FIELD_DRIVER<T>::_ptrField->_support->getEntity(),
766 //            (med_2_1::med_geometrie_element)Types[i],
767 //            MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber,
768 //            MED_FIELD_DRIVER<T>::_ptrField->_orderNumber) ;
769
770     NumberOfValues[i] = mySupport->getNumberOfElements(Types[i])
771       * MED_FIELD_DRIVER<T>::_ptrField->getNumberOfGaussPoints(Types[i]);
772
773     myValues[i] = new T[ NumberOfValues[i]*numberOfComponents ] ;
774     TotalNumberOfValues+=NumberOfValues[i] ;
775     char * ProfilName = new char[MED_TAILLE_NOM+1];
776     MESSAGE ("NumberOfValues :"<< NumberOfValues[i]);
777     MESSAGE ("NumberOfComponents :"<< numberOfComponents);
778     MESSAGE ("MESH_NAME :"<< meshName.c_str());
779     MESSAGE ("FIELD_NAME :"<< MED_FIELD_DRIVER<T>::_fieldName.c_str());
780     MESSAGE ("MED_ENTITE :"<< (med_2_1::med_entite_maillage) mySupport->getEntity());
781     MESSAGE("MED_GEOM :"<<(med_2_1::med_geometrie_element)Types[i]);
782     MESSAGE("Iteration :"<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber());
783     MESSAGE("Order :"<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber());
784     MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues+=mySupport->getNumberOfElements(Types[i]); // Ne doit pas prendre en compte les points de Gauss
785
786     med_2_1::med_err ret;
787 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000)
788     int lgth2=NumberOfValues[i]*numberOfComponents;
789     if(MED_FIELD_DRIVER<T>::_ptrField->getValueType()==MED_EN::MED_INT32)
790       {
791         med_2_1::med_int *temp=new med_2_1::med_int[lgth2];
792         ret=med_2_1::MEDchampLire(id,const_cast <char*> (meshName.c_str()),
793                                   const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
794                                   (unsigned char*) temp,
795                                   med_2_1::MED_NO_INTERLACE,
796                                   MED_ALL,
797                                   ProfilName,
798                                   (med_2_1::med_entite_maillage) mySupport->getEntity(),
799                                   (med_2_1::med_geometrie_element) Types[i],
800                                   MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
801                                   MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
802                                   );
803         for(int i2=0;i2<lgth2;i2++)
804           myValues[i][i2]=(int)(temp[i2]);
805         delete [] temp;
806       }
807     else
808 #endif
809       ret=med_2_1::MEDchampLire(id,const_cast <char*> (meshName.c_str()),
810                                 const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
811                                 (unsigned char*) myValues[i],
812                                 med_2_1::MED_NO_INTERLACE,
813                                 MED_ALL,
814                                 ProfilName,
815                                 (med_2_1::med_entite_maillage) mySupport->getEntity()
816                                 ,(med_2_1::med_geometrie_element)Types[i],
817                                 MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
818                                 MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
819                                 ); 
820     if (ret < 0)
821       {
822       // The Field can't be read then we mustdelete all previously allocated members in FIELD
823         for(int j=0; j<=i;j++)
824           delete[] myValues[j];
825         delete[] myValues;
826         delete[] NumberOfValues ;
827         delete[] ProfilName;
828         delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes ;
829         delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsNames ;
830         delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits ;
831         delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions ;
832         delete[] MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits ;
833         MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = NULL ;
834         MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = NULL ;
835         MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = NULL ;
836         MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = NULL ;
837         MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = NULL ;
838         MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ; // we have not found right field, so reset the field number 
839         throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": ERROR when read value")) ;
840       }
841
842     delete[] ProfilName ;
843   }
844   // allocate _value
845   // probleme avec les points de gauss : voir lorsqu-il y en a (!= 1)
846   // Creer un driver spécifique pour les modes MED_FULL_INTERLACE et MED_NO_INTERLACE
847   // serait plus efficicace.
848   ArrayNo * Values = new ArrayNo(numberOfComponents,TotalNumberOfValues);
849
850   for (int i=0; i<numberOfComponents; i++)
851     {
852       //T * ValuesT = Values->getRow(i+1) ;
853       int Count = 1 ;
854       for (int j=0; j<NumberOfTypes; j++)
855         {
856           T * myValue = myValues[j] ;
857           int NumberOf = NumberOfValues[j] ;
858           //      MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues+=NumberOf; // problem with gauss point : _numberOfValues != TotalNumberOfValues !!!!!!!
859           int offset = NumberOf*i ;
860           for (int k=0 ; k<NumberOf; k++) {
861             //ValuesT[Count]=myValue[k+offset] ;
862             Values->setIJ(Count,i+1,myValue[k+offset]);
863             //jfa 22.07.2005:SCRUTE(Count);
864             //jfa 22.07.2005:SCRUTE(Values->getIJ(Count,i+1));
865             Count++;
866           }
867         }
868     }
869       
870   for (int j=0; j<NumberOfTypes; j++)
871     delete[] myValues[j] ;
872   delete[] myValues ;
873   delete[] NumberOfValues ;
874
875   if (MED_FIELD_DRIVER<T>::_ptrField->_value != NULL)
876     delete MED_FIELD_DRIVER<T>::_ptrField->_value;
877
878   if ( MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE )
879     {
880       // dynamic_cast inutile
881       MED_FIELD_DRIVER<T>::_ptrField->_value=dynamic_cast<ArrayFull *>(ArrayConvert(*Values));
882       delete Values;
883     }
884   else
885     MED_FIELD_DRIVER<T>::_ptrField->_value=Values;
886   
887   MED_FIELD_DRIVER<T>::_ptrField->_isRead = true ;
888
889   MED_FIELD_DRIVER<T>::_ptrField->_support=mySupport; //Prévenir l'utilisateur ?
890       
891   END_OF(LOC);
892 }
893
894 template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::write( void ) const
895   throw (MEDEXCEPTION)
896 {
897   throw MEDEXCEPTION("MED_FIELD_RDONLY_DRIVER21::write : Can't write with a RDONLY driver !");
898 }
899
900 /*--------------------- WRONLY PART -------------------------------*/
901
902 template <class T> GENDRIVER * MED_FIELD_WRONLY_DRIVER21<T>::copy(void) const
903 {
904   return new MED_FIELD_WRONLY_DRIVER21<T>(*this);
905 }
906
907 template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::read (void)
908   throw (MEDEXCEPTION)
909 {
910   throw MEDEXCEPTION("MED_FIELD_WRONLY_DRIVER21::read : Can't read with a WRONLY driver !");
911 }
912
913 template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const
914   throw (MEDEXCEPTION)
915 {
916   const char * LOC = "MED_FIELD_WRONLY_DRIVER21::write(void) const " ;
917   BEGIN_OF(LOC);
918
919   typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo;
920   typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull;
921
922   if (MED_FIELD_DRIVER<T>::_status==MED_OPENED)
923     {
924       int err ;
925
926       int component_count=MED_FIELD_DRIVER<T>::_ptrField->getNumberOfComponents();
927       string   component_name(component_count*MED_TAILLE_PNOM21,' ') ;
928       string   component_unit(component_count*MED_TAILLE_PNOM21,' ') ;
929
930       const string * listcomponent_name=MED_FIELD_DRIVER<T>::_ptrField->getComponentsNames() ;
931       const string * listcomponent_unit=MED_FIELD_DRIVER<T>::_ptrField->getMEDComponentsUnits() ;
932       int length ;
933       for (int i=0; i < component_count ; i++) {
934         length = min(MED_TAILLE_PNOM21,(int)listcomponent_name[i].size());
935         component_name.replace(i*MED_TAILLE_PNOM21,length,
936                                listcomponent_name[i],0,length);
937         length = min(MED_TAILLE_PNOM21,(int)listcomponent_unit[i].size());
938         component_unit.replace(i*MED_TAILLE_PNOM21,length,
939                                listcomponent_unit[i],0,length);
940       }
941
942       MESSAGE("component_name=|"<<component_name<<"|");
943       MESSAGE("component_unit=|"<<component_unit<<"|");
944
945       MED_EN::med_type_champ ValueType=MED_FIELD_DRIVER<T>::_ptrField->getValueType() ;
946       
947       MESSAGE("Template Type =|"<<ValueType<<"|");
948       
949       // le champ existe deja ???
950       char * champName = new char[MED_TAILLE_NOM+1] ;
951       med_2_1::med_type_champ type ;
952       char * compName ;
953       char * compUnit ;
954       bool Find = false ;
955       int n = med_2_1::MEDnChamp(MED_FIELD_DRIVER21<T>::_medIdt,0);
956       int nbComp ;
957       for (int i=1; i<=n; i++) {
958         nbComp = med_2_1::MEDnChamp(MED_FIELD_DRIVER21<T>::_medIdt,i);
959         compName = new char[MED_TAILLE_PNOM21*nbComp+1];
960         compUnit = new char[MED_TAILLE_PNOM21*nbComp+1];
961         err = med_2_1::MEDchampInfo(MED_FIELD_DRIVER21<T>::_medIdt,i,champName,&type,compName,compUnit,nbComp);
962         if (err == 0)
963           if (strcmp(champName,MED_FIELD_DRIVER<T>::_ptrField->getName().c_str())==0) { // Found !
964             Find = true ;
965             break ;
966           }
967         delete[] compName ;
968         delete[] compUnit ;
969       }
970       delete[] champName ;
971       if (Find) {
972         // the same ?
973         if (nbComp != component_count)
974           throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
975                                          <<": Field exist in file, but number of component are different : "<<nbComp<<" in file and "<<component_count<<" in memory."
976                                          )
977                               );
978         // component name and unit
979         MESSAGE(LOC<<" Component name in file : "<<compName);
980         MESSAGE(LOC<<" Component name in memory : "<<component_name);
981         MESSAGE(LOC<<" Component unit in file : "<<compUnit);
982         MESSAGE(LOC<<" Component unit in memory : "<<component_unit);
983         delete[] compName ;
984         delete[] compUnit ;
985
986       } else {
987         // Verify the field doesn't exist
988
989         string dataGroupName =  "/CHA/";
990         dataGroupName        += MED_FIELD_DRIVER<T>::_ptrField->getName();
991         MESSAGE(LOC << "|" << dataGroupName << "|" );
992         med_2_1::med_idt gid =  H5Gopen(MED_FIELD_DRIVER21<T>::_medIdt, dataGroupName.c_str() );
993         
994         if ( gid < 0 ) {
995           // create field :
996           err=med_2_1::MEDchampCr(MED_FIELD_DRIVER21<T>::_medIdt, 
997                                  const_cast <char*> ((MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()),
998                                  (med_2_1::med_type_champ) ValueType,
999                                  const_cast <char*> ( component_name.c_str() ),
1000                                  const_cast <char*> ( component_unit.c_str() ),
1001                                  component_count);
1002           if ( err < 0 )
1003             throw MEDEXCEPTION( LOCALIZED (STRING(LOC) 
1004                                            << ": Error MEDchampCr : "<<err
1005                                            )
1006                                 );
1007         }
1008         else H5Gclose(gid);
1009       }
1010
1011       const SUPPORT * mySupport = MED_FIELD_DRIVER<T>::_ptrField->getSupport() ;
1012
1013       if (! mySupport->isOnAllElements())
1014         throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
1015                                        <<": Field must be on all entity"
1016                                        )
1017                             );
1018       
1019       MESH * myMesh = mySupport->getMesh() ;
1020       string MeshName = myMesh->getName() ;
1021       //MED_EN::medModeSwitch Mode = MED_FIELD_DRIVER<T>::_ptrField->_value->getMode() ;
1022       // on boucle sur tout les types pour ecrire les tableaux de valeur
1023       int NumberOfType = mySupport->getNumberOfTypes() ;
1024       int Index = 1 ;
1025       const MED_EN::medGeometryElement * Types = mySupport->getTypes() ;
1026
1027       const T * value     = NULL;
1028       ArrayFull * myArray = NULL;
1029       if ( MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE )
1030         myArray = MED_FIELD_DRIVER<T>::_ptrField->getArrayNoGauss();
1031       else {
1032         // En attendant la convertion de FIELD, on utilise le ArrayConvert
1033         // ( les infos _ptrField-> sont les mêmes )
1034         myArray = ArrayConvert( *( dynamic_cast< ArrayNo * >
1035                                    (MED_FIELD_DRIVER<T>::_ptrField->getArrayNoGauss()
1036                                     ))
1037                                 );
1038       }
1039
1040       for (int i=0;i<NumberOfType;i++) {
1041         int NumberOfElements = mySupport->getNumberOfElements(Types[i]) ;
1042         int NumberOfGaussPoints = MED_FIELD_DRIVER<T>::_ptrField->getNumberOfGaussPoints(Types[i]) ;
1043
1044 //      const T * value = MED_FIELD_DRIVER<T>::_ptrField->getValueI(MED_EN::MED_FULL_INTERLACE,Index) ;
1045
1046         value = myArray->getRow(Index) ;
1047         
1048         MESSAGE("MED_FIELD_DRIVER21<T>::_medIdt                         : "<<MED_FIELD_DRIVER21<T>::_medIdt);
1049         MESSAGE("MeshName.c_str()                : "<<MeshName.c_str());
1050         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getName()            : "<<MED_FIELD_DRIVER<T>::_ptrField->getName());
1051         MESSAGE("value                           : "<<value);
1052         MESSAGE("NumberOfElements                : "<<NumberOfElements);
1053         MESSAGE("NumberOfGaussPoints             : "<<NumberOfGaussPoints);
1054         MESSAGE("mySupport->getEntity()          : "<<mySupport->getEntity());
1055         MESSAGE("Types[i]                        : "<<Types[i]);
1056         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber());
1057         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getTime()            : "<<MED_FIELD_DRIVER<T>::_ptrField->getTime());
1058         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()     : "<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber());
1059         
1060 /*      char chanom[MED_TAILLE_NOM+1];
1061         char chacomp[MED_TAILLE_NOM+1];
1062         char chaunit[MED_TAILLE_NOM+1];
1063         med_2_1::med_type_champ chatype;
1064         med_int chancomp=1;
1065         
1066         err=med_2_1::MEDchampInfo(MED_FIELD_DRIVER<T>::_medIdt,1,chanom,&chatype,chacomp,chaunit,chancomp);
1067
1068         if (err<0) 
1069                 {
1070                 cout<<"=======================================================================> gros probleme"<<endl;
1071                 exit(-1);
1072                 }
1073         cout<<"==================> nom lu            = "<<chanom<<endl;
1074         cout<<"==================> type lu           = "<<chatype<<endl;
1075         cout<<"==================> nom composante lu = "<<chacomp<<endl;
1076         cout<<"==================> nom unit lu       = "<<chaunit<<endl;
1077         cout<<"==================> valeur de med_2_1::MED_REEL64 = "<<med_2_1::MED_REEL64<<endl;
1078 */      
1079 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000)
1080         if(_ptrField->getValueType()==MED_EN::MED_INT32)
1081           {
1082             int lgth2=_ptrField->getNumberOfValues();
1083             med_2_1::med_int *temp=new med_2_1::med_int[lgth2];
1084             for(int i2=0;i2<lgth2;i2++)
1085               temp[i2]=(int)(value[i2]);
1086             err=med_2_1::MEDchampEcr(MED_FIELD_DRIVER21<T>::_medIdt, 
1087                                     const_cast <char*> ( MeshName.c_str()) ,                         //( string(mesh_name).resize(MED_TAILLE_NOM).c_str())
1088                                     const_cast <char*> ( (MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()),
1089                                     (unsigned char*)temp, 
1090                                     med_2_1::MED_FULL_INTERLACE,
1091                                     NumberOfElements,
1092                                     NumberOfGaussPoints,
1093                                     MED_ALL,
1094                                     MED_NOPFL,
1095                                     med_2_1::MED_REMP,  // PROFIL NON GERE, mode de remplacement non géré
1096                                     (med_2_1::med_entite_maillage)mySupport->getEntity(),
1097                                     (med_2_1::med_geometrie_element)Types[i],
1098                                     MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
1099                                     "        ",
1100                                     MED_FIELD_DRIVER<T>::_ptrField->getTime(),
1101                                     MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
1102                                     );
1103             delete [] temp;
1104           }
1105         else
1106 #endif
1107         err=med_2_1::MEDchampEcr(MED_FIELD_DRIVER21<T>::_medIdt, 
1108                                 const_cast <char*> ( MeshName.c_str()) ,                         //( string(mesh_name).resize(MED_TAILLE_NOM).c_str())
1109                                 const_cast <char*> ( (MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()),
1110                                 (unsigned char*)value, 
1111                                 med_2_1::MED_FULL_INTERLACE,
1112                                 NumberOfElements,
1113                                 NumberOfGaussPoints,
1114                                 MED_ALL,
1115                                 MED_NOPFL,
1116                                 med_2_1::MED_REMP,  // PROFIL NON GERE, mode de remplacement non géré
1117                                 (med_2_1::med_entite_maillage)mySupport->getEntity(),
1118                                 (med_2_1::med_geometrie_element)Types[i],
1119                                 MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
1120                                 "        ",
1121                                 MED_FIELD_DRIVER<T>::_ptrField->getTime(),
1122                                 MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
1123                                 );
1124         if (err < MED_VALID )
1125           {
1126             if ( MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE ) delete myArray;
1127
1128             throw MEDEXCEPTION(LOCALIZED( STRING(LOC)
1129                                           <<": Error in writing Field "<< MED_FIELD_DRIVER<T>::_ptrField->getName() <<", type "<<Types[i]
1130                                           )
1131                                );
1132           }
1133
1134         Index += NumberOfElements ;
1135         
1136       }
1137       if ( MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE ) delete myArray;
1138
1139     }
1140   
1141   END_OF(LOC);
1142 }
1143
1144 /*--------------------- RDWR PART -------------------------------*/
1145
1146 template <class T> GENDRIVER * MED_FIELD_RDWR_DRIVER21<T>::copy(void) const
1147 {
1148   return new MED_FIELD_RDWR_DRIVER21<T>(*this);
1149 }
1150
1151 template <class T> void MED_FIELD_RDWR_DRIVER21<T>::write(void) const
1152   throw (MEDEXCEPTION)
1153 {
1154   BEGIN_OF("MED_FIELD_RDWR_DRIVER21::write(void)");
1155   MED_FIELD_WRONLY_DRIVER21<T>::write(); 
1156   END_OF("MED_FIELD_RDWR_DRIVER21::write(void)");
1157
1158
1159 template <class T> void MED_FIELD_RDWR_DRIVER21<T>::read (void)
1160   throw (MEDEXCEPTION)
1161 {
1162   BEGIN_OF("MED_FIELD_RDWR_DRIVER21::read(void)");
1163   MED_FIELD_RDONLY_DRIVER21<T>::read();
1164   END_OF("MED_FIELD_RDWR_DRIVER21::read(void)");
1165 }
1166 }//End namespace MEDMEM
1167 /*-----------------------------------------------------------------*/
1168
1169 #endif /* MED_FIELD_DRIVER_HXX */
1170