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 00014 #ifndef ESYS_LSMNEIGHBOURTABLE_HPP 00015 #define ESYS_LSMNEIGHBOURTABLE_HPP 00016 00017 namespace esys 00018 { 00019 namespace lsm 00020 { 00021 template <class TmplParticle> 00022 NeighbourTable<TmplParticle>::NeighbourTable( 00023 const BoundingBox &bBox, 00024 double gridSpacing 00025 ) 00026 : m_dimensions(), 00027 m_minIndex(), 00028 m_maxIndex(Vec3L(-1, -1, -1)), 00029 m_gridSpacing(gridSpacing), 00030 m_bBox(bBox), 00031 m_insertedParticles(), 00032 m_tablePtr() 00033 { 00034 resize(bBox, gridSpacing); 00035 } 00036 00037 template <class TmplParticle> 00038 NeighbourTable<TmplParticle>::NeighbourTable( 00039 const NeighbourTable &nTable 00040 ) 00041 : m_dimensions(nTable.m_dimensions), 00042 m_minIndex(nTable.m_minIndex), 00043 m_maxIndex(nTable.m_maxIndex), 00044 m_gridSpacing(nTable.m_gridSpacing), 00045 m_bBox(nTable.m_bBox), 00046 m_insertedParticles(nTable.m_insertedParticles), 00047 m_tablePtr() 00048 { 00049 m_tablePtr = 00050 ParticleVectorArrayPtr( 00051 new ParticleVector[nTable.getNumCells()] 00052 ); 00053 for (int i = 0; i < nTable.getNumCells(); i++) 00054 { 00055 m_tablePtr[i] = nTable.m_tablePtr[i]; 00056 } 00057 } 00058 00059 template <class TmplParticle> 00060 NeighbourTable<TmplParticle>::~NeighbourTable() 00061 { 00062 } 00063 00064 template <class TmplParticle> 00065 void NeighbourTable<TmplParticle>::clear() 00066 { 00067 for (int i = getMinVecIndex().X(); i <= getMaxVecIndex().X(); i++) { 00068 for (int j = getMinVecIndex().Y(); j <= getMaxVecIndex().Y(); j++) { 00069 for (int k = getMinVecIndex().Z(); k <= getMaxVecIndex().Z(); k++) { 00070 m_tablePtr[getScalarIndex(i, j, k)].clear(); 00071 } 00072 } 00073 } 00074 m_insertedParticles.clear(); 00075 } 00076 00077 template <class TmplParticle> 00078 double NeighbourTable<TmplParticle>::getGridSpacing() const 00079 { 00080 return m_gridSpacing; 00081 } 00082 00083 template <class TmplParticle> 00084 void NeighbourTable<TmplParticle>::resize( 00085 const BoundingBox &bBox, 00086 double gridSpacing 00087 ) 00088 { 00089 ParticleVector particles = getInsertedParticles(); 00090 clearAndRecomputeGrid(bBox, gridSpacing); 00091 for ( 00092 typename ParticleVector::iterator it = particles.begin(); 00093 it != particles.end(); 00094 it++ 00095 ) 00096 { 00097 insert(*it); 00098 } 00099 } 00100 00101 template <class TmplParticle> 00102 const Vec3L & 00103 NeighbourTable<TmplParticle>::getDimensions() const 00104 { 00105 return m_dimensions; 00106 } 00107 00108 template <class TmplParticle> 00109 const BoundingBox & 00110 NeighbourTable<TmplParticle>::getBBox() const 00111 { 00112 return m_bBox; 00113 } 00114 00115 template <class TmplParticle> 00116 const Vec3 & 00117 NeighbourTable<TmplParticle>::getMinPt() const 00118 { 00119 return getBBox().getMinPt(); 00120 } 00121 00122 template <class TmplParticle> 00123 size_t NeighbourTable<TmplParticle>::size() const 00124 { 00125 return m_insertedParticles.size(); 00126 } 00127 00128 template <class TmplParticle> 00129 int NeighbourTable<TmplParticle>::getScalarIndex( 00130 int xIdx, 00131 int yIdx, 00132 int zIdx 00133 ) const 00134 { 00135 return 00136 xIdx*m_dimensions.Z()*m_dimensions.Y() 00137 + 00138 yIdx*m_dimensions.Z() 00139 + 00140 zIdx; 00141 } 00142 00143 template <class TmplParticle> 00144 int NeighbourTable<TmplParticle>::getScalarIndex(const Vec3L &index) const 00145 { 00146 return getScalarIndex(index.X(), index.Y(), index.Z()); 00147 } 00148 00149 template <class TmplParticle> 00150 int 00151 NeighbourTable<TmplParticle>::getScalarIndex(const Vec3 &pt) const 00152 { 00153 return getScalarIndex(getVecIndex(pt)); 00154 } 00155 00156 template <class TmplParticle> 00157 const Vec3L & 00158 NeighbourTable<TmplParticle>::getMinVecIndex() const 00159 { 00160 return m_minIndex; 00161 } 00162 00163 template <class TmplParticle> 00164 const Vec3L & 00165 NeighbourTable<TmplParticle>::getMaxVecIndex() const 00166 { 00167 return m_maxIndex; 00168 } 00169 00170 template <class TmplParticle> 00171 Vec3L 00172 NeighbourTable<TmplParticle>::getVecIndex(const Vec3 &pt) const 00173 { 00174 const Vec3 relPos = Vec3((pt - getMinPt())/m_gridSpacing); 00175 const Vec3L index = Vec3L(int(floor(relPos.X())), int(floor(relPos.Y())), int(floor(relPos.Z()))); 00176 return getMinVecIndex().max(getMaxVecIndex().min(index)); 00177 } 00178 00179 template <class TmplParticle> 00180 typename NeighbourTable<TmplParticle>::ParticleVector 00181 NeighbourTable<TmplParticle>::getNeighbourVector( 00182 const Vec3 &pt, 00183 double radius 00184 ) const 00185 { 00186 ParticleVector neighbours; 00187 neighbours.reserve(128); 00188 const Vec3L min = getVecIndex(pt - radius); 00189 const Vec3L max = getVecIndex(pt + radius); 00190 for (int i = min.X(); i <= max.X(); i++) { 00191 for (int j = min.Y(); j <= max.Y(); j++) { 00192 for (int k = min.Z(); k <= max.Z(); k++) { 00193 neighbours.insert( 00194 neighbours.end(), 00195 m_tablePtr[getScalarIndex(i, j, k)].begin(), 00196 m_tablePtr[getScalarIndex(i, j, k)].end() 00197 ); 00198 } 00199 } 00200 } 00201 return neighbours; 00202 } 00203 00204 template <class TmplParticle> 00205 typename NeighbourTable<TmplParticle>::ParticleVector 00206 NeighbourTable<TmplParticle>::getUniqueNeighbourVector( 00207 const Vec3 &pt, 00208 double radius 00209 ) const 00210 { 00211 ParticleVector neighbours = getNeighbourVector(pt, radius); 00212 std::sort(neighbours.begin(), neighbours.end()); 00213 typename ParticleVector::iterator uniqueEnd = 00214 std::unique(neighbours.begin(), neighbours.end()); 00215 neighbours.erase( 00216 uniqueEnd, 00217 neighbours.end() 00218 ); 00219 00220 return neighbours; 00221 } 00222 00223 template <class TmplParticle> 00224 typename NeighbourTable<TmplParticle>::ParticleVector 00225 NeighbourTable<TmplParticle>::getNeighbourVector( 00226 const Vec3 &pt 00227 ) const 00228 { 00229 return m_tablePtr[getScalarIndex(pt)]; 00230 } 00231 00232 template <class TmplParticle> 00233 void NeighbourTable<TmplParticle>::insert(Particle *pParticle) 00234 { 00235 const Vec3L minIdx = getVecIndex(pParticle->getPos() - pParticle->getRad()); 00236 const Vec3L maxIdx = getVecIndex(pParticle->getPos() + pParticle->getRad()); 00237 insertInTable(pParticle, minIdx, maxIdx); 00238 addInserted(pParticle); 00239 } 00240 00241 template <class TmplParticle> 00242 void NeighbourTable<TmplParticle>::insert(Particle &particle) 00243 { 00244 insert(&particle); 00245 } 00246 00247 template <class TmplParticle> 00248 typename NeighbourTable<TmplParticle>::ParticleIterator 00249 NeighbourTable<TmplParticle>::getParticleIterator() 00250 { 00251 return ParticleIterator(m_insertedParticles); 00252 } 00253 00254 template <class TmplParticle> 00255 typename NeighbourTable<TmplParticle>::ParticleConstIterator 00256 NeighbourTable<TmplParticle>::getParticleIterator() const 00257 { 00258 return ParticleConstIterator(m_insertedParticles); 00259 } 00260 00261 template <class TmplParticle> 00262 void NeighbourTable<TmplParticle>::insertInTable( 00263 Particle *pParticle, 00264 const Vec3L &minIdx, 00265 const Vec3L &maxIdx 00266 ) 00267 { 00268 for (int i = minIdx.X(); i <= maxIdx.X(); i++) { 00269 for (int j = minIdx.Y(); j <= maxIdx.Y(); j++) { 00270 for (int k = minIdx.Z(); k <= maxIdx.Z(); k++) { 00271 m_tablePtr[getScalarIndex(i, j, k)].push_back(pParticle); 00272 } 00273 } 00274 } 00275 } 00276 00277 template <class TmplParticle> 00278 void NeighbourTable<TmplParticle>::addInserted(Particle *pParticle) 00279 { 00280 m_insertedParticles.push_back(pParticle); 00281 } 00282 00283 template <class TmplParticle> 00284 int NeighbourTable<TmplParticle>::getNumCells() const 00285 { 00286 return getDimensions()[0]*getDimensions()[1]*getDimensions()[2]; 00287 } 00288 00289 template <class TmplParticle> 00290 typename NeighbourTable<TmplParticle>::ParticleVector 00291 NeighbourTable<TmplParticle>::getInsertedParticles() const 00292 { 00293 return m_insertedParticles; 00294 } 00295 00296 template <class TmplParticle> 00297 void NeighbourTable<TmplParticle>::clearAndRecomputeGrid( 00298 const BoundingBox &bBox, 00299 double gridSpacing 00300 ) 00301 { 00302 clear(); 00303 m_bBox = bBox; 00304 m_gridSpacing = gridSpacing; 00305 00306 const Vec3 dims = m_bBox.getSizes()/gridSpacing; 00307 m_dimensions = 00308 Vec3L( 00309 int(floor(dims[0])), 00310 int(floor(dims[1])), 00311 int(floor(dims[2])) 00312 ); 00313 m_dimensions = m_dimensions.max(Vec3L(1, 1, 1)); 00314 00315 m_tablePtr = 00316 ParticleVectorArrayPtr( 00317 new ParticleVector[ 00318 m_dimensions.X()*m_dimensions.Y()*m_dimensions.Z() 00319 ] 00320 ); 00321 m_minIndex = Vec3L(0, 0, 0); 00322 m_maxIndex = (m_dimensions - 1); 00323 } 00324 } 00325 } 00326 00327 #endif