Chombo + EB + MF  3.2
ListBoxI.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 // ANAG, LBNL
12 
13 #ifndef _LISTBOXI_H_
14 #define _LISTBOXI_H_
15 
16 #include "Arena.H"
17 #include "BoxIterator.H"
18 #include <iostream>
19 #include "parstream.H"
20 #include "NamespaceHeader.H"
21 
22 //
23 // Implementation
24 //
25 
26 template <class T>
28  :
29  m_box(Box()),
30  m_dptr(0),
31  m_mesh_spacing(D_DECL6(0, 0, 0, 0, 0, 0)),
32  m_origin(D_DECL6(0, 0, 0, 0, 0, 0))
33 {}
34 
35 template <class T>
36 ListBox<T>::ListBox(const Box& a_box,
37  const RealVect& a_meshSpacing,
38  const RealVect& a_origin)
39  :
40  m_dptr(0)
41 {
42  define(a_box, a_meshSpacing, a_origin);
43 }
44 
45 template <class T>
47 
48 template <class T>
50 {
51  undefine();
52 }
53 
54 template <class T>
55 void ListBox<T>::define(const Box& a_box,
56  const RealVect& a_meshSpacing,
57  const RealVect& a_origin)
58 {
59 
60  CH_assert(m_dptr == 0);
61 
62 #ifdef CH_USE_MEMORY_TRACKING
63  if (this->s_Arena == NULL)
64  {
65  this->s_Arena = new BArena(this->name().c_str());
66  }
67 #else
68  if (this->s_Arena == NULL)
69  {
70  this->s_Arena = new BArena("");
71  }
72 #endif
73 
74  if (this->s_Arena == NULL)
75  {
76  MayDay::Error("Malloc in ListBox failed");
77  }
78 
79  // allocate our list
80  this->m_dptr =
81  static_cast<List<T>*>(this->s_Arena->alloc(sizeof(List<T>)));
82 
83 #ifdef CH_USE_MEMORY_TRACKING
84  this->s_Arena->bytes += sizeof(List<T>) + sizeof(ListBox<T>);
85  if (this->s_Arena->bytes > this->s_Arena->peak)
86  {
87  this->s_Arena->peak = this->s_Arena->bytes;
88  }
89 #endif
90 
91  new (m_dptr) List<T>;
92 
93  m_box = a_box;
94  m_mesh_spacing = a_meshSpacing;
95  m_origin = a_origin;
96 }
97 
98 template <class T>
100 {
101 
102  if (m_dptr == 0)
103  {
104  return;
105  }
106 
107  m_dptr->~List<T>();
108 
109  s_Arena->free(m_dptr);
110 
111 #ifdef CH_USE_MEMORY_TRACKING
112  s_Arena->bytes -= sizeof(List<T>) + sizeof(ListBox<T>);
113  CH_assert(s_Arena->bytes >= 0);
114 #endif
115 
116  m_dptr = 0;
117 }
118 
119 // retrieve list of items
120 template <class T>
122 {
123  CH_assert(!(this->m_dptr == NULL));
124 
125  return *(static_cast<List<T>*>(this->m_dptr));
126 }
127 
128 template <class T>
130 {
131  CH_assert(!(this->m_dptr == NULL));
132 
133  return *(static_cast<List<T>*>(this->m_dptr));
134 }
135 
136 template <class T>
137 void ListBox<T>::getItems(List<T>& a_list, const Box& a_valid) const
138 {
139  CH_assert(!(this->m_dptr == NULL));
140 
141  if (a_valid == m_box)
142  {
143  a_list.join( listItems() );
144  }
145  else
146  {
147  for (ListIterator<T> li( listItems() ); li; ++li)
148  {
149  // loop through items
150  if ( isEnclosed(li(), a_valid) )
151  {
152  a_list.add(*li);
153  }
154  }
155  }
156 }
157 
158 template <class T>
159 void ListBox<T>::getItemsDestructive(List<T>& a_list, const Box& a_valid)
160 {
161  CH_assert(!(this->m_dptr == NULL));
162 
163  if (a_valid == m_box)
164  {
165  a_list.catenate( listItems() );
166  }
167  else
168  {
169  // loop through items, and add to rlist
170  for (ListIterator<T> li( listItems() ); li; )
171  {
172  // const RealVect& x = items[li].position();
173  if ( isEnclosed(li(),a_valid) )
174  {
175  a_list.transfer(li);
176  }
177  else
178  {
179  // removing a list element has the side-effect of moving
180  // the iterator forward, so only increment explicitly if
181  // not removed
182  ++li;
183  }
184  }
185  }
186 }
187 
188 template <class T>
189 void ListBox<T>::getInvalid(List<T>& a_list, const Box& a_valid) const
190 {
191  CH_assert(!(this->m_dptr == NULL));
192 
193  for (ListIterator<T> li( listItems() ); li; ++li)
194  {
195  // loop through items
196  if ( !isEnclosed(li(), a_valid) )
197  {
198  a_list.add(*li);
199  }
200  }
201 }
202 
203 template <class T>
204 void ListBox<T>::getInvalidDestructive(List<T>& a_list, const Box& a_valid)
205 {
206  CH_assert(!(this->m_dptr == NULL));
207 
208  // loop through items, and add to rlist
209  for (ListIterator<T> li( listItems() ); li; )
210  {
211  if ( !isEnclosed(li(),a_valid) )
212  {
213  a_list.transfer(li);
214  }
215  else
216  {
217  // removing a list element has the side-effect of moving
218  // the iterator forward, so only increment explicitly if
219  // not removed
220  ++li;
221  }
222  }
223 }
224 
225 template <class T>
226 void ListBox<T>::addItem(const T& a_item)
227 {
228  if ( isEnclosed(a_item, m_box) )
229  {
230  listItems().add(a_item);
231  }
232 }
233 
234 template <class T>
235 void ListBox<T>::addItems(const List<T>& a_list)
236 {
237  if (a_list.isNotEmpty())
238  {
239  List<T>& litems = listItems();
240 
241  for (ListIterator<T> li(a_list); li.ok(); ++li)
242  {
243  if ( isEnclosed(li(), m_box) )
244  {
245  litems.add(*li);
246  }
247  }
248  }
249 }
250 
251 template <class T>
253 {
254  addItemsDestructive(a_list, m_box);
255 }
256 
257 template <class T>
258 void ListBox<T>::addItemsDestructive(List<T>& a_list, const Box& a_valid)
259 {
260  if (a_list.isNotEmpty())
261  {
262  List<T>& litems = listItems();
263 
264  for (ListIterator<T> li(a_list); li; )
265  {
266  if ( isEnclosed(li(), a_valid) )
267  {
268  litems.transfer(li);
269  }
270  else
271  {
272  ++li;
273  }
274  }
275  }
276 }
277 
278 template <class T>
280  const Box& a_srcBox,
281  const Box& a_destBox,
282  const int a_srcComp,
283  const int a_destComp,
284  const int a_numComp)
285 {
286 
287  // avoid self-transfering
288  if (this->m_dptr != a_src.m_dptr)
289  {
290  CH_assert(a_destBox.sameSize(a_srcBox));
291  CH_assert(this->m_box.contains(a_destBox));
292 
293  // when transfering particles don't check destination box because that
294  // can't always be right before applying BCs
295  a_src.getItemsDestructive(listItems(), a_srcBox);
296  }
297 }
298 
299 template <class T>
300 void ListBox<T>::copy(const Box& a_RegionFrom,
301  const Interval& a_Cdest,
302  const Box& a_RegionTo,
303  const ListBox<T>& a_src,
304  const Interval& a_Csrc)
305 {
306  // remove the items from this ListBox that are within a_RegionTo
307  getItemsDestructive(listItems(), a_RegionTo);
308  List<T> tmpList;
309  a_src.getItems(tmpList, a_RegionFrom);
310  addItemsDestructive(tmpList, a_RegionTo);
311 }
312 
313 template <class T>
314 size_t ListBox<T>::numItems() const
315 {
316  return listItems().length();
317 }
318 
319 template <class T>
320 size_t ListBox<T>::numItems(const Box& a_box, const bool a_in) const
321 {
322 
323  if (a_in)
324  {
325  if (a_box.isEmpty())
326  {
327  return 0;
328  }
329  else
330  {
331  size_t nitems = 0;
332  for (ListIterator<T> li( listItems() ); li.ok(); ++li)
333  {
334  if ( isEnclosed(li(), a_box) ) ++nitems;
335  }
336  return nitems;
337  }
338  }
339  else
340  {
341  if (a_box.isEmpty())
342  {
343  return numItems();
344  }
345  else
346  {
347  size_t nitems = 0;
348  for (ListIterator<T> li( listItems() ); li.ok(); ++li)
349  {
350  if ( !isEnclosed(li(), a_box) ) ++nitems;
351  }
352  return nitems;
353  }
354  }
355 }
356 
357 // The number of bytes used by linearIn()/linearOut().
358 template <class T>
359 int ListBox<T>::size(const Box& a_box,
360  const Interval& a_comps) const
361 {
362  // total size = num_items * size_item + integer
363  // the integer is to determine how many items to transfer
364 
365  const int totalSize = numItems(a_box) * T().size() + sizeof(size_t);
366 
367  return totalSize;
368 }
369 
370 template <class T> void
372  const Box& a_box,
373  const Interval& a_comps) const
374 {
375  // all we do in this function is loop over the list (ignore components),
376  // and call linearOut on the individual items...
377 
378  // size of template object
379  const size_t tsize = T().size();
380 
381  // cast buffer to a char*
382  char* ch_buf = (char*)a_buf;
383 
384  // call functions with box argument
385  List<T> items;
386  getItems(items,a_box);
387 
388  *(size_t*)ch_buf = items.length();
389  ch_buf += sizeof(size_t);
390 
391  for (ListIterator<T> li(items); li; ++li)
392  {
393  li().linearOut(ch_buf);
394  ch_buf += tsize;
395  }
396 }
397 
398 template <class T> void
400  const Box& a_box,
401  const Interval& a_comps)
402 {
403  // all we do in this function is loop over the box (ignore components),
404  // and call linearOut on the individual items...
405 
406  // size of template object
407  const size_t tsize = T().size();
408 
409  // cast buffer to a char*
410  char* ch_buf = (char*)a_buf;
411 
412  // call functions with box argument
413  List<T> items;
414  getItemsDestructive(items,a_box);
415 
416  *(size_t*)ch_buf = items.length();
417  ch_buf += sizeof(size_t);
418 
419  for (ListIterator<T> li(items); li; ++li)
420  {
421  li().linearOut(ch_buf);
422  ch_buf += tsize;
423  }
424 }
425 
426 template <class T>
427 void ListBox<T>::linearIn(void* a_buf,
428  const Box& a_box,
429  const Interval& a_comps)
430 {
431  // size of template object
432  const size_t tsize = T().size();
433 
434  // should be just the inverse of linearOut
435  char* ch_buf = (char*)a_buf;
436 
437  List<T>& items = listItems();
438 
439  size_t numItems = *((size_t*)ch_buf);
440  ch_buf += sizeof(size_t);
441 
442  for (size_t i=0; i<numItems; i++)
443  {
444  T item;
445  item.linearIn( ch_buf );
446 
447  // assume care has been taken to ensure the item is inside
448  // m_box. Check this below when debugging.
449  items.append(item);
450 
451  ch_buf += tsize;
452  }
453 }
454 
455 template <class T>
457 {
458  return m_mesh_spacing;
459 }
460 
461 template <class T>
462 const Box& ListBox<T>::box() const
463 {
464  return m_box;
465 }
466 
467 template <class T>
469 {
470  this->undefine();
471 
472  m_box = Box();
475 }
476 
477 template <class T>
478 inline std::string ListBox<T>::name()
479 {
480  std::string rtn = (typeid(T)).name();
481 
482  return rtn;
483 }
484 
485 template <class T>
486 bool ListBox<T>::isEnclosed(const T& a_item, const Box& a_box) const
487 {
488  // corners of valid region
489  const IntVect& loEnd = a_box.smallEnd();
490  const IntVect& hiEnd = a_box.bigEnd();
491 
492  // item position
493  const RealVect& x = a_item.position() - m_origin;
494  const RealVect& dx= m_mesh_spacing;
495 
496  bool is_in = D_TERM6( (x[0]>=loEnd[0]*dx[0] && x[0]<(hiEnd[0]+1)*dx[0]),
497  && (x[1]>=loEnd[1]*dx[1] && x[1]<(hiEnd[1]+1)*dx[1]),
498  && (x[2]>=loEnd[2]*dx[2] && x[2]<(hiEnd[2]+1)*dx[2]),
499  && (x[3]>=loEnd[3]*dx[3] && x[3]<(hiEnd[3]+1)*dx[3]),
500  && (x[4]>=loEnd[4]*dx[4] && x[4]<(hiEnd[4]+1)*dx[4]),
501  && (x[5]>=loEnd[5]*dx[5] && x[5]<(hiEnd[5]+1)*dx[5]));
502 
503  return is_in;
504 }
505 
506 #include "NamespaceFooter.H"
507 
508 #endif
#define D_DECL6(a, b, c, d, e, f)
Definition: CHArray.H:39
void catenate(List< T > &src)
Appends a copy of all items in List<T> src to this List<T>.
Definition: ListImplem.H:211
RealVect m_mesh_spacing
The cell size in physical space.
Definition: ListBox.H:181
List< T > & listItems()
Returns the list of items contained in this ListBox.
Definition: ListBoxI.H:121
IntVect size() const
as in BaseFab; needed for loop-unroll macro
Definition: ListBox.H:163
#define D_TERM6(a, b, c, d, e, f)
Definition: CHArray.H:40
virtual void transfer(ListBox< T > &a_src, const Box &a_srcBox, const Box &a_destBox, const int a_srcComp=0, const int a_destComp=0, const int a_numComp=1)
Definition: ListBoxI.H:279
#define CH_assert(cond)
Definition: CHArray.H:37
virtual void addItems(const List< T > &a_list)
Definition: ListBoxI.H:235
Definition: ListBox.H:31
void transfer(ListIterator< T > &lit)
Transfer the object pointed to by lit from the List<T> lit is associated with to this one...
Definition: ListImplem.H:317
Box m_box
The Box that defines the valid region of this ListBox.
Definition: ListBox.H:175
bool sameSize(const Box &b) const
Definition: Box.H:1912
virtual void linearOut(void *a_buf, const Box &a_box, const Interval &a_comps=Interval()) const
Write a serialized (packed) representation into a_buf.
Definition: ListBoxI.H:371
void append(const T &value)
Adds a copy of the value to the end of the List<T>.
Definition: List.H:582
bool contains(const IntVect &p) const
Definition: Box.H:1887
virtual bool isEnclosed(const T &a_item, const Box &a_box) const
Determines whether a_item is enclosed in a_box.
Definition: ListBoxI.H:486
RealVect m_origin
The center of our coordinate system. Used for binning our items.
Definition: ListBox.H:184
A Concrete Class for Dynamic Memory Management.
Definition: Arena.H:124
virtual void * alloc(size_t a_sz)=0
void join(const List< T > &src)
Appends a copy of all items in List<T> src to this List<T>.
Definition: ListImplem.H:203
virtual void define(const Box &a_box, const RealVect &a_meshSpacing, const RealVect &a_origin)
Same as the constructor.
Definition: ListBoxI.H:55
bool ok() const
Return true if the iterator is not past the end of the list.
Definition: List.H:465
virtual void free(void *a_pt)=0
const IntVect & bigEnd() const
Definition: Box.H:1784
static const RealVect Zero
Definition: RealVect.H:421
virtual ~ListBox()
Destructor.
Definition: ListBoxI.H:49
virtual void undefine()
Free the memory associated with this ListBox.
Definition: ListBoxI.H:99
Structure for passing component ranges in code.
Definition: Interval.H:23
A Doubly-Linked List Class.
Definition: List.H:21
Iterator over a List.
Definition: List.H:20
void add(const T &value)
Adds a copy of the value to the end of the List<T>.
Definition: ListImplem.H:49
const IntVect & smallEnd() const
{ Accessors}
Definition: Box.H:1770
A Virtual Base Class for Dynamic Memory Managemen.
Definition: Arena.H:40
virtual void getItemsDestructive(List< T > &a_list, const Box &a_valid)
Definition: ListBoxI.H:159
const Box & box() const
Retrieve the box.
Definition: ListBoxI.H:462
ListBox()
Null constructor.
Definition: ListBoxI.H:27
virtual void clear()
Delete all items in this ListBox and reset it to the null Box.
Definition: ListBoxI.H:468
bool isNotEmpty() const
Returns true if the List<T> is not empty.
Definition: List.H:627
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.
static Arena * s_Arena
Definition: ListBox.H:170
A Rectangular Domain on an Integer Lattice.
Definition: Box.H:469
A Real vector in SpaceDim-dimensional space.
Definition: RealVect.H:41
virtual void getInvalidDestructive(List< T > &a_list, const Box &a_valid)
Definition: ListBoxI.H:204
int length() const
Returns the number of objects in the List<T>.
Definition: ListImplem.H:56
static std::string name()
Definition: ListBoxI.H:478
virtual const RealVect & meshSpacing() const
Retrieve the mesh size.
Definition: ListBoxI.H:456
virtual void addItem(const T &a_item)
Add a_item to this ListBox if it is contained within m_box.
Definition: ListBoxI.H:226
virtual void addItemsDestructive(List< T > &a_list)
Definition: ListBoxI.H:252
An integer Vector in SpaceDim-dimensional space.
Definition: CHArray.H:42
virtual void linearOutDestructive(void *buf, const Box &a_box, const Interval &a_comps=Interval())
Definition: ListBoxI.H:399
virtual size_t numItems() const
Return the number of items in this ListBox.
Definition: ListBoxI.H:314
virtual void getInvalid(List< T > &a_list, const Box &a_valid) const
Definition: ListBoxI.H:189
bool isEmpty() const
{ Comparison Functions}
Definition: Box.H:1862
List< T > * m_dptr
Pointer to the List that stores our items.
Definition: ListBox.H:178
virtual void getItems(List< T > &a_list, const Box &a_valid) const
Definition: ListBoxI.H:137
virtual void copy(const Box &a_RegionFrom, const Interval &a_Cdest, const Box &a_RegionTo, const ListBox< T > &a_src, const Interval &a_Csrc)
Definition: ListBoxI.H:300
virtual void linearIn(void *a_buf, const Box &a_box, const Interval &a_comps=Interval())
Extract a serialized (packed) representation from a_buf.
Definition: ListBoxI.H:427