|
[Sponsors] |
February 6, 2012, 12:49 |
Easy lagrangian fluid particle tracking
|
#1 |
New Member
Michael Bruckner
Join Date: Apr 2009
Location: France
Posts: 27
Rep Power: 17 |
Hello Foamers,
I would like to know if there is a simple solver which could allow me to track a cloud of fluid particles ( size less : no drag & massless : no settling due to gravity) injected as a sphere of given position and diameter at t = 0 (only) with no initial velocity in an unsteady simulation. Is there a way of doing such things with the icoLagrangianFoam solver in OpenFOAM-1.6-ext ? I couldn't figure out what would be the appropriate parameters in the kinematicCloudProperties dic file. Actually, I need, for each saved timestep, the particles locations and their distances to wall patches. If anybody could give me an hint on how to start here, I would be eternally thankful. Best regards, Michael |
|
February 9, 2012, 11:00 |
passiveParticle
|
#2 |
Member
Bernhard Grieser
Join Date: Mar 2010
Location: Zurich, Switzerland
Posts: 30
Rep Power: 16 |
Hi Michael,
I'm trying the same at the moment: Massless tracer particles. So far, I've only succeeded to load two particles in a cloud, and to write out their positions in an object file. Still fiddling around with the particle movement, though. That's my code, so far: Code:
vector position1(0.00005, 0.0001, 0.000995); vector position2(0.00005, 0.0001, 0.001005); label celli1 = mesh.findCell(position1); label celli2 = mesh.findCell(position2); Info<< "celli1 = mesh.findCell(position1) = " << celli1 << endl; Info<< "celli2 = mesh.findCell(position2) = " << celli2 << endl; const IDLList<passiveParticle>& particles(); passiveParticleCloud cloud(mesh, "cloud", particles); cloud.clear(); passiveParticle* ptr1 = new passiveParticle(cloud, position1, celli1); cloud.addParticle(ptr1); passiveParticle* ptr2 = new passiveParticle(cloud, position2, celli2); cloud.addParticle(ptr2); cloud.writePositions(); Best Regards, Bernhard |
|
February 9, 2012, 11:10 |
move particle tracer with the flow
|
#3 |
Member
Bernhard Grieser
Join Date: Mar 2010
Location: Zurich, Switzerland
Posts: 30
Rep Power: 16 |
one question would be, for example:
1.) How to address the cloud member function move()? Compiling with Code:
cloud.move(); Code:
error: no matching function for call to 'Foam::passiveParticleCloud::move()' Code:
warning: the address of 'const Foam::IDLList<Foam::passiveParticle>& particles()' will always evaluate as 'true' Bernhard |
|
February 9, 2012, 12:55 |
|
#4 |
Member
Francesco Capuano
Join Date: May 2010
Posts: 81
Rep Power: 16 |
One guess for question #1: move is a member function of the base cloud class Cloud<ParticleType>, which is templated on particle type, see:
http://foam.sourceforge.net/docs/cpp...ce.html#l00181 You might try to define cloud as an object of Cloud<passiveParticle> and then try to call the move function. Hope it helps, Francesco |
|
February 10, 2012, 04:03 |
template class TrackingData
|
#5 | |
Member
Bernhard Grieser
Join Date: Mar 2010
Location: Zurich, Switzerland
Posts: 30
Rep Power: 16 |
Hi Francesco, thanks for the reply.
Quote:
Code:
template<class ParticleType> template<class TrackingData> void Foam::Cloud<ParticleType>::move(TrackingData& td) { const globalMeshData& pData = polyMesh_.globalData(); const labelList& processorPatches = pData.processorPatches(); const labelList& processorPatchIndices = pData.processorPatchIndices(); const labelList& processorPatchNeighbours = pData.processorPatchNeighbours(); // Initialise the setpFraction moved for the particles forAllIter(typename Cloud<ParticleType>, *this, pIter) { pIter().stepFraction() = 0; } // Assume there will be particles to transfer bool transfered = true; // While there are particles to transfer while (transfered) { // List of lists of particles to be transfered for all the processor // patches List<IDLList<ParticleType> > transferList(processorPatches.size()); // Loop over all particles forAllIter(typename Cloud<ParticleType>, *this, pIter) { ParticleType& p = pIter(); // Move the particle bool keepParticle = p.move(td); // If the particle is to be kept // (i.e. it hasn't passed through an inlet or outlet) if (keepParticle) { // If we are running in parallel and the particle is on a // boundary face if (Pstream::parRun() && p.facei_ >= pMesh().nInternalFaces()) { label patchi = pMesh().boundaryMesh().whichPatch(p.facei_); label n = processorPatchIndices[patchi]; // ... and the face is on a processor patch // prepare it for transfer if (n != -1) { p.prepareForParallelTransfer(patchi, td); transferList[n].append(this->remove(&p)); } } } else { deleteParticle(p); } } if (Pstream::parRun()) { // List of the numbers of particles to be transfered across the // processor patches labelList nsTransPs(transferList.size()); forAll(transferList, i) { nsTransPs[i] = transferList[i].size(); } // List of the numbers of particles to be transfered across the // processor patches for all the processors labelListList allNTrans(Pstream::nProcs()); allNTrans[Pstream::myProcNo()] = nsTransPs; combineReduce(allNTrans, combineNsTransPs()); transfered = false; forAll(allNTrans, i) { forAll(allNTrans[i], j) { if (allNTrans[i][j]) { transfered = true; break; } } } if (!transfered) { break; } forAll(transferList, i) { if (transferList[i].size()) { OPstream particleStream ( Pstream::blocking, refCast<const processorPolyPatch> ( pMesh().boundaryMesh()[processorPatches[i]] ).neighbProcNo() ); particleStream << transferList[i]; } } forAll(processorPatches, i) { label patchi = processorPatches[i]; const processorPolyPatch& procPatch = refCast<const processorPolyPatch> (pMesh().boundaryMesh()[patchi]); label neighbProci = procPatch.neighbProcNo() - Pstream::masterNo(); label neighbProcPatchi = processorPatchNeighbours[patchi]; label nRecPs = allNTrans[neighbProci][neighbProcPatchi]; if (nRecPs) { IPstream particleStream ( Pstream::blocking, procPatch.neighbProcNo() ); IDLList<ParticleType> newParticles ( particleStream, typename ParticleType::iNew(*this) ); forAllIter ( typename Cloud<ParticleType>, newParticles, newpIter ) { ParticleType& newp = newpIter(); newp.correctAfterParallelTransfer(patchi, td); addParticle(newParticles.remove(&newp)); } } } } else { transfered = false; } } } Thanks |
||
February 10, 2012, 09:21 |
|
#6 |
Member
Francesco Capuano
Join Date: May 2010
Posts: 81
Rep Power: 16 |
Maybe you already know it, anyway the following reference could be useful:
http://www.tfd.chalmers.se/~hani/kur...LPT_120911.pdf Cheers, Francesco |
|
February 10, 2012, 10:50 |
|
#7 |
New Member
Michael Bruckner
Join Date: Apr 2009
Location: France
Posts: 27
Rep Power: 17 |
Hi guys,
thanks for addressing the problem. I've kept trying so far to use what is already implemented in the code and it really looks like that there are tons of material to deal with. ( Because I'm horrible at C++ coding... ) Unfortunately, I can't figure out what are meaning all the parameters available in a "kinematicCloudProperties" file. I thought that I could specify a very low particle density leading me to a very small Stokes number therefore implying near to massless fluid particle tracking. So until now, I've been playing around with the tutorials/lagrangian/icoLagrangianFoam/channelParticles of OpenFOAM-1.6-ext. Only three particles are injected at t=0, but are not moving unless I activate the gravity. Particles are then just settling downwards. Here is my "kinematicCloudProperties" file : Code:
/*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM Extend Project: Open Source CFD | | \\ / O peration | Version: 1.6-ext | | \\ / A nd | Web: www.extend-project.de | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; location "constant"; object kinematicCloud1Properties; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // active yes; InjectionModel ManualInjection; DragModel none; DispersionModel none; PatchInteractionModel StandardWallInteraction; PostProcessingModel none; coupled true; cellValueSourceCorrection on; parcelTypeId 2; constantProperties { rhoMin rhoMin [ 1 -3 0 0 0 ] 1e-15; minParticleMass minParticleMass [ 1 0 0 0 0 ] 1e-15; rho0 rho0 [ 1 -3 0 0 0 ] 5000; } interpolationSchemes { rho cell; U cellPoint; mu cell; } integrationSchemes { U Euler; } particleForces { gravity off; virtualMass off; pressureGradient off; } ManualInjectionCoeffs { massTotal massTotal [ 1 0 0 0 0 ] 0.0002; parcelBasisType mass; SOI 0; positionsFile "kinematicCloudPositions"; U0 ( 0 0 0 ); parcelPDF { pdfType RosinRammler; RosinRammlerPDF { minValue 5e-05; maxValue 0.0001; d ( 7.5e-05 ); n ( 0.5 ); } } } ConeInjectionCoeffs { SOI 0.001; duration 0.005; position ( 0.25 0.25 0.05 ); direction ( 0 -1 0 ); parcelsPerSecond 10000; volumeFlowRate Constant 0.01; Umag Constant 50; thetaInner Constant 0; thetaOuter Constant 30; parcelPDF { pdfType RosinRammler; RosinRammlerPDF { minValue 5e-05; maxValue 0.0001; d ( 7.5e-05 ); n ( 0.5 ); } } } StandardWallInteractionCoeffs { type rebound; } Code:
/*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM Extend Project: Open Source CFD | | \\ / O peration | Version: 1.6-ext | | \\ / A nd | Web: www.extend-project.de | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class vectorField; object kinematicCloud1Positions; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // ( (0.05 0.025 0.005) (0.05 0.05 0.005) (0.05 0.075 0.005) ) Best, Michael |
|
February 10, 2012, 10:59 |
|
#8 |
New Member
Michael Bruckner
Join Date: Apr 2009
Location: France
Posts: 27
Rep Power: 17 |
@Bernhard :
We might take advantage of the files associated with the pdf Francesco suggested : http://www.tfd.chalmers.se/~hani/kur...olver_case.tgz I'll have a look and keep you updated. Best, Michael |
|
February 10, 2012, 12:23 |
|
#9 | |
Member
Bernhard Grieser
Join Date: Mar 2010
Location: Zurich, Switzerland
Posts: 30
Rep Power: 16 |
Quote:
Nice Didn't know that one, thanks! Still stuck with the problem, though... I'll dive back in the code, then. Cheers, Bernhard |
||
February 14, 2012, 08:53 |
|
#10 |
New Member
Michael Bruckner
Join Date: Apr 2009
Location: France
Posts: 27
Rep Power: 17 |
Hi Bernhard,
I managed to inject some particles with kinematicCloud classes in the pimpleFoam transient solver. Here's an example with around 5000 particles in a 3D lid-driven cavity. Works fine in parallel too. Tell me if you want me to share. However, I'm still wondering about the kinematicCloudProperties file, and yet not sure whether I specified correct parameters for massless fluid particles. The reason I'm doubting is that when I turn off the particleForces, particles aren't moving anymore. And much of the parameters are still very obscure to me. I'm doubting whether I should start I new thread about the correct use of "kinematicCloudProperties". Would somebody be able to tell us a little bit more about it ? Cheers, Michael |
|
February 14, 2012, 11:56 |
passive particle tracking simplistic approach
|
#11 |
Member
Bernhard Grieser
Join Date: Mar 2010
Location: Zurich, Switzerland
Posts: 30
Rep Power: 16 |
Hi Michael,
looks very promising, I'd like to have a look at your implementation, yes. Meanwhile I succeeded in implementing my own particle tracking in a very simplistic approach. For my part, I only have a very small amount of tracer particles, so I do not take advantage of the stepwise particle tracking (stepFraction to next face, etc.) which was intended to avoid calling the mesh.findCell(position) for every particle at every timestep, from what I've understood. Maybe you want to have a look at it: Code:
// my solver C-file: #include "fvCFD.H" #include "volMesh.H" #include "interpolationCellPoint.H" #include "IFstream.H" #include "OFstream.H" int main(int argc, char *argv[]) { #include "setRootCase.H" #include "createTime.H" #include "createMesh.H" #include "createFields.H" #include "initContinuityErrs.H" // Load particle positions from dictionary IOdictionary particlePositionsDict ( IOobject ( "particlePositionsDict", runTime.timeName(), mesh, IOobject::MUST_READ, IOobject::AUTO_WRITE ) ); List<vector> particlePositions ( particlePositionsDict.lookup("particlePositions") ); // Initialize List for the interpolated particle velocity and the motion vector deltaX labelList particleCell(particlePositions.size()); List<vector> Uint(particlePositions.size()); List<vector> deltaX(particlePositions.size()); // Initialize particleTracks std::fstream particleTracks; particleTracks.open("particleTracks",std::ios::out | std::ios::app); particleTracks << "#Time[s]\t\t"; forAll(particlePositions, posI) { Info<< " Position of particle #" << posI+1 << ": " << particlePositions[posI] << endl; particleTracks << "particle" << posI+1 << ".x()\t" << "particle" << posI+1 << ".y()\t" << "particle" << posI+1 << ".z()\t\t"; } particleTracks << std::endl; // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // Info<< "\nStarting time loop\n" << endl; while (runTime.loop()) { Info<< "Time = " << runTime.timeName() << nl << endl; #include "readPISOControls.H" #include "CourantNo.H" scalar deltaT = runTime.deltaT().value(); interpolationCellPoint<vector> UInt_(U); particleTracks << runTime.time().value() << "\t\t"; forAll(particlePositions, posI) { particleCell[posI] = mesh.findCell(particlePositions[posI]); Uint[posI] = UInt_.interpolate(particlePositions[posI], particleCell[posI]); deltaX[posI] = Uint[posI]*deltaT; particlePositions[posI] += deltaX[posI]; particleTracks << particlePositions[posI].x() << "\t" << particlePositions[posI].y() << "\t" << particlePositions[posI].z() << "\t\t"; } particleTracks << std::endl; ... The latter one looks like this: Code:
/*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | | \\ / O peration | Version: 1.7.1 | | \\ / A nd | Web: www.OpenFOAM.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ FoamFile { version 2.0; format ascii; class dictionary; location "0"; object particlePositionsDict; } // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // particlePositions ( (5e-05 0.0001 0.000993) (5e-05 0.0001 0.001013) ); Bernhard |
|
February 14, 2012, 13:02 |
|
#12 |
New Member
Michael Bruckner
Join Date: Apr 2009
Location: France
Posts: 27
Rep Power: 17 |
Hello,
attached is what I've done without any guarantee . I compiled it under OpenFOAM-2.0.1 and for some reason, it required some libraries that were buried deep into the source code. I like your implementation since you have a total control of what you're doing. How many particles do you think you could track ? Is there a limitation implied by the format ? Do you have any idea if this is quicker and more/less accurate than what I've done? I would be very interested in the results if you do some comparison. cheers, Michael |
|
February 15, 2012, 07:58 |
|
#13 | |
Member
Bernhard Grieser
Join Date: Mar 2010
Location: Zurich, Switzerland
Posts: 30
Rep Power: 16 |
Quote:
Thanks for your files, I'll check them. Bernhard |
||
April 6, 2014, 07:41 |
|
#14 | |
Member
CFDUser
Join Date: Mar 2014
Posts: 59
Rep Power: 13 |
Quote:
Dear Francesco, This link is not working. May be it will be useful for me as well. Can you please re-upload. Thanks Regards CFDUser_ |
||
April 6, 2014, 08:24 |
|
#15 |
Retired Super Moderator
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,981
Blog Entries: 45
Rep Power: 128 |
Quick answer - The current link is this one: http://www.tfd.chalmers.se/~hani/kur...LPT_120911.pdf
|
|
April 6, 2014, 08:29 |
|
#16 | |
Member
CFDUser
Join Date: Mar 2014
Posts: 59
Rep Power: 13 |
Quote:
Regards CFDUser_ |
||
December 7, 2014, 05:35 |
|
#17 | |
Member
CFDUser
Join Date: Mar 2014
Posts: 59
Rep Power: 13 |
Dear All,
Can somebody post LPTVOF case files Michaelb said about? Quote:
CFDUser_ |
||
December 8, 2014, 14:09 |
|
#18 |
Retired Super Moderator
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,981
Blog Entries: 45
Rep Power: 128 |
Quick answer: http://www.tfd.chalmers.se/~hani/kur...olver_case.tgz
PS: The course changes links with each new year: http://openfoamwiki.net/index.php/Ha...ource_software Last edited by wyldckat; December 8, 2014 at 14:11. Reason: see "PS:" |
|
June 15, 2015, 07:19 |
different numbers of particle injection?
|
#19 |
New Member
Mamadou Camara
Join Date: Mar 2015
Posts: 12
Rep Power: 11 |
Dear foamers, |
|
August 26, 2015, 04:00 |
|
#20 |
Senior Member
Albrecht vBoetticher
Join Date: Aug 2010
Location: Zürich, Swizerland
Posts: 240
Rep Power: 17 |
Hi Mamadou,
Did you find something? I am stuck at the same place. I implemented a write-out control such that I can write the particle position in a higher frequency than the fluid field variables, and I would start to implement the same for reading in from particlePosition files at predefined times- but I am shure someone has solved this before! |
|
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Blood Damage Modelling via Particle Tracking in a Centrifugal Heart Pump | scatman | CFX | 7 | January 8, 2018 01:59 |
Lagrangian Particle Tracking Initial step | Bruce Hartley | OpenFOAM Programming & Development | 4 | September 2, 2015 06:32 |
Lagrangian particle tracking | skabilan | OpenFOAM Running, Solving & CFD | 7 | July 15, 2014 13:40 |
Particle tracking without "Particle interaction with continuous phase" | Peter023 | Fluent UDF and Scheme Programming | 0 | November 30, 2011 10:08 |
cod for lagrangian particle tracking | mazdak | Main CFD Forum | 2 | December 29, 2009 03:53 |