CFD Online Discussion Forums

CFD Online Discussion Forums (http://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (http://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Create particle clouds at runtime (http://www.cfd-online.com/Forums/openfoam-programming-development/74957-create-particle-clouds-runtime.html)

CedricVH April 13, 2010 04:35

Create particle clouds at runtime
 
The standard way of defining a kinematic cloud is by creating a createClouds.H file with following constructor:

Code:

Info<< "Constructing kinematicCloud1" << endl;
basicKinematicCloud kinematicCloud1
(
    "kinematicCloud1",
    rho,
    U,
    mu,
    g
);

However, all clouds must be specified at compile time which is not a good programming practice. To define it at run time, it is better to create a dictionary file constant/kinematicCloudList which specifies the clouds:

Code:

kinematicCloudNames        kinematicCloud1 kinematicCloud2;
I want to read in this file in the createClouds.H file to see which clouds have to be created at runtime:

Code:

Info<< "Reading kinematicCloudList\n" << endl;

IOdictionary kinematicCloudList
(
        IOobject
        (
        "kinematicCloudList",
        runTime.constant(),
        mesh,
        IOobject::MUST_READ,
        IOobject::NO_WRITE
        )
);

List<word> kinematicCloudNames(kinematicCloudList.lookup("kinematicCloudNames"));

Now I want to use this information to create a Map or a List of these clouds which I can use in my main solver (to evolve the cloud):

Code:

Map<kinematicCloud> kinematicClouds(kinematicCloudNames.size());

forAll(kinematicCloudNames, cloudI)
{
    Info<< "Constructing " << kinematicCloudNames[cloudI] << endl;
    kinematicClouds.set(kinematicCloudNames[cloudI], new basicKinematicCloud
    (
        kinematicCloudNames[cloudI],
        rho,
        U,
        mu,
        g
    ),true);
}

But when compiling, I get following error:

Code:

createClouds.H: In function ‘int main(int, char**)’:
createClouds.H:29: fout: no matching function for call to ‘Foam::Map<Foam::kinematicCloud>::set(Foam::word&, Foam::basicKinematicCloud*, bool)’
/home/cedric/OpenFOAM/OpenFOAM-1.6.x/src/OpenFOAM/lnInclude/HashTable.C:256: note: kandidaten zijn: bool Foam::HashTable<T, Key, Hash>::set(const Key&, const T&, bool) [with T = Foam::kinematicCloud, Key = int, Hash = Foam::Hash<int>]
/home/cedric/OpenFOAM/OpenFOAM-1.6.x/src/OpenFOAM/lnInclude/HashTableI.H:88: note:                  bool Foam::HashTable<T, Key, Hash>::set(const Key&, const T&) [with T = Foam::kinematicCloud, Key = int, Hash = Foam::Hash<int>]

It seems that the constructor of Map does not work with the type kinematicCloud. I have also tried it with List<kinematicCloud>, but this gave the same error.

Is there a better system of grouping clouds? Or is there a better system to create clouds at runtime?

CedricVH April 15, 2010 04:04

I am really unable to solve this problem. I have changed my code a bit

Code:

...
Read in dictionary
...
List<word> kinematicCloudNames(kinematicCloudList.lookup("kinematicCloudNames"));
HashTable<kinematicCloud> kinematicClouds(kinematicCloudNames.size());

Now I have constructed a HashTable and I want to fill it in with the function bool set (const Key &, const T &newElmt)

Code:

forAll(kinematicCloudNames, cloudI)
{
    Info<< "Constructing " << kinematicCloudNames[cloudI] << endl;
    bool test = kinematicClouds.set(kinematicCloudNames[cloudI], new basicKinematicCloud
    (
        kinematicCloudNames[cloudI],
        rho,
        U,
        mu,
        g
    ));

}

But it still gives me the error:

No matching function for call to ‘Foam::HashTable<Foam::kinematicCloud, Foam::word, Foam::string::hash>::set(Foam::word&, Foam::basicKinematicCloud*)’
/home/cedric/OpenFOAM/OpenFOAM-1.6.x/src/OpenFOAM/lnInclude/HashTable.C:256: note: candidates are: bool Foam::HashTable<T, Key, Hash>::set(const Key&, const T&, bool) [with T = Foam::kinematicCloud, Key = Foam::word, Hash = Foam::string::hash]

However, as a test, when I try it with a HashTable of scalars, it works perfectly!

Code:

HashTable<scalar> testTable(kinematicCloudNames.size());
forAll(kinematicCloudNames, cloudI)
{
    bool test = testTable.set(kinematicCloudNames[cloudI], 1);
}

Why is it impossible to make a HashTable or List of (kinematic)Clouds? Is there any way to accomplish that?

l_r_mcglashan April 20, 2010 06:41

Instead of using List<>, use PtrList<>. I do a very similar thing to what you're trying to do in your code.

http://foam.sourceforge.net/doc/Doxy..._1PtrList.html

CedricVH April 20, 2010 07:29

Thank you very much! It works perfectly now!

As a Java programmer, I am used to the fact that Lists and HashMaps can contain any Object, but in C++ this works a bit different:)

For people having the same problem, the final code is:

Code:

Info<< "Reading kinematicCloudList\n" << endl;

IOdictionary kinematicCloudList
(
        IOobject
        (
        "kinematicCloudList",
        runTime.constant(),
        mesh,
        IOobject::MUST_READ,
        IOobject::NO_WRITE
        )
);

List<word> kinematicCloudNames(kinematicCloudList.lookup("kinematicCloudNames"));
PtrList<basicKinematicCloud> kinematicClouds(kinematicCloudNames.size());

forAll(kinematicCloudNames, cloudI)
{
    Info<< "Constructing " << kinematicCloudNames[cloudI] << endl;
    kinematicClouds.set(cloudI, new basicKinematicCloud
    (
        kinematicCloudNames[cloudI],
        rho,
        U,
        mu,
        g
    ));
}

For particle tracking, you have to loop trough this list in your main file:

Code:

forAll(kinematicClouds, cloudI)
{
    Info<< "Evolving " << kinematicClouds[cloudI].name() << endl;
    kinematicClouds[cloudI].evolve();
}


l_r_mcglashan April 20, 2010 07:57

Also be careful, 'List' is not the STL version which is 'list', even though it probably has very similar functionality.

The problem you had was that 'set' was not a member function for 'List'. I'm always getting tripped up by these sort of things myself.

ambros May 15, 2010 11:59

Hi guys, I also need to define kinematic clouds at runtime and I'm happy to have just found this useful topic! So very thank you both for this code.
In the posts however there is no reference to the necessary correction to the Ueqn.H file in which the contributions of individual clouds of momentum equation must be added (if I'm not wrong...).
I'm trying to do this and I've written some code. I'm not a good C++ programmer so hope someone could help me.

I've tried with this Ueqn.H:

Code:

Foam::tmp<Foam::DimensionedField<Foam::vector, Foam::volMesh > > SU;
 
 forAll(kinematicClouds, cloudI)
 {
    SU = SU + kinematicClouds[cloudI].SU();
 }


    fvVectorMatrix UEqn
    (
        fvm::ddt(rho, U)
      + fvm::div(phi, U)
      + turbulence->divDevRhoReff(U)
    ==
//        kinematicCloud1.SU()
      SU
      + rho.dimensionedInternalField()*g
      + flowDirection*DeltaPonL
    );

    UEqn.relax();

    if (momentumPredictor)
    {
        solve(UEqn == -fvc::grad(p));
    }

Is this code correct? I mean, I haven't to initialize to zero the SU variable before of the loop, have I?

Thanks for the help.
Fiorenzo

aujamal20 March 7, 2013 06:51

Dear OFrs
I am using OF 2.1.0 and looking for to write a simple macro to control writeInterval entitiy of controlDict file. For example if endTime is 10 and startTime is 0. I want to write every time directories like 1 2 3 4 5 and when runTime is greater than 5 then I want alternative directories 7 9 ..., I mean write internval should change from 1 to 2 as the time passes by 5.
I am trying to use following line controlDict file but returned with errors
writeInterval $(if(runTime.()>5) ? 2:1);

please let me know how to use macro/directives properly in this regard. And in general is there documentation available for this topic.

Thanks




All times are GMT -4. The time now is 09:53.