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

How to make a dictionary run-time modifiable?

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

Like Tree2Likes
  • 2 Post By wyldckat

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   April 8, 2011, 08:46
Default How to make a dictionary run-time modifiable?
  #1
New Member
 
Kedar Jathar
Join Date: Jan 2010
Posts: 7
Rep Power: 16
kedarj14 is on a distinguished road
Hello All:

I have a bool type of variable which is read from the transport properties file. The true/false value gets read for the first time. However if I change that value in the transport properties file at runtime then the change is not communicated to the solver. The solver registers that the transport properties file has changed but it doesn't update the value of my variable. Controldict runtime modifiable is yes.

Is there something more I need to do to make the solver understand it has to read the updated value ?

Thanks,
Kedar

Last edited by wyldckat; October 12, 2014 at 15:37. Reason: merged thread "how to make my variable run time modifiable" with this one
kedarj14 is offline   Reply With Quote

Old   September 21, 2014, 14:10
Default How to make a dictionary run-time modifiable?
  #2
New Member
 
Gennaro
Join Date: May 2014
Posts: 23
Rep Power: 11
Gennaro is on a distinguished road
Hi all,

I created the following dictionary in createFields.H:
Code:
        IOdictionary equationConstants
        (
            IOobject
            (
                "equationConstants",
                runTime.constant(),
                fluidRegions[i],
                IOobject::MUST_READ,
                IOobject::NO_WRITE
            )
        );
    
        Info<< "    Reading Alambda\n" << endl;
        Alambdas.set
        (
            i,
            new dimensionedScalar(equationConstants.lookup("Alambda"))
        );
    
        Info<< "    Reading Slambda\n" << endl;
        Slambdas.set
        (
            i,
            new dimensionedScalar(equationConstants.lookup("Slambda"))
        );
    
        Info<< "    Reading Tlambda\n" << endl;
        Tlambdas.set
        (
            i,
            new dimensionedScalar(equationConstants.lookup("Tlambda"))
        );
    
        Info<< "    Reading SMALL\n" << endl;
        SMALLs.set
        (
            i,
            new dimensionedScalar(equationConstants.lookup("SMALL"))
        );

        Info<< "    Reading Sigma\n" << endl;
        Sigmas.set
        (
            i,
            new dimensionedScalar(equationConstants.lookup("Sigma"))
        );
        
        Info<< "    Reading Lref\n" << endl;
        Lrefs.set
        (
            i,
            new dimensionedScalar(equationConstants.lookup("Lref"))
        );
How can I make it run-time modifiable?

Thanks in advance

Gennaro
Gennaro is offline   Reply With Quote

Old   September 25, 2014, 10:35
Default
  #3
New Member
 
Gennaro
Join Date: May 2014
Posts: 23
Rep Power: 11
Gennaro is on a distinguished road
any ideas? The problem is that not currently being run-time modifiable, if I change values in the dictionary file while a simulation is running, the new values are not read.
Gennaro is offline   Reply With Quote

Old   October 12, 2014, 13:56
Default
  #4
Senior Member
 
Join Date: Jan 2013
Posts: 372
Rep Power: 14
openfoammaofnepo is on a distinguished road
Dear Gennaro,

I have the same concern, did you solve this problem now? Thank you very much.
OFFO


Quote:
Originally Posted by Gennaro View Post
any ideas? The problem is that not currently being run-time modifiable, if I change values in the dictionary file while a simulation is running, the new values are not read.
openfoammaofnepo is offline   Reply With Quote

Old   October 12, 2014, 16:17
Default
  #5
Retired Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,974
Blog Entries: 45
Rep Power: 128
wyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to all
Greetings to all!

I've moved the very first post from an old thread to this thread, since it's all in the same topic.

And I have to say that this is a bit of a tricky topic. First of all, the core magic happens if you use this option:
Code:
IOobject::MUST_READ_IF_MODIFIED
instead of:
Code:
IOobject::MUST_READ
But this only ensures that the dictionary variable is updated. In Gennaro's example, the variable "equationConstants" is automatically updated at the beginning of the "runTime"/"simpleControl"/"pimpleControl" loop.
Therefore, the variables "*lambdas" can only be updated if "equationConstants" is called once again.

Usually what's done is that this kind of auto-updatable code is placed inside a class that handles the data maintenance and storage. For example, if you look at the class "motionSolver": https://github.com/OpenFOAM/OpenFOAM...r/motionSolver - you'll see how this class derives from "IOdictionary", where the method "read()" is a virtual method that when reimplemented in "motionSolver", will automatically update the variables within "motionSolver" based on the data read from the assigned dictionary file. This method "read()" is called automatically by the mechanism "IOdictionary" inherits from other classes - for more information, read this wiki page and the ones referenced in it: http://openfoamwiki.net/index.php/Op...IOobject_class

Therefore, the solution should be to do the following steps, in Gennaro's example:
  1. Create a new class that derives from "IOdictionary" and place inside it the code that handles the population of the variables "*lambda". I'll call it "LambdaManager" for example.
  2. In the "createFields.H" file, replace all of your presented code with something like this:
    Code:
    //definition for replacing all of the lists you've got with just one
    PtrList<LambdaManager> equationConstants(numRegions);
    
    //... then use this instead
    
            equationConstants.set
            (
              i,
              new LambdaManager(
                IOobject(
                (
                    "equationConstants",
                    runTime.constant(),
                    fluidRegions[i],
                    IOobject::MUST_READ_IF_MODIFIED,
                    IOobject::NO_WRITE
                )
              )
            );
  3. Now, the final step for this trick (assuming you can create the new class on your own), is to replace the calls to the variables from this:
    Code:
    Alambdas(i)()
    To this:
    Code:
    equationConstants(i)().Alambda()


A simplified version of this big example would be something like this:
  1. Have a look at the solver "laplacianFoam": https://github.com/OpenFOAM/OpenFOAM.../laplacianFoam
  2. Move this piece of code from "createFields.H":
    Code:
        Info<< "Reading diffusivity DT\n" << endl;
    
        dimensionedScalar DT
        (
            transportProperties.lookup("DT")
        );
    to "laplacianFoam.C", after this part of the code:
    Code:
        while (simple.loop())
        {
            Info<< "Time = " << runTime.timeName() << nl << endl;
  3. In other words, it becomes something like this:
    Code:
        while (simple.loop())
        {
            Info<< "Time = " << runTime.timeName() << nl << endl;
    
            Info<< "Updating diffusivity DT\n" << endl;
    
            dimensionedScalar DT
            (
                transportProperties.lookup("DT")
            );
  4. It's not the prettiest solution, but I'm not in the mood to test this myself and to improve this solution
    I'm not 100% certain, but I think that this might work:
    Code:
        while (simple.loop())
        {
            Info<< "Time = " << runTime.timeName() << nl << endl;
    
            if(transportProperties.modified())
            {
                Info<< "Updating diffusivity DT\n" << endl;
    
                DT = dimensionedScalar(transportProperties.lookup("DT"));
            }
    Of course this implies that in this case, you should not make any changes to the file "createFields.H"
    • edit 1 year later: After OFFO asked the question below, I tested things myself and the "modified()" method is useless in this scenario. Simply do:
      Code:
          while (simple.loop())
          {
              Info<< "Time = " << runTime.timeName() << nl << endl;
      
              DT = dimensionedScalar(transportProperties.lookup("DT"));
Best regards,
Bruno
turbobluestreak and Ramzy1990 like this.
__________________

Last edited by wyldckat; November 29, 2015 at 12:24. Reason: see "edit 1 year later"
wyldckat is offline   Reply With Quote

Old   November 3, 2015, 13:02
Default
  #6
Senior Member
 
Join Date: Jan 2013
Posts: 372
Rep Power: 14
openfoammaofnepo is on a distinguished road
Dear Bruno,

This is an old problem, but it seems I have not solved it yet.

I add the following in the createField.H to build a dictionary:
Code:
    IOdictionary additionalControlsDict
    (
        IOobject
        (
            "additionalControls",
            runTime.constant(),
            mesh,
            IOobject::MUST_READ_IF_MODIFIED,
            IOobject::NO_WRITE
        )
    );
Then in the main code for a solver:

Code:
            dimensionedScalar relax(additionalControlsDict.lookup("relax"));
            Info<<"relax="<< relax <<endl;
When I change relax in that dictionary, the information printed by the solver is the new value of "relax". However, the strange thing is: this new value is not used by the solver (I checked my results and this can be confirmed). So that means the solver is still using the old one for running. Do you know what causes this problem? I think this implementation is similar to what you mentioned in the last thread.

Also, in the last thread, you mentioned that:

Code:
Therefore, the variables "*lambdas" can only be updated if "equationConstants" is called once again.
It is not clear for me about the how to call "equationConstants" (in my case it is "additionalControlsDict") again?

Thank you.
openfoammaofnepo is offline   Reply With Quote

Old   November 29, 2015, 12:27
Default
  #7
Retired Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,974
Blog Entries: 45
Rep Power: 128
wyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to all
Hi OFFO,

Many thanks for asking about this, because as I had mentioned in the previous post, I wasn't certain if it would work, since I didn't test it myself.

Nonetheless, I've tested this now with icoFoam and apparently the "modified()" method can only be used by the auto-reading mechanism. What we should simply do is the same that the file "readPISOControls.H" does (see in folder "src/finiteVolume/cfdTools/general/include/" in OpenFOAM 2.1.1):
Code:
    const dictionary& pisoDict = mesh.solutionDict().subDict("PISO");

    const int nOuterCorr =
        pisoDict.lookupOrDefault<int>("nOuterCorrectors", 1);

    const int nCorr =
        pisoDict.lookupOrDefault<int>("nCorrectors", 1);

    const int nNonOrthCorr =
        pisoDict.lookupOrDefault<int>("nNonOrthogonalCorrectors", 0);

    const bool momentumPredictor =
        pisoDict.lookupOrDefault("momentumPredictor", true);

    const bool transonic =
        pisoDict.lookupOrDefault("transonic", false);
In other words, I've already updated my previous post with an addendum, but the idea is that you can change the following in "icoFoam.C":
Code:
    while (runTime.loop())
    {
        Info<< "Time = " << runTime.timeName() << nl << endl;

        #include "readPISOControls.H"
        #include "CourantNo.H"

        fvVectorMatrix UEqn
        (
            fvm::ddt(U)
          + fvm::div(phi, U)
          - fvm::laplacian(nu, U)
        );
To this:
Code:
    while (runTime.loop())
    {
        Info<< "Time = " << runTime.timeName() << nl << endl;

        #include "readPISOControls.H"
        #include "CourantNo.H"
        
        nu = transportProperties.lookup("nu");

        fvVectorMatrix UEqn
        (
            fvm::ddt(U)
          + fvm::div(phi, U)
          - fvm::laplacian(nu, U)
        );
Best regards,
Bruno
__________________
wyldckat is offline   Reply With Quote

Reply

Tags
runtime modifiable

Thread Tools Search this Thread
Search this Thread:

Advanced Search
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 Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Transient simulation not converging skabilan OpenFOAM Running, Solving & CFD 14 December 17, 2019 00:12
How to export time series of variables for one point? mary mor OpenFOAM Post-Processing 8 July 19, 2017 11:54
simpleFoam error - "Floating point exception" mbcx4jc2 OpenFOAM Running, Solving & CFD 12 August 4, 2015 03:20
Sudden jump in Courant number NJG OpenFOAM Running, Solving & CFD 7 May 15, 2014 14:52
AMI interDyMFoam for mixer nu problem danny123 OpenFOAM Programming & Development 8 September 6, 2013 03:34


All times are GMT -4. The time now is 03:13.