1 #ifndef MED_FIELD_DRIVER_HXX
2 #define MED_FIELD_DRIVER_HXX
6 #include "MEDMEM_define.hxx"
8 #include "MEDMEM_GenDriver.hxx"
11 #include "MEDMEM_STRING.hxx"
12 #include "MEDMEM_Exception.hxx"
13 #include "MEDMEM_Unit.hxx"
14 #include "MEDMEM_Array.hxx"
15 #include "MEDMEM_Support.hxx"
16 //#include "MEDMEM_Field.hxx"
18 //using namespace MED_FR ;
20 template <class T> class FIELD;
22 // A QD LA CLASSE MED_ALL_ELEMENTS_DRIVER.... :) pour mutualiser le open ..... avec led _medIdt...
23 template <class T> class MED_FIELD_DRIVER : public GENDRIVER
28 MED_FR::med_idt _medIdt;
36 // all MED cell type ?? Classe de Définition ??
37 // static const medGeometryElement all_cell_type[MED_NBR_GEOMETRIE_MAILLE];
39 // static const char * const all_cell_type_tab [MED_NBR_GEOMETRIE_MAILLE];
41 MED_FIELD_DRIVER():GENDRIVER(),
42 _ptrField((FIELD<T> *)MED_NULL),_medIdt(MED_INVALID),
43 _fieldName(""),_fieldNum(MED_INVALID) {}
44 MED_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField,
45 med_mode_acces accessMode)
46 : GENDRIVER(fileName,accessMode),
47 _ptrField((FIELD<T> *) ptrField),_medIdt(MED_INVALID),
48 _fieldName(""),_fieldNum(MED_INVALID)
53 const char * LOC = "MED_FIELD_DRIVER::open() ";
56 // we must set fieldname before open, because we must find field number in file (if it exist !!!)
58 MESSAGE(LOC<<"_fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
59 _medIdt = MED_FR::MEDouvrir( (const_cast <char *> (_fileName.c_str())),(MED_FR::med_mode_acces) _accessMode);
60 MESSAGE(LOC<<"_medIdt : "<< _medIdt );
61 if (_medIdt > 0) _status=MED_OPENED; else {
62 _status = MED_INVALID;
69 BEGIN_OF("MED_FIELD_DRIVER::close()");
70 MED_FR::med_int err = 0;
71 if (_status == MED_OPENED) {
72 err=MED_FR::MEDfermer(_medIdt);
73 H5close(); // If we call H5close() all the files are closed.
75 _medIdt = MED_INVALID;
76 MESSAGE(" MED_FIELD_DRIVER::close() : MEDfermer : _medIdt= " << _medIdt );
77 MESSAGE(" MED_FIELD_DRIVER::close() : MEDfermer : err = " << err );
79 END_OF("MED_FIELD_DRIVER::close()");
82 virtual void write( void ) const = 0 ;
83 virtual void read ( void ) = 0 ;
84 void setFieldName(const string & fieldName) ;
85 string getFieldName() const ;
88 template <class T> class MED_FIELD_RDONLY_DRIVER : public virtual MED_FIELD_DRIVER<T>
93 MED_FIELD_RDONLY_DRIVER():MED_FIELD_DRIVER<T>() {};
95 MED_FIELD_RDONLY_DRIVER(const string & fileName, FIELD<T> * ptrField):
96 MED_FIELD_DRIVER<T>(fileName,ptrField,MED_RDONLY) {
97 BEGIN_OF("MED_FIELD_RDONLY_DRIVER::MED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
98 END_OF("MED_FIELD_RDONLY_DRIVER::MED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
101 ~MED_FIELD_RDONLY_DRIVER() {
102 BEGIN_OF("MED_FIELD_RDONLY_DRIVER::~MED_FIELD_RDONLY_DRIVER()");
103 END_OF("MED_FIELD_RDONLY_DRIVER::~MED_FIELD_RDONLY_DRIVER()");
106 // CREER UNE METHODE POUR LIRE LA LISTE DES MAILLAGES .....
108 void write( void ) const ;
112 template <class T> class MED_FIELD_WRONLY_DRIVER : public virtual MED_FIELD_DRIVER<T> {
116 MED_FIELD_WRONLY_DRIVER():MED_FIELD_DRIVER<T>() {}
118 MED_FIELD_WRONLY_DRIVER(const string & fileName, FIELD<T> * ptrField):
119 MED_FIELD_DRIVER<T>(fileName,ptrField,MED_WRONLY)
121 BEGIN_OF("MED_FIELD_WRONLY_DRIVER::MED_FIELD_WRONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
122 END_OF("MED_FIELD_WRONLY_DRIVER::MED_FIELD_WRONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
125 ~MED_FIELD_WRONLY_DRIVER() { }
127 void write( void ) const ;
132 template <class T> class MED_FIELD_RDWR_DRIVER : public MED_FIELD_RDONLY_DRIVER<T>, public MED_FIELD_WRONLY_DRIVER<T> {
136 MED_FIELD_RDWR_DRIVER():MED_FIELD_DRIVER<T>() {}
138 MED_FIELD_RDWR_DRIVER(const string & fileName, FIELD<T> * ptrField):
139 MED_FIELD_DRIVER<T>(fileName,ptrField,MED_RDWR)
141 BEGIN_OF("MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
142 END_OF("MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
145 ~MED_FIELD_RDWR_DRIVER() { }
147 void write(void) const ;
152 /*-------------------------*/
153 /* template implementation */
154 /*-------------------------*/
156 /*--------------------- DRIVER PART -------------------------------*/
158 template <class T> void MED_FIELD_DRIVER<T>::setFieldName(const string & fieldName)
160 _fieldName = fieldName;
163 template <class T> string MED_FIELD_DRIVER<T>::getFieldName() const
168 // template <class T> void MED_FIELD_DRIVER<T>::search_field() {
169 // const char * LOC = "template <class T> class MED_FIELD_DRIVER::search_field() :";
171 // // we search the field number !!!!
172 // if (_status==MED_OPENED)
173 // if (_fieldNum==MED_INVALID) {
175 // int numberOfFields = 0; //MED_INVALID
176 // // char fieldName[MED_TAILLE_NOM+1] = "";
177 // char fieldName[MED_TAILLE_NOM+1] ;
178 // int numberOfComponents = 0;
179 // char * componentName = (char *) MED_NULL;
180 // char * unitName = (char *) MED_NULL;
181 // MED_FR::med_type_champ type ;
182 // numberOfFields = MED_FR::MEDnChamp(_medIdt,0) ;
183 // if ( numberOfFields <= 0 )
184 // throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": No Field found !"));
185 // for (int i=1;i<=numberOfFields;i++) {
187 // numberOfComponents = MED_FR::MEDnChamp(_medIdt,i) ;
188 // if ( numberOfComponents <= 0 )
189 // throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
190 // << "Be careful there is no compound for field n°"
191 // << i << "in file |"<<_fileName<<"| !"));
193 // componentName = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;
194 // unitName = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;
196 // err = MED_FR::MEDchampInfo(_medIdt, i, fieldName, &type, componentName,
197 // unitName, numberOfComponents) ;
199 // delete[] componentName ;
200 // delete[] unitName ;
201 // MESSAGE("Champ "<<i<<" : #" << fieldName <<"# et recherche #"<<_fieldName.c_str()<<"#");
202 // if ( !strcmp(fieldName,_fieldName.c_str()) ) {
203 // MESSAGE("FOUND FIELD "<< fieldName <<" : "<<i);
211 /*--------------------- RDONLY PART -------------------------------*/
213 template <class T> void MED_FIELD_RDONLY_DRIVER<T>::read(void)
215 const char * LOC = " MED_FIELD_RDONLY_DRIVER::read() " ;
218 if (_ptrField->_name=="")
219 _ptrField->_name = _fieldName ;
221 _fieldName = _ptrField->_name; // bug indetermine ! apres avoir fait readfilestruct, lorsque je recupere le champ, tout est bon sauf le nom du champ dans le driver !!!!!
223 MESSAGE("###### "<<LOC<<" fieldNameDRIVER : "<<_fieldName<<" fieldName : "<<_ptrField->_name);
225 string MeshName = _ptrField->getSupport()->getMesh()->getName() ;
227 if (_status==MED_OPENED)
233 fieldName = new char[MED_TAILLE_NOM+1] ;
235 int numberOfComponents = 0;
236 char * componentName = (char *) MED_NULL;
237 char * unitName = (char *) MED_NULL;
238 MED_FR::med_type_champ type ;
240 // we search the field number !!!!
241 if (_fieldNum==MED_INVALID) {
242 int numberOfFields = 0; //MED_INVALID
243 numberOfFields = MED_FR::MEDnChamp(_medIdt,0) ;
244 if ( numberOfFields <= 0 )
245 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": No Field found !"));
246 for (int i=1;i<=numberOfFields;i++) {
248 numberOfComponents = MED_FR::MEDnChamp(_medIdt,i) ;
249 if ( numberOfComponents <= 0 )
250 // throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
251 // << "Be careful there is no compound for field n°"
252 // << i << "in file |"<<_fileName<<"| !"));
253 MESSAGE(LOC<<"Be careful there is no compound for field n°"<<i<<"in file |"<<_fileName<<"| !");
255 componentName = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;
256 unitName = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;
258 err = MED_FR::MEDchampInfo(_medIdt, i, fieldName, &type, componentName,
259 unitName, numberOfComponents) ;
261 MESSAGE("Champ "<<i<<" : #" << fieldName <<"# et recherche #"<<_fieldName.c_str()<<"#");
262 if ( !strcmp(fieldName,_fieldName.c_str()) ) {
263 MESSAGE("FOUND FIELD "<< fieldName <<" : "<<i);
272 if (_fieldNum==MED_INVALID)
273 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) << ": Field "<<_fieldName << " not found in file " << _fileName ) );
274 MESSAGE ("FieldNum : "<<_fieldNum);
277 // int NumberOfComponents = MED_FR::MEDnChamp(_medIdt,_fieldNum) ;
278 if (numberOfComponents < 1)
279 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"no component")) ; // use iostring !
280 // test type to check if it is rigth !!!???
281 _ptrField->_numberOfComponents = numberOfComponents ;
282 _ptrField->_componentsTypes = new int[numberOfComponents] ;
283 _ptrField->_componentsNames = new string[numberOfComponents] ;
284 _ptrField->_componentsUnits = new UNIT[numberOfComponents] ;
285 _ptrField->_componentsDescriptions = new string[numberOfComponents] ;
286 _ptrField->_MEDComponentsUnits = new string[numberOfComponents] ;
287 for (int i=0; i<numberOfComponents; i++) {
288 _ptrField->_componentsTypes[i] = 1 ;
290 // PG : what about space !!!
291 _ptrField->_componentsNames[i] = string(componentName,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM) ;
292 SCRUTE(_ptrField->_componentsNames[i]);
293 _ptrField->_MEDComponentsUnits[i] = string(unitName,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM) ;
294 SCRUTE(_ptrField->_MEDComponentsUnits[i]);
296 delete[] componentName;
299 // read values for each geometric type in _support
300 int NumberOfTypes = _ptrField->_support->getNumberOfTypes() ;
301 medGeometryElement *Types = _ptrField->_support->getTypes() ;
302 T ** myValues = new (T*)[NumberOfTypes] ;
303 int * NumberOfValues = new int[NumberOfTypes] ;
304 int TotalNumberOfValues = 0 ;
305 MESSAGE ("NumberOfTypes :"<< NumberOfTypes);
306 for (int i=0; i<NumberOfTypes; i++) {
307 MESSAGE ("Type["<<i+1<<"] :"<< Types[i]);
308 MESSAGE ("Entity :"<<_ptrField->_support->getEntity());
311 const_cast <char*> (_fieldName.c_str()),
312 (MED_FR::med_entite_maillage)_ptrField->_support->getEntity(),
313 (MED_FR::med_geometrie_element)Types[i],
314 _ptrField->_iterationNumber,
315 _ptrField->_orderNumber) ; // no time step ! prend en compte le nbre de pt de gauss
316 // test if NumberOfValues is the same in _support !!! TODO that !!
318 // we could allocate array
319 myValues[i] = new T[ NumberOfValues[i]*numberOfComponents ] ;
320 TotalNumberOfValues+=NumberOfValues[i] ;// diviser par le nombre de point de gauss
321 char * ProfilName = new char[MED_TAILLE_NOM+1];
322 MESSAGE ("NumberOfValues :"<< NumberOfValues[i]);
323 MESSAGE ("NumberOfComponents :"<< numberOfComponents);
324 MESSAGE ("MESH_NAME :"<< MeshName.c_str());
325 MESSAGE ("FIELD_NAME :"<< _fieldName.c_str());
326 MESSAGE ("MED_ENTITE :"<< (MED_FR::med_entite_maillage) _ptrField->_support->getEntity());
327 MESSAGE("MED_GEOM :"<<(MED_FR::med_geometrie_element)Types[i]);
328 MESSAGE("Iteration :"<<_ptrField->getIterationNumber());
329 MESSAGE("Order :"<<_ptrField->getOrderNumber());
330 if ( MED_FR::MEDchampLire(_medIdt,const_cast <char*> (MeshName.c_str()),
331 const_cast <char*> (_fieldName.c_str()),
332 (unsigned char*) myValues[i],
333 MED_FR::MED_NO_INTERLACE,
336 (MED_FR::med_entite_maillage) _ptrField->_support->getEntity(),(MED_FR::med_geometrie_element)Types[i],
337 _ptrField->getIterationNumber(),
338 _ptrField->getOrderNumber()
340 // we must do some delete !!!
341 _fieldNum = MED_INVALID ; // we have not found right field, so reset the field number
342 throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": ERROR when read value")) ;
345 delete[] ProfilName ;
348 // probleme avec les points de gauss : voir lorsqu-il y en a (!= 1)
349 // MEDARRAY<T> * Values = new MEDARRAY<T>(_ptrField->getNumberOfComponents(),TotalNumberOfValues/_ptrField->getNumberOfComponents(),MED_EN::MED_NO_INTERLACE);
351 if (_ptrField->_value==NULL)
352 _ptrField->_value=new MEDARRAY<T>(numberOfComponents,TotalNumberOfValues,MED_EN::MED_NO_INTERLACE);
354 MEDARRAY<T> * Values = _ptrField->_value ; // create by constructor ???
355 // check if dimensions are right
356 if (Values->getLeadingValue() != numberOfComponents)
357 throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": leading dimension are false : "<<Values->getLeadingValue()<<" and "<<numberOfComponents) ) ;
358 if (Values->getLengthValue() != TotalNumberOfValues)
359 throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": length dimension are false : "<<Values->getLengthValue()<<" and "<<TotalNumberOfValues) ) ;
361 for (int i=0; i<numberOfComponents; i++) {
362 T * ValuesT = Values->getI(MED_NO_INTERLACE,i+1) ;
364 for (int j=0; j<NumberOfTypes; j++) {
365 T * myValue = myValues[j] ;
366 int NumberOf = NumberOfValues[j] ;
367 int offset = NumberOf*i ;
368 for (int k=0 ; k<NumberOf; k++) {
369 ValuesT[Count]=myValue[k+offset] ;
375 for (int j=0; j<NumberOfTypes; j++)
376 delete[] myValues[j] ;
378 delete[] NumberOfValues ;
383 template <class T> void MED_FIELD_RDONLY_DRIVER<T>::write( void ) const
385 throw MEDEXCEPTION("MED_FIELD_RDONLY_DRIVER::write : Can't write with a RDONLY driver !");
388 /*--------------------- WRONLY PART -------------------------------*/
390 template <class T> void MED_FIELD_WRONLY_DRIVER<T>::read (void)
392 throw MEDEXCEPTION("MED_FIELD_WRONLY_DRIVER::write : Can't read with a WRONLY driver !");
395 template <class T> void MED_FIELD_WRONLY_DRIVER<T>::write(void) const
397 const char * LOC = "MED_FIELD_WRONLY_DRIVER::write(void) const " ;
399 if (_status==MED_OPENED)
403 int component_count=_ptrField->getNumberOfComponents();
404 string component_name(component_count*MED_TAILLE_PNOM,' ') ;
405 string component_unit(component_count*MED_TAILLE_PNOM,' ') ;
407 string * listcomponent_name=_ptrField->getComponentsNames() ;
408 string * listcomponent_unit=_ptrField->getMEDComponentsUnits() ;
410 for (int i=0; i < component_count ; i++) {
411 length = min(MED_TAILLE_PNOM,(int)listcomponent_name[i].size());
412 component_name.replace(i*MED_TAILLE_PNOM,length,
413 listcomponent_name[i],0,length);
414 length = min(MED_TAILLE_PNOM,(int)listcomponent_unit[i].size());
415 component_unit.replace(i*MED_TAILLE_PNOM,length,
416 listcomponent_unit[i],0,length);
419 MESSAGE("component_name=|"<<component_name<<"|");
420 MESSAGE("component_unit=|"<<component_unit<<"|");
422 MED_EN::med_type_champ ValueType=_ptrField->getValueType() ;
424 // le champ existe deja ???
425 char * champName = new char[MED_TAILLE_NOM+1] ;
426 MED_FR::med_type_champ type ;
430 int n = MED_FR::MEDnChamp(_medIdt,0);
432 for (int i=1; i<=n; i++) {
433 nbComp = MED_FR::MEDnChamp(_medIdt,i);
434 compName = new char[MED_TAILLE_PNOM*nbComp+1];
435 compUnit = new char[MED_TAILLE_PNOM*nbComp+1];
436 err = MED_FR::MEDchampInfo(_medIdt,i,champName,&type,compName,compUnit,nbComp);
438 if (strcmp(champName,_ptrField->getName().c_str())==0) { // Found !
448 if (nbComp != component_count)
449 throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
450 <<": Field exist in file, but number of component are different : "<<nbComp<<" in file and "<<component_count<<" in memory."
453 // component name and unit
454 MESSAGE(LOC<<" Component name in file : "<<compName);
455 MESSAGE(LOC<<" Component name in memory : "<<component_name);
456 MESSAGE(LOC<<" Component unit in file : "<<compUnit);
457 MESSAGE(LOC<<" Component unit in memory : "<<component_unit);
462 // Verify the field doesn't exist
464 string dataGroupName = "/CHA/";
465 dataGroupName += _ptrField->getName();
466 MESSAGE(LOC << "|" << dataGroupName << "|" );
467 med_idt gid = H5Gopen(_medIdt, dataGroupName.c_str() );
471 err=MED_FR::MEDchampCr(_medIdt,
472 const_cast <char*> ((_ptrField->getName()).c_str()),
473 (MED_FR::med_type_champ) ValueType,
474 const_cast <char*> ( component_name.c_str() ),
475 const_cast <char*> ( component_unit.c_str() ),
478 throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
479 << ": Error MEDchampCr : "<<err
486 const SUPPORT * mySupport = _ptrField->getSupport() ;
488 if (! mySupport->isOnAllElements())
489 throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
490 <<": Field must be on all entity"
494 MESH * myMesh = mySupport->getMesh() ;
495 string MeshName = myMesh->getName() ;
496 //MED_EN::medModeSwitch Mode = _ptrField->_value->getMode() ;
497 // on boucle sur tout les types pour ecrire les tableaux de valeur
498 int NumberOfType = mySupport->getNumberOfTypes() ;
500 medGeometryElement * Types = mySupport->getTypes() ;
501 int * NumberOfGaussPoint = mySupport->getNumberOfGaussPoint() ;
502 for (int i=0;i<NumberOfType;i++) {
503 int NumberOfElements = mySupport->getNumberOfElements(Types[i]) ;
505 MESSAGE(" "<<_ptrField->getName());
506 MESSAGE(" "<<NumberOfElements);
507 MESSAGE(" "<<NumberOfGaussPoint[i]);
508 MESSAGE(" "<<mySupport->getEntity());
509 MESSAGE(" "<<Types[i]);
510 MESSAGE(" "<<_ptrField->getIterationNumber());
511 MESSAGE(" "<<_ptrField->getTime());
512 MESSAGE(" "<<_ptrField->getOrderNumber());
513 MESSAGE("MEDchampEcr :"<<MeshName.c_str());
515 T * value = _ptrField->getValueI(MED_EN::MED_FULL_INTERLACE,Index) ;
517 err=MED_FR::MEDchampEcr(_medIdt, const_cast <char*> ( MeshName.c_str()) , //( string(mesh_name).resize(MED_TAILLE_NOM).c_str())
518 const_cast <char*> ( (_ptrField->getName()).c_str()),
519 (unsigned char*)value, MED_FR::MED_FULL_INTERLACE,
521 NumberOfGaussPoint[i],MED_ALL, MED_NOPFL, MED_FR::MED_REMP, // PROFIL NON GERE, mode de remplacement non géré
522 (MED_FR::med_entite_maillage)mySupport->getEntity(),
523 (MED_FR::med_geometrie_element)Types[i],
524 _ptrField->getIterationNumber()," ",
525 _ptrField->getTime(),_ptrField->getOrderNumber()
527 if (err < MED_VALID )
528 throw MEDEXCEPTION(LOCALIZED( STRING(LOC)
529 <<": Error in writing Field "<< _ptrField->getName() <<", type "<<Types[i]
532 Index += NumberOfElements ;
540 /*--------------------- RDWR PART -------------------------------*/
542 template <class T> void MED_FIELD_RDWR_DRIVER<T>::write(void) const
544 BEGIN_OF("MED_FIELD_RDWR_DRIVER::write(void)");
545 MED_FIELD_WRONLY_DRIVER<T>::write();
546 END_OF("MED_FIELD_RDWR_DRIVER::write(void)");
549 template <class T> void MED_FIELD_RDWR_DRIVER<T>::read (void)
551 BEGIN_OF("MED_FIELD_RDWR_DRIVER::read(void)");
552 MED_FIELD_RDONLY_DRIVER<T>::read();
553 END_OF("MED_FIELD_RDWR_DRIVER::read(void)");
556 /*-----------------------------------------------------------------*/
558 #endif /* MED_FIELD_DRIVER_HXX */