OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
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  // Compare RegionLayouts to see if they represent the same domain.
202  return Domain == x.Domain;
203  }
204 
205  //
206  // virtual functions for FieldLayoutUser's (and other UserList users)
207  //
208 
209  // Repartition onto a new layout
210  virtual void Repartition(UserList *);
211 
212  // Tell this object that an object is being deleted
213  virtual void notifyUserOfDelete(UserList *);
214 
215  //
216  // UserList operations, so that users of this RegionLayout can be
217  // kept and notified of changes to the RegionLayout. We use
218  // FieldLayoutUser as the class which must check in here for
219  // convenience, since FieldLayoutUser defines a virtual function
220  // 'Repartition' which we'll need to call for the users when this
221  // RegionLayout changes via repartitioning of itself or of it's
222  // internal FieldLayout.
223  //
224 
225  // Return our ID, as generated by UserList.
226  UserList::ID_t get_Id() const { return getUserListID(); }
227 
228  // Tell this object that a FieldLayoutUser is using it.
229  // This is different than the checkinUser from UserList, since we need
230  // a FieldLayoutUser to be stored that has a Repartition virtual function.
232 
233  // Tell this object that a FieldLayoutUser is no longer using it.
234  // This is different than the checkoutUser from UserList,
235  // for symmetry with checkin. Both of these make sure this object
236  // only allows FieldLayoutUser's to check in.
238 
239 private:
240  // The local and the remote subdomains which comprise the total domain
243 
244  // The total domain, i.e. the bounding box for the spatial region
246 
247  // A FieldLayout which is used to represent a grid over our spatial area
250 
251  // A MeshType which is used to represent a grid over our spatial area
252  MeshType *theMesh;
253  bool WeOwnMesh;
254 
255  // The number of vertices in the mesh
257 
258  // Offset from 'normal' Index space to 'Mesh' Index space
260 
261  // Offset needed between centering of Index space and Mesh points
263 
264  // The routine which actually sets things up.
265  void setup(const NDRegion<T,Dim>&, int);
266 
267  // Scan through the given FieldLayout and construct Rnodes based on
268  // the FieldLayout and NDRegion. Put them into out local
269  // and remote Rnode containers.
271 
272  // Delete the Rnodes in out local and remote lists ... actually,
273  // just returns them back to the static pool.
274  void delete_rnodes();
275 
276  // Store a layout object pointer, and note if we own it or not.
277  // Delete our current FLayout, and set it to NULL; we may have to
278  // check out from the layout
279  void store_flayout(FieldLayout<Dim>*, bool WeOwn);
280  void delete_flayout();
281 
282  // Store a mesh object pointer, and note if we own it or not.
283  // Delete our current MeshType, and set it to NULL; we may have to
284  // check out from the mesh
285  void store_mesh(MeshType*, bool WeOwn);
286  void delete_mesh();
287 
288  // Calculate the boundary region of the given mesh, and the number of
289  // vertices
290  // Is this really a C++ error here, or just something mwerksCW4 doesn't grok?
291  NDRegion<T,Dim> getMeshDomain(MeshType *);
292  NDIndex<Dim> getMeshVertices(MeshType *);
293 
294  //
295  // Rnode pool - a static pool of unused Rnode's, used to cut down on new's
296  //
297 
298  class RnodePool : public std::vector<Rnode<T,Dim> *> {
299  public:
300  // the constructor and destructor ... the destructor will clean up
301  // the storage for allocated Rnode's when the program exits
302  RnodePool() { }
304  while (this->size() > 0) {
305  delete this->back();
306  this->pop_back();
307  }
308  }
309 
310  // create a new Rnode, or get one from storage.
312  if (this->empty()) {
313  return new Rnode<T,Dim>(nr, node);
314  }
315  else {
316  Rnode<T,Dim>* rnode = this->back();
317  this->pop_back();
318  *rnode = Rnode<T,Dim>(nr, node);
319  return rnode;
320  }
321  }
322 
323  // one more version of create, also specifying an offset
325  const Vektor<T,Dim>& v,
326  int node) {
327  if (this->empty()) {
328  return new Rnode<T,Dim>(nr, v, node);
329  }
330  else {
331  Rnode<T,Dim>* rnode = this->back();
332  this->pop_back();
333  *rnode = Rnode<T,Dim>(nr, v, node);
334  return rnode;
335  }
336  }
337  };
338 
339  // a static pool of Rnodes
341 
342 };
343 
344 #include "Region/RegionLayout.hpp"
345 
346 #endif // REGION_LAYOUT_H
347 
348 /***************************************************************************
349  * $RCSfile: RegionLayout.h,v $ $Author: adelmann $
350  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:32 $
351  * IPPL_VERSION_ID: $Id: RegionLayout.h,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $
352  ***************************************************************************/
const int nr
Definition: ClassicRandom.h:24
const unsigned Dim
std::ostream & operator<<(std::ostream &, const RegionLayout< T, Dim, MeshType > &)
iterator end()
Definition: DomainMap.h:497
unsigned size_type
Definition: DomainMap.h:75
size_type size() const
Definition: DomainMap.h:509
std::pair< touch_iterator, touch_iterator > touch_range(const Key &t) const
Definition: DomainMap.hpp:102
iterator begin()
Definition: DomainMap.h:496
Definition: Index.h:237
NDIndex< Dim > MeshVertices
Definition: RegionLayout.h:256
void RepartitionLayout(NDIndex< Dim > &domain)
Definition: RegionLayout.h:184
bool initialized() const
Definition: RegionLayout.h:128
void delete_mesh()
void changeDomain(FieldLayout< Dim > &)
void setup(const NDRegion< T, Dim > &, int)
void RepartitionLayout(NDIndex< Dim > *, NDIndex< Dim > *)
const NDRegion< T, Dim > & getDomain() const
Definition: RegionLayout.h:131
ac_domain_vnodes::iterator iterator_dv
Definition: RegionLayout.h:68
const_iterator_iv begin_iv() const
Definition: RegionLayout.h:148
void make_rnodes(const NDRegion< T, Dim > &, FieldLayout< Dim > &)
ac_domain_vnodes::const_iterator const_iterator_dv
Definition: RegionLayout.h:69
iterator_dv begin_rdv()
Definition: RegionLayout.h:155
MeshType * theMesh
Definition: RegionLayout.h:252
iterator_iv begin_iv()
Definition: RegionLayout.h:146
const_iterator_dv end_rdv() const
Definition: RegionLayout.h:158
bool operator==(const RegionLayout< T, Dim, MeshType > &x)
Definition: RegionLayout.h:201
static RnodePool StaticRnodePool
Definition: RegionLayout.h:340
iterator_dv end_rdv()
Definition: RegionLayout.h:156
NDRegion< T, Dim > getMeshDomain(MeshType *)
NDIndex< Dim > convert_region(const NDRegion< T, Dim > &) const
const_iterator_iv end_iv() const
Definition: RegionLayout.h:149
NDRegion< T, Dim > convert_index(const NDIndex< Dim > &) const
ac_id_vnodes::size_type size_iv() const
Definition: RegionLayout.h:145
NDRegion< T, Dim > Domain
Definition: RegionLayout.h:245
virtual void notifyUserOfDelete(UserList *)
touch_range_dv touch_range_rdv(const NDRegion< T, Dim > &domain)
Definition: RegionLayout.h:159
ac_id_vnodes::const_iterator const_iterator_iv
Definition: RegionLayout.h:67
ac_domain_vnodes::size_type size_rdv() const
Definition: RegionLayout.h:152
ac_id_vnodes::iterator iterator_iv
Definition: RegionLayout.h:66
virtual void Repartition(UserList *)
FieldLayout< Dim > * FLayout
Definition: RegionLayout.h:248
vmap< Unique::type, Rnode< T, Dim > * > ac_id_vnodes
Definition: RegionLayout.h:59
DomainMap< NDRegion< T, Dim >, Rnode< T, Dim > *, TouchesRegion< T, Dim >, ContainsRegion< T, Dim >, SplitRegion< T, Dim > > ac_domain_vnodes
Definition: RegionLayout.h:63
const MeshType & getMesh() const
Definition: RegionLayout.h:142
ac_id_vnodes Local_ac
Definition: RegionLayout.h:241
void checkin(FieldLayoutUser &f)
Definition: RegionLayout.h:231
UserList::ID_t get_Id() const
Definition: RegionLayout.h:226
virtual ~RegionLayout()
iterator_iv end_iv()
Definition: RegionLayout.h:147
ac_domain_vnodes::touch_iterator touch_iterator_dv
Definition: RegionLayout.h:70
bool WeOwnFieldLayout
Definition: RegionLayout.h:249
MeshType & getMesh()
Definition: RegionLayout.h:141
std::pair< touch_iterator_dv, touch_iterator_dv > touch_range_dv
Definition: RegionLayout.h:71
void delete_rnodes()
NDIndex< Dim > getMeshVertices(MeshType *)
const FieldLayout< Dim > & getFieldLayout() const
Definition: RegionLayout.h:138
ac_domain_vnodes * Remote_ac
Definition: RegionLayout.h:242
bool CenterOffset[Dim]
Definition: RegionLayout.h:262
FieldLayout< Dim > & getFieldLayout()
Definition: RegionLayout.h:137
const_iterator_dv begin_rdv() const
Definition: RegionLayout.h:157
void delete_flayout()
void checkout(FieldLayoutUser &f)
Definition: RegionLayout.h:237
int IndexOffset[Dim]
Definition: RegionLayout.h:259
void store_flayout(FieldLayout< Dim > *, bool WeOwn)
void store_mesh(MeshType *, bool WeOwn)
Rnode< T, Dim > * create_rnode(const NDRegion< T, Dim > &nr, const Vektor< T, Dim > &v, int node)
Definition: RegionLayout.h:324
Rnode< T, Dim > * create_rnode(const NDRegion< T, Dim > &nr, int node)
Definition: RegionLayout.h:311
Definition: Rnode.h:30
ID_t getUserListID() const
Definition: UserList.cpp:54
virtual void checkoutUser(Key key, bool informuser=false)
Definition: UserList.cpp:124
User::ID_t ID_t
Definition: UserList.h:46
virtual ID_t checkinUser(User &user)
Definition: UserList.cpp:109
Definition: vmap.h:59
rep_type::iterator iterator
Definition: vmap.h:98
size_type size() const
Definition: vmap.h:120
rep_type::size_type size_type
Definition: vmap.h:102
iterator end()
Definition: vmap.h:108
iterator begin()
Definition: vmap.h:107
rep_type::const_iterator const_iterator
Definition: vmap.h:99