]> SALOME platform Git repositories - modules/med.git/blob - src/MEDMEM/MEDMEM_MedFieldDriver21.hxx
Salome HOME
8912451da57d81665602c6045a20aa31387ce313
[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   BEGIN_OF(LOC);
350
351   map<int, list<MED_EN::medGeometryElement> > CellAndNodeEntities;
352   map<int, list<MED_EN::medGeometryElement> >::iterator currentEntity;
353   CellAndNodeEntities[MED_EN::MED_CELL]  = MED_EN::meshEntities[MED_EN::MED_CELL];
354   CellAndNodeEntities[MED_EN::MED_NODE] = MED_EN::meshEntities[MED_EN::MED_NODE];
355   list< MED_EN::medGeometryElement >::const_iterator currentGeometry;
356
357   MED_EN::medEntityMesh entityCurrent;
358   MED_EN::medGeometryElement geometryCurrent;
359
360   //med_2_1::med_entite_maillage
361   MED_EN::medEntityMesh entity;
362   bool alreadyFoundAnEntity=false, alreadyFoundPdtIt = false, anyGauss=false;
363   int  numberOfElements = 0, numberOfElements1 = 0,numberOfElements2 = 0;
364   int  numberOfGeometricType = 0;
365   //med_2_1::med_geometrie_element..
366   MED_EN::medGeometryElement geometricType[MED_NBR_GEOMETRIE_MAILLE];
367   int numberOfElementsOfType[MED_NBR_GEOMETRIE_MAILLE];
368   int numberOfGaussPoints[MED_NBR_GEOMETRIE_MAILLE];
369
370   med_2_1::med_int ngauss=0, numdt=-1, numo=-1, nbPdtIt=0; //nmaa=0
371   char dtunit[MED_TAILLE_PNOM21+1], maa[MED_TAILLE_NOM+1];
372   med_2_1::med_float   dt=-1.0;
373   //med_2_1::med_booleen local;
374   med_2_1::med_err     ret=1;
375
376   for (currentEntity = CellAndNodeEntities.begin();
377        currentEntity != CellAndNodeEntities.end(); currentEntity++) {
378     for (currentGeometry  = (*currentEntity).second.begin();
379          currentGeometry != (*currentEntity).second.end(); currentGeometry++) {
380
381       entityCurrent = (*currentEntity).first ;
382       geometryCurrent = (*currentGeometry) ;
383
384       // That is a difference between Med File and Med Memory (NB)
385
386       if (geometryCurrent == MED_EN::MED_SEG2 || geometryCurrent == MED_EN::MED_SEG3)
387         entityCurrent = MED_EN::MED_EDGE;
388
389       if (geometryCurrent == MED_EN::MED_TRIA3 || geometryCurrent == MED_EN::MED_QUAD4 ||
390           geometryCurrent == MED_EN::MED_TRIA6 || geometryCurrent == MED_EN::MED_QUAD8)
391         entityCurrent = MED_EN::MED_FACE;
392
393       numberOfElements1 =  med_2_1::MEDnVal(id, const_cast <char*> ( fieldName.c_str() ),
394                                             (med_2_1::med_entite_maillage)   (*currentEntity).first,
395                                             (med_2_1::med_geometrie_element) *currentGeometry,
396                                             ndt, od);
397
398       numberOfElements2 =  med_2_1::MEDnVal(id, const_cast <char*> ( fieldName.c_str() ),
399                                             (med_2_1::med_entite_maillage) entityCurrent,
400                                             (med_2_1::med_geometrie_element) *currentGeometry,
401                                             ndt, od);
402       if (numberOfElements2 < numberOfElements1) entityCurrent = (*currentEntity).first ;
403
404       numberOfElements = (numberOfElements1>numberOfElements2)?numberOfElements1:numberOfElements2;
405
406       SCRUTE(numberOfElements);
407
408       if ( numberOfElements <=  0 )
409         continue;
410
411       if ( alreadyFoundAnEntity ) {
412         if (entity != entityCurrent)
413           throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |"  << fieldName
414                                        << "| with (ndt,or) = (" << ndt << ","
415                                        << od << ") must not be defined on nodes and cells" ));
416
417       } else { entity=entityCurrent; alreadyFoundAnEntity = true; };
418
419       nbPdtIt = med_2_1::MEDnPasdetemps(id, const_cast <char*> ( fieldName.c_str() ),
420                                         (med_2_1::med_entite_maillage) entityCurrent,
421                                         (med_2_1::med_geometrie_element)  *currentGeometry );
422
423       SCRUTE(nbPdtIt);
424       SCRUTE(numberOfElements);
425
426       if ( nbPdtIt < 0 )
427         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = ("
428                                      << ndt << "," << od << ") should be defined for (entityType,geometricType)=("
429                                      << MED_EN::entNames[entityCurrent] << ","
430                                      << MED_EN::geoNames[*currentGeometry] << ")" ));
431
432       ret = 0; alreadyFoundPdtIt = false; ngauss =0;
433       for ( med_2_1::med_int j=1; j <= nbPdtIt; j++ ) {
434
435         // Search how many <ngauss> (<fieldName>,<ndt>,<ot>) has
436         ret = med_2_1::MEDpasdetempsInfo(id, const_cast <char*> ( fieldName.c_str() ),
437                                          (med_2_1::med_entite_maillage) entityCurrent,
438                                          (med_2_1::med_geometrie_element)  *currentGeometry,
439                                          j,maa,&ngauss,&numdt,dtunit,&dt,&numo);
440
441         //          ret = med_2_2::MEDpasdetempsInfo(id, const_cast <char*> ( fieldName.c_str() ),
442         //                                  (med_2_1::med_entite_maillage)   (*currentEntity).first,
443         //                                  (med_2_1::med_geometrie_element)  *currentGeometry,
444         //                                  j, &ngauss,  &numdt,  &numo, &dtunit, &dt, &maa, &local, &nmaa)
445
446         if ( ndt == numdt && numo == od ) {
447           alreadyFoundPdtIt = true;
448           if ( ! meshName.empty() )
449             if ( meshName != maa ) {
450
451               //                  if ( nmaa > 1 )
452               {
453                 //EF : Gérer le meshName pour le driver 2.2
454                 //                    MESSAGE(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = (" << ndt << ","
455                 //                            << ot << ") is  defined on " << nmaa << " meshes, using mesh |"
456                 //                            << maa << "|");
457                 //                  }
458                 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = ("
459                                              << ndt << "," << od << ") for (entityType,geometricType)=("
460                                              << MED_EN::entNames[entityCurrent] << ","
461                                              << MED_EN::geoNames[*currentGeometry] << ")"
462                                              << "is defined on mesh |" << maa << "| not on mesh |" << meshName ));
463               }
464             }
465           break;
466         }
467       }
468
469       MESSAGE(LOC << " a (dt,it) is found ?? " << alreadyFoundPdtIt);
470
471       if ( !alreadyFoundPdtIt )
472         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = ("
473                                      << ndt << "," << od << ") should be defined for (entityType,geometricType)=("
474                                      << MED_EN::entNames[entityCurrent] << ","
475                                      << MED_EN::geoNames[*currentGeometry] << ")" ));
476
477       if ( (ret != 0)  || (ngauss < 1 ) )
478         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Error in MEDpasdetempsInfo for  Field |" << fieldName 
479                                      << "| with (ndt,or) = ("
480                                      << ndt << "," << od << ") for (entityType,geometricType)=("
481                                      << MED_EN::entNames[entityCurrent] << ","
482                                      << MED_EN::geoNames[*currentGeometry] << ")" )); ;
483
484       //totalNumberOfElements+=numberOfElements;
485       numberOfElementsOfType[numberOfGeometricType] = numberOfElements/ngauss;
486       numberOfGaussPoints[numberOfGeometricType] = ngauss;
487       anyGauss = (anyGauss || (ngauss-1) );
488       geometricType[numberOfGeometricType]= *currentGeometry;
489       numberOfGeometricType++;
490
491     } // End Second For
492
493   } // End Premier For
494
495   if ( alreadyFoundAnEntity) {
496     support.setName(fieldName+"Support");
497     support.setMeshName(string(maa)); // Vérifier que les différents noms de maillages lus soient identiques
498     support.setEntity(entity);
499     // REM : Signification précédente erronée pour un champ qui ne repose pas sur toutes les entités géométriques 
500     // du maillage mais dont le SUPPORT a été crée à partir des informations d'un maillage, comme
501     // celà fût la plupart du temps.
502     support.setNumberOfGeometricType(numberOfGeometricType);
503     support.setGeometricType(geometricType); // Utile uniquement si setAll == false
504     support.setNumberOfElements(numberOfElementsOfType);    //setNumberOfElements effectue une copie
505     support.setAll(true);
506
507     END_OF(LOC);
508
509     return alreadyFoundAnEntity;
510   } else
511     {
512       END_OF(LOC);
513
514       return false;
515     }
516 }
517
518 template <class T> void
519 MED_FIELD_DRIVER21<T>::getMeshGeometricType(med_2_1::med_idt id,
520                                           string & meshName,
521                                           MED_EN::medEntityMesh  entity,
522                                           vector<MED_EN::medGeometryElement> & geoType,
523                                           vector<int> &nbOfElOfType) const
524 {
525   const char LOC[] = "MED_FIELD_DRIVER<T>::getMeshGeometricType(...)";
526
527   int numberOfGeometricType=0;
528   MED_EN::medGeometryElement geometricType[MED_NBR_GEOMETRIE_MAILLE];
529   int numberOfElementsOfType[MED_NBR_GEOMETRIE_MAILLE];
530   med_2_1::med_int   numberOfElements=0;
531   med_2_1::med_table quoi;
532   if (entity == MED_EN::MED_CELL) quoi=med_2_1::MED_CONN;
533   else
534     if (entity == MED_EN::MED_NODE) quoi=med_2_1::MED_COOR;
535     else
536       MESSAGE(LOC<<" Support Creation from Mesh |"  << meshName
537                                    << "| on entity " << MED_EN::entNames[entity]
538                                    << "| is impossible,  must be  on MED_NODE or MED_CELL");
539
540 //       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Support Creation from Mesh |"  << meshName
541 //                                 << "| on entity " << MED_EN::entNames[entity]
542 //                                 << "| is impossible,  must be  on MED_NODE or MED_CELL" ));
543
544   list<MED_EN::medGeometryElement>::const_iterator currentGeometry;
545   bool alreadyFoundAnEntity = false;
546
547   for (currentGeometry  = (MED_EN::meshEntities[entity]).begin();
548        currentGeometry != (MED_EN::meshEntities[entity]).end(); currentGeometry++) {
549
550
551     if ( (numberOfElements =
552           med_2_1::MEDnEntMaa(id,
553                               const_cast<char*> (meshName.c_str()),
554                               quoi,
555                               (med_2_1::med_entite_maillage)   entity,
556                               (med_2_1::med_geometrie_element)  *currentGeometry,
557                               med_2_1::MED_NOD) ) <= 0)
558       continue;
559
560     alreadyFoundAnEntity = true;
561     numberOfElementsOfType[numberOfGeometricType] = numberOfElements;
562     geometricType[numberOfGeometricType] = *currentGeometry;
563     numberOfGeometricType++;
564
565   }
566   
567   geoType = vector<MED_EN::medGeometryElement>(geometricType,geometricType+numberOfGeometricType);
568   nbOfElOfType = vector<int> (numberOfElementsOfType,numberOfElementsOfType+numberOfGeometricType);
569
570 }
571
572 /*--------------------- RDONLY PART -------------------------------*/
573
574 template <class T> GENDRIVER * MED_FIELD_RDONLY_DRIVER21<T>::copy(void) const
575 {
576   return new MED_FIELD_RDONLY_DRIVER21<T>(*this);
577 }
578
579 template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::read(void)
580   throw (MEDEXCEPTION)
581 {
582   const char * LOC = " MED_FIELD_RDONLY_DRIVER21::read() " ;
583   BEGIN_OF(LOC);
584
585   typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array   ArrayNo;
586   typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull;
587
588   if ( ( MED_FIELD_DRIVER<T>::_fieldName.empty()       ) &&
589        ( MED_FIELD_DRIVER<T>::_ptrField->_name.empty() )    )
590     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
591                                  <<" neither <fieldName> is set in driver nor in object FIELD.")) ;
592
593   // If _fieldName is not set in driver, try to use _ptrfield->_fieldName
594   if ( ( MED_FIELD_DRIVER<T>::_fieldName.empty()       ) &&
595        ( !MED_FIELD_DRIVER<T>::_ptrField->_name.empty() )    )
596     MED_FIELD_DRIVER<T>::_fieldName=MED_FIELD_DRIVER<T>::_ptrField->_name;
597
598   if ( MED_FIELD_DRIVER<T>::_fieldName.size() > MED_TAILLE_NOM )
599     MESSAGE(LOC << "Warning <fieldName> size in object driver FIELD is > MED_TAILLE_NOM .");
600    
601 //     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
602 //                               <<" <fieldName> size in object driver FIELD is > MED_TAILLE_NOM ."));
603
604
605   MESSAGE("###### "<<LOC<<" fieldNameDRIVER : "<< MED_FIELD_DRIVER<T>::_fieldName << 
606           " fieldName : "<<MED_FIELD_DRIVER<T>::_fieldName);
607
608
609   if (MED_FIELD_DRIVER<T>::_status!=MED_OPENED)
610     throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": Method open must be called before method read.")) ;
611
612 // EF :
613 //   Si un support a été donnée au champ, pour des raisons de compatibilité avec
614 //   les versions précédentes, ce support sera utilisé pour
615 //   - Obtenir le nom du maillage sur lequel on veut lire le champ
616 //     (eventuellement on pourrait l'utiliser pour selectionner un champ qui
617 //      repose sur plusieurs maillages cf HOMARD-ASTER)
618 //   -  vérifier le type d'entité (MED_NOEUD xor  MED_MAILLE xor MED_FACE xor MED_ARETE ) sur lequel
619 //      il faut lire le champ qui est également  retouvé.
620 //   - Si le support défini une liste d'entité ( différente de MED_ALL_ELEMENTS), celle-ci est ignorée
621 //     à la lecture et écrasé par les listes de profils lus s'il en existe
622
623 //   Si aucun support n'a été donné au champ :
624 //   - A la lecture : Un support est crée et le type d'entité unique est lu
625 //                    (cf decision gt MED qu'un champ repose sur une entité unique ?),
626 //                    l'ensemble des types géométriques est lu,
627 //                    l'ensemble des profils par type géométrique est lu
628 //                    Le nom du maillage associé est lu mais le pointeur SUPPORT-MESH non initialisé
629
630   char fieldName[MED_TAILLE_NOM+1] ;
631
632   int err ;
633   int    numberOfComponents          = 0;
634   char * componentName               = (char *) MED_NULL;
635   char * unitName                    = (char *) MED_NULL;
636   med_2_1::med_type_champ type ;
637   med_2_1::med_idt id = MED_FIELD_DRIVER21<T>::_medIdt;
638
639   // we search for the field med number of <fieldName>
640   // Having found <fieldName> variables <numberOfComponents>,
641   // <componentName>, <unitname>, <type> and attribute <_fieldNum> are set.
642   if (MED_FIELD_DRIVER<T>::_fieldNum==MED_INVALID)
643     {
644       int    numberOfFields              = 0;      //MED_INVALID
645       numberOfFields = med_2_1::MEDnChamp(id,0) ;
646       if ( numberOfFields <= 0 ) 
647         throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": No Field found !"));
648
649       for (int i=1;i<=numberOfFields;i++)
650         {
651           numberOfComponents = med_2_1::MEDnChamp(id,i) ;
652           if ( numberOfComponents <= 0 ) 
653             //                throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) 
654             //                                                 <<  "Be careful there is no compound for field n°" 
655             //                                                 << i << "in file |"<<_fileName<<"| !"));
656             MESSAGE(LOC<<"Be careful there is no compound for field n°"<<i<<"in file |"<<MED_FIELD_DRIVER<T>::_fileName<<"| !");
657
658           componentName = new char[numberOfComponents*MED_TAILLE_PNOM21+1] ;
659           unitName      = new char[numberOfComponents*MED_TAILLE_PNOM21+1] ;   
660             
661           err = med_2_1::MEDchampInfo(id, i, fieldName, &type, componentName, 
662                                       unitName, numberOfComponents) ;
663
664           MESSAGE("Champ "<<i<<" : #" << fieldName <<"# et recherche #"<<MED_FIELD_DRIVER<T>::_fieldName.c_str()<<"#");
665           if ( !strcmp(fieldName,MED_FIELD_DRIVER<T>::_fieldName.c_str()) )
666             {
667               MESSAGE("FOUND FIELD "<< fieldName <<" : "<<i);
668               MED_FIELD_DRIVER<T>::_fieldNum = i ;
669               break ;
670             }
671           // not found : release memory and search next field !
672           delete[] componentName ;
673           delete[] unitName ;
674         }
675     }
676       
677   //delete[] fieldName ;
678
679   if (MED_FIELD_DRIVER<T>::_fieldNum==MED_INVALID)
680     throw MEDEXCEPTION(LOCALIZED( STRING(LOC) << ": Field "<<MED_FIELD_DRIVER<T>::_fieldName << " not found in file " << MED_FIELD_DRIVER<T>::_fileName ) );
681
682   MESSAGE ("FieldNum : "<<MED_FIELD_DRIVER<T>::_fieldNum);
683
684   if (numberOfComponents < 1)
685     {
686       delete[] componentName; delete[] unitName;
687       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"no component found for field "
688                                    << MED_FIELD_DRIVER<T>::_fieldName)) ;
689     }
690
691   // Pourquoi _ptrField est toujour null et non MED_FIELD_DRIVER<T>::_ptrField
692   switch ( (med_2_1::med_type_champ) MED_FIELD_DRIVER<T>::_ptrField->_valueType ) {
693   case  med_2_1::MED_INT :
694   case  med_2_1::MED_INT32 :
695   case  med_2_1::MED_INT64 :
696     if ( type == ( med_2_1::MED_REEL64 ) ) {
697       delete[] componentName; delete[] unitName;
698       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field Type in file (" << type
699                                    <<") differs from FIELD object type (" <<
700                                    MED_FIELD_DRIVER<T>::_ptrField->_valueType << ")" )) ;
701     }
702     break;
703   default:
704     break;
705   }
706
707
708   string meshName="";
709   bool   haveSupport = false;
710   if ( MED_FIELD_DRIVER<T>::_ptrField->getSupport() ) {
711     // Verif sur la taille du meshName
712     meshName =  MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getMesh()->getName() ;
713     haveSupport = true;
714   }
715
716   // Cherche le type d'entité, le nombre d'entité  par type géométrique sur le type d'entité
717   // (MED_MAILLE ou MED_NOEUD uniquement car MEDMEMOIRE ne gère pas la connectivité descendante).
718   // et crée le support correspondant.
719   SUPPORT * mySupport = new SUPPORT();
720   bool found = createFieldSupport(id,MED_FIELD_DRIVER<T>::_fieldName,
721                                   MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber,
722                                   MED_FIELD_DRIVER<T>::_ptrField->_orderNumber,
723                                   *mySupport, meshName) ;
724   if ( !found ) {
725     delete mySupport; delete[] componentName; delete[] unitName;
726     MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ;
727      throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"  Can't find any entity for field |"
728                                  << MED_FIELD_DRIVER<T>::_fieldName
729                                  << "| with (it,or) = ("
730                                   << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
731                                  << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), on mesh "
732                                  << meshName << "|" ));
733   }
734
735   if (! haveSupport)
736     meshName = mySupport->getMeshName();
737   else {
738     if ( mySupport->getEntity() != MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getEntity() ) {
739       MED_EN::medEntityMesh ent = mySupport->getEntity();
740       delete mySupport; delete[] componentName; delete[] unitName;
741       MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ;
742       throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"  Given entity |"
743                                    << MED_EN::entNames[MED_FIELD_DRIVER<T>::_ptrField->
744                                                        getSupport()->getEntity()]
745                                    << "| for field |"
746                                    << MED_FIELD_DRIVER<T>::_fieldName
747                                    << "| with (it,or) = ("
748                                    << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
749                                    << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), on mesh "
750                                    << meshName << "| differs from found entity |"
751                                    << MED_EN::entNames[ent] << "|."
752                                    ));
753     }
754     mySupport->setName( MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getName() );
755     mySupport->setMesh( MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getMesh() );
756     mySupport->setDescription(MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getDescription());
757   }
758
759   // Test si le Support du Champ repose ou non sur toutes les entités géométriques du maillage.
760   // Pour tester les profils aussi ?
761   vector< MED_EN::medGeometryElement >  meshGeoType;
762   vector< int >  meshNbOfElOfType;
763   getMeshGeometricType(id,meshName,mySupport->getEntity(),meshGeoType,meshNbOfElOfType);
764   vector < MED_EN::medGeometryElement > v1(  mySupport->getTypes(),
765                                              mySupport->getTypes()+mySupport->getNumberOfTypes() );
766   vector < int > v2(mySupport->getNumberOfElements(),
767                     mySupport->getNumberOfElements()+mySupport->getNumberOfTypes() );
768   if ( ( meshGeoType != v1 )  || meshNbOfElOfType != v2  ) {
769     mySupport->setAll(false);
770   }
771
772   //??support->setNumber(MEDSKYLINEARRAY * Number);
773   //??support->setNumber(const int * index, const int* value, bool shallowCopy=false);
774
775   // If an error occurs while reading the field, these allocated FIELD member will be deleted
776   MED_FIELD_DRIVER<T>::_ptrField->_name =  MED_FIELD_DRIVER<T>::_fieldName;
777   MED_FIELD_DRIVER<T>::_ptrField->_numberOfComponents = numberOfComponents ;
778   MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = new int[numberOfComponents] ;
779   MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = new string[numberOfComponents] ;
780   MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = new UNIT[numberOfComponents] ;
781   MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = new string[numberOfComponents] ;
782   MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = new string[numberOfComponents] ;
783
784   for (int i=0; i<numberOfComponents; i++)
785     {
786       MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes[i] = 1 ;
787       MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i] = string(componentName,i*MED_TAILLE_PNOM21,MED_TAILLE_PNOM21) ;
788       SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i]);
789       MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i] = string(unitName,i*MED_TAILLE_PNOM21,MED_TAILLE_PNOM21) ;
790       SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i]);
791     }
792
793   delete[] componentName;
794   delete[] unitName;
795
796   // read values for each geometric type in _support
797   int NumberOfTypes = mySupport->getNumberOfTypes() ;
798   const MED_EN::medGeometryElement *Types = mySupport->getTypes() ;
799   T ** myValues = new T*[NumberOfTypes] ;
800   int * NumberOfValues = new int[NumberOfTypes] ;
801   int TotalNumberOfValues = 0 ; // Profils a gerer en 2.2 Rmq from EF
802   MESSAGE ("NumberOfTypes :"<< NumberOfTypes);
803   MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues=0 ;
804
805   for (int i=0; i<NumberOfTypes; i++) {
806     MESSAGE ("Type["<<i+1<<"] :"<< Types[i]);
807     MESSAGE ("Entity :"<< mySupport->getEntity());
808
809 //     NumberOfValues[i] = 
810 //       MEDnVal(MED_FIELD_DRIVER21<T>::_medIdt,
811 //            const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
812 //            (med_2_1::med_entite_maillage)MED_FIELD_DRIVER<T>::_ptrField->_support->getEntity(),
813 //            (med_2_1::med_geometrie_element)Types[i],
814 //            MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber,
815 //            MED_FIELD_DRIVER<T>::_ptrField->_orderNumber) ;
816
817     NumberOfValues[i] = mySupport->getNumberOfElements(Types[i])
818       * MED_FIELD_DRIVER<T>::_ptrField->getNumberOfGaussPoints(Types[i]);
819
820     myValues[i] = new T[ NumberOfValues[i]*numberOfComponents ] ;
821     TotalNumberOfValues+=NumberOfValues[i] ;
822     char * ProfilName = new char[MED_TAILLE_NOM+1];
823     MESSAGE ("NumberOfValues :"<< NumberOfValues[i]);
824     MESSAGE ("NumberOfComponents :"<< numberOfComponents);
825     MESSAGE ("MESH_NAME :"<< meshName.c_str());
826     MESSAGE ("FIELD_NAME :"<< MED_FIELD_DRIVER<T>::_fieldName.c_str());
827     MESSAGE ("MED_ENTITE :"<< (med_2_1::med_entite_maillage) mySupport->getEntity());
828     MESSAGE("MED_GEOM :"<<(med_2_1::med_geometrie_element)Types[i]);
829     MESSAGE("Iteration :"<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber());
830     MESSAGE("Order :"<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber());
831     MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues+=mySupport->getNumberOfElements(Types[i]); // Ne doit pas prendre en compte les points de Gauss
832
833     med_2_1::med_err ret;
834 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000)
835     int lgth2=NumberOfValues[i]*numberOfComponents;
836     if(MED_FIELD_DRIVER<T>::_ptrField->getValueType()==MED_EN::MED_INT32)
837       {
838         med_2_1::med_int *temp=new med_2_1::med_int[lgth2];
839         ret=med_2_1::MEDchampLire(id,const_cast <char*> (meshName.c_str()),
840                                   const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
841                                   (unsigned char*) temp,
842                                   med_2_1::MED_NO_INTERLACE,
843                                   MED_ALL,
844                                   ProfilName,
845                                   (med_2_1::med_entite_maillage) mySupport->getEntity(),
846                                   (med_2_1::med_geometrie_element) Types[i],
847                                   MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
848                                   MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
849                                   );
850         for(int i2=0;i2<lgth2;i2++)
851           myValues[i][i2]=(int)(temp[i2]);
852         delete [] temp;
853       }
854     else
855 #endif
856       ret=med_2_1::MEDchampLire(id,const_cast <char*> (meshName.c_str()),
857                                 const_cast <char*> (MED_FIELD_DRIVER<T>::_fieldName.c_str()),
858                                 (unsigned char*) myValues[i],
859                                 med_2_1::MED_NO_INTERLACE,
860                                 MED_ALL,
861                                 ProfilName,
862                                 (med_2_1::med_entite_maillage) mySupport->getEntity()
863                                 ,(med_2_1::med_geometrie_element)Types[i],
864                                 MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
865                                 MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
866                                 ); 
867     if (ret < 0)
868       {
869       // The Field can't be read then we mustdelete all previously allocated members in FIELD
870         for(int j=0; j<=i;j++)
871           delete[] myValues[j];
872         delete[] myValues;
873         delete[] NumberOfValues ;
874         delete[] ProfilName;
875         delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes ;
876         delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsNames ;
877         delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits ;
878         delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions ;
879         delete[] MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits ;
880         MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = NULL ;
881         MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = NULL ;
882         MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = NULL ;
883         MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = NULL ;
884         MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = NULL ;
885         MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ; // we have not found right field, so reset the field number 
886         throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": ERROR when read value")) ;
887       }
888
889     delete[] ProfilName ;
890   }
891   // allocate _value
892   // probleme avec les points de gauss : voir lorsqu-il y en a (!= 1)
893   // Creer un driver spécifique pour les modes MED_FULL_INTERLACE et MED_NO_INTERLACE
894   // serait plus efficicace.
895   ArrayNo * Values = new ArrayNo(numberOfComponents,TotalNumberOfValues);
896
897   for (int i=0; i<numberOfComponents; i++)
898     {
899       //T * ValuesT = Values->getRow(i+1) ;
900       int Count = 1 ;
901       for (int j=0; j<NumberOfTypes; j++)
902         {
903           T * myValue = myValues[j] ;
904           int NumberOf = NumberOfValues[j] ;
905           //      MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues+=NumberOf; // problem with gauss point : _numberOfValues != TotalNumberOfValues !!!!!!!
906           int offset = NumberOf*i ;
907           for (int k=0 ; k<NumberOf; k++) {
908             //ValuesT[Count]=myValue[k+offset] ;
909             Values->setIJ(Count,i+1,myValue[k+offset]);
910             //jfa 22.07.2005:SCRUTE(Count);
911             //jfa 22.07.2005:SCRUTE(Values->getIJ(Count,i+1));
912             Count++;
913           }
914         }
915     }
916       
917   for (int j=0; j<NumberOfTypes; j++)
918     delete[] myValues[j] ;
919   delete[] myValues ;
920   delete[] NumberOfValues ;
921
922   if (MED_FIELD_DRIVER<T>::_ptrField->_value != NULL)
923     delete MED_FIELD_DRIVER<T>::_ptrField->_value;
924
925   if ( MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE )
926     {
927       // dynamic_cast inutile
928       MED_FIELD_DRIVER<T>::_ptrField->_value=dynamic_cast<ArrayFull *>(ArrayConvert(*Values));
929       delete Values;
930     }
931   else
932     MED_FIELD_DRIVER<T>::_ptrField->_value=Values;
933   
934   MED_FIELD_DRIVER<T>::_ptrField->_isRead = true ;
935
936   MED_FIELD_DRIVER<T>::_ptrField->_support=mySupport; //Prévenir l'utilisateur ?
937       
938   END_OF(LOC);
939 }
940
941 template <class T> void MED_FIELD_RDONLY_DRIVER21<T>::write( void ) const
942   throw (MEDEXCEPTION)
943 {
944   throw MEDEXCEPTION("MED_FIELD_RDONLY_DRIVER21::write : Can't write with a RDONLY driver !");
945 }
946
947 /*--------------------- WRONLY PART -------------------------------*/
948
949 template <class T> GENDRIVER * MED_FIELD_WRONLY_DRIVER21<T>::copy(void) const
950 {
951   return new MED_FIELD_WRONLY_DRIVER21<T>(*this);
952 }
953
954 template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::read (void)
955   throw (MEDEXCEPTION)
956 {
957   throw MEDEXCEPTION("MED_FIELD_WRONLY_DRIVER21::read : Can't read with a WRONLY driver !");
958 }
959
960 template <class T> void MED_FIELD_WRONLY_DRIVER21<T>::write(void) const
961   throw (MEDEXCEPTION)
962 {
963   const char * LOC = "MED_FIELD_WRONLY_DRIVER21::write(void) const " ;
964   BEGIN_OF(LOC);
965
966   typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo;
967   typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull;
968
969   if (MED_FIELD_DRIVER<T>::_status==MED_OPENED)
970     {
971       int err ;
972
973       int component_count=MED_FIELD_DRIVER<T>::_ptrField->getNumberOfComponents();
974       string   component_name(component_count*MED_TAILLE_PNOM21,' ') ;
975       string   component_unit(component_count*MED_TAILLE_PNOM21,' ') ;
976
977       const string * listcomponent_name=MED_FIELD_DRIVER<T>::_ptrField->getComponentsNames() ;
978       const string * listcomponent_unit=MED_FIELD_DRIVER<T>::_ptrField->getMEDComponentsUnits() ;
979       int length ;
980       for (int i=0; i < component_count ; i++) {
981         length = min(MED_TAILLE_PNOM21,(int)listcomponent_name[i].size());
982         component_name.replace(i*MED_TAILLE_PNOM21,length,
983                                listcomponent_name[i],0,length);
984         length = min(MED_TAILLE_PNOM21,(int)listcomponent_unit[i].size());
985         component_unit.replace(i*MED_TAILLE_PNOM21,length,
986                                listcomponent_unit[i],0,length);
987       }
988
989       MESSAGE("component_name=|"<<component_name<<"|");
990       MESSAGE("component_unit=|"<<component_unit<<"|");
991
992       MED_EN::med_type_champ ValueType=MED_FIELD_DRIVER<T>::_ptrField->getValueType() ;
993       
994       MESSAGE("Template Type =|"<<ValueType<<"|");
995       
996       // le champ existe deja ???
997       char * champName = new char[MED_TAILLE_NOM+1] ;
998       med_2_1::med_type_champ type ;
999       char * compName ;
1000       char * compUnit ;
1001       bool Find = false ;
1002       int n = med_2_1::MEDnChamp(MED_FIELD_DRIVER21<T>::_medIdt,0);
1003       int nbComp ;
1004       for (int i=1; i<=n; i++) {
1005         nbComp = med_2_1::MEDnChamp(MED_FIELD_DRIVER21<T>::_medIdt,i);
1006         compName = new char[MED_TAILLE_PNOM21*nbComp+1];
1007         compUnit = new char[MED_TAILLE_PNOM21*nbComp+1];
1008         err = med_2_1::MEDchampInfo(MED_FIELD_DRIVER21<T>::_medIdt,i,champName,&type,compName,compUnit,nbComp);
1009         if (err == 0)
1010           if (strcmp(champName,MED_FIELD_DRIVER<T>::_ptrField->getName().c_str())==0) { // Found !
1011             Find = true ;
1012             break ;
1013           }
1014         delete[] compName ;
1015         delete[] compUnit ;
1016       }
1017       delete[] champName ;
1018       if (Find) {
1019         // the same ?
1020         if (nbComp != component_count)
1021           throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
1022                                          <<": Field exist in file, but number of component are different : "<<nbComp<<" in file and "<<component_count<<" in memory."
1023                                          )
1024                               );
1025         // component name and unit
1026         MESSAGE(LOC<<" Component name in file : "<<compName);
1027         MESSAGE(LOC<<" Component name in memory : "<<component_name);
1028         MESSAGE(LOC<<" Component unit in file : "<<compUnit);
1029         MESSAGE(LOC<<" Component unit in memory : "<<component_unit);
1030         delete[] compName ;
1031         delete[] compUnit ;
1032
1033       } else {
1034         // Verify the field doesn't exist
1035
1036         string dataGroupName =  "/CHA/";
1037         dataGroupName        += MED_FIELD_DRIVER<T>::_ptrField->getName();
1038         MESSAGE(LOC << "|" << dataGroupName << "|" );
1039         med_2_1::med_idt gid =  H5Gopen(MED_FIELD_DRIVER21<T>::_medIdt, dataGroupName.c_str() );
1040         
1041         if ( gid < 0 ) {
1042           // create field :
1043           err=med_2_1::MEDchampCr(MED_FIELD_DRIVER21<T>::_medIdt, 
1044                                  const_cast <char*> ((MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()),
1045                                  (med_2_1::med_type_champ) ValueType,
1046                                  const_cast <char*> ( component_name.c_str() ),
1047                                  const_cast <char*> ( component_unit.c_str() ),
1048                                  component_count);
1049           if ( err < 0 )
1050             throw MEDEXCEPTION( LOCALIZED (STRING(LOC) 
1051                                            << ": Error MEDchampCr : "<<err
1052                                            )
1053                                 );
1054         }
1055         else H5Gclose(gid);
1056       }
1057
1058       const SUPPORT * mySupport = MED_FIELD_DRIVER<T>::_ptrField->getSupport() ;
1059
1060       if (! mySupport->isOnAllElements())
1061         throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
1062                                        <<": Field must be on all entity"
1063                                        )
1064                             );
1065       
1066       MESH * myMesh = mySupport->getMesh() ;
1067       string MeshName = myMesh->getName() ;
1068       //MED_EN::medModeSwitch Mode = MED_FIELD_DRIVER<T>::_ptrField->_value->getMode() ;
1069       // on boucle sur tout les types pour ecrire les tableaux de valeur
1070       int NumberOfType = mySupport->getNumberOfTypes() ;
1071       int Index = 1 ;
1072       const MED_EN::medGeometryElement * Types = mySupport->getTypes() ;
1073
1074       const T * value     = NULL;
1075       ArrayFull * myArray = NULL;
1076       if ( MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE )
1077         myArray = MED_FIELD_DRIVER<T>::_ptrField->getArrayNoGauss();
1078       else {
1079         // En attendant la convertion de FIELD, on utilise le ArrayConvert
1080         // ( les infos _ptrField-> sont les mêmes )
1081         myArray = ArrayConvert( *( dynamic_cast< ArrayNo * >
1082                                    (MED_FIELD_DRIVER<T>::_ptrField->getArrayNoGauss()
1083                                     ))
1084                                 );
1085       }
1086
1087       for (int i=0;i<NumberOfType;i++) {
1088         int NumberOfElements = mySupport->getNumberOfElements(Types[i]) ;
1089         int NumberOfGaussPoints = MED_FIELD_DRIVER<T>::_ptrField->getNumberOfGaussPoints(Types[i]) ;
1090
1091 //      const T * value = MED_FIELD_DRIVER<T>::_ptrField->getValueI(MED_EN::MED_FULL_INTERLACE,Index) ;
1092
1093         value = myArray->getRow(Index) ;
1094         
1095         MESSAGE("MED_FIELD_DRIVER21<T>::_medIdt                         : "<<MED_FIELD_DRIVER21<T>::_medIdt);
1096         MESSAGE("MeshName.c_str()                : "<<MeshName.c_str());
1097         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getName()            : "<<MED_FIELD_DRIVER<T>::_ptrField->getName());
1098         MESSAGE("value                           : "<<value);
1099         MESSAGE("NumberOfElements                : "<<NumberOfElements);
1100         MESSAGE("NumberOfGaussPoints             : "<<NumberOfGaussPoints);
1101         MESSAGE("mySupport->getEntity()          : "<<mySupport->getEntity());
1102         MESSAGE("Types[i]                        : "<<Types[i]);
1103         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber());
1104         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getTime()            : "<<MED_FIELD_DRIVER<T>::_ptrField->getTime());
1105         MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()     : "<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber());
1106         
1107 /*      char chanom[MED_TAILLE_NOM+1];
1108         char chacomp[MED_TAILLE_NOM+1];
1109         char chaunit[MED_TAILLE_NOM+1];
1110         med_2_1::med_type_champ chatype;
1111         med_int chancomp=1;
1112         
1113         err=med_2_1::MEDchampInfo(MED_FIELD_DRIVER<T>::_medIdt,1,chanom,&chatype,chacomp,chaunit,chancomp);
1114
1115         if (err<0) 
1116                 {
1117                 cout<<"=======================================================================> gros probleme"<<endl;
1118                 exit(-1);
1119                 }
1120         cout<<"==================> nom lu            = "<<chanom<<endl;
1121         cout<<"==================> type lu           = "<<chatype<<endl;
1122         cout<<"==================> nom composante lu = "<<chacomp<<endl;
1123         cout<<"==================> nom unit lu       = "<<chaunit<<endl;
1124         cout<<"==================> valeur de med_2_1::MED_REEL64 = "<<med_2_1::MED_REEL64<<endl;
1125 */      
1126 #if defined(IRIX64) || defined(OSF1) || defined(VPP5000)
1127         if(_ptrField->getValueType()==MED_EN::MED_INT32)
1128           {
1129             int lgth2=_ptrField->getNumberOfValues();
1130             med_2_1::med_int *temp=new med_2_1::med_int[lgth2];
1131             for(int i2=0;i2<lgth2;i2++)
1132               temp[i2]=(int)(value[i2]);
1133             err=med_2_1::MEDchampEcr(MED_FIELD_DRIVER21<T>::_medIdt, 
1134                                     const_cast <char*> ( MeshName.c_str()) ,                         //( string(mesh_name).resize(MED_TAILLE_NOM).c_str())
1135                                     const_cast <char*> ( (MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()),
1136                                     (unsigned char*)temp, 
1137                                     med_2_1::MED_FULL_INTERLACE,
1138                                     NumberOfElements,
1139                                     NumberOfGaussPoints,
1140                                     MED_ALL,
1141                                     MED_NOPFL,
1142                                     med_2_1::MED_REMP,  // PROFIL NON GERE, mode de remplacement non géré
1143                                     (med_2_1::med_entite_maillage)mySupport->getEntity(),
1144                                     (med_2_1::med_geometrie_element)Types[i],
1145                                     MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
1146                                     "        ",
1147                                     MED_FIELD_DRIVER<T>::_ptrField->getTime(),
1148                                     MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
1149                                     );
1150             delete [] temp;
1151           }
1152         else
1153 #endif
1154         err=med_2_1::MEDchampEcr(MED_FIELD_DRIVER21<T>::_medIdt, 
1155                                 const_cast <char*> ( MeshName.c_str()) ,                         //( string(mesh_name).resize(MED_TAILLE_NOM).c_str())
1156                                 const_cast <char*> ( (MED_FIELD_DRIVER<T>::_ptrField->getName()).c_str()),
1157                                 (unsigned char*)value, 
1158                                 med_2_1::MED_FULL_INTERLACE,
1159                                 NumberOfElements,
1160                                 NumberOfGaussPoints,
1161                                 MED_ALL,
1162                                 MED_NOPFL,
1163                                 med_2_1::MED_REMP,  // PROFIL NON GERE, mode de remplacement non géré
1164                                 (med_2_1::med_entite_maillage)mySupport->getEntity(),
1165                                 (med_2_1::med_geometrie_element)Types[i],
1166                                 MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
1167                                 "        ",
1168                                 MED_FIELD_DRIVER<T>::_ptrField->getTime(),
1169                                 MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
1170                                 );
1171         if (err < MED_VALID )
1172           {
1173             if ( MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE ) delete myArray;
1174
1175             throw MEDEXCEPTION(LOCALIZED( STRING(LOC)
1176                                           <<": Error in writing Field "<< MED_FIELD_DRIVER<T>::_ptrField->getName() <<", type "<<Types[i]
1177                                           )
1178                                );
1179           }
1180
1181         Index += NumberOfElements ;
1182         
1183       }
1184       if ( MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE ) delete myArray;
1185
1186     }
1187   
1188   END_OF(LOC);
1189 }
1190
1191 /*--------------------- RDWR PART -------------------------------*/
1192
1193 template <class T> GENDRIVER * MED_FIELD_RDWR_DRIVER21<T>::copy(void) const
1194 {
1195   return new MED_FIELD_RDWR_DRIVER21<T>(*this);
1196 }
1197
1198 template <class T> void MED_FIELD_RDWR_DRIVER21<T>::write(void) const
1199   throw (MEDEXCEPTION)
1200 {
1201   BEGIN_OF("MED_FIELD_RDWR_DRIVER21::write(void)");
1202   MED_FIELD_WRONLY_DRIVER21<T>::write(); 
1203   END_OF("MED_FIELD_RDWR_DRIVER21::write(void)");
1204
1205
1206 template <class T> void MED_FIELD_RDWR_DRIVER21<T>::read (void)
1207   throw (MEDEXCEPTION)
1208 {
1209   BEGIN_OF("MED_FIELD_RDWR_DRIVER21::read(void)");
1210   MED_FIELD_RDONLY_DRIVER21<T>::read();
1211   END_OF("MED_FIELD_RDWR_DRIVER21::read(void)");
1212 }
1213 }//End namespace MEDMEM
1214 /*-----------------------------------------------------------------*/
1215
1216 #endif /* MED_FIELD_DRIVER_HXX */
1217