CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > OpenFOAM Programming & Development

Create particle clouds at runtime

Register Blogs Members List Search Today's Posts Mark Forums Read

Reply
 
LinkBack Thread Tools Display Modes
Old   April 13, 2010, 04:35
Default Create particle clouds at runtime
  #1
Member
 
Cedric Van Holsbeke
Join Date: Dec 2009
Location: Belgium
Posts: 81
Rep Power: 7
CedricVH is on a distinguished road
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 is offline   Reply With Quote

Old   April 15, 2010, 04:04
Default
  #2
Member
 
Cedric Van Holsbeke
Join Date: Dec 2009
Location: Belgium
Posts: 81
Rep Power: 7
CedricVH is on a distinguished road
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?
CedricVH is offline   Reply With Quote

Old   April 20, 2010, 06:41
Default
  #3
Senior Member
 
Laurence R. McGlashan
Join Date: Mar 2009
Posts: 370
Rep Power: 14
l_r_mcglashan will become famous soon enough
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
__________________
Laurence R. McGlashan :: Website
l_r_mcglashan is offline   Reply With Quote

Old   April 20, 2010, 07:29
Default
  #4
Member
 
Cedric Van Holsbeke
Join Date: Dec 2009
Location: Belgium
Posts: 81
Rep Power: 7
CedricVH is on a distinguished road
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();
}
CedricVH is offline   Reply With Quote

Old   April 20, 2010, 07:57
Default
  #5
Senior Member
 
Laurence R. McGlashan
Join Date: Mar 2009
Posts: 370
Rep Power: 14
l_r_mcglashan will become famous soon enough
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.
__________________
Laurence R. McGlashan :: Website
l_r_mcglashan is offline   Reply With Quote

Old   May 15, 2010, 11:59
Default
  #6
New Member
 
Fiorenzo Ambrosino
Join Date: Mar 2010
Location: Naples, Italy
Posts: 5
Rep Power: 7
ambros is on a distinguished road
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
ambros is offline   Reply With Quote

Old   March 7, 2013, 06:51
Default
  #7
Member
 
Jamal
Join Date: May 2012
Location: Freiburg
Posts: 54
Rep Power: 4
aujamal20 is an unknown quantity at this point
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


aujamal20 is offline   Reply With Quote

Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Actuator disk model audrich FLUENT 0 September 21, 2009 07:06
Where's the singularity/mesh flaw? audrich FLUENT 3 August 4, 2009 01:07
DPM UDF particle position using the macro P_POS(p)[i] dm2747 FLUENT 0 April 17, 2009 01:29
fluent add additional zones for the mesh file SSL FLUENT 2 January 26, 2008 12:55
Meshing a Sphere Ajay FLUENT 9 March 29, 2004 09:14


All times are GMT -4. The time now is 14:31.