CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Running, Solving & CFD (https://www.cfd-online.com/Forums/openfoam-solving/)
-   -   Easy lagrangian fluid particle tracking (https://www.cfd-online.com/Forums/openfoam-solving/96976-easy-lagrangian-fluid-particle-tracking.html)

michaelb February 6, 2012 11:49

Easy lagrangian fluid particle tracking
 
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

BernhardGrieser February 9, 2012 10:00

passiveParticle
 
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();

Did you already solve the issue? Can somebody else help us?

Best Regards,
Bernhard

BernhardGrieser February 9, 2012 10:10

move particle tracer with the flow
 
one question would be, for example:

1.) How to address the cloud member function move()?

Compiling with
Code:

cloud.move();
returns the error message:
Code:

error: no matching function for call to 'Foam::passiveParticleCloud::move()'
2.) How to interpret the following warning message?

Code:

warning: the address of 'const Foam::IDLList<Foam::passiveParticle>& particles()' will always evaluate as 'true'
Cheers,
Bernhard

francesco_capuano February 9, 2012 11:55

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

BernhardGrieser February 10, 2012 03:03

template class TrackingData
 
Hi Francesco, thanks for the reply.

Quote:

Originally Posted by francesco_capuano (Post 343620)
You might try to define cloud as an object of Cloud<passiveParticle> and then try to call the move function.

My cloud was already defined as a passiveParticleCloud (see previous post). While instantiating, it calls the constructor of Cloud<passiveParticle>. But the member function move(TrackingData&) still cannot be called, probably because I don't know which argument it needs to be fed with. I probably address it the wrong way, since I'm not that familiar with template classes. Here's the move implementation:

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;
        }
    }
}

How can I interpret the TrackingData template? Since move expects its argument to be of Type TrackingData, which tracking data are valid, then?

Thanks :)

francesco_capuano February 10, 2012 08:21

Maybe you already know it, anyway the following reference could be useful:

http://www.tfd.chalmers.se/~hani/kur...LPT_120911.pdf

Cheers,
Francesco

michaelb February 10, 2012 09:50

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;
}

and the kinematicCloudPosition

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)
)

If nobody can give me an hint here, I think I'll just follow your way Bernhard...

Best,

Michael

michaelb February 10, 2012 09:59

@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

BernhardGrieser February 10, 2012 11:23

Quote:

Originally Posted by francesco_capuano (Post 343789)
Maybe you already know it, anyway the following reference could be useful:

http://www.tfd.chalmers.se/~hani/kurser/OS_CFD/OF_kurs_LPT_120911.pdf

Cheers,
Francesco


Nice :) Didn't know that one, thanks!

Still stuck with the problem, though... I'll dive back in the code, then.

Cheers, Bernhard

michaelb February 14, 2012 07:53

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

http://img17.imageshack.us/img17/929...ew312064bi.png

BernhardGrieser February 14, 2012 10:56

passive particle tracking simplistic approach
 
Quote:

Originally Posted by michaelb (Post 344331)
Tell me if you want me to share.

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;
...

Basically, I create a restartable log file for the particle positions at every timestep ("particleTracks") as well as a restartable dictionary in the respective time folder which contains the particle positions (particlePositionsDict).

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)
);

Best regards,
Bernhard

michaelb February 14, 2012 12:02

1 Attachment(s)
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

BernhardGrieser February 15, 2012 06:58

Quote:

Originally Posted by michaelb (Post 344394)
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 ?

Hi Michael, the flaws of the simplistic approach are: nonparallel simulations only, particleTracks have to be transformed in order to be able to view them in paraview.

Thanks for your files, I'll check them.
Bernhard

CFDUser_ April 6, 2014 06:41

Quote:

Originally Posted by francesco_capuano (Post 343789)
Maybe you already know it, anyway the following reference could be useful:

http://www.tfd.chalmers.se/~hani/kurser/OS_CFD/OF_kurs_LPT_120911.pdf

Cheers,
Francesco


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_

wyldckat April 6, 2014 07:24

Quick answer - The current link is this one: http://www.tfd.chalmers.se/~hani/kur...LPT_120911.pdf

CFDUser_ April 6, 2014 07:29

Quote:

Originally Posted by wyldckat (Post 484138)

Thanks for very quick and kind reply. Seems it will be very useful for me.

Regards
CFDUser_

CFDUser_ December 7, 2014 04:35

Dear All,

Can somebody post LPTVOF case files Michaelb said about?

Quote:

Originally Posted by michaelb (Post 343807)
@Bernhard :
We might take advantage of the files associated with the pdf Francesco suggested :
http://www.tfd.chalmers.se/~hani/kurser/OS_CFD/LPTVOF_solver_case.tgz

I'll have a look and keep you updated.

Best,

Michael

Thanks & Regards,
CFDUser_

wyldckat December 8, 2014 13:09

Quote:

Originally Posted by CFDUser_ (Post 522774)
Can somebody post LPTVOF case files Michaelb said about?

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

camzis June 15, 2015 06:19

different numbers of particle injection?
 
Dear foamers,
I'm currently working with the solver "iconUncoupledKinematicParcelFoam (lagrangian)



I need to inject a different number of particles at each time step.
I'm currently using the model "patchInjection" in the file kinematicCloudProperties.
The problem is, I dont know how to make the number of particels vary.


Is there a way to force the number of particles to vary by wether providing a table (for number of particles vs. time) or as a function?


Any suggestions, ideas are very welcome.

Please, my master thesis depends on this.

vonboett August 26, 2015 03:00

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!

vonboett August 26, 2015 04:36

Hi Mamadou,

have a look at the coneNozzleInjection in the sprayFoam/aachenBomb tutorial: massFlowRateProfile sets the mass flow at a certain time (t, m*).
Although the parcels per second are specified, there might be a possibility to get that calculated if the mass per parcel is fixed. Its only a guess based on
http://www.tfd.chalmers.se/~hani/kur...ing_report.pdf stating that "in a transient case, the time-step,
the duration of the injection, the mass flow rate and other properties defined are taken into account to calculate the number of parcels the injector is going to introduce
in the system per time-step in order to fulfill the user's requirements."
Looking at PatchFlowRateInjection.H seems to confirm that there are ways to adjust the number of parcels injected, because the user
specifies Injection target concentration/carrier volume flow rate and the parcel diameters are obtained by the distribution model which should allow constant values...


potentialFoam February 5, 2016 09:23

Dear Foamers,

the original question dealt with the tracking of massless particles and the latest answers as well as the proposed work from chalmers
http://www.tfd.chalmers.se/~hani/kur...LPT_120911.pdf
(and others) deal with solid particles (with a mass and diameter greater than zero).

How did the first question (tracking of massless particles) has been solved finally?

I think, one can modify a solver like here:
http://www.tfd.chalmers.se/~hani/kur...tonPersson.pdf
(chapter 3) and use another particle class instead of the 'solidParticle' one.
(Maybe the basic one from '$FOAM_SRC/lagrangian/basic/particle/'?)

Besides, why to write a new function therefor like in post #5:
http://www.cfd-online.com/Forums/ope...tml#post343725

Thanks :)

vonboett February 5, 2016 09:29

iconUncoupledKinematicParcelFoam worked for me to use particles as passive tracers and modifying that to a interFOAM version for open channel flow was straight forward.

potentialFoam February 8, 2016 11:58

At first: thanks for your fast response!

Unfortunately, I don't understand how to use (ico)uncoupledKinematicFoam for massless tracer particles.
Hence, within the 'kinematicCloudProperties' dict file, you have to specify collision parameters ASO. Besides, running the solver tells the user how much mass has been added (mass introduced).
How to setup the solver for massless tracer particles?

Referring to this post
http://www.cfd-online.com/Forums/ope...tml#post277371
I produced a transient solution (with pimpleFoam) and used the case-folders for the simulation with icoUncoupledKinematicFoam.
But icoUncoupledKinematicFoam did'nt use the solution, but used a steady velocity field out of it.
According to what I understood, the icoUncoupledKinematicFoam-solver should read the solution and use it to calculate the positions of the tracer particles.
Why does'nt it work?

vonboett February 10, 2016 04:50

The particles take over the velocity field without momentum transfer to the fluid phase in icoUncoupledKinematicParcelFoam and I would start with the corresponding hopper tutorial in the lagrangian tutorial folder. Yes, the particles interact and that's OK because they will not leave your boundaries that way. What I do to use them as passive tracers is to define their diameter as neglectible small in kinematicCloudProperties:

parcelBasisType fixed;
sizeDistribution
{
type fixedValue;
fixedValueDistribution
{
value 1e-6;
}
}

A million particles have then about 5e-10 kg mass in my water flow. However, my main whish was to have more control about when to write the particle positions, so I implemented the lagrangian parts looking through the interSettlingFoam and LPT for erosion modeling project reports (Chalmers University of Technology, Pedram Ramin / Alejandro Lopez) and the Coupling of VOF with LPT in OpenFOAM by Aurelia Vallier LTH Lund University and some others I cant remember right now but I could look it up. The result was an implementation I try to show step by step: I decided to go for kinematicCloud but the code allows to go for a particleCloud implementation, too, making use of particle classes defined in a src dictionary created in your OpenFOAM user dictionary so you can modify them if you need to. To have the modified classes in your solver from lagrangian/intermediate so the make/options file starts with:
LIB_USER_SRC = $(WM_PROJECT_USER_DIR)/src

then one needs (or at least I put it in here):

-I$(LIB_SRC)/lagrangian/basic/lnInclude \
-I$(LIB_SRC)/lagrangian/intermediate/lnInclude \
-I$(LIB_USER_SRC)/lagrangian/intermediate/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/specie/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/basic/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/reactionThermo/lnInclude \
-I$(LIB_SRC)/thermophysicalModels/radiationModels/lnInclude \
...
-I$(LIB_SRC)/regionModels/regionModel/lnInclude \
-I$(LIB_SRC)/regionModels/surfaceFilmModels/lnInclude
and at the libraries (EXE_LIBS =)
-llagrangian \
-llagrangianIntermediate \
-lthermophysicalFunctions \
-lfluidThermophysicalModels \
-lspecie \
-lradiationModels \

I copied the solidParticle and solidParticleCloud class files into my solver folder and in my solver.c file I added the headers:

#include "basicKinematicCollidingCloud.H"
#include "solidParticleCloud.H"

before the main method. In the main method, the very first thing to do is

argList::addOption
(
"cloudName",
"name",
"specify alternative cloud name. default is 'kinematicCloud'"
);

In the solver in the runTime.run(), all you need is:

// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// kinematic cloud AND particle cloud

mu = mixture.nu()*rhoInfValue; // needed for cloud
kinematicCloud.evolve();
if (false)//(runTime.value()-lastIOTime>lagInterval)
{
//Info <<runTime.times()[0].value();
kinematicCloud.writeFields();
lastIOTime = runTime.value();
}
// particleCloud addresses Uc as fluid velocity
//Uc = U;

/*particles.move(g);commented out, only kinematic cloud
if (runTime.value()-lastIOTime>lagInterval)
{
//Info <<runTime.times()[0].value();
particles.writeFields();
lastIOTime = runTime.value();
}*/


// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

but in the createFields.H you need to specify the missing fields, the fluid density as the lagrangian phase asks for it:

volScalarField rhoInf
(
IOobject
(
"rhoInf",
runTime.timeName(),
mesh,
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
rhoInfValue
);

and maybe gravitation, (at least in interFoam):

volScalarField gh("gh", g & mesh.C());
surfaceScalarField ghf("ghf", g & mesh.Cf());

and finally:

word kinematicCloudName("kinematicCloud");
args.optionReadIfPresent("cloudName", kinematicCloudName);

Info<< "Constructing kinematicCloud " << kinematicCloudName << endl;
basicKinematicCollidingCloud kinematicCloud
(
kinematicCloudName,
rhoInf,
U,
mu,
g
);

IOobject Hheader
(
"H",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
);

autoPtr<volVectorField> HPtr;

if (Hheader.headerOk())
{
Info<< "\nReading field H\n" << endl;

HPtr.reset(new volVectorField (Hheader, mesh));
}

IOobject HdotGradHheader
(
"HdotGradH",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
);

autoPtr<volVectorField> HdotGradHPtr;

if (HdotGradHheader.headerOk())
{
Info<< "Reading field HdotGradH" << endl;

HdotGradHPtr.reset(new volVectorField(HdotGradHheader, mesh));
}

#include "createNonInertialFrameFields.H"


Info<< "Constructing particleCloud commented out, only kinematiClouds" << endl;
//solidParticleCloud particles(mesh);

the createNonInertialFrameFields.H file looks like:


Info<< "Reading non-inertial frame fields" << endl;

IOobject linearAccelerationHeader
(
"linearAcceleration",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
);

autoPtr<uniformDimensionedVectorField> linearAccelerationPtr;

if (linearAccelerationHeader.headerOk())
{
Info<< " Reading " << linearAccelerationHeader.name() << endl;

linearAccelerationPtr.reset
(
new uniformDimensionedVectorField(linearAccelerationHe ader)
);
}


IOobject angularVelocityHeader
(
"angularVelocity",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
);

autoPtr<uniformDimensionedVectorField> angularVelocityPtr;

if (angularVelocityHeader.headerOk())
{
Info<< " Reading " << angularVelocityHeader.name() << endl;

angularVelocityPtr.reset
(
new uniformDimensionedVectorField(angularVelocityHeade r)
);
}


IOobject angularAccelerationHeader
(
"angularAcceleration",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
);

autoPtr<uniformDimensionedVectorField> angularAccelerationPtr;

if (angularAccelerationHeader.headerOk())
{
Info<< " Reading " << angularAccelerationHeader.name() << endl;

angularAccelerationPtr.reset
(
new uniformDimensionedVectorField(angularAccelerationH eader)
);
}


IOobject centreOfRotationHeader
(
"centreOfRotation",
runTime.timeName(),
mesh,
IOobject::MUST_READ,
IOobject::AUTO_WRITE
);

autoPtr<uniformDimensionedVectorField> centreOfRotationPtr;

if (centreOfRotationHeader.headerOk())
{
Info<< " Reading " << centreOfRotationHeader.name() << endl;

centreOfRotationPtr.reset
(
new uniformDimensionedVectorField(centreOfRotationHead er)
);
}


and you put it in your solver folder. Hope this helps. However, in case you want to go for a two-way coupling, I recommend the way it is done in DPMFoam (source terms in the pressure equation), that worked well for me to get a stable coupled lagrangian interMixingFoam version.

ywang July 25, 2016 15:44

Quote:

Originally Posted by potentialFoam (Post 584213)
At first: thanks for your fast response!

Unfortunately, I don't understand how to use (ico)uncoupledKinematicFoam for massless tracer particles.
Hence, within the 'kinematicCloudProperties' dict file, you have to specify collision parameters ASO. Besides, running the solver tells the user how much mass has been added (mass introduced).
How to setup the solver for massless tracer particles?

Referring to this post
http://www.cfd-online.com/Forums/ope...tml#post277371
I produced a transient solution (with pimpleFoam) and used the case-folders for the simulation with icoUncoupledKinematicFoam.
But icoUncoupledKinematicFoam did'nt use the solution, but used a steady velocity field out of it.
According to what I understood, the icoUncoupledKinematicFoam-solver should read the solution and use it to calculate the positions of the tracer particles.
Why does'nt it work?

Hi Peter,

Did you finally find the answer? I am also thinking about using uncoupledKinematicFoam to read pre-calculated transient flow field.

zhaoshiyu April 14, 2017 07:22

Hi, Vonbotte, I also work on the debris flow simulation. I am quite curious about the particle method in openFoam coupled with interFoam, but in my case, it is only weightless tracers, is it possible to use it as the way in CFD-DEM coupling?

meth January 9, 2020 23:55

Dear MIchael,

Can you please share your files with me, if I am not too late?

Thank you
Methma



Quote:

Originally Posted by michaelb (Post 344331)
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

http://img17.imageshack.us/img17/929...ew312064bi.png



All times are GMT -4. The time now is 18:11.