Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "Cloud.H"
00027 #include <OpenFOAM/processorPolyPatch.H>
00028 #include <OpenFOAM/globalMeshData.H>
00029 #include <OpenFOAM/PstreamCombineReduceOps.H>
00030 #include <OpenFOAM/mapPolyMesh.H>
00031 #include <OpenFOAM/Time.H>
00032 #include <OpenFOAM/OFstream.H>
00033
00034
00035
00036 template<class ParticleType>
00037 Foam::Cloud<ParticleType>::Cloud
00038 (
00039 const polyMesh& pMesh,
00040 const IDLList<ParticleType>& particles
00041 )
00042 :
00043 cloud(pMesh),
00044 IDLList<ParticleType>(),
00045 polyMesh_(pMesh),
00046 particleCount_(0)
00047 {
00048 IDLList<ParticleType>::operator=(particles);
00049 }
00050
00051
00052 template<class ParticleType>
00053 Foam::Cloud<ParticleType>::Cloud
00054 (
00055 const polyMesh& pMesh,
00056 const word& cloudName,
00057 const IDLList<ParticleType>& particles
00058 )
00059 :
00060 cloud(pMesh, cloudName),
00061 IDLList<ParticleType>(),
00062 polyMesh_(pMesh),
00063 particleCount_(0)
00064 {
00065 IDLList<ParticleType>::operator=(particles);
00066 }
00067
00068
00069
00070
00071 template<class ParticleType>
00072 Foam::label Foam::Cloud<ParticleType>::getNewParticleID() const
00073 {
00074 label id = particleCount_++;
00075
00076 if (id == labelMax)
00077 {
00078 WarningIn("Cloud<ParticleType>::getNewParticleID() const")
00079 << "Particle counter has overflowed. This might cause problems"
00080 << " when reconstructing particle tracks." << endl;
00081 }
00082 return id;
00083 }
00084
00085
00086 template<class ParticleType>
00087 void Foam::Cloud<ParticleType>::addParticle(ParticleType* pPtr)
00088 {
00089 this->append(pPtr);
00090 }
00091
00092
00093 template<class ParticleType>
00094 void Foam::Cloud<ParticleType>::deleteParticle(ParticleType& p)
00095 {
00096 delete(this->remove(&p));
00097 }
00098
00099
00100 namespace Foam
00101 {
00102
00103 class combineNsTransPs
00104 {
00105
00106 public:
00107
00108 void operator()(labelListList& x, const labelListList& y) const
00109 {
00110 forAll(y, i)
00111 {
00112 if (y[i].size())
00113 {
00114 x[i] = y[i];
00115 }
00116 }
00117 }
00118 };
00119
00120 }
00121
00122
00123 template<class ParticleType>
00124 template<class TrackingData>
00125 void Foam::Cloud<ParticleType>::move(TrackingData& td)
00126 {
00127 const globalMeshData& pData = polyMesh_.globalData();
00128 const labelList& processorPatches = pData.processorPatches();
00129 const labelList& processorPatchIndices = pData.processorPatchIndices();
00130 const labelList& processorPatchNeighbours =
00131 pData.processorPatchNeighbours();
00132
00133
00134 forAllIter(typename Cloud<ParticleType>, *this, pIter)
00135 {
00136 pIter().stepFraction() = 0;
00137 }
00138
00139
00140 bool transfered = true;
00141
00142
00143 while (transfered)
00144 {
00145
00146
00147 List<IDLList<ParticleType> > transferList(processorPatches.size());
00148
00149
00150 forAllIter(typename Cloud<ParticleType>, *this, pIter)
00151 {
00152 ParticleType& p = pIter();
00153
00154
00155 bool keepParticle = p.move(td);
00156
00157
00158
00159 if (keepParticle)
00160 {
00161
00162
00163 if (Pstream::parRun() && p.facei_ >= pMesh().nInternalFaces())
00164 {
00165 label patchi = pMesh().boundaryMesh().whichPatch(p.facei_);
00166 label n = processorPatchIndices[patchi];
00167
00168
00169
00170 if (n != -1)
00171 {
00172 p.prepareForParallelTransfer(patchi, td);
00173 transferList[n].append(this->remove(&p));
00174 }
00175 }
00176 }
00177 else
00178 {
00179 deleteParticle(p);
00180 }
00181 }
00182
00183 if (Pstream::parRun())
00184 {
00185
00186
00187 labelList nsTransPs(transferList.size());
00188
00189 forAll(transferList, i)
00190 {
00191 nsTransPs[i] = transferList[i].size();
00192 }
00193
00194
00195
00196 labelListList allNTrans(Pstream::nProcs());
00197 allNTrans[Pstream::myProcNo()] = nsTransPs;
00198 combineReduce(allNTrans, combineNsTransPs());
00199
00200 transfered = false;
00201
00202 forAll(allNTrans, i)
00203 {
00204 forAll(allNTrans[i], j)
00205 {
00206 if (allNTrans[i][j])
00207 {
00208 transfered = true;
00209 break;
00210 }
00211 }
00212 }
00213
00214 if (!transfered)
00215 {
00216 break;
00217 }
00218
00219 forAll(transferList, i)
00220 {
00221 if (transferList[i].size())
00222 {
00223 OPstream particleStream
00224 (
00225 Pstream::blocking,
00226 refCast<const processorPolyPatch>
00227 (
00228 pMesh().boundaryMesh()[processorPatches[i]]
00229 ).neighbProcNo()
00230 );
00231
00232 particleStream << transferList[i];
00233 }
00234 }
00235
00236 forAll(processorPatches, i)
00237 {
00238 label patchi = processorPatches[i];
00239
00240 const processorPolyPatch& procPatch =
00241 refCast<const processorPolyPatch>
00242 (pMesh().boundaryMesh()[patchi]);
00243
00244 label neighbProci =
00245 procPatch.neighbProcNo() - Pstream::masterNo();
00246
00247 label neighbProcPatchi = processorPatchNeighbours[patchi];
00248
00249 label nRecPs = allNTrans[neighbProci][neighbProcPatchi];
00250
00251 if (nRecPs)
00252 {
00253 IPstream particleStream
00254 (
00255 Pstream::blocking,
00256 procPatch.neighbProcNo()
00257 );
00258 IDLList<ParticleType> newParticles
00259 (
00260 particleStream,
00261 typename ParticleType::iNew(*this)
00262 );
00263
00264 forAllIter
00265 (
00266 typename Cloud<ParticleType>,
00267 newParticles,
00268 newpIter
00269 )
00270 {
00271 ParticleType& newp = newpIter();
00272 newp.correctAfterParallelTransfer(patchi, td);
00273 addParticle(newParticles.remove(&newp));
00274 }
00275 }
00276 }
00277 }
00278 else
00279 {
00280 transfered = false;
00281 }
00282 }
00283 }
00284
00285
00286 template<class ParticleType>
00287 void Foam::Cloud<ParticleType>::autoMap(const mapPolyMesh& mapper)
00288 {
00289 if (cloud::debug)
00290 {
00291 Info<< "Cloud<ParticleType>::autoMap(const morphFieldMapper& map) "
00292 "for lagrangian cloud " << cloud::name() << endl;
00293 }
00294
00295 const labelList& reverseCellMap = mapper.reverseCellMap();
00296 const labelList& reverseFaceMap = mapper.reverseFaceMap();
00297
00298 forAllIter(typename Cloud<ParticleType>, *this, pIter)
00299 {
00300 if (reverseCellMap[pIter().celli_] >= 0)
00301 {
00302 pIter().celli_ = reverseCellMap[pIter().celli_];
00303
00304 if (pIter().facei_ >= 0 && reverseFaceMap[pIter().facei_] >= 0)
00305 {
00306 pIter().facei_ = reverseFaceMap[pIter().facei_];
00307 }
00308 else
00309 {
00310 pIter().facei_ = -1;
00311 }
00312 }
00313 else
00314 {
00315 label trackStartCell = mapper.mergedCell(pIter().celli_);
00316
00317 if (trackStartCell < 0)
00318 {
00319 trackStartCell = 0;
00320 }
00321
00322 vector p = pIter().position();
00323 const_cast<vector&>(pIter().position()) =
00324 polyMesh_.cellCentres()[trackStartCell];
00325 pIter().stepFraction() = 0;
00326 pIter().track(p);
00327 }
00328 }
00329 }
00330
00331
00332 template<class ParticleType>
00333 void Foam::Cloud<ParticleType>::writePositions() const
00334 {
00335 OFstream pObj
00336 (
00337 this->db().time().path()/this->name() + "_positions.obj"
00338 );
00339
00340 forAllConstIter(typename Cloud<ParticleType>, *this, pIter)
00341 {
00342 const ParticleType& p = pIter();
00343 pObj<< "v " << p.position().x() << " " << p.position().y() << " "
00344 << p.position().z() << nl;
00345 }
00346
00347 pObj.flush();
00348 }
00349
00350
00351
00352
00353 #include "CloudIO.C"
00354
00355