OPAL (Object Oriented Parallel Accelerator Library)  2021.1.99
OPAL
RegionLayout.hpp
Go to the documentation of this file.
1 // -*- C++ -*-
2 /***************************************************************************
3  *
4  * The IPPL Framework
5  *
6  * This program was prepared by PSI.
7  * All rights in the program are reserved by PSI.
8  * Neither PSI nor the author(s)
9  * makes any warranty, express or implied, or assumes any liability or
10  * responsibility for the use of this software
11  *
12  * Visit www.amas.web.psi for more details
13  *
14  ***************************************************************************/
15 
16 // -*- C++ -*-
17 /***************************************************************************
18  *
19  * The IPPL Framework
20  *
21  *
22  * Visit http://people.web.psi.ch/adelmann/ for more details
23  *
24  ***************************************************************************/
25 
26 // include files
27 #include "Region/RegionLayout.h"
28 #include "Region/Rnode.h"
29 #include "Index/NDIndex.h"
30 #include "Field/GuardCellSizes.h"
32 #include "Utility/PAssert.h"
33 #include "Utility/IpplInfo.h"
34 
35 
36 // static RegionLayout members
37 template < class T, unsigned Dim, class MeshType >
40 
41 
43 // default constructor
44 template < class T, unsigned Dim, class MeshType >
46 
47 
48 
49  for (unsigned d=0; d < Dim; ++d) {
50  IndexOffset[d] = 0;
51  CenterOffset[d] = 0;
52  }
53 
54  Remote_ac = 0;
55  // store_mesh(0, true);
56  // store_flayout(0, true);
57  // Initialize the data members directly,
58  // to avoid problems with non-zero default values of pointers
59  theMesh = 0;
60  WeOwnMesh = true;
61  FLayout = 0;
62  WeOwnFieldLayout = true;
63 }
64 
66 // copy constructor
67 template < class T, unsigned Dim, class MeshType >
69 
70 
71 
72  for (unsigned d=0; d < Dim; ++d) {
73  IndexOffset[d] = r.IndexOffset[d];
74  CenterOffset[d] = r.CenterOffset[d];
75  }
76 
77  FLayout = 0;
78  theMesh = 0;
79  Remote_ac = 0;
80 
81  if (r.WeOwnMesh) {
82  // make local copy of mesh
83  store_mesh(new MeshType(*(r.theMesh)), true);
84  } else {
85  // just copy the pointer
86  store_mesh(r.theMesh, false);
87  }
88 
89  if (r.WeOwnFieldLayout)
90  changeDomain(r.Domain, r.size_iv() + r.size_rdv());
91  else
92  changeDomain(*((FieldLayout<Dim> *)(r.FLayout)));
93 }
94 
95 
97 // destructor
98 template < class T, unsigned Dim, class MeshType >
100 
101 
102 
103  // delete all our existing rnodes
104  delete_rnodes();
105 
106  // delete the FieldLayout
107  delete_flayout();
108 
109  // delete the mesh
110  delete_mesh();
111 }
112 
113 
115 // constructor for an N-Dimensional PRegion
116 template < class T, unsigned Dim, class MeshType >
118  MeshType& mesh, int vnodes) {
119 
120 
121 
122  FLayout = 0;
123  theMesh = 0;
124  Remote_ac = 0;
125  store_mesh(&mesh, false);
126  changeDomain(domain, vnodes);
127 }
128 
130 // constructor for just a 1-D PRegion
131 template < class T, unsigned Dim, class MeshType >
133  MeshType& mesh, int vnodes) {
134 
135 
136 
137  PInsist(Dim==1,
138  "Number of PRegion arguments does not match RegionLayout dimension!!");
139  FLayout = 0;
140  theMesh = 0;
141  Remote_ac = 0;
142  store_mesh(&mesh, false);
143  NDRegion<T,Dim> dom;
144  dom[0] = i1;
145  changeDomain(dom, vnodes);
146 }
147 
149 // constructor for just a 2-D PRegion
150 template < class T, unsigned Dim, class MeshType >
152  const PRegion<T>& i2,
153  MeshType& mesh,
154  int vnodes) {
155 
156 
157  PInsist(Dim==2,
158  "Number of PRegion arguments does not match RegionLayout dimension!!");
159  FLayout = 0;
160  theMesh = 0;
161  Remote_ac = 0;
162  store_mesh(&mesh, false);
163  NDRegion<T,Dim> dom;
164  dom[0] = i1;
165  dom[1] = i2;
166  changeDomain(dom, vnodes);
167 }
168 
170 // constructor for just a 3-D PRegion
171 template < class T, unsigned Dim, class MeshType >
173  const PRegion<T>& i2,
174  const PRegion<T>& i3,
175  MeshType& mesh,
176  int vnodes) {
177 
178  PInsist(Dim==3,
179  "Number of PRegion arguments does not match RegionLayout dimension!!");
180  FLayout = 0;
181  theMesh = 0;
182  Remote_ac = 0;
183  store_mesh(&mesh, false);
184  NDRegion<T,Dim> dom;
185  dom[0] = i1;
186  dom[1] = i2;
187  dom[2] = i3;
188  changeDomain(dom, vnodes);
189 }
190 
191 
192 
194 // constructor for an N-Dimensional PRegion, given an NDIndex
195 template < class T, unsigned Dim, class MeshType >
197  int vnodes) {
198 
199 
200 
201  // build mesh on this domain, with each axis extended by one
202  NDIndex<Dim> extended;
203  for (unsigned int i=0; i<Dim; i++)
204  extended[i] = Index(domain[i].first(), domain[i].last()+1,
205  domain[i].stride());
206  FLayout = 0;
207  theMesh = 0;
208  Remote_ac = 0;
209  store_mesh(new MeshType(extended), true);
210  changeDomain(domain, vnodes);
211 }
212 
214 // constructor for just a 1-D PRegion, given an Index
215 template < class T, unsigned Dim, class MeshType >
217 
218 
219 
220  PInsist(Dim==1,
221  "Number of Index arguments does not match RegionLayout dimension!!");
222  // build mesh on this Index, extended by one
223  Index extended(i1.first(), i1.last()+1, i1.stride());
224  FLayout = 0;
225  theMesh = 0;
226  Remote_ac = 0;
227  store_mesh(new MeshType(extended), true);
228  NDIndex<Dim> dom;
229  dom[0] = i1;
230  changeDomain(dom, vnodes);
231 }
232 
234 // constructor for just a 2-D PRegion, given two Index objecs
235 template < class T, unsigned Dim, class MeshType >
237  int vnodes) {
238 
239 
240 
241  PInsist(Dim==2,
242  "Number of Index arguments does not match RegionLayout dimension!!");
243  // build mesh on domain extended by one on each axis
244  Index ex1(i1.first(), i1.last()+1, i1.stride());
245  Index ex2(i2.first(), i2.last()+1, i2.stride());
246  FLayout = 0;
247  theMesh = 0;
248  Remote_ac = 0;
249  store_mesh(new MeshType(ex1, ex2), true);
250  NDIndex<Dim> dom;
251  dom[0] = i1;
252  dom[1] = i2;
253  changeDomain(dom, vnodes);
254 }
255 
257 // constructor for just a 3-D PRegion, given three Index objecs
258 template < class T, unsigned Dim, class MeshType >
260  const Index& i3, int vnodes) {
261 
262  PInsist(Dim==3,
263  "Number of Index arguments does not match RegionLayout dimension!!");
264  // build mesh on domain extended by one on each axis
265  Index ex1(i1.first(), i1.last()+1, i1.stride());
266  Index ex2(i2.first(), i2.last()+1, i2.stride());
267  Index ex3(i3.first(), i3.last()+1, i3.stride());
268  FLayout = 0;
269  theMesh = 0;
270  Remote_ac = 0;
271  store_mesh(new MeshType(ex1, ex2, ex3), true);
272  NDIndex<Dim> dom;
273  dom[0] = i1;
274  dom[1] = i2;
275  dom[2] = i3;
276  changeDomain(dom, vnodes);
277 }
278 
279 
280 
282 // constructor for an N-Dimensional PRegion, given an NDIndex and Mesh
283 template < class T, unsigned Dim, class MeshType >
285  MeshType& mesh,
286  int vnodes) {
287 
288 
289 
290  FLayout = 0;
291  theMesh = 0;
292  Remote_ac = 0;
293  store_mesh(&mesh, false);
294  changeDomain(domain, vnodes);
295 }
296 
298 // constructor for just a 1-D PRegion, given an Index and Mesh
299 template < class T, unsigned Dim, class MeshType >
301  MeshType& mesh,
302  int vnodes) {
303 
304 
305 
306  PInsist(Dim==1,
307  "Number of Index arguments does not match RegionLayout dimension!!");
308  FLayout = 0;
309  theMesh = 0;
310  Remote_ac = 0;
311  store_mesh(&mesh, false);
312  NDIndex<Dim> dom;
313  dom[0] = i1;
314  changeDomain(dom, vnodes);
315 }
316 
318 // constructor for just a 2-D PRegion, given two Index objecs and a Mesh
319 template < class T, unsigned Dim, class MeshType >
321  const Index& i2,
322  MeshType& mesh,
323  int vnodes) {
324 
325  PInsist(Dim==2,
326  "Number of Index arguments does not match RegionLayout dimension!!");
327  FLayout = 0;
328  theMesh = 0;
329  Remote_ac = 0;
330  store_mesh(&mesh, false);
331  NDIndex<Dim> dom;
332  dom[0] = i1;
333  dom[1] = i2;
334  changeDomain(dom, vnodes);
335 }
336 
338 // constructor for just a 3-D PRegion, given three Index objecs and a Mesh
339 template < class T, unsigned Dim, class MeshType >
341  const Index& i2,
342  const Index& i3,
343  MeshType& mesh,
344  int vnodes) {
345 
346  PInsist(Dim==3,
347  "Number of Index arguments does not match RegionLayout dimension!!");
348  FLayout = 0;
349  theMesh = 0;
350  Remote_ac = 0;
351  store_mesh(&mesh, false);
352  NDIndex<Dim> dom;
353  dom[0] = i1;
354  dom[1] = i2;
355  dom[2] = i3;
356  changeDomain(dom, vnodes);
357 }
358 
359 
361 // Constructor which takes a FieldLayout, and uses it for our layout
362 template < class T, unsigned Dim, class MeshType >
364 
365 
366 
367  // build mesh on domain extended by one along each axis
368  NDIndex<Dim> domain = fl.getDomain();
369  NDIndex<Dim> extended;
370  for (unsigned int i=0; i<Dim; i++)
371  extended[i] = Index(domain[i].first(), domain[i].last()+1,
372  domain[i].stride());
373  FLayout = 0;
374  theMesh = 0;
375  Remote_ac = 0;
376  store_mesh(new MeshType(extended), true);
377  changeDomain(fl);
378 }
379 
380 
382 // Constructor which takes a FieldLayout and a Mesh
383 template < class T, unsigned Dim, class MeshType >
385  MeshType& mesh) {
386 
387 
388 
389  FLayout = 0;
390  theMesh = 0;
391  Remote_ac = 0;
392  store_mesh(&mesh, false);
393  changeDomain(fl);
394 }
395 
396 
398 // Reconstruct this RegionLayout from the given domain. This clears
399 // out the existing data, and generates a new partitioning.
400 template < class T, unsigned Dim, class MeshType >
402  int vnodes) {
403 
404 
405 
406  unsigned int d; // loop variable
407 
408  // delete our existing FieldLayout
409  delete_flayout();
410 
411  // create a mesh, if necessary
412  if (theMesh == 0) {
413  NDIndex<Dim> ex;
414  for (d=0; d < Dim; ++d)
415  ex[d] = Index(domain[d].first(),domain[d].last()+1,domain[d].stride());
416  store_mesh(new MeshType(ex), true);
417  }
418 
419  // set our index space offset
420  for (d=0; d < Dim; ++d) {
421  IndexOffset[d] = domain[d].first();
422  CenterOffset[d] = (MeshVertices[d].length() > domain[d].length());
423  }
424 
425  // build the FieldLayout from this NDIndex ... note that
426  // we're making our own FieldLayout here. Creating this FieldLayout
427  // results in a distribution of vnodes, which we will use for our rnodes.
428  store_flayout(new FieldLayout<Dim>(domain, 0, vnodes), true);
429 
430  // save the region, and note that our domain matches the FieldLayout's,
431  // so that there is no offset
432  Domain = convert_index(FLayout->getDomain());
433 
434  // from the FieldLayout and Domain, build our internal representation
435  make_rnodes(Domain, *FLayout);
436  return;
437 }
438 
439 
441 // Reconstruct this RegionLayout from the given domain. This clears
442 // out the existing data, and generates a new partitioning.
443 template < class T, unsigned Dim, class MeshType >
445  int vnodes) {
446 
447 
448 
449  unsigned int d; // loop variable
450 
451  // delete our existing FieldLayout
452  delete_flayout();
453 
454  // create a mesh, if necessary
455  // right now, we assume that the current mesh is adequate, but
456  // we might have to pass a new one in or create one.
457  PAssert(theMesh);
458 
459  // set our index space and centering offsets
460  for (d=0; d < Dim; ++d) {
461  IndexOffset[d] = 0;
462  CenterOffset[d] = true; // make the internal FieldLayout cell-centered
463  }
464 
465  // make an NDIndex based on the NDRegion & mesh
466  NDIndex<Dim> area = convert_region(domain);
467 
468  // build the FieldLayout from this NDIndex ... note that
469  // we're making our own FieldLayout here. Creating this FieldLayout
470  // results in a distribution of vnodes, which we will use for our rnodes.
471  store_flayout(new FieldLayout<Dim>(area, 0, vnodes), true);
472 
473  // save the region, and note that our domain is offset from the FieldLayout's
474  Domain = domain;
475 
476  // from the FieldLayout, build our internal representation
477  make_rnodes(Domain, *FLayout);
478  return;
479 }
480 
481 
483 // Reconstruct this RegionLayout from the given FieldLayout. This
484 // we just use the FieldLayout as-is, instead of making a new one.
485 template < class T, unsigned Dim, class MeshType >
487 
488 
489 
490  unsigned int d; // loop variable
491 
492  // delete our existing FieldLayout
493  delete_flayout();
494 
495  // create a mesh, if necessary
496  if (theMesh == 0) {
497  NDIndex<Dim> ex;
498  const NDIndex<Dim>& domain(fl.getDomain());
499  for (d=0; d < Dim; ++d)
500  ex[d] = Index(domain[d].first(),domain[d].last()+1,domain[d].stride());
501  store_mesh(new MeshType(ex), true);
502  }
503 
504  // set our index space offset
505  for (d=0; d < Dim; ++d) {
506  IndexOffset[d] = fl.getDomain()[d].first();
507  CenterOffset[d] = (theMesh->gridSizes[d] > fl.getDomain()[d].length());
508  }
509 
510  // save this new layout, and set up our data structures
511  Domain = convert_index(fl.getDomain());
512  store_flayout(&fl, false);
513  make_rnodes(Domain, *FLayout);
514  return;
515 }
516 
517 
519 // convert a given NDIndex into an NDRegion ... if this object was
520 // constructed from a FieldLayout, this does nothing, but if we are maintaining
521 // our own internal FieldLayout, we must convert from the [0,N-1] index
522 // space to our own continuous NDRegion space.
523 // NOTE: THIS ASSUMES THAT REGION'S HAVE first() < last() !!
524 template < class T, unsigned Dim, class MeshType >
527 
528  NDRegion<T,Dim> new_pregion; // Needed in TAU_TYPE_STRING
529 
530  unsigned int d;
531 
532  // find first and last points in NDIndex and get coordinates from mesh
533  NDIndex<Dim> FirstPoint, LastPoint;
534  for (d=0; d<Dim; d++) {
535  int first = ni[d].first() - IndexOffset[d];
536  int last = ni[d].last() - IndexOffset[d] + CenterOffset[d];
537  FirstPoint[d] = Index(first, first);
538  LastPoint[d] = Index(last, last);
539  }
540 
541  // convert to mesh space
542  Vektor<T,Dim> FirstCoord = theMesh->getVertexPosition(FirstPoint);
543  Vektor<T,Dim> LastCoord = theMesh->getVertexPosition(LastPoint);
544  for (d=0; d<Dim; d++) {
545  if (!CenterOffset[d]) { // vertex centering, so offset region endpoints
546  if ( !(FirstPoint[d] == Index(0,0)) ) {
547  FirstPoint[d] = FirstPoint[d] - 1;
548  FirstCoord = theMesh->getVertexPosition(FirstPoint);
549  FirstCoord(d) = FirstCoord(d) +
550  0.5 * theMesh->getDeltaVertex(FirstPoint)(d);
551  }
552  int final = theMesh->gridSizes[d]-1;
553  if ( !(LastPoint[d] == Index(final,final)) )
554  LastCoord(d) = LastCoord(d) +
555  0.5 * theMesh->getDeltaVertex(LastPoint)(d);
556  }
557 
558  new_pregion[d] = PRegion<T>(FirstCoord(d), LastCoord(d));
559  }
560 
561  return new_pregion;
562 }
563 
564 
566 // perform the inverse of convert_index: convert a given NDRegion (with
567 // coordinates in the 'region' space) into an NDIndex (with values in
568 // the [0,N-1] 'index' space). This will truncate values when converting
569 // from continuous to integer data.
570 template < class T, unsigned Dim, class MeshType >
573  NDIndex<Dim> index;
574 
575 
576 
577  unsigned d;
578 
579  // find mesh points corresponding to endpoints of region
580  Vektor<T,Dim> FirstCoord, LastCoord;
581  for (d=0; d<Dim; d++) {
582  FirstCoord(d) = nr[d].first();
583  LastCoord(d) = nr[d].last();
584  }
585  NDIndex<Dim> FirstPoint = theMesh->getNearestVertex(FirstCoord);
586  NDIndex<Dim> LastPoint = theMesh->getNearestVertex(LastCoord);
587  for (d=0; d<Dim; d++) {
588  if (!CenterOffset[d]) { // vertex centering
589  if (theMesh->getVertexPosition(FirstPoint)(d) < FirstCoord(d))
590  FirstPoint[d] = FirstPoint[d] + 1;
591  if (theMesh->getVertexPosition(LastPoint)(d) > LastCoord(d))
592  LastPoint[d] = LastPoint[d] - 1;
593  }
594  index[d] = Index(FirstPoint[d].first() + IndexOffset[d],
595  LastPoint[d].first() + IndexOffset[d] - CenterOffset[d]);
596  }
597 
598  return index;
599 }
600 
602 // Scan through the internal FieldLayout and construct Rnodes based on
603 // the current FieldLayout and PRegion. Put them into out local
604 // and remote Rnode containers.
605 template < class T, unsigned Dim, class MeshType >
606 void
608  FieldLayout<Dim>& FL) {
609 
610 
611 
612  //Inform dbgmsg("RegionLayout::make_rnodes");
613  //dbgmsg << "Creating new rnodes based on FieldLayout = " << FL << endl;
614 
615  // delete the existing rnodes
616  delete_rnodes();
617 
618  // for each local vnode in the FieldLayout, make a corresponding NDRegion
619  // and put it in a local Rnode
620  typedef typename ac_id_vnodes::value_type lrnode_t;
621  typename FieldLayout<Dim>::iterator_iv lociter = FL.begin_iv();
622  typename FieldLayout<Dim>::iterator_iv endloc = FL.end_iv();
623  for ( ; lociter != endloc; ++lociter) {
624  Rnode<T,Dim> *rnode =
625  StaticRnodePool.create_rnode(
626  convert_index((*((*lociter).second)).getDomain()),
627  (*((*lociter).second)).getNode());
628 
629  //dbgmsg << " Created local rnode = " << rnode->getDomain();
630  //dbgmsg << " from vnode = " << (*((*lociter).second)).getDomain() <<endl;
631 
632  Local_ac.insert( lrnode_t(Unique::get(), rnode) );
633  }
634 
635  // similarly, for each remote vnode in the FieldLayout, make an Rnode
636  Remote_ac = new ac_domain_vnodes(dom);
637  typedef typename ac_domain_vnodes::value_type rrnode_t;
638  typename FieldLayout<Dim>::iterator_dv remiter = FL.begin_rdv();
639  typename FieldLayout<Dim>::iterator_dv endrem = FL.end_rdv();
640  for ( ; remiter != endrem; ++remiter) {
641  Rnode<T,Dim> *rnode =
642  StaticRnodePool.create_rnode(
643  convert_index((*((*remiter).second)).getDomain()),
644  (*((*remiter).second)).getNode());
645 
646  //dbgmsg << " Created remote rnode = " << rnode->getDomain();
647  //dbgmsg << " from vnode = " << (*((*remiter).second)).getDomain() <<endl;
648 
649  Remote_ac->insert( rrnode_t(rnode->getDomain(), rnode) );
650  }
651 
652  // Since the rnodes changed, repartition each object using this
653  // RegionLayout. We have made sure only FieldLayoutUser's can
654  // check in with us, so we know that all user's can be cast to
655  // FieldLayoutUser.
656  for (iterator_user p = begin_user(); p != end_user(); ++p) {
657  FieldLayoutUser *user = (FieldLayoutUser *) (*p).second;
658  user->Repartition(this);
659  }
660 }
661 
662 
664 // Delete the Rnodes in the given local and remote lists ... actually,
665 // just returns them back to the static pool. Note that this DOES NOT
666 // remove the elements from the lists.
667 template < class T, unsigned Dim, class MeshType >
669 
670 
671 
672  // delete local rnodes
673  typename ac_id_vnodes::iterator lociter = Local_ac.begin();
674  typename ac_id_vnodes::iterator endloc = Local_ac.end();
675  for ( ; lociter != endloc; ++lociter)
676  StaticRnodePool.push_back((*lociter).second);
677  Local_ac.erase(Local_ac.begin(), Local_ac.end());
678 
679  // delete remote rnodes
680  if (Remote_ac != 0) {
681  typename ac_domain_vnodes::iterator remiter = Remote_ac->begin();
682  typename ac_domain_vnodes::iterator endrem = Remote_ac->end();
683  for ( ; remiter != endrem; ++remiter)
684  StaticRnodePool.push_back((*remiter).second);
685  delete Remote_ac;
686  Remote_ac = 0;
687  }
688 }
689 
690 
692 // Store a FieldLayout pointer, and note if we own it or not.
693 template < class T, unsigned Dim, class MeshType >
695  bool WeOwn) {
696 
697 
698 
699  // get rid of the existing layout, if necessary
700  delete_flayout();
701 
702  // save the pointer, and whether we own it. Also, check in to the
703  // layout
704  FLayout = f;
705  WeOwnFieldLayout = WeOwn;
706  if (FLayout != 0)
707  FLayout->checkin(*this);
708 }
709 
710 
712 // Delete our current FLayout, and set it to NULL; we may have to
713 // check out from the layout
714 template < class T, unsigned Dim, class MeshType >
716 
717  if (FLayout != 0) {
718  FLayout->checkout(*this);
719  if (WeOwnFieldLayout)
720  delete FLayout;
721  FLayout = 0;
722  }
723 }
724 
725 
727 // Store a Mesh pointer, and note if we own it or not.
728 template < class T, unsigned Dim, class MeshType >
729 void RegionLayout<T,Dim,MeshType>::store_mesh(MeshType* m, bool WeOwn) {
730 
731 
732 
733  // get rid of the existing mesh, if necessary
734  delete_mesh();
735 
736  // save the pointer, and whether we own it. Also, check in to the
737  // layout
738  theMesh = m;
739  WeOwnMesh = WeOwn;
740  if (theMesh != 0) {
741  theMesh->checkin(*this);
742  for (unsigned int d=0; d < Dim; ++d)
743  MeshVertices[d] = Index(theMesh->gridSizes[d]);
744  }
745 }
746 
747 
749 // Delete our current MeshType, and set it to NULL; we may have to
750 // check out from the mesh
751 template < class T, unsigned Dim, class MeshType >
753 
754 
755  if (theMesh != 0) {
756  theMesh->checkout(*this);
757  if (WeOwnMesh)
758  delete theMesh;
759  theMesh = 0;
760  }
761 }
762 
763 
765 // calculate the boundary region of the given mesh object
766 template < class T, unsigned Dim, class MeshType >
768  NDRegion<T,Dim> retDomain;
769 
770 
771 
772 
773  typename MeshType::MeshVektor_t morigin = m->get_origin();
774  NDIndex<Dim> meshCells;
775  unsigned int d;
776  for (d=0; d < Dim; ++d)
777  meshCells[d] = Index(MeshVertices[d].first(),MeshVertices[d].last()-1);
778  typename MeshType::MeshVektor_t msize = m->getDeltaVertex(meshCells);
779  for (d=0; d < Dim; ++d)
780  retDomain[d] = PRegion<T>(morigin[d], morigin[d] + msize[d]);
781  return retDomain;
782 }
783 
784 
786 // calculate the number of vertices in the given mesh
787 template < class T, unsigned Dim, class MeshType >
789  NDIndex<Dim> mvertices;
790 
791 
792 
793 
794  for (unsigned int d=0; d < Dim; ++d)
795  mvertices[d] = Index(m->gridSizes[d]);
796  return mvertices;
797 }
798 
799 
801 // output
802 template < class T, unsigned Dim, class MeshType >
803 std::ostream& operator<<(std::ostream& out, const RegionLayout<T,Dim,MeshType>& f) {
804 
805 
806 
807  int icount;
808 
809  // the whole domain
810  out << "Total Domain = " << f.getDomain() << "\n";
811 
812  // iterate over the local vnodes and print them out.
813  out << "Local Rnodes = " << f.size_iv() << "\n";
816  for(icount=0 ; v_i != v_e; ++v_i, ++icount)
817  out << " rnode " << icount << " : " << (*v_i).second->getDomain() << "\n";
818 
819  // iterate over the remote vnodes and print them out.
820  out << "Remote Rnodes = " << f.size_rdv() << "\n";
821  if (f.size_rdv() > 0) {
824  for (icount=0 ; dv_i != dv_e; ++dv_i, ++icount)
825  out << " rnode " << icount << " : " << (*dv_i).first << "\n";
826  }
827 
828  // print out our internal FieldLayout
829  out << "Internal FieldLayout = " << f.getFieldLayout();
830 
831  return out;
832 }
833 
834 
836 // Repartition the region, from a list of NDIndex objects which
837 // represent our local domain. This assumes two things:
838 // 1. We are repartitioning the same global domain, just in a different
839 // way. Thus, the encompassing NDRegion 'Domain' does not change.
840 // 2. The NDIndex objects cover a domain which corresponds to our
841 // internal FieldLayout domain. This may or may not directly
842 // overlap with the NDRegion domain. The basic point is that with
843 // these NDIndex objects, we can replace the FieldLayout directly,
844 // and then regenerate our RegionLayout (Rnode) data.
845 template < class T, unsigned Dim, class MeshType >
847  NDIndex<Dim>* nf) {
848 
849 
850 
851  // repartition the FieldLayout, using the given list of local vnodes. This
852  // call will result in a distribution of the data to all the nodes. Also,
853  // as part of the Repartition process the FieldLayout will tell us to
854  // recreate out rnodes by calling RegionLayout::Repartition.
855  if (FLayout != 0)
856  FLayout->Repartition(ni, nf);
857 }
858 
859 
861 // Repartition onto a new layout, if the layout changes ... this is a
862 // virtual function called by a UserList, as opposed to the RepartitionLayout
863 // function used by the particle load balancing mechanism.
864 template < class T, unsigned Dim, class MeshType >
866 
867 
868 
869  if (theMesh != 0 && userlist->getUserListID() == theMesh->get_Id()) {
870  // perform actions to restructure our data due to a change in the
871  // mesh
872 
873  //Inform dbgmsg("RegionLayout::Repartition");
874  //dbgmsg << "Repartitioning RegionLayout due to mesh change ..." << endl;
875 
876  // have the number of mesh points changed?
877  NDIndex<Dim> mvertices(getMeshVertices(theMesh));
878  if (!(mvertices == MeshVertices)) {
879  // yes they have ... we must reconstruct everything, including
880  // our FieldLayout.
881  MeshVertices = mvertices;
882  if (WeOwnFieldLayout)
883  changeDomain(getMeshDomain(theMesh), size_iv() + size_rdv());
884  else
885  changeDomain(*FLayout);
886  } else {
887  // since we have the same number of vertices, the layout has not
888  // changed, only the size of the rnodes and the total domain.
889  Domain = getMeshDomain(theMesh);
890  make_rnodes(Domain, *FLayout);
891  }
892 
893  } else {
894 
895  //Inform dbgmsg("RegionLayout::Repartition");
896  //dbgmsg << "Repartitioning RegionLayout due to layout change ..." << endl;
897 
898  // Must be a FieldLayout change instead, so,
899  // create new rnodes based on the vnodes in this layout. Since this
900  // is called by the FieldLayout we are using, there is no need to
901  // change our FLayout pointer.
902  FieldLayout<Dim>* newLayout = (FieldLayout<Dim>*)( userlist );
903  make_rnodes(Domain, *newLayout);
904  }
905 }
906 
907 
909 // Tell the subclass that the FieldLayoutBase is being deleted, so
910 // don't use it anymore
911 template < class T, unsigned Dim, class MeshType >
913 
914 
915 
916  if (FLayout != 0 && FLayout->get_Id() == userlist->getUserListID()) {
917  // set our FieldLayout pointer to null, if it matches the given userlist.
918  // This may render this RegionLayout instance useless,
919  // so this should be followed only by a call to the destructor of
920  // RegionLayout.
921  FLayout = 0;
922 
923  } else if (theMesh != 0 && userlist->getUserListID() == theMesh->get_Id()) {
924  // set our mesh pointer to null, if it matches the given userlist.
925  // This may render this RegionLayout instance useless,
926  // so this should be followed only by a call to the destructor of
927  // RegionLayout.
928  theMesh = 0;
929 
930  } else {
931  // for now, print a warning ... but in general, this is OK and this
932  // warning should be removed
933  WARNMSG("RegionLayout: notified of unknown UserList being deleted.");
934  }
935 }
936 
937 
938 /***************************************************************************
939  * $RCSfile: RegionLayout.cpp,v $ $Author: adelmann $
940  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:32 $
941  * IPPL_VERSION_ID: $Id: RegionLayout.cpp,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $
942  ***************************************************************************/
const int nr
Definition: ClassicRandom.h:24
const unsigned Dim
std::ostream & operator<<(std::ostream &out, const RegionLayout< T, Dim, MeshType > &f)
#define WARNMSG(msg)
Definition: IpplInfo.h:349
#define PInsist(c, m)
Definition: PAssert.h:120
#define PAssert(c)
Definition: PAssert.h:102
iterator_iv end_iv()
Definition: FieldLayout.h:716
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
iterator_dv begin_rdv(const GuardCellSizes< Dim > &gc=gc0())
Definition: FieldLayout.h:765
iterator_dv end_rdv(const GuardCellSizes< Dim > &gc=gc0())
Definition: FieldLayout.h:772
void checkin(FieldLayoutUser &f, const GuardCellSizes< Dim > &gc=gc0())
ac_id_vnodes::iterator iterator_iv
Definition: FieldLayout.h:73
iterator_iv begin_iv()
Definition: FieldLayout.h:709
virtual void Repartition(UserList *)=0
Definition: Index.h:237
int stride() const
Definition: IndexInlines.h:121
int last() const
Definition: IndexInlines.h:136
int first() const
Definition: IndexInlines.h:116
void delete_mesh()
void changeDomain(FieldLayout< Dim > &)
void RepartitionLayout(NDIndex< Dim > *, NDIndex< Dim > *)
const NDRegion< T, Dim > & getDomain() const
Definition: RegionLayout.h:131
void make_rnodes(const NDRegion< T, Dim > &, FieldLayout< Dim > &)
iterator_dv begin_rdv()
Definition: RegionLayout.h:155
MeshType * theMesh
Definition: RegionLayout.h:252
iterator_iv begin_iv()
Definition: RegionLayout.h:146
iterator_dv end_rdv()
Definition: RegionLayout.h:156
NDRegion< T, Dim > getMeshDomain(MeshType *)
NDIndex< Dim > convert_region(const NDRegion< T, Dim > &) const
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 *)
ac_id_vnodes::const_iterator const_iterator_iv
Definition: RegionLayout.h:67
ac_domain_vnodes::size_type size_rdv() const
Definition: RegionLayout.h:152
virtual void Repartition(UserList *)
FieldLayout< Dim > * FLayout
Definition: RegionLayout.h:248
virtual ~RegionLayout()
iterator_iv end_iv()
Definition: RegionLayout.h:147
bool WeOwnFieldLayout
Definition: RegionLayout.h:249
void delete_rnodes()
NDIndex< Dim > getMeshVertices(MeshType *)
bool CenterOffset[Dim]
Definition: RegionLayout.h:262
FieldLayout< Dim > & getFieldLayout()
Definition: RegionLayout.h:137
void delete_flayout()
int IndexOffset[Dim]
Definition: RegionLayout.h:259
void store_flayout(FieldLayout< Dim > *, bool WeOwn)
void store_mesh(MeshType *, bool WeOwn)
Definition: Rnode.h:30
const NDRegion< T, Dim > & getDomain()
Definition: Rnode.h:53
static type get()
Definition: Unique.h:33
ID_t getUserListID() const
Definition: UserList.cpp:54
UserList_t::iterator iterator_user
Definition: UserList.h:43
rep_type::iterator iterator
Definition: vmap.h:98
std::pair< Unique::type, Rnode< T, Dim > * > value_type
Definition: vmap.h:64