src/Particle/ParticleInteractLayout.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 /***************************************************************************
00003  *
00004  * The IPPL Framework
00005  * 
00006  *
00007  * Visit http://people.web.psi.ch/adelmann/ for more details
00008  *
00009  ***************************************************************************/
00010 
00011 #ifndef PARTICLE_INTERACT_LAYOUT_H
00012 #define PARTICLE_INTERACT_LAYOUT_H
00013 
00014 /*
00015  * ParticleInteractLayout - particle layout based on spatial decomposition,
00016  *   with particle interaction (nearest-neighbor with cutoff)
00017  *
00018  * This is a specialized version of ParticleLayout, which places particles
00019  * on processors based on their spatial location relative to a fixed grid.
00020  * In particular, this can maintain particles on processors based on a
00021  * specified FieldLayout or RegionLayout, so that particles are always on
00022  * the same node as the node containing the Field region to which they are
00023  * local.  This may also be used if there is no associated Field at all,
00024  * in which case a grid is selected based on an even distribution of
00025  * particles among processors.
00026  */
00027 
00028 // include files
00029 #include "Particle/ParticleSpatialLayout.h"
00030 #include "Particle/ParticleInteractAttrib.h"
00031 #include "Particle/ParticleBase.h"
00032 #include "Region/RegionLayout.h"
00033 
00034 #ifdef IPPL_STDSTL
00035 #include <vector>
00036 using std::vector;
00037 #else
00038 #include <vector.h>
00039 #endif // IPPL_STDSTL
00040 
00041 #ifdef IPPL_USE_STANDARD_HEADERS
00042 #include <iostream>
00043 using namespace std;
00044 #else
00045 #include <iostream.h>
00046 #endif
00047 
00048 // forward declarations
00049 class UserList;
00050 template <unsigned Dim> class FieldLayout;
00051 template <unsigned Dim, class T> class UniformCartesian;
00052 template <class T, unsigned Dim, class Mesh> class ParticleInteractLayout;
00053 template <class T, unsigned Dim, class Mesh>
00054 ostream& operator<<(ostream&, const ParticleInteractLayout<T,Dim,Mesh>&);
00055 
00056 
00057 // ParticleInteractLayout class definition.  Template parameters are the type
00058 // and dimension of the ParticlePos object used for the particles.  The
00059 // dimension of the position must match the dimension of the FieldLayout
00060 // object used in this particle layout, if any.
00061 // Optional template parameter for the mesh type
00062 template < class T, unsigned Dim, class Mesh=UniformCartesian<Dim,T> >
00063 class ParticleInteractLayout : public ParticleSpatialLayout<T, Dim, Mesh> {
00064 
00065 public:
00066   // a struct which holds data for a single pairwise interaction
00067   struct pair_t {
00068     unsigned first;             // index of 2nd member of pair
00069     T second;                   // separation of particles
00070     pair_t(unsigned f, T s) : first(f), second(s) { }
00071     pair_t() { }
00072   };
00073 
00074   // type of iterator over pairs
00075   typedef typename vector<pair_t>::iterator pair_iterator;
00076 
00077   typedef typename ParticleLayout<T, Dim>::SingleParticlePos_t
00078     SingleParticlePos_t;
00079   typedef typename ParticleLayout<T, Dim>::Index_t Index_t;
00080 
00081   // type of attributes this layout should use for position, ID, and rad
00082   typedef ParticleInteractAttrib<SingleParticlePos_t> ParticlePos_t;
00083   typedef ParticleInteractAttrib<Index_t>             ParticleIndex_t;
00084   typedef ParticleInteractAttrib<T>                   ParticleInterRadius_t;
00085 
00086 public:
00087   // constructor: The Field layout to which we match our particle's
00088   // locations.
00089   ParticleInteractLayout(FieldLayout<Dim>&);
00090 
00091   // constructor: this one also takes a Mesh
00092   ParticleInteractLayout(FieldLayout<Dim>&, Mesh&);
00093 
00094   // a similar constructor, but this one takes a RegionLayout.
00095   ParticleInteractLayout(const RegionLayout<T,Dim,Mesh>&);
00096 
00097   // a default constructor ... in this case, no layout will
00098   // be assumed by this class.  A layout may be given later via the
00099   // 'setLayout' method, either as a FieldLayout or as a RegionLayout.
00100   ParticleInteractLayout();
00101 
00102   // destructor
00103   ~ParticleInteractLayout();
00104 
00105   //
00106   // Particle swapping/update routines
00107   //
00108 
00109   // Update the location and indices of all atoms in the given ParticleBase
00110   // object.  This handles swapping particles among processors if
00111   // needed, and handles create and destroy requests.  When complete,
00112   // all nodes have correct layout information.
00113   void update(ParticleBase< ParticleInteractLayout<T,Dim,Mesh> >& p,
00114               const ParticleAttrib<char>* canSwap=0);
00115 
00116   //
00117   // Nearest-neighbor interaction calculation routines
00118   //
00119 
00120   // Retrieve a Forward-style iterator for the beginning and end of the
00121   // Nth (local) particle's nearest-neighbor pairlist.
00122   // If this is the first call of this
00123   // method after update(), this must make sure up-to-date info on particles
00124   // from neighboring nodes is available.
00125   void getPairlist(unsigned, pair_iterator&, pair_iterator&,
00126                    ParticleBase< ParticleInteractLayout<T,Dim,Mesh> >&);
00127 
00128   // specify the interaction radius ... two versions, one which gives a
00129   // single value for all atoms, the other giving a ParticleAttrib<T>
00130   // object with interaction radii for all the atoms in this object
00131   void setInteractionRadius(const T& r) {
00132     InterRadius = r;
00133     InterRadiusArray = 0;
00134     return;
00135   }
00136   void setInteractionRadius(ParticleInterRadius_t& rAttrib) {
00137     InterRadiusArray = &rAttrib;
00138     return;
00139   }
00140 
00141   // Return the maximum interaction radius of the entire system.  This is
00142   // the value from the most recent call to update()
00143   T getMaxInteractionRadius() { return MaxGlobalInterRadius; }
00144 
00145   // Return the interaction radius of atom i.
00146   T getInteractionRadius(unsigned i) {
00147     return (InterRadiusArray != 0 ? (*InterRadiusArray)[i] : InterRadius);
00148   }
00149 
00150   // directly set NeedGhostSwap flag to indicate whether this is needed
00151   // useful when a ParticleAttrib other than position R is modified and
00152   // we do not need to call update().
00153   void setNeedGhostSwap(bool cond=true) {
00154     NeedGhostSwap = cond;
00155   }
00156 
00157   //
00158   // virtual functions for FieldLayoutUser's (and other UserList users)
00159   //
00160 
00161   // Repartition onto a new layout
00162   virtual void Repartition(UserList *);
00163 
00164 private:
00165   // information needed to compute which ghost particles to send/receive
00166   bool NeedGhostSwap;
00167   bool* InterNodeList;
00168   bool* SentToNodeList;
00169   unsigned InteractionNodes;
00170 
00171   // pairlist storage - a set of vectors
00172   vector< vector<pair_t>* > PairList;
00173 
00174   // interaction radius data.  If the attribute pointer is null, use the
00175   // scalar value instead.
00176   // also, the maximum interaction radius for the local particles, and for all
00177   // the particles
00178   T InterRadius, MaxGlobalInterRadius;
00179   ParticleInterRadius_t *InterRadiusArray;
00180 
00181   // perform common constructor tasks
00182   void setup();
00183 
00184   // recalculate where we need to send ghost particles for building
00185   // nearest-neighbor interaction lists
00186   void rebuild_interaction_data();
00187 
00188   // recalculate where we need to send ghost particles for building
00189   // nearest-neighbor interaction lists
00190   // special version which accounts for periodic boundary conditions
00191   void rebuild_interaction_data(const bool periodicBC[2*Dim]);
00192 
00193   // copy particles to other nodes for pairlist computation.  The arguments
00194   // are the current number of local particles, and the ParticleBase object.
00195   // This will also calculate the pairlists if necessary.
00196   void swap_ghost_particles(unsigned,
00197                     ParticleBase< ParticleInteractLayout<T,Dim,Mesh> >&);
00198 
00199   // copy particles to other nodes for pairlist computation.  The arguments
00200   // are the current number of local particles, and the ParticleBase object.
00201   // This will also calculate the pairlists if necessary.
00202   // special version to take account of periodic boundaries
00203   void swap_ghost_particles(unsigned,
00204                     ParticleBase< ParticleInteractLayout<T,Dim,Mesh> >&,
00205                     const bool periodicBC[2*Dim]);
00206 
00207   // find the pairs between our local particles and particles a1 ... (a2 - 1).
00208   // if the last argument is true, initialize all the pairlists to be empty.
00209   void find_pairs(const unsigned LocalNum, const unsigned a1,
00210                   const unsigned a2, const bool initLists,
00211                   ParticleBase< ParticleInteractLayout<T,Dim,Mesh> >& PData);
00212 
00213   // change the value of the maximum local interaction radius
00214   void setMaxInteractionRadius(T maxval) { MaxGlobalInterRadius = maxval; }
00215 
00216   // Return the maximum interaction radius of the local particles.
00217   T getMaxLocalInteractionRadius();
00218 };
00219 
00220 #include "Particle/ParticleInteractLayout.cpp"
00221 
00222 #endif  // PARTICLE_INTERACT_LAYOUT_H
00223 
00224 /***************************************************************************
00225  * $RCSfile: ParticleInteractLayout.h,v $   $Author: adelmann $
00226  * $Revision: 1.1.1.1 $   $Date: 2003/01/23 07:40:29 $
00227  * IPPL_VERSION_ID: $Id: ParticleInteractLayout.h,v 1.1.1.1 2003/01/23 07:40:29 adelmann Exp $ 
00228  ***************************************************************************/

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