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_Field.hxx"
16 //using namespace MED_FR ;
18 template <class T> class FIELD;
20 // A QD LA CLASSE MED_ALL_ELEMENTS_DRIVER.... :) pour mutualiser le open ..... avec led _medIdt...
21 template <class T> class MED_FIELD_DRIVER : public GENDRIVER
26 MED_FR::med_idt _medIdt;
34 // all MED cell type ?? Classe de Définition ??
35 // static const medGeometryElement all_cell_type[MED_NBR_GEOMETRIE_MAILLE];
37 // static const char * const all_cell_type_tab [MED_NBR_GEOMETRIE_MAILLE];
39 MED_FIELD_DRIVER():GENDRIVER(),
40 _ptrField((FIELD<T> *)MED_NULL),_medIdt(MED_INVALID),
41 _fieldName(""),_fieldNum(MED_INVALID) {}
42 MED_FIELD_DRIVER(const string & fileName, FIELD<T> * ptrField,
43 med_mode_acces accessMode)
44 : GENDRIVER(fileName,accessMode),
45 _ptrField((FIELD<T> *) ptrField),_medIdt(MED_INVALID),
46 _fieldName(""),_fieldNum(MED_INVALID)
51 const char * LOC = "MED_FIELD_DRIVER::open() ";
54 // we must set fieldname before open, because we must find field number in file (if it exist !!!)
56 MESSAGE(LOC<<"_fileName.c_str : "<< _fileName.c_str()<<",mode : "<< _accessMode);
57 _medIdt = MED_FR::MEDouvrir( (const_cast <char *> (_fileName.c_str())),(MED_FR::med_mode_acces) _accessMode);
58 MESSAGE(LOC<<"_medIdt : "<< _medIdt );
59 if (_medIdt > 0) _status=MED_OPENED; else {
60 _status = MED_INVALID;
67 BEGIN_OF("MED_FIELD_DRIVER::close()");
68 MED_FR::med_int err = 0;
69 if (_status == MED_OPENED) {
70 err=MED_FR::MEDfermer(_medIdt);
73 _medIdt = MED_INVALID;
74 MESSAGE(" MED_FIELD_DRIVER::close() : MEDfermer : _medIdt= " << _medIdt );
75 MESSAGE(" MED_FIELD_DRIVER::close() : MEDfermer : err = " << err );
77 END_OF("MED_FIELD_DRIVER::close()");
80 virtual void write( void ) const = 0 ;
81 virtual void read ( void ) = 0 ;
82 void setFieldName(const string & fieldName) ;
83 string getFieldName() const ;
86 template <class T> class MED_FIELD_RDONLY_DRIVER : public virtual MED_FIELD_DRIVER<T>
91 MED_FIELD_RDONLY_DRIVER():MED_FIELD_DRIVER<T>() {};
93 MED_FIELD_RDONLY_DRIVER(const string & fileName, FIELD<T> * ptrField):
94 MED_FIELD_DRIVER<T>(fileName,ptrField,MED_RDONLY) {
95 BEGIN_OF("MED_FIELD_RDONLY_DRIVER::MED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
96 END_OF("MED_FIELD_RDONLY_DRIVER::MED_FIELD_RDONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
99 ~MED_FIELD_RDONLY_DRIVER() {
100 BEGIN_OF("MED_FIELD_RDONLY_DRIVER::~MED_FIELD_RDONLY_DRIVER()");
101 END_OF("MED_FIELD_RDONLY_DRIVER::~MED_FIELD_RDONLY_DRIVER()");
104 // CREER UNE METHODE POUR LIRE LA LISTE DES MAILLAGES .....
106 void write( void ) const ;
110 template <class T> class MED_FIELD_WRONLY_DRIVER : public virtual MED_FIELD_DRIVER<T> {
114 MED_FIELD_WRONLY_DRIVER():MED_FIELD_DRIVER<T>() {}
116 MED_FIELD_WRONLY_DRIVER(const string & fileName, FIELD<T> * ptrField):
117 MED_FIELD_DRIVER<T>(fileName,ptrField,MED_WRONLY)
119 BEGIN_OF("MED_FIELD_WRONLY_DRIVER::MED_FIELD_WRONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
120 END_OF("MED_FIELD_WRONLY_DRIVER::MED_FIELD_WRONLY_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
123 ~MED_FIELD_WRONLY_DRIVER() { }
125 void write( void ) const ;
130 template <class T> class MED_FIELD_RDWR_DRIVER : public MED_FIELD_RDONLY_DRIVER<T>, public MED_FIELD_WRONLY_DRIVER<T> {
134 MED_FIELD_RDWR_DRIVER():MED_FIELD_DRIVER<T>() {}
136 MED_FIELD_RDWR_DRIVER(const string & fileName, FIELD<T> * ptrField):
137 MED_FIELD_DRIVER<T>(fileName,ptrField,MED_RDWR)
139 BEGIN_OF("MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
140 END_OF("MED_FIELD_RDWR_DRIVER::MED_FIELD_RDWR_DRIVER(const string & fileName, const FIELD<T> * ptrField)");
143 ~MED_FIELD_RDWR_DRIVER() { }
145 void write(void) const ;
150 /*-------------------------*/
151 /* template implementation */
152 /*-------------------------*/
154 /*--------------------- DRIVER PART -------------------------------*/
156 template <class T> void MED_FIELD_DRIVER<T>::setFieldName(const string & fieldName)
158 _fieldName = fieldName;
161 template <class T> string MED_FIELD_DRIVER<T>::getFieldName() const
166 // template <class T> void MED_FIELD_DRIVER<T>::search_field() {
167 // const char * LOC = "template <class T> class MED_FIELD_DRIVER::search_field() :";
169 // // we search the field number !!!!
170 // if (_status==MED_OPENED)
171 // if (_fieldNum==MED_INVALID) {
173 // int numberOfFields = 0; //MED_INVALID
174 // // char fieldName[MED_TAILLE_NOM+1] = "";
175 // char fieldName[MED_TAILLE_NOM+1] ;
176 // int numberOfComponents = 0;
177 // char * componentName = (char *) MED_NULL;
178 // char * unitName = (char *) MED_NULL;
179 // MED_FR::med_type_champ type ;
180 // numberOfFields = MED_FR::MEDnChamp(_medIdt,0) ;
181 // if ( numberOfFields <= 0 )
182 // throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": No Field found !"));
183 // for (int i=1;i<=numberOfFields;i++) {
185 // numberOfComponents = MED_FR::MEDnChamp(_medIdt,i) ;
186 // if ( numberOfComponents <= 0 )
187 // throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
188 // << "Be careful there is no compound for field n°"
189 // << i << "in file |"<<_fileName<<"| !"));
191 // componentName = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;
192 // unitName = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;
194 // err = MED_FR::MEDchampInfo(_medIdt, i, fieldName, &type, componentName,
195 // unitName, numberOfComponents) ;
197 // delete[] componentName ;
198 // delete[] unitName ;
199 // MESSAGE("Champ "<<i<<" : #" << fieldName <<"# et recherche #"<<_fieldName.c_str()<<"#");
200 // if ( !strcmp(fieldName,_fieldName.c_str()) ) {
201 // MESSAGE("FOUND FIELD "<< fieldName <<" : "<<i);
209 /*--------------------- RDONLY PART -------------------------------*/
211 template <class T> void MED_FIELD_RDONLY_DRIVER<T>::read(void)
213 const char * LOC = " MED_FIELD_RDONLY_DRIVER::read() " ;
216 if (_ptrField->_name=="")
217 _ptrField->_name = _fieldName ;
219 _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 !!!!!
221 MESSAGE("###### "<<LOC<<" fieldNameDRIVER : "<<_fieldName<<" fieldName : "<<_ptrField->_name);
223 string MeshName = _ptrField->getSupport()->getMesh()->getName() ;
225 if (_status==MED_OPENED)
231 fieldName = new char[MED_TAILLE_NOM+1] ;
233 int numberOfComponents = 0;
234 char * componentName = (char *) MED_NULL;
235 char * unitName = (char *) MED_NULL;
236 MED_FR::med_type_champ type ;
238 // we search the field number !!!!
239 if (_fieldNum==MED_INVALID) {
240 int numberOfFields = 0; //MED_INVALID
241 numberOfFields = MED_FR::MEDnChamp(_medIdt,0) ;
242 if ( numberOfFields <= 0 )
243 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": No Field found !"));
244 for (int i=1;i<=numberOfFields;i++) {
246 numberOfComponents = MED_FR::MEDnChamp(_medIdt,i) ;
247 if ( numberOfComponents <= 0 )
248 // throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
249 // << "Be careful there is no compound for field n°"
250 // << i << "in file |"<<_fileName<<"| !"));
251 MESSAGE(LOC<<"Be careful there is no compound for field n°"<<i<<"in file |"<<_fileName<<"| !");
253 componentName = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;
254 unitName = new char[numberOfComponents*MED_TAILLE_PNOM+1] ;
256 err = MED_FR::MEDchampInfo(_medIdt, i, fieldName, &type, componentName,
257 unitName, numberOfComponents) ;
259 MESSAGE("Champ "<<i<<" : #" << fieldName <<"# et recherche #"<<_fieldName.c_str()<<"#");
260 if ( !strcmp(fieldName,_fieldName.c_str()) ) {
261 MESSAGE("FOUND FIELD "<< fieldName <<" : "<<i);
270 if (_fieldNum==MED_INVALID)
271 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) << ": Field "<<_fieldName << " not found in file " << _fileName ) );
272 MESSAGE ("FieldNum : "<<_fieldNum);
275 // int NumberOfComponents = MED_FR::MEDnChamp(_medIdt,_fieldNum) ;
276 if (numberOfComponents < 1)
277 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"no component")) ; // use iostring !
278 // test type to check if it is rigth !!!???
279 _ptrField->_numberOfComponents = numberOfComponents ;
280 _ptrField->_componentsTypes = new int[numberOfComponents] ;
281 _ptrField->_componentsNames = new string[numberOfComponents] ;
282 _ptrField->_componentsUnits = new UNIT[numberOfComponents] ;
283 _ptrField->_componentsDescriptions = new string[numberOfComponents] ;
284 _ptrField->_MEDComponentsUnits = new string[numberOfComponents] ;
285 for (int i=0; i<numberOfComponents; i++) {
286 _ptrField->_componentsTypes[i] = 1 ;
288 // PG : what about space !!!
289 _ptrField->_componentsNames[i] = string(componentName,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM) ;
290 SCRUTE(_ptrField->_componentsNames[i]);
291 _ptrField->_MEDComponentsUnits[i] = string(unitName,i*MED_TAILLE_PNOM,MED_TAILLE_PNOM) ;
292 SCRUTE(_ptrField->_MEDComponentsUnits[i]);
294 delete[] componentName;
297 // read values for each geometric type in _support
298 int NumberOfTypes = _ptrField->_support->getNumberOfTypes() ;
299 medGeometryElement *Types = _ptrField->_support->getTypes() ;
300 T ** myValues = new (T*)[NumberOfTypes] ;
301 int * NumberOfValues = new int[NumberOfTypes] ;
302 int TotalNumberOfValues = 0 ;
303 MESSAGE ("NumberOfTypes :"<< NumberOfTypes);
304 for (int i=0; i<NumberOfTypes; i++) {
305 MESSAGE ("Type["<<i+1<<"] :"<< Types[i]);
306 MESSAGE ("Entity :"<<_ptrField->_support->getEntity());
309 const_cast <char*> (_fieldName.c_str()),
310 (MED_FR::med_entite_maillage)_ptrField->_support->getEntity(),
311 (MED_FR::med_geometrie_element)Types[i],
312 _ptrField->_iterationNumber,
313 _ptrField->_orderNumber) ; // no time step ! prend en compte le nbre de pt de gauss
314 // test if NumberOfValues is the same in _support !!! TODO that !!
316 // we could allocate array
317 myValues[i] = new T[ NumberOfValues[i]*numberOfComponents ] ;
318 TotalNumberOfValues+=NumberOfValues[i] ;// diviser par le nombre de point de gauss
319 char * ProfilName = new char[MED_TAILLE_NOM+1];
320 MESSAGE ("NumberOfValues :"<< NumberOfValues[i]);
321 MESSAGE ("NumberOfComponents :"<< numberOfComponents);
322 MESSAGE ("MESH_NAME :"<< MeshName.c_str());
323 MESSAGE ("FIELD_NAME :"<< _fieldName.c_str());
324 MESSAGE ("MED_ENTITE :"<< (MED_FR::med_entite_maillage) _ptrField->_support->getEntity());
325 MESSAGE("MED_GEOM :"<<(MED_FR::med_geometrie_element)Types[i]);
326 MESSAGE("Iteration :"<<_ptrField->getIterationNumber());
327 MESSAGE("Order :"<<_ptrField->getOrderNumber());
328 if ( MED_FR::MEDchampLire(_medIdt,const_cast <char*> (MeshName.c_str()),
329 const_cast <char*> (_fieldName.c_str()),
330 (unsigned char*) myValues[i],
331 MED_FR::MED_NO_INTERLACE,
334 (MED_FR::med_entite_maillage) _ptrField->_support->getEntity(),(MED_FR::med_geometrie_element)Types[i],
335 _ptrField->getIterationNumber(),
336 _ptrField->getOrderNumber()
338 // we must do some delete !!!
339 _fieldNum = MED_INVALID ; // we have not found right field, so reset the field number
340 throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": ERROR when read value")) ;
343 delete[] ProfilName ;
346 // probleme avec les points de gauss : voir lorsqu-il y en a (!= 1)
347 // MEDARRAY<T> * Values = new MEDARRAY<T>(_ptrField->getNumberOfComponents(),TotalNumberOfValues/_ptrField->getNumberOfComponents(),MED_EN::MED_NO_INTERLACE);
349 if (_ptrField->_value==NULL)
350 _ptrField->_value=new MEDARRAY<T>(numberOfComponents,TotalNumberOfValues,MED_EN::MED_NO_INTERLACE);
352 MEDARRAY<T> * Values = _ptrField->_value ; // create by constructor ???
353 // check if dimensions are right
354 if (Values->getLeadingValue() != numberOfComponents)
355 throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": leading dimension are false : "<<Values->getLeadingValue()<<" and "<<numberOfComponents) ) ;
356 if (Values->getLengthValue() != TotalNumberOfValues)
357 throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": length dimension are false : "<<Values->getLengthValue()<<" and "<<TotalNumberOfValues) ) ;
359 for (int i=0; i<numberOfComponents; i++) {
360 T * ValuesT = Values->getI(MED_NO_INTERLACE,i+1) ;
362 for (int j=0; j<NumberOfTypes; j++) {
363 T * myValue = myValues[j] ;
364 int NumberOf = NumberOfValues[j] ;
365 int offset = NumberOf*i ;
366 for (int k=0 ; k<NumberOf; k++) {
367 ValuesT[Count]=myValue[k+offset] ;
373 for (int j=0; j<NumberOfTypes; j++)
374 delete[] myValues[j] ;
376 delete[] NumberOfValues ;
381 template <class T> void MED_FIELD_RDONLY_DRIVER<T>::write( void ) const
383 throw MEDEXCEPTION("MED_FIELD_RDONLY_DRIVER::write : Can't write with a RDONLY driver !");
386 /*--------------------- WRONLY PART -------------------------------*/
388 template <class T> void MED_FIELD_WRONLY_DRIVER<T>::read (void)
390 throw MEDEXCEPTION("MED_FIELD_WRONLY_DRIVER::write : Can't read with a WRONLY driver !");
393 template <class T> void MED_FIELD_WRONLY_DRIVER<T>::write(void) const
395 const char * LOC = "MED_FIELD_WRONLY_DRIVER::write(void) const " ;
397 if (_status==MED_OPENED)
401 int component_count=_ptrField->getNumberOfComponents();
402 string component_name(component_count*MED_TAILLE_PNOM,' ') ;
403 string component_unit(component_count*MED_TAILLE_PNOM,' ') ;
405 string * listcomponent_name=_ptrField->getComponentsNames() ;
406 string * listcomponent_unit=_ptrField->getMEDComponentsUnits() ;
408 for (int i=0; i < component_count ; i++) {
409 length = min(MED_TAILLE_PNOM,(int)listcomponent_name[i].size());
410 component_name.replace(i*MED_TAILLE_PNOM,length,
411 listcomponent_name[i],0,length);
412 length = min(MED_TAILLE_PNOM,(int)listcomponent_unit[i].size());
413 component_unit.replace(i*MED_TAILLE_PNOM,length,
414 listcomponent_unit[i],0,length);
417 MESSAGE("component_name=|"<<component_name<<"|");
418 MESSAGE("component_unit=|"<<component_unit<<"|");
420 MED_EN::med_type_champ ValueType=_ptrField->getValueType() ;
422 // le champ existe deja ???
423 char * champName = new char[MED_TAILLE_NOM+1] ;
424 MED_FR::med_type_champ type ;
428 int n = MED_FR::MEDnChamp(_medIdt,0);
430 for (int i=1; i<=n; i++) {
431 nbComp = MED_FR::MEDnChamp(_medIdt,i);
432 compName = new char[MED_TAILLE_PNOM*nbComp+1];
433 compUnit = new char[MED_TAILLE_PNOM*nbComp+1];
434 err = MED_FR::MEDchampInfo(_medIdt,i,champName,&type,compName,compUnit,nbComp);
436 if (strcmp(champName,_ptrField->getName().c_str())==0) { // Found !
446 if (nbComp != component_count)
447 throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
448 <<": Field exist in file, but number of component are different : "<<nbComp<<" in file and "<<component_count<<" in memory."
451 // component name and unit
452 MESSAGE(LOC<<" Component name in file : "<<compName);
453 MESSAGE(LOC<<" Component name in memory : "<<component_name);
454 MESSAGE(LOC<<" Component unit in file : "<<compUnit);
455 MESSAGE(LOC<<" Component unit in memory : "<<component_unit);
460 // Verify the field doesn't exist
462 string dataGroupName = "/CHA/";
463 dataGroupName += _ptrField->getName();
464 MESSAGE(LOC << "|" << dataGroupName << "|" );
465 med_idt gid = H5Gopen(_medIdt, dataGroupName.c_str() );
469 err=MED_FR::MEDchampCr(_medIdt,
470 const_cast <char*> ((_ptrField->getName()).c_str()),
471 (MED_FR::med_type_champ) ValueType,
472 const_cast <char*> ( component_name.c_str() ),
473 const_cast <char*> ( component_unit.c_str() ),
476 throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
477 << ": Error MEDchampCr : "<<err
484 const SUPPORT * mySupport = _ptrField->getSupport() ;
486 if (! mySupport->isOnAllElements())
487 throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
488 <<": Field must be on all entity"
492 MESH * myMesh = mySupport->getMesh() ;
493 string MeshName = myMesh->getName() ;
494 //MED_EN::medModeSwitch Mode = _ptrField->_value->getMode() ;
495 // on boucle sur tout les types pour ecrire les tableaux de valeur
496 int NumberOfType = mySupport->getNumberOfTypes() ;
498 medGeometryElement * Types = mySupport->getTypes() ;
499 int * NumberOfGaussPoint = mySupport->getNumberOfGaussPoint() ;
500 for (int i=0;i<NumberOfType;i++) {
501 int NumberOfElements = mySupport->getNumberOfElements(Types[i]) ;
503 MESSAGE(" "<<_ptrField->getName());
504 MESSAGE(" "<<NumberOfElements);
505 MESSAGE(" "<<NumberOfGaussPoint[i]);
506 MESSAGE(" "<<mySupport->getEntity());
507 MESSAGE(" "<<Types[i]);
508 MESSAGE(" "<<_ptrField->getIterationNumber());
509 MESSAGE(" "<<_ptrField->getTime());
510 MESSAGE(" "<<_ptrField->getOrderNumber());
511 MESSAGE("MEDchampEcr :"<<MeshName.c_str());
513 T * value = _ptrField->getValueI(MED_EN::MED_FULL_INTERLACE,Index) ;
515 err=MED_FR::MEDchampEcr(_medIdt, const_cast <char*> ( MeshName.c_str()) , //( string(mesh_name).resize(MED_TAILLE_NOM).c_str())
516 const_cast <char*> ( (_ptrField->getName()).c_str()),
517 (unsigned char*)value, MED_FR::MED_FULL_INTERLACE,
519 NumberOfGaussPoint[i],MED_ALL, MED_NOPFL, MED_FR::MED_REMP, // PROFIL NON GERE, mode de remplacement non géré
520 (MED_FR::med_entite_maillage)mySupport->getEntity(),
521 (MED_FR::med_geometrie_element)Types[i],
522 _ptrField->getIterationNumber()," ",
523 _ptrField->getTime(),_ptrField->getOrderNumber()
525 if (err < MED_VALID )
526 throw MEDEXCEPTION(LOCALIZED( STRING(LOC)
527 <<": Error in writing Field "<< _ptrField->getName() <<", type "<<Types[i]
530 Index += NumberOfElements ;
538 /*--------------------- RDWR PART -------------------------------*/
540 template <class T> void MED_FIELD_RDWR_DRIVER<T>::write(void) const
542 BEGIN_OF("MED_FIELD_RDWR_DRIVER::write(void)");
543 MED_FIELD_WRONLY_DRIVER<T>::write();
544 END_OF("MED_FIELD_RDWR_DRIVER::write(void)");
547 template <class T> void MED_FIELD_RDWR_DRIVER<T>::read (void)
549 BEGIN_OF("MED_FIELD_RDWR_DRIVER::read(void)");
550 MED_FIELD_RDONLY_DRIVER<T>::read();
551 END_OF("MED_FIELD_RDWR_DRIVER::read(void)");
554 /*-----------------------------------------------------------------*/
556 #endif /* MED_FIELD_DRIVER_HXX */