Back to index

salome-med  6.5.0
MEDMEM_AsciiFieldDriver.hxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #ifndef ASCII_FIELD_DRIVER_HXX
00024 #define ASCII_FIELD_DRIVER_HXX
00025 
00026 #include "MEDMEM.hxx"
00027 #include "MEDMEM_GenDriver.hxx"
00028 #include "MEDMEM_Exception.hxx"
00029 #include "MEDMEM_Unit.hxx"
00030 #include "MEDMEM_Support.hxx"
00031 #include "MEDMEM_Mesh.hxx"
00032 #include "MEDMEM_ArrayInterface.hxx"
00033 #include "MEDMEM_ArrayConvert.hxx"
00034 
00035 #include <list>
00036 #include <string>
00037 #include <ctype.h>
00038 #include <iomanip>
00039 #include <stdlib.h>
00040 #include <string.h>
00041 #include <fstream>
00042 
00043 namespace MEDMEM {
00044 
00045   const int    PRECISION_IN_ASCII_FILE = 10;
00046   const double PRECISION_IN_COMPARE    = 1e-10;
00047   const int    SPACE_BETWEEN_NBS       = 19;
00048 
00049   template<int N,unsigned int CODE>
00050   void fill(double *a, const double *b)
00051   {
00052     a[N]=b[CODE & 0x3 ];
00053     fill<N-1, (CODE>>2) >(a,b);
00054   }
00055 
00056   template<int N>
00057   bool compare(const double* a, const double* b)
00058   {
00059     double sign=b[N]<0 ? -1 : 1;
00060     if(a[N]<b[N]*(1-sign*PRECISION_IN_COMPARE))
00061       return true;
00062     if(a[N]>b[N]*(1+sign*PRECISION_IN_COMPARE))
00063       return false;
00064     return compare<N-1>(a,b);
00065   }
00066 
00067   template<> MEDMEM_EXPORT
00068   void fill<-1,0x3>(double *a, const double *b);
00069 
00070   template<> MEDMEM_EXPORT 
00071   bool compare<-1>(const double *a, const double *b);
00072 
00073   template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY> 
00074   class SDForSorting
00075   {
00076   private:
00077     double _coords[SPACEDIMENSION];
00078     T *_components;
00079     int _nbComponents;
00080   public:
00081     SDForSorting(const double *coords, const T* comp, int nbComponents);
00082     SDForSorting(const SDForSorting& other);
00083     ~SDForSorting();
00084     bool operator< (const SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>& other) const;
00085     void writeLine(ofstream& file) const;
00086   };
00087 
00088   template <class T>
00089   class ASCII_FIELD_DRIVER : public GENDRIVER
00090   {
00091   private:
00092     MESH                   *_mesh;
00093     SUPPORT                *_support;
00094     mutable FIELD<T>       *_ptrField;
00095     std::string             _fileName;
00096     mutable ofstream        _file;
00097     unsigned int            _code;
00098     MED_EN::med_sort_direc  _direc;
00099     int                     _nbComponents;
00100     int                     _spaceDimension;
00101     //static int           _nbComponentsForCpyInfo;
00102 
00103   public:
00104     template <class INTERLACING_TAG>
00105     ASCII_FIELD_DRIVER():GENDRIVER(ASCII_DRIVER),
00106                          _ptrField((FIELD<T>)MED_NULL),
00107                          _fileName("") {}
00108 
00109     template <class INTERLACING_TAG>
00110     ASCII_FIELD_DRIVER(const string & fileName, FIELD<T,INTERLACING_TAG> * ptrField,
00111                        MED_EN::med_sort_direc direction=MED_EN::ASCENDING,
00112                        const char *priority="");
00113 
00114 
00115     ASCII_FIELD_DRIVER(const ASCII_FIELD_DRIVER<T>& other);
00116     void open() throw (MEDEXCEPTION);
00117     void close();
00118     void read ( void ) throw (MEDEXCEPTION);
00119     void write( void ) const throw (MEDEXCEPTION);
00120     GENDRIVER* copy() const;
00121   private:
00122     void buildIntroduction() const;
00123     template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>
00124     void sortAndWrite() const;
00125     //template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>//, std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > > >
00126     //static void copyInfo(const double *a,T *b);
00127     //static void copyInfo2(const double *,T *);
00128   };
00129 }
00130 
00131 
00132 namespace MEDMEM {
00133 
00134   template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
00135   SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::SDForSorting(const double *coords, const T* comp, int nbComponents):_nbComponents(nbComponents)
00136   {
00137     fill<SPACEDIMENSION-1,SORTSTRATEGY>(_coords,coords);
00138     _components=new T[_nbComponents];
00139     memcpy(_components,comp,sizeof(T)*_nbComponents);
00140   }
00141 
00142   template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
00143   SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::SDForSorting(const SDForSorting& other):_nbComponents(other._nbComponents)
00144   {
00145     memcpy(_coords,other._coords,sizeof(double)*SPACEDIMENSION);
00146     _components=new T[_nbComponents];
00147     memcpy(_components,other._components,sizeof(T)*_nbComponents);
00148   }
00149 
00150   template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
00151   SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::~SDForSorting()
00152   {
00153     delete [] _components;
00154   }
00155 
00156   template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
00157   bool SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::operator< (const SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>& other) const
00158   {
00159     return compare<SPACEDIMENSION-1>(_coords,other._coords);
00160   }
00161 
00162   template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
00163   void SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::writeLine(ofstream& file) const
00164   {
00165     int i;
00166     double temp[SPACEDIMENSION];
00167     fill<SPACEDIMENSION-1,SORTSTRATEGY>(temp,_coords);
00168     for(i=0;i<SPACEDIMENSION;i++)
00169       file << setw(SPACE_BETWEEN_NBS) << temp[i];
00170     for(i=0;i<_nbComponents;i++)
00171       file << setw(SPACE_BETWEEN_NBS) << _components[i];
00172     file << endl;
00173   }
00174 
00175   template <class T>
00176   template <class INTERLACING_TAG>
00177   ASCII_FIELD_DRIVER<T>::ASCII_FIELD_DRIVER(const string & fileName,
00178                                             FIELD<T,INTERLACING_TAG> * ptrField,
00179                                             MED_EN::med_sort_direc direction,
00180                                             const char *priority)
00181     :GENDRIVER(fileName, MED_EN::WRONLY, ASCII_DRIVER),
00182      _ptrField((FIELD<T>*)ptrField),
00183      _fileName(fileName),
00184      _direc(direction)
00185     {
00186       _nbComponents=_ptrField->getNumberOfComponents();
00187       if(_nbComponents<=0)
00188         throw MEDEXCEPTION("ASCII_FIELD_DRIVER : No components in FIELD<T>");
00189       _support=(SUPPORT *)_ptrField->getSupport();
00190       _mesh=(MESH *)_support->getMesh();
00191       _spaceDimension=_mesh->getSpaceDimension();
00192       _code=3;
00193       int i;
00194       if(priority[0]=='\0')
00195         for(i=_spaceDimension-1;i>=0;i--)
00196           {
00197             _code<<=2;
00198             _code+=i;
00199           }
00200       else
00201         {
00202           if(_spaceDimension != (int)strlen(priority))
00203             throw MEDEXCEPTION("ASCII_FIELD_DRIVER : Coordinate priority invalid with spaceDim");
00204           for(i=_spaceDimension-1;i>=0;i--)
00205             {
00206               char c=toupper(priority[i]);
00207               if(int(c-'X')>(_spaceDimension-1) || int(c-'X')<0)
00208                 throw MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid priority definition");
00209               _code<<=2;
00210               _code+=c-'X';
00211             }
00212         }
00213     }
00214 
00215 
00216   template <class T>
00217   ASCII_FIELD_DRIVER<T>::ASCII_FIELD_DRIVER(const ASCII_FIELD_DRIVER<T>& other):
00218     GENDRIVER(ASCII_DRIVER),
00219     _mesh(other._mesh),
00220     _support(other._support),
00221     _ptrField(other._ptrField),
00222     _fileName(other._fileName),
00223     _code(other._code),
00224     _direc(other._direc),
00225     _nbComponents(other._nbComponents),
00226     _spaceDimension(other._spaceDimension)
00227   {
00228   }
00229 
00230   template <class T>
00231   void ASCII_FIELD_DRIVER<T>::open() throw (MEDEXCEPTION)
00232   {
00233                 if (_file.is_open())
00234                         throw MEDEXCEPTION("ASCII_FIELD_DRIVER::open() : file is already open !");
00235     _file.open(_fileName.c_str(),ofstream::out | ofstream::app);
00236     // for MEDMEMTest_AsciiFieldDriver.cxx:208 :
00237     // must throw because the file is opened
00238     //CPPUNIT_ASSERT_MED_THROW(aDriver1->setFileName("anyfile2"), MEDEXCEPTION);
00239     _status = _file.is_open() ? MED_OPENED : MED_INVALID;
00240   }
00241 
00242   template <class T>
00243   void ASCII_FIELD_DRIVER<T>::close()
00244   {
00245     _file.close();
00246     _status = MED_CLOSED;
00247   }
00248 
00249   template <class T>
00250   void ASCII_FIELD_DRIVER<T>::read ( void ) throw (MEDEXCEPTION)
00251   {
00252     throw MEDEXCEPTION("ASCII_FIELD_DRIVER::read : Can't read with a WRONLY driver !");
00253   }
00254 
00255   template <class T>
00256   GENDRIVER* ASCII_FIELD_DRIVER<T>::copy() const
00257   {
00258     return new ASCII_FIELD_DRIVER<T>(*this);
00259   }
00260 
00261   template <class T>
00262   void ASCII_FIELD_DRIVER<T>::write( void ) const throw (MEDEXCEPTION)
00263   {
00264                 if (!_file.is_open()) 
00265                         throw MEDEXCEPTION("ASCII_FIELD_DRIVER::write : can't write a file that was not opened !");
00266                 
00267     buildIntroduction();
00268     switch(_spaceDimension)
00269       {
00270       case 2:
00271         {
00272           switch(_code)
00273             {
00274             case 52: //XY
00275               {
00276                 sortAndWrite<2,52>();
00277                 break;
00278               }
00279             case 49: //YX
00280               {
00281                 sortAndWrite<2,49>();
00282                 break;
00283               }
00284             default:
00285               MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid priority definition");
00286             }
00287           break;
00288         }
00289         case 3:
00290         {
00291           switch(_code)
00292             {
00293             case 228: //XYZ
00294               {
00295                 sortAndWrite<3,228>();
00296                 break;
00297               }
00298             case 216: //XZY
00299               {
00300                 sortAndWrite<3,216>();
00301                 break;
00302               }
00303             case 225://YXZ
00304               {
00305                 sortAndWrite<3,225>();
00306                 break;
00307               }
00308             case 201://YZX
00309               {
00310                 sortAndWrite<3,201>();
00311                 break;
00312               }
00313             case 210://ZXY
00314               {
00315                 sortAndWrite<3,210>();
00316                 break;
00317               }
00318             case 198://ZYX
00319               {
00320                 sortAndWrite<3,198>();
00321                 break;
00322               }
00323              default:
00324               MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid priority definition");
00325             }
00326           break;
00327           }
00328       default:
00329         MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid space dimension must be 2 or 3");
00330         }
00331   }
00332 
00333   template <class T>
00334   void ASCII_FIELD_DRIVER<T>::buildIntroduction() const
00335   {
00336 
00337     int i;
00338     _file  << setiosflags(ios::scientific);
00339     _file << "#TITLE: table " << _ptrField->getName() << " TIME: " << _ptrField->getTime() << " IT: " << _ptrField->getIterationNumber() << endl;
00340     _file << "#COLUMN_TITLES: ";
00341     for(i=0;i<_spaceDimension;i++)
00342       _file << char('X'+i) << " | ";
00343     const std::string *compoNames=_ptrField->getComponentsNames();
00344     for(i=0;i<_nbComponents;i++)
00345       {
00346         if(!compoNames)
00347           _file << compoNames[i];
00348         else
00349           _file << "None";
00350         if(i<_nbComponents-1)
00351           _file << " | ";
00352       }
00353     _file << endl;
00354     _file << "#COLUMN_UNITS: ";
00355     compoNames=_mesh->getCoordinateptr()->getCoordinatesUnits();
00356     for(i=0;i<_spaceDimension;i++)
00357       {
00358         if(!compoNames)
00359           _file << compoNames[i];
00360         else
00361           _file << "None";
00362         _file << " | ";
00363       }
00364     const UNIT *compoUnits=_ptrField->getComponentsUnits();
00365     for(i=0;i<_nbComponents;i++)
00366       {
00367         if(!compoUnits)
00368           _file << compoUnits[i].getName();
00369         else
00370           _file << "None";
00371         if(i<_nbComponents-1)
00372           _file << " | ";
00373       }
00374     _file << endl;
00375   }
00376 }
00377 
00378 #include "MEDMEM_Field.hxx"
00379 
00380 namespace MEDMEM
00381 {
00382   template <class T>
00383   template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>
00384   void ASCII_FIELD_DRIVER<T>::sortAndWrite() const
00385   {
00386     typedef typename MEDMEM_ArrayInterface<double,NoInterlace,NoGauss>::Array    ArrayDoubleNo;
00387     typedef typename MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array  ArrayDoubleFull;
00388     typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array         ArrayNo;
00389     typedef typename MEDMEM_ArrayInterface<T,NoInterlaceByType,NoGauss>::Array   ArrayNoByType;
00390     typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array       ArrayFull;
00391 
00392     int i,j;
00393     int numberOfValues=_ptrField->getNumberOfValues();
00394     std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > > li;
00395     const double * coord;
00396     FIELD<double,FullInterlace> * barycenterField=0;
00397     ArrayDoubleNo * baryArrayTmp = NULL;
00398     double * xyz[SPACEDIMENSION];
00399     bool deallocateXyz=false;
00400 
00401     if(_support->getEntity()==MED_EN::MED_NODE) {
00402       if (_support->isOnAllElements()) {
00403 
00404         coord=_mesh->getCoordinates(MED_EN::MED_NO_INTERLACE);
00405         for(i=0; i<SPACEDIMENSION; i++)
00406           xyz[i]=(double *)coord+i*numberOfValues;
00407 
00408       } else {
00409 
00410         coord = _mesh->getCoordinates(MED_EN::MED_FULL_INTERLACE);
00411         const int * nodesNumber=_support->getNumber(MED_EN::MED_ALL_ELEMENTS);
00412         for(i=0; i<SPACEDIMENSION; i++)
00413           xyz[i]=new double[numberOfValues];
00414             deallocateXyz=true;
00415             for(i=0;i<numberOfValues;i++) {
00416               for(j=0;j<SPACEDIMENSION;j++)
00417                 xyz[j][i]=coord[(nodesNumber[i]-1)*SPACEDIMENSION+j];
00418             }
00419       }
00420     } else {
00421 
00422       barycenterField = _mesh->getBarycenter(_support);
00423       baryArrayTmp = ArrayConvert
00424         ( *( static_cast<ArrayDoubleFull*>(barycenterField->getArray()) ) );
00425       coord = baryArrayTmp->getPtr();
00426       for(i=0; i<SPACEDIMENSION; i++)
00427         xyz[i]=(double *)(coord+i*numberOfValues);
00428     }
00429 
00430     const T * valsToSet;
00431     ArrayFull * tmpArray = NULL;
00432     if ( _ptrField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE )
00433       valsToSet= _ptrField->getValue();
00434     else if ( _ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
00435       tmpArray = ArrayConvert
00436         ( *( static_cast<ArrayNoByType*>(_ptrField->getArray()) ) );
00437       valsToSet= tmpArray->getPtr();
00438     }
00439     else {
00440       tmpArray = ArrayConvert
00441         ( *( static_cast<ArrayNo*>(_ptrField->getArray()) ) );
00442       valsToSet= tmpArray->getPtr();
00443     }
00444     double temp[SPACEDIMENSION];
00445     for(i=0;i<numberOfValues;i++) {
00446       for(j=0;j<SPACEDIMENSION;j++)
00447         temp[j]=xyz[j][i];
00448       li.push_back(SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>(temp,valsToSet+i*_nbComponents,_nbComponents));
00449     }
00450 
00451     if (barycenterField) barycenterField->removeReference();
00452     if (baryArrayTmp)    delete baryArrayTmp;
00453     if (tmpArray)        delete tmpArray;
00454 
00455     if(deallocateXyz)
00456       for(j=0;j<SPACEDIMENSION;j++)
00457         delete [] xyz[j];
00458 
00459     li.sort();
00460     _file << setprecision(PRECISION_IN_ASCII_FILE);
00461     if(_direc==MED_EN::ASCENDING) {
00462       typename std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > >::iterator iter;
00463       for(iter=li.begin();iter!=li.end();iter++)
00464         (*iter).writeLine(_file);
00465       _file << endl;
00466     } else if (_direc==MED_EN::DESCENDING) {
00467 
00468       typename std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > >::reverse_iterator iter;
00469       for(iter=li.rbegin();iter!=li.rend();iter++)
00470         (*iter).writeLine(_file);
00471       _file << endl;
00472     } else
00473       MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid sort direction");
00474   }
00475 
00476   //{
00477     //_nbComponentsForCpyInfo=_nbComponents;
00478     //_ptrField->fillFromAnalytic <TEST<T>::copyInfo3> ();
00479     //_ptrField->fillFromAnalytic<  ASCII_FIELD_DRIVER<T>::copyInfo<SPACEDIMENSION,SORTSTRATEGY> > ();
00480     //li.sort();
00481     //typename std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > >::iterator iter;
00482     //_file << setiosflags(ios::scientific) << setprecision(PRECISION_IN_ASCII_FILE);
00483     //for(iter=li.begin();iter!=li.end();iter++)
00484     //  {
00485     //(*iter).writeLine(_file);
00486     // }
00487 
00488 //   template <class T>
00489 //   template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>//, std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY> > lis>
00490 //   void ASCII_FIELD_DRIVER<T>::copyInfo(const double *a,T *b)
00491 //   {
00492 //     //lis.push_back(SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>(a,b,_nbComponentsForCpyInfo));
00493 //   }
00494 
00495 //   template <class T>
00496 //   int ASCII_FIELD_DRIVER<T>::_nbComponentsForCpyInfo=0;
00497 }
00498 
00499 #endif