OPAL (Object Oriented Parallel Accelerator Library) 2022.1
OPAL
IntTSC.h
Go to the documentation of this file.
1// -*- C++ -*-
2/***************************************************************************
3 *
4 * The IPPL Framework
5 *
6 *
7 * Visit http://people.web.psi.ch/adelmann/ for more details
8 *
9 ***************************************************************************/
10
11#ifndef INT_TSC_H
12#define INT_TSC_H
13
14/* IntTSC.h -- Definition of simple class to perform cloud-in-cell
15 interpolation of data for a single particle to or from a IPPL Field.
16 This interpolation scheme is also referred to as linear interpolation,
17 area-weighting (in 2D), or volume-weighting (in 3D). */
18
19// include files
21#include "Field/Field.h"
22
23
24// forward declaration
25class IntTSC;
26
27// specialization of InterpolatorTraits
28template <class T, unsigned Dim>
31};
32
33
34
35// IntTSCImpl class definition
36template <unsigned Dim>
37class IntTSCImpl : public Interpolator {
38
39public:
40 // constructor/destructor
43
44 // gather/scatter functions
45
46 // scatter particle data into Field using particle position and mesh
47 template <class FT, class M, class C, class PT>
48 static
49 void scatter(const FT& /*pdata*/, Field<FT,Dim,M,C>& f,
50 const Vektor<PT,Dim>& ppos, const M& mesh) {
51 CenteringTag<C> ctag;
52 Vektor<PT,Dim> gpos, dpos, delta;
53 NDIndex<Dim> ngp;
55 //BENI: offset not needed, since NGP is used as center
56 //int lgpoff[Dim];
57 // find nearest grid point for particle position, store in NDIndex obj
58 ngp = FindNGP(mesh, ppos, ctag);
59 // get position of ngp
60 FindPos(gpos, mesh, ngp, ctag);
61 // get mesh spacings
62 FindDelta(delta, mesh, ngp, ctag);
63 // Try to find ngp in local fields and get iterator
64 fiter = getFieldIter(f,ngp);
65 // Now we find the offset from ngp to next-lowest grip point (lgp)
66 /* //BENI: we take nearest grid point as it is as the center. No modification needed.
67 for (d=0; d<Dim; ++d) {
68 if (gpos(d) > ppos(d)) {
69 lgpoff[d] = -1; // save the offset
70 gpos(d) = gpos(d) - delta(d); // adjust gpos to lgp position
71 }
72 else {
73 lgpoff[d] = 0; // save the offset
74 }
75 }
76 // adjust position of Field iterator to lgp position
77 fiter.moveBy(lgpoff);
78 */
79 // get distance from ppos to gpos
80 dpos = ppos - gpos;
81 // normalize dpos by mesh spacing
82 dpos /= delta;
83 // accumulate into local elements
84 ERRORMSG("IntTSC::scatter: not implemented for Dim>3!!"<<endl);
85 return;
86 }
87
88 // scatter particle data into Field using particle position and mesh
89 // and cache mesh information for reuse
90 template <class FT, class M, class C, class PT>
91 static
92 void scatter(const FT& /*pdata*/, Field<FT,Dim,M,C>& f,
93 const Vektor<PT,Dim>& ppos, const M& mesh,
94 NDIndex<Dim>& ngp, int [Dim], Vektor<PT,Dim>& dpos) {
95 CenteringTag<C> ctag;
96 Vektor<PT,Dim> gpos, delta;
98 // find nearest grid point for particle position, store in NDIndex obj
99 ngp = FindNGP(mesh, ppos, ctag);
100 // get position of ngp
101 FindPos(gpos, mesh, ngp, ctag);
102 // get mesh spacings
103 FindDelta(delta, mesh, ngp, ctag);
104 // Try to find ngp in local fields and get iterator
105 fiter = getFieldIter(f,ngp);
106 // Now we find the offset from ngp to next-lowest grip point (lgp)
107 /*
108 for (d=0; d<Dim; ++d) {
109 if (gpos(d) > ppos(d)) {
110 lgpoff[d] = -1; // save the offset
111 gpos(d) = gpos(d) - delta(d); // adjust gpos to lgp position
112 }
113 else {
114 lgpoff[d] = 0; // save the offset
115 }
116 }
117 // adjust position of Field iterator to lgp position
118 fiter.moveBy(lgpoff);
119 // get distance from ppos to gpos
120 */
121 dpos = ppos - gpos;
122 // normalize dpos by mesh spacing
123 dpos /= delta;
124 // accumulate into local elements
125 ERRORMSG("IntTSC::scatter: not implemented for Dim>3!!"<<endl);
126 return;
127 }
128
129 // scatter particle data into Field using cached mesh information
130 template <class FT, class M, class C, class PT>
131 static
132 void scatter(const FT& /*pdata**/, Field<FT,Dim,M,C>& f,
133 const NDIndex<Dim>& ngp, const int /*lgpoff*/ [Dim],
134 const Vektor<PT,Dim>& /*dpos*/) {
136 // Try to find ngp in local fields and get iterator
137 fiter = getFieldIter(f,ngp);
138 // adjust position of Field iterator to lgp position
139 //fiter.moveBy(lgpoff);
140 // accumulate into local elements
141 ERRORMSG("IntTSC::scatter: not implemented for Dim>3!!"<<endl);
142 return;
143 }
144
145 // gather particle data from Field using particle position and mesh
146 template <class FT, class M, class C, class PT>
147 static
148 void gather(FT& /*pdata*/, const Field<FT,Dim,M,C>& f,
149 const Vektor<PT,Dim>& ppos, const M& mesh) {
150 CenteringTag<C> ctag;
151 Vektor<PT,Dim> gpos, dpos, delta;
152 NDIndex<Dim> ngp;
154 int lgpoff[Dim];
155 // find nearest grid point for particle position, store in NDIndex obj
156 ngp = FindNGP(mesh, ppos, ctag);
157 // get position of ngp
158 FindPos(gpos, mesh, ngp, ctag);
159 // get mesh spacings
160 FindDelta(delta, mesh, ngp, ctag);
161 // Try to find ngp in local fields and get iterator
162 fiter = getFieldIter(f,ngp);
163 /*
164 // Now we find the offset from ngp to next-lowest grip point (lgp)
165 for (d=0; d<Dim; ++d) {
166 if (gpos(d) > ppos(d)) {
167 lgpoff[d] = -1; // save the offset
168 gpos(d) = gpos(d) - delta(d); // adjust gpos to lgp position
169 }
170 else {
171 lgpoff[d] = 0; // save the offset
172 }
173 }
174 // adjust position of Field iterator to lgp position
175 fiter.moveBy(lgpoff);
176 */
177 // get distance from ppos to gpos
178 dpos = ppos - gpos;
179 // normalize dpos by mesh spacing
180 dpos /= delta;
181 // accumulate into particle attrib
182 ERRORMSG("IntTSC::gather: not implemented for Dim>3!!"<<endl);
183 return;
184 }
185
186 // gather particle data from Field using particle position and mesh
187 // and cache mesh information for reuse
188 template <class FT, class M, class C, class PT>
189 static
190 void gather(FT& /*pdata*/, const Field<FT,Dim,M,C>& f,
191 const Vektor<PT,Dim>& ppos, const M& mesh,
192 NDIndex<Dim>& ngp, int /*lgpoff*/[Dim], Vektor<PT,Dim>& dpos) {
193 CenteringTag<C> ctag;
194 Vektor<PT,Dim> gpos, delta;
196 // find nearest grid point for particle position, store in NDIndex obj
197 ngp = FindNGP(mesh, ppos, ctag);
198 // get position of ngp
199 FindPos(gpos, mesh, ngp, ctag);
200 // get mesh spacings
201 FindDelta(delta, mesh, ngp, ctag);
202 // Try to find ngp in local fields and get iterator
203 fiter = getFieldIter(f,ngp);
204 /*
205 // Now we find the offset from ngp to next-lowest grip point (lgp)
206 for (d=0; d<Dim; ++d) {
207 if (gpos(d) > ppos(d)) {
208 lgpoff[d] = -1; // save the offset
209 gpos(d) = gpos(d) - delta(d); // adjust gpos to lgp position
210 }
211 else {
212 lgpoff[d] = 0; // save the offset
213 }
214 }
215 // adjust position of Field iterator to lgp position
216 fiter.moveBy(lgpoff);
217 */
218 // get distance from ppos to gpos
219 dpos = ppos - gpos;
220 // normalize dpos by mesh spacing
221 dpos /= delta;
222 // accumulate into particle attrib
223 ERRORMSG("IntTSC::gather: not implemented for Dim>3!!"<<endl);
224 return;
225 }
226
227 // gather particle data from Field using cached mesh information
228 template <class FT, class M, class C, class PT>
229 static
230 void gather(FT& /*pdata*/, const Field<FT,Dim,M,C>& f,
231 const NDIndex<Dim>& ngp, const int /*lgpoff*/[Dim],
232 const Vektor<PT,Dim>& /*dpos*/) {
234 // Try to find ngp in local fields and get iterator
235 fiter = getFieldIter(f,ngp);
236 // adjust position of Field iterator to lgp position
237 //fiter.moveBy(lgpoff);
238 // accumulate into particle attrib
239 ERRORMSG("IntTSC::gather: not implemented for Dim>3!!"<<endl);
240 return;
241 }
242
243};
244
245
246template <>
247class IntTSCImpl<1U> : public Interpolator {
248
249public:
250 // constructor/destructor
253
254 // gather/scatter functions
255
256 // scatter particle data into Field using particle position and mesh
257 template <class FT, class M, class C, class PT>
258 static
259 void scatter(const FT& pdata, Field<FT,1U,M,C>& f,
260 const Vektor<PT,1U>& ppos, const M& mesh) {
261 CenteringTag<C> ctag;
262 Vektor<PT,1U> gpos, dpos, delta;
263 NDIndex<1U> ngp;
265 // find nearest grid point for particle position, store in NDIndex obj
266 ngp = FindNGP(mesh, ppos, ctag);
267 // get position of ngp
268 FindPos(gpos, mesh, ngp, ctag);
269 // get mesh spacings
270 FindDelta(delta, mesh, ngp, ctag);
271 // Try to find ngp in local fields and get iterator
272 fiter = getFieldIter(f,ngp);
273 // get distance from ppos to gpos
274 dpos = ppos - gpos;
275 // normalize dpos by mesh spacing
276 dpos /= delta;
277 // accumulate into local elements
278 auto W = [dpos](int p, unsigned i) {
279 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
280 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
281 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
282
283 for (int p0 = -1; p0 <= 1; ++p0) {
284 fiter.offset(p0) += W(p0,0) * pdata;
285 }
286 return;
287 }
288
289 // scatter particle data into Field using particle position and mesh
290 // and cache mesh information for reuse
291 template <class FT, class M, class C, class PT>
292 static
293 void scatter(const FT& pdata, Field<FT,1U,M,C>& f,
294 const Vektor<PT,1U>& ppos, const M& mesh,
295 NDIndex<1U>& ngp, int /*lgpoff*/ [1U], Vektor<PT,1U>& dpos) {
296 CenteringTag<C> ctag;
297 Vektor<PT,1U> gpos, delta;
299 // find nearest grid point for particle position, store in NDIndex obj
300 ngp = FindNGP(mesh, ppos, ctag);
301 // get position of ngp
302 FindPos(gpos, mesh, ngp, ctag);
303 // get mesh spacings
304 FindDelta(delta, mesh, ngp, ctag);
305 // Try to find ngp in local fields and get iterator
306 fiter = getFieldIter(f,ngp);
307 // get distance from ppos to gpos
308 dpos = ppos - gpos;
309 // normalize dpos by mesh spacing
310 dpos /= delta;
311 // accumulate into local elements
312 auto W = [dpos](int p, unsigned i) {
313 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
314 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
315 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
316
317 for (int p0 = -1; p0 <= 1; ++p0) {
318 fiter.offset(p0) += W(p0,0) * pdata;
319 }
320 return;
321 }
322
323 // scatter particle data into Field using cached mesh information
324 template <class FT, class M, class C, class PT>
325 static
326 void scatter(const FT& pdata, Field<FT,1U,M,C>& f,
327 const NDIndex<1U>& ngp, const int /*lgpoff*/ [1U],
328 const Vektor<PT,1U>& dpos) {
330 // Try to find ngp in local fields and get iterator
331 fiter = getFieldIter(f,ngp);
332 // adjust position of Field iterator to lgp position
333 //fiter.moveBy(lgpoff);
334 // accumulate into local elements
335 auto W = [dpos](int p, unsigned i) {
336 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
337 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
338 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
339
340 for (int p0 = -1; p0 <= 1; ++p0) {
341 fiter.offset(p0) += W(p0,0) * pdata;
342 }
343
344 return;
345 }
346
347 // gather particle data from Field using particle position and mesh
348 template <class FT, class M, class C, class PT>
349 static
350 void gather(FT& pdata, const Field<FT,1U,M,C>& f,
351 const Vektor<PT,1U>& ppos, const M& mesh) {
352 CenteringTag<C> ctag;
353 Vektor<PT,1U> gpos, dpos, delta;
354 NDIndex<1U> ngp;
356 // find nearest grid point for particle position, store in NDIndex obj
357 ngp = FindNGP(mesh, ppos, ctag);
358 // get position of ngp
359 FindPos(gpos, mesh, ngp, ctag);
360 // get mesh spacings
361 FindDelta(delta, mesh, ngp, ctag);
362 // Try to find ngp in local fields and get iterator
363 fiter = getFieldIter(f,ngp);
364 // get distance from ppos to gpos
365 dpos = ppos - gpos;
366 // normalize dpos by mesh spacing
367 dpos /= delta;
368 // accumulate into particle attrib
369 auto W = [dpos](int p, unsigned i) {
370 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
371 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
372 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
373
374 pdata = 0;
375 for (int p0 = -1; p0 <= 1; ++p0) {
376 pdata += W(p0,0) * fiter.offset(p0);
377 }
378 return;
379 }
380
381 // gather particle data from Field using particle position and mesh
382 // and cache mesh information for reuse
383 template <class FT, class M, class C, class PT>
384 static
385 void gather(FT& pdata, const Field<FT,1U,M,C>& f,
386 const Vektor<PT,1U>& ppos, const M& mesh,
387 NDIndex<1U>& ngp, int /*lgpoff*/ [1U], Vektor<PT,1U>& dpos) {
388 CenteringTag<C> ctag;
389 Vektor<PT,1U> gpos, delta;
391 // find nearest grid point for particle position, store in NDIndex obj
392 ngp = FindNGP(mesh, ppos, ctag);
393 // get position of ngp
394 FindPos(gpos, mesh, ngp, ctag);
395 // get mesh spacings
396 FindDelta(delta, mesh, ngp, ctag);
397 // Try to find ngp in local fields and get iterator
398 fiter = getFieldIter(f,ngp);
399 // get distance from ppos to gpos
400 dpos = ppos - gpos;
401 // normalize dpos by mesh spacing
402 dpos /= delta;
403 // accumulate into particle attrib
404 auto W = [dpos](int p, unsigned i) {
405 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
406 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
407 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
408
409 pdata = 0;
410 for (int p0 = -1; p0 <= 1; ++p0) {
411 pdata += W(p0,0) * fiter.offset(p0);
412 }
413
414 return;
415 }
416
417 // gather particle data from Field using cached mesh information
418 template <class FT, class M, class C, class PT>
419 static
420 void gather(FT& pdata, const Field<FT,1U,M,C>& f,
421 const NDIndex<1U>& ngp, const int /*lgpoff*/[1U],
422 const Vektor<PT,1U>& dpos) {
424 // Try to find ngp in local fields and get iterator
425 fiter = getFieldIter(f,ngp);
426 // accumulate into particle attrib
427 auto W = [dpos](int p, unsigned i) {
428 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
429 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
430 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
431
432 pdata = 0;
433 for (int p0 = -1; p0 <= 1; ++p0) {
434 pdata += W(p0,0) * fiter.offset(p0);
435 }
436
437 return;
438 }
439
440};
441
442
443template <>
444class IntTSCImpl<2U> : public Interpolator {
445
446public:
447 // constructor/destructor
450
451 // gather/scatter functions
452
453 // scatter particle data into Field using particle position and mesh
454 template <class FT, class M, class C, class PT>
455 static
456 void scatter(const FT& pdata, Field<FT,2U,M,C>& f,
457 const Vektor<PT,2U>& ppos, const M& mesh) {
458 CenteringTag<C> ctag;
459 Vektor<PT,2U> gpos, dpos, delta;
460 NDIndex<2U> ngp;
462 // find nearest grid point for particle position, store in NDIndex obj
463 ngp = FindNGP(mesh, ppos, ctag);
464 // get position of ngp
465 FindPos(gpos, mesh, ngp, ctag);
466 // get mesh spacings
467 FindDelta(delta, mesh, ngp, ctag);
468 // Try to find ngp in local fields and get iterator
469 fiter = getFieldIter(f,ngp);
470 // get distance from ppos to gpos
471 dpos = ppos - gpos;
472 // normalize dpos by mesh spacing
473 dpos /= delta;
474 // accumulate into local elements
475 auto W = [dpos](int p, unsigned i) {
476 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
477 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
478 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
479
480 for (int p0 = -1; p0 <= 1; ++p0) {
481 for (int p1 = -1; p1 <= 1; ++p1) {
482 fiter.offset(p0,p1) += W(p0,0) * W(p1,1) * pdata;
483 }
484 }
485 return;
486 }
487
488 // scatter particle data into Field using particle position and mesh
489 // and cache mesh information for reuse
490 template <class FT, class M, class C, class PT>
491 static
492 void scatter(const FT& pdata, Field<FT,2U,M,C>& f,
493 const Vektor<PT,2U>& ppos, const M& mesh,
494 NDIndex<2U>& ngp, int /*lgpoff*/[2U], Vektor<PT,2U>& dpos) {
495 CenteringTag<C> ctag;
496 Vektor<PT,2U> gpos, delta;
498 // find nearest grid point for particle position, store in NDIndex obj
499 ngp = FindNGP(mesh, ppos, ctag);
500 // get position of ngp
501 FindPos(gpos, mesh, ngp, ctag);
502 // get mesh spacings
503 FindDelta(delta, mesh, ngp, ctag);
504 // Try to find ngp in local fields and get iterator
505 fiter = getFieldIter(f,ngp);
506 // get distance from ppos to gpos
507 dpos = ppos - gpos;
508 // normalize dpos by mesh spacing
509 dpos /= delta;
510 // accumulate into local elements
511 auto W = [dpos](int p, unsigned i) {
512 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
513 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
514 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
515
516 for (int p0 = -1; p0 <= 1; ++p0) {
517 for (int p1 = -1; p1 <= 1; ++p1) {
518 fiter.offset(p0,p1) += W(p0,0) * W(p1,1) * pdata;
519 }
520 }
521
522 return;
523 }
524
525 // scatter particle data into Field using cached mesh information
526 template <class FT, class M, class C, class PT>
527 static
528 void scatter(const FT& pdata, Field<FT,2U,M,C>& f,
529 const NDIndex<2U>& ngp, const int /*lpgoff*/[2U],
530 const Vektor<PT,2U>& dpos) {
532 // Try to find ngp in local fields and get iterator
533 fiter = getFieldIter(f,ngp);
534 // adjust position of Field iterator to lgp position
535 // fiter.moveBy(lgpoff);
536 // accumulate into local elements
537 auto W = [dpos](int p, unsigned i) {
538 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
539 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
540 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
541
542 for (int p0 = -1; p0 <= 1; ++p0) {
543 for (int p1 = -1; p1 <= 1; ++p1) {
544 fiter.offset(p0,p1) += W(p0,0) * W(p1,1) * pdata;
545 }
546 }
547
548 return;
549 }
550
551 // gather particle data from Field using particle position and mesh
552 template <class FT, class M, class C, class PT>
553 static
554 void gather(FT& pdata, const Field<FT,2U,M,C>& f,
555 const Vektor<PT,2U>& ppos, const M& mesh) {
556 CenteringTag<C> ctag;
557 Vektor<PT,2U> gpos, dpos, delta;
558 NDIndex<2U> ngp;
560 // find nearest grid point for particle position, store in NDIndex obj
561 ngp = FindNGP(mesh, ppos, ctag);
562 // get position of ngp
563 FindPos(gpos, mesh, ngp, ctag);
564 // get mesh spacings
565 FindDelta(delta, mesh, ngp, ctag);
566 // Try to find ngp in local fields and get iterator
567 fiter = getFieldIter(f,ngp);
568 // get distance from ppos to gpos
569 dpos = ppos - gpos;
570 // normalize dpos by mesh spacing
571 dpos /= delta;
572 // accumulate into particle attrib
573 pdata = 0;
574 auto W = [dpos](int p, unsigned i) {
575 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
576 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
577 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
578
579 for (int p0 = -1; p0 <= 1; ++p0) {
580 for (int p1 = -1; p1 <= 1; ++p1) {
581 pdata += W(p0,0) * W(p1,1) * fiter.offset(p0,p1);
582 }
583 }
584 return;
585 }
586
587 // gather particle data from Field using particle position and mesh
588 // and cache mesh information for reuse
589 template <class FT, class M, class C, class PT>
590 static
591 void gather(FT& pdata, const Field<FT,2U,M,C>& f,
592 const Vektor<PT,2U>& ppos, const M& mesh,
593 NDIndex<2U>& ngp, int /*lgpoff*/[2U], Vektor<PT,2U>& dpos) {
594 CenteringTag<C> ctag;
595 Vektor<PT,2U> gpos, delta;
597 // find nearest grid point for particle position, store in NDIndex obj
598 ngp = FindNGP(mesh, ppos, ctag);
599 // get position of ngp
600 FindPos(gpos, mesh, ngp, ctag);
601 // get mesh spacings
602 FindDelta(delta, mesh, ngp, ctag);
603 // Try to find ngp in local fields and get iterator
604 fiter = getFieldIter(f,ngp);
605 // get distance from ppos to gpos
606 dpos = ppos - gpos;
607 // normalize dpos by mesh spacing
608 dpos /= delta;
609 // accumulate into particle attrib
610 pdata = 0;
611 auto W = [dpos](int p, unsigned i) {
612 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
613 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
614 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
615
616 for (int p0 = -1; p0 <= 1; ++p0) {
617 for (int p1 = -1; p1 <= 1; ++p1) {
618 pdata += W(p0,0) * W(p1,1) * fiter.offset(p0,p1);
619 }
620 }
621 return;
622 }
623
624 // gather particle data from Field using cached mesh information
625 template <class FT, class M, class C, class PT>
626 static
627 void gather(FT& pdata, const Field<FT,2U,M,C>& f,
628 const NDIndex<2U>& ngp, const int /*lgpoff*/[2U],
629 const Vektor<PT,2U>& dpos) {
631 // Try to find ngp in local fields and get iterator
632 fiter = getFieldIter(f,ngp);
633 // accumulate into particle attrib
634 pdata = 0;
635 auto W = [dpos](int p, unsigned i) {
636 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
637 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
638 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
639
640 for (int p0 = -1; p0 <= 1; ++p0) {
641 for (int p1 = -1; p1 <= 1; ++p1) {
642 pdata += W(p0,0) * W(p1,1) * fiter.offset(p0,p1);
643 }
644 }
645 return;
646 }
647
648};
649
650
651template <>
652class IntTSCImpl<3U> : public Interpolator {
653
654public:
655 // constructor/destructor
658
659 // gather/scatter functions
660
661 // scatter particle data into Field using particle position and mesh
662 template <class FT, class M, class C, class PT>
663 static
664 void scatter(const FT& pdata, Field<FT,3U,M,C>& f,
665 const Vektor<PT,3U>& ppos, const M& mesh) {
666 CenteringTag<C> ctag;
667 Vektor<PT,3U> gpos, dpos, delta;
668 NDIndex<3U> ngp;
670 //int lgpoff[3U];
671 //unsigned int d;
672 // find nearest grid point for particle position, store in NDIndex obj
673 ngp = FindNGP(mesh, ppos, ctag);
674 // get position of ngp
675 FindPos(gpos, mesh, ngp, ctag);
676 // get mesh spacings
677 FindDelta(delta, mesh, ngp, ctag);
678 // Try to find ngp in local fields and get iterator
679 fiter = getFieldIter(f,ngp);
680 // get distance from ppos to gpos
681 dpos = ppos - gpos;
682 // normalize dpos by mesh spacing
683 dpos /= delta;
684 // accumulate into local elements
685 auto W = [dpos](int p, unsigned i) {
686 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
687 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
688 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
689
690 for (int p0 = -1; p0 <= 1; ++p0) {
691 for (int p1 = -1; p1 <= 1; ++p1) {
692 for (int p2 = -1; p2 <= 1; ++p2) {
693 fiter.offset(p0,p1,p2) += W(p0,0) * W(p1,1) * W(p2,2) * pdata;
694 }
695 }
696 }
697 return;
698 }
699
700 // scatter particle data into Field using particle position and mesh
701 // and cache mesh information for reuse
702 template <class FT, class M, class C, class PT>
703 static
704 void scatter(const FT& pdata, Field<FT,3U,M,C>& f,
705 const Vektor<PT,3U>& ppos, const M& mesh,
706 NDIndex<3U>& ngp, int /*lgpoff*/[3U], Vektor<PT,3U>& dpos) {
707 CenteringTag<C> ctag;
708 Vektor<PT,3U> gpos, delta;
710 // find nearest grid point for particle position, store in NDIndex obj
711 ngp = FindNGP(mesh, ppos, ctag);
712 // get position of ngp
713 FindPos(gpos, mesh, ngp, ctag);
714 // get mesh spacings
715 FindDelta(delta, mesh, ngp, ctag);
716 // Try to find ngp in local fields and get iterator
717 fiter = getFieldIter(f,ngp);
718 // get distance from ppos to gpos
719 dpos = ppos - gpos;
720 // normalize dpos by mesh spacing
721 dpos /= delta;
722 // accumulate into local elements
723 auto W = [dpos](int p, unsigned i) {
724 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
725 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
726 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
727
728 for (int p0 = -1; p0 <= 1; ++p0) {
729 for (int p1 = -1; p1 <= 1; ++p1) {
730 for (int p2 = -1; p2 <= 1; ++p2) {
731 fiter.offset(p0,p1,p2) += W(p0,0) * W(p1,1) * W(p2,2) * pdata;
732 }
733 }
734 }
735 return;
736 }
737
738 // scatter particle data into Field using cached mesh information
739 template <class FT, class M, class C, class PT>
740 static
741 void scatter(const FT& pdata, Field<FT,3U,M,C>& f,
742 const NDIndex<3U>& ngp, const int /*lgpoff*/[3U],
743 const Vektor<PT,3U>& dpos) {
745 // Try to find ngp in local fields and get iterator
746 fiter = getFieldIter(f,ngp);
747
748 auto W = [dpos](int p, unsigned i) {
749 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
750 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
751 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
752
753 for (int p0 = -1; p0 <= 1; ++p0) {
754 for (int p1 = -1; p1 <= 1; ++p1) {
755 for (int p2 = -1; p2 <= 1; ++p2) {
756 fiter.offset(p0,p1,p2) += W(p0,0) * W(p1,1) * W(p2,2) * pdata;
757 }
758 }
759 }
760 return;
761 }
762
763 // gather particle data from Field using particle position and mesh
764 template <class FT, class M, class C, class PT>
765 static
766 void gather(FT& pdata, const Field<FT,3U,M,C>& f,
767 const Vektor<PT,3U>& ppos, const M& mesh) {
768 CenteringTag<C> ctag;
769 Vektor<PT,3U> gpos, dpos, delta;
770 NDIndex<3U> ngp;
772 // find nearest grid point for particle position, store in NDIndex obj
773 ngp = FindNGP(mesh, ppos, ctag);
774 // get position of ngp
775 FindPos(gpos, mesh, ngp, ctag);
776 // get mesh spacings
777 FindDelta(delta, mesh, ngp, ctag);
778 // Try to find ngp in local fields and get iterator
779 fiter = getFieldIter(f,ngp);
780 // get distance from ppos to gpos
781 dpos = ppos - gpos;
782 // normalize dpos by mesh spacing
783 dpos /= delta;
784 // accumulate into particle attrib
785 pdata = 0;
786 auto W = [dpos](int p, unsigned i) {
787 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
788 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
789 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
790
791 for (int p0 = -1; p0 <= 1; ++p0) {
792 for (int p1 = -1; p1 <= 1; ++p1) {
793 for (int p2 = -1; p2 <= 1; ++p2) {
794 pdata += W(p0,0) * W(p1,1) * W(p2,2) * fiter.offset(p0,p1,p2);
795 }
796 }
797 }
798 return;
799 }
800
801 // gather particle data from Field using particle position and mesh
802 // and cache mesh information for reuse
803 template <class FT, class M, class C, class PT>
804 static
805 void gather(FT& pdata, const Field<FT,3U,M,C>& f,
806 const Vektor<PT,3U>& ppos, const M& mesh,
807 NDIndex<3U>& ngp, int /*lgpoff*/[3U], Vektor<PT,3U>& dpos) {
808 CenteringTag<C> ctag;
809 Vektor<PT,3U> gpos, delta;
811 // find nearest grid point for particle position, store in NDIndex obj
812 ngp = FindNGP(mesh, ppos, ctag);
813 // get position of ngp
814 FindPos(gpos, mesh, ngp, ctag);
815 // get mesh spacings
816 FindDelta(delta, mesh, ngp, ctag);
817 // Try to find ngp in local fields and get iterator
818 fiter = getFieldIter(f,ngp);
819 // get distance from ppos to gpos
820 dpos = ppos - gpos;
821 // normalize dpos by mesh spacing
822 dpos /= delta;
823 // accumulate into particle attrib
824 pdata = 0;
825 auto W = [dpos](int p, unsigned i) {
826 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
827 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
828 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
829
830 for (int p0 = -1; p0 <= 1; ++p0) {
831 for (int p1 = -1; p1 <= 1; ++p1) {
832 for (int p2 = -1; p2 <= 1; ++p2) {
833 pdata += W(p0,0) * W(p1,1) * W(p2,2) * fiter.offset(p0,p1,p2);
834 }
835 }
836 }
837 return;
838 }
839
840 // gather particle data from Field using cached mesh information
841 template <class FT, class M, class C, class PT>
842 static
843 void gather(FT& pdata, const Field<FT,3U,M,C>& f,
844 const NDIndex<3U>& ngp, const int /*lgpoff*/[3U],
845 const Vektor<PT,3U>& dpos) {
847 // Try to find ngp in local fields and get iterator
848 fiter = getFieldIter(f,ngp);
849 // adjust position of Field iterator to lgp position
850 //fiter.moveBy(lgpoff);
851 // accumulate into particle attrib
852 pdata = 0;
853 auto W = [dpos](int p, unsigned i) {
854 if (p==-1) return .125 * (1 - 4 * dpos(i) + 4 * dpos(i) * dpos(i));
855 else if (p==0) return .25 * (3 - 4 * dpos(i) * dpos(i));
856 else if (p==+1) return .125 * (1 + 4 * dpos(i) + 4 * dpos(i) * dpos(i)); };
857
858 for (int p0 = -1; p0 <= 1; ++p0) {
859 for (int p1 = -1; p1 <= 1; ++p1) {
860 for (int p2 = -1; p2 <= 1; ++p2) {
861 pdata += W(p0,0) * W(p1,1) * W(p2,2) * fiter.offset(p0,p1,p2);
862 }
863 }
864 }
865 return;
866 }
867
868};
869
870
871// IntTSC class -- what the user sees
872class IntTSC {
873
874public:
875 // constructor/destructor
878
879 // gather/scatter functions
880
881 // scatter particle data into Field using particle position and mesh
882 template <class FT, unsigned Dim, class M, class C, class PT>
883 static
884 void scatter(const FT& pdata, Field<FT,Dim,M,C>& f,
885 const Vektor<PT,Dim>& ppos, const M& mesh) {
886 IntTSCImpl<Dim>::scatter(pdata,f,ppos,mesh);
887 }
888
889 // scatter particle data into Field using particle position and mesh
890 // and cache mesh information for reuse
891 template <class FT, unsigned Dim, class M, class C, class PT>
892 static
893 void scatter(const FT& pdata, Field<FT,Dim,M,C>& f,
894 const Vektor<PT,Dim>& ppos, const M& mesh,
895 CacheDataTSC<PT,Dim>& cache) {
896 IntTSCImpl<Dim>::scatter(pdata,f,ppos,mesh,cache.Index_m,
897 cache.Offset_m,cache.Delta_m);
898 }
899
900 // scatter particle data into Field using cached mesh information
901 template <class FT, unsigned Dim, class M, class C, class PT>
902 static
903 void scatter(const FT& pdata, Field<FT,Dim,M,C>& f,
904 const CacheDataTSC<PT,Dim>& cache) {
905 IntTSCImpl<Dim>::scatter(pdata,f,cache.Index_m,
906 cache.Offset_m,cache.Delta_m);
907 }
908
909 // gather particle data from Field using particle position and mesh
910 template <class FT, unsigned Dim, class M, class C, class PT>
911 static
912 void gather(FT& pdata, const Field<FT,Dim,M,C>& f,
913 const Vektor<PT,Dim>& ppos, const M& mesh) {
914 IntTSCImpl<Dim>::gather(pdata,f,ppos,mesh);
915 }
916
917 // gather particle data from Field using particle position and mesh
918 // and cache mesh information for reuse
919 template <class FT, unsigned Dim, class M, class C, class PT>
920 static
921 void gather(FT& pdata, const Field<FT,Dim,M,C>& f,
922 const Vektor<PT,Dim>& ppos, const M& mesh,
923 CacheDataTSC<PT,Dim>& cache) {
924 IntTSCImpl<Dim>::gather(pdata,f,ppos,mesh,cache.Index_m,
925 cache.Offset_m,cache.Delta_m);
926 }
927
928 // gather particle data from Field using cached mesh information
929 template <class FT, unsigned Dim, class M, class C, class PT>
930 static
931 void gather(FT& pdata, const Field<FT,Dim,M,C>& f,
932 const CacheDataTSC<PT,Dim>& cache) {
933 IntTSCImpl<Dim>::gather(pdata,f,cache.Index_m,
934 cache.Offset_m,cache.Delta_m);
935 }
936
937};
938
939#endif // INT_TSC_H
940
941/***************************************************************************
942 * $RCSfile: IntTSC.h,v $ $Author: adelmann $
943 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:28 $
944 * IPPL_VERSION_ID: $Id: IntTSC.h,v 1.1.1.1 2003/01/23 07:40:28 adelmann Exp $
945 ***************************************************************************/
const unsigned Dim
void FindDelta(Vektor< PT, Dim > &delta, const M &mesh, const NDIndex< Dim > &gp, CenteringTag< Cell >)
Definition: Interpolator.h:95
NDIndex< Dim > FindNGP(const M &mesh, const Vektor< PT, Dim > &ppos, CenteringTag< Cell >)
Definition: Interpolator.h:37
void FindPos(Vektor< PT, Dim > &pos, const M &mesh, const NDIndex< Dim > &indices, CenteringTag< Cell >)
Definition: Interpolator.h:62
Inform & endl(Inform &inf)
Definition: Inform.cpp:42
#define ERRORMSG(msg)
Definition: IpplInfo.h:350
Definition: Vektor.h:32
Definition: Field.h:33
T & offset(int i) const
NDIndex< Dim > Index_m
Definition: Interpolator.h:157
Vektor< T, Dim > Delta_m
Definition: Interpolator.h:159
int Offset_m[Dim]
Definition: Interpolator.h:158
static CompressedBrickIterator< T, Dim > getFieldIter(const BareField< T, Dim > &f, const NDIndex< Dim > &pt)
Definition: Interpolator.h:183
CacheDataTSC< T, Dim > Cache_t
Definition: IntTSC.h:30
static void gather(FT &, const Field< FT, Dim, M, C > &f, const Vektor< PT, Dim > &ppos, const M &mesh)
Definition: IntTSC.h:148
static void scatter(const FT &, Field< FT, Dim, M, C > &f, const Vektor< PT, Dim > &ppos, const M &mesh, NDIndex< Dim > &ngp, int[Dim], Vektor< PT, Dim > &dpos)
Definition: IntTSC.h:92
static void scatter(const FT &, Field< FT, Dim, M, C > &f, const NDIndex< Dim > &ngp, const int[Dim], const Vektor< PT, Dim > &)
Definition: IntTSC.h:132
~IntTSCImpl()
Definition: IntTSC.h:42
IntTSCImpl()
Definition: IntTSC.h:41
static void gather(FT &, const Field< FT, Dim, M, C > &f, const Vektor< PT, Dim > &ppos, const M &mesh, NDIndex< Dim > &ngp, int[Dim], Vektor< PT, Dim > &dpos)
Definition: IntTSC.h:190
static void scatter(const FT &, Field< FT, Dim, M, C > &f, const Vektor< PT, Dim > &ppos, const M &mesh)
Definition: IntTSC.h:49
static void gather(FT &, const Field< FT, Dim, M, C > &f, const NDIndex< Dim > &ngp, const int[Dim], const Vektor< PT, Dim > &)
Definition: IntTSC.h:230
static void gather(FT &pdata, const Field< FT, 1U, M, C > &f, const Vektor< PT, 1U > &ppos, const M &mesh, NDIndex< 1U > &ngp, int[1U], Vektor< PT, 1U > &dpos)
Definition: IntTSC.h:385
static void scatter(const FT &pdata, Field< FT, 1U, M, C > &f, const Vektor< PT, 1U > &ppos, const M &mesh, NDIndex< 1U > &ngp, int[1U], Vektor< PT, 1U > &dpos)
Definition: IntTSC.h:293
static void scatter(const FT &pdata, Field< FT, 1U, M, C > &f, const NDIndex< 1U > &ngp, const int[1U], const Vektor< PT, 1U > &dpos)
Definition: IntTSC.h:326
static void scatter(const FT &pdata, Field< FT, 1U, M, C > &f, const Vektor< PT, 1U > &ppos, const M &mesh)
Definition: IntTSC.h:259
static void gather(FT &pdata, const Field< FT, 1U, M, C > &f, const NDIndex< 1U > &ngp, const int[1U], const Vektor< PT, 1U > &dpos)
Definition: IntTSC.h:420
static void gather(FT &pdata, const Field< FT, 1U, M, C > &f, const Vektor< PT, 1U > &ppos, const M &mesh)
Definition: IntTSC.h:350
static void scatter(const FT &pdata, Field< FT, 2U, M, C > &f, const Vektor< PT, 2U > &ppos, const M &mesh, NDIndex< 2U > &ngp, int[2U], Vektor< PT, 2U > &dpos)
Definition: IntTSC.h:492
static void scatter(const FT &pdata, Field< FT, 2U, M, C > &f, const Vektor< PT, 2U > &ppos, const M &mesh)
Definition: IntTSC.h:456
static void gather(FT &pdata, const Field< FT, 2U, M, C > &f, const Vektor< PT, 2U > &ppos, const M &mesh, NDIndex< 2U > &ngp, int[2U], Vektor< PT, 2U > &dpos)
Definition: IntTSC.h:591
static void scatter(const FT &pdata, Field< FT, 2U, M, C > &f, const NDIndex< 2U > &ngp, const int[2U], const Vektor< PT, 2U > &dpos)
Definition: IntTSC.h:528
static void gather(FT &pdata, const Field< FT, 2U, M, C > &f, const Vektor< PT, 2U > &ppos, const M &mesh)
Definition: IntTSC.h:554
static void gather(FT &pdata, const Field< FT, 2U, M, C > &f, const NDIndex< 2U > &ngp, const int[2U], const Vektor< PT, 2U > &dpos)
Definition: IntTSC.h:627
static void scatter(const FT &pdata, Field< FT, 3U, M, C > &f, const Vektor< PT, 3U > &ppos, const M &mesh, NDIndex< 3U > &ngp, int[3U], Vektor< PT, 3U > &dpos)
Definition: IntTSC.h:704
static void scatter(const FT &pdata, Field< FT, 3U, M, C > &f, const NDIndex< 3U > &ngp, const int[3U], const Vektor< PT, 3U > &dpos)
Definition: IntTSC.h:741
static void gather(FT &pdata, const Field< FT, 3U, M, C > &f, const Vektor< PT, 3U > &ppos, const M &mesh)
Definition: IntTSC.h:766
static void gather(FT &pdata, const Field< FT, 3U, M, C > &f, const Vektor< PT, 3U > &ppos, const M &mesh, NDIndex< 3U > &ngp, int[3U], Vektor< PT, 3U > &dpos)
Definition: IntTSC.h:805
static void scatter(const FT &pdata, Field< FT, 3U, M, C > &f, const Vektor< PT, 3U > &ppos, const M &mesh)
Definition: IntTSC.h:664
static void gather(FT &pdata, const Field< FT, 3U, M, C > &f, const NDIndex< 3U > &ngp, const int[3U], const Vektor< PT, 3U > &dpos)
Definition: IntTSC.h:843
Definition: IntTSC.h:872
static void gather(FT &pdata, const Field< FT, Dim, M, C > &f, const CacheDataTSC< PT, Dim > &cache)
Definition: IntTSC.h:931
~IntTSC()
Definition: IntTSC.h:877
static void gather(FT &pdata, const Field< FT, Dim, M, C > &f, const Vektor< PT, Dim > &ppos, const M &mesh, CacheDataTSC< PT, Dim > &cache)
Definition: IntTSC.h:921
static void gather(FT &pdata, const Field< FT, Dim, M, C > &f, const Vektor< PT, Dim > &ppos, const M &mesh)
Definition: IntTSC.h:912
IntTSC()
Definition: IntTSC.h:876
static void scatter(const FT &pdata, Field< FT, Dim, M, C > &f, const Vektor< PT, Dim > &ppos, const M &mesh, CacheDataTSC< PT, Dim > &cache)
Definition: IntTSC.h:893
static void scatter(const FT &pdata, Field< FT, Dim, M, C > &f, const Vektor< PT, Dim > &ppos, const M &mesh)
Definition: IntTSC.h:884
static void scatter(const FT &pdata, Field< FT, Dim, M, C > &f, const CacheDataTSC< PT, Dim > &cache)
Definition: IntTSC.h:903