00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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
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
00126
00127
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
00237
00238
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:
00275 {
00276 sortAndWrite<2,52>();
00277 break;
00278 }
00279 case 49:
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:
00294 {
00295 sortAndWrite<3,228>();
00296 break;
00297 }
00298 case 216:
00299 {
00300 sortAndWrite<3,216>();
00301 break;
00302 }
00303 case 225:
00304 {
00305 sortAndWrite<3,225>();
00306 break;
00307 }
00308 case 201:
00309 {
00310 sortAndWrite<3,201>();
00311 break;
00312 }
00313 case 210:
00314 {
00315 sortAndWrite<3,210>();
00316 break;
00317 }
00318 case 198:
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
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 }
00498
00499 #endif