OPAL (Object Oriented Parallel Accelerator Library)  2.2.0
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 
601 #ifdef IPPL_USE_MEMBER_TEMPLATES
602 
603 //mwerks Moved into class definition (.h file).
604 
605 #endif
606 
608 // Scan through the internal FieldLayout and construct Rnodes based on
609 // the current FieldLayout and PRegion. Put them into out local
610 // and remote Rnode containers.
611 template < class T, unsigned Dim, class MeshType >
612 void
614  FieldLayout<Dim>& FL) {
615 
616 
617 
618  //Inform dbgmsg("RegionLayout::make_rnodes");
619  //dbgmsg << "Creating new rnodes based on FieldLayout = " << FL << endl;
620 
621  // delete the existing rnodes
622  delete_rnodes();
623 
624  // for each local vnode in the FieldLayout, make a corresponding NDRegion
625  // and put it in a local Rnode
626  typedef typename ac_id_vnodes::value_type lrnode_t;
627  typename FieldLayout<Dim>::iterator_iv lociter = FL.begin_iv();
628  typename FieldLayout<Dim>::iterator_iv endloc = FL.end_iv();
629  for ( ; lociter != endloc; ++lociter) {
630  Rnode<T,Dim> *rnode =
631  StaticRnodePool.create_rnode(
632  convert_index((*((*lociter).second)).getDomain()),
633  (*((*lociter).second)).getNode());
634 
635  //dbgmsg << " Created local rnode = " << rnode->getDomain();
636  //dbgmsg << " from vnode = " << (*((*lociter).second)).getDomain() <<endl;
637 
638  Local_ac.insert( lrnode_t(Unique::get(), rnode) );
639  }
640 
641  // similarly, for each remote vnode in the FieldLayout, make an Rnode
642  Remote_ac = new ac_domain_vnodes(dom);
643  typedef typename ac_domain_vnodes::value_type rrnode_t;
644  typename FieldLayout<Dim>::iterator_dv remiter = FL.begin_rdv();
645  typename FieldLayout<Dim>::iterator_dv endrem = FL.end_rdv();
646  for ( ; remiter != endrem; ++remiter) {
647  Rnode<T,Dim> *rnode =
648  StaticRnodePool.create_rnode(
649  convert_index((*((*remiter).second)).getDomain()),
650  (*((*remiter).second)).getNode());
651 
652  //dbgmsg << " Created remote rnode = " << rnode->getDomain();
653  //dbgmsg << " from vnode = " << (*((*remiter).second)).getDomain() <<endl;
654 
655  Remote_ac->insert( rrnode_t(rnode->getDomain(), rnode) );
656  }
657 
658  // Since the rnodes changed, repartition each object using this
659  // RegionLayout. We have made sure only FieldLayoutUser's can
660  // check in with us, so we know that all user's can be cast to
661  // FieldLayoutUser.
662  for (iterator_user p = begin_user(); p != end_user(); ++p) {
663  FieldLayoutUser *user = (FieldLayoutUser *) (*p).second;
664  user->Repartition(this);
665  }
666 }
667 
668 
670 // Delete the Rnodes in the given local and remote lists ... actually,
671 // just returns them back to the static pool. Note that this DOES NOT
672 // remove the elements from the lists.
673 template < class T, unsigned Dim, class MeshType >
675 
676 
677 
678  // delete local rnodes
679  typename ac_id_vnodes::iterator lociter = Local_ac.begin();
680  typename ac_id_vnodes::iterator endloc = Local_ac.end();
681  for ( ; lociter != endloc; ++lociter)
682  StaticRnodePool.push_back((*lociter).second);
683  Local_ac.erase(Local_ac.begin(), Local_ac.end());
684 
685  // delete remote rnodes
686  if (Remote_ac != 0) {
687  typename ac_domain_vnodes::iterator remiter = Remote_ac->begin();
688  typename ac_domain_vnodes::iterator endrem = Remote_ac->end();
689  for ( ; remiter != endrem; ++remiter)
690  StaticRnodePool.push_back((*remiter).second);
691  delete Remote_ac;
692  Remote_ac = 0;
693  }
694 }
695 
696 
698 // Store a FieldLayout pointer, and note if we own it or not.
699 template < class T, unsigned Dim, class MeshType >
701  bool WeOwn) {
702 
703 
704 
705  // get rid of the existing layout, if necessary
706  delete_flayout();
707 
708  // save the pointer, and whether we own it. Also, check in to the
709  // layout
710  FLayout = f;
711  WeOwnFieldLayout = WeOwn;
712  if (FLayout != 0)
713  FLayout->checkin(*this);
714 }
715 
716 
718 // Delete our current FLayout, and set it to NULL; we may have to
719 // check out from the layout
720 template < class T, unsigned Dim, class MeshType >
722 
723  if (FLayout != 0) {
724  FLayout->checkout(*this);
725  if (WeOwnFieldLayout)
726  delete FLayout;
727  FLayout = 0;
728  }
729 }
730 
731 
733 // Store a Mesh pointer, and note if we own it or not.
734 template < class T, unsigned Dim, class MeshType >
735 void RegionLayout<T,Dim,MeshType>::store_mesh(MeshType* m, bool WeOwn) {
736 
737 
738 
739  // get rid of the existing mesh, if necessary
740  delete_mesh();
741 
742  // save the pointer, and whether we own it. Also, check in to the
743  // layout
744  theMesh = m;
745  WeOwnMesh = WeOwn;
746  if (theMesh != 0) {
747  theMesh->checkin(*this);
748  for (unsigned int d=0; d < Dim; ++d)
749  MeshVertices[d] = Index(theMesh->gridSizes[d]);
750  }
751 }
752 
753 
755 // Delete our current MeshType, and set it to NULL; we may have to
756 // check out from the mesh
757 template < class T, unsigned Dim, class MeshType >
759 
760 
761  if (theMesh != 0) {
762  theMesh->checkout(*this);
763  if (WeOwnMesh)
764  delete theMesh;
765  theMesh = 0;
766  }
767 }
768 
769 
771 // calculate the boundary region of the given mesh object
772 template < class T, unsigned Dim, class MeshType >
774  NDRegion<T,Dim> retDomain;
775 
776 
777 
778 
779  typename MeshType::MeshVektor_t morigin = m->get_origin();
780  NDIndex<Dim> meshCells;
781  unsigned int d;
782  for (d=0; d < Dim; ++d)
783  meshCells[d] = Index(MeshVertices[d].first(),MeshVertices[d].last()-1);
784  typename MeshType::MeshVektor_t msize = m->getDeltaVertex(meshCells);
785  for (d=0; d < Dim; ++d)
786  retDomain[d] = PRegion<T>(morigin[d], morigin[d] + msize[d]);
787  return retDomain;
788 }
789 
790 
792 // calculate the number of vertices in the given mesh
793 template < class T, unsigned Dim, class MeshType >
795  NDIndex<Dim> mvertices;
796 
797 
798 
799 
800  for (unsigned int d=0; d < Dim; ++d)
801  mvertices[d] = Index(m->gridSizes[d]);
802  return mvertices;
803 }
804 
805 
807 // output
808 template < class T, unsigned Dim, class MeshType >
809 std::ostream& operator<<(std::ostream& out, const RegionLayout<T,Dim,MeshType>& f) {
810 
811 
812 
813  int icount;
814 
815  // the whole domain
816  out << "Total Domain = " << f.getDomain() << "\n";
817 
818  // iterate over the local vnodes and print them out.
819  out << "Local Rnodes = " << f.size_iv() << "\n";
820  typename RegionLayout<T,Dim,MeshType>::const_iterator_iv v_i = f.begin_iv();
821  typename RegionLayout<T,Dim,MeshType>::const_iterator_iv v_e = f.end_iv();
822  for(icount=0 ; v_i != v_e; ++v_i, ++icount)
823  out << " rnode " << icount << " : " << (*v_i).second->getDomain() << "\n";
824 
825  // iterate over the remote vnodes and print them out.
826  out << "Remote Rnodes = " << f.size_rdv() << "\n";
827  if (f.size_rdv() > 0) {
828  typename RegionLayout<T,Dim,MeshType>::const_iterator_dv dv_i = f.begin_rdv();
829  typename RegionLayout<T,Dim,MeshType>::const_iterator_dv dv_e = f.end_rdv();
830  for (icount=0 ; dv_i != dv_e; ++dv_i, ++icount)
831  out << " rnode " << icount << " : " << (*dv_i).first << "\n";
832  }
833 
834  // print out our internal FieldLayout
835  out << "Internal FieldLayout = " << f.getFieldLayout();
836 
837  return out;
838 }
839 
840 
842 // Repartition the region, from a list of NDIndex objects which
843 // represent our local domain. This assumes two things:
844 // 1. We are repartitioning the same global domain, just in a different
845 // way. Thus, the encompassing NDRegion 'Domain' does not change.
846 // 2. The NDIndex objects cover a domain which corresponds to our
847 // internal FieldLayout domain. This may or may not directly
848 // overlap with the NDRegion domain. The basic point is that with
849 // these NDIndex objects, we can replace the FieldLayout directly,
850 // and then regenerate our RegionLayout (Rnode) data.
851 template < class T, unsigned Dim, class MeshType >
853  NDIndex<Dim>* nf) {
854 
855 
856 
857  // repartition the FieldLayout, using the given list of local vnodes. This
858  // call will result in a distribution of the data to all the nodes. Also,
859  // as part of the Repartition process the FieldLayout will tell us to
860  // recreate out rnodes by calling RegionLayout::Repartition.
861  if (FLayout != 0)
862  FLayout->Repartition(ni, nf);
863 }
864 
865 
867 // Repartition onto a new layout, if the layout changes ... this is a
868 // virtual function called by a UserList, as opposed to the RepartitionLayout
869 // function used by the particle load balancing mechanism.
870 template < class T, unsigned Dim, class MeshType >
872 
873 
874 
875  if (theMesh != 0 && userlist->getUserListID() == theMesh->get_Id()) {
876  // perform actions to restructure our data due to a change in the
877  // mesh
878 
879  //Inform dbgmsg("RegionLayout::Repartition");
880  //dbgmsg << "Repartitioning RegionLayout due to mesh change ..." << endl;
881 
882  // have the number of mesh points changed?
883  NDIndex<Dim> mvertices(getMeshVertices(theMesh));
884  if (!(mvertices == MeshVertices)) {
885  // yes they have ... we must reconstruct everything, including
886  // our FieldLayout.
887  MeshVertices = mvertices;
888  if (WeOwnFieldLayout)
889  changeDomain(getMeshDomain(theMesh), size_iv() + size_rdv());
890  else
891  changeDomain(*FLayout);
892  } else {
893  // since we have the same number of vertices, the layout has not
894  // changed, only the size of the rnodes and the total domain.
895  Domain = getMeshDomain(theMesh);
896  make_rnodes(Domain, *FLayout);
897  }
898 
899  } else {
900 
901  //Inform dbgmsg("RegionLayout::Repartition");
902  //dbgmsg << "Repartitioning RegionLayout due to layout change ..." << endl;
903 
904  // Must be a FieldLayout change instead, so,
905  // create new rnodes based on the vnodes in this layout. Since this
906  // is called by the FieldLayout we are using, there is no need to
907  // change our FLayout pointer.
908  FieldLayout<Dim>* newLayout = (FieldLayout<Dim>*)( userlist );
909  make_rnodes(Domain, *newLayout);
910  }
911 }
912 
913 
915 // Tell the subclass that the FieldLayoutBase is being deleted, so
916 // don't use it anymore
917 template < class T, unsigned Dim, class MeshType >
919 
920 
921 
922  if (FLayout != 0 && FLayout->get_Id() == userlist->getUserListID()) {
923  // set our FieldLayout pointer to null, if it matches the given userlist.
924  // This may render this RegionLayout instance useless,
925  // so this should be followed only by a call to the destructor of
926  // RegionLayout.
927  FLayout = 0;
928 
929  } else if (theMesh != 0 && userlist->getUserListID() == theMesh->get_Id()) {
930  // set our mesh pointer to null, if it matches the given userlist.
931  // This may render this RegionLayout instance useless,
932  // so this should be followed only by a call to the destructor of
933  // RegionLayout.
934  theMesh = 0;
935 
936  } else {
937  // for now, print a warning ... but in general, this is OK and this
938  // warning should be removed
939  WARNMSG("RegionLayout: notified of unknown UserList being deleted.");
940  }
941 }
942 
943 
944 /***************************************************************************
945  * $RCSfile: RegionLayout.cpp,v $ $Author: adelmann $
946  * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:32 $
947  * IPPL_VERSION_ID: $Id: RegionLayout.cpp,v 1.1.1.1 2003/01/23 07:40:32 adelmann Exp $
948  ***************************************************************************/
const NDRegion< T, Dim > & getDomain()
Definition: Rnode.h:53
MeshType * theMesh
Definition: RegionLayout.h:280
static type get()
Definition: Unique.h:33
void delete_rnodes()
Definition: Rnode.h:30
void changeDomain(FieldLayout< Dim > &)
FieldLayout< Dim > * FLayout
Definition: RegionLayout.h:276
void store_mesh(MeshType *, bool WeOwn)
void make_rnodes(const NDRegion< T, Dim > &, FieldLayout< Dim > &)
virtual void Repartition(UserList *)
ID_t getUserListID() const
Definition: UserList.cpp:54
const int nr
Definition: ClassicRandom.h:24
bool WeOwnFieldLayout
Definition: RegionLayout.h:277
NDIndex< Dim > getMeshVertices(MeshType *)
ac_id_vnodes::size_type size_iv() const
Definition: RegionLayout.h:145
iterator_dv end_rdv(const GuardCellSizes< Dim > &gc=gc0())
Definition: FieldLayout.h:772
Definition: Index.h:236
bool CenterOffset[Dim]
Definition: RegionLayout.h:290
int last() const
Definition: IndexInlines.h:136
ac_domain_vnodes::size_type size_rdv() const
Definition: RegionLayout.h:152
iterator_iv end_iv()
Definition: FieldLayout.h:716
iterator_iv begin_iv()
Definition: FieldLayout.h:709
int IndexOffset[Dim]
Definition: RegionLayout.h:287
virtual ~RegionLayout()
ac_id_vnodes::iterator iterator_iv
Definition: FieldLayout.h:73
NDRegion< T, Dim > convert_index(const NDIndex< Dim > &) const
virtual void Repartition(UserList *)=0
NDRegion< T, Dim > getMeshDomain(MeshType *)
void delete_flayout()
#define WARNMSG(msg)
Definition: IpplInfo.h:398
std::pair< Unique::type, Rnode< T, Dim > * > value_type
Definition: vmap.h:71
virtual void notifyUserOfDelete(UserList *)
void delete_mesh()
UserList_t::iterator iterator_user
Definition: UserList.h:43
ac_id_vnodes::const_iterator const_iterator_iv
Definition: RegionLayout.h:67
NDRegion< T, Dim > Domain
Definition: RegionLayout.h:273
int stride() const
Definition: IndexInlines.h:121
int first() const
Definition: IndexInlines.h:116
#define PAssert(c)
Definition: PAssert.h:117
void RepartitionLayout(NDIndex< Dim > *, NDIndex< Dim > *)
iterator_dv begin_rdv(const GuardCellSizes< Dim > &gc=gc0())
Definition: FieldLayout.h:765
#define PInsist(c, m)
Definition: PAssert.h:135
const unsigned Dim
NDIndex< Dim > convert_region(const NDRegion< T, Dim > &) const
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
void checkin(FieldLayoutUser &f, const GuardCellSizes< Dim > &gc=gc0())
void store_flayout(FieldLayout< Dim > *, bool WeOwn)