1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #ifndef ASCII_FIELD_DRIVER_HXX
21 #define ASCII_FIELD_DRIVER_HXX
24 #include "MEDMEM_GenDriver.hxx"
25 #include "MEDMEM_Exception.hxx"
26 #include "MEDMEM_Unit.hxx"
27 #include "MEDMEM_Support.hxx"
28 #include "MEDMEM_Mesh.hxx"
29 #include "MEDMEM_ArrayInterface.hxx"
30 #include "MEDMEM_ArrayConvert.hxx"
40 #define PRECISION_IN_ASCII_FILE 10
41 #define PRECISION_IN_COMPARE 1e-10
42 #define SPACE_BETWEEN_NBS 19
47 template<int N,unsigned int CODE>
48 void fill(double *a, const double *b)
51 fill<N-1, (CODE>>2) >(a,b);
55 bool compare(const double* a, const double* b)
57 double sign=b[N]<0 ? -1 : 1;
58 if(a[N]<b[N]*(1-sign*PRECISION_IN_COMPARE))
60 if(a[N]>b[N]*(1+sign*PRECISION_IN_COMPARE))
62 return compare<N-1>(a,b);
65 template<> MEDMEM_EXPORT
66 void fill<-1,0x3>(double *a, const double *b);
68 template<> MEDMEM_EXPORT
69 bool compare<-1>(const double *a, const double *b);
71 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
75 double _coords[SPACEDIMENSION];
79 SDForSorting(const double *coords, const T* comp, int nbComponents);
80 SDForSorting(const SDForSorting& other);
82 bool operator< (const SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>& other) const;
83 void writeLine(ofstream& file) const;
87 class ASCII_FIELD_DRIVER : public GENDRIVER
92 mutable FIELD<T> *_ptrField;
93 std::string _fileName;
94 mutable ofstream _file;
96 MED_EN::med_sort_direc _direc;
99 //static int _nbComponentsForCpyInfo;
102 template <class INTERLACING_TAG>
103 ASCII_FIELD_DRIVER():GENDRIVER(),
104 _ptrField((FIELD<T>)MED_NULL),
107 template <class INTERLACING_TAG>
108 ASCII_FIELD_DRIVER(const string & fileName, FIELD<T,INTERLACING_TAG> * ptrField,
109 MED_EN::med_sort_direc direction=MED_EN::ASCENDING,
110 const char *priority="");
113 ASCII_FIELD_DRIVER(const ASCII_FIELD_DRIVER<T>& other);
114 void open() throw (MEDEXCEPTION);
116 void read ( void ) throw (MEDEXCEPTION);
117 void write( void ) const throw (MEDEXCEPTION);
118 GENDRIVER* copy() const;
120 void buildIntroduction() const;
121 template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>
122 void sortAndWrite() const;
123 //template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>//, std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > > >
124 //static void copyInfo(const double *a,T *b);
125 //static void copyInfo2(const double *,T *);
132 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
133 SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::SDForSorting(const double *coords, const T* comp, int nbComponents):_nbComponents(nbComponents)
135 fill<SPACEDIMENSION-1,SORTSTRATEGY>(_coords,coords);
136 _components=new T[_nbComponents];
137 memcpy(_components,comp,sizeof(T)*_nbComponents);
140 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
141 SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::SDForSorting(const SDForSorting& other):_nbComponents(other._nbComponents)
143 memcpy(_coords,other._coords,sizeof(double)*SPACEDIMENSION);
144 _components=new T[_nbComponents];
145 memcpy(_components,other._components,sizeof(T)*_nbComponents);
148 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
149 SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::~SDForSorting()
151 delete [] _components;
154 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
155 bool SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::operator< (const SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>& other) const
157 return compare<SPACEDIMENSION-1>(_coords,other._coords);
160 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
161 void SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::writeLine(ofstream& file) const
164 double temp[SPACEDIMENSION];
165 fill<SPACEDIMENSION-1,SORTSTRATEGY>(temp,_coords);
166 for(i=0;i<SPACEDIMENSION;i++)
167 file << setw(SPACE_BETWEEN_NBS) << temp[i];
168 for(i=0;i<_nbComponents;i++)
169 file << setw(SPACE_BETWEEN_NBS) << _components[i];
174 template <class INTERLACING_TAG>
175 ASCII_FIELD_DRIVER<T>::ASCII_FIELD_DRIVER(const string & fileName,
176 FIELD<T,INTERLACING_TAG> * ptrField,
177 MED_EN::med_sort_direc direction,
178 const char *priority)
179 :GENDRIVER(fileName,MED_EN::MED_ECRI),_ptrField((FIELD<T>*)ptrField),_fileName(fileName),_direc(direction)
181 _nbComponents=_ptrField->getNumberOfComponents();
183 throw MEDEXCEPTION("ASCII_FIELD_DRIVER : No components in FIELD<T>");
184 _support=(SUPPORT *)_ptrField->getSupport();
185 _mesh=(MESH *)_support->getMesh();
186 _spaceDimension=_mesh->getSpaceDimension();
189 if(priority[0]=='\0')
190 for(i=_spaceDimension-1;i>=0;i--)
197 if(_spaceDimension!=strlen(priority))
198 throw MEDEXCEPTION("ASCII_FIELD_DRIVER : Coordinate priority invalid with spaceDim");
199 for(i=_spaceDimension-1;i>=0;i--)
201 char c=toupper(priority[i]);
202 if(int(c-'X')>(_spaceDimension-1))
203 throw MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid priority definition");
212 ASCII_FIELD_DRIVER<T>::ASCII_FIELD_DRIVER(const ASCII_FIELD_DRIVER<T>& other)
213 :_ptrField(other._ptrField),_fileName(other._fileName),_direc(other._direc),_mesh(other._mesh),_nbComponents(other._nbComponents),
214 _code(other._code),_spaceDimension(other._spaceDimension),_support(other._support)
219 void ASCII_FIELD_DRIVER<T>::open() throw (MEDEXCEPTION)
222 throw MEDEXCEPTION("ASCII_FIELD_DRIVER::open() : file is already open !");
223 _file.open(_fileName.c_str(),ofstream::out | ofstream::app);
227 void ASCII_FIELD_DRIVER<T>::close()
233 void ASCII_FIELD_DRIVER<T>::read ( void ) throw (MEDEXCEPTION)
235 throw MEDEXCEPTION("ASCII_FIELD_DRIVER::read : Can't read with a WRONLY driver !");
239 GENDRIVER* ASCII_FIELD_DRIVER<T>::copy() const
241 return new ASCII_FIELD_DRIVER<T>(*this);
245 void ASCII_FIELD_DRIVER<T>::write( void ) const throw (MEDEXCEPTION)
247 if (!_file.is_open())
248 throw MEDEXCEPTION("ASCII_FIELD_DRIVER::write : can't write a file that was not opened !");
251 switch(_spaceDimension)
259 sortAndWrite<2,52>();
264 sortAndWrite<2,49>();
268 MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid priority definition");
278 sortAndWrite<3,228>();
283 sortAndWrite<3,216>();
288 sortAndWrite<3,225>();
293 sortAndWrite<3,201>();
298 sortAndWrite<3,210>();
303 sortAndWrite<3,198>();
307 MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid priority definition");
312 MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid space dimension must be 2 or 3");
317 void ASCII_FIELD_DRIVER<T>::buildIntroduction() const
321 _file << setiosflags(ios::scientific);
322 _file << "#TITLE: table " << _ptrField->getName() << " TIME: " << _ptrField->getTime() << " IT: " << _ptrField->getIterationNumber() << endl;
323 _file << "#COLUMN_TITLES: ";
324 for(i=0;i<_spaceDimension;i++)
325 _file << char('X'+i) << " | ";
326 const std::string *compoNames=_ptrField->getComponentsNames();
327 for(i=0;i<_nbComponents;i++)
330 _file << compoNames[i];
333 if(i<_nbComponents-1)
337 _file << "#COLUMN_UNITS: ";
338 compoNames=_mesh->getCoordinateptr()->getCoordinatesUnits();
339 for(i=0;i<_spaceDimension;i++)
342 _file << compoNames[i];
347 const UNIT *compoUnits=_ptrField->getComponentsUnits();
348 for(i=0;i<_nbComponents;i++)
351 _file << compoUnits[i].getName();
354 if(i<_nbComponents-1)
361 #include "MEDMEM_Field.hxx"
366 template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>
367 void ASCII_FIELD_DRIVER<T>::sortAndWrite() const
369 typedef typename MEDMEM_ArrayInterface<double,NoInterlace,NoGauss>::Array ArrayDoubleNo;
370 typedef typename MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array ArrayDoubleFull;
371 typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo;
372 typedef typename MEDMEM_ArrayInterface<T,NoInterlaceByType,NoGauss>::Array ArrayNoByType;
373 typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull;
376 int numberOfValues=_ptrField->getNumberOfValues();
377 std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > > li;
378 const double * coord;
379 FIELD<double,FullInterlace> * barycenterField=0;
380 ArrayDoubleNo * baryArrayTmp = NULL;
381 double * xyz[SPACEDIMENSION];
382 bool deallocateXyz=false;
384 if(_support->getEntity()==MED_EN::MED_NODE) {
385 if (_support->isOnAllElements()) {
387 coord=_mesh->getCoordinates(MED_EN::MED_NO_INTERLACE);
388 for(i=0; i<SPACEDIMENSION; i++)
389 xyz[i]=(double *)coord+i*numberOfValues;
393 coord = _mesh->getCoordinates(MED_EN::MED_FULL_INTERLACE);
394 const int * nodesNumber=_support->getNumber(MED_EN::MED_ALL_ELEMENTS);
395 for(i=0; i<SPACEDIMENSION; i++)
396 xyz[i]=new double[numberOfValues];
398 for(i=0;i<numberOfValues;i++) {
399 for(j=0;j<SPACEDIMENSION;j++)
400 xyz[j][i]=coord[(nodesNumber[i]-1)*SPACEDIMENSION+j];
405 barycenterField = _mesh->getBarycenter(_support);
406 baryArrayTmp = ArrayConvert
407 ( *( static_cast<ArrayDoubleFull*>(barycenterField->getArray()) ) );
408 coord = baryArrayTmp->getPtr();
409 for(i=0; i<SPACEDIMENSION; i++)
410 xyz[i]=(double *)(coord+i*numberOfValues);
414 ArrayFull * tmpArray = NULL;
415 if ( _ptrField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE )
416 valsToSet= _ptrField->getValue();
417 else if ( _ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
418 tmpArray = ArrayConvert
419 ( *( static_cast<ArrayNoByType*>(_ptrField->getArray()) ) );
420 valsToSet= tmpArray->getPtr();
423 tmpArray = ArrayConvert
424 ( *( static_cast<ArrayNo*>(_ptrField->getArray()) ) );
425 valsToSet= tmpArray->getPtr();
427 double temp[SPACEDIMENSION];
428 for(i=0;i<numberOfValues;i++) {
429 for(j=0;j<SPACEDIMENSION;j++)
431 li.push_back(SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>(temp,valsToSet+i*_nbComponents,_nbComponents));
434 if (barycenterField) delete barycenterField;
435 if (baryArrayTmp) delete baryArrayTmp;
436 if (tmpArray) delete tmpArray;
439 for(j=0;j<SPACEDIMENSION;j++)
443 _file << setprecision(PRECISION_IN_ASCII_FILE);
444 if(_direc==MED_EN::ASCENDING) {
445 typename std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > >::iterator iter;
446 for(iter=li.begin();iter!=li.end();iter++)
447 (*iter).writeLine(_file);
449 } else if (_direc==MED_EN::DESCENDING) {
451 typename std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > >::reverse_iterator iter;
452 for(iter=li.rbegin();iter!=li.rend();iter++)
453 (*iter).writeLine(_file);
456 MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid sort direction");
460 //_nbComponentsForCpyInfo=_nbComponents;
461 //_ptrField->fillFromAnalytic <TEST<T>::copyInfo3> ();
462 //_ptrField->fillFromAnalytic< ASCII_FIELD_DRIVER<T>::copyInfo<SPACEDIMENSION,SORTSTRATEGY> > ();
464 //typename std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > >::iterator iter;
465 //_file << setiosflags(ios::scientific) << setprecision(PRECISION_IN_ASCII_FILE);
466 //for(iter=li.begin();iter!=li.end();iter++)
468 //(*iter).writeLine(_file);
471 // template <class T>
472 // template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>//, std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY> > lis>
473 // void ASCII_FIELD_DRIVER<T>::copyInfo(const double *a,T *b)
475 // //lis.push_back(SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>(a,b,_nbComponentsForCpyInfo));
478 // template <class T>
479 // int ASCII_FIELD_DRIVER<T>::_nbComponentsForCpyInfo=0;