1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #ifndef ASCII_FIELD_DRIVER_HXX
24 #define ASCII_FIELD_DRIVER_HXX
27 #include "MEDMEM_GenDriver.hxx"
28 #include "MEDMEM_Exception.hxx"
29 #include "MEDMEM_Unit.hxx"
30 #include "MEDMEM_Support.hxx"
31 #include "MEDMEM_Mesh.hxx"
32 #include "MEDMEM_ArrayInterface.hxx"
33 #include "MEDMEM_ArrayConvert.hxx"
45 const int PRECISION_IN_ASCII_FILE = 10;
46 const double PRECISION_IN_COMPARE = 1e-10;
47 const int SPACE_BETWEEN_NBS = 19;
49 template<int N,unsigned int CODE>
50 void fill(double *a, const double *b)
53 fill<N-1, (CODE>>2) >(a,b);
57 bool compare(const double* a, const double* b)
59 double sign=b[N]<0 ? -1 : 1;
60 if(a[N]<b[N]*(1-sign*PRECISION_IN_COMPARE))
62 if(a[N]>b[N]*(1+sign*PRECISION_IN_COMPARE))
64 return compare<N-1>(a,b);
67 template<> MEDMEM_EXPORT
68 void fill<-1,0x3>(double *a, const double *b);
70 template<> MEDMEM_EXPORT
71 bool compare<-1>(const double *a, const double *b);
73 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
77 double _coords[SPACEDIMENSION];
81 SDForSorting(const double *coords, const T* comp, int nbComponents);
82 SDForSorting(const SDForSorting& other);
84 bool operator< (const SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>& other) const;
85 void writeLine(ofstream& file) const;
89 class ASCII_FIELD_DRIVER : public GENDRIVER
94 mutable FIELD<T> *_ptrField;
95 std::string _fileName;
96 mutable ofstream _file;
98 MED_EN::med_sort_direc _direc;
101 //static int _nbComponentsForCpyInfo;
104 template <class INTERLACING_TAG>
105 ASCII_FIELD_DRIVER():GENDRIVER(ASCII_DRIVER),
106 _ptrField((FIELD<T>)MED_NULL),
109 template <class INTERLACING_TAG>
110 ASCII_FIELD_DRIVER(const string & fileName, FIELD<T,INTERLACING_TAG> * ptrField,
111 MED_EN::med_sort_direc direction=MED_EN::ASCENDING,
112 const char *priority="");
115 ASCII_FIELD_DRIVER(const ASCII_FIELD_DRIVER<T>& other);
116 void open() throw (MEDEXCEPTION);
118 void read ( void ) throw (MEDEXCEPTION);
119 void write( void ) const throw (MEDEXCEPTION);
120 GENDRIVER* copy() const;
122 void buildIntroduction() const;
123 template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>
124 void sortAndWrite() const;
125 //template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>//, std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > > >
126 //static void copyInfo(const double *a,T *b);
127 //static void copyInfo2(const double *,T *);
134 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
135 SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::SDForSorting(const double *coords, const T* comp, int nbComponents):_nbComponents(nbComponents)
137 fill<SPACEDIMENSION-1,SORTSTRATEGY>(_coords,coords);
138 _components=new T[_nbComponents];
139 memcpy(_components,comp,sizeof(T)*_nbComponents);
142 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
143 SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::SDForSorting(const SDForSorting& other):_nbComponents(other._nbComponents)
145 memcpy(_coords,other._coords,sizeof(double)*SPACEDIMENSION);
146 _components=new T[_nbComponents];
147 memcpy(_components,other._components,sizeof(T)*_nbComponents);
150 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
151 SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::~SDForSorting()
153 delete [] _components;
156 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
157 bool SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::operator< (const SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>& other) const
159 return compare<SPACEDIMENSION-1>(_coords,other._coords);
162 template <class T, int SPACEDIMENSION, unsigned int SORTSTRATEGY>
163 void SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>::writeLine(ofstream& file) const
166 double temp[SPACEDIMENSION];
167 fill<SPACEDIMENSION-1,SORTSTRATEGY>(temp,_coords);
168 for(i=0;i<SPACEDIMENSION;i++)
169 file << setw(SPACE_BETWEEN_NBS) << temp[i];
170 for(i=0;i<_nbComponents;i++)
171 file << setw(SPACE_BETWEEN_NBS) << _components[i];
176 template <class INTERLACING_TAG>
177 ASCII_FIELD_DRIVER<T>::ASCII_FIELD_DRIVER(const string & fileName,
178 FIELD<T,INTERLACING_TAG> * ptrField,
179 MED_EN::med_sort_direc direction,
180 const char *priority)
181 :GENDRIVER(fileName, MED_EN::WRONLY, ASCII_DRIVER),
182 _ptrField((FIELD<T>*)ptrField),
186 _nbComponents=_ptrField->getNumberOfComponents();
188 throw MEDEXCEPTION("ASCII_FIELD_DRIVER : No components in FIELD<T>");
189 _support=(SUPPORT *)_ptrField->getSupport();
190 _mesh=(MESH *)_support->getMesh();
191 _spaceDimension=_mesh->getSpaceDimension();
194 if(priority[0]=='\0')
195 for(i=_spaceDimension-1;i>=0;i--)
202 if(_spaceDimension != (int)strlen(priority))
203 throw MEDEXCEPTION("ASCII_FIELD_DRIVER : Coordinate priority invalid with spaceDim");
204 for(i=_spaceDimension-1;i>=0;i--)
206 char c=toupper(priority[i]);
207 if(int(c-'X')>(_spaceDimension-1) || int(c-'X')<0)
208 throw MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid priority definition");
217 ASCII_FIELD_DRIVER<T>::ASCII_FIELD_DRIVER(const ASCII_FIELD_DRIVER<T>& other):
218 GENDRIVER(ASCII_DRIVER),
220 _support(other._support),
221 _ptrField(other._ptrField),
222 _fileName(other._fileName),
224 _direc(other._direc),
225 _nbComponents(other._nbComponents),
226 _spaceDimension(other._spaceDimension)
231 void ASCII_FIELD_DRIVER<T>::open() throw (MEDEXCEPTION)
234 throw MEDEXCEPTION("ASCII_FIELD_DRIVER::open() : file is already open !");
235 _file.open(_fileName.c_str(),ofstream::out | ofstream::app);
236 // for MEDMEMTest_AsciiFieldDriver.cxx:208 :
237 // must throw because the file is opened
238 //CPPUNIT_ASSERT_MED_THROW(aDriver1->setFileName("anyfile2"), MEDEXCEPTION);
239 _status = _file.is_open() ? MED_OPENED : MED_INVALID;
243 void ASCII_FIELD_DRIVER<T>::close()
246 _status = MED_CLOSED;
250 void ASCII_FIELD_DRIVER<T>::read ( void ) throw (MEDEXCEPTION)
252 throw MEDEXCEPTION("ASCII_FIELD_DRIVER::read : Can't read with a WRONLY driver !");
256 GENDRIVER* ASCII_FIELD_DRIVER<T>::copy() const
258 return new ASCII_FIELD_DRIVER<T>(*this);
262 void ASCII_FIELD_DRIVER<T>::write( void ) const throw (MEDEXCEPTION)
264 if (!_file.is_open())
265 throw MEDEXCEPTION("ASCII_FIELD_DRIVER::write : can't write a file that was not opened !");
268 switch(_spaceDimension)
276 sortAndWrite<2,52>();
281 sortAndWrite<2,49>();
285 MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid priority definition");
295 sortAndWrite<3,228>();
300 sortAndWrite<3,216>();
305 sortAndWrite<3,225>();
310 sortAndWrite<3,201>();
315 sortAndWrite<3,210>();
320 sortAndWrite<3,198>();
324 MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid priority definition");
329 MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid space dimension must be 2 or 3");
334 void ASCII_FIELD_DRIVER<T>::buildIntroduction() const
338 _file << setiosflags(ios::scientific);
339 _file << "#TITLE: table " << _ptrField->getName() << " TIME: " << _ptrField->getTime() << " IT: " << _ptrField->getIterationNumber() << endl;
340 _file << "#COLUMN_TITLES: ";
341 for(i=0;i<_spaceDimension;i++)
342 _file << char('X'+i) << " | ";
343 const std::string *compoNames=_ptrField->getComponentsNames();
344 for(i=0;i<_nbComponents;i++)
347 _file << compoNames[i];
350 if(i<_nbComponents-1)
354 _file << "#COLUMN_UNITS: ";
355 compoNames=_mesh->getCoordinateptr()->getCoordinatesUnits();
356 for(i=0;i<_spaceDimension;i++)
359 _file << compoNames[i];
364 const UNIT *compoUnits=_ptrField->getComponentsUnits();
365 for(i=0;i<_nbComponents;i++)
368 _file << compoUnits[i].getName();
371 if(i<_nbComponents-1)
378 #include "MEDMEM_Field.hxx"
383 template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>
384 void ASCII_FIELD_DRIVER<T>::sortAndWrite() const
386 typedef typename MEDMEM_ArrayInterface<double,NoInterlace,NoGauss>::Array ArrayDoubleNo;
387 typedef typename MEDMEM_ArrayInterface<double,FullInterlace,NoGauss>::Array ArrayDoubleFull;
388 typedef typename MEDMEM_ArrayInterface<T,NoInterlace,NoGauss>::Array ArrayNo;
389 typedef typename MEDMEM_ArrayInterface<T,NoInterlaceByType,NoGauss>::Array ArrayNoByType;
390 typedef typename MEDMEM_ArrayInterface<T,FullInterlace,NoGauss>::Array ArrayFull;
393 int numberOfValues=_ptrField->getNumberOfValues();
394 std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > > li;
395 const double * coord;
396 FIELD<double,FullInterlace> * barycenterField=0;
397 ArrayDoubleNo * baryArrayTmp = NULL;
398 double * xyz[SPACEDIMENSION];
399 bool deallocateXyz=false;
401 if(_support->getEntity()==MED_EN::MED_NODE) {
402 if (_support->isOnAllElements()) {
404 coord=_mesh->getCoordinates(MED_EN::MED_NO_INTERLACE);
405 for(i=0; i<SPACEDIMENSION; i++)
406 xyz[i]=(double *)coord+i*numberOfValues;
410 coord = _mesh->getCoordinates(MED_EN::MED_FULL_INTERLACE);
411 const int * nodesNumber=_support->getNumber(MED_EN::MED_ALL_ELEMENTS);
412 for(i=0; i<SPACEDIMENSION; i++)
413 xyz[i]=new double[numberOfValues];
415 for(i=0;i<numberOfValues;i++) {
416 for(j=0;j<SPACEDIMENSION;j++)
417 xyz[j][i]=coord[(nodesNumber[i]-1)*SPACEDIMENSION+j];
422 barycenterField = _mesh->getBarycenter(_support);
423 baryArrayTmp = ArrayConvert
424 ( *( static_cast<ArrayDoubleFull*>(barycenterField->getArray()) ) );
425 coord = baryArrayTmp->getPtr();
426 for(i=0; i<SPACEDIMENSION; i++)
427 xyz[i]=(double *)(coord+i*numberOfValues);
431 ArrayFull * tmpArray = NULL;
432 if ( _ptrField->getInterlacingType() == MED_EN::MED_FULL_INTERLACE )
433 valsToSet= _ptrField->getValue();
434 else if ( _ptrField->getInterlacingType() == MED_EN::MED_NO_INTERLACE_BY_TYPE ) {
435 tmpArray = ArrayConvert
436 ( *( static_cast<ArrayNoByType*>(_ptrField->getArray()) ) );
437 valsToSet= tmpArray->getPtr();
440 tmpArray = ArrayConvert
441 ( *( static_cast<ArrayNo*>(_ptrField->getArray()) ) );
442 valsToSet= tmpArray->getPtr();
444 double temp[SPACEDIMENSION];
445 for(i=0;i<numberOfValues;i++) {
446 for(j=0;j<SPACEDIMENSION;j++)
448 li.push_back(SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>(temp,valsToSet+i*_nbComponents,_nbComponents));
451 if (barycenterField) barycenterField->removeReference();
452 if (baryArrayTmp) delete baryArrayTmp;
453 if (tmpArray) delete tmpArray;
456 for(j=0;j<SPACEDIMENSION;j++)
460 _file << setprecision(PRECISION_IN_ASCII_FILE);
461 if(_direc==MED_EN::ASCENDING) {
462 typename std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > >::iterator iter;
463 for(iter=li.begin();iter!=li.end();iter++)
464 (*iter).writeLine(_file);
466 } else if (_direc==MED_EN::DESCENDING) {
468 typename std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > >::reverse_iterator iter;
469 for(iter=li.rbegin();iter!=li.rend();iter++)
470 (*iter).writeLine(_file);
473 MEDEXCEPTION("ASCII_FIELD_DRIVER : Invalid sort direction");
477 //_nbComponentsForCpyInfo=_nbComponents;
478 //_ptrField->fillFromAnalytic <TEST<T>::copyInfo3> ();
479 //_ptrField->fillFromAnalytic< ASCII_FIELD_DRIVER<T>::copyInfo<SPACEDIMENSION,SORTSTRATEGY> > ();
481 //typename std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY > >::iterator iter;
482 //_file << setiosflags(ios::scientific) << setprecision(PRECISION_IN_ASCII_FILE);
483 //for(iter=li.begin();iter!=li.end();iter++)
485 //(*iter).writeLine(_file);
488 // template <class T>
489 // template<int SPACEDIMENSION, unsigned int SORTSTRATEGY>//, std::list< SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY> > lis>
490 // void ASCII_FIELD_DRIVER<T>::copyInfo(const double *a,T *b)
492 // //lis.push_back(SDForSorting<T,SPACEDIMENSION,SORTSTRATEGY>(a,b,_nbComponentsForCpyInfo));
495 // template <class T>
496 // int ASCII_FIELD_DRIVER<T>::_nbComponentsForCpyInfo=0;