Chombo + EB  3.0
IndexTMI.H
Go to the documentation of this file.
1 #ifdef CH_LANG_CC
2 /*
3  * _______ __
4  * / ___/ / ___ __ _ / / ___
5  * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6  * \___/_//_/\___/_/_/_/_.__/\___/
7  * Please refer to Copyright.txt, in Chombo's root directory.
8  */
9 #endif
10 
11 #ifndef _INDEXTMI_H_
12 #define _INDEXTMI_H_
13 
14 #include <iostream>
15 using std::ostream;
16 using std::istream;
17 using std::ws;
18 
19 #include "MayDay.H"
20 #include "Misc.H"
21 #include "IndexTM.H"
22 #include "parstream.H"
23 #include <cmath>
24 #include <algorithm>
25 #include <functional>
26 #include <numeric>
27 #include "Metaprograms.H"
28 
29 #include "BaseNamespaceHeader.H"
30 
31 template<typename T, int N> ostream& operator<< (ostream & a_os,
32  const IndexTM<T,N> & a_p)
33 {
34  a_os << '(';
35 
36  for (int i = 0; i < N; ++i)
37  {
38  a_os << a_p[i];
39 
40  if (i < N-1)
41  {
42  a_os << ',';
43  }
44  }
45 
46  a_os << ')';
47 
48  if (a_os.fail())
49  {
50  MayDay::Abort("operator<<(ostream&,Index&) failed");
51  }
52 
53  return a_os;
54 }
55 
56 //
57 // Copied from <Utility.H>
58 //
59 #define CH_IGNORE_MAX 100000
60 
61 template<typename T, int N> istream& operator>> (istream & a_is,
62  IndexTM<T,N> & a_p)
63 {
64  a_is >> ws;
65 
66  char c;
67  a_is >> c;
68  a_is.putback(c);
69 
70  if (c == '(')
71  {
72  a_is.ignore(CH_IGNORE_MAX, '(') >> a_p[0];
73 
74  for (int i = 1; i < N; ++i)
75  {
76  a_is.ignore(CH_IGNORE_MAX, ',') >> a_p[i];
77  }
78 
79  a_is.ignore(CH_IGNORE_MAX, ')');
80  }
81  else if (c == '<')
82  {
83  a_is.ignore(CH_IGNORE_MAX, '<') >> a_p[0];
84 
85  for (int i = 1; i < N; ++i)
86  {
87  a_is.ignore(CH_IGNORE_MAX, ',') >> a_p[1];
88  }
89  a_is.ignore(CH_IGNORE_MAX, '>');
90  }
91  else
92  {
93  MayDay::Abort("operator>>(istream&,Index&): expected \'(\' or \'<\'");
94  }
95 
96  if (a_is.fail())
97  {
98  MayDay::Abort("operator>>(istream&,Index&) failed");
99  }
100 
101  return a_is;
102 }
103 
104 template<typename T, int N> void IndexTM<T,N>::printOn (ostream & a_os) const
105 {
106  a_os << "Index: " << *this << "\n";
107 }
108 
109 template<typename T, int N> void IndexTM<T,N>::p() const
110 {
111  pout() << *this << "\n";
112 }
113 
114 template<typename T, int N> void IndexTM<T,N>::dumpOn (ostream & a_os) const
115 {
116  a_os << "Index " << *this << "\n";
117 }
118 
119 //
120 // Static object initialization.
121 //
122 /*
123 template<typename T, int N> int IndexTM<T,N>::InitStatics()
124 {
125  IndexTM<T,N>& pz = const_cast<IndexTM<T,N>&>(IndexTM<T,N>::Zero);
126 
127  pz.setAll(0);
128 
129  IndexTM<T,N>& pu = const_cast<IndexTM<T,N>&>(IndexTM<T,N>::Unit);
130 
131  pu.setAll(1);
132 
133  // No danger of Index::Zero and Unit not having been allocated, as ARM section
134  // 3.4 says "The initialization of nonlocal static objects in a translation unit
135  // is done before the first use of any function...defined in that translation
136  // unit."
137  //
138  // Had to go through the const_cast stuff because it's nice to be able to declare
139  // Index::Zero and Index::Unit as const.
140 
141  return 0; // arbitrary
142 }
143 */
144 
145 //
146 // Inlines.
147 //
148 template<typename T, int N> inline IndexTM<T,N>::IndexTM(const T *a_a)
149  : GenericArithmeticable< T, IndexTM<T,N> >(this)
150 {
151  memcpy(m_vect, a_a, N*sizeof(T));
152 }
153 
154 template<typename T, int N> inline IndexTM<T,N>::IndexTM(const char* a_reference)
155  : GenericArithmeticable< T, IndexTM<T,N> >(this)
156 {
157  if (a_reference[0] == 48) setAll(0);
158  else if(a_reference[0] == 49) setAll(1);
159  else
160  MayDay::Error("unknown static initialization for IndexTM");
161 }
162 
163 template<typename T, int N> inline IndexTM<T,N>::IndexTM(const IndexTM<T,N> & a_iv)
164  : GenericArithmeticable< T, IndexTM<T,N> >(this)
165 {
166  memcpy(m_vect, a_iv.m_vect, N*sizeof(T));
167 }
168 
169 template<typename T, int N> inline IndexTM<T,N>& IndexTM<T,N>::operator=(const IndexTM<T,N> & a_iv)
170 {
171  memcpy(m_vect, a_iv.m_vect, N*sizeof(T));
172  return *this;
173 }
174 
175 template<typename T, int N> inline T& IndexTM<T,N>::operator[] (int a_i)
176 {
177  CH_assert(a_i >= 0 && a_i < N);
178  return m_vect[a_i];
179 }
180 
181 template<typename T, int N> inline T IndexTM<T,N>::operator[] (int a_i) const
182 {
183  CH_assert(a_i >= 0 && a_i < N);
184  return m_vect[a_i];
185 }
186 
187 template<typename T, int N> inline void IndexTM<T,N>::setVal(int a_i,
188  T a_val)
189 {
190  CH_assert(a_i >= 0 && a_i < N);
191  m_vect[a_i] = a_val;
192 }
193 
194 template<typename T, int N> inline void IndexTM<T,N>::setAll(T a_val)
195 {
196  for (int i = 0; i < N; i++)
197  {
198  m_vect[i] = a_val;
199  }
200 }
201 
202 template<typename T, int N> inline const T* IndexTM<T,N>::dataPtr() const
203 {
204  return m_vect;
205 }
206 
207 template<typename T, int N> inline T* IndexTM<T,N>::dataPtr()
208 {
209  return m_vect;
210 }
211 
212 template<typename T, int N> inline const T* IndexTM<T,N>::getVect() const
213 {
214  return m_vect;
215 }
216 
217 template<typename T, int N> inline bool IndexTM<T,N>::operator== (const IndexTM & a_p) const
218 {
219  return Metaprograms::pointwiseCompare<N,T,std::equal_to<T> >(m_vect,a_p.m_vect);
220 }
221 
222 template<typename T, int N> inline bool IndexTM<T,N>::operator!= (const IndexTM & a_p) const
223 {
224  return !(operator==(a_p));
225 }
226 
227 template<typename T, int N> inline bool IndexTM<T,N>::lexLT(const IndexTM & a_s) const
228 {
229  return Metaprograms::LexLT<N,T>()(m_vect,a_s.m_vect);
230 }
231 
232 template<typename T, int N> inline bool IndexTM<T,N>::lexGT(const IndexTM & a_s) const
233 {
234  return ! Metaprograms::LexLT<N,T>()(m_vect,a_s.m_vect);
235 }
236 
237 template<typename T, int N> inline IndexTM<T,N> IndexTM<T,N>::operator+ () const
238 {
239  return IndexTM<T,N>(*this);
240 }
241 
242 template<typename T, int N> inline IndexTM<T,N> IndexTM<T,N>::operator- () const
243 {
244  IndexTM<T,N> result(*this);
245  for (int i = 0; i < N; ++i)
246  {
247  result.m_vect[i] *= -1;
248  }
249  return result;
250 }
251 
252 template<typename T, int N> inline T IndexTM<T,N>::dotProduct(const IndexTM<T,N> & a_rhs ) const
253 {
254  return Metaprograms::InnerProduct<N,T,T,
255  std::plus<T>,
256  std::multiplies<T> >()(m_vect,
257  a_rhs.m_vect);
258 }
259 
260 template<typename T, int N> inline T IndexTM<T,N>::sum() const
261 {
263 }
264 
265 template<typename T, int N> inline T IndexTM<T,N>::product () const
266 {
268 }
269 
270 template<typename T, int N> template<typename OP> bool IndexTM<T,N>::operatorCompare(const IndexTM<T,N> & a_p,
271  const OP & a_op) const
272 {
273  return Metaprograms::pointwiseCompare<N,T,OP>(m_vect,a_p.m_vect);
274 }
275 
276 
277 template<typename T, int N> template<typename OP> inline IndexTM<T,N>& IndexTM<T,N>::operatorOpEquals(const T & a_s,
278  const OP & a_op)
279 {
281  return *this;
282 }
283 
284 template<typename T, int N> template<typename OP> inline IndexTM<T,N>& IndexTM<T,N>::operatorOpEquals(const IndexTM<T,N> & a_p,
285  const OP & a_op)
286 {
288  return *this;
289 }
290 
291 template<typename T, int N> inline IndexTM<T,N>& IndexTM<T,N>::reciprocal()
292 {
293  std::transform(m_vect, m_vect+N, m_vect, bind1st(std::divides<T>(),T(1)));
294  return *this;
295 }
296 
297 template<typename T> static bool abscompare(const T & a_a,
298  const T & a_b)
299 {
300  return ::fabs(a_a) < ::fabs(a_b);
301 }
302 template<typename T, int N> inline int IndexTM<T,N>::minDir(bool a_doAbs) const
303 {
304  if (a_doAbs)
305  {
306  return std::min_element(m_vect, m_vect+N, std::ptr_fun(abscompare<T>)) - m_vect;
307  }
308  else
309  {
310  return std::min_element(m_vect, m_vect+N) - m_vect;
311  }
312 }
313 
314 template<typename T, int N> inline int IndexTM<T,N>::maxDir(bool a_doAbs) const
315 {
316  if (a_doAbs)
317  {
318  return std::max_element(m_vect, m_vect+N, std::ptr_fun(abscompare<T>)) - m_vect;
319  }
320  else
321  {
322  return std::max_element(m_vect, m_vect+N) - m_vect;
323  }
324 }
325 
326 template<typename T> static T ourmin(T a_a,
327  T a_b)
328 {
329  return ((a_a < a_b) ? a_a : a_b);
330 }
331 
332 template<typename T> static T ourmax(T a_a,
333  T a_b)
334 {
335  return (a_a > a_b ? a_a : a_b);
336 }
337 
338 template<typename T, int N> inline IndexTM<T,N>& IndexTM<T,N>::min(const IndexTM<T,N> & a_p)
339 {
340  std::transform(m_vect, m_vect+N, a_p.m_vect, m_vect,
341  std::ptr_fun(ourmin<T>));
342  return *this;
343 }
344 
345 template<typename T, int N> inline IndexTM<T,N>& IndexTM<T,N>::max(const IndexTM<T,N> & a_p)
346 {
347  std::transform(m_vect, m_vect+N, a_p.m_vect, m_vect,
348  std::ptr_fun(ourmax<T>));
349  return *this;
350 }
351 
352 
353 template<typename T, int N> inline IndexTM<T,N>& IndexTM<T,N>::scale(T a_s)
354 {
355  return (*this) *= a_s;
356 }
357 
358 template<typename T, int N> inline IndexTM<T,N>& IndexTM<T,N>::reflect (T a_refIx,
359  int a_idir)
360 {
361  CH_assert(a_idir >= 0 && a_idir < N);
362  m_vect[a_idir] = -m_vect[a_idir] + 2*a_refIx;
363  return *this;
364 }
365 
366 template<typename T, int N> inline IndexTM<T,N>& IndexTM<T,N>::shift(int a_coord,
367  T a_s)
368 {
369  CH_assert(a_coord >= 0 && a_coord < N);
370  m_vect[a_coord] += a_s;
371  return *this;
372 }
373 
374 template<typename T, int N> inline IndexTM<T,N>& IndexTM<T,N>::shift(const IndexTM<T,N> & a_iv)
375 {
376  return (*this) += a_iv;
377 }
378 
379 template<typename T, int N> inline IndexTM<T,N>& IndexTM<T,N>::diagShift(T a_s)
380 {
381  return (*this) += a_s;
382 }
383 
384 template<typename T, int N> inline IndexTM<T,N> scale (const IndexTM<T,N> & a_p,
385  T a_s)
386 {
387  return a_p * a_s;
388 }
389 
390 template<typename T, int N> inline IndexTM<T,N> diagShift(const IndexTM<T,N> & a_p,
391  T a_s)
392 {
393  return a_p + a_s;
394 }
395 
396 template<typename T, int N> inline IndexTM<T,N> min(const IndexTM<T,N> & a_p1,
397  const IndexTM<T,N> & a_p2)
398 {
399  IndexTM<T,N> result(a_p1);
400  return result.min(a_p2);
401 }
402 
403 template<typename T, int N> inline IndexTM<T,N> max(const IndexTM<T,N> & a_p1,
404  const IndexTM<T,N> & a_p2)
405 {
406  IndexTM<T,N> result(a_p1);
407  return result.max(a_p2);
408 }
409 
410 template<typename T, int N> inline IndexTM<T,N> BASISV_TM(int a_dir)
411 {
412  CH_assert(a_dir >= 0 && a_dir < N);
414  tmp.dataPtr()[a_dir] = T(1);
415  return tmp;
416 }
417 
418 template<typename T, int N> inline IndexTM<T,N> reflect(const IndexTM<T,N> & a_a,
419  T a_refIx,
420  int a_idir)
421 {
422  IndexTM<T,N> result(a_a);
423  return result.reflect(a_refIx, a_idir);
424 }
425 
426 template<typename T> static T ourcoarsen(T a_a,
427  T a_b)
428 {
429  return (a_a < 0 ? T(-::fabs(a_a+1))/a_b-1 : a_a/a_b);
430 }
431 
432 template<typename T, int N> inline IndexTM<T,N> coarsen(const IndexTM<T,N> & a_p,
433  T a_s)
434 {
435  IndexTM<T,N> result(a_p);
436  return result.coarsen(a_s);
437 }
438 
439 template<typename T, int N> inline IndexTM<T,N> coarsen(const IndexTM<T,N> & a_p1,
440  const IndexTM<T,N> & a_p2)
441 {
442  IndexTM<T,N> result(a_p1);
443  return result.coarsen(a_p2);
444 }
445 
446 /*
447 template<typename T, int N> IndexTM<T,N>::operator IndexTM<Real,N>()
448 {
449  IndexTM<Real,N> result;
450  for (int i = 0; i < N; ++i)
451  {
452  result.dataPtr()[i] = Real(m_vect[i]);
453  }
454  return result;
455 }
456 */
457 
458 template<typename T, int N> inline IndexTM<T,N>& IndexTM<T,N>::coarsen(T a_s)
459 {
460  CH_assert(a_s > 0);
461  std::transform(m_vect, m_vect+N, m_vect,
462  std::bind2nd(std::ptr_fun(ourcoarsen<T>),a_s));
463  return *this;
464 }
465 
466 template<typename T, int N> inline IndexTM<T,N>& IndexTM<T,N>::coarsen(const IndexTM<T,N> & a_p)
467 {
469  std::transform(m_vect, m_vect+N, a_p.m_vect, m_vect, std::ptr_fun(ourcoarsen<T>));
470  return *this;
471 }
472 
473 template<typename T, int N> void IndexTM<T,N>::linearIn(const void* a_inBuf)
474 {
475  memcpy(m_vect, (T*)a_inBuf, N*sizeof(T));
476 }
477 
478 template<typename T, int N> void IndexTM<T,N>::linearOut(void* a_outBuf) const
479 {
480  memcpy((T*)a_outBuf, m_vect, N*sizeof(T));
481 }
482 
483 template<typename T, int N> IndexTM<T,N>::IndexTM(T a_i)
484  : GenericArithmeticable< T, IndexTM<T,N> >(this)
485 {
486  STATIC_ASSERT(N == 1);
487  m_vect[0] = a_i;
488 }
489 
490 template<typename T, int N> IndexTM<T,N>::IndexTM(T a_i,
491  T a_j)
492  : GenericArithmeticable< T, IndexTM<T,N> >(this)
493 {
494  STATIC_ASSERT(N == 2);
495  m_vect[0] = a_i;
496  m_vect[1] = a_j;
497 }
498 
499 template<typename T, int N> IndexTM<T,N>::IndexTM(T a_i,
500  T a_j,
501  T a_k)
502  : GenericArithmeticable< T, IndexTM<T,N> >(this)
503 {
504  STATIC_ASSERT(N == 3);
505  m_vect[0] = a_i;
506  m_vect[1] = a_j;
507  m_vect[2] = a_k;
508 }
509 
510 template<typename T, int N> IndexTM<T,N>::IndexTM(T a_i,
511  T a_j,
512  T a_k,
513  T a_l)
514  : GenericArithmeticable< T, IndexTM<T,N> >(this)
515 {
516  STATIC_ASSERT(N == 4);
517  m_vect[0] = a_i;
518  m_vect[1] = a_j;
519  m_vect[2] = a_k;
520  m_vect[3] = a_l;
521 }
522 
523 template<typename T, int N> IndexTM<T,N>::IndexTM(T a_i,
524  T a_j,
525  T a_k,
526  T a_l,
527  T a_m)
528  : GenericArithmeticable< T, IndexTM<T,N> >(this)
529 {
530  STATIC_ASSERT(N == 5);
531  m_vect[0] = a_i;
532  m_vect[1] = a_j;
533  m_vect[2] = a_k;
534  m_vect[3] = a_l;
535  m_vect[4] = a_m;
536 }
537 
538 template<typename T, int N> IndexTM<T,N>::IndexTM(T a_i,
539  T a_j,
540  T a_k,
541  T a_l,
542  T a_m,
543  T a_n)
544  : GenericArithmeticable< T, IndexTM<T,N> >(this)
545 {
546  STATIC_ASSERT(N == 6);
547  m_vect[0] = a_i;
548  m_vect[1] = a_j;
549  m_vect[2] = a_k;
550  m_vect[3] = a_l;
551  m_vect[4] = a_m;
552  m_vect[5] = a_n;
553 }
554 
555 /*
556 template<typename T, int N> const IndexTM<T,N> IndexTM<T,N>::Zero;
557 template<typename T, int N> const IndexTM<T,N> IndexTM<T,N>::Unit;
558 
559 static int s_dummyForIntVectCpp1 (IndexTM<int ,1>::InitStatics());
560 static int s_dummyForIntVectCpp2 (IndexTM<int ,2>::InitStatics());
561 static int s_dummyForIntVectCpp3 (IndexTM<int ,3>::InitStatics());
562 static int s_dummyForIntVectCpp4 (IndexTM<int ,4>::InitStatics());
563 static int s_dummyForIntVectCpp5 (IndexTM<int ,5>::InitStatics());
564 static int s_dummyForIntVectCpp6 (IndexTM<int ,6>::InitStatics());
565 static int s_dummyForRealVectCpp1(IndexTM<Real,1>::InitStatics());
566 static int s_dummyForRealVectCpp2(IndexTM<Real,2>::InitStatics());
567 static int s_dummyForRealVectCpp3(IndexTM<Real,3>::InitStatics());
568 static int s_dummyForRealVectCpp4(IndexTM<Real,4>::InitStatics());
569 static int s_dummyForRealVectCpp5(IndexTM<Real,5>::InitStatics());
570 static int s_dummyForRealVectCpp6(IndexTM<Real,6>::InitStatics());
571 */
572 
573 // If Index::Zero and Index::Unit were pointers, we wouldn't need this extra
574 // static int. But they're objects, and the danger is that the initializations
575 // right above here ("Index Index::Zero;" and "Index Index::Unit;") are hit
576 // after the last call to Index::InitStatics, and in that case the
577 // Index::Index() constructor could redefine Zero and Unit. In fact, the way
578 // things stand now, nothing bad would happen, because the Index::Index()
579 // constructor doesn't assign anything to any of the data members. But we don't
580 // want to count on that always being the case.
581 
582 #include "BaseNamespaceFooter.H"
583 
584 #endif // include guard
const T * dataPtr() const
Definition: IndexTMI.H:202
std::ostream & pout()
Use this in place of std::cout for program output.
void dumpOn(std::ostream &a_os) const
Definition: IndexTMI.H:114
istream & operator>>(istream &a_is, IndexTM< T, N > &a_p)
Definition: IndexTMI.H:61
Definition: Metaprograms.H:153
IndexTM< T, N > & operatorOpEquals(const IndexTM< T, N > &a_p, const OP &a_op)
Definition: IndexTMI.H:284
#define CH_assert(cond)
Definition: CHArray.H:37
IndexTM()
Definition: IndexTM.H:93
void setAll(T a_val)
Definition: IndexTMI.H:194
static bool abscompare(const T &a_a, const T &a_b)
Definition: IndexTMI.H:297
bool operator!=(const IndexTM &a_p) const
Definition: IndexTMI.H:222
IndexTM operator-() const
Definition: IndexTMI.H:242
static T ourmin(T a_a, T a_b)
Definition: IndexTMI.H:326
Definition: GenericArithmetic.H:54
T dotProduct(const IndexTM &a_rhs) const
Definition: IndexTMI.H:252
IndexTM< T, N > BASISV_TM(int a_dir)
Definition: IndexTMI.H:410
IndexTM & reciprocal()
Definition: IndexTMI.H:291
bool lexLT(const IndexTM &a_s) const
Definition: IndexTMI.H:227
Definition: IndexTM.H:36
IndexTM & diagShift(T a_s)
Definition: IndexTMI.H:379
void setVal(int a_i, T a_val)
Definition: IndexTMI.H:187
T sum() const
Definition: IndexTMI.H:260
T & operator[](int a_i)
Definition: IndexTMI.H:175
static T ourcoarsen(T a_a, T a_b)
Definition: IndexTMI.H:426
IndexTM & reflect(T a_refIx, int a_idir)
Definition: IndexTMI.H:358
IndexTM operator+() const
Definition: IndexTMI.H:237
bool lexGT(const IndexTM &a_s) const
Definition: IndexTMI.H:232
IndexTM & coarsen(const IndexTM &a_p)
Definition: IndexTMI.H:466
IndexTM & scale(T a_s)
Definition: IndexTMI.H:353
IndexTM & min(const IndexTM &a_p)
Definition: IndexTMI.H:338
bool operator==(const IndexTM &a_p) const
Definition: IndexTMI.H:217
static void Error(const char *const a_msg=m_nullString, int m_exitCode=CH_DEFAULT_ERROR_CODE)
Print out message to cerr and exit with the specified exit code.
void linearOut(void *a_outBuf) const
Definition: IndexTMI.H:478
T product() const
Definition: IndexTMI.H:265
bool operatorCompare(const IndexTM< T, N > &a_p, const OP &a_op) const
Definition: IndexTMI.H:270
#define CH_IGNORE_MAX
Definition: IndexTMI.H:59
Definition: Metaprograms.H:122
void p() const
Definition: IndexTMI.H:109
ostream & operator<<(ostream &a_os, const IndexTM< T, N > &a_p)
Definition: IndexTMI.H:31
const T * getVect() const
Definition: IndexTMI.H:212
Definition: Metaprograms.H:39
Definition: Metaprograms.H:91
IndexTM & max(const IndexTM &a_p)
Definition: IndexTMI.H:345
IndexTM & shift(int a_coord, T a_s)
Definition: IndexTMI.H:366
void linearIn(const void *a_inBuf)
Definition: IndexTMI.H:473
void printOn(std::ostream &a_os) const
Definition: IndexTMI.H:104
int minDir(bool a_doAbs) const
Definition: IndexTMI.H:302
IndexTM & operator=(const IndexTM &a_rhs)
Definition: IndexTMI.H:169
static T ourmax(T a_a, T a_b)
Definition: IndexTMI.H:332
T m_vect[N]
Definition: IndexTM.H:460
static void Abort(const char *const a_msg=m_nullString)
Print out message to cerr and exit via abort() (if serial) or MPI_Abort() (if parallel).
int maxDir(bool a_doAbs) const
Definition: IndexTMI.H:314