00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "Particle/ParticleAttrib.h"
00028 #include "Field/Field.h"
00029 #include "Field/LField.h"
00030 #include "Message/Message.h"
00031 #include "Utility/IpplInfo.h"
00032 #include "Utility/PAssert.h"
00033 #include "Utility/IpplStats.h"
00034 #include "AppTypes/AppTypeTraits.h"
00035 #include "Profile/Profiler.h"
00036
00037
00039
00040
00041 template <class T>
00042 ParticleAttribElem<T,1U>
00043 ParticleAttrib<T>::operator()(unsigned i) {
00044 PInsist(AppTypeTraits<T>::ElemDim > 0,
00045 "No operator()(unsigned) for this element type!!");
00046 return ParticleAttribElem<T,1U>(*this, vec<unsigned,1U>(i));
00047 }
00048
00049
00051
00052 template <class T>
00053 ParticleAttribElem<T,2U>
00054 ParticleAttrib<T>::operator()(unsigned i, unsigned j) {
00055 PInsist(AppTypeTraits<T>::ElemDim > 1,
00056 "No operator()(unsigned,unsigned) for this element type!!");
00057 return ParticleAttribElem<T,2U>(*this, vec<unsigned,2U>(i,j));
00058 }
00059
00060
00062
00063 template <class T>
00064 ParticleAttribElem<T,3U>
00065 ParticleAttrib<T>::operator()(unsigned i, unsigned j, unsigned k) {
00066 PInsist(AppTypeTraits<T>::ElemDim > 2,
00067 "No operator()(unsigned,unsigned,unsigned) for this element type!!");
00068 return ParticleAttribElem<T,3U>(*this, vec<unsigned,3U>(i,j,k));
00069 }
00070
00071
00073
00074
00075 template<class T>
00076 void ParticleAttrib<T>::create(size_t M) {
00077 TAU_PROFILE("ParticleAttrib::create()", "void (unsigned)", TAU_PARTICLE);
00078
00079
00080 if (M > 0)
00081 ParticleList.insert(ParticleList.end(), M, T());
00082 }
00083
00084
00086
00087
00088
00089
00090
00091
00092
00093 template<class T>
00094 void ParticleAttrib<T>::destroy(size_t M, size_t I, bool optDestroy) {
00095 TAU_PROFILE("ParticleAttrib::destroy()", "void (unsigned, unsigned, bool)", TAU_PARTICLE);
00096
00097 if (M == 0) return;
00098 if (optDestroy) {
00099
00100
00101 typename ParticleList_t::iterator putloc = ParticleList.begin() + I;
00102 typename ParticleList_t::iterator getloc = ParticleList.end() - M;
00103 typename ParticleList_t::iterator endloc = ParticleList.end();
00104
00105
00106 if ((I + M) > (ParticleList.size() - M))
00107 getloc = putloc + M;
00108
00109
00110 while (getloc != endloc)
00111 *putloc++ = *getloc++;
00112
00113 ParticleList.erase(endloc - M, endloc);
00114 }
00115 else {
00116
00117 typename ParticleList_t::iterator loc = ParticleList.begin() + I;
00118 ParticleList.erase(loc, loc + M);
00119 }
00120 return;
00121 }
00122
00123
00125
00126
00127
00128
00129
00130
00131
00132 template <class T>
00133 void ParticleAttrib<T>::destroy(const vector< pair<size_t,size_t> >& dlist,
00134 bool optDestroy)
00135 {
00136 TAU_PROFILE("ParticleAttrib::destroy()", "void (vector< pair<unsigned,unsigned> >, bool)", TAU_PARTICLE);
00137
00138 if (dlist.empty()) return;
00139 typedef vector< pair<size_t,size_t> > dlist_t;
00140 if (optDestroy) {
00141
00142 dlist_t::const_reverse_iterator rbeg, rend = dlist.rend();
00143
00144 typename ParticleList_t::iterator putloc, saveloc;
00145 typename ParticleList_t::iterator getloc = ParticleList.end();
00146 typename ParticleList_t::iterator endloc = ParticleList.end();
00147
00148 size_t I, M, numParts=0;
00149 for (rbeg = dlist.rbegin(); rbeg != rend; ++rbeg) {
00150 I = (*rbeg).first;
00151 M = (*rbeg).second;
00152 numParts += M;
00153
00154 putloc = ParticleList.begin() + I;
00155
00156 if ((I + M) > ((getloc - ParticleList.begin()) - M)) {
00157
00158 saveloc = getloc;
00159 getloc = putloc + M;
00160
00161 while (getloc != saveloc) {
00162 *putloc++ = *getloc++;
00163 }
00164
00165 getloc = putloc;
00166 }
00167 else {
00168
00169 getloc = getloc - M;
00170 saveloc = getloc;
00171
00172 for (size_t m=0; m<M; ++m)
00173 *putloc++ = *getloc++;
00174
00175 getloc = saveloc;
00176 }
00177 }
00178
00179 ParticleList.erase( endloc - numParts, endloc );
00180 }
00181 else {
00182
00183 dlist_t::const_iterator dnext = dlist.begin(), dend = dlist.end();
00184 size_t putIndex, getIndex, endIndex = ParticleList.size();
00185 putIndex = (*dnext).first;
00186 getIndex = putIndex + (*dnext).second;
00187 ++dnext;
00188
00189 while (dnext != dend && getIndex == (*dnext).first) {
00190 getIndex += (*dnext).second;
00191 ++dnext;
00192 }
00193 while (dnext != dend) {
00194
00195 ParticleList[putIndex++] = ParticleList[getIndex++];
00196
00197 while (dnext != dend && getIndex == (*dnext).first) {
00198 getIndex += (*dnext).second;
00199 ++dnext;
00200 }
00201 }
00202
00203 while (getIndex < endIndex) {
00204
00205 ParticleList[putIndex++] = ParticleList[getIndex++];
00206 }
00207
00208 typename ParticleList_t::iterator loc = ParticleList.begin() + putIndex;
00209 ParticleList.erase(loc, ParticleList.end());
00210 }
00211 return;
00212 }
00213
00214
00216
00217
00218 template<class T>
00219 size_t
00220 ParticleAttrib<T>::putMessage(Message& msg, size_t M, size_t I)
00221 {
00222 TAU_PROFILE("ParticleAttrib::putMessage()",
00223 "unsigned (Message, unsigned, unsigned)", TAU_PARTICLE);
00224
00225 if (M > 0) {
00226 if (isTemporary()) {
00227 ::putMessage(msg, M);
00228 }
00229 else {
00230 typename ParticleList_t::iterator currp = ParticleList.begin() + I;
00231 typename ParticleList_t::iterator endp = currp + M;
00232 ::putMessage(msg, currp, endp);
00233 }
00234 }
00235
00236 return M;
00237 }
00238
00239
00241
00242
00243 template<class T>
00244 size_t
00245 ParticleAttrib<T>::putMessage(Message& msg,
00246 const vector<size_t>& putList)
00247 {
00248 TAU_PROFILE("ParticleAttrib::putMessage()",
00249 "unsigned (Message, vector<unsigned>)", TAU_PARTICLE);
00250
00251 vector<size_t>::size_type M = putList.size();
00252
00253 if (M > 0) {
00254 if (isTemporary()) {
00255 ::putMessage(msg, M);
00256 }
00257 else {
00258 ::putMessage(msg, putList, ParticleList.begin());
00259 }
00260 }
00261
00262 return M;
00263 }
00264
00265
00267
00268
00269
00270 template<class T>
00271 size_t
00272 ParticleAttrib<T>::getMessage(Message& msg, size_t M)
00273 {
00274 TAU_PROFILE("ParticleAttrib::getMessage()",
00275 "unsigned (Message, unsigned)", TAU_PARTICLE);
00276
00277 if (M > 0) {
00278 if (isTemporary()) {
00279 size_t checksize;
00280 ::getMessage(msg, checksize);
00281 PAssert(checksize == M);
00282 create(M);
00283 }
00284 else {
00285 size_t currsize = size();
00286 create(M);
00287 ::getMessage_iter(msg, ParticleList.begin() + currsize);
00288 }
00289 }
00290
00291 return M;
00292 }
00293
00294
00296
00297
00298 template<class T>
00299 void ParticleAttrib<T>::printDebug(Inform& o)
00300 {
00301 TAU_PROFILE("ParticleAttrib::printDebug()",
00302 "void (Inform)", TAU_PARTICLE | TAU_IO);
00303
00304 o << "PAttr: size = " << ParticleList.size()
00305 << ", capacity = " << ParticleList.capacity()
00306 << ", temporary = " << isTemporary();
00307 }
00308
00309
00310 template<class T>
00311 struct PASortCompare
00312 {
00313 static bool compare(const T &, const T &, bool)
00314 {
00315
00316 return false;
00317 }
00318 };
00319
00320 #define PA_SORT_COMPARE_SCALAR(SCALAR) \
00321 template<> \
00322 struct PASortCompare<SCALAR> \
00323 { \
00324 static bool compare(const SCALAR &a, const SCALAR &b, bool ascending) \
00325 { \
00326 return (ascending ? (a < b) : (a > b)); \
00327 } \
00328 };
00329
00330 PA_SORT_COMPARE_SCALAR(char)
00331 PA_SORT_COMPARE_SCALAR(unsigned char)
00332 PA_SORT_COMPARE_SCALAR(short)
00333 PA_SORT_COMPARE_SCALAR(unsigned short)
00334 PA_SORT_COMPARE_SCALAR(int)
00335 PA_SORT_COMPARE_SCALAR(unsigned int)
00336 PA_SORT_COMPARE_SCALAR(long)
00337 PA_SORT_COMPARE_SCALAR(unsigned long)
00338 PA_SORT_COMPARE_SCALAR(float)
00339 PA_SORT_COMPARE_SCALAR(double)
00340
00341
00343
00344
00345
00346
00347
00348
00349
00350
00351 template<class T>
00352 void ParticleAttrib<T>::calcSortList(SortList_t &slist, bool ascending)
00353 {
00354 int i, j;
00355
00356
00357
00358
00359 SortList_t::size_type slsize = slist.size();
00360 size_t mysize = size();
00361 if (slsize < mysize) {
00362
00363 slist.insert(slist.end(), mysize - slsize, (SortList_t::value_type) 0);
00364
00365 }
00366
00367
00368
00369
00370 for (i=0; i < mysize; ++i)
00371 slist[i] = (-1);
00372
00373
00374
00375
00376 int firstindx = 0;
00377 int lastindx = (mysize - 1);
00378 for (i=0; i < mysize; ++i) {
00379 int currindx = firstindx;
00380 T currval = ParticleList[currindx];
00381
00382 for (j=(firstindx + 1); j <= lastindx; ++j) {
00383
00384 if (slist[j] < 0) {
00385
00386
00387 if (PASortCompare<T>::compare(ParticleList[j], currval, ascending)) {
00388 currindx = j;
00389 currval = ParticleList[currindx];
00390 }
00391 }
00392 }
00393
00394
00395
00396
00397 slist[currindx] = i;
00398
00399
00400
00401
00402 while (slist[firstindx] >= 0 && firstindx < lastindx)
00403 firstindx++;
00404 while (slist[lastindx] >= 0 && firstindx < lastindx)
00405 lastindx--;
00406
00407
00408 }
00409 }
00410
00411
00413
00414
00415
00416
00417
00418
00419
00420 template<class T>
00421 void ParticleAttrib<T>::sort(SortList_t &slist)
00422 {
00423
00424 PAssert(slist.size() >= size());
00425
00426
00427
00428
00429
00430 int i, mysize = size();
00431 for (i=0; i < mysize; ++i) {
00432 PAssert(slist[i] < mysize);
00433
00434
00435
00436 if (slist[i] >= 0 && slist[i] != i) {
00437
00438 PAssert(slist[slist[i]] >= 0);
00439
00440
00441 T tmpval = ParticleList[i];
00442 ParticleList[i] = ParticleList[slist[i]];
00443 ParticleList[slist[i]] = tmpval;
00444
00445
00446
00447
00448 slist[slist[i]] -= mysize;
00449
00450
00451
00452 }
00453 }
00454
00455
00456 for (i=0; i < mysize; ++i) {
00457 if (slist[i] < 0)
00458 slist[i] += mysize;
00459
00460
00461 }
00462 }
00463
00464
00466
00468
00469
00470
00472
00474
00475
00477
00479
00480
00482
00484
00485 template <class FT, unsigned Dim, class M, class C, class PT, class IntOp>
00486 void
00487 scatter(Field<FT,Dim,M,C>& f, const ParticleAttrib< Vektor<PT,Dim> >& pp,
00488 const IntOp& intop, FT val) {
00489 TAU_TYPE_STRING(taustr, "void (" + CT(f) + ", " + CT(pp) + ", "
00490 + CT(intop) + ", " + CT(val) + " )" );
00491 TAU_PROFILE("scatter()", taustr, TAU_PARTICLE);
00492
00493
00494 f.Uncompress();
00495 FT zero = 0;
00496 f.setGuardCells(zero);
00497
00498 const M& mesh = f.get_mesh();
00499
00500 typename ParticleAttrib< Vektor<PT,Dim> >::iterator ppiter, ppend=pp.end();
00501 for (ppiter = pp.begin(); ppiter != ppend; ++ppiter)
00502 IntOp::scatter(val,f,*ppiter,mesh);
00503
00504
00505 f.accumGuardCells();
00506
00507 INCIPPLSTAT(incParticleScatters);
00508 return;
00509 }
00510
00511 template <class FT, unsigned Dim, class M, class C, class PT,
00512 class IntOp, class CacheData>
00513 void
00514 scatter(Field<FT,Dim,M,C>& f, const ParticleAttrib< Vektor<PT,Dim> >& pp,
00515 const IntOp& intop, ParticleAttrib<CacheData>& cache, FT val) {
00516
00517 TAU_TYPE_STRING(taustr, "void (" + CT(f) + ", " + CT(pp) + ", "
00518 + CT(intop) + ", " + CT(cache) + ", " + CT(val) + " )" );
00519 TAU_PROFILE("scatter()", taustr, TAU_PARTICLE);
00520
00521
00522 f.Uncompress();
00523 FT zero = 0;
00524 f.setGuardCells(zero);
00525
00526 const M& mesh = f.get_mesh();
00527
00528 typename ParticleAttrib< Vektor<PT,Dim> >::iterator ppiter, ppend=pp.end();
00529 typename ParticleAttrib<CacheData>::iterator citer=cache.begin();
00530 for (ppiter = pp.begin(); ppiter != ppend; ++ppiter, ++citer)
00531 IntOp::scatter(val,f,*ppiter,mesh,*citer);
00532
00533
00534 f.accumGuardCells();
00535
00536 INCIPPLSTAT(incParticleScatters);
00537 return;
00538 }
00539
00540 template <class FT, unsigned Dim, class M, class C,
00541 class CacheData, class IntOp>
00542 void
00543 scatter(Field<FT,Dim,M,C>& f, const IntOp& intop,
00544 const ParticleAttrib<CacheData>& cache, FT val) {
00545
00546 TAU_TYPE_STRING(taustr, "void (" + CT(f) + ", " + CT(intop) + ", "
00547 + CT(cache) + ", " + CT(val) + " )" );
00548 TAU_PROFILE("scatter()", taustr, TAU_PARTICLE);
00549
00550
00551 f.Uncompress();
00552 FT zero = 0;
00553 f.setGuardCells(zero);
00554
00555
00556 typename ParticleAttrib<CacheData>::iterator citer, cend=cache.end();
00557 for (citer = cache.begin(); citer != cend; ++citer)
00558 IntOp::scatter(val,f,*citer);
00559
00560
00561 f.accumGuardCells();
00562
00563 INCIPPLSTAT(incParticleScatters);
00564 return;
00565 }
00566
00567
00568
00569
00570
00571
00572