00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef MEDMEM_EnsightUtils_HeaderFile
00025 #define MEDMEM_EnsightUtils_HeaderFile
00026
00027 #include "MEDMEM_GenDriver.hxx"
00028 #include "MEDMEM_Exception.hxx"
00029 #include "MEDMEM_DriverTools.hxx"
00030 #include "MEDMEM_Mesh.hxx"
00031
00032
00033 #include <set>
00034 #include <float.h>
00035 #include <cmath>
00036
00037 #ifdef WNT
00038 #define isnan _isnan
00039 #endif
00040
00041 namespace MEDMEM {
00042
00043
00048
00049
00050 enum EnSightFormat { ENSIGHT_6, ENSIGHT_GOLD };
00051
00052 void MEDMEM_EXPORT setEnSightFormatForWriting (EnSightFormat format, bool isBinary);
00053
00054 EnSightFormat getEnSightFormatForWriting();
00055 bool isBinaryEnSightFormatForWriting();
00056
00057
00068
00069
00070 void MEDMEM_EXPORT setIgnoreIncompatibility(bool toIgnore=true);
00071 }
00072
00073 namespace MEDMEM {
00074 class ENSIGHT_MESH_RDONLY_DRIVER;
00075 class ENSIGHT_FIELD_RDONLY_DRIVER;
00076 class ENSIGHT_MESH_WRONLY_DRIVER;
00077 class ENSIGHT_FIELD_WRONLY_DRIVER;
00078 }
00079
00080
00081 namespace MEDMEM_ENSIGHT {
00082
00083
00084 class _CaseFileDriver;
00085 class _CaseFileDriver_User;
00086 struct _InterMed;
00087 struct _SubPart;
00088 struct _SubPartDesc;
00089 struct _Support;
00090 typedef std::set< _SubPartDesc > _SupportDesc;
00091
00092 using namespace MED_EN;
00093 using namespace MEDMEM;
00094 using namespace std;
00095
00096
00101 STRING compatibilityPb(const string& exceptionText);
00102
00103
00107 bool toIgnoreIncompatibility();
00108
00109
00111 bool contains( const char* what, const char* inString );
00112
00113
00118 struct TEnSightElemType
00119 {
00120 string _name;
00121 vector<int> _medIndex;
00122 medGeometryElement _medType;
00123 };
00124
00128 const TEnSightElemType& getEnSightType(medGeometryElement medType);
00129
00130
00134 const TEnSightElemType& getEnSightType(const string& typeName);
00135
00136
00140 inline bool isGhostType(const string& typeName)
00141 { return ( typeName[0] == 'g' && typeName[1] == '_'); }
00142
00143
00147 const int MAX_LINE_LENGTH = 80;
00148
00149
00153 const int MAX_FIELD_NAME_LENGTH = 19;
00154
00155
00159 const string ILLEGAL_FIELD_NAME_CHARACTERS = " !@#$^()[]*/+-";
00160
00161
00165 const int INT_WIDTH_6 = 8;
00166 const int INT_WIDTH_GOLD = 10;
00167 const int FLT_WIDTH = 12;
00168
00169
00173 const int SPACE_DIM = 3;
00174
00175
00179 static const char* TIME_STEP_BEG = "BEGIN TIME STEP";
00180 static const char* TIME_STEP_END = "END TIME STEP";
00181 const size_t TIME_STEP_BEG_LEN = 15;
00182 const size_t TIME_STEP_END_LEN = 13;
00183
00184
00185
00189 static inline float _toFloat (const double & value) {
00190 if ( value > FLT_MAX ) return FLT_MAX;
00191 if ( value < -FLT_MAX ) return -FLT_MAX;
00192 if ( isnan( value )) throw MEDEXCEPTION(compatibilityPb("NaN value not allowed"));
00193 return float( value );
00194 }
00195 static inline float _toFloat (const int & value) { return float( value ); }
00196 static inline float _toFloat (const long & value) { return float( value ); }
00197
00198
00206
00207
00208 class _CaseFileDriver
00209 {
00210 public:
00211 _CaseFileDriver(const string& fileName, const _CaseFileDriver_User* creator);
00212 ~_CaseFileDriver();
00213
00214 void read() throw (MEDEXCEPTION);
00215
00216
00217
00218
00219
00220 int getNbMeshes() const;
00221
00223 void setDataFileName(const int meshIndex, ENSIGHT_MESH_RDONLY_DRIVER* meshDriver);
00224
00225
00226
00227
00228
00229 int getNbVariables() const;
00230
00231 int getNbVarSteps(const int variableIndex);
00232
00234 int getVariableIndex(const string & varName) const;
00235
00237 int setDataFileName(const int varIndex,
00238 const int stepIndex,
00239 ENSIGHT_FIELD_RDONLY_DRIVER* fieldDriver);
00240
00241
00242
00243
00244
00246 void addMesh(const ENSIGHT_MESH_WRONLY_DRIVER* meshDriver);
00247
00249 void addField(const ENSIGHT_FIELD_WRONLY_DRIVER * fieldDriver);
00250
00252 void write() throw (MEDEXCEPTION);
00253
00254 private:
00255
00257 bool checkWasRead() const throw (MEDEXCEPTION);
00258
00260 int fixWildCardName(const int timeStep,
00261 const std::string & ts,
00262 const std::string & fs,
00263 std::string & fileName,
00264 std::string & time);
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 struct _Model {
00283 string _timeSetNumber, _fileSetNumber;
00284 string _fileName;
00285 string _change_coords_only;
00286 };
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309 struct _Variable {
00310 string _type;
00311 string _name;
00312 string _timeSetNumber, _fileSetNumber;
00313 string _fileNameOrData;
00314 };
00315
00316
00317
00318
00319
00320
00321 struct _FileSet {
00322 int _number;
00323 std::list<int> _nbStepsInFile;
00324 std::list<std::string> _fileIndex;
00325 };
00326
00327
00328 struct _TimeSet {
00329 int _number;
00330 std::vector<std::string> _fileIndex;
00331 std::vector<std::string> _times;
00332
00333 bool operator==(const _TimeSet& ts) const
00334 { return ( _fileIndex == ts._fileIndex && _times == ts._times ); }
00335 };
00336
00337 private:
00338
00339 std::string _fileName;
00340 std::string _directory;
00341 EnSightFormat _format;
00342 _Model _model;
00343 std::map< int, _Variable> _variables;
00344 std::map< int, _TimeSet > _timeSets;
00345 std::map< int, _FileSet > _fileSets;
00346
00347 const _CaseFileDriver_User* _user;
00348
00349 std::list<ENSIGHT_MESH_WRONLY_DRIVER*> _meshDrivers;
00350
00351 typedef std::map<std::string, std::list< ENSIGHT_FIELD_WRONLY_DRIVER* > > TFieldDriversByName;
00352 TFieldDriversByName _fieldDrivers;
00353
00355 bool _blocked;
00356 };
00357
00358
00363
00364
00365 class MEDMEM_EXPORT _CaseFileDriver_User: public GENDRIVER
00366 {
00367 protected:
00368
00369 _CaseFileDriver_User(const std::string& caseFileName="",
00370 MED_EN::med_mode_acces mode=MED_EN::RDWR);
00371
00372 const std::string& getCaseFileName() const { return GENDRIVER::_fileName; }
00373
00374 const std::string& getDataFileName() const { return _dataFileName; }
00375
00376 bool isGoldFormat() const { return _isGoldFormat; }
00377
00379 bool isSingleFileMode() const { return _singleFileMode; }
00380
00382 int getIndexInDataFile() const { return _indexInDataFile; }
00383
00385 bool isTransientMode() const { return _transientMode; }
00386
00388 double getTime() const { return atof(_time.c_str()); }
00389
00390
00391
00392
00393
00395 void setInterData(_InterMed* imed);
00396
00398 _InterMed* getInterData();
00399
00400 _SubPart* getSubPart(const _SubPartDesc & descriptor) throw (MEDEXCEPTION);
00401
00402 _Support* getSupport(const _SupportDesc & descriptor,
00403 const medEntityMesh entity) throw (MEDEXCEPTION);
00404
00405
00406 public:
00408 int getPartNumber(const SUPPORT* support) const;
00409
00410 static bool canOpenFile(const string& fileName, med_mode_acces mode);
00411
00412 static void getSupportNodes(const SUPPORT* sup, map<int, int> & nodeIds);
00413
00415 static bool isBinaryDataFile(const string& dataFileName);
00416
00417 static bool isTimeStepBeginning(const string& line)
00418 { return ( line == TIME_STEP_BEG ); }
00419
00420 static bool isTimeStepEnd(const char* line)
00421 { return ( strncmp( line, TIME_STEP_END, TIME_STEP_END_LEN ) == 0 ); }
00422
00423 static bool isToWriteEntity(const medEntityMesh entity, const GMESH* mesh);
00424
00425 ~_CaseFileDriver_User();
00426
00427 void merge( const GENDRIVER& driver);
00428
00429 private:
00430
00431 friend class _CaseFileDriver;
00432
00433
00434 std::string _dataFileName;
00435 bool _isGoldFormat;
00436 bool _transientMode;
00437 bool _singleFileMode;
00438 int _indexInDataFile;
00439 std::string _time;
00440
00441 _InterMed* _imed;
00442 string _imedMapKey;
00443
00444 };
00445
00446
00450
00451
00452 struct _SubPartDesc: public std::pair<int, std::string >
00453 {
00454 _SubPartDesc(int partNumber=-1,
00455 const std::string& typeName="")
00456 : std::pair<int, std::string > ( partNumber, typeName ) {}
00457
00458 const int& partNumber() const { return this->first; }
00459 const string& typeName() const { return this->second; }
00460
00461 static _SubPartDesc globalCoordDesc() { return _SubPartDesc(-1,"coordinates"); }
00462 };
00463
00464 std::ostream& operator << (std::ostream& os, const _SubPartDesc& desc);
00465
00466
00471
00472
00473 struct _SubPart: public _SubPartDesc
00474 {
00475
00476
00477
00478
00479
00480
00481
00482 int myNbCells;
00483 int myCellGroupIndex;
00484 _groupe::TMailleIter myFirstCell;
00485
00486 int myNbNodes;
00487 mutable int myNodeGroupIndex;
00488 _maille::TNoeud myFirstNode;
00489
00490 _SubPart(int partNumber=-1,
00491 const std::string& typeName="")
00492 : _SubPartDesc(partNumber,typeName),
00493 myNbCells(0), myCellGroupIndex(-1),
00494 myNbNodes(0), myNodeGroupIndex(-1)
00495 {}
00496
00497 _SubPartDesc getDescriptor() const { return _SubPartDesc( partNumber(), typeName() ); }
00498 };
00499
00500
00504
00505
00506 struct _Support
00507 {
00508 _groupe * myCellGroup;
00509 _groupe * myNodeGroup;
00510
00511 _Support(): myCellGroup(0), myNodeGroup(0) {}
00512
00513 void setGroup( _groupe* g );
00514 SUPPORT* medSupport( medEntityMesh entity );
00515
00516 int getIndex( const pair<const int,_noeud>& node);
00517 int getIndex( const _groupe::TMaille& cell);
00518
00519
00520
00521 };
00522
00523
00527
00528
00529 struct _InterMed : public _intermediateMED
00530 {
00531 MESH* _medMesh;
00532 bool _isOwnMedMesh;
00533 int _nbUsers;
00534
00535 bool _needSubParts;
00536
00537 map< _SubPartDesc, _SubPart > _subPartDescribed;
00538
00539 map< _SupportDesc, _Support > _supportDescribed;
00540
00541 void addSubPart(const _SubPart& subPart);
00542
00543 ~_InterMed();
00544 };
00545
00546
00550
00551
00552 template <typename T> struct _ValueOwner {
00553 T * myValues;
00554 _ValueOwner(T* values):myValues(values) {}
00555 ~_ValueOwner() { if ( myValues ) delete [] myValues; }
00556 operator T*() { return myValues; }
00557 private:
00558 _ValueOwner(const _ValueOwner& other) {}
00559 };
00560
00561 typedef _ValueOwner<char> TStrOwner;
00562 typedef _ValueOwner<int> TIntOwner;
00563 typedef _ValueOwner<double> TDblOwner;
00564 typedef _ValueOwner<float> TFltOwner;
00565
00566
00570
00571
00572 template <typename T> class _ValueIterator
00573 {
00574 protected:
00575 const T* myPtr;
00576 int myDelta;
00577 public:
00578 _ValueIterator()
00579 : myPtr(zeroPtr()), myDelta( 0 ) {}
00580
00581 _ValueIterator(const T* values, int delta): myPtr(values-delta), myDelta(delta) {}
00582
00583 const T & next() { myPtr += myDelta; return *myPtr; }
00584
00585 static const T* zeroPtr() { static T a0 = 0; return &a0; }
00586 };
00587
00588
00592
00593
00594 class _ASCIIFileReader
00595 {
00596 public:
00597 _ASCIIFileReader(const string& fileName) throw (MEDEXCEPTION);
00598
00599 ~_ASCIIFileReader();
00600
00601 bool eof();
00602
00603 string getWord();
00604
00605 int getInt() throw (MEDEXCEPTION) {
00606 if ( eof() ) throw MEDEXCEPTION("Unexpected EOF");
00607 return strtol(_ptr, &_ptr, 10);
00608 }
00609 float getReal() throw (MEDEXCEPTION) {
00610 if ( eof() ) throw MEDEXCEPTION("Unexpected EOF");
00611 #ifdef WNT
00612 #else
00613 return strtof(_ptr, &_ptr);
00614 #endif
00615 }
00617 void toNextLine() {
00618 while (isspace(*_ptr)) if ((++_ptr)[-1]=='\n') break;
00619 }
00620 char* getLine() throw (MEDEXCEPTION);
00621
00622 const char* getCurrentPtr() const { return _ptr; }
00623
00624 bool lookAt( const char* text );
00625
00626 bool isTimeStepBeginning();
00627
00628 bool isTimeStepEnd();
00629
00631 void skip(int nbVals, int nbPerLine, int valWidth);
00632
00634 void skip(int width, int nbLines);
00635
00636 template <class T>
00637 char* convertReals( const int nbValues,
00638 const char* undefValue = 0,
00639 set<int>* undefIndices = 0,
00640 const vector<int>* partialIndices = 0,
00641 const int nbPartialComponents = 0)
00642 throw (MEDEXCEPTION)
00643 {
00644 T* result = new T[ nbValues ];
00645 T* ptrT = result;
00646 if ( undefValue )
00647 {
00648 undefIndices->clear();
00649 float undef = atof( undefValue );
00650 for ( int i = 0; i < nbValues; ++i, ++ptrT ) {
00651 float value = getReal();
00652 (*ptrT) = (T) value;
00653 if ( value == undef )
00654 undefIndices->insert( undefIndices->end(), i+1 );
00655 }
00656 }
00657 else if ( partialIndices )
00658 {
00659
00660
00661 int shift = 1;
00662 for ( int j = 1; j <= nbPartialComponents; ++j ) {
00663 vector<int>::const_iterator i = partialIndices->begin(), iEnd = partialIndices->end();
00664 while ( i != iEnd )
00665 result[ *i++ - shift ] = (T) getReal();
00666 shift += nbValues;
00667 }
00668 }
00669 else
00670 {
00671 for ( int i = 0; i < nbValues; ++i, ++ptrT )
00672 (*ptrT) = (T) getReal();
00673 }
00674 return (char*) result;
00675 }
00676
00677
00678
00680 static int split(const string& str,
00681 string & part1,
00682 string & part2,
00683 const char separator=' ',
00684 const bool fromBack=false);
00685
00687 static int split(const string& str,
00688 std::list<string> & parts,
00689 const char separator=' ',
00690 const bool fromBack=false);
00691
00693 static bool isDigit(const string& str, const bool real=false);
00694
00695 private:
00696
00697 int _file;
00698 char* _start;
00699 char* _ptr;
00700 char* _eptr;
00701
00702 bool _isWin;
00703
00704 };
00705
00706
00707
00711
00712
00713 class _BinaryFileReader
00714 {
00715 public:
00716 _BinaryFileReader(const string& fileName) throw (MEDEXCEPTION);
00717
00718 ~_BinaryFileReader();
00719
00720 void rewind();
00721
00722 void swapBytes()
00723 { _mySwapBytes = true; }
00724
00725 int moreValuesAvailable() const;
00726
00727 bool eof();
00728
00729 void skip(int size) throw (MEDEXCEPTION);
00730
00731 void skipTimeStepBeginning() throw (MEDEXCEPTION);
00732
00733 char* getLine() throw (MEDEXCEPTION)
00734 { return get<char>(80); }
00735
00736 int* getInt(int nb) throw (MEDEXCEPTION)
00737 { return get<int>(nb,_mySwapBytes); }
00738
00739 float* getFlt(int nb) throw (MEDEXCEPTION)
00740 { return get<float>(nb,_mySwapBytes); }
00741
00742 ssize_t getPosition() const { return _pos; }
00743
00744 template <class T>
00745 char* convertReals( const int nbValues,
00746 const char* undefValue = 0,
00747 set<int>* undefIndices = 0,
00748 const vector<int>* partialIndices = 0,
00749 const int nbPartialComponents = 0 )
00750 throw (MEDEXCEPTION)
00751 {
00752 T* result = new T[ nbValues ];
00753 T* ptrT = result, *endT = result + nbValues;
00754 int nb = partialIndices ? partialIndices->size() * nbPartialComponents : nbValues;
00755 TFltOwner fltData( getFlt( nb ));
00756 float* ptrFlt = fltData;
00757 if ( undefValue )
00758 {
00759 undefIndices->clear();
00760 float undef = atof( undefValue );
00761 while ( ptrT < endT ) {
00762 float value = *ptrFlt++;
00763 *ptrT++ = (T) value;
00764 if ( std::abs( value - undef ) <= FLT_MIN )
00765 undefIndices->insert( undefIndices->end(), ptrT - result );
00766 }
00767 }
00768 else if ( partialIndices )
00769 {
00770
00771
00772 int shift = 1;
00773 for ( int j = 1; j <= nbPartialComponents; ++j ) {
00774 vector<int>::const_iterator i = partialIndices->begin(), iEnd = partialIndices->end();
00775 while ( i != iEnd )
00776 result[ *i++ - shift ] = (T) *ptrFlt++;
00777 shift += nbValues;
00778 }
00779 }
00780 else
00781 {
00782 while ( ptrT < endT )
00783 *ptrT++ = (T) *ptrFlt++;
00784 }
00785 return (char*) result;
00786 }
00787 private:
00788
00789 int _file;
00790 MEDEXCEPTION _exception;
00791 ssize_t _pos, _maxPos;
00792 bool _mySwapBytes;
00793
00795 template <typename T> T* get(int nb, bool inverseBytes=false)
00796 {
00797 size_t bufSize = nb * sizeof( T );
00798 if ( int(bufSize) > _maxPos - _pos )
00799 throw _exception;
00800 T* buf = new T[ nb ];
00801 #ifdef WNT
00802 #else
00803 ssize_t nBytesRead = ::read (_file, buf, bufSize );
00804 _pos += nBytesRead;
00805 if ( int(nBytesRead) < int(bufSize) ) {
00806 delete buf;
00807 throw _exception;
00808 }
00809 if ( inverseBytes ) {
00810 int* intBuf = ((int*) buf) - 1;
00811 int* bufEnd = (int*)((char*) buf + nBytesRead);
00812 while ( ++intBuf < bufEnd )
00813 *intBuf = MEDMEM::swapBytes( *intBuf );
00814 }
00815 #endif
00816 return buf;
00817 }
00818 };
00819
00820
00824
00825
00826 class _BinaryFileWriter
00827 {
00828 public:
00829 _BinaryFileWriter(const string& fileName) throw (MEDEXCEPTION);
00830
00831 ~_BinaryFileWriter();
00832
00834 void addString(const char* str) throw (MEDEXCEPTION);
00835
00837 void addString(const string& str) throw (MEDEXCEPTION)
00838 { addString( str.c_str() ); }
00839
00841 void addInt(const int value) throw (MEDEXCEPTION)
00842 { add( &value, 1 ); }
00843
00845 void addInt(const int* data, int nbValues) throw (MEDEXCEPTION)
00846 { add( data, nbValues ); }
00847
00849 void addInt(const vector< int >& data) throw (MEDEXCEPTION)
00850 { add( &data[0], data.size() ); }
00851
00853 template <typename T>
00854 void addReal(const T* data, int nbValues) throw (MEDEXCEPTION)
00855 {
00856 _RealData realData( data, nbValues );
00857 add( realData.values(), nbValues );
00858 }
00859
00861 template <class TValueIterator>
00862 void addReal(vector< TValueIterator >& componentIt,
00863 const int nbValues,
00864 const medModeSwitch interlace) throw (MEDEXCEPTION)
00865 {
00866 _RealData realData( componentIt, nbValues, interlace );
00867 add( realData.values(), nbValues * componentIt.size() );
00868 }
00869
00870 private:
00871
00872 int _file;
00873 MEDEXCEPTION _exception;
00874
00876 template <typename T>
00877 void add(const T* data, int nbValues) throw (MEDEXCEPTION)
00878 {
00879 #ifdef WNT
00880 #else
00881 ssize_t nbWritten = ::write( _file, (const void *) data, nbValues * sizeof(T));
00882 if ( nbWritten < 0 ) throw _exception;
00883 #endif
00884 }
00885
00889
00890 class _RealData {
00891 PointerOf<float> _floatData;
00892 public:
00894 const float* values() { return _floatData; }
00895
00897 template <typename T>
00898 _RealData(const T* data, int nbValues)
00899 {
00900 if ( sizeof( T ) == sizeof( float ))
00901 _floatData.set((const float*) data);
00902 else {
00903 _floatData.set(nbValues);
00904 float* floatPtr = _floatData;
00905 const T *tPtr = data, *tEnd = data + nbValues;
00906 while ( tPtr < tEnd )
00907 *floatPtr++ = _toFloat( *tPtr++ );
00908 }
00909 }
00910
00912 template <class TValueIterator>
00913 _RealData(vector< TValueIterator >& componentIt,
00914 const int nbValues,
00915 const medModeSwitch interlace)
00916 {
00917 int nbComponents = componentIt.size();
00918 _floatData.set(nbValues * nbComponents);
00919 float* floatPtr = _floatData;
00920 if ( interlace == MED_FULL_INTERLACE && nbComponents > 1 ) {
00921 for ( int i = 0; i < nbValues; ++i )
00922 for ( int j = 0; j < nbComponents; ++j )
00923 *floatPtr++ = _toFloat( componentIt[ j ].next() );
00924 }
00925 else {
00926 for ( int j = 0; j < nbComponents; ++j ) {
00927 TValueIterator & values = componentIt[ j ];
00928 for ( int i = 0; i < nbValues; ++i )
00929 *floatPtr++ = _toFloat( values.next() );
00930 }
00931 }
00932 }
00933 };
00934
00935 };
00936
00937 }
00938
00939 #endif