OPAL (Object Oriented Parallel Accelerator Library) 2022.1
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"
32#include "Utility/PAssert.h"
33#include "Utility/IpplInfo.h"
34
35
36// static RegionLayout members
37template < class T, unsigned Dim, class MeshType >
40
41
43// default constructor
44template < 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
67template < 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;
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
97// destructor
98template < class T, unsigned Dim, class MeshType >
101
102
103 // delete all our existing rnodes
104 delete_rnodes();
105
106 // delete the FieldLayout
107 delete_flayout();
109 // delete the mesh
110 delete_mesh();
111}
112
113
115// constructor for an N-Dimensional PRegion
116template < class T, unsigned Dim, class MeshType >
118 MeshType& mesh, int vnodes) {
119
120
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
131template < 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
150template < 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
171template < 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
194// constructor for an N-Dimensional PRegion, given an NDIndex
195template < class T, unsigned Dim, class MeshType >
197 int vnodes) {
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
215template < 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
235template < 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
258template < 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
282// constructor for an N-Dimensional PRegion, given an NDIndex and Mesh
283template < 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
299template < 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
319template < 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
339template < 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
362template < 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
383template < 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.
400template < 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.
443template < 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.
485template < 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() !!
524template < 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.
570template < 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.
605template < class T, unsigned Dim, class MeshType >
606void
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.
667template < 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.
693template < 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
714template < 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.
728template < class T, unsigned Dim, class MeshType >
729void 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
751template < 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
766template < 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
787template < 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
802template < class T, unsigned Dim, class MeshType >
803std::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.
845template < 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.
864template < 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
911template < 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 PInsist(c, m)
Definition: PAssert.h:120
#define PAssert(c)
Definition: PAssert.h:102
#define WARNMSG(msg)
Definition: IpplInfo.h:349
iterator_iv end_iv()
Definition: FieldLayout.h:716
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
const NDIndex< Dim > & getDomain() const
Definition: FieldLayout.h:325
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 > *)
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
const NDRegion< T, Dim > & getDomain() const
Definition: RegionLayout.h:131
bool WeOwnFieldLayout
Definition: RegionLayout.h:249
void delete_rnodes()
NDIndex< Dim > getMeshVertices(MeshType *)
bool CenterOffset[Dim]
Definition: RegionLayout.h:262
void delete_flayout()
int IndexOffset[Dim]
Definition: RegionLayout.h:259
FieldLayout< Dim > & getFieldLayout()
Definition: RegionLayout.h:137
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