1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #ifndef MED_FIELD_DRIVER22_HXX
21 #define MED_FIELD_DRIVER22_HXX
26 #include "MEDMEM_FieldConvert.hxx"
27 #include "MEDMEM_ArrayInterface.hxx"
28 #include "MEDMEM_ArrayConvert.hxx"
30 #include "MEDMEM_define.hxx"
31 #include "MEDMEM_Utilities.hxx"
32 #include "MEDMEM_STRING.hxx"
33 #include "MEDMEM_Exception.hxx"
35 #include "MEDMEM_DriversDef.hxx"
36 #include "MEDMEM_MedFieldDriver.hxx"
37 #include "MEDMEM_Unit.hxx"
38 #include "MEDMEM_Support.hxx"
39 #include "MEDMEM_GaussLocalization.hxx"
47 Generic part : implement open and close methods.
51 template <class T> class MED_FIELD_DRIVER22 : public virtual MED_FIELD_DRIVER<T>
55 med_2_3::med_idt _medIdt;
57 bool createFieldSupportPart1(med_2_3::med_idt id,
58 const string & fieldName,
63 vector<int> & numberOfElementsOfTypeC,
64 vector<int> & numberOfGaussPoint,
65 int & totalNumberOfElWg
66 ) const throw (MEDEXCEPTION);
68 void getMeshGeometricTypeFromFile(med_2_3::med_idt id,
70 MED_EN::medEntityMesh entite,
71 vector<MED_EN::medGeometryElement> & geoType,
72 vector<int> &nbOfElOfType,
73 vector<int> &nbOfElOfTypeC) const throw(MEDEXCEPTION);
75 void getMeshGeometricTypeFromMESH( MESH * meshPtr,
76 MED_EN::medEntityMesh entity,
77 vector<MED_EN::medGeometryElement> & geoType,
78 vector<int> &nbOfElOfType,
79 vector<int> &nbOfElOfTypeC) const throw(MEDEXCEPTION);
86 MED_FIELD_DRIVER22():MED_FIELD_DRIVER<T>(),_medIdt(MED_INVALID)
91 template <class INTERLACING_TAG>
92 MED_FIELD_DRIVER22(const string & fileName,
93 FIELD<T, INTERLACING_TAG> * ptrField,
94 MED_EN::med_mode_acces accessMode)
95 : MED_FIELD_DRIVER<T>(fileName,ptrField,accessMode),_medIdt(MED_INVALID)
102 MED_FIELD_DRIVER22(const MED_FIELD_DRIVER22 & fieldDriver):
103 MED_FIELD_DRIVER<T>(fieldDriver),
104 _medIdt(fieldDriver._medIdt)
111 virtual ~MED_FIELD_DRIVER22() {
114 void open() throw (MEDEXCEPTION)
116 const char * LOC = "MED_FIELD_DRIVER22::open() ";
119 // we must set fieldname before open, because we must find field number in file (if it exist !!!)
120 if ( MED_FIELD_DRIVER<T>::_fileName == "" )
121 throw MED_EXCEPTION ( LOCALIZED( STRING(LOC)
122 << "_fileName is |\"\"|, please set a correct fileName before calling open()"
126 MESSAGE(LOC<<"_fileName.c_str : "<< MED_FIELD_DRIVER<T>::_fileName.c_str()<<",mode : "<< MED_FIELD_DRIVER<T>::_accessMode);
127 MED_FIELD_DRIVER22<T>::_medIdt = med_2_3::MEDouvrir( (const_cast <char *> (MED_FIELD_DRIVER<T>::_fileName.c_str())),(med_2_3::med_mode_acces) MED_FIELD_DRIVER<T>::_accessMode);
128 MESSAGE(LOC<<"_medIdt : "<< MED_FIELD_DRIVER22<T>::_medIdt );
129 if (MED_FIELD_DRIVER22<T>::_medIdt > 0)
130 MED_FIELD_DRIVER<T>::_status=MED_OPENED;
132 MED_FIELD_DRIVER<T>::_status = MED_INVALID;
133 MED_FIELD_DRIVER22<T>::_medIdt = MED_INVALID;
134 throw MED_EXCEPTION (LOCALIZED( STRING(LOC)
135 << "Can't open |" << MED_FIELD_DRIVER<T>::_fileName
136 << "|, _medIdt : " << MED_FIELD_DRIVER22<T>::_medIdt
145 BEGIN_OF("MED_FIELD_DRIVER22::close()");
146 med_2_3::med_int err = 0;
147 if (MED_FIELD_DRIVER<T>::_status == MED_OPENED) {
148 err=med_2_3::MEDfermer(MED_FIELD_DRIVER22<T>::_medIdt);
149 //H5close(); // If we call H5close() all the files are closed.
150 MED_FIELD_DRIVER<T>::_status = MED_CLOSED;
151 MED_FIELD_DRIVER22<T>::_medIdt = MED_INVALID;
152 MESSAGE(" MED_FIELD_DRIVER22::close() : MEDfermer : _medIdt= " << MED_FIELD_DRIVER22<T>::_medIdt );
153 MESSAGE(" MED_FIELD_DRIVER22::close() : MEDfermer : err = " << err );
155 END_OF("MED_FIELD_DRIVER22::close()");
161 Driver Med for FIELD : Read only.
163 Implement read method.
167 template <class T> class MED_FIELD_RDONLY_DRIVER22 : public virtual MED_FIELD_DRIVER22<T>, public virtual IMED_FIELD_RDONLY_DRIVER<T>
175 MED_FIELD_RDONLY_DRIVER22():MED_FIELD_DRIVER<T>() {};
180 template <class INTERLACING_TAG>
181 MED_FIELD_RDONLY_DRIVER22(const string & fileName,
182 FIELD<T, INTERLACING_TAG> * ptrField):
183 IMED_FIELD_RDONLY_DRIVER<T>(fileName,ptrField),
184 MED_FIELD_DRIVER22<T>(fileName,ptrField,MED_EN::MED_RDONLY),
185 MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_RDONLY)
187 BEGIN_OF("MED_FIELD_RDONLY_DRIVER22::MED_FIELD_RDONLY_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)");
188 END_OF("MED_FIELD_RDONLY_DRIVER22::MED_FIELD_RDONLY_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)");
194 MED_FIELD_RDONLY_DRIVER22(const MED_FIELD_RDONLY_DRIVER22 & fieldDriver):
195 IMED_FIELD_RDONLY_DRIVER<T>(fieldDriver),
196 MED_FIELD_DRIVER22<T>(fieldDriver),
197 MED_FIELD_DRIVER<T>(fieldDriver)
203 virtual ~MED_FIELD_RDONLY_DRIVER22() {};
205 // CREER UNE METHODE POUR LIRE LA LISTE DES MAILLAGES .....
208 Return a MEDEXCEPTION : it is the read-only driver.
210 void write( void ) const throw (MEDEXCEPTION) ;
212 Read FIELD in the specified file.
214 void read ( void ) throw (MEDEXCEPTION) ;
217 GENDRIVER * copy( void ) const ;
223 Driver Med for FIELD : Write only.
225 Implement write method.
229 template <class T> class MED_FIELD_WRONLY_DRIVER22 : public virtual MED_FIELD_DRIVER22<T>, public virtual IMED_FIELD_WRONLY_DRIVER<T> {
236 MED_FIELD_WRONLY_DRIVER22():MED_FIELD_DRIVER<T>() {}
241 template <class INTERLACING_TAG>
242 MED_FIELD_WRONLY_DRIVER22(const string & fileName,
243 FIELD<T, INTERLACING_TAG> * ptrField):
244 IMED_FIELD_WRONLY_DRIVER<T>(fileName,ptrField),
245 MED_FIELD_DRIVER22<T>(fileName,ptrField,MED_EN::MED_WRONLY),
246 MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_WRONLY)
248 BEGIN_OF("MED_FIELD_WRONLY_DRIVER22::MED_FIELD_WRONLY_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)");
249 END_OF("MED_FIELD_WRONLY_DRIVER22::MED_FIELD_WRONLY_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)");
255 MED_FIELD_WRONLY_DRIVER22(const MED_FIELD_WRONLY_DRIVER22 & fieldDriver):
256 IMED_FIELD_WRONLY_DRIVER<T>(fieldDriver),
257 MED_FIELD_DRIVER22<T>(fieldDriver),
258 MED_FIELD_DRIVER<T>(fieldDriver)
264 virtual ~MED_FIELD_WRONLY_DRIVER22() {};
267 Write FIELD in the specified file.
269 void write( void ) const throw (MEDEXCEPTION) ;
271 Return a MEDEXCEPTION : it is the write-only driver.
273 void read ( void ) throw (MEDEXCEPTION) ;
276 GENDRIVER * copy( void ) const ;
283 Driver Med for FIELD : Read write.
284 - Use read method from MED_FIELD_RDONLY_DRIVER
285 - Use write method from MED_FIELD_WDONLY_DRIVER
289 template <class T> class MED_FIELD_RDWR_DRIVER22 : public MED_FIELD_RDONLY_DRIVER22<T>, public MED_FIELD_WRONLY_DRIVER22<T>, public IMED_FIELD_RDWR_DRIVER<T> {
296 MED_FIELD_RDWR_DRIVER22():MED_FIELD_DRIVER22<T>() {}
301 template <class INTERLACING_TAG>
302 MED_FIELD_RDWR_DRIVER22(const string & fileName,
303 FIELD<T, INTERLACING_TAG> * ptrField):
304 MED_FIELD_WRONLY_DRIVER22<T>(fileName,ptrField),
305 MED_FIELD_RDONLY_DRIVER22<T>(fileName,ptrField),
306 IMED_FIELD_RDONLY_DRIVER<T>(fileName,ptrField),
307 IMED_FIELD_WRONLY_DRIVER<T>(fileName,ptrField),
308 MED_FIELD_DRIVER<T>(fileName,ptrField,MED_EN::MED_RDWR),
309 IMED_FIELD_RDWR_DRIVER<T>(fileName,ptrField)
311 BEGIN_OF("MED_FIELD_RDWR_DRIVER22::MED_FIELD_RDWR_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)");
312 //_accessMode = MED_RDWR ;
313 END_OF("MED_FIELD_RDWR_DRIVER22::MED_FIELD_RDWR_DRIVER22(const string & fileName, const FIELD<T,INTERLACING_TAG> * ptrField)");
319 MED_FIELD_RDWR_DRIVER22(const MED_FIELD_RDWR_DRIVER22 & fieldDriver):
320 MED_FIELD_WRONLY_DRIVER22<T>(fieldDriver),
321 MED_FIELD_RDONLY_DRIVER22<T>(fieldDriver),
322 IMED_FIELD_RDWR_DRIVER<T>(fieldDriver),
323 IMED_FIELD_RDONLY_DRIVER<T>(fieldDriver),
324 IMED_FIELD_WRONLY_DRIVER<T>(fieldDriver),
325 MED_FIELD_DRIVER<T>(fieldDriver)
331 ~MED_FIELD_RDWR_DRIVER22() {};
334 Write FIELD in the specified file.
336 void write(void) const throw (MEDEXCEPTION) ;
338 Read FIELD in the specified file.
340 void read (void) throw (MEDEXCEPTION) ;
343 GENDRIVER * copy( void ) const ;
348 /*-------------------------*/
349 /* template implementation */
350 /*-------------------------*/
352 /*--------------------- DRIVER PART -------------------------------*/
357 Cette méthode crée le SUPPORT du champ <fieldName> pour le
358 <n°de pas de temps,n°d'itération>=<ndt,od>.
360 Le SUPPORT crée à pour nom <fieldName>Support et contient
361 la liste des types géométriques sur le premier type
362 d'entité trouvé (en MEDMEM on inderdit aux champs de reposer
363 sur plusieurs types d'entité).
364 Il contient également le nombre d'entités trouvées pour chaque
366 Par défaut l'attribut onAll du SUPPORT est positionné à true car
367 cette routine ne lit rien de ce qui concerne les entités
369 La méthode renvoie true si elle réussit à créer le SUPPORT
371 Le nom du maillage associé ( en MEDMEM on ne
372 supporte pas encore les maillages multiples ) est renvoyé dans <meshName>.
373 Deux tableaux directements exploitables par MEDMEMnArray sont renvoyés :
374 - numberOfElementsOfTypeC : nombres d'entités cumulés de chaque type géométrique
375 avec numberOfElementsOfTypeC[0]=1 et de taille nombre de types+1
376 - numberOfGaussPoint : nombre de points de Gauss par type géométrique
377 avec numberOfGaussPoint[0]=1 et de taille nombre de types+1
380 template <class T> bool
381 MED_FIELD_DRIVER22<T>::createFieldSupportPart1(med_2_3::med_idt id,
382 const string & fieldName,
383 med_2_3::med_int ndt,
387 vector<int> & numberOfElementsOfTypeC,
388 vector<int> & numberOfGaussPoint,
389 int & totalNumberOfElWg
390 ) const throw (MEDEXCEPTION)
393 //EF : Gérer le meshName pour le driver 2.2
394 const char * LOC="MED_FIELD_DRIVER<T>::createFieldSupportPart1(...)";
398 map<int, list<MED_EN::medGeometryElement> > CellAndNodeEntities;
399 map<int, list<MED_EN::medGeometryElement> >::iterator currentEntity;
400 CellAndNodeEntities[MED_EN::MED_CELL] = MED_EN::meshEntities[MED_EN::MED_CELL];
401 CellAndNodeEntities[MED_EN::MED_NODE] = MED_EN::meshEntities[MED_EN::MED_NODE];
402 list< MED_EN::medGeometryElement >::const_iterator currentGeometry;
404 MED_EN::medEntityMesh entityCurrent;
405 MED_EN::medGeometryElement geometryCurrent;
407 MED_EN::medEntityMesh entity;
408 bool alreadyFoundAnEntity=false,alreadyFoundPdtIt = false;
409 int numberOfElements = 0;
410 int numberOfGeometricType = 0;
411 MED_EN::medGeometryElement geometricType[MED_NBR_GEOMETRIE_MAILLE];
412 int numberOfElementsOfType[MED_NBR_GEOMETRIE_MAILLE];
413 numberOfElementsOfTypeC.clear();numberOfGaussPoint.clear();
414 numberOfElementsOfTypeC.resize(MED_NBR_GEOMETRIE_MAILLE+1);
415 numberOfGaussPoint.resize(MED_NBR_GEOMETRIE_MAILLE+1);
417 med_2_3::med_int nmaa=0, ngauss=0, numdt=-1, numo=-1, nbPdtIt=0, nbPdtIt1=0, nbPdtIt2=0;
418 char dtunit[MED_TAILLE_PNOM22+1];
419 char maa[MED_TAILLE_NOM+1];
420 med_2_3::med_float dt=-1.0;
421 med_2_3::med_booleen local;
422 med_2_3::med_err ret=1;
423 numberOfElementsOfTypeC[0] = 1;
424 numberOfGaussPoint[0] = 1;
425 totalNumberOfElWg = 0;
427 /* Détermine le type d'entité et la liste des types géométriques associés
428 au champ <fieldName> */
429 for (currentEntity = CellAndNodeEntities.begin();
430 currentEntity != CellAndNodeEntities.end(); currentEntity++) {
431 for (currentGeometry = (*currentEntity).second.begin();
432 currentGeometry != (*currentEntity).second.end(); currentGeometry++) {
434 entityCurrent = (*currentEntity).first ;
435 geometryCurrent = (*currentGeometry) ;
437 // That is a difference between Med File and Med Memory (NB)
438 if (geometryCurrent == MED_EN::MED_SEG2 || geometryCurrent == MED_EN::MED_SEG3)
439 entityCurrent = MED_EN::MED_EDGE;
441 if (geometryCurrent == MED_EN::MED_TRIA3 || geometryCurrent == MED_EN::MED_QUAD4 ||
442 geometryCurrent == MED_EN::MED_TRIA6 || geometryCurrent == MED_EN::MED_QUAD8 ||
443 geometryCurrent == MED_EN::MED_POLYGON)
444 entityCurrent = MED_EN::MED_FACE;
446 nbPdtIt1 = med_2_3::MEDnPasdetemps(id, const_cast <char*> ( fieldName.c_str() ),
447 (med_2_3::med_entite_maillage) (*currentEntity).first,
448 (med_2_3::med_geometrie_element) *currentGeometry );
450 nbPdtIt2 = med_2_3::MEDnPasdetemps(id, const_cast <char*> ( fieldName.c_str() ),
451 (med_2_3::med_entite_maillage) entityCurrent,
452 (med_2_3::med_geometrie_element) geometryCurrent );
454 if (nbPdtIt2 < nbPdtIt1) entityCurrent = (*currentEntity).first ;
456 nbPdtIt = (nbPdtIt1>nbPdtIt2)?nbPdtIt1:nbPdtIt2;
461 /* Verifie que le champ n'est pas défini sur un autre type d'entité */
462 if ( alreadyFoundAnEntity )
464 //if (entity != (*currentEntity).first ) (NB)
465 if ( entity != entityCurrent )
466 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName
467 << "| with (ndt,or) = (" << ndt << ","
468 << od << ") must not be defined on nodes and cells" ));
473 //entity=(*currentEntity).first; (NB)
474 entity=entityCurrent;
475 alreadyFoundAnEntity = true;
479 /* Cherche le champ pour le <ndt>,<ot> demandé et détermine le nombre de points de Gauss*/
480 ret = 0; alreadyFoundPdtIt = false; ngauss =0;
481 for ( med_2_3::med_int j=1; j <= nbPdtIt; j++ ) {
483 // Search how many <ngauss> (<fieldName>,<ndt>,<ot>) has (NB)
484 //ret += med_2_3::MEDpasdetempsInfo(id, const_cast <char*> ( fieldName.c_str() ),
485 // (med_2_3::med_entite_maillage) (*currentEntity).first,
486 // (med_2_3::med_geometrie_element) *currentGeometry,
487 // j, &ngauss, &numdt, &numo, dtunit, &dt,
488 // maa, &local, &nmaa);
490 ret += med_2_3::MEDpasdetempsInfo(id, const_cast <char*> ( fieldName.c_str() ),
491 (med_2_3::med_entite_maillage) entityCurrent,
492 (med_2_3::med_geometrie_element) *currentGeometry,
493 j, &ngauss, &numdt, &numo, dtunit, &dt,
496 MED_FIELD_DRIVER<T>::_ptrField->setTime(dt); // PAL12664
498 if ( ndt == numdt && numo == od ) {
499 alreadyFoundPdtIt = true;
502 MESSAGE(LOC<<" Field |" << fieldName << "| with (ndt,or) = ("
503 << ndt << "," << od << ") for (entityType,geometricType)=("
504 << MED_EN::entNames[entityCurrent] << ","
505 << MED_EN::geoNames[*currentGeometry] << ")"
506 << "is defined on multiple meshes, using dafault mesh |" << maa << "|" );
510 MESSAGE(" Field |" << fieldName << "| with (ndt,or) = ("
511 << ndt << "," << od << ") for (entityType,geometricType)=("
512 << MED_EN::entNames[entityCurrent] << ","
513 << MED_EN::geoNames[*currentGeometry] << ")"
514 << "is using a mesh on a distant file (ignored)" );
516 // throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = ("
517 // << ndt << "," << od << ") for (entityType,geometricType)=("
518 // << MED_EN::entNames[(*currentEntity).first] << ","
519 // << MED_EN::geoNames[*currentGeometry] << ")"
520 // << "is using a mesh on a different file which is not yet supported" ));
523 if ( ! meshName.empty() )
524 if ( meshName != maa ) {
525 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = ("
526 << ndt << "," << od << ") for (entityType,geometricType)=("
527 << MED_EN::entNames[entityCurrent] << ","
528 << MED_EN::geoNames[*currentGeometry] << ")"
529 << "is defined on mesh |" << maa << "| not on mesh |" << meshName ));
536 MESSAGE(LOC << " a (dt,it) is found ?? " << alreadyFoundPdtIt);
538 if ( !alreadyFoundPdtIt )
539 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field |" << fieldName << "| with (ndt,or) = ("
540 << ndt << "," << od << ") should be defined for (entityType,geometricType)=("
541 << MED_EN::entNames[entityCurrent] << ","
542 << MED_EN::geoNames[*currentGeometry] << ")" ));
544 if ( (ret != 0) || (ngauss < 1 ) )
545 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Error in MEDpasdetempsInfo for Field |" << fieldName
546 << "| with (ndt,or) = ("
547 << ndt << "," << od << ") for (entityType,geometricType)=("
548 << MED_EN::entNames[entityCurrent] << ","
549 << MED_EN::geoNames[*currentGeometry] << ")" )); ;
551 if ( (numberOfElements = med_2_3::MEDnVal(id, const_cast <char*> ( fieldName.c_str() ),
552 (med_2_3::med_entite_maillage) entityCurrent,
553 (med_2_3::med_geometrie_element) *currentGeometry,
554 numdt, numo, maa, med_2_3::MED_COMPACT)) <= 0 )
555 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Error in MEDnVal for Field |" << fieldName
556 << "| with (ndt,or) = ("
557 << ndt << "," << od << ") for (entityType,geometricType)=("
558 << MED_EN::entNames[entityCurrent] << ","
559 << MED_EN::geoNames[*currentGeometry] << ")" )); ;
561 numberOfElementsOfType[numberOfGeometricType] = numberOfElements/ngauss;
562 numberOfElementsOfTypeC[numberOfGeometricType+1]=
563 numberOfElementsOfTypeC[numberOfGeometricType]
564 + numberOfElementsOfType[numberOfGeometricType];
565 numberOfGaussPoint[numberOfGeometricType+1] = ngauss;
566 geometricType[numberOfGeometricType]= *currentGeometry;
567 numberOfGeometricType++;
568 totalNumberOfElWg+=numberOfElements;
574 if ( alreadyFoundAnEntity) {
575 support.setName(fieldName+"Support");
576 support.setMeshName(string(maa)); // Vérifier que les différents noms de maillages lus soient identiques
577 support.setEntity(entity);
578 // REM : Le nombre <numberOfGeometricType> dans la précédente version du Driver
579 // était erronée pour un champ qui ne reposait pas sur toutes les entités géométriques
580 // du maillage mais dont le SUPPORT a été crée à partir des informations du maillage
581 // ( méthode qui était largement utilisée pour construire un SUPPORT).
582 support.setNumberOfGeometricType(numberOfGeometricType);
583 support.setGeometricType(geometricType); // Utile uniquement si setAll == false ?
584 support.setNumberOfElements(numberOfElementsOfType); //setNumberOfElements effectue une copie
585 // Par défaut considère que le champ repose sur tous les type géométriques du maillage
586 // Si ce n'est pas le cas les champs geometricType et numberOfElementsOfType du SUPPORT sont corrects
587 support.setAll(true);
588 numberOfElementsOfTypeC.resize(numberOfGeometricType+1);
589 numberOfGaussPoint.resize(numberOfGeometricType+1);
591 return alreadyFoundAnEntity;
598 Renvoie la liste <geoType> des types géométriques définis dans le maillage <meshName>
599 pour le type d'entité <entity>.
600 * < nbOfElOfType > contient le nombre d'entités de chaque type
601 * < numberOfElementsOfTypeC > contient le nombre d'entités cumulées de chaque type
602 avec numberOfElementsOfTypeC[0]=0;
605 template <class T> void
606 MED_FIELD_DRIVER22<T>::getMeshGeometricTypeFromFile(med_2_3::med_idt id,
608 MED_EN::medEntityMesh entity,
609 vector<MED_EN::medGeometryElement> & geoType,
610 vector<int> &nbOfElOfType,
611 vector<int> &nbOfElOfTypeC
612 ) const throw(MEDEXCEPTION)
614 BEGIN_OF("MED_FIELD_DRIVER<T>::getMeshGeometricTypeFromFile(...)");
616 int numberOfGeometricType=0;
617 MED_EN::medGeometryElement geometricType[MED_NBR_GEOMETRIE_MAILLE];
618 int numberOfElementsOfType [MED_NBR_GEOMETRIE_MAILLE];
619 int numberOfElementsOfTypeC[MED_NBR_GEOMETRIE_MAILLE+1];
620 med_2_3::med_int numberOfElements=0;
621 med_2_3::med_table quoi;
623 /*in MED file, all entities are regarded as MED_CELL
624 (except for those related to descending connectivities),
625 whereas in MEDMEM the distinction between MED_CELL, MED_FACE and MED_EDGE exists
626 it is therefore necessary to distinguish the MED-file entity
627 that will be used for the call to MED-file
628 and the MEDMEM entity*/
629 MED_EN::medEntityMesh medfile_entity;
630 if (entity==MED_EN::MED_NODE)
632 medfile_entity=MED_EN::MED_NODE;
633 quoi=med_2_3::MED_COOR;
637 medfile_entity=MED_EN::MED_CELL;
638 quoi=med_2_3::MED_CONN;
641 list<MED_EN::medGeometryElement>::const_iterator currentGeometry;
642 bool alreadyFoundAnEntity = false;
643 numberOfElementsOfTypeC[0]=0;
645 for (currentGeometry = (MED_EN::meshEntities[entity]).begin();
646 currentGeometry != (MED_EN::meshEntities[entity]).end(); currentGeometry++)
649 med_2_3::MEDnEntMaa(id,
650 const_cast<char*> (meshName.c_str()),
652 (med_2_3::med_entite_maillage) medfile_entity,
653 (med_2_3::med_geometrie_element) *currentGeometry,
655 if (numberOfElements <= 0)
658 alreadyFoundAnEntity = true;
659 numberOfElementsOfType[numberOfGeometricType] = numberOfElements;
660 numberOfElementsOfTypeC[numberOfGeometricType+1] =
661 numberOfElementsOfTypeC[numberOfGeometricType]+numberOfElements;
662 MED_EN::medGeometryElement geomType;
664 //MED_FILE uses MED_NONE as a geometricType to describe MED_NODE
665 //MEDMEM uses MED_POINT1
666 if ( *currentGeometry==MED_NONE)
669 geomType=*currentGeometry;
670 geometricType[numberOfGeometricType] = geomType;
672 numberOfGeometricType++;
675 //Because MEDFILE and MEDMEM differ on the definition of MED_CELL
676 //it is necessary to remove the cells that do not
677 //have maximum cell dimension in the range covered by geometricType
679 for (int i=0; i<numberOfGeometricType; i++)
681 CELLMODEL model(geometricType[i]);
682 int dim = model.getDimension();
683 if (dim>maxdim) maxdim=dim;
686 nbOfElOfTypeC.push_back(0);
687 for (int i=0; i<numberOfGeometricType; i++)
689 CELLMODEL model(geometricType[i]);
690 int dim = model.getDimension();
691 if (dim==maxdim || entity != MED_CELL)
693 geoType.push_back(geometricType[i]);
694 int nbelems = numberOfElementsOfType[i];
695 nbOfElOfType.push_back(nbelems);
696 nbOfElOfTypeC.push_back(nbOfElOfTypeC[nbOfElOfTypeC.size()-1]+nbelems);
700 // geoType = vector<MED_EN::medGeometryElement>(geometricType,geometricType+numberOfGeometricType);
701 // nbOfElOfType = vector<int> (numberOfElementsOfType,numberOfElementsOfType+numberOfGeometricType);
702 // nbOfElOfTypeC = vector<int> (numberOfElementsOfTypeC,numberOfElementsOfTypeC+numberOfGeometricType+1);
704 // for (int j =0 ; j<= numberOfGeometricType;++j)
705 // cout << "nbOfElOfTypeC["<<j<<"]="<<nbOfElOfTypeC[j]<<endl;
707 END_OF("MED_FIELD_DRIVER<T>::getMeshGeometricTypeFromFile(...)");
711 reads the MESH object in order to retrieve the list of geometric types for a given entity
712 \param[in] meshPtr pointer to MESH
713 \param[in] entity entity for which the geom types are required
714 \param[out] geoType list of geom types
715 \param[out] nbOfElOfType vector containing the number of elements per type (size : ntype)
716 \param[out] nbOfElOfTypeC accumulated version of nbOfElType (size : ntype+1)
719 template <class T> void
720 MED_FIELD_DRIVER22<T>::getMeshGeometricTypeFromMESH( MESH * meshPtr,
721 MED_EN::medEntityMesh entity,
722 vector<MED_EN::medGeometryElement> & geoType,
723 vector<int> &nbOfElOfType,
724 vector<int> &nbOfElOfTypeC) const throw(MEDEXCEPTION)
726 const char LOC[] = "MED_FIELD_DRIVER<T>::getMeshGeometricTypeFromMESH(...) : ";
730 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"ptrMesh must be non null" )); ;
732 // Il est plus pratique de créer un support "onAll"
733 // pour calculer les tableaux du nombre d'entités cumulées
735 SUPPORT mySupportFromMesh (meshPtr, "Temporary Support From Associated Mesh", entity);
736 geoType = vector<MED_EN::medGeometryElement>(mySupportFromMesh.getTypes(),
737 mySupportFromMesh.getTypes()+mySupportFromMesh.getNumberOfTypes());
738 nbOfElOfType.resize(mySupportFromMesh.getNumberOfTypes());
739 nbOfElOfTypeC.resize(mySupportFromMesh.getNumberOfTypes()+1);
742 for (int j=1; j<=mySupportFromMesh.getNumberOfTypes(); ++j) {
743 nbOfElOfType[j-1]=mySupportFromMesh.getNumberOfElements(geoType[j-1]);
744 nbOfElOfTypeC[j]+=nbOfElOfTypeC[j-1]+nbOfElOfType[j-1];
750 /*--------------------- RDONLY PART -------------------------------*/
752 template <class T> GENDRIVER * MED_FIELD_RDONLY_DRIVER22<T>::copy(void) const
754 return new MED_FIELD_RDONLY_DRIVER22<T>(*this);
757 template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::read(void)
760 const char * LOC = " MED_FIELD_RDONLY_DRIVER22::read() " ;
763 typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo;
764 typedef typename MEDMEM_ArrayInterface<T,NoInterlace,Gauss>::Array ArrayNoWg;
765 typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull;
766 typedef typename MEDMEM_ArrayInterface<T,FullInterlace,Gauss>::Array ArrayFullWg;
767 typedef typename MEDMEM_ArrayInterface<T,NoInterlaceByType,NoGauss>::Array ArrayByType;
768 typedef typename MEDMEM_ArrayInterface<T,NoInterlaceByType,Gauss>::Array ArrayByTypeWg;
770 if (MED_FIELD_DRIVER<T>::_status!=MED_OPENED)
771 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": Method open must be called before method read.")) ;
773 if ( ( MED_FIELD_DRIVER<T>::_fieldName.empty() ) &&
774 ( MED_FIELD_DRIVER<T>::_ptrField->_name.empty() ) )
775 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
776 <<" neither <fieldName> is set in driver nor in object FIELD.")) ;
778 // If _fieldName is not set in driver, try to use _ptrfield->_fieldName
779 if ( ( MED_FIELD_DRIVER<T>::_fieldName.empty() ) &&
780 ( !MED_FIELD_DRIVER<T>::_ptrField->_name.empty() ) )
781 MED_FIELD_DRIVER<T>::_fieldName=MED_FIELD_DRIVER<T>::_ptrField->_name;
783 if ( MED_FIELD_DRIVER<T>::_fieldName.size() > MED_TAILLE_NOM )
785 SCRUTE(MED_FIELD_DRIVER<T>::_fieldName.size());
786 SCRUTE(MED_TAILLE_NOM);
788 // throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
789 // <<" <fieldName> size in object driver FIELD is > MED_TAILLE_NOM ."));
791 MESSAGE(LOC << "Warning <fieldName> size in object driver FIELD is > MED_TAILLE_NOM .");
794 const string & fieldName = MED_FIELD_DRIVER<T>::_fieldName;
796 MED_EN::medModeSwitch interlacingType = MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType();
797 bool isFullInterlace = ( interlacingType == MED_EN::MED_FULL_INTERLACE );
798 bool isNoInterlaceByType = ( interlacingType == MED_EN::MED_NO_INTERLACE_BY_TYPE );//PAL17011
800 MESSAGE("###### "<<LOC<<" fieldNameDRIVER : "<< fieldName << " fieldName : "<< MED_FIELD_DRIVER<T>::_ptrField->_name);
803 // Si un support a été donnée au champ, pour des raisons de compatibilité avec
804 // les versions précédentes, ce support sera utilisé pour
805 // - Obtenir le nom du maillage sur lequel on veut lire le champ
806 // (eventuellement on pourrait l'utiliser pour selectionner un champ qui
807 // repose sur plusieurs maillages cf HOMARD-ASTER, ce qui n'est pas géré dans MEDMEM)
808 // - vérifier le type d'entité (MED_NOEUD xor MED_MAILLE xor MED_FACE xor MED_ARETE ) sur lequel
809 // il faut lire le champ qui est également retouvé.
810 // - Si le support défini une liste d'entité ( différente de MED_ALL_ELEMENTS), celle-ci est ignorée
811 // à la lecture et écrasé par soit :
812 // - onall, après avoir vérifié que la liste des types géométriques utilisés par le champ
813 // est égale à la liste des type géométriques définis dans le maillage associé
814 // pour tous le même type d'entité.
815 // - La sous liste des types géométriques utilisés (onAll quand même, cf commenataire ci-dessous )
816 // - les listes de profils lus s'il en existe pour une sous liste de types
819 // Si aucun support n'a été donné au champ :
820 // - A la lecture : Un support est crée et le type d'entité unique est lu
821 // (cf decision gt MED qu'un champ repose sur une entité unique ?),
822 // l'ensemble des types géométriques est lu,
823 // l'ensemble des profils par type géométrique est lu
824 // Le nom du maillage associé est lu mais le pointeur SUPPORT-MESH non initialisé
827 char tmpFieldName[MED_TAILLE_NOM+1] ;
829 int numberOfComponents = 0;
830 char * componentName = (char *) MED_NULL;
831 char * unitName = (char *) MED_NULL;
832 med_2_3::med_type_champ type ;
833 med_2_3::med_idt id = MED_FIELD_DRIVER22<T>::_medIdt;
834 bool needConversionToDouble = false,needConversionToInt64 = false;
836 // we search for the "field med number" of <fieldName>
837 // Having found <fieldName>, variables <numberOfComponents>,
838 // <componentName>, <unitname>, <type> and attribute <_fieldNum> are set.
839 if (MED_FIELD_DRIVER<T>::_fieldNum==MED_INVALID)
841 int numberOfFields = med_2_3::MEDnChamp(id,0) ;
842 if ( numberOfFields <= 0 )
843 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": There is no field found in the file !"));
845 for (int i=1;i<=numberOfFields;i++)
847 numberOfComponents = med_2_3::MEDnChamp(id,i) ;
849 if ( numberOfComponents <= 0 )
850 MESSAGE(LOC<<"Be careful there is no compound for field n°"<<i<<"in file |"<<MED_FIELD_DRIVER<T>::_fileName<<"| !");
852 componentName = new char[numberOfComponents*MED_TAILLE_PNOM22+1] ;
853 unitName = new char[numberOfComponents*MED_TAILLE_PNOM22+1] ;
855 err = med_2_3::MEDchampInfo(id, i, tmpFieldName, &type, componentName,
856 unitName, numberOfComponents) ;
858 MESSAGE("Field "<<i<<" : #" << tmpFieldName <<"# et recherche #"<<fieldName.c_str()<<"#");
859 if ( !strcmp(tmpFieldName,fieldName.c_str()) ) {
860 MESSAGE("FOUND FIELD "<< tmpFieldName <<" : "<<i);
861 MED_FIELD_DRIVER<T>::_fieldNum = i ;
864 // not found : release memory and search next field !
865 delete[] componentName ;
870 //delete[] tmpFieldName ;
872 // Si aucun champ ne correspond les variables <componentName> et <unitName> ont été correctement
873 // désallouées dans la boucle de recherche
874 if (MED_FIELD_DRIVER<T>::_fieldNum==MED_INVALID)
875 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) << ": Field "<< fieldName
876 << " not found in file " << MED_FIELD_DRIVER<T>::_fileName) );
878 MESSAGE ("FieldNum : "<<MED_FIELD_DRIVER<T>::_fieldNum);
880 if (numberOfComponents < 1) {
881 delete[] componentName; delete[] unitName;
882 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" no component found for field "
886 // Verifie que l'on essaye pas de lire un champ double dans un FIELD<int>
887 switch ( (med_2_3::med_type_champ) MED_FIELD_DRIVER<T>::_ptrField->_valueType ) {
888 case med_2_3::MED_INT :
889 case med_2_3::MED_INT32 :
890 case med_2_3::MED_INT64 :
891 if ( type == ( med_2_3::MED_FLOAT64 ) ) {
892 delete[] componentName; delete[] unitName;
893 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Field Type in file (" << type
894 <<") differs from FIELD object type (" <<
895 MED_FIELD_DRIVER<T>::_ptrField->_valueType << ")" )) ;
897 #if defined(IRIX64) || defined(OSF1) ||defined(VPP5000) || defined(PCLINUX64)
898 if (MED_FIELD_DRIVER<T>::_ptrField->_valueType==MED_EN::MED_INT32 )
899 needConversionToInt64=true;
902 case med_2_3::MED_FLOAT64 :
903 if (type != med_2_3::MED_FLOAT64)
904 needConversionToDouble=true;
912 bool haveSupport = false;
913 bool haveMesh = false;
914 if ( MED_FIELD_DRIVER<T>::_ptrField->getSupport() ) {
915 // Verif à faire sur la taille du meshName
916 ptrMesh = MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getMesh();
918 meshName = MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getMesh()->getName() ;
924 // Cherche le type d'entité, le nombre d'entité par type géométrique sur le type d'entité
925 // (MED_MAILLE ou MED_NOEUD uniquement car MEDMEMOIRE ne gère pas la connectivité descendante).
926 // et crée le support correspondant.
927 SUPPORT * mySupport = new SUPPORT();
928 vector<int> numberOfElementsOfTypeC;
929 vector<int> numberOfGaussPoint;
930 int totalNumberOfElWg=0;
932 bool found = createFieldSupportPart1(id,fieldName,
933 MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber,
934 MED_FIELD_DRIVER<T>::_ptrField->_orderNumber,
935 *mySupport, meshName,
936 numberOfElementsOfTypeC, numberOfGaussPoint,totalNumberOfElWg);
939 delete mySupport; delete[] componentName; delete[] unitName;
940 MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ;
941 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Can't find any entity for field |"
943 << "| with (it,or) = ("
944 << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
945 << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), on mesh "
946 << meshName << "|" ));
949 MED_EN::medEntityMesh entityType = mySupport->getEntity();
950 //Si un SUPPORT était donné, récupère son nom, sa description et
951 // le pointeur du maillage associé
953 meshName = mySupport->getMeshName();
955 if ( mySupport->getEntity() != MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getEntity() ) {
956 delete mySupport; delete[] componentName; delete[] unitName;
957 MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ;
958 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<"Given entity |"
959 << MED_EN::entNames[MED_FIELD_DRIVER<T>::_ptrField->
960 getSupport()->getEntity()]
963 << "| with (it,or) = ("
964 << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
965 << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), on mesh "
966 << meshName << "| differs from found entity |"
967 << MED_EN::entNames[entityType] << "|."
970 mySupport->setName( MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getName() );
971 mySupport->setMesh( MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getMesh() );
972 mySupport->setDescription(MED_FIELD_DRIVER<T>::_ptrField->getSupport()->getDescription());
975 vector< MED_EN::medGeometryElement > MESHgeoType;
976 vector< int > MESHnbOfElOfType;
977 vector< int > MESHnbOfElOfTypeC;
979 this->getMeshGeometricTypeFromMESH(ptrMesh,entityType,MESHgeoType,
980 MESHnbOfElOfType,MESHnbOfElOfTypeC);
982 int fileHasMesh = ( med_2_3::MEDdimLire(id, const_cast<char *>(meshName.c_str())) > 0);
983 vector< MED_EN::medGeometryElement > meshGeoType;
984 vector< int > meshNbOfElOfType;
985 vector< int > meshNbOfElOfTypeC;
986 // Si le maillage n'est pas trouvé les tableaux renvoyés sont vides
989 MED_EN::medEntityMesh entityTypeLoc = entityType;
990 if (entityType == MED_EN::MED_FACE || entityType == MED_EN::MED_EDGE) entityTypeLoc = MED_EN::MED_CELL;
992 this->getMeshGeometricTypeFromFile(id,meshName,entityTypeLoc,meshGeoType,
993 meshNbOfElOfType,meshNbOfElOfTypeC);
996 SCRUTE(meshGeoType.size());
997 SCRUTE(MESHgeoType.size());
998 SCRUTE(meshNbOfElOfTypeC.size());
999 SCRUTE(MESHnbOfElOfTypeC.size());
1001 if (meshGeoType.size() != MESHgeoType.size())
1003 for (int i = 0; i<meshGeoType.size();i++)
1004 MESSAGE("debug meshGeotype " << meshGeoType[i]);
1006 for (int i = 0; i<MESHgeoType.size();i++)
1007 MESSAGE("debug MESHgeoType. " << MESHgeoType[i]);
1010 if (meshNbOfElOfTypeC.size() == MESHnbOfElOfTypeC.size())
1012 for (int i = 0; i<meshNbOfElOfTypeC.size();i++)
1013 MESSAGE("debug meshNbOfElOfTypeC " << meshNbOfElOfTypeC[i]);
1015 for (int i = 0; i<MESHnbOfElOfTypeC.size();i++)
1016 MESSAGE("debug MESHnbOfElOfTypeC " << MESHnbOfElOfTypeC[i]);
1019 if (fileHasMesh && haveSupport )
1020 if ( ( meshGeoType != MESHgeoType ) || (meshNbOfElOfTypeC != MESHnbOfElOfTypeC) )
1022 MESSAGE("Warning MedField driver 21 while getting mesh information from file for FIELD "<< fieldName
1023 << " on entity " << MED_EN::entNames[entityType]
1024 << " with (it,or) = ("
1025 << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
1026 << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << ")"
1027 << " on mesh " << meshName
1028 << " : geometric types or number of elements by type differs from MESH object !");
1030 // throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Error while getting mesh information from file for FIELD "<< fieldName
1031 // << " on entity " << MED_EN::entNames[entityType]
1032 // << " with (it,or) = ("
1033 // << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
1034 // << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << ")"
1035 // << " on mesh " << meshName
1036 // << " : geometric types or number of elements by type differs from MESH object !"
1041 if ( !fileHasMesh && !haveSupport )
1042 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Error while getting mesh information for FIELD "<< fieldName
1043 << " on entity " << MED_EN::entNames[entityType]
1044 << " with (it,or) = ("
1045 << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
1046 << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << ")"
1047 << " on mesh " << meshName
1048 << " : SUPPORT must contain a valid MESH reference or file must contain the associated MESH."
1053 if (!fileHasMesh && haveSupport) {
1054 meshNbOfElOfTypeC = MESHnbOfElOfTypeC;
1055 meshGeoType = MESHgeoType;
1056 meshNbOfElOfType = MESHnbOfElOfType;
1059 // Test si le Support du Champ repose ou non sur toutes les entités géométriques
1060 // du maillage associé et positionne ou non l'attribut onAll du SUPPORT.
1061 // Il ne s'agit pas de la gestion des profils
1062 vector < MED_EN::medGeometryElement > v1( mySupport->getTypes(),
1063 mySupport->getTypes()+mySupport->getNumberOfTypes() );
1064 vector<int> v2(numberOfElementsOfTypeC.size());
1065 transform(numberOfElementsOfTypeC.begin(),
1066 numberOfElementsOfTypeC.end(),v2.begin(), bind2nd(plus<int>(),1));
1068 if ( ( meshGeoType != v1 ) || meshNbOfElOfTypeC != v2 ) {
1069 // ATTENTION : mySupport->setAll(false);
1070 // Pb : On a envie de positionner onAll à faux si le champ n'est pas défini sur tous les
1071 // types géométriques du maillage associé.
1072 // Mais si onAll est false et si aucun profil n'est détecté par la suite,
1073 // l'attribut SUPPORT->_number est censé être positionné quand même ! Que faire ?
1074 // Si on veut être compatible avec la signification première de onAll,
1075 // il faudrait créer des profils contenant toutes les entités pour chaque type géométrique
1076 // du SUPPORT mais d'une part c'est dommage d'un point de vue de l'encombrement mémoire
1077 // et d'autre part, à la réécriture du fichier MED on stockera des profils
1078 // alors qu'il n'y en avait pas à l'origine (fichier MED différent après lecture/écriture) !
1079 // Si on laisse setAll à vrai il faut être sûr que les utilisateurs prennent les
1080 // informations sur les types gémétrique au niveau du support et non pas du maillage.
1081 // Solution : Signification du onAll -> onAllElements des type géométriques définis
1082 // dans le SUPPORT et non du maillage associé (dans la plupart des cas si le fichier ne
1083 // contient pas de profil, le champ est défini sur toutes les entités de tous les types
1084 // géométriques définis dans le maillage).
1088 // If an error occurs while reading the field, these allocated FIELD member will be deleted
1090 MED_FIELD_DRIVER<T>::_ptrField->_name = fieldName;
1091 MED_FIELD_DRIVER<T>::_ptrField->_numberOfComponents = numberOfComponents ;
1092 MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = new int [numberOfComponents] ;
1093 MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = new string[numberOfComponents] ;
1094 MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = new UNIT [numberOfComponents] ;
1095 MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = new string[numberOfComponents] ;
1096 MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = new string[numberOfComponents] ;
1097 for (int i=0; i<numberOfComponents; i++) {
1098 MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes[i] = 1 ;
1099 MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i] = string(componentName+i*MED_TAILLE_PNOM22,MED_TAILLE_PNOM22) ;
1100 MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i] = string(unitName+i*MED_TAILLE_PNOM22,MED_TAILLE_PNOM22) ;
1101 SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_componentsNames[i]);
1102 SCRUTE(MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits[i]);
1104 delete[] componentName;
1107 int NumberOfTypes = mySupport->getNumberOfTypes() ;
1108 const MED_EN::medGeometryElement *types = mySupport->getTypes() ;
1109 T * myValues = new T[totalNumberOfElWg*numberOfComponents];
1110 const int * nbOfElOfType = mySupport->getNumberOfElements() ;
1111 bool anyProfil = false;
1112 int pflSize=0,index=0;
1113 // Le vecteur de profil est dimensionné par rapport aux nombres de types
1114 // géométriques du champ même si le champ n'a pas de profil MED FICHIER sur
1115 // tous ses types géométriques car dans MEDMEM si onAllElement
1116 // du SUPPORT est false il faut positionner un profil pour tous les types géométriques
1118 int profilSizeC = 0;
1119 vector < int > profilSize (NumberOfTypes,0);
1120 vector < string > profilNameList(NumberOfTypes);
1121 vector < vector<med_2_3::med_int> > profilList (NumberOfTypes); // IPAL13481
1122 vector < vector<med_2_3::med_int> > profilListFromFile (NumberOfTypes); // IPAL13481
1123 char * profilName = new char[MED_TAILLE_NOM+1];
1125 MESSAGE ("NumberOfTypes : "<< NumberOfTypes);
1126 MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues=0 ;
1128 // PAL16681 (Read no interlace field from file) ->
1129 // use medModeSwitch of a field in MEDMEMchampLire() if there is one geometric type
1130 // to exclude array conversion
1131 med_2_3::med_mode_switch modswt = med_2_3::MED_FULL_INTERLACE;
1132 // NOTE: field can be either of 3 medModeSwitch'es, MED_NO_INTERLACE_BY_TYPE added (PAL17011)
1133 if ( NumberOfTypes == 1 && !isFullInterlace || isNoInterlaceByType )
1134 modswt = med_2_3::MED_NO_INTERLACE;
1136 for (int typeNo=0; typeNo<NumberOfTypes; typeNo++) {
1138 int numberOfValuesWc= nbOfElOfType[typeNo]*numberOfGaussPoint[typeNo+1]*numberOfComponents;
1139 char * gaussModelName = new char[MED_TAILLE_NOM+1];
1141 MESSAGE ("FIELD_NAME : "<< fieldName.c_str());
1142 MESSAGE ("MESH_NAME : "<< meshName.c_str());
1143 MESSAGE ("MED_ENTITE : "<< MED_EN::entNames[entityType]);
1144 MESSAGE ("MED_GEOM : "<< MED_EN::geoNames[types[typeNo]]);
1145 MESSAGE ("Iteration : "<< MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber());
1146 MESSAGE ("Order : "<< MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber());
1147 MESSAGE ("Time : "<< MED_FIELD_DRIVER<T>::_ptrField->getTime());
1148 MESSAGE ("NumberOfElements : "<< nbOfElOfType[typeNo]);
1149 MESSAGE ("NumberOfComponents : "<< numberOfComponents);
1150 MESSAGE ("NumberOfGaussPts : "<< numberOfGaussPoint[typeNo+1]);
1151 MESSAGE ("NumberOfValuesWg : "<< nbOfElOfType[typeNo]*numberOfGaussPoint[typeNo+1]);
1152 MESSAGE ("NumberOfValuesWgWc : "<< numberOfValuesWc);
1153 MESSAGE ("Index : "<< index);
1154 med_2_3::med_err ret=-1;
1156 med_2_3::med_int * myValuesTmp=0;
1157 unsigned char* ptrTmp=0;
1158 if (needConversionToDouble || needConversionToInt64 ) {
1159 myValuesTmp = new med_2_3::med_int[numberOfValuesWc];
1160 ptrTmp = (unsigned char*) myValuesTmp;
1162 ptrTmp = (unsigned char*) &myValues[index];
1165 ret=med_2_3::MEDchampLire(id,const_cast <char*> (meshName.c_str() ),
1166 const_cast <char*> (fieldName.c_str()),
1167 (unsigned char*) ptrTmp,
1168 modswt /*med_2_3::MED_FULL_INTERLACE*/, // PAL16681,17011
1172 med_2_3::MED_COMPACT,
1173 (med_2_3::med_entite_maillage) entityType,
1174 (med_2_3::med_geometrie_element)types[typeNo],
1175 MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
1176 MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
1179 if (needConversionToDouble || needConversionToInt64 ) {
1181 if (needConversionToInt64 ) //utiliser un trait
1182 for(int i=0;i<numberOfValuesWc;++i)
1183 myValues[index+i]=(int)(myValuesTmp[i]);
1185 for(int i=0;i<numberOfValuesWc;++i)
1186 myValues[index+i]=myValuesTmp[i];
1187 delete[] myValuesTmp;
1192 // The Field can't be read then we must delete all previously allocated members in FIELD
1193 //for(int j=0; j<=i;j++)
1194 // delete[] myValues[j];
1196 //delete[] NumberOfValues ;
1197 delete[] profilName;
1198 delete[] gaussModelName;
1199 delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes ;
1200 delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsNames ;
1201 delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits ;
1202 delete[] MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions ;
1203 delete[] MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits ;
1204 MED_FIELD_DRIVER<T>::_ptrField->_componentsTypes = NULL ;
1205 MED_FIELD_DRIVER<T>::_ptrField->_componentsNames = NULL ;
1206 MED_FIELD_DRIVER<T>::_ptrField->_componentsUnits = NULL ;
1207 MED_FIELD_DRIVER<T>::_ptrField->_componentsDescriptions = NULL ;
1208 MED_FIELD_DRIVER<T>::_ptrField->_MEDComponentsUnits = NULL ;
1209 MED_FIELD_DRIVER<T>::_fieldNum = MED_INVALID ; // we have not found right field, so reset the field number
1210 throw MEDEXCEPTION( LOCALIZED( STRING(LOC) <<": ERROR while reading values")) ;
1213 index += numberOfValuesWc;
1214 // Le support prend en compte le nombre de valeurs lié aux profils
1215 MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues+=
1216 nbOfElOfType[typeNo];// Ne doit pas prendre en compte les points de Gauss
1218 // second et troisième test lié à un bug medfichier
1219 if ( strcmp(gaussModelName,MED_NOGAUSS) && strcmp(gaussModelName,string(MED_TAILLE_NOM,' ').c_str() )
1220 && strcmp(gaussModelName,string(16,' ').c_str() ) ) {
1222 int type_geo = (int) types[typeNo];
1223 int t1 = (type_geo%100)*(type_geo/100);
1224 int ngauss = numberOfGaussPoint[typeNo+1];
1225 int t2 = ngauss*(type_geo/100);
1226 med_2_3::med_float * refcoo = new med_2_3::med_float[t1];
1227 med_2_3::med_float * gscoo = new med_2_3::med_float[t2];
1228 med_2_3::med_float * wg = new med_2_3::med_float[ngauss];
1230 if (MEDgaussLire(id, refcoo, gscoo, wg, modswt, gaussModelName ) < 0)
1231 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Error while reading Gauss Model |"
1232 << gaussModelName << "| for FIELD "<< fieldName
1233 << " on geometric type " << MED_EN::geoNames[types[typeNo]]
1236 if (isFullInterlace ) { //serait inutile avec un driver template du type d'entrelacement
1237 GAUSS_LOCALIZATION<FullInterlace> * loc;
1238 loc = new GAUSS_LOCALIZATION<FullInterlace>(gaussModelName,types[typeNo],ngauss, refcoo,gscoo, wg);
1239 MED_FIELD_DRIVER<T>::_ptrField->_gaussModel[types[typeNo]]=loc;
1241 GAUSS_LOCALIZATION<NoInterlace> * loc;
1242 loc = new GAUSS_LOCALIZATION<NoInterlace>(gaussModelName,types[typeNo],ngauss, refcoo,gscoo, wg);
1243 MED_FIELD_DRIVER<T>::_ptrField->_gaussModel[types[typeNo]]=loc;
1245 // cout << *MED_FIELD_DRIVER<T>::_ptrField->_gaussModel[types[typeNo]] << endl;
1246 delete [] refcoo;delete [] gscoo; delete [] wg;
1249 delete[] gaussModelName ;
1251 if ( strcmp(profilName,MED_NOPFL) ) {
1253 pflSize = med_2_3::MEDnValProfil(id,profilName);
1255 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<" Error while reading the profil size of |"
1256 << profilName << "|" ));
1258 profilSize[typeNo]=pflSize;
1259 profilList[typeNo].resize(pflSize);
1260 profilListFromFile[typeNo].resize(pflSize);
1261 ret = med_2_3::MEDprofilLire(id,&profilList[typeNo][0],profilName); // cf item 16 Effective STL // IPAL13481
1262 profilListFromFile[typeNo] = profilList[typeNo];
1263 profilNameList[typeNo]=string(profilName);
1267 delete[] profilName;
1269 //MESSAGE ("Index : "<< index);
1270 assert(index == totalNumberOfElWg*numberOfComponents);
1271 assert(MED_FIELD_DRIVER<T>::_ptrField->_numberOfValues == mySupport->getNumberOfElements(MED_ALL_ELEMENTS));
1275 for (int typeNo=0; typeNo < NumberOfTypes; typeNo++)
1277 //MED_FILE uses MED_NONE as a geometricType to describe MED_NODE
1278 //MEDMEM uses MED_POINT1
1279 MED_EN::medGeometryElement geomType = types[typeNo];
1280 if (geomType == MED_EN::MED_NONE)
1281 geomType = MED_EN::MED_POINT1;
1283 // Trouve l'index du type géométrique dans la liste des types géométriques du maillage
1284 // correspondant au type géométrique du champ traité
1285 vector<MED_EN::medGeometryElement>::iterator meshTypeNoIt =
1286 find(meshGeoType.begin(),meshGeoType.end(),geomType); //Gérer l'exception
1287 if (meshTypeNoIt == meshGeoType.end())
1288 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<": Can't find "<< MED_EN::geoNames[geomType]
1289 << " on entity " << MED_EN::entNames[entityType]
1290 << " in geometric type list of mesh " << meshName));
1291 int meshTypeNo = meshTypeNoIt - meshGeoType.begin();
1293 if (! profilList[typeNo].empty() )
1295 // for (int j =0 ; j< meshGeoType.size();++j)
1296 // cout << "--MeshTypeNo : "<<meshTypeNo<<"-> meshNbOfElOfTypeC["<<j<<"]="<<meshNbOfElOfTypeC[j]<<endl;
1297 // cout << "--typeNo--" << typeNo << endl;
1298 // cout << "meshNbOfElOfTypeC["<<meshTypeNo<<"]=" << meshNbOfElOfTypeC[meshTypeNo] <<endl;
1300 // Transformer les numéros locaux d'entités medfichier en numéro global medmémoire
1301 for (int i = 0 ; i < profilList[typeNo].size(); i++ ) {
1302 // Les numéros des entités commencent à 1 dans MEDfichier comme dans MEDmémoire
1303 // meshNbOfElOfTypeC[0]=0 ...meshNbOfEltOfTypeC[meshTypeNo]=
1304 // meshNbOfElOfTypeC[meshTypeNo-1]+nbrOfElem of meshTypeNo type
1305 // rem1 : Si le meshTypeNo trouvé est 0 (premier type géométrique du maillage
1306 // il ne faut pas décaler les numéros du profils qui commencent à 1 dans MEDFICHIER
1307 // rem2 : meshNbOfElOfTypeC[NumberOfTypes] ne devrait jamais être utilisé
1308 profilList[typeNo][i]+=meshNbOfElOfTypeC[meshTypeNo];
1311 // Créer le profil <MED_ALL> pour ce type géométrique
1312 // uniquement pour renseigner le tableau skyline avec des accesseurs directs
1313 // par type géométriques
1314 // REM : Une conséquence est qu'à la réecriture le fichier contiendra des
1315 // profils sur certains types géométriques alors qu'à la lecture il n'y en avait pas !
1316 // Solution : Stocker les noms des profils et les utiliser pour savoir si il y avait ou non
1318 int pflSize = meshNbOfElOfType[meshTypeNo];
1319 // profil = new int[pflSize];
1321 profilList[typeNo].resize(pflSize);
1322 profilSize[typeNo]=pflSize;
1324 for (int j = 1; j <= pflSize; j++) {
1325 profilList[typeNo][j-1]=meshNbOfElOfTypeC[meshTypeNo] + j ; // index MEDMEM commence à 1
1327 profilNameList[typeNo] = MED_NOPFL; //Information a utiliser pour la sauvegarde : PLUTOT MED_ALL
1329 profilSizeC+=profilList[typeNo].size();
1332 MEDSKYLINEARRAY * skyLine = new MEDSKYLINEARRAY(profilList.size(), profilSizeC );
1333 vector<int> index(NumberOfTypes+1,0);
1335 for( int typeNo=0; typeNo < NumberOfTypes; typeNo++ )
1336 index[typeNo+1]=index[typeNo]+profilSize[typeNo];
1337 skyLine->setIndex(&index[0]);
1338 for (int i=1; i <= profilList.size() ; i++) {
1339 vector<int> aTmp(profilList[i-1].size()); // IPAL13481
1340 for (int j=0; j < profilList[i-1].size(); j++)
1341 aTmp[j] = (int) profilList[i-1][j];
1342 skyLine->setI(i,&aTmp[0]);
1343 //skyLine->setI(i,&profilList[i-1][0]);
1346 MEDSKYLINEARRAY * skyLineFromFile = new MEDSKYLINEARRAY(profilListFromFile.size(), profilSizeC );
1347 skyLineFromFile->setIndex(&index[0]);
1348 for (int i=1; i <= profilListFromFile.size() ; i++) {
1349 vector<int> aTmp(profilListFromFile[i-1].size()); // IPAL13481
1350 for (int j=0; j < profilListFromFile[i-1].size(); j++)
1351 aTmp[j] = (int) profilListFromFile[i-1][j];
1352 skyLineFromFile->setI(i,&aTmp[0]);
1353 //skyLineFromFile->setI(i,&profilListFromFile[i-1][0]);
1356 mySupport->setAll(false);
1357 mySupport->setpartial(skyLine,true);
1358 mySupport->setpartial_fromfile(skyLineFromFile,true);
1359 mySupport->setProfilNames(profilNameList);
1360 // cout << "Valeurs du skyline du SUPPORT partiel crée : " << *skyLine << endl;
1363 // Créer un driver spécifique pour les modes MED_FULL_INTERLACE et MED_NO_INTERLACE
1364 // serait plus efficace.
1365 bool anyGauss = (numberOfGaussPoint != vector<int>(numberOfGaussPoint.size(),1));
1367 MEDMEM_Array_ * Values;
1369 SCRUTE(mySupport->getNumberOfElements(MED_ALL_ELEMENTS) );
1370 SCRUTE(NumberOfTypes);
1371 SCRUTE(numberOfElementsOfTypeC[NumberOfTypes]-1);
1372 assert(mySupport->getNumberOfElements(MED_ALL_ELEMENTS) == (numberOfElementsOfTypeC[NumberOfTypes]-1) );
1373 // PAL16681. If NumberOfTypes == 1 then myValues is what should be
1374 // in a field value, inspite of InterlacingType
1375 if ( NumberOfTypes == 1 && modswt == med_2_3::MED_NO_INTERLACE )
1376 Values = new ArrayNoWg(myValues,
1378 numberOfElementsOfTypeC[NumberOfTypes]-1,
1380 &numberOfElementsOfTypeC[0],
1381 &numberOfGaussPoint[0],
1383 else if ( isNoInterlaceByType ) // PAL17011 (MEDMEM : no_interlace_by_type fields)
1384 Values = new ArrayByTypeWg(myValues,
1386 numberOfElementsOfTypeC[NumberOfTypes]-1,
1388 &numberOfElementsOfTypeC[0],
1389 &numberOfGaussPoint[0],
1392 Values = new ArrayFullWg(myValues,
1394 numberOfElementsOfTypeC[NumberOfTypes]-1,
1395 // Up : Prend en compte les profils et
1396 // Ne prend pas en compte le nbre de composantes et
1397 // le nombre de points de Gauss
1399 &numberOfElementsOfTypeC[0],
1400 &numberOfGaussPoint[0],
1402 // cout << "Valeurs du ArrayFullWg crée : " << endl <<
1403 // *(static_cast<ArrayFullWg*>(Values)) << endl;
1406 // PAL16681. If NumberOfTypes == 1 then myValues is what should be
1407 // in a field value, inspite of InterlacingType
1408 if ( NumberOfTypes == 1 && interlacingType == MED_EN::MED_NO_INTERLACE )
1409 Values = new ArrayNo(myValues,numberOfComponents,totalNumberOfElWg,
1411 else if ( isNoInterlaceByType ) // PAL17011 (MEDMEM : no_interlace_by_type fields)
1412 Values = new ArrayByType(myValues,numberOfComponents,totalNumberOfElWg,
1413 NumberOfTypes, &numberOfElementsOfTypeC[0], true,true);
1415 Values = new ArrayFull(myValues,numberOfComponents,totalNumberOfElWg,
1418 if (MED_FIELD_DRIVER<T>::_ptrField->_value != NULL)
1419 delete MED_FIELD_DRIVER<T>::_ptrField->_value;
1421 if ( NumberOfTypes != 1 && // PAL16681
1422 interlacingType == MED_EN::MED_NO_INTERLACE )
1424 // Convert MED_FULL_INTERLACE -> MED_NO_INTERLACE
1425 if (Values->getGaussPresence())
1426 MED_FIELD_DRIVER<T>::_ptrField->_value=ArrayConvert(*static_cast<ArrayFullWg*>(Values));
1428 MED_FIELD_DRIVER<T>::_ptrField->_value=ArrayConvert(*static_cast<ArrayFull* >(Values));
1433 MED_FIELD_DRIVER<T>::_ptrField->_value=Values;
1436 MED_FIELD_DRIVER<T>::_ptrField->_isRead = true ;
1438 MED_FIELD_DRIVER<T>::_ptrField->_support=mySupport; //Prévenir l'utilisateur ?
1443 template <class T> void MED_FIELD_RDONLY_DRIVER22<T>::write( void ) const
1444 throw (MEDEXCEPTION)
1446 throw MEDEXCEPTION("MED_FIELD_RDONLY_DRIVER22::write : Can't write with a RDONLY driver !");
1449 /*--------------------- WRONLY PART -------------------------------*/
1451 template <class T> GENDRIVER * MED_FIELD_WRONLY_DRIVER22<T>::copy(void) const
1453 return new MED_FIELD_WRONLY_DRIVER22<T>(*this);
1456 template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::read (void)
1457 throw (MEDEXCEPTION)
1459 throw MEDEXCEPTION("MED_FIELD_WRONLY_DRIVER22::read : Can't read with a WRONLY driver !");
1462 template <class T> void MED_FIELD_WRONLY_DRIVER22<T>::write(void) const
1463 throw (MEDEXCEPTION)
1465 const char * LOC = "MED_FIELD_WRONLY_DRIVER22::write(void) const " ;
1467 typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo;
1468 typedef typename MEDMEM_ArrayInterface<T,NoInterlace,Gauss>::Array ArrayNoWg;
1469 typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull;
1470 typedef typename MEDMEM_ArrayInterface<T,FullInterlace,Gauss>::Array ArrayFullWg;
1472 typedef map<MED_EN::medGeometryElement,GAUSS_LOCALIZATION<FullInterlace>*> locMapFull;
1473 typedef map<MED_EN::medGeometryElement,GAUSS_LOCALIZATION<NoInterlace>*> locMapNo;
1474 typedef map<MED_EN::medGeometryElement,GAUSS_LOCALIZATION_*> locMap;
1476 med_2_3::med_idt id = MED_FIELD_DRIVER22<T>::_medIdt;
1478 if (MED_FIELD_DRIVER<T>::_status!=MED_OPENED)
1479 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)<<": Method open must be called before method write.")) ;
1482 if ( ( MED_FIELD_DRIVER<T>::_fieldName.empty() ) &&
1483 ( MED_FIELD_DRIVER<T>::_ptrField->_name.empty() ) )
1484 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
1485 <<" neither <fieldName> is set in driver nor in object FIELD.")) ;
1487 // If _fieldName is not set in driver, try to use _ptrfield->_fieldName
1488 if ( ( MED_FIELD_DRIVER<T>::_fieldName.empty() ) &&
1489 ( !MED_FIELD_DRIVER<T>::_ptrField->_name.empty() ) )
1490 fieldName = MED_FIELD_DRIVER<T>::_ptrField->_name;
1492 fieldName = MED_FIELD_DRIVER<T>::_fieldName;
1494 //if ( ! MED_FIELD_DRIVER<T>::_ptrField->_isRead )
1495 // throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
1496 // <<" FIELD |"<<fieldName<<"| was not read but is being written"));
1499 if ( fieldName.size() > MED_TAILLE_NOM ) {
1500 fieldName.substr(0,MED_TAILLE_NOM);
1501 MESSAGE( "Be careful <fieldName> size must not be > MED_TAILLE_NOM, using fieldName : |"<< fieldName <<"|." );
1504 const SUPPORT * mySupport = MED_FIELD_DRIVER<T>::_ptrField->getSupport() ;
1506 throw MEDEXCEPTION(LOCALIZED(STRING(LOC)
1507 <<" There is no SUPPORT associated with FIELD : "
1508 << fieldName << "."));
1510 bool onAll = mySupport->isOnAllElements();
1511 const locMap & gaussModel = MED_FIELD_DRIVER<T>::_ptrField->_gaussModel;
1514 string meshName = mySupport->getMeshName();
1516 if ( meshName.size() > MED_TAILLE_NOM ) {
1517 meshName = meshName.substr(0,MED_TAILLE_NOM);
1518 MESSAGE( "Be careful <meshName> size must not be > MED_TAILLE_NOM, using meshName : |"<< meshName <<"|." );
1520 MED_EN::medEntityMesh entityType = mySupport->getEntity();
1522 // Reconstruit les listes contigues des noms de composantes et des unités
1523 // Les noms sont tronqués à MED_TAILLE_PNOM22
1525 int component_count=MED_FIELD_DRIVER<T>::_ptrField->getNumberOfComponents();
1526 string component_name(component_count*MED_TAILLE_PNOM22,' ') ;
1527 string component_unit(component_count*MED_TAILLE_PNOM22,' ') ;
1529 const string * listcomponent_name=MED_FIELD_DRIVER<T>::_ptrField->getComponentsNames() ;
1530 const string * listcomponent_unit=MED_FIELD_DRIVER<T>::_ptrField->getMEDComponentsUnits() ;
1531 if ( ! listcomponent_name || ! listcomponent_unit )
1532 throw MEDEXCEPTION(LOCALIZED(STRING(LOC) <<" Udefined components of FIELD : "
1533 << fieldName << "."));
1535 for (int i=0; i < component_count ; i++) {
1536 length = min(MED_TAILLE_PNOM22,(int)listcomponent_name[i].size());
1537 component_name.replace(i*MED_TAILLE_PNOM22,length,
1538 listcomponent_name[i],0,length);
1539 length = min(MED_TAILLE_PNOM22,(int)listcomponent_unit[i].size());
1540 component_unit.replace(i*MED_TAILLE_PNOM22,length,
1541 listcomponent_unit[i],0,length);
1544 MESSAGE("using component_name=|"<<component_name<<"|");
1545 MESSAGE("using component_unit=|"<<component_unit<<"|");
1547 MED_EN::med_type_champ ValueType=MED_FIELD_DRIVER<T>::_ptrField->getValueType() ;
1549 MESSAGE("Template Type =|"<<ValueType<<"|");
1551 // Vérifier si le champ existe déjà
1552 char champName[MED_TAILLE_NOM+1];
1553 char * compName, * compUnit ;
1554 med_2_3::med_type_champ type ;
1556 int n = med_2_3::MEDnChamp(id,0);
1558 for (int i=1; i<=n; i++) {
1559 nbComp = med_2_3::MEDnChamp(id,i);
1560 compName = new char[MED_TAILLE_PNOM22*nbComp+1];
1561 compUnit = new char[MED_TAILLE_PNOM22*nbComp+1];
1562 err = med_2_3::MEDchampInfo(id,i,champName,&type,compName,compUnit,nbComp);
1564 if (!strcmp(champName,fieldName.c_str()) ) {
1574 if (nbComp != component_count)
1575 throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
1576 <<": Field exist in file, but number of component are different : "
1577 <<nbComp<<" in file and "
1578 <<component_count<<" in memory."
1581 // component name and unit
1583 MESSAGE(LOC<<" Component name in file : "<<compName);
1584 MESSAGE(LOC<<" Component name in memory : "<<component_name);
1585 MESSAGE(LOC<<" Component unit in file : "<<compUnit);
1586 MESSAGE(LOC<<" Component unit in memory : "<<component_unit);
1591 // Verify the field isn't yet created
1593 string dataGroupName = "/CHA/";
1594 dataGroupName += fieldName;
1595 MESSAGE(LOC << "|" << dataGroupName << "|" );
1596 med_2_3::med_idt gid = H5Gopen(id, dataGroupName.c_str() );
1600 err=med_2_3::MEDchampCr(id,
1601 const_cast <char*> (fieldName.c_str()),
1602 (med_2_3::med_type_champ) ValueType,
1603 const_cast <char*> ( component_name.c_str() ),
1604 const_cast <char*> ( component_unit.c_str() ),
1607 throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
1608 << ": Error MEDchampCr : "<<err
1617 // On s'assure que le champ est dans le bon type d'entrelacement.
1618 // REM : Il faudrait un driver par type d'entrelacement, ce qui eviterait
1619 // de doubler l'utilisation de la taille mémoire si le champ n'est pas dans
1621 FIELD<T,FullInterlace> * myField = 0;
1622 MED_EN::medModeSwitch interlacingType = MED_FIELD_DRIVER<T>::_ptrField->getInterlacingType();
1623 bool isFullInterlace = ( interlacingType == MED_EN::MED_FULL_INTERLACE );
1624 bool isNoInterlaceByType = ( interlacingType == MED_EN::MED_NO_INTERLACE_BY_TYPE );//PAL17011
1625 med_2_3::med_mode_switch modswt = med_2_3::MED_FULL_INTERLACE;
1627 if ( isFullInterlace ) {
1628 myField = MED_FIELD_DRIVER<T>::_ptrField;
1630 else if ( isNoInterlaceByType ) {
1631 // PAL17011, no need to convert, that is what this improvement is needed for
1632 modswt = med_2_3::MED_NO_INTERLACE;
1635 myField = FieldConvert( *((FIELD<T,NoInterlace>*) MED_FIELD_DRIVER<T>::_ptrField ));
1638 // Il est necessaire de calculer le tableau
1639 // du nombre d'entités cumulées de chaque type géométrique du maillage
1640 // pour convertir les profils de la numérotation globale
1641 // à la numérotation locale au type géométrique.
1642 // Pour celà on établit ce tableau à partir de l'objet MESH si la relation SUPPORT-MESH existe.
1643 // Si le maillage existe dans le fichier MED on essaye également de reconstituer ce tableau
1644 // pour vérifier la cohérence des informations.
1645 // Si la relation SUPPRT-MESH n'esiste pas on constitue le tableau uniquement à partir du fichier qui
1646 // doit alors obligatoirement contenir le maillage.
1647 const int * number, *numberIndex = 0;
1649 vector<string> profilNameList;
1650 vector<MED_EN::medGeometryElement> meshGeoType;
1651 vector<int> meshNbOfElOfType;
1652 vector<int> meshNbOfElOfTypeC;
1653 vector<MED_EN::medGeometryElement> fileMeshGeoType;
1654 vector<int> fileMeshNbOfElOfType;
1655 vector<int> fileMeshNbOfElOfTypeC;
1656 med_2_3::med_int fileHasMesh=0;
1660 number = mySupport->getNumber(MED_ALL_ELEMENTS);
1661 numberIndex = mySupport->getNumberIndex();
1662 profilNameList=mySupport->getProfilNames();
1664 fileHasMesh = ( med_2_3::MEDdimLire(id, const_cast<char *>(meshName.c_str())) > 0);
1665 MESH * meshPtr = mySupport->getMesh();
1668 this->getMeshGeometricTypeFromFile(id, meshName,
1670 fileMeshGeoType,fileMeshNbOfElOfType,fileMeshNbOfElOfTypeC);
1673 this->getMeshGeometricTypeFromMESH( meshPtr, entityType,meshGeoType,
1678 if ( ( fileMeshGeoType != meshGeoType ) || (fileMeshNbOfElOfTypeC != meshNbOfElOfTypeC) )
1679 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Error while getting mesh information from file for FIELD "<< fieldName
1680 << " on entity " << MED_EN::entNames[entityType]
1681 << " with (it,or) = ("
1682 << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
1683 << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << ")"
1684 << " on mesh " << meshName
1685 << " : geometric types or number of elements by type differs from MESH object !"
1691 if ( !fileHasMesh && meshPtr==0 )
1692 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Error while getting mesh information for FIELD "<< fieldName
1693 << " on entity " << MED_EN::entNames[entityType]
1694 << " with (it,or) = ("
1695 << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
1696 << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << ")"
1697 << " on mesh " << meshName
1698 << " : SUPPORT must contain a valid MESH reference or file must contain the associated MESH."
1703 if (fileHasMesh && !meshPtr) {
1704 meshNbOfElOfTypeC = fileMeshNbOfElOfTypeC;
1705 meshGeoType = fileMeshGeoType;
1706 meshNbOfElOfType = fileMeshNbOfElOfType;
1710 const MED_EN::medGeometryElement * types = mySupport->getTypes() ;
1711 int numberOfTypes = mySupport->getNumberOfTypes() ;
1712 int numberOfElForMED = -1;
1713 const T * value = NULL;
1715 // on boucle sur tout les types pour ecrire les tableaux de valeur
1716 for (int typeNo=0;typeNo<numberOfTypes;typeNo++) {
1718 int numberOfElements = mySupport->getNumberOfElements(types[typeNo]) ;
1719 //UP : prend en compte les profils, pas les points de Gauss
1721 //value = MED_FIELD_DRIVER<T>::_ptrField->getRow(index) ;
1722 // rem 1 : le getRow du Array est différent de celui du FIELD si le SUPPORT contient
1723 // des profils (les indices des valeurs ne se suivent pas forcément)
1724 // rem 2 : Afin de respecter la norme MEDFICHIER, les indices contenus dans les
1725 // profils doivent être croissant
1728 if ( isNoInterlaceByType ) { //PAL17011
1729 value = MED_FIELD_DRIVER<T>::_ptrField->getValueByType(typeNo+1);
1730 //((ArrayNoByType *)MED_FIELD_DRIVER<T>::_ptrField->getArray())->getValueByType(i+1);
1733 value = myField->getRow(index);
1735 profilName=MED_NOPFL;
1736 numberOfElForMED = numberOfElements;
1740 if ( isNoInterlaceByType ) { //PAL17011
1741 value = MED_FIELD_DRIVER<T>::_ptrField->getValueByType(typeNo+1);
1744 value = myField->getRow(number[index-1]);
1746 // PAL16854(Partial support on nodes) ->
1747 //profilName = (profilNameList.size()>typeNo) ? profilNameList[typeNo].substr(0,MED_TAILLE_NOM) : MED_NOPFL;
1748 if (profilNameList[typeNo].size()>MED_TAILLE_NOM)
1749 profilName = profilNameList[typeNo].substr(0,MED_TAILLE_NOM);
1751 profilName= profilNameList[typeNo];
1753 // Rem : Si le SUPPORT n'est pas onAll mais que pour un type géométrique donné le nom
1754 // du profil associé est MED_NOPFL alors le profil n'est pas écrit dans le fichier MED.
1755 // Car en MEDMEMOIRE si le champ repose sur des éléments de deux types géométriques
1756 // différents et est défini sur tous les éléments d'un type géométrique
1757 // mais pas de l'autre, il existe tout de même des profils sur les deux types géométriques.
1758 // Ce n'est pas le cas en MEDFICHIER.
1759 vector<med_2_3::med_int> profil(&number[index-1],&(number[index-1])+numberOfElements);
1762 if ( entityType != MED_EN::MED_NODE ) // PAL16854(Partial support on nodes)
1764 // Trouve l'index du type géométrique dans la liste des types géométriques du maillage
1765 // correspondant au type géométrique du champ en cours de traitement
1766 vector<MED_EN::medGeometryElement>::iterator meshTypeNoIt =
1767 find(meshGeoType.begin(),meshGeoType.end(),types[typeNo]);
1768 if ( meshTypeNoIt == meshGeoType.end() )
1769 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Can't find "<< MED_EN::geoNames[types[typeNo]]
1770 << " on entity " << MED_EN::entNames[entityType]
1771 << " in geometric type list of mesh " << meshName
1774 meshTypeNo = meshTypeNoIt - meshGeoType.begin();
1777 if ( profilName == MED_NOPFL && profil.size() != meshNbOfElOfType[meshTypeNo] )
1778 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Error while creating profil for FIELD "<< fieldName
1779 << " on entity " << MED_EN::entNames[entityType]
1780 << " and geometric type " << MED_EN::geoNames[types[typeNo]] << " with (it,or) = ("
1781 << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
1782 << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), with profilName "
1783 << profilName << " on mesh " << meshName
1784 << " : There is no profileName but profilsize (" <<profil.size()
1785 << ") differs from number of elements in associated MESH ("
1786 << meshNbOfElOfType[meshTypeNo] << ")."
1790 //REM : Ce n'est pas évident, mais lorsqu'il y a un profil, le nombre de valeurs
1791 // que l'on indique à MEDchampEcr est le nombre de valeurs sans profil, d'où
1792 // le nombre d'éléments du maillage sur le type géométrique courant.
1793 numberOfElForMED = meshNbOfElOfType[meshTypeNo];
1795 for (int ind=0;ind < numberOfElements;++ind) {
1796 // cout << "number["<<index-1<<"]="<<number[index-1]<<endl;
1797 // cout << "profil1["<<ind<<"]="<<profil[ind]<<endl;
1798 profil[ind]-=meshNbOfElOfTypeC[meshTypeNo];
1799 // cout << "profil2["<<ind<<"]="<<profil[ind]<<endl;
1802 if ( profil[numberOfElements-1] > numberOfElForMED )
1803 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Error while creating profil for FIELD "<< fieldName
1804 << " on entity " << MED_EN::entNames[entityType]
1805 << " and geometric type " << MED_EN::geoNames[types[typeNo]] << " with (it,or) = ("
1806 << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
1807 << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), with profilName "
1808 << profilName << " on mesh " << meshName
1809 << " : profil["<<numberOfElements-1<<"]=" << profil[numberOfElements-1]
1810 << " must not be superior to field size without profil : "
1815 if ( med_2_3::MEDprofilEcr(id,
1818 const_cast<char *>(profilName.c_str())) < 0)
1820 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Error while writing "<< numberOfElements
1821 << " values for MED profil "<< profilName
1826 bool anyGauss = MED_FIELD_DRIVER<T>::_ptrField->getGaussPresence();
1827 string locName=MED_NOGAUSS;
1829 // cout << endl << "Nombre de points de Gauss à l'écriture de " << fieldName
1830 // << " pour le type géométrique : " << MED_EN::geoNames[types[typeNo]]
1831 // << " : " << myField->getNumberOfGaussPoints(types[typeNo]) << endl;
1832 // cout << *mySupport << endl;
1834 const GAUSS_LOCALIZATION_ * locPtr=0;
1835 locMap::const_iterator it;
1836 if ( ( it = gaussModel.find(types[typeNo])) != gaussModel.end() )
1837 locPtr = (*it).second;
1839 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Error while creating Gauss Model for FIELD "<< fieldName
1840 << " on entity " << MED_EN::entNames[entityType]
1841 << " and geometric type " << MED_EN::geoNames[types[typeNo]] << " with (it,or) = ("
1842 << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
1843 << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), with profilName "
1844 << profilName << " on mesh " << meshName
1845 << " : Can't find a Gauss localisation model for this geometric type"
1850 if ( locPtr->getInterlacingType() == MED_EN::MED_FULL_INTERLACE ) {
1851 const GAUSS_LOCALIZATION<FullInterlace> & loc=*(static_cast<const GAUSS_LOCALIZATION<FullInterlace> * >(locPtr));
1852 ngauss = loc.getNbGauss();
1853 locName=loc.getName();
1854 err=med_2_3::MEDgaussEcr(id,
1855 (med_2_3::med_geometrie_element) loc.getType(),
1856 (med_2_3::med_float *) loc.getRefCoo().getPtr(),
1857 med_2_3::MED_FULL_INTERLACE,
1858 (med_2_3::med_int) ngauss,
1859 (med_2_3::med_float *) loc.getGsCoo().getPtr(),
1860 (med_2_3::med_float *) (&loc.getWeight()[0]),
1861 const_cast<char *> (locName.c_str())
1864 const GAUSS_LOCALIZATION<NoInterlace> & loc=*(static_cast<const GAUSS_LOCALIZATION<NoInterlace> * >(locPtr));
1865 ngauss = loc.getNbGauss();
1866 locName=loc.getName();
1867 err=med_2_3::MEDgaussEcr(id,
1868 (med_2_3::med_geometrie_element) loc.getType(),
1869 (med_2_3::med_float *) loc.getRefCoo().getPtr(),
1870 med_2_3::MED_NO_INTERLACE,
1871 (med_2_3::med_int) ngauss,
1872 (med_2_3::med_float *) loc.getGsCoo().getPtr(),
1873 (med_2_3::med_float *) (&loc.getWeight()[0]),
1874 const_cast<char *> (locName.c_str())
1880 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Error while writing Gauss Model for FIELD "<< fieldName
1881 << " on entity " << MED_EN::entNames[entityType]
1882 << " and geometric type " << MED_EN::geoNames[types[typeNo]]
1886 //numberOfElForMED *= mySupport->getNumberOfGaussPoints(types[typeNo]); //Deplacer la méthode dans FIELD
1887 numberOfElForMED *= ngauss;
1890 MESSAGE("MED_FIELD_DRIVER22<T>::_medIdt : "<<id);
1891 MESSAGE("meshName.c_str() : "<<meshName.c_str());
1892 MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getName() : "<<MED_FIELD_DRIVER<T>::_ptrField->getName());
1893 MESSAGE("MED_FIELD_DRIVER<T>::_fieldName : "<<MED_FIELD_DRIVER<T>::_fieldName);
1894 MESSAGE("value : "<<value);
1895 MESSAGE("numberOfElements : "<<numberOfElements);
1896 MESSAGE("numberOfElForMED : "<<numberOfElForMED);
1897 MESSAGE("entityType : "<<MED_EN::entNames[entityType]);
1898 MESSAGE("types[i] : "<<MED_EN::geoNames[types[typeNo]]);
1899 if (myField) //myField may be NULL (PAL17011)
1900 MESSAGE("NumberOfGaussPoint[i] : "<<myField->getNumberOfGaussPoints(types[typeNo]));
1901 MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber());
1902 MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getTime() : "<<MED_FIELD_DRIVER<T>::_ptrField->getTime());
1903 MESSAGE("MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber() : "<<MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber());
1905 // Rem 1 : le nombre d'éléments passé à MEDchampEcr ne doit pas tenir compte de la taille
1906 // des profils : c'est la taille du champ sans profil.
1907 err=med_2_3::MEDchampEcr(id,
1908 const_cast <char*> ( meshName.c_str()) ,
1909 const_cast <char*> ( fieldName.c_str()),
1910 (unsigned char*)value, modswt,//med_2_3::MED_FULL_INTERLACE,- PAL17011
1912 //UP : prend en compte le nombre de points de Gauss mais
1913 // pas le nombre de composantes
1914 const_cast <char*> ( locName.c_str()),
1916 const_cast <char *> (profilName.c_str()), med_2_3::MED_COMPACT,
1917 (med_2_3::med_entite_maillage)entityType,
1918 (med_2_3::med_geometrie_element)types[typeNo],
1919 MED_FIELD_DRIVER<T>::_ptrField->getIterationNumber(),
1920 " ", // A FAIRE : IMPLEMENTER L'UNITE DU PAS DE TEMPS!
1921 MED_FIELD_DRIVER<T>::_ptrField->getTime(),
1922 MED_FIELD_DRIVER<T>::_ptrField->getOrderNumber()
1925 if (err < MED_VALID ) {
1926 if ( !isFullInterlace )
1928 throw MEDEXCEPTION(LOCALIZED( STRING(LOC) <<": Error while writing "<< numberOfElements
1929 << " values for FIELD "<< fieldName
1930 << " on entity " << MED_EN::entNames[entityType]
1931 << " and geometric type " << MED_EN::geoNames[types[typeNo]]
1932 << " with (it,or) = ("
1933 << MED_FIELD_DRIVER<T>::_ptrField->_iterationNumber << ","
1934 << MED_FIELD_DRIVER<T>::_ptrField->_orderNumber << "), with profilName "
1935 << profilName << " on mesh " << meshName
1940 index += numberOfElements ; //Ne doit pas prendre en compte le nombre de points de GAUSS
1941 //ni les composantes.
1944 if ( !isFullInterlace ) delete myField;
1950 /*--------------------- RDWR PART -------------------------------*/
1952 template <class T> GENDRIVER * MED_FIELD_RDWR_DRIVER22<T>::copy(void) const
1954 return new MED_FIELD_RDWR_DRIVER22<T>(*this);
1957 template <class T> void MED_FIELD_RDWR_DRIVER22<T>::write(void) const
1958 throw (MEDEXCEPTION)
1960 BEGIN_OF("MED_FIELD_RDWR_DRIVER22::write(void)");
1961 MED_FIELD_WRONLY_DRIVER22<T>::write();
1962 END_OF("MED_FIELD_RDWR_DRIVER22::write(void)");
1965 template <class T> void MED_FIELD_RDWR_DRIVER22<T>::read (void)
1966 throw (MEDEXCEPTION)
1968 BEGIN_OF("MED_FIELD_RDWR_DRIVER22::read(void)");
1969 MED_FIELD_RDONLY_DRIVER22<T>::read();
1970 END_OF("MED_FIELD_RDWR_DRIVER22::read(void)");
1973 } //End namespace MEDMEM
1974 /*-----------------------------------------------------------------*/
1976 #endif /* MED_FIELD_DRIVER_HXX */