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_ATTRIB_H 00012 #define PARTICLE_INTERACT_ATTRIB_H 00013 00014 /* 00015 * ParticleInteractAttrib - Templated class for all particle attribute classes. 00016 * 00017 * This templated class is used to represent a single particle attribute. 00018 * An attribute is one data element within a particle object, and is 00019 * stored as an array. This class stores the type information for the 00020 * attribute, and provides methods to create and destroy new items, and 00021 * to perform operations involving this attribute with others. It also 00022 * provides iterators to allow the user to operate on single particles 00023 * instead of the entire array. 00024 * 00025 * ParticleInteractAttrib is the primary element involved in expressions for 00026 * particles (just as Field is the primary element there). This file 00027 * defines the necessary templated classes and functions to make 00028 * ParticleInteractAttrib a capable expression-template participant. 00029 * 00030 * For some types such as Vektor, Tenzor, etc. which have multipple items, 00031 * we want to involve just the Nth item from each data element in an 00032 * expression. The () operator here returns an object of type 00033 * ParticleInteractAttribElem, which will use the () operator on each 00034 * individual elem to access an item over which one can iterate and get the 00035 * Nth item from each data element. For example, if we have an attribute 00036 * like this: 00037 * ParticleInteractAttrib< Vektor<float, 4> > Data 00038 * we can involve just the 2nd item of each Vektor in an expression by 00039 * referring to this as 00040 * Data(1) 00041 * which returns an object of type ParticleAttribElem that knows to return 00042 * just the 2nd item from each Vektor. ParticleAttribElem is also expression- 00043 * template-aware; in fact, it is intended primarily for use in expressions 00044 * and not in many other situations. The ParticleAttribElem will use the 00045 * () operator to get the Nth item out of each data element, so this requires 00046 * the user to define operator () for the particle attribute type being 00047 * used (for Vektor, Tenzor, etc., this has already been done). This same 00048 * thing has been done for operator () involving either one or two indices, 00049 * which is needed to get the i,j element of a Tenzor, for example. 00050 * 00051 * Each ParticleInteractAttrib contains a set of ghost particle attributes as 00052 * well. These are stored in a separate vector container, but to users 00053 * this object looks like a single array with (local + ghost) attributes total. 00054 */ 00055 00056 // include files 00057 #include "Particle/ParticleAttrib.h" 00058 #include "PETE/IpplExpressions.h" 00059 00060 #ifdef IPPL_STDSTL 00061 #include <vector> 00062 using std::vector; 00063 #else 00064 #include <vector.h> 00065 #endif // IPPL_STDSTL 00066 00067 00068 // forward declarations 00069 class Inform; 00070 class Message; 00071 00072 // ParticleInteractAttrib class definition 00073 template <class T> 00074 class ParticleInteractAttrib : public ParticleAttrib<T> { 00075 00076 public: 00077 typedef typename ParticleAttrib<T>::ParticleList_t ParticleList_t; 00078 00079 // default constructor 00080 ParticleInteractAttrib() { } 00081 00082 // copy constructor 00083 ParticleInteractAttrib(const ParticleInteractAttrib<T>& pa) 00084 : ParticleAttrib<T>(pa), GhostList(pa.GhostList) { } 00085 ParticleInteractAttrib(const ParticleAttrib<T>& pa) 00086 : ParticleAttrib<T>(pa) { } 00087 00088 // destructor: delete the storage of the attribute array 00089 ~ParticleInteractAttrib() { } 00090 00091 // 00092 // Assignment operators 00093 // 00094 00095 // assign a general expression 00096 template<class T1> 00097 const ParticleInteractAttrib<T>& operator=(const PETE_Expr<T1>& rhs) { 00098 assign(*this,rhs); 00099 return *this; 00100 } 00101 00102 // assignment of a ParticleInteractAttrib 00103 const ParticleInteractAttrib<T>& operator=(const 00104 ParticleInteractAttrib<T>& rhs) { 00105 if (this->size() != rhs.size()) { 00106 ERRORMSG("Attempting to copy particle attributes with unequal sizes."); 00107 ERRORMSG("\n" << this->size() << " != " << rhs.size() << endl); 00108 } 00109 assign(*this,rhs); 00110 return *this; 00111 } 00112 00113 // assignment of a ParticleAttrib 00114 const ParticleInteractAttrib<T>& operator=(const ParticleAttrib<T>& rhs) { 00115 if (this->size() != rhs.size()) { 00116 ERRORMSG("Attempting to copy particle attributes with unequal sizes."); 00117 ERRORMSG("\n" << this->size() << " != " << rhs.size() << endl); 00118 } 00119 assign(*this,rhs); 00120 return *this; 00121 } 00122 00123 // assignment of a scalar 00124 const ParticleInteractAttrib<T>& operator=(T rhs) { 00125 assign(*this,rhs); 00126 return *this; 00127 } 00128 00129 // 00130 // methods specific to ghost particle data 00131 // 00132 00133 // provide a new version of the [] operator; if the argument is greater 00134 // than the size of our normal storage, then it refers to one of the 00135 // 'ghost' particles 00136 typename ParticleList_t::reference operator[](size_t n) { 00137 return (n < this->size() ? this->ParticleList[n] : GhostList[n - this->size()]); 00138 } 00139 00140 typename ParticleList_t::const_reference operator[](size_t n) const { 00141 return (n < this->size() ? this->ParticleList[n] : GhostList[n - this->size()]); 00142 } 00143 00144 // return the attrib data for the Nth ghost particle 00145 typename ParticleList_t::reference ghostAttrib(size_t n) 00146 { return GhostList[n]; } 00147 00148 typename ParticleList_t::const_reference ghostAttrib(size_t n) const 00149 { return GhostList[n]; } 00150 00151 // puts M particle's data starting from index I into a Message. 00152 // Return the number of particles put into the message. 00153 virtual size_t putMessage(Message&, size_t, size_t); 00154 00155 // Another version of putMessage, which takes list of indices 00156 // Return the number of particles put into the message. 00157 virtual size_t putMessage(Message& m, const vector<size_t>& v) { 00158 return ParticleAttrib<T>::putMessage(m, v); 00159 } 00160 00161 // 00162 // methods used to manipulate the ghost particle data 00163 // 00164 00165 // Delete the ghost attrib storage for M particles, starting at pos I. 00166 // Items from the end of the list are moved up to fill in the space. 00167 // Return the number of items actually destroyed. 00168 virtual size_t ghostDestroy(size_t M, size_t I); 00169 00170 // puts M particle's data starting from index I into a Message. 00171 // Return the number of particles put into the message. This is for 00172 // when particles are being swapped to build ghost particle interaction 00173 // lists. 00174 virtual size_t ghostPutMessage(Message &msg, size_t M, size_t I) { 00175 return putMessage(msg, M, I); 00176 } 00177 // puts data for a list of particles into a Message, for interaction lists. 00178 // Return the number of particles put into the message. 00179 virtual size_t ghostPutMessage(Message &msg, const vector<size_t> &v) { 00180 return putMessage(msg, v); 00181 } 00182 00183 // Get ghost particle data from a message. 00184 virtual size_t ghostGetMessage(Message&, size_t); 00185 00186 // 00187 // other functions 00188 // 00189 00190 // Print out information for debugging purposes. 00191 virtual void printDebug(Inform&); 00192 00193 private: 00194 // storage for 'ghost' particles, those stored on the local node which 00195 // actually belong to other nodes 00196 ParticleList_t GhostList; 00197 }; 00198 00199 #include "Particle/ParticleInteractAttrib.cpp" 00200 00201 #endif // PARTICLE_INTERACT_ATTRIB_H 00202 00203 /*************************************************************************** 00204 * $RCSfile: ParticleInteractAttrib.h,v $ $Author: adelmann $ 00205 * $Revision: 1.1.1.1 $ $Date: 2003/01/23 07:40:29 $ 00206 * IPPL_VERSION_ID: $Id: ParticleInteractAttrib.h,v 1.1.1.1 2003/01/23 07:40:29 adelmann Exp $ 00207 ***************************************************************************/