OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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
20 #include "Particle/Interpolator.h"
21 #include "Field/Field.h"
22 
23 
24 // forward declaration
25 class IntTSC;
26 
27 // specialization of InterpolatorTraits
28 template <class T, unsigned Dim>
31 };
32 
33 
34 
35 // IntTSCImpl class definition
36 template <unsigned Dim>
37 class IntTSCImpl : public Interpolator {
38 
39 public:
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 
246 template <>
247 class IntTSCImpl<1U> : public Interpolator {
248 
249 public:
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 
443 template <>
444 class IntTSCImpl<2U> : public Interpolator {
445 
446 public:
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 
651 template <>
652 class IntTSCImpl<3U> : public Interpolator {
653 
654 public:
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
872 class IntTSC {
873 
874 public:
875  // constructor/destructor
876  IntTSC() {}
877  ~IntTSC() {}
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
NDIndex< Dim > FindNGP(const M &mesh, const Vektor< PT, Dim > &ppos, CenteringTag< Cell >)
Definition: Interpolator.h:37
void FindDelta(Vektor< PT, Dim > &delta, const M &mesh, const NDIndex< Dim > &gp, CenteringTag< Cell >)
Definition: Interpolator.h:95
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