OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
FFT.h
Go to the documentation of this file.
1 //
2 // IPPL FFT
3 //
4 // Copyright (c) 2008-2018
5 // Paul Scherrer Institut, Villigen PSI, Switzerland
6 // All rights reserved.
7 //
8 // OPAL is licensed under GNU GPL version 3.
9 //
10 
18 #ifndef IPPL_FFT_FFT_H
19 #define IPPL_FFT_FFT_H
20 
21 #include "FFT/FFTBase.h"
22 
23 // forward declarations
24 //template <unsigned Dim> class FieldLayout;
26 template <class T, unsigned Dim> class BareField;
27 template <class T, unsigned Dim> class LField;
28 
29 
30 
34 class CCTransform {};
38 class RCTransform {};
42 class SineTransform {};
43 
47 template <class Transform, size_t Dim, class T>
48 class FFT : public FFTBase<Dim,T> {};
49 
53 template <size_t Dim, class T>
54 class FFT<CCTransform,Dim,T> : public FFTBase<Dim,T> {
55 
56 public:
57 
59  typedef std::complex<T> Complex_t;
63 
69  FFT(const Domain_t& cdomain, const bool transformTheseDims[Dim],
70  const bool& compressTemps=false);
71 
78 FFT(const Domain_t& cdomain, const bool& compressTemps=false)
80 
81  // construct array of axis lengths
82  int lengths[Dim];
83  size_t d;
84  for (d=0; d<Dim; ++d)
85  lengths[d] = cdomain[d].length();
86 
87  // construct array of transform types for FFT Engine, compute normalization
88  int transformTypes[Dim];
89  T& normFact = this->getNormFact();
90  normFact = 1.0;
91  for (d=0; d<Dim; ++d) {
92  transformTypes[d] = FFTBase<Dim,T>::ccFFT; // all transforms are complex-to-complex
93  normFact /= lengths[d];
94  }
95 
96  // set up FFT Engine
97  this->getEngine().setup(Dim, transformTypes, lengths);
98  // set up the temporary fields
99  setup();
100  }
101 
102 
103  // Destructor
104  ~FFT(void);
105 
113  void transform(int direction, ComplexField_t& f, ComplexField_t& g,
114  const bool& constInput=false);
118  void transform(const char* directionName, ComplexField_t& f,
119  ComplexField_t& g, const bool& constInput=false);
120 
123  void transform(int direction, ComplexField_t& f);
124 
125  void transform(const char* directionName, ComplexField_t& f) {
126  // invoke in-place transform function using direction name string
127  int direction = this->getDirection(directionName);
128 
129  // Check domain of incoming Field
130  const Layout_t& in_layout = f.getLayout();
131  const Domain_t& in_dom = in_layout.getDomain();
132  PAssert_EQ(this->checkDomain(this->getDomain(),in_dom), true);
133 
134  // Common loop iterate and other vars:
135  size_t d;
136  int idim; // idim loops over the number of transform dims.
137  int begdim, enddim; // beginning and end of transform dim loop
138  size_t nTransformDims = this->numTransformDims();
139  // Field* for temp Field management:
140  ComplexField_t* temp = &f;
141  // Local work array passed to FFT:
142  Complex_t* localdata;
143 
144  // Loop over the dimensions be transformed:
145  begdim = (direction == +1) ? 0 : (nTransformDims-1);
146  enddim = (direction == +1) ? nTransformDims : -1;
147  for (idim = begdim; idim != enddim; idim += direction) {
148 
149  // Now do the serial transforms along this dimension:
150 
151  bool skipTranspose = false;
152  // if this is the first transform dimension, we might be able
153  // to skip the transpose into the first temporary Field
154  if (idim == begdim) {
155  // get domain for comparison
156  const Domain_t& first_dom = tempLayouts_m[idim]->getDomain();
157  // check that zeroth axis is the same and is serial
158  // and that there are no guard cells
159  skipTranspose = ( (in_dom[0].sameBase(first_dom[0])) &&
160  (in_dom[0].length() == first_dom[0].length()) &&
161  (in_layout.getDistribution(0) == SERIAL) &&
163  }
164 
165  // if this is the last transform dimension, we might be able
166  // to skip the last temporary and transpose right into f
167  if (idim == enddim-direction) {
168  // get domain for comparison
169  const Domain_t& last_dom = tempLayouts_m[idim]->getDomain();
170  // check that zeroth axis is the same and is serial
171  // and that there are no guard cells
172  skipTranspose = ( (in_dom[0].sameBase(last_dom[0])) &&
173  (in_dom[0].length() == last_dom[0].length()) &&
174  (in_layout.getDistribution(0) == SERIAL) &&
176  }
177 
178  if (!skipTranspose) {
179  // transpose and permute to Field with transform dim first
180  (*tempFields_m[idim])[tempLayouts_m[idim]->getDomain()] =
181  (*temp)[temp->getLayout().getDomain()];
182 
183  // Compress out previous iterate's storage:
184  if (this->compressTemps() && temp != &f) *temp = 0;
185  temp = tempFields_m[idim]; // Field* management aid
186  }
187  else if (idim == enddim-direction && temp != &f) {
188  // last transform and we can skip the last temporary field
189  // so do the transpose here using f instead
190 
191  // transpose and permute to Field with transform dim first
192  f[in_dom] = (*temp)[temp->getLayout().getDomain()];
193 
194  // Compress out previous iterate's storage:
195  if (this->compressTemps()) *temp = 0;
196  temp = &f; // Field* management aid
197  }
198 
199 
200 
201  // Loop over all the Vnodes, working on the LField in each.
202  typename ComplexField_t::const_iterator_if l_i, l_end = temp->end_if();
203  for (l_i = temp->begin_if(); l_i != l_end; ++l_i) {
204 
205  // Get the LField
206  ComplexLField_t* ldf = (*l_i).second.get();
207  // make sure we are uncompressed
208  ldf->Uncompress();
209  // get the raw data pointer
210  localdata = ldf->getP();
211 
212  // Do 1D complex-to-complex FFT's on all the strips in the LField:
213  int nstrips = 1, length = ldf->size(0);
214  for (d=1; d<Dim; ++d) nstrips *= ldf->size(d);
215  for (int istrip=0; istrip<nstrips; ++istrip) {
216  // Do the 1D FFT:
217  this->getEngine().callFFT(idim, direction, localdata);
218  // advance the data pointer
219  localdata += length;
220  } // loop over 1D strips
221  } // loop over all the LFields
222 
223 
224  } // loop over all transformed dimensions
225 
226  // skip final assignment and compress if we used f as final temporary
227  if (temp != &f) {
228 
229  // Now assign back into original Field, and compress last temp's storage:
230  f[in_dom] = (*temp)[temp->getLayout().getDomain()];
231  if (this->compressTemps()) *temp = 0;
232 
233  }
234 
235  // Normalize:
236  if (direction == +1)
237  f *= Complex_t(this->getNormFact(), 0.0);
238  return;
239  }
240 private:
241 
246  void setup(void);
247 
255 
260 
261 };
262 
263 
267 template <size_t Dim, class T>
268 inline void
270  const char* directionName,
273  const bool& constInput)
274 {
275  int dir = this->getDirection(directionName);
276  transform(dir, f, g, constInput);
277  return;
278 }
279 
280 
284 template <class T>
285 class FFT<CCTransform,1U,T> : public FFTBase<1U,T> {
286 
287 public:
288 
289  // typedefs
291  typedef std::complex<T> Complex_t;
295 
296  // Constructors:
297 
303  FFT(const Domain_t& cdomain, const bool transformTheseDims[1U],
304  const bool& compressTemps=false);
311  FFT(const Domain_t& cdomain, const bool& compressTemps=false);
312 
313  // Destructor
314  ~FFT(void);
315 
323  void transform(int direction, ComplexField_t& f, ComplexField_t& g,
324  const bool& constInput=false);
328  void transform(const char* directionName, ComplexField_t& f,
329  ComplexField_t& g, const bool& constInput=false);
330 
334  void transform(int direction, ComplexField_t& f);
335  void transform(const char* directionName, ComplexField_t& f);
336 
337 private:
338 
343  void setup(void);
344 
349 
354 
355 };
356 
357 
358 // inline function definitions
359 
363 template <class T>
364 inline void
366  const char* directionName,
369  const bool& constInput)
370 {
371  int dir = this->getDirection(directionName);
372  transform(dir, f, g, constInput);
373  return;
374 }
375 
379 template <class T>
380 inline void
382  const char* directionName,
384 {
385  int dir = this->getDirection(directionName);
386  transform(dir, f);
387  return;
388 }
389 
390 
394 template <size_t Dim, class T>
395 class FFT<RCTransform,Dim,T> : public FFTBase<Dim,T> {
396 
397 private:
398 
399 public:
400 
401  // typedefs
405  typedef std::complex<T> Complex_t;
409 
410  // Constructors:
411 
417  FFT(const Domain_t& rdomain, const Domain_t& cdomain,
418  const bool transformTheseDims[Dim], const bool& compressTemps=false);
419 
423  FFT(const Domain_t& rdomain, const Domain_t& cdomain,
424  const bool& compressTemps=false, int serialAxes = 1);
425 
426  // Destructor
427  ~FFT(void);
428 
436  void transform(int direction, RealField_t& f, ComplexField_t& g,
437  const bool& constInput=false);
438  void transform(const char* directionName, RealField_t& f,
439  ComplexField_t& g, const bool& constInput=false);
440 
447  void transform(int direction, ComplexField_t& f, RealField_t& g,
448  const bool& constInput=false);
449  void transform(const char* directionName, ComplexField_t& f,
450  RealField_t& g, const bool& constInput=false);
451 
456 private:
457 
462  void setup(void);
463 
470 
475 
480 
485 
491 
496 };
497 
498 // Inline function definitions
499 
503 template <size_t Dim, class T>
504 inline void
506  const char* directionName,
509  const bool& constInput)
510 {
511  int dir = this->getDirection(directionName);
512  transform(dir, f, g, constInput);
513  return;
514 }
515 
519 template <size_t Dim, class T>
520 inline void
522  const char* directionName,
525  const bool& constInput)
526 {
527  int dir = this->getDirection(directionName);
528  transform(dir, f, g, constInput);
529  return;
530 }
531 
532 
536 template <class T>
537 class FFT<RCTransform,1U,T> : public FFTBase<1U,T> {
538 
539 public:
540 
541  // typedefs
545  typedef std::complex<T> Complex_t;
549 
550  // Constructors:
551 
558  FFT(const Domain_t& rdomain, const Domain_t& cdomain,
559  const bool transformTheseDims[1U], const bool& compressTemps=false);
563  FFT(const Domain_t& rdomain, const Domain_t& cdomain,
564  const bool& compressTemps=false);
565 
569  ~FFT(void);
570 
579  void transform(int direction, RealField_t& f, ComplexField_t& g,
580  const bool& constInput=false);
581  void transform(const char* directionName, RealField_t& f,
582  ComplexField_t& g, const bool& constInput=false);
583 
588  void transform(int direction, ComplexField_t& f, RealField_t& g,
589  const bool& constInput=false);
590  void transform(const char* directionName, ComplexField_t& f,
591  RealField_t& g, const bool& constInput=false);
592 
593 private:
594 
599  void setup(void);
600 
605 
610 
615 
620  // const Domain_t& complexDomain_m;
622 };
623 
627 template <class T>
628 inline void
630  const char* directionName,
633  const bool& constInput)
634 {
635  int dir = this->getDirection(directionName);
636  transform(dir, f, g, constInput);
637  return;
638 }
639 
643 template <class T>
644 inline void
646  const char* directionName,
649  const bool& constInput)
650 {
651  int dir = this->getDirection(directionName);
652  transform(dir, f, g, constInput);
653  return;
654 }
655 
659 template <size_t Dim, class T>
660 class FFT<SineTransform,Dim,T> : public FFTBase<Dim,T> {
661 
662 public:
663 
664  // typedefs
668  typedef std::complex<T> Complex_t;
672 
680  FFT(const Domain_t& rdomain, const Domain_t& cdomain,
681  const bool transformTheseDims[Dim],
682  const bool sineTransformDims[Dim], const bool& compressTemps=false);
686  FFT(const Domain_t& rdomain, const Domain_t& cdomain,
687  const bool sineTransformDims[Dim], const bool& compressTemps=false);
695  FFT(const Domain_t& rdomain, const bool sineTransformDims[Dim],
696  const bool& compressTemps=false);
700  FFT(const Domain_t& rdomain, const bool& compressTemps=false);
701 
702  ~FFT(void);
703 
714  void transform(int direction, RealField_t& f, ComplexField_t& g,
715  const bool& constInput=false);
716  void transform(const char* directionName, RealField_t& f,
717  ComplexField_t& g, const bool& constInput=false);
718 
723  void transform(int direction, ComplexField_t& f, RealField_t& g,
724  const bool& constInput=false);
725  void transform(const char* directionName, ComplexField_t& f,
726  RealField_t& g, const bool& constInput=false);
727 
737  void transform(int direction, RealField_t& f, RealField_t& g,
738  const bool& constInput=false);
739  void transform(const char* directionName, RealField_t& f,
740  RealField_t& g, const bool& constInput=false);
741 
745  void transform(int direction, RealField_t& f);
746  void transform(const char* directionName, RealField_t& f);
747 
748 private:
749 
754  void setup(void);
755 
756 
757 
761  bool sineTransformDims_m[Dim];
762 
767 
776 
781 
786 
791 
796 };
797 
801 template <size_t Dim, class T>
802 inline void
804  const char* directionName,
807  const bool& constInput)
808 {
809  int dir = this->getDirection(directionName);
810  transform(dir, f, g, constInput);
811  return;
812 }
813 
817 template <size_t Dim, class T>
818 inline void
820  const char* directionName,
823  const bool& constInput)
824 {
825  int dir = this->getDirection(directionName);
826  transform(dir, f, g, constInput);
827  return;
828 }
829 
833 template <size_t Dim, class T>
834 inline void
836  const char* directionName,
839  const bool& constInput)
840 {
841  int dir = this->getDirection(directionName);
842  transform(dir, f, g, constInput);
843  return;
844 }
845 
849 template <size_t Dim, class T>
850 inline void
852  const char* directionName,
854 {
855  int dir = this->getDirection(directionName);
856  transform(dir, f);
857  return;
858 }
859 
860 
864 template <class T>
865 class FFT<SineTransform,1U,T> : public FFTBase<1U,T> {
866 
867 public:
868 
873 
881  FFT(const Domain_t& rdomain, const bool sineTransformDims[1U],
882  const bool& compressTemps=false);
886  FFT(const Domain_t& rdomain, const bool& compressTemps=false);
887 
888 
889  ~FFT(void);
890 
899  void transform(int direction, RealField_t& f, RealField_t& g,
900  const bool& constInput=false);
901  void transform(const char* directionName, RealField_t& f,
902  RealField_t& g, const bool& constInput=false);
903 
907  void transform(int direction, RealField_t& f);
908  void transform(const char* directionName, RealField_t& f);
909 
910 private:
911 
916  void setup(void);
917 
922 
927 
928 };
929 
933 template <class T>
934 inline void
936  const char* directionName,
939  const bool& constInput)
940 {
941  int dir = this->getDirection(directionName);
942  transform(dir, f, g, constInput);
943  return;
944 }
945 
949 template <class T>
950 inline void
952  const char* directionName,
954 {
955  int dir = this->getDirection(directionName);
956  transform(dir, f);
957  return;
958 }
959 #include "FFT/FFT.hpp"
960 #endif // IPPL_FFT_FFT_H
const unsigned Dim
@ SERIAL
Definition: FieldLayout.h:55
#define PAssert_EQ(a, b)
Definition: PAssert.h:104
const GuardCellSizes< Dim > & getGC() const
Definition: BareField.h:146
iterator_if begin_if()
Definition: BareField.h:100
ac_id_larray::const_iterator const_iterator_if
Definition: BareField.h:93
iterator_if end_if()
Definition: BareField.h:101
Layout_t & getLayout() const
Definition: BareField.h:131
Definition: LField.h:58
int size(unsigned d) const
Definition: LField.h:97
T * getP()
Definition: LField.h:100
void Uncompress(bool fill_domain=true)
Definition: LField.h:172
Definition: FFT.h:48
void transform(int direction, ComplexField_t &f, ComplexField_t &g, const bool &constInput=false)
BareField< Complex_t, Dim > ComplexField_t
Definition: FFT.h:60
LField< Complex_t, Dim > ComplexLField_t
Definition: FFT.h:61
FFTBase< Dim, T >::Domain_t Domain_t
Definition: FFT.h:62
FieldLayout< Dim > Layout_t
Definition: FFT.h:58
void transform(const char *directionName, ComplexField_t &f)
Definition: FFT.h:125
FFT(const Domain_t &cdomain, const bool &compressTemps=false)
Definition: FFT.h:78
std::complex< T > Complex_t
Definition: FFT.h:59
void transform(int direction, ComplexField_t &f)
FFT(const Domain_t &cdomain, const bool transformTheseDims[Dim], const bool &compressTemps=false)
Layout_t ** tempLayouts_m
Definition: FFT.h:254
void transform(const char *directionName, ComplexField_t &f, ComplexField_t &g, const bool &constInput=false)
ComplexField_t ** tempFields_m
Definition: FFT.h:259
FFTBase< 1U, T >::Domain_t Domain_t
Definition: FFT.h:294
void transform(const char *directionName, ComplexField_t &f, ComplexField_t &g, const bool &constInput=false)
void transform(const char *directionName, ComplexField_t &f)
Layout_t * tempLayouts_m
Definition: FFT.h:348
std::complex< T > Complex_t
Definition: FFT.h:291
FFT(const Domain_t &cdomain, const bool transformTheseDims[1U], const bool &compressTemps=false)
void transform(int direction, ComplexField_t &f, ComplexField_t &g, const bool &constInput=false)
LField< Complex_t, 1U > ComplexLField_t
Definition: FFT.h:293
FFT(const Domain_t &cdomain, const bool &compressTemps=false)
void transform(int direction, ComplexField_t &f)
FieldLayout< 1U > Layout_t
Definition: FFT.h:290
BareField< Complex_t, 1U > ComplexField_t
Definition: FFT.h:292
ComplexField_t * tempFields_m
Definition: FFT.h:353
BareField< Complex_t, Dim > ComplexField_t
Definition: FFT.h:406
FFTBase< Dim, T >::Domain_t Domain_t
Definition: FFT.h:408
ComplexField_t ** tempFields_m
Definition: FFT.h:479
std::complex< T > Complex_t
Definition: FFT.h:405
Layout_t * tempRLayout_m
Definition: FFT.h:474
void transform(const char *directionName, ComplexField_t &f, RealField_t &g, const bool &constInput=false)
void transform(int direction, RealField_t &f, ComplexField_t &g, const bool &constInput=false)
RealField_t * tempRField_m
Definition: FFT.h:484
FFT(const Domain_t &rdomain, const Domain_t &cdomain, const bool &compressTemps=false, int serialAxes=1)
Layout_t ** tempLayouts_m
Definition: FFT.h:469
LField< Complex_t, Dim > ComplexLField_t
Definition: FFT.h:407
Domain_t complexDomain_m
Definition: FFT.h:490
void transform(const char *directionName, RealField_t &f, ComplexField_t &g, const bool &constInput=false)
FieldLayout< Dim > Layout_t
Definition: FFT.h:402
BareField< T, Dim > RealField_t
Definition: FFT.h:403
LField< T, Dim > RealLField_t
Definition: FFT.h:404
void transform(int direction, ComplexField_t &f, RealField_t &g, const bool &constInput=false)
FFT(const Domain_t &rdomain, const Domain_t &cdomain, const bool transformTheseDims[Dim], const bool &compressTemps=false)
void transform(const char *directionName, ComplexField_t &f, RealField_t &g, const bool &constInput=false)
std::complex< T > Complex_t
Definition: FFT.h:545
LField< Complex_t, 1U > ComplexLField_t
Definition: FFT.h:547
FieldLayout< 1U > Layout_t
Definition: FFT.h:542
FFTBase< 1U, T >::Domain_t Domain_t
Definition: FFT.h:548
void transform(int direction, RealField_t &f, ComplexField_t &g, const bool &constInput=false)
BareField< T, 1U > RealField_t
Definition: FFT.h:543
FFT(const Domain_t &rdomain, const Domain_t &cdomain, const bool transformTheseDims[1U], const bool &compressTemps=false)
void transform(const char *directionName, RealField_t &f, ComplexField_t &g, const bool &constInput=false)
BareField< Complex_t, 1U > ComplexField_t
Definition: FFT.h:546
ComplexField_t * tempFields_m
Definition: FFT.h:609
FFT(const Domain_t &rdomain, const Domain_t &cdomain, const bool &compressTemps=false)
LField< T, 1U > RealLField_t
Definition: FFT.h:544
Domain_t complexDomain_m
Definition: FFT.h:621
void transform(int direction, ComplexField_t &f, RealField_t &g, const bool &constInput=false)
Layout_t * tempRLayout_m
Definition: FFT.h:614
Layout_t * tempLayouts_m
Definition: FFT.h:604
BareField< T, Dim > RealField_t
Definition: FFT.h:666
void transform(int direction, RealField_t &f)
ComplexField_t ** tempFields_m
Definition: FFT.h:785
void transform(int direction, RealField_t &f, ComplexField_t &g, const bool &constInput=false)
void transform(int direction, ComplexField_t &f, RealField_t &g, const bool &constInput=false)
const Domain_t * complexDomain_m
Definition: FFT.h:795
std::complex< T > Complex_t
Definition: FFT.h:668
Layout_t ** tempRLayouts_m
Definition: FFT.h:780
Layout_t ** tempLayouts_m
Definition: FFT.h:775
FFT(const Domain_t &rdomain, const bool sineTransformDims[Dim], const bool &compressTemps=false)
FFT(const Domain_t &rdomain, const bool &compressTemps=false)
FFT(const Domain_t &rdomain, const Domain_t &cdomain, const bool transformTheseDims[Dim], const bool sineTransformDims[Dim], const bool &compressTemps=false)
void transform(int direction, RealField_t &f, RealField_t &g, const bool &constInput=false)
BareField< Complex_t, Dim > ComplexField_t
Definition: FFT.h:669
RealField_t ** tempRFields_m
Definition: FFT.h:790
FFT(const Domain_t &rdomain, const Domain_t &cdomain, const bool sineTransformDims[Dim], const bool &compressTemps=false)
FFTBase< Dim, T >::Domain_t Domain_t
Definition: FFT.h:671
LField< Complex_t, Dim > ComplexLField_t
Definition: FFT.h:670
void transform(const char *directionName, RealField_t &f, RealField_t &g, const bool &constInput=false)
LField< T, Dim > RealLField_t
Definition: FFT.h:667
void transform(const char *directionName, RealField_t &f, ComplexField_t &g, const bool &constInput=false)
void transform(const char *directionName, ComplexField_t &f, RealField_t &g, const bool &constInput=false)
void transform(const char *directionName, RealField_t &f)
FieldLayout< Dim > Layout_t
Definition: FFT.h:665
Layout_t * tempRLayouts_m
Definition: FFT.h:921
void transform(int direction, RealField_t &f)
FFT(const Domain_t &rdomain, const bool sineTransformDims[1U], const bool &compressTemps=false)
FieldLayout< 1U > Layout_t
Definition: FFT.h:869
RealField_t * tempRFields_m
Definition: FFT.h:926
void transform(const char *directionName, RealField_t &f, RealField_t &g, const bool &constInput=false)
FFT(const Domain_t &rdomain, const bool &compressTemps=false)
void transform(int direction, RealField_t &f, RealField_t &g, const bool &constInput=false)
void transform(const char *directionName, RealField_t &f)
FFTBase< 1U, T >::Domain_t Domain_t
Definition: FFT.h:872
LField< T, 1U > RealLField_t
Definition: FFT.h:871
BareField< T, 1U > RealField_t
Definition: FFT.h:870
InternalFFT_t & getEngine(void)
access the internal FFT Engine
Definition: FFTBase.h:154
int getDirection(const char *directionName) const
translate direction name string into dimension number
Definition: FFTBase.h:225
unsigned numTransformDims(void) const
query number of transform dimensions
Definition: FFTBase.h:148
const Domain_t & getDomain(void) const
get our domain
Definition: FFTBase.h:160
Precision_t & getNormFact(void)
get the FFT normalization factor
Definition: FFTBase.h:157
bool compressTemps(void) const
do we compress temps?
Definition: FFTBase.h:166
@ ccFFT
Definition: FFTBase.h:63
bool checkDomain(const Domain_t &dom1, const Domain_t &dom2) const
compare indexes of two domains
Definition: FFTBase.h:269
void callFFT(unsigned transformDim, int direction, Complex_t *data)
void setup(unsigned numTransformDims, const int *transformTypes, const int *axisLengths)
Definition: fftpack_FFT.h:153
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
e_dim_tag getDistribution(unsigned int d) const
Definition: FieldLayout.h:396