Chombo + EB + MF  3.2
CodimBoxImplem.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 _CODIMBOXIMPLEM_H_
12 #define _CODIMBOXIMPLEM_H_
13 
14 #include "CodimBox.H"
15 
16 #include "NamespaceHeader.H"
17 
18 /*******************************************************************************
19  *
20  * \file CodimBox.cpp
21  *
22  * \brief Non-inline definitions for CodimBox class
23  *
24  ******************************************************************************/
25 
26 /*--------------------------------------------------------------------*
27  * Definitions of static member data (these must be in the same file
28  * as the constructor definitions)
29  *--------------------------------------------------------------------*/
30 
31 template<typename S> int CodimBox<S>::numOrient[CodimBox<S>::numCD] =
32  {
33  -1
34  };
35 template<typename S> int CodimBox<S>::totOrient[CodimBox<S>::numCD] =
36  {
37  -1
38  };
39 template<typename S> unsigned CodimBox<S>::bitOrient[CodimBox<S>::numAI] =
40  {
41  0
42  };
43 template<typename S> int CodimBox<S>::indexFAB[CodimBox<S>::numAI] =
44  {
45  -1
46  };
47 
48 /*==============================================================================
49  * Constructors and destructors
50  *============================================================================*/
51 
52 /*--------------------------------------------------------------------*/
53 /// Default constructor
54 /** The codimension can be set by the 'define' function
55  *//*-----------------------------------------------------------------*/
56 
57 template<typename S> CodimBox<S>::CodimBox()
58 {
59  initialize();
60 }
61 
62 /*--------------------------------------------------------------------*/
63 /// Full constructor
64 /** \param[in] a_codim
65  * The codimension intended for the object
66  * \param[in] a_box The cell centered box for the FArrays
67  * \param[in] a_nvar The number of components for the FArrays
68  *//*-----------------------------------------------------------------*/
69 
70 template<typename S> CodimBox<S>::CodimBox(const int a_codim, const Box& a_box, const int a_nvar)
71 :
72 m_codim(a_codim)
73 {
74  initialize();
75  define(a_box, a_nvar);
76 }
77 
78 /*--------------------------------------------------------------------*/
79 /// Destructor
80 /*--------------------------------------------------------------------*/
81 
82 template<typename S> CodimBox<S>::~CodimBox()
83 {
84  clear();
85 }
86 
87 /*==============================================================================
88  * Member functions
89  *============================================================================*/
90 
91 /*--------------------------------------------------------------------*/
92 /// Initialize static lookup tables
93 /** Construct lookup tables that give the index of the appropriate
94  * S for a given codimension and orientation. This function
95  * is only called once to initialize the static lookup tables. The
96  * constructors will call initialize but if any static members are
97  * used before construction, it must be called manually. See class
98  * CodimBox for more information on the lookup tables.
99  *//*-----------------------------------------------------------------*/
100 
101 template<typename S> void CodimBox<S>::initialize()
102 {
103  if (indexFAB[0] == -1)
104  {
105  numOrient[0] = 1; // A codimension 0 object has 1 orientation.
106  indexFAB[0] = 0; // A codimension 0 object has 1 array with
107  // index 0
108  for (int i = 1; i != numCD; ++i) numOrient[i] = 0;
109  // The following temporary is used to save the global orientation
110  // sequentially for each codimension.
111  int tmpCodim[numCD][numAI];
112  tmpCodim[0][0] = 0; // A codimension 0 object has global
113  // orientation index 0
114  // The bits in 'i' described the directions that a codimension object
115  // is orthogonal to. In other words, they describe the orientation of
116  // the codimensional object.
117  for (int i = 1; i != numAI; ++i)
118  {
119  // Count the number of 1 bits in 'i'. This is the codimension
120  // and is stored in j.
121  unsigned k = i;
122  int j = (k & 1);
123  while (k >>= 1)
124  if (k & 1) ++j;
125  // The object with codimension 'j' and orientation 'i' is
126  // associated with the FArray at index 'numOrient[j]'. This is
127  // stored for lookup in 'indexFAB'
128  indexFAB[i] = numOrient[j];
129  // Save the orientation
130  tmpCodim[j][numOrient[j]] = i;
131  ++numOrient[j];
132  }
133  // 'numOrient[i]' now has the number of different orientations of a
134  // codimension 'i' object.
135  // Now update totOrient to a the total orientation from all small
136  // codimensiona and update bitOrient to sequentially store the
137  // orientations for each codimension
138  int k = 0; // Sequential index
139  int cOrient = 0; // Count of total orientations
140  for (int iCodim = 0; iCodim != numCD; ++iCodim)
141  {
142  const int nOrient = numOrient[iCodim];
143  totOrient[iCodim] = cOrient;
144  cOrient += nOrient;
145  for (int i = 0; i != nOrient; ++i)
146  bitOrient[k++] = tmpCodim[iCodim][i];
147  }
148  }
149 }
150 
151 /*--------------------------------------------------------------------*/
152 /// Define function allocates space
153 /** \param[in] a_codim
154  * The codimension intended for the object
155  * \param[in] a_box The cell centered box for the FArrays
156  * \param[in] a_nvar The number of components for the FArrays
157  *//*-----------------------------------------------------------------*/
158 
159 template<typename S> void CodimBox<S>::define(const int a_codim, const Box& a_box, const int a_nvar)
160 {
161  CH_assert(a_codim >= 0);
162  CH_assert(a_codim <= SpaceDim);
163  m_codim = a_codim;
164  define(a_box, a_nvar);
165 }
166 
167 /*--------------------------------------------------------------------*/
168 /// Define function allocates space
169 /** Codimension set by constructor
170  * \param[in] a_box The cell centered box for the FArrays
171  * \param[in] a_nvar The number of components for the FArrays
172  *//*-----------------------------------------------------------------*/
173 
174 template<typename S> void CodimBox<S>::define(const Box& a_box, const int a_nvar)
175 {
176  CH_assert(a_nvar > 0);
177  m_box = a_box;
178  m_nvar = a_nvar;
179  clear();
180  const int nOrient = numOrient[m_codim];
181  m_S.resize(nOrient);
182  for (int iOrient = 0; iOrient < nOrient; ++iOrient)
183  {
184  const Box cdbox = orientBox(iOrient);
185  m_S[iOrient] = new S(cdbox, m_nvar);
186  }
187 }
188 
189 /*--------------------------------------------------------------------*/
190 /// Deallocation of all memory
191 /*--------------------------------------------------------------------*/
192 
193 template<typename S> void CodimBox<S>::clear()
194 {
195  if (m_S.size() != 0)
196  {
197  const int nOrient = numOrient[m_codim];
198  for (int iOrient = 0; iOrient < nOrient; ++iOrient)
199  {
200  if (m_S[iOrient] != NULL)
201  delete m_S[iOrient];
202  }
203  m_S.clear();
204  }
205 }
206 
207 /*--------------------------------------------------------------------*/
208 /// Get the 'i'th orthogonal direction of an orientation
209 /** \param[in] a_iOrient
210  * The sequential orientation index from which to
211  * get the directions
212  * \param[in] a_i The 'i'th direction. 0 <= a_i < m_codim
213  * \return An integer defining the requested direction
214  * 0 <= return < SpaceDim
215  * \note
216  * <ul>
217  * <li> The directions are orderd from smallest to largest so
218  * a_i = 0 always returns the smallest direction.
219  * </ul>
220  *//*-----------------------------------------------------------------*/
221 
222 template<typename S> int CodimBox<S>::getDirection(const int a_iOrient, int a_i) const
223 {
224  CH_assert(a_i < m_codim); // Otherwise may loop forever
225  unsigned bOrient = seq2bit(a_iOrient);
226  int dir = 0;
227  ++a_i;
228  while (a_i)
229  {
230  if (bOrient & 1)
231  --a_i;
232  bOrient >>= 1;
233  ++dir;
234  }
235  return dir - 1;
236 }
237 
238 /*--------------------------------------------------------------------*/
239 /// Returns S in the directions defined by an IndexType
240 /** \param[in] a_ixType
241  * Box index type which must define exactly
242  * m_codim directions as 'NODE'
243  *//*-----------------------------------------------------------------*/
244 
245 /// Returns S in the directions defined by an IndexType
246 template<typename S> const S& CodimBox<S>::operator()(const IndexType &a_ixType) const
247 {
248  // Bit representation should be the same as used internally in IndexType but
249  // do a translation anyways
250  int count = 0;
251  unsigned bOrient = 0;
252  for (int i = 0; i != SpaceDim; ++i)
253  {
254  if (a_ixType[i])
255  {
256  bOrient += (1 << i);
257  ++count;
258  }
259  }
260  CH_assert(count == m_codim);
261  return getS(bOrient);
262 }
263 
264 template<typename S> S& CodimBox<S>::operator()(const IndexType &a_ixType)
265 {
266  // Bit representation should be the same as used internally in IndexType but
267  // do a translation anyways
268  int count = 0;
269  unsigned bOrient = 0;
270  for (int i = 0; i != SpaceDim; ++i)
271  {
272  if (a_ixType[i])
273  {
274  bOrient += (1 << i);
275  ++count;
276  }
277  }
278  CH_assert(count == m_codim);
279  return getS(bOrient);
280 }
281 
282 /*====================================================================*/
283 /** \name Accessor functions (1 for each codimension)
284  * \param[in] a_dir0-a_dir5
285  * The orthogonal directions define the
286  * orientation of the codimensional geometry.
287  * Directions can be specified in any order. For
288  * example, the edges in 3D orthogonal to
289  * directions i and j may be specified as (0, 1)
290  * or (1, 0). The individual directions should
291  * be unique but assertions are only implemented
292  * for codimensions <= 3.
293  *//*=================================================================*/
294 //@{
295 
296 /// Returns S in the given direction (codimension 0 or SpaceDim)
297 /** Formally this operator is for codimension 0 objects but it is also
298  * allowed for codimension 'SpaceDim' objects since there is also only
299  * one codimension object (the vertices) in that case. A codimension
300  * 'SpaceDim' object can also be accessed by specifying all the
301  * directions as orthogonal.
302  */
303 template<typename S> const S&CodimBox<S>::operator()() const
304 {
305  CH_assert(SpaceDim >= 0);
306  CH_assert(m_codim == 0 || m_codim == SpaceDim);
307  return getS((m_codim == 0) ? 0 : numAI - 1);
308 }
309 
310 template<typename S> S& CodimBox<S>::operator()()
311 {
312  CH_assert(SpaceDim >= 0);
313  CH_assert(m_codim == 0 || m_codim == SpaceDim);
314  return getS((m_codim == 0) ? 0 : numAI - 1);
315 }
316 
317 /// Returns S in the given direction (codimension 1)
318 template<typename S> const S&CodimBox<S>::operator()(const int a_dir0) const
319 {
320  CH_assert(SpaceDim >= 1);
321  CH_assert(m_codim == 1);
322  CH_assert(a_dir0 < SpaceDim);
323  return getS((1 << a_dir0));
324 }
325 
326 template<typename S> S&CodimBox<S>::operator()(const int a_dir0)
327 {
328  CH_assert(SpaceDim >= 1);
329  CH_assert(m_codim == 1);
330  CH_assert(a_dir0 < SpaceDim);
331  return getS((1 << a_dir0));
332 }
333 
334 /// Returns S in the given direction (codimension 2)
335 template<typename S> const S&CodimBox<S>::operator()(const int a_dir0,
336  const int a_dir1) const
337 {
338  CH_assert(SpaceDim >= 2);
339  CH_assert(m_codim == 2);
340  CH_assert(a_dir0 < SpaceDim);
341  CH_assert(a_dir1 < SpaceDim);
342  CH_assert(a_dir0 != a_dir1);
343  return getS((1 << a_dir0) +
344  (1 << a_dir1));
345 }
346 
347 template<typename S> S& CodimBox<S>::operator()(const int a_dir0,
348  const int a_dir1)
349 {
350  CH_assert(SpaceDim >= 2);
351  CH_assert(m_codim == 2);
352  CH_assert(a_dir0 < SpaceDim);
353  CH_assert(a_dir1 < SpaceDim);
354  CH_assert(a_dir0 != a_dir1);
355  return getS((1 << a_dir0) +
356  (1 << a_dir1));
357 }
358 
359 /// Returns S in the given direction (codimension 3)
360 template<typename S> const S&CodimBox<S>::operator()(const int a_dir0,
361  const int a_dir1,
362  const int a_dir2) const
363 {
364  CH_assert(SpaceDim >= 3);
365  CH_assert(m_codim == 3);
366  CH_assert(a_dir0 < SpaceDim);
367  CH_assert(a_dir1 < SpaceDim);
368  CH_assert(a_dir2 < SpaceDim);
369  CH_assert(a_dir0 != a_dir1);
370  CH_assert(a_dir1 != a_dir2);
371  CH_assert(a_dir2 != a_dir0);
372  return getS((1 << a_dir0) +
373  (1 << a_dir1) +
374  (1 << a_dir2));
375 }
376 
377 template<typename S> S& CodimBox<S>::operator()(const int a_dir0,
378  const int a_dir1,
379  const int a_dir2)
380 {
381  CH_assert(SpaceDim >= 3);
382  CH_assert(m_codim == 3);
383  CH_assert(a_dir0 < SpaceDim);
384  CH_assert(a_dir1 < SpaceDim);
385  CH_assert(a_dir2 < SpaceDim);
386  CH_assert(a_dir0 != a_dir1);
387  CH_assert(a_dir1 != a_dir2);
388  CH_assert(a_dir2 != a_dir0);
389  return getS((1 << a_dir0) +
390  (1 << a_dir1) +
391  (1 << a_dir2));
392 }
393 
394 /// Returns S in the given direction (codimension 4)
395 template<typename S> const S& CodimBox<S>::operator()(const int a_dir0,
396  const int a_dir1,
397  const int a_dir2,
398  const int a_dir3) const
399 {
400  CH_assert(SpaceDim >= 4);
401  CH_assert(m_codim == 4);
402  CH_assert(a_dir0 < SpaceDim);
403  CH_assert(a_dir1 < SpaceDim);
404  CH_assert(a_dir2 < SpaceDim);
405  CH_assert(a_dir3 < SpaceDim);
406  // No more checks for unique directions
407  return getS((1 << a_dir0) +
408  (1 << a_dir1) +
409  (1 << a_dir2) +
410  (1 << a_dir3));
411 }
412 
413 template<typename S> S&CodimBox<S>::operator()(const int a_dir0,
414  const int a_dir1,
415  const int a_dir2,
416  const int a_dir3)
417 {
418  CH_assert(SpaceDim >= 4);
419  CH_assert(m_codim == 4);
420  CH_assert(a_dir0 < SpaceDim);
421  CH_assert(a_dir1 < SpaceDim);
422  CH_assert(a_dir2 < SpaceDim);
423  CH_assert(a_dir3 < SpaceDim);
424  // No more checks for unique directions
425  return getS((1 << a_dir0) +
426  (1 << a_dir1) +
427  (1 << a_dir2) +
428  (1 << a_dir3));
429 }
430 
431 /// Returns S in the given direction (codimension 5)
432 template<typename S> const S& CodimBox<S>::operator()(const int a_dir0,
433  const int a_dir1,
434  const int a_dir2,
435  const int a_dir3,
436  const int a_dir4) const
437 {
438  CH_assert(SpaceDim >= 5);
439  CH_assert(m_codim == 5);
440  CH_assert(a_dir0 < SpaceDim);
441  CH_assert(a_dir1 < SpaceDim);
442  CH_assert(a_dir2 < SpaceDim);
443  CH_assert(a_dir3 < SpaceDim);
444  CH_assert(a_dir4 < SpaceDim);
445  // No more checks for unique directions
446  return getS((1 << a_dir0) +
447  (1 << a_dir1) +
448  (1 << a_dir2) +
449  (1 << a_dir3) +
450  (1 << a_dir4));
451 }
452 
453 template<typename S> S& CodimBox<S>::operator()(const int a_dir0,
454  const int a_dir1,
455  const int a_dir2,
456  const int a_dir3,
457  const int a_dir4)
458 {
459  CH_assert(SpaceDim >= 5);
460  CH_assert(m_codim == 5);
461  CH_assert(a_dir0 < SpaceDim);
462  CH_assert(a_dir1 < SpaceDim);
463  CH_assert(a_dir2 < SpaceDim);
464  CH_assert(a_dir3 < SpaceDim);
465  CH_assert(a_dir4 < SpaceDim);
466  // No more checks for unique directions
467  return getS((1 << a_dir0) +
468  (1 << a_dir1) +
469  (1 << a_dir2) +
470  (1 << a_dir3) +
471  (1 << a_dir4));
472 }
473 
474 /// Returns S in the given direction (codimension 6)
475 template<typename S> const S& CodimBox<S>::operator()(const int a_dir0,
476  const int a_dir1,
477  const int a_dir2,
478  const int a_dir3,
479  const int a_dir4,
480  const int a_dir5) const
481 {
482  CH_assert(SpaceDim >= 6);
483  CH_assert(m_codim == 6);
484  CH_assert(a_dir0 < SpaceDim);
485  CH_assert(a_dir1 < SpaceDim);
486  CH_assert(a_dir2 < SpaceDim);
487  CH_assert(a_dir3 < SpaceDim);
488  CH_assert(a_dir4 < SpaceDim);
489  CH_assert(a_dir5 < SpaceDim);
490  // No more checks for unique directions
491  return getS((1 << a_dir0) +
492  (1 << a_dir1) +
493  (1 << a_dir2) +
494  (1 << a_dir3) +
495  (1 << a_dir4) +
496  (1 << a_dir5));
497 }
498 
499 template<typename S> S& CodimBox<S>::operator()(const int a_dir0,
500  const int a_dir1,
501  const int a_dir2,
502  const int a_dir3,
503  const int a_dir4,
504  const int a_dir5)
505 {
506  CH_assert(SpaceDim >= 6);
507  CH_assert(m_codim == 6);
508  CH_assert(a_dir0 < SpaceDim);
509  CH_assert(a_dir1 < SpaceDim);
510  CH_assert(a_dir2 < SpaceDim);
511  CH_assert(a_dir3 < SpaceDim);
512  CH_assert(a_dir4 < SpaceDim);
513  CH_assert(a_dir5 < SpaceDim);
514  // No more checks for unique directions
515  return getS((1 << a_dir0) +
516  (1 << a_dir1) +
517  (1 << a_dir2) +
518  (1 << a_dir3) +
519  (1 << a_dir4) +
520  (1 << a_dir5));
521 }
522 //@}
523 
524 /*--------------------------------------------------------------------*/
525 /// Set all values in all FAB
526 /** \param[in] a_x New value
527  *//*-----------------------------------------------------------------*/
528 
529 template<typename S> void CodimBox<S>::setVal(const Real a_x)
530 {
531  const int nOrient = numOrient[m_codim];
532  for (int iOrient = 0; iOrient < nOrient; ++iOrient)
533  {
534  m_S[iOrient]->setVal(a_x);
535  }
536 }
537 
538 /*====================================================================*/
539 /** \name Functions for compatability with containers like
540  * BoxLayoutData.h
541  *//*=================================================================*/
542 //@{
543 
544 /*--------------------------------------------------------------------*/
545 /// Copy from another CodimBox
546 /** \param[in] a_R Centered box describing region to copy
547  * \param[in] a_Cd Interval for components at destination
548  * \param[in] a_src The source CodimBox (must be same codimension)
549  * \param[in] a_Cs Interval for components at source
550  * \note
551  * <ul>
552  * <li> It is assumed that both CodimBoxes have the same
553  * orientation at their intersection.
554  * <li> a_R is not assumed to be contained within m_box because
555  * higher-level copy routines generally work on cell centers.
556  * </ul>
557  *//*-----------------------------------------------------------------*/
558 
559 template<typename S> void CodimBox<S>::copy(const Box& a_R,
560  const Interval& a_Cd,
561  const CodimBox& a_src,
562  const Interval& a_Cs)
563 {
564  CH_assert(m_codim == a_src.m_codim);
565  const int nOrient = numOrient[m_codim];
566  for (int iOrient = 0; iOrient != nOrient; ++iOrient)
567  {
568  CH_assert(m_S[iOrient] != NULL);
569  const S& srcFab = *a_src.m_S[iOrient];
570  // Orient box in othogonal orientation directions
571  Box cdbox = orientBox(iOrient, a_R);
572  // Intersect with both source and destination
573  cdbox &= srcFab.box();
574  cdbox &= m_S[iOrient]->box();
575  if (!cdbox.isEmpty())
576  {
577  m_S[iOrient]->copy(cdbox, a_Cd, cdbox, srcFab, a_Cs);
578  }
579  }
580 }
581 
582 /*--------------------------------------------------------------------*/
583 /// Copy from another CodimBox but to a different region
584 /** \param[in] a_Rs Centered box describing region to copy from in
585  * source
586  * \param[in] a_Cd Interval for components at destination
587  * \param[in] a_Rd Centered box describing region to copy to in
588  * destination
589  * \param[in] a_src The source CodimBox (must be same codimension)
590  * \param[in] a_Cs Interval for components at source
591  * \note
592  * <ul>
593  * <li> It is assumed that both CodimBoxes have the same
594  * orientation at their intersection.
595  * <li> Beware that the source and destination arguments are not
596  * grouped together.
597  * <li> The story here seems to be that copyTo in a LevelData uses
598  * centered boxes to see who to copy to. So we need +1 ghost
599  * cells in the destination to ensure abutting boxes are
600  * matched and that we can then copy abutting codimension
601  * objects. Hence, a_Rd may not be contained in m_box and
602  * must be intersected. Then make assumtions about what
603  * a_Rs should be.
604  * </ul>
605  *//*-----------------------------------------------------------------*/
606 
607 template<typename S> void CodimBox<S>::copy(const Box& a_Rs,
608  const Interval& a_Cd,
609  const Box& a_Rd,
610  const CodimBox<S>& a_src,
611  const Interval& a_Cs)
612 {
613  CH_assert(m_codim == a_src.m_codim);
614  CH_assert(a_Rs.sameSize(a_Rd));
615  const int nOrient = numOrient[m_codim];
616  for (int iOrient = 0; iOrient != nOrient; ++iOrient)
617  {
618  CH_assert(m_S[iOrient] != NULL);
619  // Orient destination box in othogonal orientation directions
620  Box cdboxd = orientBox(iOrient, a_Rd);
621  cdboxd &= m_S[iOrient]->box();
622  // Now assume a box size for the source
623  Box cdboxs = cdboxd;
624  if (a_Rs != a_Rd)
625  // Use 'cdboxd' but with shift from 'a_Rd' to 'a_Rs'
626  {
627  IntVect shiftVect(a_Rs.smallEnd());
628  shiftVect -= a_Rd.smallEnd();
629  cdboxs.shift(shiftVect);
630  }
631  if (!cdboxd.isEmpty())
632  {
633  m_S[iOrient]->copy(cdboxs, a_Cd, cdboxd,
634  *a_src.m_S[iOrient], a_Cs);
635  }
636  }
637 }
638 
639 /*--------------------------------------------------------------------*/
640 /// Returns size of serialized data
641 /** Returns size, in number of bytes, of a 1D representation of data
642  * in the class.
643  * \param[in] a_R Centered box describing size
644  * \param[in] a_comps
645  * Number of components for describing size
646  *//*-----------------------------------------------------------------*/
647 
648 template<typename S> int CodimBox<S>::size(const Box& a_R, const Interval& a_comps) const
649 {
650  int totalSize = 0;
651  S tempFab;
652  const int nOrient = numOrient[m_codim];
653  for (int iOrient = 0; iOrient != nOrient; ++iOrient)
654  {
655  const Box cdbox = orientBox(iOrient, a_R);
656  totalSize += tempFab.size(cdbox, a_comps);
657  }
658  return totalSize;
659 }
660 
661 /*--------------------------------------------------------------------*/
662 /// Writes a serialized representation of this CodimBox
663 /** Write a linear representaion of the internal data. Assumes that
664  * sufficient memory for the buffer has already been allocated by
665  * the caller.
666  * \param[in] a_buf Buffer for linear representation
667  * \param[in] a_R Centered box from which to write
668  * \param[in] a_comps
669  * Components to be written
670  *//*-----------------------------------------------------------------*/
671 
672 template<typename S> void CodimBox<S>::linearOut(void* a_buf, const Box& a_R, const Interval& a_comps) const
673 {
674  Real* buffer = static_cast<Real*>(a_buf);
675  const int nOrient = numOrient[m_codim];
676  for (int iOrient = 0; iOrient != nOrient; ++iOrient)
677  {
678  CH_assert(m_S[iOrient] != NULL);
679  const Box cdbox = orientBox(iOrient, a_R);
680  const int orientSize = m_S[iOrient]->size(cdbox, a_comps);
681  m_S[iOrient]->linearOut(buffer, cdbox, a_comps);
682  buffer += orientSize/sizeof(Real);
683  }
684 }
685 
686 /*--------------------------------------------------------------------*/
687 /// Reads a serialized representation of this CodimBox
688 /** Reads in the output of linearOut.
689  * \param[in] a_buf Buffer for linear representation
690  * \param[in] a_R Centered box to read to
691  * \param[in] a_comps
692  * Components to be read
693  *//*-----------------------------------------------------------------*/
694 
695 template<typename S> void CodimBox<S>::linearIn(void* a_buf, const Box& a_R, const Interval& a_comps)
696 {
697  Real* buffer = static_cast<Real*>(a_buf);
698  const int nOrient = numOrient[m_codim];
699  for (int iOrient = 0; iOrient != nOrient; ++iOrient)
700  {
701  CH_assert(m_S[iOrient] != NULL);
702  const Box cdbox = orientBox(iOrient, a_R);
703  const int orientSize = m_S[iOrient]->size(cdbox, a_comps);
704  m_S[iOrient]->linearIn(buffer, cdbox, a_comps);
705  buffer += orientSize/sizeof(Real);
706  }
707 }
708 //@}
709 
710 /*==============================================================================
711  * Private member functions
712  *============================================================================*/
713 
714 /*--------------------------------------------------------------------*/
715 /// Get all the orthogonal directions of an orientation (general)
716 /** General static routine for a given codimension and a bit
717  * representation of the orientation
718  * \param[in] a_codim
719  * The codimension
720  * \param[in] a_bOrient
721  * Bit representation of the orientation
722  * \param[in] a_dir Array with minimum size [a_codim]
723  * \param[out] a_dir Integers defining the directions
724  * 0 <= dir[i] < SpaceDim
725  * \note
726  * <ul>
727  * <li> The directions are orderd from smallest to largest.
728  * </ul>
729  *//*-----------------------------------------------------------------*/
730 
731 template<typename S> void CodimBox<S>::genGetDirections(const int a_codim,
732  int a_bOrient,
733  int *const a_dir)
734 {
735  for (int i = 0; i != a_codim; ++i)
736  a_dir[i] = 0;
737  int iStart = 0;
738  while (a_bOrient)
739  {
740  if (a_bOrient & 1)
741  ++iStart;
742  a_bOrient >>= 1;
743  for (int i = iStart; i < a_codim; ++i)
744  ++a_dir[i];
745  }
746 }
747 
748 /*--------------------------------------------------------------------*/
749 /// Orient a centered box in the othogonal directions of the given
750 /// orientation (general)
751 /** General static routine for a given codimension and a bit
752  * representation of the orientation
753  * \param[in] a_bOrient
754  * Bit representation of the orientation
755  * \param[in] a_cbox
756  * A centered box.
757  * \return The orientated box
758  *//*-----------------------------------------------------------------*/
759 
760 template<typename S> Box CodimBox<S>::genOrientBox(int a_bOrient, Box a_cbox)
761 {
762  int dir = 0;
763  while (a_bOrient)
764  {
765  if (a_bOrient & 1)
766  a_cbox.surroundingNodes(dir);
767  a_bOrient >>= 1;
768  ++dir;
769  }
770  return a_cbox;
771 }
772 
773 // Only of use with a register class
774 // /*--------------------------------------------------------------------*/
775 // /// Shift all FABs by halves in one direction.
776 // /** \param[in] a_dir Direction to shift
777 // * \param[in] a_numHalfs
778 // * Number of halves to shift
779 // * \note
780 // * <ul>
781 // * <li> This really messes with the concept of the CodimBox -
782 // * hence only for private use and the shifting should be
783 // * undone as soon as possible
784 // * </ul>
785 // *//*-----------------------------------------------------------------*/
786 
787 // void
788 // CodimBox::shiftHalf(const int a_dir, const int a_numHalfs)
789 // {
790 // const int nOrient = numOrient[m_codim];
791 // for (int iOrient = 0; iOrient != nOrient; ++iOrient)
792 // {
793 // m_S[iOrient]->shiftHalf(a_dir, a_numHalfs);
794 // }
795 // }
796 
797 #include "NamespaceFooter.H"
798 
799 #endif
~CodimBox()
Destructor.
Definition: CodimBoxImplem.H:82
unsigned seq2bit(const int a_iOrient) const
Definition: CodimBox.H:360
#define CH_assert(cond)
Definition: CHArray.H:37
const S & operator()() const
Returns S in the given direction (codimension 0)
Definition: CodimBoxImplem.H:303
bool sameSize(const Box &b) const
Definition: Box.H:1912
Number of codimensions.
Definition: CodimBox.H:71
static int totOrient[numCD]
Definition: CodimBox.H:252
static unsigned bitOrient[CodimBox::numAI]
Definition: CodimBox.H:254
static void initialize()
Initialize static lookup tables.
Definition: CodimBoxImplem.H:101
int size(const Box &a_R, const Interval &a_comps) const
Returns size of serialized data.
Definition: CodimBoxImplem.H:648
Vector< S * > m_S
The Ses for each orientation.
Definition: CodimBox.H:272
Box & surroundingNodes()
const int SpaceDim
Definition: SPACE.H:38
static int numOrient[numCD]
Definition: CodimBox.H:250
void resize(unsigned int isize)
Definition: Vector.H:346
void clear()
Definition: Vector.H:180
Structure for passing component ranges in code.
Definition: Interval.H:23
const IntVect & smallEnd() const
{ Accessors}
Definition: Box.H:1770
void linearOut(void *a_buf, const Box &a_R, const Interval &a_comps) const
Writes a serialized representation of this CodimBox.
Definition: CodimBoxImplem.H:672
double Real
Definition: REAL.H:33
int m_nvar
Number of components in the S.
Definition: CodimBox.H:271
size_t size() const
Definition: Vector.H:192
static Box genOrientBox(int a_bOrient, Box a_cbox)
Definition: CodimBoxImplem.H:760
void copy(const Box &a_R, const Interval &a_Cd, const CodimBox &a_src, const Interval &a_Cs)
Copy from another CodimBox.
Definition: CodimBoxImplem.H:559
static void genGetDirections(const int a_codim, int a_bOrient, int *const a_dir)
Get all the orthogonal directions of an orientation (general)
Definition: CodimBoxImplem.H:731
int m_codim
Definition: CodimBox.H:269
void linearIn(void *a_buf, const Box &a_R, const Interval &a_comps)
Reads a serialized representation of this CodimBox.
Definition: CodimBoxImplem.H:695
Definition: CodimBox.H:72
A Rectangular Domain on an Integer Lattice.
Definition: Box.H:469
void clear()
Deallocate.
Definition: CodimBoxImplem.H:193
An FArrayBox container for storage on the codimensions of a box.
Definition: CodimBox.H:65
S & getS(const unsigned i)
Return the FArray box from a bit description of the orientation.
Definition: CodimBox.H:545
int getDirection(const int a_iOrient, int a_i) const
Get the &#39;i&#39;th orthogonal direction of an orientation.
Definition: CodimBoxImplem.H:222
An integer Vector in SpaceDim-dimensional space.
Definition: CHArray.H:42
Cell-Based or Node-Based Indices.
Definition: Box.H:45
void define(const int a_codim, const Box &a_box, const int a_nvar)
Full define function.
Definition: CodimBoxImplem.H:159
Box & shift(int dir, int nzones)
shift functions
Definition: Box.H:2083
void setVal(const Real a_x)
Set all values in all FAB.
Definition: CodimBoxImplem.H:529
bool isEmpty() const
{ Comparison Functions}
Definition: Box.H:1862
static int indexFAB[CodimBox::numAI]
Definition: CodimBox.H:258
Box m_box
Definition: CodimBox.H:267
CodimBox()
Default constructor.
Definition: CodimBoxImplem.H:57
Box orientBox(const int a_iOrient) const
Definition: CodimBox.H:468