OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
OPAL
RegionLayout.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 REGION_LAYOUT_H
12 #define REGION_LAYOUT_H
13 
14 /***************************************************************************
15  * RegionLayout stores a partitioned set of NDRegion objects, to represent
16  * the parallel layout of an encompassing NDRegion. It also contains
17  * functions to find the subsets of the NDRegion partitions which intersect
18  * or touch a given NDRegion. It is similar to FieldLayout, with the
19  * following changes:
20  * 1. It uses NDRegion instead of NDIndex, so it is templated on the position
21  * data type (although it can be constructed with an NDIndex and a Mesh
22  * as well);
23  * 2. It does not contain any consideration for guard cells;
24  * 3. It can store not only the partitioned domain, but periodic copies of
25  * the partitioned domain for use by particle periodic boundary conditions
26  * 4. It also keeps a list of FieldLayoutUser's, so that it can notify them
27  * when the internal FieldLayout here is reparitioned or otherwise changed.
28  *
29  * If this is constructed with a FieldLayout, it stores a pointer to it
30  * so that if we must repartition the copy of the FieldLayout that
31  * is stored here, we will end up repartitioning all the registered Fields.
32  ***************************************************************************/
33 
34 // include files
35 #include "Region/Rnode.h"
36 #include "Index/NDIndex.h"
37 #include "DomainMap/DomainMap.h"
39 #include "Utility/Unique.h"
40 #include "Utility/UserList.h"
41 #include "Utility/vmap.h"
42 
43 #include <iostream>
44 
45 // forward declarations
46 template <unsigned Dim> class FieldLayout;
47 template <unsigned Dim, class T> class UniformCartesian;
48 template <class T, unsigned Dim, class MeshType> class RegionLayout;
49 template <class T, unsigned Dim, class MeshType>
50 std::ostream& operator<<(std::ostream&, const RegionLayout<T,Dim,MeshType>&);
51 
52 
53 // the RegionLayout class definition
54 template < class T, unsigned Dim, class MeshType=UniformCartesian<Dim,T> >
55 class RegionLayout : public FieldLayoutUser, private UserList {
56 
57 public:
58  // Typedefs for containers.
64 
65  // Typedefs for iterators.
71  typedef std::pair<touch_iterator_dv,touch_iterator_dv> touch_range_dv;
72 
73 public:
74  // Default constructor. To make this class actually work, the user
75  // will have to later call 'changeDomain' to set the proper Domain
76  // and get a new partitioning.
77  RegionLayout();
78 
79  // Copy constructor.
81 
82  // Constructors which partition the given ND, 1D, 2D, or 3D PRegions
83  RegionLayout(const NDRegion<T,Dim>& domain, MeshType& mesh, int vnodes=-1);
84  RegionLayout(const PRegion<T>& i1, MeshType& mesh, int vnodes=-1);
85  RegionLayout(const PRegion<T>& i1, const PRegion<T>& i2, MeshType& mesh,
86  int vnodes=-1);
87  RegionLayout(const PRegion<T>& i1, const PRegion<T>& i2,
88  const PRegion<T>& i3, MeshType& mesh, int vnodes=-1);
89 
90  // Constructor which takes a FieldLayout, and stores a ref to it
91  // This will assume a MeshType with unit spacing and that the domain of
92  // the MeshType is one larger in each dimension than the domain of the
93  // FieldLayout (i.e., the FieldLayout index space refers to cell-centered
94  // Field quantities).
96 
97  // Constructor which takes a FieldLayout and a MeshType
98  // This one compares the domain of the FieldLayout and the domain of
99  // the MeshType to determine the centering of the index space.
100  RegionLayout(FieldLayout<Dim>&, MeshType&);
101 
102  // Constructor which takes an NDIndex and converts it to a RegionLayout.
103  // These assume a MeshType with unit spacing and that the domain of
104  // the MeshType is one larger in each dimension than the given domain
105  // (i.e., the index space refers to cell-centered Field quantities).
106  RegionLayout(const NDIndex<Dim>& domain, int vnodes=-1);
107  RegionLayout(const Index& i1,int vnodes=-1);
108  RegionLayout(const Index& i1,const Index& i2,int vnodes=-1);
109  RegionLayout(const Index& i1,const Index& i2,const Index& i3,int vnodes=-1);
110 
111  // Constructors which take NDIndex and MeshType and convert to RegionLayout.
112  // These compare the given domain and the domain of
113  // the MeshType to determine the centering of the index space.
114  RegionLayout(const NDIndex<Dim>& domain, MeshType& mesh, int vnodes=-1);
115  RegionLayout(const Index& i1, MeshType& mesh, int vnodes=-1);
116  RegionLayout(const Index& i1, const Index& i2,MeshType& mesh,int vnodes=-1);
117  RegionLayout(const Index& i1, const Index& i2, const Index& i3,
118  MeshType& mesh, int vnodes=-1);
119 
120  // Destructor.
121  virtual ~RegionLayout();
122 
123  //
124  // accessor member functions
125  //
126 
127  // Has the domain been initialized and partitioned yet?
128  bool initialized() const { return (FLayout != 0); }
129 
130  // Return the encompassing domain.
131  const NDRegion<T,Dim>& getDomain() const { return Domain; }
132 
133  // Return the underlying FieldLayout. This is not const, since we may
134  // want to make Field's out of it (and have those Field's temporarily
135  // register themselves with this FieldLayout). We do supply a const
136  // version, however.
138  const FieldLayout<Dim>& getFieldLayout() const { return *FLayout; }
139 
140  // get the mesh
141  MeshType& getMesh() { return *theMesh; }
142  const MeshType& getMesh() const { return *theMesh; }
143 
144  // Accessors for the locals domains by Id.
145  typename ac_id_vnodes::size_type size_iv() const { return Local_ac.size(); }
147  iterator_iv end_iv() { return Local_ac.end(); }
148  const_iterator_iv begin_iv() const { return Local_ac.begin(); }
149  const_iterator_iv end_iv() const { return Local_ac.end(); }
150 
151  // Accessors for the remote vnodes themselves.
153  return (Remote_ac != 0 ? Remote_ac->size() : 0);
154  }
156  iterator_dv end_rdv() { return Remote_ac->end(); }
158  const_iterator_dv end_rdv() const { return Remote_ac->end(); }
160  return Remote_ac->touch_range(domain);
161  }
162 
163  //
164  // operator/action methods
165  //
166 
167  // Repartition the region, using the given layout as the new global
168  // domain. This is essentially the same as what occurs during construction,
169  // but may be done any time after construction.
171  void changeDomain(const NDIndex<Dim>&, int vnodes=-1);
172  void changeDomain(const NDRegion<T,Dim>&, int vnodes=-1);
173 
174  // Repartition the region, from a list of NDIndex objects which
175  // represent our local domain. This assumes two things:
176  // 1. We are repartitioning the same global domain, just in a different
177  // way. Thus, the encompassing NDRegion 'Domain' does not change.
178  // 2. The NDIndex objects cover a domain which corresponds to our
179  // internal FieldLayout domain. This may or may not directly
180  // overlap with the NDRegion domain. The basic point is that with
181  // these NDIndex objects, we can replace the FieldLayout directly,
182  // and then regenerate our RegionLayout (Rnode) data.
185  RepartitionLayout(&domain, (&domain) + 1);
186  }
187 
188  // convert a given NDIndex into an NDRegion ... if this object was
189  // constructed from a FieldLayout, this does nothing, but if we have
190  // our own internal FieldLayout, we must convert from the [0,N-1] index
191  // space to our own continuous NDRegion space.
193 
194  // perform the inverse of convert_index: convert a given NDRegion (with
195  // coordinates in the 'region' space) into an NDIndex (with values in
196  // the [0,N-1] 'index' space). This will truncate values when converting
197  // from continuous to integer data.
199 
200 #ifdef IPPL_USE_MEMBER_TEMPLATES
201  //mwerks template < unsigned D >
202  //mwerks NDRegion<T,Dim> convert_index(const NDIndex<D>&) const;
203  template < unsigned D >
205  convert_index(const NDIndex<D>& ni) const {
206  NDRegion<T,Dim> new_pregion; // Needed in TAU_TYPE_STRING
207 
208 
209 
210  PInsist(D==Dim,"Dimension of input NDIndex does not match RegionLayout!!");
211  return new_pregion;
212  }
213 
214  //mwerks template < unsigned D >
215  //mwerks NDIndex<Dim> convert_region(const NDRegion<T,D>&) const;
216  template < unsigned D >
218  convert_region(const NDRegion<T,D>& nr) const {
219  NDIndex<Dim> index;
220 
221 
222 
223  PInsist(D==Dim,"Dimension of input NDRegion does not match RegionLayout!!");
224  return index;
225  }
226 #endif
227 
228  // Compare RegionLayouts to see if they represent the same domain.
230  return Domain == x.Domain;
231  }
232 
233  //
234  // virtual functions for FieldLayoutUser's (and other UserList users)
235  //
236 
237  // Repartition onto a new layout
238  virtual void Repartition(UserList *);
239 
240  // Tell this object that an object is being deleted
241  virtual void notifyUserOfDelete(UserList *);
242 
243  //
244  // UserList operations, so that users of this RegionLayout can be
245  // kept and notified of changes to the RegionLayout. We use
246  // FieldLayoutUser as the class which must check in here for
247  // convenience, since FieldLayoutUser defines a virtual function
248  // 'Repartition' which we'll need to call for the users when this
249  // RegionLayout changes via repartitioning of itself or of it's
250  // internal FieldLayout.
251  //
252 
253  // Return our ID, as generated by UserList.
254  UserList::ID_t get_Id() const { return getUserListID(); }
255 
256  // Tell this object that a FieldLayoutUser is using it.
257  // This is different than the checkinUser from UserList, since we need
258  // a FieldLayoutUser to be stored that has a Repartition virtual function.
260 
261  // Tell this object that a FieldLayoutUser is no longer using it.
262  // This is different than the checkoutUser from UserList,
263  // for symmetry with checkin. Both of these make sure this object
264  // only allows FieldLayoutUser's to check in.
266 
267 private:
268  // The local and the remote subdomains which comprise the total domain
271 
272  // The total domain, i.e. the bounding box for the spatial region
274 
275  // A FieldLayout which is used to represent a grid over our spatial area
278 
279  // A MeshType which is used to represent a grid over our spatial area
280  MeshType *theMesh;
281  bool WeOwnMesh;
282 
283  // The number of vertices in the mesh
285 
286  // Offset from 'normal' Index space to 'Mesh' Index space
288 
289  // Offset needed between centering of Index space and Mesh points
291 
292  // The routine which actually sets things up.
293  void setup(const NDRegion<T,Dim>&, int);
294 
295  // Scan through the given FieldLayout and construct Rnodes based on
296  // the FieldLayout and NDRegion. Put them into out local
297  // and remote Rnode containers.
299 
300  // Delete the Rnodes in out local and remote lists ... actually,
301  // just returns them back to the static pool.
302  void delete_rnodes();
303 
304  // Store a layout object pointer, and note if we own it or not.
305  // Delete our current FLayout, and set it to NULL; we may have to
306  // check out from the layout
307  void store_flayout(FieldLayout<Dim>*, bool WeOwn);
308  void delete_flayout();
309 
310  // Store a mesh object pointer, and note if we own it or not.
311  // Delete our current MeshType, and set it to NULL; we may have to
312  // check out from the mesh
313  void store_mesh(MeshType*, bool WeOwn);
314  void delete_mesh();
315 
316  // Calculate the boundary region of the given mesh, and the number of
317  // vertices
318 #if defined(__MWERKS__)
319 #if __MWERKS__ < 0x2300
320  const NDRegion<T,Dim> getMeshDomain(MeshType *);
321 #else
322  NDRegion<T,Dim> getMeshDomain(MeshType *);
323 #endif
324 #else
325  // Is this really a C++ error here, or just something mwerksCW4 doesn't grok?
326  NDRegion<T,Dim> getMeshDomain(MeshType *);
327 #endif // __MWERKS__
328  NDIndex<Dim> getMeshVertices(MeshType *);
329 
330  //
331  // Rnode pool - a static pool of unused Rnode's, used to cut down on new's
332  //
333 
334  class RnodePool : public std::vector<Rnode<T,Dim> *> {
335  public:
336  // the constructor and destructor ... the destructor will clean up
337  // the storage for allocated Rnode's when the program exits
338  RnodePool() { }
340  while (this->size() > 0) {
341  delete this->back();
342  this->pop_back();
343  }
344  }
345 
346  // create a new Rnode, or get one from storage.
348  if (this->empty()) {
349  return new Rnode<T,Dim>(nr, node);
350  }
351  else {
352  Rnode<T,Dim>* rnode = this->back();
353  this->pop_back();
354  *rnode = Rnode<T,Dim>(nr, node);
355  return rnode;
356  }
357  }
358 
359  // one more version of create, also specifying an offset
361  const Vektor<T,Dim>& v,
362  int node) {
363  if (this->empty()) {
364  return new Rnode<T,Dim>(nr, v, node);
365  }
366  else {
367  Rnode<T,Dim>* rnode = this->back();
368  this->pop_back();
369  *rnode = Rnode<T,Dim>(nr, v, node);
370  return rnode;
371  }
372  }
373  };
374 
375  // a static pool of Rnodes
376  static RnodePool StaticRnodePool;
377 
378 };
379 
380 #include "Region/RegionLayout.hpp"
381 
382 #endif // REGION_LAYOUT_H
383 
384 /***************************************************************************
385  * $RCSfile: RegionLayout.h,v $ $Author: adelmann $
386  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:32 $
387  * IPPL_VERSION_ID: $Id: RegionLayout.h,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $
388  ***************************************************************************/
iterator begin()
Definition: vmap.h:125
MeshType * theMesh
Definition: RegionLayout.h:280
void delete_rnodes()
rep_type::size_type size_type
Definition: vmap.h:120
Definition: Rnode.h:30
void changeDomain(FieldLayout< Dim > &)
void checkin(FieldLayoutUser &f)
Definition: RegionLayout.h:259
FieldLayout< Dim > * FLayout
Definition: RegionLayout.h:276
const_iterator_dv end_rdv() const
Definition: RegionLayout.h:158
void setup(const NDRegion< T, Dim > &, int)
void store_mesh(MeshType *, bool WeOwn)
void make_rnodes(const NDRegion< T, Dim > &, FieldLayout< Dim > &)
const NDRegion< T, Dim > & getDomain() const
Definition: RegionLayout.h:131
virtual void Repartition(UserList *)
ID_t getUserListID() const
Definition: UserList.cpp:54
const int nr
Definition: ClassicRandom.h:24
iterator_iv begin_iv()
Definition: RegionLayout.h:146
ac_domain_vnodes * Remote_ac
Definition: RegionLayout.h:270
const_iterator_iv begin_iv() const
Definition: RegionLayout.h:148
ac_id_vnodes::iterator iterator_iv
Definition: RegionLayout.h:66
unsigned size_type
Definition: DomainMap.h:79
const_iterator_iv end_iv() const
Definition: RegionLayout.h:149
ac_domain_vnodes::touch_iterator touch_iterator_dv
Definition: RegionLayout.h:70
bool initialized() const
Definition: RegionLayout.h:128
bool WeOwnFieldLayout
Definition: RegionLayout.h:277
iterator end()
Definition: DomainMap.h:502
DomainMap< NDRegion< T, Dim >, Rnode< T, Dim > *, TouchesRegion< T, Dim >, ContainsRegion< T, Dim >, SplitRegion< T, Dim > > ac_domain_vnodes
Definition: RegionLayout.h:63
NDIndex< Dim > getMeshVertices(MeshType *)
ac_id_vnodes::size_type size_iv() const
Definition: RegionLayout.h:145
static RnodePool StaticRnodePool
Definition: RegionLayout.h:376
Definition: Index.h:236
bool CenterOffset[Dim]
Definition: RegionLayout.h:290
ac_domain_vnodes::size_type size_rdv() const
Definition: RegionLayout.h:152
NDIndex< Dim > MeshVertices
Definition: RegionLayout.h:284
bool operator==(const RegionLayout< T, Dim, MeshType > &x)
Definition: RegionLayout.h:229
const FieldLayout< Dim > & getFieldLayout() const
Definition: RegionLayout.h:138
ac_id_vnodes Local_ac
Definition: RegionLayout.h:269
int IndexOffset[Dim]
Definition: RegionLayout.h:287
void RepartitionLayout(NDIndex< Dim > &domain)
Definition: RegionLayout.h:184
virtual ~RegionLayout()
iterator_iv end_iv()
Definition: RegionLayout.h:147
iterator_dv end_rdv()
Definition: RegionLayout.h:156
Rnode< T, Dim > * create_rnode(const NDRegion< T, Dim > &nr, int node)
Definition: RegionLayout.h:347
NDRegion< T, Dim > convert_index(const NDIndex< Dim > &) const
iterator begin()
Definition: DomainMap.h:501
NDRegion< T, Dim > getMeshDomain(MeshType *)
UserList::ID_t get_Id() const
Definition: RegionLayout.h:254
void delete_flayout()
std::pair< touch_iterator, touch_iterator > touch_range(const Key &t) const
Definition: DomainMap.hpp:103
void checkout(FieldLayoutUser &f)
Definition: RegionLayout.h:265
iterator_dv begin_rdv()
Definition: RegionLayout.h:155
const MeshType & getMesh() const
Definition: RegionLayout.h:142
virtual void notifyUserOfDelete(UserList *)
virtual void checkoutUser(Key key, bool informuser=false)
Definition: UserList.cpp:124
void delete_mesh()
ac_id_vnodes::const_iterator const_iterator_iv
Definition: RegionLayout.h:67
const_iterator_dv begin_rdv() const
Definition: RegionLayout.h:157
NDRegion< T, Dim > Domain
Definition: RegionLayout.h:273
MeshType & getMesh()
Definition: RegionLayout.h:141
touch_range_dv touch_range_rdv(const NDRegion< T, Dim > &domain)
Definition: RegionLayout.h:159
FieldLayout< Dim > & getFieldLayout()
Definition: RegionLayout.h:137
void RepartitionLayout(NDIndex< Dim > *, NDIndex< Dim > *)
size_type size() const
Definition: vmap.h:138
#define PInsist(c, m)
Definition: PAssert.h:135
const unsigned Dim
std::pair< touch_iterator_dv, touch_iterator_dv > touch_range_dv
Definition: RegionLayout.h:71
Rnode< T, Dim > * create_rnode(const NDRegion< T, Dim > &nr, const Vektor< T, Dim > &v, int node)
Definition: RegionLayout.h:360
vmap< Unique::type, Rnode< T, Dim > * > ac_id_vnodes
Definition: RegionLayout.h:59
NDIndex< Dim > convert_region(const NDRegion< T, Dim > &) const
virtual ID_t checkinUser(User &user)
Definition: UserList.cpp:109
size_type size() const
Definition: DomainMap.h:514
User::ID_t ID_t
Definition: UserList.h:46
ac_domain_vnodes::iterator iterator_dv
Definition: RegionLayout.h:68
ac_domain_vnodes::const_iterator const_iterator_dv
Definition: RegionLayout.h:69
rep_type::const_iterator const_iterator
Definition: vmap.h:117
iterator end()
Definition: vmap.h:126
Definition: vmap.h:65
void store_flayout(FieldLayout< Dim > *, bool WeOwn)