src/Particle/ParticleBalancer.cpp

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  * This program was prepared by PSI. 
00007  * All rights in the program are reserved by PSI.
00008  * Neither PSI nor the author(s)
00009  * makes any warranty, express or implied, or assumes any liability or
00010  * responsibility for the use of this software
00011  *
00012  * Visit http://www.acl.lanl.gov/POOMS for more details
00013  *
00014  ***************************************************************************/
00015 
00016 // -*- C++ -*-
00017 /***************************************************************************
00018  *
00019  * The IPPL Framework
00020  * 
00021  *
00022  * Visit http://people.web.psi.ch/adelmann/ for more details
00023  *
00024  ***************************************************************************/
00025 
00026 // include files
00027 #include "Particle/ParticleBalancer.h"
00028 #include "Particle/ParticleBase.h"
00029 #include "Particle/ParticleSpatialLayout.h"
00030 #include "Particle/ParticleUniformLayout.h"
00031 #include "Particle/ParticleAttrib.h"
00032 #include "Particle/IntNGP.h"
00033 #include "Region/RegionLayout.h"
00034 #include "Index/NDIndex.h"
00035 #include "FieldLayout/FieldLayout.h"
00036 #include "FieldLayout/BinaryBalancer.h"
00037 #include "Utility/IpplInfo.h"
00038 #include "Profile/Profiler.h"
00039 
00040 
00042 // calculate a new RegionLayout for a given ParticleBase, and distribute the
00043 // new RegionLayout to all the nodes.  This uses a Field BinaryBalancer.
00044 template < class T, unsigned Dim, class Mesh>
00045 void
00046 BinaryRepartition(ParticleBase<ParticleSpatialLayout<T,Dim,Mesh> >& PB) {
00047   TAU_TYPE_STRING(taustr, "void (" + CT(PB) + " )");
00048   TAU_PROFILE("BinaryRepartition()", taustr, TAU_PARTICLE);
00049 
00050   static IntNGP interp; // to scatter particle density
00051 
00052   //Inform dbgmsg("Particle BinaryRepartition", INFORM_ALL_NODES);
00053   //dbgmsg << "Performing particle load balancing, for ";
00054   //dbgmsg << PB.getTotalNum() << " particles ..." << endl;
00055 
00056   // get the internal FieldLayout from the Particle object's internal
00057   // RegionLayout.  From this, we make a new Field (we do not need a
00058   RegionLayout<T,Dim,Mesh>& RL = PB.getLayout().getLayout();
00059   if ( ! RL.initialized()) {
00060     ERRORMSG("Cannot repartition particles: uninitialized layout." << endl);
00061     return;
00062   }
00063   FieldLayout<Dim>& FL = RL.getFieldLayout();
00064   Mesh& mesh = RL.getMesh();
00065 
00066   // NDIndex which describes the entire domain ... if a particle is
00067   // outside this region, we are in trouble!
00068   const NDIndex<Dim>& TotalDomain = FL.getDomain();
00069 
00070   // for all the particles, do the following:
00071   //   1. get the position, and invert to the 'FieldLayout' index space
00072   //   2. increment the field at the position near this index position
00073   NDIndex<Dim> indx;
00074 
00075   // By default, we do the number density computation and repartition of
00076   // index space on a cell-centered Field.  If FieldLayout is vertex-centered,
00077   // we'll need to make some adjustments here.
00078   bool CenterOffset[Dim];
00079   int CenteringTotal = 0;
00080   unsigned int d;
00081   for (d=0; d<Dim; ++d) {
00082     CenterOffset[d] = (TotalDomain[d].length() < mesh.gridSizes[d]);
00083     CenteringTotal += CenterOffset[d];
00084   }
00085 
00086   if (CenteringTotal == Dim) { // allCell centering
00087     Field<double,Dim,Mesh,Cell> BF(mesh,FL,GuardCellSizes<Dim>(1));
00088 
00089     // Now do a number density scatter on this Field
00090     // Afterwards, the Field will be deleted, and will checkout of the
00091     // FieldLayout.  This is desired so that when we repartition the
00092     // FieldLayout, we do not waste time redistributing the Field's data.
00093     BF = 0.0;
00094     scatter(BF,PB.R,interp);
00095 
00096     // calculate a new repartitioning of the field, and use this to repartition
00097     // the FieldLayout used inside the Particle object
00098     indx = CalcBinaryRepartition(FL, BF);
00099   }
00100   else if (CenteringTotal == 0) { // allVert centering
00101     Field<double,Dim,Mesh,Vert> BF(mesh,FL,GuardCellSizes<Dim>(1));
00102 
00103     // Now do a number density scatter on this Field
00104     // Afterwards, the Field will be deleted, and will checkout of the
00105     // FieldLayout.  This is desired so that when we repartition the
00106     // FieldLayout, we do not waste time redistributing the Field's data.
00107     BF = 0.0;
00108     scatter(BF,PB.R,interp);
00109 
00110     // calculate a new repartitioning of the field, and use this to repartition
00111     // the FieldLayout used inside the Particle object
00112     indx = CalcBinaryRepartition(FL, BF);
00113   }
00114   else {
00115     ERRORMSG("Not implemented for face- and edge-centered Fields!!" << endl);
00116     Ippl::abort();
00117   }
00118 
00119   // now, we can repartition the FieldLayout within the RegionLayout
00120   RL.RepartitionLayout(indx);
00121   PB.update();
00122 }
00123 
00124 
00125 // the same, but taking a uniform layout (this will not actually do anything)
00126 template<class T, unsigned Dim>
00127 void
00128 BinaryRepartition(ParticleBase<ParticleUniformLayout<T,Dim> >&) {
00129   // for a uniform layout, this repartition method does nothing, so just
00130   // exit
00131   return;
00132 }
00133 
00134 
00135 /***************************************************************************
00136  * $RCSfile: ParticleBalancer.cpp,v $   $Author: adelmann $
00137  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:28 $
00138  * IPPL_VERSION_ID: $Id: ParticleBalancer.cpp,v 1.1.1.1 2003/01/23 07:40:28 adelmann Exp $ 
00139  ***************************************************************************/
00140 
00141 

Generated on Mon Jan 16 13:23:52 2006 for IPPL by  doxygen 1.4.6