ESyS-Particle
4.0.1
|
00001 00002 // // 00003 // Copyright (c) 2003-2011 by The University of Queensland // 00004 // Earth Systems Science Computational Centre (ESSCC) // 00005 // http://www.uq.edu.au/esscc // 00006 // // 00007 // Primary Business: Brisbane, Queensland, Australia // 00008 // Licensed under the Open Software License version 3.0 // 00009 // http://www.opensource.org/licenses/osl-3.0.php // 00010 // // 00012 00013 template<typename P,typename InteractionType> 00014 const int ParallelInteractionStorage_E<P,InteractionType>::m_exchg_tag=43; 00015 00022 template<typename P,typename I> 00023 ParallelInteractionStorage_E<P,I>::ParallelInteractionStorage_E( 00024 AParallelParticleArray* PPA, 00025 const typename I::ParameterType& param 00026 ) 00027 : TParallelInteractionStorage<I>(PPA), 00028 m_comm(PPA->getComm()), 00029 m_param(param) 00030 { 00031 m_unbreakable=false; 00032 } 00033 00037 template<typename P,typename InteractionType> 00038 void ParallelInteractionStorage_E<P,InteractionType>::exchange() 00039 { 00040 for(int i=0;i<3;i++){ 00041 if(m_comm.get_dim(i)>1){ 00042 // -- up -- 00043 exchange_boundary(i,1); 00044 // -- down -- 00045 exchange_boundary(i,-1); 00046 } 00047 } 00048 } 00049 00056 template<typename P,typename InteractionType> 00057 void ParallelInteractionStorage_E<P,InteractionType>::exchange_boundary(int dim,int dir) 00058 { 00059 console.XDebug() << "PIS_E::exchange_boundary(" << dim << "," << dir << ") at node " << m_comm.rank() << "\n"; 00060 set<int> bdry_ids; 00061 vector<InteractionType> recv_buffer; 00062 vector<InteractionType> send_buffer; 00063 00064 // get boundary 00065 bdry_ids = this->m_ppa->getBoundarySlabIds(dim,dir); 00066 // for all interactions 00067 for( 00068 typename list<InteractionType>::iterator iter = this->m_interactions.begin(); 00069 iter != this->m_interactions.end(); 00070 iter++ 00071 ){ 00072 vector<int> pids=iter->getAllID(); // get particle IDs 00073 bool flag=false; 00074 // check if any id is in boundary slab 00075 vector<int>::iterator it2=pids.begin(); 00076 while(it2!=pids.end() && !flag){ 00077 flag=(bdry_ids.find(*it2)!=bdry_ids.end()); 00078 it2++; 00079 } 00080 if(flag){ 00081 send_buffer.push_back(*iter); 00082 } 00083 } 00084 // shift 00085 m_comm.shift_cont_packed(send_buffer,recv_buffer,dim,dir,m_exchg_tag); 00086 // try to insert the received interactions 00087 for(typename vector<InteractionType>::iterator iter=recv_buffer.begin(); 00088 iter!=recv_buffer.end(); 00089 iter++){ 00090 tryInsert(*iter); 00091 } 00092 // clean buffers 00093 send_buffer.clear(); 00094 recv_buffer.clear(); 00095 console.XDebug() << "end PIS_E::exchange_boundary(" << dim << "," << dir << ") at node " << m_comm.rank() << "\n"; 00096 } 00097 00102 template<typename P,typename InteractionType> 00103 void ParallelInteractionStorage_E<P,InteractionType>::rebuild() 00104 { 00105 console.XDebug() << "PIS_E::rebuild at node " << m_comm.rank() << "\n"; 00106 console.XDebug() << "size pre rebuild: " << this->m_interactions.size() << "\n"; 00107 00108 // -- DEBUG --- 00109 for(typename list<InteractionType>::iterator iter = this->m_interactions.begin(); 00110 iter!=this->m_interactions.end(); 00111 iter++){ 00112 vector<int> pids=iter->getAllID(); 00113 console.XDebug() << pids[0] << " - " << pids[1] << "\n"; 00114 } 00115 // --- END DEBUG --- 00116 vector<P*> pptr; 00117 ParallelParticleArray<P>* t_ppa=(ParallelParticleArray<P>*)(this->m_ppa); 00118 typename list<InteractionType>::iterator iter = this->m_interactions.begin(); 00119 while(iter != this->m_interactions.end()){ 00120 vector<int> pids=iter->getAllID(); 00121 vector<int>::const_iterator it2=pids.begin(); 00122 bool flag=true; 00123 // check if the particles with the stored IDs are here 00124 while(it2!=pids.end() && flag){ 00125 P* ptr=t_ppa->getParticlePtrByIndex(*it2); 00126 if(ptr!=NULL){ 00127 pptr.push_back(ptr); 00128 } else { 00129 flag=false; 00130 } 00131 it2++; 00132 } 00133 if(flag){ // if all particle IDs are valid -> set particle pointers 00134 iter->setPP(pptr); 00135 iter->checkIDs(); 00136 iter++; 00137 } else { // if not -> erase interactions 00138 const typename list<InteractionType>::iterator er_iter=iter; 00139 iter++; 00140 this->m_interactions.erase(er_iter); 00141 m_set.erase(make_pair(pids[0],pids[1])); 00142 } 00143 pptr.clear(); 00144 } 00145 console.XDebug() << "size post rebuild: " << this->m_interactions.size() << "\n"; 00146 // cout << "end PIS_E::rebuild at node " << m_comm.rank() << endl; 00147 } 00148 00149 00156 template<typename P,typename InteractionType> 00157 void ParallelInteractionStorage_E<P,InteractionType>::tryInsert(const InteractionType& In) 00158 { 00159 bool flag=true; 00160 00161 ParallelParticleArray<P>* t_ppa=(ParallelParticleArray<P>*)(this->m_ppa); 00162 // check if interaction is already in 00163 vector<int> pids=In.getAllID(); 00164 flag=!isIn(pids); 00165 // try to get particle pointers from ppa 00166 vector<int>::const_iterator iter=pids.begin(); 00167 while(iter!=pids.end() && flag){ 00168 P* ptr=t_ppa->getParticlePtrByIndex(*iter); 00169 if(ptr!=NULL){ 00170 //pptr.push_back(ptr); 00171 } else { 00172 flag=false; 00173 } 00174 iter++; 00175 } 00176 00177 if(flag){ 00178 this->m_interactions.push_back(In); 00179 m_set.insert(make_pair(pids[0],pids[1])); 00180 } 00181 } 00182 00186 template<typename P,typename InteractionType> 00187 bool ParallelInteractionStorage_E<P,InteractionType>::isIn(const vector<int>& pids) 00188 { 00189 bool res; 00190 00191 if(pids[0] > pids [1]){ 00192 console.Debug()<< "flipped PIDS : " << pids[0] << "," << pids[1] << "\n"; 00193 } 00194 res=m_set.find(make_pair(pids[0],pids[1]))!=m_set.end(); 00195 00196 return res; 00197 } 00198 00199 00207 template<typename P,typename InteractionType> 00208 void ParallelInteractionStorage_E<P,InteractionType>::tryInsert(const vector<int>& pids) 00209 { 00210 vector<P*> pptr; 00211 bool flag=true; 00212 00213 ParallelParticleArray<P>* t_ppa=(ParallelParticleArray<P>*)(this->m_ppa); 00214 // check if interaction is already in 00215 flag=!isIn(pids); 00216 // try to get particle pointers from ppa 00217 vector<int>::const_iterator iter=pids.begin(); 00218 while(iter!=pids.end() && flag){ 00219 P* ptr=t_ppa->getParticlePtrByIndex(*iter); 00220 if(ptr!=NULL){ 00221 pptr.push_back(ptr); 00222 } else { 00223 flag=false; 00224 } 00225 iter++; 00226 } 00227 00228 if(flag){ 00229 // initialize interaction from particle pointers and interaction parameters 00230 InteractionType new_interaction(pptr[0],pptr[1],m_param); 00231 vector<int> allid=new_interaction.getAllID(); 00232 console.XDebug() << allid[0] << " , " << allid[1] << "\n"; 00233 // insert interaction 00234 this->m_interactions.push_back(new_interaction); 00235 this->m_set.insert(make_pair(pids[0],pids[1])); 00236 } 00237 } 00238 00242 template<typename P,typename InteractionType> 00243 void ParallelInteractionStorage_E<P,InteractionType>::calcForces() 00244 { 00245 console.Debug() 00246 << "calculating " 00247 << this->m_interactions.size() 00248 << " interaction forces\n" ; 00249 00250 for( 00251 typename list<InteractionType>::iterator it = this->m_interactions.begin(); 00252 it != this->m_interactions.end(); 00253 it++ 00254 ){ 00255 it->calcForces(); 00256 } 00257 } 00258 00264 template<typename P,typename InteractionType> 00265 void ParallelInteractionStorage_E<P,InteractionType>::setUnbreakable(bool b) 00266 { 00267 m_unbreakable=b; 00268 }