1 // MED MEDMEM : MED files in memory
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : MEDMEM_Med.cxx
30 # include "MEDMEM_Med.hxx"
32 # include "MEDMEM_STRING.hxx"
34 # include "MEDMEM_Mesh.hxx"
35 # include "MEDMEM_Grid.hxx"
36 # include "MEDMEM_Field.hxx"
38 # include "MEDMEM_Exception.hxx"
39 # include "utilities.h"
45 MESSAGE("MED::MED()");
51 MED::MED(driverTypes driverType, const string & fileName)
53 const char * LOC = "MED::MED(driverTypes driverType, const string & fileName) : ";
56 MED_MED_RDONLY_DRIVER * myDriver = new MED_MED_RDONLY_DRIVER(fileName,this) ;
57 int current = addDriver(*myDriver);
58 //int current= addDriver(driverType,fileName);
60 _drivers[current]->open();
61 _drivers[current]->readFileStruct();
62 _drivers[current]->close();
72 const char * LOC = "MED::~MED() : ";
75 // Analysis of the object MED
79 map<FIELD_ *, MESH_NAME_>::const_iterator currentField;
81 for ( currentField=_meshName.begin();currentField != _meshName.end(); currentField++ ) {
82 if ( (*currentField).first != NULL) index++;
85 MESSAGE(LOC << " there is(are) " << index << " field(s):");
86 for ( currentField=_meshName.begin();currentField != _meshName.end(); currentField++ ) {
87 if ( (*currentField).first != NULL) MESSAGE(" " << ((*currentField).first)->getName().c_str());
90 map<MESH_NAME_, map<MED_FR::med_entite_maillage,SUPPORT *> >::iterator itSupportOnMesh ;
92 for ( itSupportOnMesh=_support.begin();itSupportOnMesh != _support.end(); itSupportOnMesh++ ) {
93 map<MED_FR::med_entite_maillage,SUPPORT *>::iterator itSupport ;
94 for ( itSupport=(*itSupportOnMesh).second.begin();itSupport!=(*itSupportOnMesh).second.end();itSupport++)
98 MESSAGE(LOC << " there is(are) " << index << " support(s):");
100 map<MESH_NAME_,MESH*>::const_iterator currentMesh;
102 for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
103 if ( (*currentMesh).second != NULL)
107 MESSAGE(LOC << " there is(are) " << index << " meshe(s):");
108 // for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
109 // if ( (*currentMesh).second != NULL)
111 // SCRUTE((*currentMesh).second);
113 // string meshName = ((*currentMesh).second)->getName();
115 // MESSAGE(" " << meshName);
119 // delete all ? : PG : YES !
120 // map<FIELD_ *, MESH_NAME_>::const_iterator currentField;
121 for ( currentField=_meshName.begin();currentField != _meshName.end(); currentField++ ) {
122 if ( (*currentField).first != NULL) {
123 // cast in right type to delete it !
124 switch ((*currentField).first->getValueType()) {
126 // mpv: such recursive destructors call is problematic for current ALLIANCES algorithms
127 //delete (FIELD<int>*) (*currentField).first ;
130 // mpv: such recursive destructors call is problematic for current ALLIANCES algorithms
131 //delete (FIELD<double>*) (*currentField).first ;
134 INFOS("Field has type different of int or double, could not destroy its values array !") ;
135 // mpv: such recursive destructors call is problematic for current ALLIANCES algorithms
136 //delete (*currentField).first;
140 // map<MESH_NAME_, map<MED_FR::med_entite_maillage,SUPPORT *> >::iterator itSupportOnMesh ;
141 for ( itSupportOnMesh=_support.begin();itSupportOnMesh != _support.end(); itSupportOnMesh++ ) {
142 map<MED_FR::med_entite_maillage,SUPPORT *>::iterator itSupport ;
143 for ( itSupport=(*itSupportOnMesh).second.begin();itSupport!=(*itSupportOnMesh).second.end();itSupport++)
144 ;// mpv: such recursive destructors call is problematic for current ALLIANCES algorithms
145 //delete (*itSupport).second ;
148 // map<MESH_NAME_,MESH*>::const_iterator currentMesh;
149 for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
150 if ( (*currentMesh).second != NULL)
152 if (!((*currentMesh).second)->getIsAGrid())
153 ;// mpv: such recursive destructors call is problematic for current ALLIANCES algorithms
154 //delete (*currentMesh).second;
156 ;// mpv: such recursive destructors call is problematic for current ALLIANCES algorithms
157 //delete (GRID *) (*currentMesh).second;
161 index =_drivers.size();
163 MESSAGE(LOC << "In this object MED there is(are) " << index << " driver(s):");
165 for (int ind=0; ind < _drivers.size(); ind++ )
167 SCRUTE(_drivers[ind]);
168 if ( _drivers[ind] != NULL) delete _drivers[ind];
176 // ------- Drivers Management Part
178 // Add your new driver instance declaration here (step 3-1)
179 MED::INSTANCE_DE<MED_MED_RDWR_DRIVER> MED::inst_med ;
180 MED::INSTANCE_DE<VTK_MED_DRIVER> MED::inst_vtk ;
182 // Add your new driver instance in the MED instance list (step 3-2)
183 const MED::INSTANCE * const MED::instances[] = { &MED::inst_med, &MED::inst_vtk };
186 Create the specified driver and return its index reference to path to
187 read or write methods.
189 int MED::addDriver(driverTypes driverType, const string & fileName="Default File Name.med") {
191 const char * LOC = "MED::addDriver(driverTypes driverType, const string & fileName=\"Default File Name.med\") : ";
197 MESSAGE(LOC << " the file name is " << fileName);
198 driver = instances[driverType]->run(fileName, this) ;
199 current = _drivers.size()-1;
200 driver->setId(current);
207 Duplicate the given driver and return its index reference to path to
208 read or write methods.
210 int MED::addDriver(GENDRIVER & driver) {
211 const char * LOC = "MED::addDriver(GENDRIVER &) : ";
216 SCRUTE(_drivers.size());
218 _drivers.push_back(&driver);
220 SCRUTE(_drivers.size());
225 current = _drivers.size()-1;
226 driver.setId(current);
234 Remove the driver referenced by its index.
236 void MED::rmDriver (int index/*=0*/)
237 throw (MED_EXCEPTION)
239 const char * LOC = "MED::rmDriver (int index=0): ";
243 //_drivers.erase(&_drivers[index]);
246 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
247 << "The index given is invalid, index must be between 0 and |"
255 ??? to do comment ???
257 void MED::writeFrom (int index/*=0*/)
258 throw (MED_EXCEPTION)
260 const char * LOC = "MED::write (int index=0): ";
263 if (_drivers[index]) {
264 // open and close are made by all objects !
265 _drivers[index]->writeFrom();
267 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
268 << "The index given is invalid, index must be between 0 and |"
276 Write all objects with the driver given by its index.
278 void MED::write (int index/*=0*/)
279 throw (MED_EXCEPTION)
281 const char * LOC = "MED::write (int index=0): ";
284 if (_drivers[index]) {
285 // open and close are made by the subsequent objects !
286 _drivers[index]->write();
289 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
290 << "The index given is invalid, index must be between 0 and |"
298 Parse all the file and generate empty object.
300 All object must be read explicitly later with their own method read
301 or use MED::read to read all.
303 This method is automaticaly call by constructor with driver information.
305 void MED::readFileStruct (int index/*=0*/)
306 throw (MED_EXCEPTION)
308 const char * LOC = "MED::readFileStruct (int index=0): ";
311 if (_drivers[index]) {
312 _drivers[index]->open();
313 _drivers[index]->readFileStruct();
314 _drivers[index]->close();
317 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
318 << "The index given is invalid, index must be between 0 and |"
326 Read all objects in the file specified in the driver given by its index.
328 void MED::read (int index/*=0*/)
329 throw (MED_EXCEPTION)
331 const char * LOC = "MED::read (int index=0): ";
334 if (_drivers[index]) {
335 // open and close are made by all objects !
337 SCRUTE(_drivers[index]);
338 SCRUTE(&_drivers[index]);
339 // _drivers[index]->open();
340 _drivers[index]->read();
341 // _drivers[index]->close();
344 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
345 << "The index given is invalid, index must be between >0 and < |"
353 // ------- End Of Drivers Management Part
356 Get the number of MESH objects.
358 int MED::getNumberOfMeshes ( void ) const {
360 const char * LOC = "MED::getNumberOfMeshes ( void ) const : ";
363 return _meshes.size();
369 Get the number of FIELD objects.
371 int MED::getNumberOfFields ( void ) const {
373 const char * LOC = "MED::getNumberOfFields ( void ) const : ";
376 return _fields.size(); // we get number of field with different name
382 Get the names of all MESH objects.
384 meshNames is an in/out argument.
386 It is a string array of size the
387 number of MESH objects. It must be allocated before calling
388 this method. All names are put in it.
390 void MED::getMeshNames ( string * meshNames ) const
391 throw (MED_EXCEPTION)
393 const char * LOC = "MED::getMeshNames ( string * ) const : ";
397 if ( ( meshNamesSize = sizeof(meshNames) / sizeof(string *) )
399 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
400 << "Size of parameter meshNames is |"
401 << meshNamesSize << "| and should be |"
402 << _meshes.size() << "| and should be |"
406 // REM : ALLOCATION D'UN TABLEAU DE POINTEURS SUR STRING FAITE PAR LE CLIENT
407 map<MESH_NAME_,MESH*>::const_iterator currentMesh; // ??ITERATEUR CONST SUR UN OBJET NON CONST ??
409 int meshNamesIndex = 0;
411 for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
412 meshNames[meshNamesIndex]=(*currentMesh).first;
413 meshNamesIndex++; // CF OPTIMISATION
420 Get the names of all MESH objects.
422 Return a deque<string> object which contain the name of all MESH objects.
424 deque<string> MED::getMeshNames () const {
426 const char * LOC = "MED::getMeshNames () const : ";
429 deque<string> meshNames(_meshes.size());
431 map<MESH_NAME_,MESH*>::const_iterator currentMesh; // ??ITERATEUR CONST SUR UN OBJET NON CONST ??
433 int meshNamesIndex = 0;
435 for ( currentMesh=_meshes.begin();currentMesh != _meshes.end(); currentMesh++ ) {
436 meshNames[meshNamesIndex]=(*currentMesh).first;
437 meshNamesIndex++; // CF OPTIMISATION
446 Return a reference to the MESH object named meshName.
448 MESH * MED::getMesh ( const string & meshName ) const
449 throw (MED_EXCEPTION)
452 const char * LOC = "MED::getMesh ( const string & meshName ) const : ";
455 map<MESH_NAME_,MESH*>::const_iterator itMeshes = _meshes.find(meshName);
457 if ( itMeshes == _meshes.end() )
458 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
459 << "There is no known mesh named |"
464 return (*itMeshes).second;
470 \internal Return a reference to the MESH object associated with
473 MESH * MED::getMesh (const FIELD_ * const field ) const
474 throw (MED_EXCEPTION)
477 const char * LOC = "MED::getMesh ( const FIELD * field ) const : ";
480 FIELD_ * f = const_cast< FIELD_* > (field); // Comment faire mieux ?
481 map<FIELD_ *, MESH_NAME_>::const_iterator itMeshName = _meshName.find(f);
483 if ( itMeshName == _meshName.end() )
484 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
485 << "There is no known mesh associated with |"
486 << field << "| pointer"
490 string meshName = (*itMeshName).second;
491 map<MESH_NAME_,MESH*>::const_iterator itMeshes = _meshes.find(meshName);
492 if ( itMeshes == _meshes.end() )
493 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
494 << "There is no known mesh named |"
495 << meshName << " while it's associated with the found field |"
496 << field << "| pointer"
500 return (*itMeshes).second;
507 Get the names of all FIELD objects.
509 fieldNames is an in/out argument.
511 It is an array of string of size the
512 number of FIELD objects. It must be allocated before calling
513 this method. All names are put in it.
515 void MED::getFieldNames ( string * fieldNames ) const
516 throw (MED_EXCEPTION)
518 const char * LOC = "MED::getFieldNames ( string * ) const : ";
521 int fieldNamesSize = sizeof(fieldNames) / sizeof(string *);
523 if ( fieldNamesSize != _fields.size() )
524 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
525 << "Size of parameter fieldNames is |"
526 << fieldNamesSize << "| and should be |"
527 << _fields.size() << "| and should be |"
531 // REM : ALLOCATION D'UN TABLEAU DE POINTEURS SUR STRING FAITE PAR LE CLIENT
532 map<FIELD_NAME_,MAP_DT_IT_>::const_iterator currentField;
534 int fieldNamesIndex = 0;
535 for ( currentField=_fields.begin();currentField != _fields.end(); currentField++ ) {
536 fieldNames[fieldNamesIndex]=(*currentField).first;
537 fieldNamesIndex++; // CF OPTIMISATION
545 Get the names of all FIELD objects.
547 Return a deque<string> object which contain the name of all FIELD objects.
549 deque<string> MED::getFieldNames () const {
551 const char * LOC = "MED::getFieldNames ( ) const : ";
554 deque<string> fieldNames(_fields.size());
556 map<FIELD_NAME_,MAP_DT_IT_>::const_iterator currentField;
558 int fieldNamesIndex = 0;
560 for ( currentField=_fields.begin();currentField != _fields.end(); currentField++ ) {
561 fieldNames[fieldNamesIndex]=(*currentField).first;
562 fieldNamesIndex++; // CF OPTIMISATION
570 Return a deque<DT_IT_> which contain all iteration step for the FIELD
571 identified by its name.
573 deque<DT_IT_> MED::getFieldIteration (const string & fieldName) const
574 throw (MED_EXCEPTION)
577 const char * LOC = "MED::getFieldIteration ( const string & ) const : ";
580 map<FIELD_NAME_,MAP_DT_IT_>::const_iterator itFields = _fields.find(fieldName);
582 if ( itFields == _fields.end() )
583 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
584 << "There is no known field named |"
588 // const MAP_DT_IT_ & myIterationMap = const_cast<const MAP_DT_IT_ & > ((*itFields).second);
589 const MAP_DT_IT_ & myIterationMap = (*itFields).second ;
590 MAP_DT_IT_::const_iterator currentIterator ;
592 deque<DT_IT_> Iteration(myIterationMap.size());
594 int iterationIndex = 0;
596 for ( currentIterator=myIterationMap.begin();currentIterator != myIterationMap.end(); currentIterator++ ) {
597 Iteration[iterationIndex]=(*currentIterator).first;
598 iterationIndex++; // CF OPTIMISATION
606 Return a reference to the FIELD object named fieldName with
607 time step number dt and order number it.
609 FIELD_ * MED::getField ( const string & fieldName, const int dt=MED_NOPDT, const int it=MED_NOPDT ) const
610 throw (MED_EXCEPTION)
613 const char * LOC = "MED::getField ( const string &, const int, const int ) const : ";
616 MESSAGE(LOC << "fieldName = "<<fieldName<<", dt ="<<dt<<", it = "<<it);
623 map<FIELD_NAME_,MAP_DT_IT_>::const_iterator itFields = _fields.find(fieldName);
625 if ( itFields == _fields.end() )
626 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
627 << "There is no known field named |"
632 const MAP_DT_IT_ & map_dtIt = const_cast<const MAP_DT_IT_ & > ((*itFields).second);
633 MAP_DT_IT_::const_iterator itMap_dtIt = map_dtIt.find(dtIt);
635 if ( itMap_dtIt == map_dtIt.end() )
636 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
637 << "There is no (dt,it) |("
638 << dt << "," << it << ")| associated with the found field |"
645 //return _fields[fieldName][dtIt];
646 return (*itMap_dtIt).second;
651 // fiend ostream & MED::operator<<(ostream &os,const MED & med) const {
656 Return a map<MED_FR::med_entite_maillage,SUPPORT*> which contain
657 foreach entity, a reference to the SUPPORT on all elements.
659 const map<MED_FR::med_entite_maillage,SUPPORT*> & MED::getSupports(const string & meshName) const
660 throw (MED_EXCEPTION)
662 const char * LOC = "MED::getSupports ( const string ) const : ";
665 map<MESH_NAME_, map<MED_FR::med_entite_maillage,SUPPORT *> >::const_iterator itSupportOnMesh = _support.find(meshName) ;
667 if ( itSupportOnMesh == _support.end() )
668 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
669 << "There is no support on mesh named |"
674 return (*itSupportOnMesh).second ;
678 Return a reference to the SUPPORT object on all elements of entity
679 for the MESH named meshName.
681 SUPPORT * MED::getSupport (const string & meshName,MED_FR::med_entite_maillage entity) const
682 throw (MED_EXCEPTION)
684 const char * LOC = "MED::getSupport ( const string, MED_FR::med_entite_maillage ) const : ";
687 map<MESH_NAME_, map<MED_FR::med_entite_maillage,SUPPORT *> >::const_iterator itSupportOnMesh = _support.find(meshName) ;
689 if ( itSupportOnMesh == _support.end() )
690 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
691 << "There is no support on mesh named |"
696 map<MED_FR::med_entite_maillage,SUPPORT *> & SupportOnMesh = (map<MED_FR::med_entite_maillage,SUPPORT *>&) ((*itSupportOnMesh).second) ;
697 map<MED_FR::med_entite_maillage,SUPPORT *>::const_iterator itSupport = SupportOnMesh.find(entity) ;
699 if (itSupport == SupportOnMesh.end() )
700 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
701 << "There is no support on entity "
702 << entity << " in mesh named |"
707 return (*itSupport).second ;
711 Temporary method : when all MESH objects are read, this methods
712 update all SUPPORT objects with the rigth dimension.
714 void MED::updateSupport ()
717 const char * LOC = "MED::updateSupport () : ";
720 map<MESH_NAME_, map<MED_FR::med_entite_maillage,SUPPORT *> >::iterator itSupportOnMesh ;
721 for ( itSupportOnMesh=_support.begin();itSupportOnMesh != _support.end(); itSupportOnMesh++ ) {
722 map<MED_FR::med_entite_maillage,SUPPORT *>::iterator itSupport ;
723 for ( itSupport=(*itSupportOnMesh).second.begin();itSupport!=(*itSupportOnMesh).second.end();itSupport++)
725 (*itSupport).second->update() ;
727 catch (MEDEXCEPTION & ex) {
728 // entity not defined in mesh -> we remove support on it !
729 MESSAGE(LOC<<ex.what());
730 delete (*itSupport).second ;
731 (*itSupportOnMesh).second.erase(itSupport) ; // that's rigth ????
740 Add the given MESH object. MED object control it,
741 and destroy it, so you must not destroy it after.
743 The meshName is given by the MESH object.
745 void MED::addMesh( MESH * const ptrMesh)
746 throw (MED_EXCEPTION)
748 const char * LOC = "MED::addMesh(const MESH * ptrMesh): ";
752 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrMesh must not be NULL !"));
755 if ( ! ( meshName = ptrMesh->getName()).size() )
756 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrMesh->_name must not be NULL !"));
758 _meshes[meshName] = ptrMesh; // if ptrMesh->meshName already exists it is modified
764 Add the given FIELD object. MED object control it,
765 and destroy it, so you must not destroy it after.
767 The fieldName is given by the FIELD object.
769 void MED::addField( FIELD_ * const ptrField)
770 throw (MED_EXCEPTION)
772 const char * LOC = "MED::addField(const FIELD_ * const ptrField): ";
776 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField must not be NULL !"));
779 if ( ! (fieldName = ptrField->getName()).size() )
780 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_name must not be NULL !"));
782 SUPPORT * ptrSupport;
783 if ( ! ( ptrSupport = (SUPPORT * ) ptrField->getSupport()) )
784 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_support must not be NULL !"));
787 if ( ! ( ptrMesh = ptrSupport->getMesh()) )
788 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_support->_mesh must not be NULL !"));
791 if ( ! ( meshName = ptrMesh->getName()).size() )
792 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC) << "ptrField->_support->_mesh->_name must not be NULL !"));
795 dtIt.dt = ptrField->getIterationNumber();
796 dtIt.it = ptrField->getOrderNumber();
798 _fields [fieldName][dtIt] = ptrField; // if it already exists it is replaced
799 _meshName [ptrField] = meshName; // if it already exists it is replaced
800 _meshes [meshName] = ptrMesh; // if it already exists it is replaced
802 int numberOfTypes = ptrSupport->getNumberOfTypes();
803 _support [meshName][ (MED_FR::med_entite_maillage) ptrSupport->getEntity()] = ptrSupport;// if it already exists it is replaced