Back to index

salome-med  6.5.0
MEDMEM_EnsightFieldDriver.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 
00020 #include <fstream>
00021 #include <sstream>
00022 #include <iomanip>
00023 
00024 #ifndef WNT
00025 #include <fenv.h>
00026 #endif
00027 
00028 #include "MEDMEM_Utilities.hxx"
00029 
00030 #include "MEDMEM_Field.hxx"
00031 #include "MEDMEM_EnsightUtils.hxx"
00032 
00033 #define TStrTool _ASCIIFileReader
00034 
00035 using namespace MED_EN;
00036 using namespace MEDMEM_ENSIGHT;
00037 
00038 namespace {
00039 
00040   // ==============================================================================
00044   template <typename T> class _SelectedValueIterator
00045   {
00046     int        myDelta;
00047     const T*   myPtr;
00048     int        myIndexDelta;
00049     const int* myIndex;
00050   public:
00051     _SelectedValueIterator() // by default next() returns zero
00052       : myDelta( 0 ),      myPtr  (_ValueIterator<T>::zeroPtr()),
00053         myIndexDelta( 0 ), myIndex(_ValueIterator<int>::zeroPtr()) {}
00054 
00055     _SelectedValueIterator(const T* values, int delta, const int* index)
00056       : myDelta( delta ), myPtr(values), myIndexDelta(1), myIndex(index-1) {}
00057 
00058     const T & next() { myIndex += myIndexDelta; return myPtr[ (*myIndex) * myDelta ]; }
00059   };
00060 
00061   // ==============================================================================
00066   struct _SubPartValues
00067   {
00068     _SubPart      mySubPart;
00069     const char *  myValues;
00070     medModeSwitch myInterlace;
00071     bool          myOwnValues; // to delete or not myValues
00072     string        myConstValue; // if myConstValue is set, other members are meaningless
00073 
00074     // for writing values of a field-on-all-entities for a group
00075     const int *   myNumbers;
00076 
00077     string        myUndefValue;
00078     set<int>      myUndefIndices;
00079     vector<int>   myPartialIndices;
00080 
00081     _SubPartValues(const _SubPart& sub=_SubPart())
00082       : mySubPart(sub), myValues(0), myInterlace(MED_NO_INTERLACE), myOwnValues(true) {};
00083 
00084     ~_SubPartValues() { clear(); }
00085     void clear() { if ( myOwnValues ) delete [] myValues; myValues = 0; }
00086 
00087     // -------------------------------------------------------------------
00089     _SubPartValues(const _SubPartValues& other)
00090       :mySubPart(other.mySubPart), myValues(other.myValues),
00091        myInterlace(other.myInterlace), myOwnValues(true)
00092     { ((_SubPartValues&)other).myValues=0; }
00093 
00094     // -------------------------------------------------------------------
00096     //   nbElements is a number of values of a component located one by one in
00097     //   not full interlace
00098     template <typename T> _ValueIterator<T>
00099     getValues( int component, int nbElements, int nbComponents ) const
00100     {
00101       const T* values = (T*) myValues;
00102       if ( myInterlace == MED_FULL_INTERLACE ) {
00103         values += (component - 1);
00104         return _ValueIterator<T>( values, nbComponents );
00105       }
00106       else {
00107         values += (component - 1) * nbElements;
00108         return _ValueIterator<T>( values, 1 );
00109       }
00110     }
00111     // -------------------------------------------------------------------
00113     //   nbElements is a number of values of a component located one by one in
00114     //   not full interlace
00115     template <typename T> _SelectedValueIterator<T>
00116     getSelectedValues( int component, int nbElements, int nbComponents ) const
00117     {
00118       // Values are specified by myNumbers. myValues points to the value
00119       // relating to myNumbers[0] element.
00120       const T* values = (T*) myValues;
00121       if ( myInterlace == MED_FULL_INTERLACE ) {
00122         values -= myNumbers[0] * nbComponents;
00123         values += (component - 1);
00124         return _SelectedValueIterator<T>( values, nbComponents, myNumbers );
00125       }
00126       else {
00127         values -= myNumbers[0];
00128         values += (component - 1) * nbElements;
00129         return _SelectedValueIterator<T>( values, 1, myNumbers );
00130       }
00131     }
00132     // -------------------------------------------------------------------
00134     template <typename T> vector< _ValueIterator<T> >
00135     getAllValues( int nbElements, int nbComponents, bool add3dComp ) const
00136     {
00137       // add the 3-d component to a vector in 2D space
00138       int addComp = ( add3dComp && nbComponents == 2 ) ? 1 : 0;
00139       vector< _ValueIterator<T> > compValIt( nbComponents + addComp);
00140       for ( int j = 1; j <= nbComponents; ++j )
00141         compValIt[ j-1 ] = getValues<T>( j, nbElements, nbComponents );
00142       return compValIt;
00143     }
00144     // -------------------------------------------------------------------
00146     template <typename T> vector< _SelectedValueIterator<T> >
00147     getAllSelectedValues( int nbElements, int nbComponents, bool add3dComp ) const
00148     {
00149       // add the 3-d component to a vector in 2D space
00150       int addComp = ( add3dComp && nbComponents == 2 ) ? 1 : 0;
00151       vector< _SelectedValueIterator<T> > compValIt( nbComponents + addComp);
00152       for ( int j = 1; j <= nbComponents; ++j )
00153         compValIt[ j-1 ] = getSelectedValues<T>( j, nbElements, nbComponents );
00154       return compValIt;
00155     }
00156   };
00157 
00158   //=======================================================================
00162   template <class FileReader>
00163   void readSubPartValues( FileReader&      reader,
00164                           const FIELD_*    field,
00165                           _SubPartValues & subValues)
00166   {
00167     medEntityMesh entity = field->getSupport()->getEntity();
00168     int     nbComponents = field->getNumberOfComponents();
00169 
00170     int nbElements = 0;
00171     if ( entity == MED_NODE )
00172       nbElements = subValues.mySubPart.myNbNodes;
00173     else
00174       nbElements = subValues.mySubPart.myNbCells;
00175 
00176     int nbValues = nbElements * nbComponents;
00177     if ( nbValues < 1 )
00178       return;
00179 
00180     const char* undefValue = 0;
00181     set<int>* undefIndices = &subValues.myUndefIndices;
00182     vector<int>* partial   = 0;
00183     if ( !subValues.myUndefValue.empty() )
00184       undefValue = subValues.myUndefValue.c_str();
00185     if ( !subValues.myPartialIndices.empty() )
00186       partial = &subValues.myPartialIndices;
00187 
00188     if ( field->getValueType() == MED_REEL64 )
00189       subValues.myValues = reader.template convertReals<double>( nbValues,
00190                                                                  undefValue, undefIndices,
00191                                                                  partial, nbComponents );
00192     else if ( field->getValueType() == MED_INT32 )
00193       subValues.myValues = reader.template convertReals<int>   ( nbValues,
00194                                                                  undefValue, undefIndices,
00195                                                                  partial, nbComponents );
00196     else
00197       subValues.myValues = reader.template convertReals<long>  ( nbValues,
00198                                                                  undefValue, undefIndices,
00199                                                                  partial, nbComponents );
00200     // convert partial indices into undef indices
00201     if ( !subValues.myPartialIndices.empty() )
00202     {
00203       // sort partial
00204       set<int> sortedPartial;
00205       vector<int>::iterator p = partial->begin(), pEnd = partial->end();
00206       while ( p != pEnd )
00207         sortedPartial.insert( sortedPartial.end(), *p++ );
00208       partial->clear();
00209 
00210       // fill undef indices
00211       set<int> & undef = subValues.myUndefIndices;
00212       set<int>::iterator sp = sortedPartial.begin();
00213       int i = 1;
00214       for ( ; sp != sortedPartial.end() && i <= nbElements; ++i, ++sp ) {
00215         while ( i < *sp )
00216           undef.insert( undef.end(), i++ );
00217       }
00218       while ( i <= nbElements )
00219         undef.insert( undef.end(), i++ );
00220     }
00221   }
00222   //=======================================================================
00226   template <class T, class TMailIter, class TArray >
00227   void _setValuesToArray( vector< _ValueIterator<T> > & compValIt,
00228                           const int                     nbValues,
00229                           TArray*                       array,
00230                           TMailIter&                    cellIt,
00231                           _Support*                     interSupport,
00232                           const set<int>&               localUndefIndices,
00233                           set<int> &                    globalUndefIndices)
00234   {
00235     int nbComponents = array->getDim();
00236     if ( localUndefIndices.empty() )
00237     {
00238       for ( int c = 0; c < nbValues; ++c, ++cellIt )
00239       {
00240         int i = interSupport->getIndex( *cellIt );
00241         for ( int j = 1; j <= nbComponents; ++j )
00242           array->setIJ( i, j, compValIt[ j ].next() );
00243       }
00244     }
00245     else
00246     {
00247       // set values from the first till undefined end
00248       set<int>::const_iterator undef = localUndefIndices.begin();
00249       int c = 1, last = min( nbValues, *localUndefIndices.rbegin() );
00250       for ( ; c <= last; ++c, ++cellIt )
00251       {
00252         int i = interSupport->getIndex( *cellIt );
00253         if ( c == *undef ) {
00254           globalUndefIndices.insert( i );
00255           ++undef;
00256         }
00257         for ( int j = 1; j <= nbComponents; ++j )
00258           array->setIJ( i, j, compValIt[ j ].next() );
00259       }
00260       // set all the rest values
00261       for ( ; c <= nbValues; ++c, ++cellIt )
00262       {
00263         int i = interSupport->getIndex( *cellIt );
00264         for ( int j = 1; j <= nbComponents; ++j )
00265           array->setIJ( i, j, compValIt[ j ].next() );
00266       }
00267     }
00268   }
00269 
00270   //================================================================================
00274   //================================================================================
00275 
00276   SUPPORT* makeShiftedSupport(const SUPPORT* support,
00277                               const set<int> undefIndices)
00278   {
00279     int nbElements = support->getNumberOfElements(MED_ALL_ELEMENTS);
00280     int nbTypes    = support->getNumberOfTypes();
00281 
00282     int i, shitf = 1;
00283     set<int>::const_iterator undef;
00284 
00285     // shift support numbers
00286     int * index  = new int[ nbTypes + 1 ];
00287     int * number = new int[ nbElements - undefIndices.size() ];
00288     if ( support->isOnAllElements() ) {
00289       // make shifted number
00290       int * numberPtr = number;
00291       for ( i = 0, undef = undefIndices.begin(); undef != undefIndices.end(); ++undef )
00292         while ( ++i < *undef )
00293           *numberPtr++ = i;
00294       while ( ++i <= nbElements )
00295         *numberPtr++ = i;
00296       // fill index but without shift
00297       const int * oldNbElemByType = support->getNumberOfElements();
00298       index[0] = 1;
00299       for ( int t = 0; t < nbTypes; ++t )
00300         index[ t+1 ] = index[ t ] + oldNbElemByType[ t ];
00301     }
00302     else {
00303       // shift existing number
00304       shitf = 1;
00305       const int * oldNumber = support->getNumber( MED_ALL_ELEMENTS );
00306       std::copy( oldNumber, oldNumber + *undefIndices.begin()-1, number ); // copy [0:firstUndef]
00307       for ( undef = undefIndices.begin(); undef != undefIndices.end(); ) {
00308         i = *undef++;
00309         int nextUndef = ( undef != undefIndices.end() ) ? *undef : nbElements + 1;
00310         while ( ++i < nextUndef )
00311           number[ i-1 - shitf ] = oldNumber[ i-1 ]; // shift number
00312         ++shitf;
00313       }
00314       // copy index
00315       const int * oldIndex  = support->getNumberIndex();
00316       std::copy( oldIndex, oldIndex + nbTypes + 1, index );
00317     }
00318     // update index
00319     {
00320       set<int>::const_reverse_iterator undef = undefIndices.rbegin();
00321       for ( ; undef != undefIndices.rend(); ++undef ) {
00322         for ( int t = nbTypes; t ; --t )
00323           if ( *undef < index[ t ] )
00324             --index[ t ];
00325           else
00326             break;
00327       }
00328     }
00329     // count number of elements by type
00330     vector<int> nbElem( nbTypes );
00331     for ( int t = 0; t < nbTypes; ++t )
00332       nbElem[ t ] = index[ t+1 ] - index[ t ];
00333 
00334     SUPPORT* newSup = new SUPPORT;
00335     newSup->setMesh                 ( support->getMesh() );
00336     newSup->setNumberOfGeometricType( nbTypes );
00337     newSup->setGeometricType        ( support->getTypes() );
00338     newSup->setNumberOfElements     ( &nbElem[0] );
00339     newSup->setNumber               ( index, number, /*shallowCopy =*/ true );
00340     newSup->setEntity               ( support->getEntity() );
00341     newSup->setAll                  ( false );
00342 
00343     return newSup;
00344   }
00345 
00346   //=======================================================================
00350   template <class T, class INTERLACE>
00351   void _setValuesToField( FIELD<T,INTERLACE>*    field,
00352                           _Support*              interSupport,
00353                           list<_SubPartValues> & subPartValues )
00354   {
00355     medEntityMesh entity = field->getSupport()->getEntity();
00356     SUPPORT* support = interSupport->medSupport( entity );
00357     field->setSupport( new SUPPORT( *support ));
00358     field->getSupport()->removeReference(); // support belongs to field only
00359 
00360     int j, nbComponents = field->getNumberOfComponents();
00361     int      nbElements = field->getSupport()->getNumberOfElements(MED_ALL_ELEMENTS);
00362 
00363     typedef typename MEDMEM_ArrayInterface<T,INTERLACE,NoGauss>::Array TArray;
00364 
00365     const string& constValue = subPartValues.front().myConstValue;
00366     if ( !constValue.empty() )
00367     {
00368       vector<T> values(nbComponents * nbElements, (T)atof(constValue.c_str()));
00369       field->setArray( new TArray( &values[0], nbComponents, nbElements ));
00370       field->setNumberOfValues( nbElements );
00371       return;
00372     }
00373 
00374     field->allocValue( nbComponents, nbElements );
00375     TArray * array = field->getArrayNoGauss();
00376 
00377     set<int> undefIndices; // indices of undefined values
00378     
00379     // loop on subParts conatining ensight field values
00380     list<_SubPartValues>::iterator subValue = subPartValues.begin();
00381     for ( ; subValue != subPartValues.end(); ++subValue )
00382     {
00383       _SubPart & subPart = subValue->mySubPart;
00384       int nbValues = entity==MED_NODE ? subPart.myNbNodes : subPart.myNbCells;
00385       if ( nbValues == 0 )
00386         continue;
00387       // value iterator for each component
00388       vector< _ValueIterator<T> > compValIt( nbComponents+1 );
00389       for ( j = 1; j <= nbComponents; ++j )
00390         compValIt[ j ] = subValue->template getValues<T>( j, nbValues, nbComponents );
00391 
00392       // Set values
00393 
00394       if ( entity == MED_NODE ) {
00395         map< int, _noeud >::iterator inode = subPart.myFirstNode;
00396         _setValuesToArray( compValIt, nbValues, array, inode, interSupport,
00397                            subValue->myUndefIndices, undefIndices );
00398       }
00399       else {
00400         _groupe::TMailleIter cell = subPart.myFirstCell;
00401         _setValuesToArray( compValIt, nbValues, array, cell, interSupport,
00402                            subValue->myUndefIndices, undefIndices );
00403       }
00404     }
00405 
00406     if ( !undefIndices.empty() )
00407     {
00408       // Some values are undefined; it's necessary to compact values in the array
00409       // and create a new support of defined numbers only.
00410 
00411       // shift values
00412       int i, shitf = 1;
00413       set<int>::iterator undef = undefIndices.begin();
00414       while ( undef != undefIndices.end() ) {
00415         i = *undef++;
00416         int nextUndef = ( undef != undefIndices.end() ) ? *undef : nbElements + 1;
00417         while ( ++i < nextUndef ) {
00418           for ( int j = 1; j <= nbComponents; ++j )
00419             array->setIJ( i - shitf, j, array->getIJ( i, j )); // shift value
00420           //number[ i-1 - shitf ] = oldNumber[ i-1 ]; // shift number
00421         }
00422         ++shitf;
00423       }
00424       array->_nbelem -= undefIndices.size();
00425       array->_arraySize = array->_nbelem * nbComponents;
00426 
00427       support = makeShiftedSupport( support, undefIndices );
00428       support->setName( STRING("Partial for ") << field->getName() );
00429       field->setSupport( support );
00430       field->setNumberOfValues( array->_nbelem );
00431     }
00432     if ( support->getName().empty() )
00433       support->setName( STRING("Support for ") << field->getName() );
00434   }
00435 
00436   //=======================================================================
00440   void setValuesToField( FIELD_*                field,
00441                          _Support*              interSupport,
00442                          list<_SubPartValues> & subPartValues )
00443   {
00444     switch ( field->getInterlacingType() ) {
00445     case MED_FULL_INTERLACE:
00446       if ( field->getValueType() == MED_REEL64 )
00447         _setValuesToField( static_cast< FIELD<double, FullInterlace>* >( field ),
00448                            interSupport, subPartValues );
00449       else
00450         _setValuesToField( static_cast< FIELD<int, FullInterlace>* >( field ),
00451                            interSupport, subPartValues );
00452       break;
00453     case MED_NO_INTERLACE:
00454       if ( field->getValueType() == MED_REEL64 )
00455         _setValuesToField( static_cast< FIELD<double, NoInterlace>* >( field ),
00456                            interSupport, subPartValues );
00457       else
00458         _setValuesToField( static_cast< FIELD<int, NoInterlace>* >( field ),
00459                            interSupport, subPartValues );
00460       break;
00461     case MED_NO_INTERLACE_BY_TYPE:
00462       if ( field->getValueType() == MED_REEL64 )
00463         _setValuesToField( static_cast< FIELD<double, NoInterlaceByType>* >( field ),
00464                            interSupport, subPartValues );
00465       else
00466         _setValuesToField( static_cast< FIELD<int, NoInterlaceByType>* >( field ),
00467                            interSupport, subPartValues );
00468       break;
00469     default:;
00470     }
00471   }
00472 
00473 
00474   //================================================================================
00478   //================================================================================
00479 
00480   int* getNodeNumbers( const SUPPORT* support, int & nbNodes )
00481   {
00482     map<int, int> nodeNumbers;
00483     _CaseFileDriver_User::getSupportNodes( support, nodeNumbers );
00484     nbNodes = nodeNumbers.size();
00485     int* nNumbers = new int[ nbNodes ];
00486     int* nPtr = nNumbers;
00487     map<int, int>::iterator n = nodeNumbers.begin(), nEnd = nodeNumbers.end();
00488     while ( n != nEnd )
00489       *nPtr++ = n->first, n++;
00490 
00491     return nNumbers;
00492   }
00493 
00494 } // namespace
00495 
00496 //=======================================================================
00500 ENSIGHT_FIELD_DRIVER::ENSIGHT_FIELD_DRIVER():
00501   _CaseFileDriver_User(),
00502   _ptrField((FIELD_ *) 0)
00503 {}
00504 //=======================================================================
00508 ENSIGHT_FIELD_DRIVER::ENSIGHT_FIELD_DRIVER(const string &  fileName,
00509                                            FIELD_       *  ptrField,
00510                                            med_mode_acces  accessMode):
00511   _CaseFileDriver_User(fileName,accessMode),
00512   _ptrField((FIELD_ *) ptrField)
00513 {
00514 }
00515 //=======================================================================
00519 ENSIGHT_FIELD_DRIVER::ENSIGHT_FIELD_DRIVER(const ENSIGHT_FIELD_DRIVER & fieldDriver):
00520   _CaseFileDriver_User(fieldDriver),
00521   _ptrField(fieldDriver._ptrField),
00522   _fieldName(fieldDriver._fieldName)
00523 {
00524 }
00525 //=======================================================================
00529 void ENSIGHT_FIELD_DRIVER::merge ( const GENDRIVER& driver )
00530 {
00531   _CaseFileDriver_User::merge( driver );
00532 
00533   const ENSIGHT_FIELD_DRIVER* other = dynamic_cast< const ENSIGHT_FIELD_DRIVER* >( &driver );
00534   if ( other ) {
00535     if ( !_ptrField )
00536       _ptrField = other->_ptrField;
00537     if ( _constantValue.empty() )
00538       _constantValue = other->_constantValue;
00539     // _fieldName is copied by GENDRIVER
00540   }
00541 }
00542 //=======================================================================
00546 ENSIGHT_FIELD_DRIVER::~ENSIGHT_FIELD_DRIVER()
00547 {
00548 }
00549 //=======================================================================
00553 void ENSIGHT_FIELD_DRIVER::setFieldName(const string & fieldName) throw (MEDEXCEPTION)
00554 {
00555   const char* LOC = "ENSIGHT_FIELD_DRIVER::setFieldName(): ";
00556   if ( (int)fieldName.size() > MAX_FIELD_NAME_LENGTH )
00557     throw MEDEXCEPTION( compatibilityPb(LOC) << "too long name (> " <<
00558                         MAX_FIELD_NAME_LENGTH << "): " << fieldName);
00559 
00560   // look for illegal characters
00561   string::size_type pos = fieldName.find_first_of( ILLEGAL_FIELD_NAME_CHARACTERS );
00562   if ( pos != fieldName.npos )
00563     throw MEDEXCEPTION( compatibilityPb(LOC) << "Character " << pos << " (" << fieldName[pos] <<
00564                         ") "<< " in " << fieldName << " is not allowed in field name in EnSight\n"
00565                         "The illegal characters are: '" << ILLEGAL_FIELD_NAME_CHARACTERS << "'");
00566   _fieldName = fieldName;
00567 }
00568 //=======================================================================
00572 void ENSIGHT_FIELD_DRIVER::openConst(bool checkDataFile) const throw (MEDEXCEPTION)
00573 {
00574   const char * LOC ="ENSIGHT_FIELD_DRIVER::open() : ";
00575   BEGIN_OF_MED(LOC);
00576 
00577   if ( checkDataFile )
00578   {
00579     if ( !getConstantValue().empty() )
00580       return; // constant value is either stored in case file or is read by _CaseFileDriver
00581 
00582     if ( getDataFileName().empty() )
00583       throw MED_EXCEPTION
00584         ( LOCALIZED( STRING(LOC) << "Internal error, variable file name is empty"));
00585 
00586     if (!canOpenFile( getDataFileName(), getAccessMode() ))
00587       throw MED_EXCEPTION
00588         ( LOCALIZED( STRING(LOC) << "Can not open Ensight Variable file " << getDataFileName()
00589                      << " in access mode " << getAccessMode()));
00590   }
00591   else
00592   {
00593     if ( getCaseFileName().empty() )
00594       throw MED_EXCEPTION
00595         ( LOCALIZED( STRING(LOC) << "Case file name is empty, "
00596                      "please set a correct fileName before calling open()"));
00597 
00598     if ( !canOpenFile( getCaseFileName(), getAccessMode() ))
00599       throw MED_EXCEPTION
00600         ( LOCALIZED( STRING(LOC) << "Can not open Ensight Case file " << getCaseFileName()
00601                      << " in access mode " << getAccessMode()));
00602   }
00603 
00604   END_OF_MED(LOC);
00605 }
00606 // ==========================================================================================
00607 //function : ENSIGHT_FIELD_RDONLY_DRIVER
00608 
00609 ENSIGHT_FIELD_RDONLY_DRIVER::ENSIGHT_FIELD_RDONLY_DRIVER()
00610   :ENSIGHT_FIELD_DRIVER(), _fieldStep(1) 
00611 {
00612 }
00613 
00614 //=======================================================================
00618 //=======================================================================
00619 
00620 ENSIGHT_FIELD_RDONLY_DRIVER::ENSIGHT_FIELD_RDONLY_DRIVER(const string & fileName,
00621                                                          FIELD_ *       ptrField,
00622                                                          int            step)
00623   :ENSIGHT_FIELD_DRIVER(fileName,ptrField,MED_EN::RDONLY),_fieldStep(step)
00624 {
00625 }
00626 
00627 //=======================================================================
00628 //function : ENSIGHT_FIELD_RDONLY_DRIVER
00629 //=======================================================================
00630 
00631 ENSIGHT_FIELD_RDONLY_DRIVER::ENSIGHT_FIELD_RDONLY_DRIVER(const ENSIGHT_FIELD_RDONLY_DRIVER & drv)
00632   :ENSIGHT_FIELD_DRIVER(drv),_fieldStep(drv._fieldStep)
00633 {
00634 }
00635 
00636 //=======================================================================
00637 //function : ~ENSIGHT_FIELD_RDONLY_DRIVER
00638 //=======================================================================
00639 
00640 ENSIGHT_FIELD_RDONLY_DRIVER::~ENSIGHT_FIELD_RDONLY_DRIVER()
00641 {
00642   close();
00643 }
00644 
00645 //=======================================================================
00646 //function : copy
00647 //=======================================================================
00648 
00649 GENDRIVER * ENSIGHT_FIELD_RDONLY_DRIVER::copy(void) const
00650 {
00651   ENSIGHT_FIELD_RDONLY_DRIVER * myDriver = new ENSIGHT_FIELD_RDONLY_DRIVER(*this);
00652 
00653   return myDriver ;
00654 }
00655 //=======================================================================
00656 //  Take missing data from other driver.
00657 //=======================================================================
00658 
00659 void ENSIGHT_FIELD_RDONLY_DRIVER::merge ( const GENDRIVER& driver )
00660 {
00661   ENSIGHT_FIELD_DRIVER::merge( driver );
00662 
00663   const ENSIGHT_FIELD_RDONLY_DRIVER* other =
00664     dynamic_cast< const ENSIGHT_FIELD_RDONLY_DRIVER* >( &driver );
00665   if ( other ) {
00666     if ( _fieldStep < other->_fieldStep )
00667       _fieldStep = other->_fieldStep;
00668   }
00669 }
00670 
00671 //=======================================================================
00672 //function : read
00673 //=======================================================================
00674 
00675 void ENSIGHT_FIELD_RDONLY_DRIVER::read (void)
00676   throw (MEDEXCEPTION)
00677 {
00678   const char * LOC = "ENSIGHT_FIELD_RDONLY_DRIVER::read() : " ;
00679   BEGIN_OF_MED(LOC);
00680 
00681   _CaseFileDriver caseFile( getCaseFileName(), this);
00682 
00683   if ( getDataFileName().empty() ) // find out what to read
00684   {
00685     openConst(false); // check if can read case file
00686 
00687     caseFile.read();
00688 
00689     // find out index of variable to read
00690     int variableIndex = caseFile.getVariableIndex( _fieldName );
00691     if ( !variableIndex )
00692       variableIndex = caseFile.getVariableIndex( _ptrField->getName() );
00693     if ( !variableIndex ) {
00694       if ( !_fieldName.empty() )
00695         throw MEDEXCEPTION
00696           (LOCALIZED(STRING(LOC) << "no field found by name |" << _fieldName << "|"));
00697       else
00698         throw MEDEXCEPTION
00699           (LOCALIZED(STRING(LOC) << "no field found by name |" << _ptrField->getName() << "|"));
00700     }
00701 
00702     //  here data from Case File is passed:
00703     // * field name
00704     // * number of components
00705     // * etc.
00706     caseFile.setDataFileName( variableIndex, _fieldStep, this );
00707   }
00708 
00709   openConst(true); // check if can read data file
00710 
00711   getInterData(); // get data on nb of entities by type and on their relocation
00712 
00713   cout << "-> Entering into the field file " << getDataFileName() << endl  ;
00714 
00715   if ( !getConstantValue().empty() )
00716   {
00717     // Create a constant value field
00718 
00719     medEntityMesh entity = MED_CELL;
00720     GROUP* support = new GROUP;
00721     support->setName( string("SupportOnAll_")+entNames[entity]);
00722     support->setMesh( getInterData()->_medMesh );
00723     support->setAll( true );
00724     support->setEntity( entity );
00725     support->update();
00726                                     
00727     _groupe interGroup;
00728     interGroup.medGroup = support;
00729     _Support interSupport;
00730     interSupport.setGroup( &interGroup );
00731 
00732     list<_SubPartValues> subPartValues( 1 );
00733     subPartValues.back().myConstValue = getConstantValue();
00734 
00735     setValuesToField( _ptrField, &interSupport, subPartValues );
00736   }
00737   else
00738   {
00739     // Read values
00740 
00741 #ifndef WNT
00742     int curExcept = fedisableexcept( FE_ALL_EXCEPT ); 
00743 #endif
00744 
00745     if ( isBinaryDataFile( getDataFileName() ) ) // binary
00746     {
00747       if ( isGoldFormat() ) // Gold
00748       {
00749         readGoldBinary();
00750       }
00751       else // EnSight6
00752       {
00753         read6Binary();
00754       }
00755     }
00756     else // ASCII
00757     {
00758       if ( isGoldFormat() ) // Gold
00759       {
00760         readGoldASCII();
00761       }
00762       else // EnSight6
00763       {
00764         read6ASCII();
00765       }
00766     }
00767 
00768 #ifndef WNT
00769     feclearexcept( FE_ALL_EXCEPT );
00770     if ( curExcept >= 0 )
00771       feenableexcept( curExcept );
00772 #endif
00773   }
00774 }
00775 
00776 //=======================================================================
00780 //=======================================================================
00781 
00782 void ENSIGHT_FIELD_RDONLY_DRIVER::readGoldASCII ()
00783 {
00784 
00785   // data that was set by CaseFile Driver
00786   medEntityMesh entity = _ptrField->getSupport()->getEntity();
00787 
00788   _SupportDesc         supportDescriptor;
00789   list<_SubPartValues> subPartValues;
00790 
00791   _ASCIIFileReader varFile( getDataFileName() );
00792 
00793   if ( isSingleFileMode() ) {
00794     int curTimeStep = 1;
00795     while ( curTimeStep < getIndexInDataFile() ) {
00796       while ( !varFile.isTimeStepEnd() )
00797         varFile.getLine();
00798       curTimeStep++;
00799     }
00800     while ( !varFile.isTimeStepBeginning() )
00801       varFile.getLine();
00802   }
00803   string description = varFile.getLine(); // description line
00804   _ptrField->setDescription( description );
00805 
00806   int partNumber = 0;
00807   _SubPartValues subValuesSample; // to keep interlace
00808   subValuesSample.myInterlace = MED_NO_INTERLACE;
00809   while ( !varFile.isTimeStepEnd() )
00810   {
00811     string word, restLine, line = varFile.getLine();
00812     TStrTool::split( line, word, restLine );
00813     if ( word == "part" ) {
00814       partNumber = varFile.getInt(); // part #
00815       continue;
00816     }
00817     subPartValues.push_back( subValuesSample );
00818     _SubPartValues & subValues = subPartValues.back(); 
00819 
00820     if ( restLine == "undef" )
00821       subValues.myUndefValue = varFile.getWord(); // undef
00822 
00823     if ( restLine == "partial" ) {
00824       int nbPartial = varFile.getInt(); // ne
00825       subValues.myPartialIndices.reserve( nbPartial );
00826       while ( nbPartial-- )
00827         subValues.myPartialIndices.push_back( varFile.getInt() ); // i_ne
00828     }
00829     _SubPartDesc desc( partNumber, word );
00830     subValues.mySubPart = *getSubPart( desc );
00831     readSubPartValues( varFile, _ptrField, subValues );
00832     supportDescriptor.insert( desc );
00833   }
00834 
00835   _Support* interSupport = getSupport( supportDescriptor, entity );
00836   setValuesToField( _ptrField, interSupport, subPartValues );
00837   
00838 }
00839 
00840 //=======================================================================
00844 //=======================================================================
00845 
00846 void ENSIGHT_FIELD_RDONLY_DRIVER::readGoldBinary()
00847 {
00848 
00849   // data that was set by CaseFile Driver
00850   medEntityMesh entity = _ptrField->getSupport()->getEntity();
00851 
00852   _SupportDesc         supportDescriptor;
00853   list<_SubPartValues> subPartValues;
00854 
00855   _BinaryFileReader varFile( getDataFileName() );
00856 
00857   // check if swapping bytes needed
00858   try {
00859     skipTimeStamp( varFile );
00860   }
00861   catch (...) {
00862     varFile.swapBytes();
00863     varFile.rewind();
00864   }
00865   if ( getIndexInDataFile() <= 1 )
00866     varFile.rewind();
00867 
00868   if ( isSingleFileMode() ) {
00869     // one time step may be skipped by skipTimeStamp()
00870     int curTimeStep = varFile.getPosition() ? 2 : 1 ;
00871     while ( curTimeStep < getIndexInDataFile() ) {
00872       skipTimeStamp( varFile );
00873       curTimeStep++;
00874     }
00875     varFile.skipTimeStepBeginning();
00876   }
00877   TStrOwner description( varFile.getLine() ); // description line
00878   _ptrField->setDescription( description.myValues );
00879 
00880   int partNumber = 0;
00881   _SubPartValues subValuesSample; // to keep interlace
00882   subValuesSample.myInterlace = MED_NO_INTERLACE;
00883   while ( !varFile.eof() )
00884   {
00885     TStrOwner line( varFile.getLine() );
00886     if ( isTimeStepEnd( line.myValues ))
00887       break;
00888     string word, restLine;
00889     TStrTool::split( line.myValues, word, restLine );
00890     if ( word == "part" ) {
00891       partNumber = *TIntOwner( varFile.getInt(1)); // part #
00892       continue;
00893     }
00894     subPartValues.push_back( subValuesSample );
00895     _SubPartValues & subValues = subPartValues.back(); 
00896 
00897     if ( restLine == "undef" )
00898       subValues.myUndefValue = (STRING( *TFltOwner( varFile.getFlt(1) ))); // undef
00899 
00900     if ( restLine == "partial" ) {
00901       int nbPartial = *TIntOwner( varFile.getInt(1) ); // ne
00902       TIntOwner partial( varFile.getInt( nbPartial ));
00903       subValues.myPartialIndices.assign( partial.myValues,
00904                                          partial.myValues+nbPartial ); // i_ne
00905     }
00906     _SubPartDesc desc( partNumber, word );
00907     subValues.mySubPart = *getSubPart( desc );
00908     readSubPartValues( varFile, _ptrField, subValues );
00909     supportDescriptor.insert( desc );
00910   }
00911 
00912   _Support* interSupport = getSupport( supportDescriptor, entity );
00913   setValuesToField( _ptrField, interSupport, subPartValues );
00914   
00915 }
00916 
00917 //=======================================================================
00921 //=======================================================================
00922 
00923 void ENSIGHT_FIELD_RDONLY_DRIVER::read6ASCII()
00924 {
00925 
00926   // data that was set by CaseFile Driver
00927   medEntityMesh entity = _ptrField->getSupport()->getEntity();
00928 
00929   _SupportDesc         supportDescriptor;
00930   list<_SubPartValues> subPartValues;
00931 
00932   _ASCIIFileReader varFile( getDataFileName() );
00933 
00934   if ( isSingleFileMode() ) {
00935     int curTimeStep = 1;
00936     while ( curTimeStep < getIndexInDataFile() ) {
00937       while ( !varFile.isTimeStepEnd() )
00938         varFile.getLine();
00939       curTimeStep++;
00940     }
00941     while ( !varFile.isTimeStepBeginning() )
00942       varFile.getLine();
00943   }
00944   string description = varFile.getLine(); // description line
00945   _ptrField->setDescription( description );
00946 
00947   const _SubPart* subPart = 0;
00948   if ( entity == MED_NODE ) // variable per node
00949   {
00950     _SubPartDesc desc = _SubPartDesc::globalCoordDesc();
00951     subPart = getSubPart( desc );
00952     if ( subPart ) {
00953       supportDescriptor.insert( desc );
00954       _SubPartValues subValues( *subPart );
00955       subValues.myInterlace = MED_FULL_INTERLACE;
00956       readSubPartValues( varFile, _ptrField, subValues );
00957       subPartValues.push_back( subValues );
00958     }
00959   }
00960   int partNumber = 0;
00961   while ( !varFile.isTimeStepEnd() )
00962   {
00963     string word = varFile.getWord();
00964     if ( word == "part" ) {
00965       partNumber = varFile.getInt();
00966       continue;
00967     }
00968     _SubPartDesc desc( partNumber, word );
00969     supportDescriptor.insert( desc );
00970     subPart = getSubPart( desc );
00971     _SubPartValues subValues( *subPart );
00972     if ( desc.typeName() == "block" )
00973       subValues.myInterlace = MED_NO_INTERLACE;
00974     else
00975       subValues.myInterlace = MED_FULL_INTERLACE;
00976     readSubPartValues( varFile, _ptrField, subValues );
00977     subPartValues.push_back( subValues );
00978   }
00979 
00980   _Support* interSupport = getSupport( supportDescriptor, entity );
00981   setValuesToField( _ptrField, interSupport, subPartValues );
00982   
00983 }
00984 
00985 //=======================================================================
00989 //=======================================================================
00990 
00991 void ENSIGHT_FIELD_RDONLY_DRIVER::read6Binary()
00992 {
00993 
00994   // data that was set by CaseFile Driver
00995   medEntityMesh entity = _ptrField->getSupport()->getEntity();
00996 
00997   _SupportDesc         supportDescriptor;
00998   list<_SubPartValues> subPartValues;
00999   const _SubPart*      subPart = 0;
01000   int                  partNumber = 0;
01001 
01002   _BinaryFileReader varFile( getDataFileName() );
01003 
01004   // check if swapping bytes needed
01005   try {
01006     skipTimeStamp( varFile );
01007   }
01008   catch (...) {
01009     varFile.swapBytes();
01010     varFile.rewind();
01011   }
01012   if ( getIndexInDataFile() <= 1 )
01013     varFile.rewind();
01014 
01015   if ( isSingleFileMode() ) {
01016     // one time step may be skipped by skipTimeStamp()
01017     int curTimeStep = varFile.getPosition() ? 2 : 1 ;
01018     while ( curTimeStep < getIndexInDataFile() ) {
01019       skipTimeStamp( varFile );
01020       curTimeStep++;
01021     }
01022     varFile.skipTimeStepBeginning();
01023   }
01024 
01025   TStrOwner description( varFile.getLine() ); // description line
01026   _ptrField->setDescription( description.myValues );
01027 
01028   if ( entity == MED_NODE ) // global unstructured node values
01029   {
01030     _SubPartDesc desc = _SubPartDesc::globalCoordDesc();
01031     subPart = getSubPart( desc );
01032     if ( subPart ) {
01033       supportDescriptor.insert( desc );
01034       _SubPartValues subValues( *subPart );
01035       subValues.myInterlace = MED_FULL_INTERLACE;
01036       readSubPartValues( varFile, _ptrField, subValues );
01037       subPartValues.push_back( subValues );
01038     }
01039   }
01040   while ( !varFile.eof() )
01041   {
01042     TStrOwner line( varFile.getLine() );
01043     if ( isTimeStepEnd( line ))
01044       break;
01045     string word, restLine;
01046     TStrTool::split( line.myValues, word, restLine );
01047     if ( word == "part" ) {
01048       partNumber = atoi( restLine.c_str() );
01049       continue;
01050     }
01051     _SubPartDesc desc( partNumber, word );
01052     supportDescriptor.insert( desc );
01053     subPart = getSubPart( desc );
01054     _SubPartValues subValues( *subPart );
01055     if ( desc.typeName() == "block" )
01056       subValues.myInterlace = MED_NO_INTERLACE;
01057     else
01058       subValues.myInterlace = MED_FULL_INTERLACE;
01059     readSubPartValues( varFile, _ptrField, subValues );
01060     subPartValues.push_back( subValues );
01061   }
01062 
01063   _Support* interSupport = getSupport( supportDescriptor, entity );
01064   setValuesToField( _ptrField, interSupport, subPartValues );
01065 
01066 }
01067 
01068 //================================================================================
01072 //================================================================================
01073 
01074 void ENSIGHT_FIELD_RDONLY_DRIVER::skipTimeStamp(_BinaryFileReader& varFile)
01075 {
01076   medEntityMesh entity = _ptrField->getSupport()->getEntity();
01077   int     nbComponents = _ptrField->getNumberOfComponents();
01078 
01079   if ( isSingleFileMode() )
01080     varFile.skipTimeStepBeginning();
01081 
01082   varFile.skip( 80 ); // description
01083 
01084   _SubPart* subPart;
01085   if ( entity == MED_NODE && !isGoldFormat() ) { // skip values on global nodes
01086     subPart = getSubPart( _SubPartDesc::globalCoordDesc() );
01087     if ( subPart )
01088       varFile.skip( subPart->myNbNodes * nbComponents * sizeof(float) );
01089   }
01090   int partNumber;
01091   while ( !varFile.eof() )
01092   {
01093     TStrOwner line( varFile.getLine() );
01094     if ( isTimeStepEnd( line ))
01095       break;
01096 
01097     string word, restLine;
01098     TStrTool::split( line.myValues, word, restLine );
01099 
01100     if ( word == "part" ) {
01101       if ( isGoldFormat() )
01102         partNumber = *TIntOwner( varFile.getInt(1));
01103       else
01104         partNumber = atoi( restLine.c_str() );
01105       continue;
01106     }
01107     if ( restLine == "undef" ) {
01108       varFile.skip( sizeof(int) );
01109     }
01110     if ( restLine == "partial" ) {
01111       int nbPartial = *TIntOwner( varFile.getInt(1)); // ne
01112       varFile.skip( nbPartial * sizeof(int));
01113     }
01114 
01115     _SubPartDesc desc( partNumber, word );
01116     subPart = getSubPart( desc );
01117     int nbElems = ( entity == MED_NODE ) ? subPart->myNbNodes : subPart->myNbCells;
01118     varFile.skip( nbElems * nbComponents * sizeof(float) );
01119   }
01120 }
01121 
01122 //=======================================================================
01123 //function : write
01124 //=======================================================================
01125 
01126 void ENSIGHT_FIELD_RDONLY_DRIVER::write(void) const
01127   throw (MEDEXCEPTION)
01128 {
01129   throw MEDEXCEPTION("ENSIGHT_FIELD_RDONLY_DRIVER::write : Can't write with a RDONLY driver !");
01130 }
01131 
01132 //=======================================================================
01133 //function : ENSIGHT_FIELD_WRONLY_DRIVER
01134 //=======================================================================
01135 
01136 ENSIGHT_FIELD_WRONLY_DRIVER::ENSIGHT_FIELD_WRONLY_DRIVER()
01137   :ENSIGHT_FIELD_DRIVER()
01138 {
01139 }
01140 
01141 //=======================================================================
01142 //function : ENSIGHT_FIELD_WRONLY_DRIVER
01143 //=======================================================================
01144 
01145 ENSIGHT_FIELD_WRONLY_DRIVER::ENSIGHT_FIELD_WRONLY_DRIVER(const string & fileName,
01146                                                          const FIELD_ * ptrField)
01147   :ENSIGHT_FIELD_DRIVER(fileName,(FIELD_*)ptrField,MED_EN::WRONLY)
01148 {
01149 }
01150 
01151 //=======================================================================
01152 //function : ENSIGHT_FIELD_WRONLY_DRIVER
01153 //=======================================================================
01154 
01155 
01156 ENSIGHT_FIELD_WRONLY_DRIVER::ENSIGHT_FIELD_WRONLY_DRIVER(const ENSIGHT_FIELD_WRONLY_DRIVER & drv)
01157   :ENSIGHT_FIELD_DRIVER(drv)
01158 {
01159 }
01160 
01161 //=======================================================================
01162 //function : ~ENSIGHT_FIELD_WRONLY_DRIVER
01163 //=======================================================================
01164 
01165 ENSIGHT_FIELD_WRONLY_DRIVER::~ENSIGHT_FIELD_WRONLY_DRIVER()
01166 {
01167   close();
01168 }
01169 
01170 
01171 //=======================================================================
01172 //function : copy
01173 //=======================================================================
01174 
01175 GENDRIVER * ENSIGHT_FIELD_WRONLY_DRIVER::copy(void) const
01176 {
01177   ENSIGHT_FIELD_WRONLY_DRIVER * myDriver = new ENSIGHT_FIELD_WRONLY_DRIVER(*this);
01178 
01179   return myDriver ;
01180 }
01181 
01182 //=======================================================================
01183 //function : read
01184 //=======================================================================
01185 
01186 void ENSIGHT_FIELD_WRONLY_DRIVER::read (void)
01187   throw (MEDEXCEPTION)
01188 {
01189   throw MEDEXCEPTION("ENSIGHT_FIELD_WRONLY_DRIVER::read : Can't read with a write only!");
01190 }
01191 
01192 //================================================================================
01196 //================================================================================
01197 const char* getValuePointer( int i, const FIELD_* field );
01198 const char* getValuePointer( int i, const FIELD_* field )
01199 {
01200   switch ( field->getInterlacingType() ) {
01201   case MED_FULL_INTERLACE:
01202     if ( field->getValueType() == MED_REEL64 )
01203       return (const char*) & static_cast<const FIELD<double, FullInterlace>* >
01204         ( field )->getArrayNoGauss()->getIJ( i, 1 );
01205     else
01206       return (const char*) & static_cast<const FIELD<int, FullInterlace>* >
01207         ( field )->getArrayNoGauss()->getIJ( i, 1 );
01208   case MED_NO_INTERLACE:
01209     if ( field->getValueType() == MED_REEL64 )
01210       return (const char*) & static_cast<const FIELD<double, NoInterlace>* >
01211         ( field )->getArrayNoGauss()->getIJ( i, 1 );
01212     else
01213       return (const char*) & static_cast<const FIELD<int, NoInterlace>* >
01214         ( field )->getArrayNoGauss()->getIJ( i, 1 );
01215   case MED_NO_INTERLACE_BY_TYPE:
01216     if ( field->getValueType() == MED_REEL64 )
01217       return (const char*) & static_cast<const FIELD<double, NoInterlaceByType>* >
01218         ( field )->getArrayNoGauss()->getIJ( i, 1 );
01219     else
01220       return (const char*) & static_cast<const FIELD<int, NoInterlaceByType>* >
01221         ( field )->getArrayNoGauss()->getIJ( i, 1 );
01222   default:;
01223   }
01224   return 0;
01225 }
01226 
01227 //=======================================================================
01231 //=======================================================================
01232 
01233 template< typename T >
01234 void write6ASCIIValues( const _SubPartValues& subPartValues,
01235                         int                   nbValues,
01236                         int                   nbComponents,
01237                         int                   componentShift,
01238                         ofstream &            ensightDataFile )
01239 {
01240   // add the 3-d component to a vector in 2D space
01241   const bool add3dComp = true;
01242   int mypoint=0;
01243   if ( subPartValues.myNumbers )
01244   {
01245     vector< _SelectedValueIterator<T> > compValIt =
01246       subPartValues.template getAllSelectedValues<T>( componentShift, nbComponents, add3dComp );
01247     nbComponents = compValIt.size();
01248     // in full interlace
01249     for (int i=0; i<nbValues; i++)
01250       for(int j=0; j<nbComponents; j++) {
01251         ensightDataFile << setw(12) << _toFloat( compValIt[j].next() );
01252         if (++mypoint == 6) {
01253           ensightDataFile << endl ;
01254           mypoint=0;
01255         }
01256       }
01257   }
01258   else {
01259     vector< _ValueIterator<T> > compValIt =
01260       subPartValues.template getAllValues<T>( componentShift, nbComponents, add3dComp );
01261     nbComponents = compValIt.size();
01262     // in full interlace
01263     for (int i=0; i<nbValues; i++)
01264       for(int j=0; j<nbComponents; j++) {
01265         ensightDataFile << setw(12) << _toFloat( compValIt[j].next() );
01266         if (++mypoint == 6) {
01267           ensightDataFile << endl ;
01268           mypoint=0;
01269         }
01270       }
01271   }
01272   if ( nbValues * nbComponents % 6 )
01273     ensightDataFile << endl;
01274 }
01275 
01276 //=======================================================================
01280 //=======================================================================
01281 
01282 template< typename T >
01283 void writeGoldASCIIValues( const _SubPartValues& subPartValues,
01284                            int                   nbValues,
01285                            int                   nbComponents,
01286                            int                   componentShift,
01287                            ofstream &            ensightDataFile )
01288 {
01289   // in no-interlace
01290   for(int j=1; j<=nbComponents; j++) {
01291     if ( subPartValues.myNumbers )
01292     {
01293       _SelectedValueIterator<T> values
01294         = subPartValues.template getSelectedValues<T>( j, componentShift, nbComponents );
01295       for (int i=0; i<nbValues; i++)
01296         ensightDataFile << setw(12) << _toFloat( values.next() ) << endl;
01297     }
01298     else {
01299       _ValueIterator<T> values
01300         = subPartValues.template getValues<T>( j, componentShift, nbComponents );
01301       for (int i=0; i<nbValues; i++)
01302         ensightDataFile << setw(12) << _toFloat( values.next() )<< endl;
01303     }
01304   }
01305   // add the 3-d component to a vector in 2D space
01306   if ( nbComponents == 2 ) {
01307     for (int i=0; i<nbValues; i++)
01308       ensightDataFile << " 0.00000e+00" << endl;
01309   }
01310 }
01311 
01312 //=======================================================================
01316 //=======================================================================
01317 
01318 template< typename T >
01319 void write6BinaryValues( const _SubPartValues& subPartValues,
01320                          int                   nbValues,
01321                          int                   nbComponents,
01322                          int                   componentShift,
01323                          _BinaryFileWriter &   ensightDataFile )
01324 {
01325   const bool add3dComp = true;
01326   if ( subPartValues.myNumbers )
01327   {
01328     vector< _SelectedValueIterator<T> > compValIt =
01329       subPartValues.template getAllSelectedValues<T>( componentShift, nbComponents, add3dComp );
01330     ensightDataFile.addReal( compValIt, nbValues, MED_FULL_INTERLACE );
01331   }
01332   else
01333   {
01334     vector< _ValueIterator<T> > compValIt =
01335       subPartValues.template getAllValues<T>( componentShift, nbComponents, add3dComp );
01336     ensightDataFile.addReal( compValIt, nbValues, MED_FULL_INTERLACE );
01337   }
01338 }
01339 
01340 //=======================================================================
01344 //=======================================================================
01345 
01346 template< typename T >
01347 void writeGoldBinaryValues( const _SubPartValues& subPartValues,
01348                             int                   nbValues,
01349                             int                   nbComponents,
01350                             int                   componentShift,
01351                             _BinaryFileWriter &   ensightDataFile )
01352 {
01353   const bool add3dComp = false;
01354   if ( subPartValues.myNumbers )
01355   {
01356     vector< _SelectedValueIterator<T> > compValIt =
01357       subPartValues.template getAllSelectedValues<T>( componentShift, nbComponents, add3dComp );
01358     ensightDataFile.addReal( compValIt, nbValues, MED_NO_INTERLACE );
01359   }
01360   else
01361   {
01362     vector< _ValueIterator<T> > compValIt =
01363       subPartValues.template getAllValues<T>( componentShift, nbComponents, add3dComp );
01364     ensightDataFile.addReal( compValIt, nbValues, MED_NO_INTERLACE );
01365   }
01366   // add the 3-d component to a vector in 2D space
01367   if ( nbComponents == 2 ) {
01368     vector<float> values( nbValues, 0. );
01369     ensightDataFile.addReal( & values[0], nbValues );
01370   }
01371 }
01372 
01373 //=======================================================================
01374 //function : write
01375 //=======================================================================
01376 
01377 void ENSIGHT_FIELD_WRONLY_DRIVER::write(void) const
01378   throw (MEDEXCEPTION)
01379 {
01380   const char * LOC = "ENSIGHT_FIELD_WRONLY_DRIVER::write(void) const " ;
01381   BEGIN_OF_MED(LOC);
01382 
01383   openConst(false) ; // check if can write to case file
01384 
01385   // Ensight case organization requires a main file (filename.case) which defines organization
01386 
01387   _CaseFileDriver caseFile( getCaseFileName(), this);
01388   caseFile.read();
01389   caseFile.addField( this ); 
01390   caseFile.write(); // all fields of _CaseFileDriver_User are set by this method
01391 
01392   openConst(true) ; // check if can write to data file
01393 
01394   const FIELD_* field     = _ptrField;
01395   const SUPPORT * support = field->getSupport();
01396   const GMESH * mesh      = support->getMesh();
01397 
01398   int dt              = field->getIterationNumber();
01399   int it              = field->getOrderNumber();
01400   int nbComponents    = field->getNumberOfComponents();
01401   med_type_champ type = field->getValueType() ;
01402 
01403   medEntityMesh entity = support->getEntity();
01404   int totalNbValues    = support->getNumberOfElements(MED_ALL_ELEMENTS);
01405   //const int* mainNbValsByType = support->getNumberOfElements();
01406 
01407   int nbValuesByType = 0;
01408   int& componentShift = (type == MED_NO_INTERLACE_BY_TYPE) ? nbValuesByType : totalNbValues;
01409 
01410   bool isOnAll = support->isOnAllElements();
01411   if (!isOnAll && !mesh)
01412     throw MED_EXCEPTION(STRING("Can't write field ") << field->getName() <<
01413                         ", which is not on all elements while mesh is not set to its support");
01414   if (!isOnAll)
01415     isOnAll = ( mesh->getNumberOfElements(entity,MED_ALL_ELEMENTS) == componentShift );
01416   if (!isOnAll && entity == MED_NODE && !isGoldFormat() ) {
01417     throw MED_EXCEPTION(compatibilityPb("Can't write field ") << field->getName() <<
01418                         " which is not on all nodes of the mesh in EnSight6 format,"
01419                         " use EnSight Gold format instead");
01420   }
01421   if ( entity == MED_EDGE && mesh && !isToWriteEntity( MED_EDGE, mesh ))
01422     throw MED_EXCEPTION(STRING(LOC) << "Can't write field " << field->getName()
01423                         << ", fields on MED_EDGE in volumic mesh are not supported");
01424 
01425   // part number
01426   int partNum = getPartNumber( support );
01427   string isPartial = "";
01428   if ( !partNum ) {
01429     if ( !isGoldFormat() )
01430       throw MED_EXCEPTION(STRING("Can't write field ") << field->getName()
01431                           << " in EnSight6 format, it's support " << support->getName()
01432                           << " is not stored in geo file, use EnSight Gold format instead");
01433     isPartial = " partial";
01434     SUPPORT *tmpSupport=new SUPPORT;
01435     tmpSupport->setAll(true);
01436     tmpSupport->setEntity( entity );
01437     partNum = getPartNumber( tmpSupport );
01438     tmpSupport->removeReference();
01439   }
01440 
01441   // supports to write the field for
01442   map< int, const SUPPORT* > parts;
01443   map< int, const SUPPORT* >::iterator partNumIt;
01444   parts[ partNum ] = support;
01445 
01446   // In Ensight 6, nodal field is visible on all parts as nodes are global, for
01447   // the rest cases we write field for all groups in order to see values on them
01448   if ( isOnAll && ( isGoldFormat() || entity != MED_NODE ) && mesh )
01449   {
01450     // In Ensight Gold, to see nodal field on all groups we write them all
01451     int ent = entity, toEntity = entity + 1;
01452     if ( isGoldFormat() && entity == MED_NODE )
01453       ent = MED_CELL, toEntity = MED_ALL_ENTITIES;
01454 
01455     for ( ; ent < toEntity; ++ent ) {
01456       int nbGroups = mesh->getNumberOfGroups(ent);
01457       for ( int i=1; i<=nbGroups; i++) {
01458         const GROUP* group = mesh->getGroup( ent, i );
01459         if (  group != support && !group->isOnAllElements() ) {
01460           partNum = getPartNumber( group );
01461           if ( partNum )
01462             parts.insert( make_pair( partNum, group ));
01463         }
01464       }
01465     }
01466   }
01467 
01468   // description
01469   string description = field->getDescription();
01470   if ( description.empty() )
01471     description = STRING(field->getName()) << " dt=" << dt << " it=" << it;
01472 
01473   cout << "-> Creating the Ensight data file " << getDataFileName() << endl ;
01474 
01475 
01476   _SubPartValues geoTypeValues;
01477   geoTypeValues.myOwnValues = false;
01478   geoTypeValues.myInterlace = field->getInterlacingType();
01479   int nbWrittenValues = 0;
01480 
01481   if ( isBinaryEnSightFormatForWriting() )
01482   {
01483     // ======================================================
01484     //                          Binary
01485     // ======================================================
01486 
01487     // function to write values
01488     typedef void (* TWriteValues) (const _SubPartValues& , int, int, int, _BinaryFileWriter &);
01489     TWriteValues writeValues;
01490     if ( isGoldFormat() ) {
01491       if ( type == MED_REEL64 )     writeValues = writeGoldBinaryValues<double>;
01492       else if ( type == MED_INT32 ) writeValues = writeGoldBinaryValues<int>;
01493       else                          writeValues = writeGoldBinaryValues<long>;
01494     }
01495     else {
01496       if ( type == MED_REEL64 )     writeValues = write6BinaryValues<double>;
01497       else if ( type == MED_INT32 ) writeValues = write6BinaryValues<int>;
01498       else                          writeValues = write6BinaryValues<long>;
01499     }
01500     _BinaryFileWriter ensightDataFile( getDataFileName() );
01501 
01502     // description
01503     ensightDataFile.addString( description );
01504 
01505     for ( partNumIt = parts.begin(); partNumIt != parts.end(); ++partNumIt)
01506     {
01507       const SUPPORT* partSup = partNumIt->second;
01508       partNum                = partNumIt->first;
01509       const bool otherEntity = ( entity != partSup->getEntity() ); // Gold, nodal field
01510       nbWrittenValues        = 0;
01511 
01512       // part number
01513       if ( isGoldFormat() ) {
01514         ensightDataFile.addString("part");
01515         ensightDataFile.addInt( partNum );
01516       }
01517       else if ( entity != MED_NODE ) {
01518         ensightDataFile.addString( STRING("part ") << partNum );
01519       }
01520       // loop on types
01521       int                       nbTypes = partSup->getNumberOfTypes();
01522       const medGeometryElement* geoType = partSup->getTypes();
01523       for (int i=0; i<nbTypes; i++)
01524       {
01525         const medGeometryElement medType = geoType[i];
01526         nbValuesByType = partSup->getNumberOfElements(medType);
01527 
01528         // type name
01529         if ( entity != MED_NODE ) {
01530           const TEnSightElemType& ensightType = getEnSightType(medType);
01531           ensightDataFile.addString( ensightType._name + isPartial );
01532         }
01533         else if ( isGoldFormat() ) {
01534           ensightDataFile.addString( "coordinates" + isPartial );
01535         }
01536 
01537         // supporting numbers (Gold only)
01538         if ( !isPartial.empty() ) {
01539           const int *number = partSup->getNumber(medType);
01540           ensightDataFile.addInt( nbValuesByType );
01541           ensightDataFile.addInt( number, nbValuesByType );
01542         }
01543 
01544         // get field values
01545         if ( otherEntity ) { // Gold, nodal field, non-nodal group (partSup)
01546           if ( isOnAll && partSup->isOnAllElements() ) {
01547             geoTypeValues.myNumbers = 0;
01548             geoTypeValues.myValues  = getValuePointer( 1, field );
01549             nbValuesByType = totalNbValues;
01550           }
01551           else {
01552             geoTypeValues.myNumbers = getNodeNumbers( partSup, nbValuesByType );
01553             geoTypeValues.myValues  = getValuePointer( geoTypeValues.myNumbers[0], field );
01554           }
01555         }
01556         else if ( partSup->getNumberOfElements(MED_ALL_ELEMENTS) != totalNbValues ) {
01557           geoTypeValues.myNumbers = partSup->getNumber(medType);
01558           geoTypeValues.myValues  = getValuePointer( geoTypeValues.myNumbers[0], field );
01559         }
01560         else {
01561           geoTypeValues.myNumbers = 0;
01562           geoTypeValues.myValues  = getValuePointer( nbWrittenValues + 1, field );
01563         }
01564         // write values
01565         writeValues(geoTypeValues, nbValuesByType, nbComponents, componentShift, ensightDataFile);
01566         nbWrittenValues += nbValuesByType;
01567 
01568         if ( otherEntity ) {
01569           if ( geoTypeValues.myNumbers ) delete [] geoTypeValues.myNumbers;
01570           break; // all nodal values are written at once
01571         }
01572       }
01573     }
01574   }
01575   else
01576   {
01577     // ======================================================
01578     //                           ASCII
01579     // ======================================================
01580 
01581     // function to write values
01582     typedef void (* TWriteValues) (const _SubPartValues& , int, int, int, ofstream &);
01583     TWriteValues writeValues;
01584     if ( isGoldFormat() ) {
01585       if ( type == MED_REEL64 )     writeValues = writeGoldASCIIValues<double>;
01586       else if ( type == MED_INT32 ) writeValues = writeGoldASCIIValues<int>;
01587       else                          writeValues = writeGoldASCIIValues<long>;
01588     }
01589     else {
01590       if ( type == MED_REEL64 )     writeValues = write6ASCIIValues<double>;
01591       else if ( type == MED_INT32 ) writeValues = write6ASCIIValues<int>;
01592       else                          writeValues = write6ASCIIValues<long>;
01593     }
01594     const int iw = isGoldFormat() ? 10 : 8; // width of integer
01595 
01596     ofstream ensightDataFile( getDataFileName().c_str(), ios::out);
01597     ensightDataFile.setf(ios::scientific);
01598     ensightDataFile.precision(5);
01599 
01600     // description
01601     ensightDataFile << description << endl;
01602 
01603     for ( partNumIt = parts.begin(); partNumIt != parts.end(); ++partNumIt)
01604     {
01605       const SUPPORT* partSup = partNumIt->second;
01606       partNum                = partNumIt->first;
01607       const bool otherEntity = ( entity != partSup->getEntity() ); // Gold, nodal field
01608       nbWrittenValues        = 0;
01609 
01610       // part number
01611       if ( isGoldFormat() )
01612         ensightDataFile << "part" << endl << setw(iw) << partNum << endl;
01613       else if ( entity != MED_NODE ) {
01614         ensightDataFile << "part " << partNum << endl;
01615       }
01616       // loop on types
01617       int                       nbTypes = partSup->getNumberOfTypes();
01618       const medGeometryElement* geoType = partSup->getTypes();
01619       for (int i=0; i<nbTypes; i++)
01620       {
01621         const medGeometryElement medType = geoType[i];
01622         nbValuesByType = partSup->getNumberOfElements(medType);
01623 
01624         // type name
01625         if ( entity != MED_NODE ) {
01626           const TEnSightElemType& ensightType = getEnSightType(medType);
01627           ensightDataFile << ensightType._name << isPartial << endl;
01628         }
01629         else if ( isGoldFormat() ) {
01630           ensightDataFile << "coordinates" << isPartial << endl;
01631         }
01632 
01633         // supporting numbers (Gold only)
01634         if ( !isPartial.empty() ) {
01635           const int *number = partSup->getNumber(medType);
01636           const int *nEnd   = number + nbValuesByType;
01637           ensightDataFile << setw(iw) << nbValuesByType << endl;
01638           while ( number < nEnd )
01639             ensightDataFile << setw(iw) << *number++ << endl;
01640         }
01641 
01642         // get field values
01643         if ( otherEntity ) { // Gold, nodal field, non-nodal group (partSup)
01644           if ( isOnAll && partSup->isOnAllElements() ) {
01645             geoTypeValues.myNumbers = 0;
01646             geoTypeValues.myValues  = getValuePointer( 1, field );
01647             nbValuesByType = totalNbValues;
01648           }
01649           else {
01650             geoTypeValues.myNumbers = getNodeNumbers( partSup, nbValuesByType );
01651             geoTypeValues.myValues  = getValuePointer( geoTypeValues.myNumbers[0], field );
01652           }
01653         }
01654         else if ( partSup->getNumberOfElements(MED_ALL_ELEMENTS) != totalNbValues ) {
01655           geoTypeValues.myNumbers = partSup->getNumber(medType);
01656           geoTypeValues.myValues  = getValuePointer( geoTypeValues.myNumbers[0], field );
01657         }
01658         else {
01659           geoTypeValues.myNumbers = 0;
01660           geoTypeValues.myValues  = getValuePointer( nbWrittenValues + 1, field );
01661         }
01662 
01663         // write values
01664         writeValues(geoTypeValues, nbValuesByType, nbComponents, componentShift, ensightDataFile);
01665         nbWrittenValues += nbValuesByType;
01666 
01667         if ( otherEntity ) {
01668           if ( geoTypeValues.myNumbers ) delete [] geoTypeValues.myNumbers;
01669           break; // all nodal values are written at once
01670         }
01671       }
01672     } // loop on supports
01673 
01674     ensightDataFile.close();  
01675   }
01676 }