CFD Online Discussion Forums

CFD Online Discussion Forums (http://www.cfd-online.com/Forums/)
-   OpenFOAM Running, Solving & CFD (http://www.cfd-online.com/Forums/openfoam-solving/)
-   -   feature or bug - deltaT issue (http://www.cfd-online.com/Forums/openfoam-solving/95872-feature-bug-deltat-issue.html)

lakeat January 5, 2012 15:44

feature or bug - deltaT issue
 
Hi developers,

Testing on OpenFOAM-2.1.0 -------------------

Here's the situation:
-----------------------------------------------------------------
After running the case and writing out for a few times, eg.
1/,
2/,
3/,
...

Then I stopped at time "3/"
and then I change the deltaT value in "controlDict" file, from 0.0001 to 0.01,
and then, I started the case again, (starting from the latestTime),

HOWEVER, the next timestep is still 3.0001,

the default deltaT is read from "3/uniform/time" file, not the "controlDict" file.

So, is this considered as a feature? :confused:

alberto January 6, 2012 11:55

Is writeControl set to adjustableRunTime in controlDict?

lakeat January 6, 2012 11:57

runTimeModifiable yes;

alberto January 6, 2012 12:08

Quote:

Originally Posted by lakeat (Post 338140)
runTimeModifiable yes;

This just indicates OF will read dictionaries and settings during the run. You should have

writeControl adjustableRunTime;

instead than

writeControl runTime;


Best,

lakeat January 6, 2012 12:29

:( It's nothing to do with the writeControl

Sorry, I didn't make it clear.

My question is this, say I have a case with the following three folders:

163/
constant/
system/

when you start the solver, it tries to look for the deltaT value, NOT first from the "system/controlDict" file, but from "163/uniform/time" file.

Which I would hope that the priority be,
1st, system/controlDict, and then
2nd, 163/uniform/time


I understand it is necessary to read mesh with the priority as first time/polyMesh dir and then the constant/polyMesh dir. But I think deltaT is a different matter.

wyldckat January 6, 2012 13:40

Greetings to all!

Daniel, what kind of solver are you using? If it is a transient solver, that probably is indeed a feature to avoid instantaneous crashes when restarting a case from a time snapshot >0.
From past experiences, with transient solvers, the advised work-flow is to restart the simulation from the latest time snapshot, wait a few iterations for it to stabilize solving it and only then should you try to change said "deltaT" will it is running.

If it is a stationary solver, then my guess is that it might be related to the need for N previous iterations of fields, which can be recreated simply by running a couple of steps with the same "deltaT" as before.

Disclaimer: I don't enough about OpenFOAM's core code to give a sure answer, these are just speculations.

Oh, and a question remains: if it is a transient solver, does it use an adaptive "deltaT"?
edit: ah, this is what Alberto already asked - if you were using:
Quote:

writeControl adjustableRunTime;
Best regards,
Bruno

lakeat January 6, 2012 15:17

Hi Thanks Bruno,

I was/am using:

writeControl runTime;

It's nothing to do with the runTimeWriteOutControl feature, I can change this to another one, but the problem remains.

solver is pisoFoam

wyldckat January 7, 2012 05:45

Hi Daniel,

After a bit of testing, it seems that one of my estimates has some validity:
Quote:

Originally Posted by wyldckat (Post 338161)
If it is a stationary solver, then my guess is that it might be related to the need for N previous iterations of fields, which can be recreated simply by running a couple of steps with the same "deltaT" as before.

I've made the tests on OF 2.0.x and the same behaviour still occurs. It seems that there are 2 "deltaT" values necessary for time >0, namely:
Code:

deltaT
deltaT0

These are defined at each "time_snapshot/uniform/time". The first one defines the next "deltaT" value and the second one has the saved value for the previous iteration. I haven't checked the code, but my guess is that these are necessary to avoid loss of continuity in the equations.

Now, I suppose that the real issue is whether "deltaT" should be simply changeable in "controlDict" or continue to have to be changed in the latest time step.
But after briefly looking at some code, my first conclusion is this: "deltaT" should be changed only if one knows what one is doing.


Although, after looking at the code: http://foam.sourceforge.net/docs/cpp...ce.html#l00031
Code:

00031 void Foam::Time::readDict()
00032 {
00033    if (!deltaTchanged_)
00034    {
00035        deltaT_ = readScalar(controlDict_.lookup("deltaT"));
00036    }
00037

Versus: http://foam.sourceforge.net/docs/cpp...ce.html#l00903
Code:

00903 void Foam::Time::setDeltaT(const scalar deltaT)
00904 {
00905    deltaT_ = deltaT;
00906    deltaTchanged_ = true;
00907    adjustDeltaT();
00908 }

Seeing the code for adjustDeltaT: http://foam.sourceforge.net/docs/cpp...ce.html#l00080
Code:

00080 void Foam::Time::adjustDeltaT()
00081 {
00082    if (writeControl_ == wcAdjustableRunTime)
00083    {
00084        scalar interval = writeInterval_;
00085        if (secondaryWriteControl_ == wcAdjustableRunTime)
00086        {
00087            interval = min(interval, secondaryWriteInterval_);
00088        }
00089
00090
00091        scalar timeToNextWrite = max
00092        (
00093            0.0,
00094            (outputTimeIndex_ + 1)*interval - (value() - startTime_)
00095        );
00096
00097        scalar nSteps = timeToNextWrite/deltaT_ - SMALL;
00098
00099        // For tiny deltaT the label can overflow!
00100        if (nSteps < labelMax)
00101        {
00102            label nStepsToNextWrite = label(nSteps) + 1;
00103
00104            scalar newDeltaT = timeToNextWrite/nStepsToNextWrite;
00105
00106            // Control the increase of the time step to within a factor of 2
00107            // and the decrease within a factor of 5.
00108            if (newDeltaT >= deltaT_)
00109            {
00110                deltaT_ = min(newDeltaT, 2.0*deltaT_);
00111            }
00112            else
00113            {
00114                deltaT_ = max(newDeltaT, 0.2*deltaT_);
00115            }
00116        }
00117    }
00118 }

Mmm.... yes, I do believe that this can be considered a bug or simply a limitation or missing feature. If "Foam::Time::readDict()" modifies "deltaT" directly, then it should also handle the logistics of "deltaTchanged_", instead of depending on it.

Looking deeper, it seems that all of this mess happens because of the events in "Foam::Time::readModifiedObjects()": http://foam.sourceforge.net/docs/cpp...ce.html#l00251 - specifically this part of the code
Code:

00268        // Time handling is special since controlDict_ is the one dictionary
00269        // that is not registered to any database.
00270
00271        if (controlDict_.readIfModified())
00272        {
00273            readDict();
00274            functionObjects_.read();
00275        }
00276
00277        bool registryModified = objectRegistry::modified();
00278
00279        if (registryModified)
00280        {
00281            objectRegistry::readModifiedObjects();
00282        }

The "uniform/time" dict is only read after "controlDict", but since "deltaT" is ignored from "controlDict" at a later time (deltaT hasn't changed yet), or even if it weren't, said "uniform/time" dict has always the last saying.

My final conclusion is this: making OpenFOAM sane to update "deltaT" simply via "controlDict", can drive the programmer insane... therefore, why bother if one can change "deltaT" in at least one of two ways:
  • Program this change in the solver or functionObject. Calling "setDeltaT" would do the trick.
  • Modify in the file "time_snapshot/uniform/time" and prove that you know what you are doing! ;)
Well, this was a good "OpenFOAM code reading" exercise :)


Best regards,
Bruno

alberto January 7, 2012 12:19

Honestly I have some problem understanding what the issue is. First of all, pisoFoam uses a fixed time step, second if you change the time step in controlDict after stopping the simulation and then you restart it, the new time-step is used, as expected.

As a guideline, changing the time step by hand is a poor practice. If you need to change your time-step, do it automatically by using a solver with adaption (pimpleFoam), and eventually implement a CFL condition that reflects your adaption criterion.

For what concerns the precedence given to what time-stepping information has precedence, giving priority to the uniform/time information seems correct to me, since your run terminated with that information. This however does not mean OpenFOAM will ignore the new time-step set in controlDict.

Finally, since the problems seemed to be that OpenFOAM saved a different time than the desired one. If you change your time-step during the simulation, you must set writeControl to adjustableTimeStep, and not to timeStep. However, this is explained in the User's Guide ;-)

Best,

wyldckat January 7, 2012 15:04

Hi Alberto,
Quote:

Originally Posted by alberto (Post 338241)
Honestly I have some problem understanding what the issue is. First of all, pisoFoam uses a fixed time step, second if you change the time step in controlDict after stopping the simulation and then you restart it, the new time-step is used, as expected.

Nope! I tried it myself with the tutorial "incompressible/pisoFoam/ras/cavity" and it did not! Only by changing the value at the "snapshot/uniform/time" file.

Quote:

Originally Posted by alberto (Post 338241)
As a guideline, changing the time step by hand is a poor practice. If you need to change your time-step, do it automatically by using a solver with adaption (pimpleFoam), and eventually implement a CFL condition that reflects your adaption criterion.

That was one of my guesses.

Quote:

Originally Posted by alberto (Post 338241)
For what concerns the precedence given to what time-stepping information has precedence, giving priority to the uniform/time information seems correct to me, since your run terminated with that information. This however does not mean OpenFOAM will ignore the new time-step set in controlDict.

Mmmm... let me check... nope, if "snapshot/uniform/time" exists, it overrides the "controlDict" value (without physically changing this dictionary). But if "snapshot/uniform/time" is erased, then the value in "controlDict" is used.

Quote:

Originally Posted by alberto (Post 338241)
Finally, since the problems seemed to be that OpenFOAM saved a different time than the desired one. If you change your time-step during the simulation, you must set writeControl to adjustableTimeStep, and not to timeStep. However, this is explained in the User's Guide ;-)

"adjustableTimeStep" doesn't exist ;) But like you said in a previous post, "adjustableRunTime" does exist. Nonetheless, pisoFoam ignores this option completely, since there is no point in its code that specifically checks if "deltaT" changed and load it.

My guess is that Daniel needs a fast running solver and that a higher or lower "deltaT" was needed only for the first few iterations.

Best regards,
Bruno

lakeat January 7, 2012 15:21

Quote:

nope, if "snapshot/uniform/time" exists, it overrides the "controlDict" value (without physically changing this dictionary)
Bruno, You've got a point there. That's exactly what I was trying to say.

I thought controlDict has higher privilege in "controlling" the deltaT value.

Anyway, its no big deal. And I feel it's too quick to judge it good or bad practice, we all have freedom to do something. I just came across to find this issue (or it is not an issue at all), when I was trying to write and test some fancy stuffs.

Thank you guys

alberto January 7, 2012 15:45

Quote:

Originally Posted by wyldckat (Post 338261)
Hi Alberto,

Nope! I tried it myself with the tutorial "incompressible/pisoFoam/ras/cavity" and it did not! Only by changing the value at the "snapshot/uniform/time" file.

You are right. I was tricked by the writeControl. In fixed-step solvers, controlDict is ignored if there is a uniform/time file.

Quote:

"adjustableTimeStep" doesn't exist ;) But like you said in a previous post, "adjustableRunTime" does exist. Nonetheless, pisoFoam ignores this option completely, since there is no point in its code that specifically checks if "deltaT" changed and load it.
Correct, it's "adjustableRunTime". My comment was general, not limited to pisoFoam, since it is a fixed step solver.

alberto January 7, 2012 15:58

Quote:

Originally Posted by lakeat (Post 338263)
Anyway, its no big deal. And I feel it's too quick to judge it good or bad practice, we all have freedom to do something. I just came across to find this issue (or it is not an issue at all), when I was trying to write and test some fancy stuffs.

Of course you can change your time-step manually during your simulation, however it is not recommended (and it has nothing to do with freedom ;-)). The reasons are different, some of convenience, and some related to more numerical and physical aspects.

- To decide the time-step you have to manually compute the maximum Courant number, which is time-consuming. A code can do it for you, exactly and reducing the chance you make mistakes. On the long run, a few more lines of code will save you a lot of time.

- You have to manually account for physical time scales you want to resolve. This can be done easily by implementing the relevant criteria.

- Manual adaption usually is less smooth than what a well-defined adaption can do for you. This reflects on accuracy and stability.

Best,

alberto January 7, 2012 16:16

As a second thought, you can change the time-step by hand directly while the simulation is running, by editing controlDict, and saving it, if runTimeModifiable is set to true in the same dictionary.

Code:

Time = 0.05161

Courant Number mean: 0.000432668 max: 0.00169887
DILUPBiCG:  Solving for Ux, Initial residual = 8.17931e-06, Final residual = 8.17931e-06, No Iterations 0
DILUPBiCG:  Solving for Uy, Initial residual = 1.05228e-05, Final residual = 2.49306e-11, No Iterations 1
DICPCG:  Solving for p, Initial residual = 2.25639e-05, Final residual = 6.67366e-07, No Iterations 17
time step continuity errors : sum local = 3.62613e-13, global = 2.84931e-21, cumulative = 6.5081e-20
DICPCG:  Solving for p, Initial residual = 2.2504e-05, Final residual = 5.38693e-07, No Iterations 17
time step continuity errors : sum local = 2.92495e-13, global = 9.48445e-22, cumulative = 6.60294e-20
ExecutionTime = 9.39 s  ClockTime = 9 s

Time = 0.05162

Courant Number mean: 0.000432674 max: 0.00169887
DILUPBiCG:  Solving for Ux, Initial residual = 8.17484e-06, Final residual = 8.17484e-06, No Iterations 0
DILUPBiCG:  Solving for Uy, Initial residual = 1.05171e-05, Final residual = 2.49175e-11, No Iterations 1
DICPCG:  Solving for p, Initial residual = 2.25517e-05, Final residual = 6.6703e-07, No Iterations 17
time step continuity errors : sum local = 3.62432e-13, global = 1.69903e-22, cumulative = 6.61993e-20
DICPCG:  Solving for p, Initial residual = 2.24918e-05, Final residual = 5.38372e-07, No Iterations 17
time step continuity errors : sum local = 2.92321e-13, global = 1.62789e-21, cumulative = 6.78272e-20
ExecutionTime = 9.39 s  ClockTime = 9 s

regIOobject::readIfModified() :
    Re-reading object controlDict from file "/home/alberto/OpenFOAM/alberto-2.1.x/tutorials/incompressible/icoFoam/cavity/system/controlDict"
Time = 0.05262

Courant Number mean: 0.043268 max: 0.169888
DILUPBiCG:  Solving for Ux, Initial residual = 0.000633579, Final residual = 2.75111e-07, No Iterations 2
DILUPBiCG:  Solving for Uy, Initial residual = 0.000954272, Final residual = 1.37441e-06, No Iterations 2
DICPCG:  Solving for p, Initial residual = 0.325047, Final residual = 6.71319e-07, No Iterations 30
time step continuity errors : sum local = 9.50543e-10, global = -9.0295e-20, cumulative = -2.24678e-20
DICPCG:  Solving for p, Initial residual = 0.0408667, Final residual = 7.39858e-07, No Iterations 29
time step continuity errors : sum local = 8.20548e-10, global = 1.77083e-19, cumulative = 1.54615e-19
ExecutionTime = 9.39 s  ClockTime = 9 s

Time = 0.05362

Courant Number mean: 0.0433123 max: 0.169856
DILUPBiCG:  Solving for Ux, Initial residual = 0.00295721, Final residual = 6.88127e-06, No Iterations 2
DILUPBiCG:  Solving for Uy, Initial residual = 0.00340695, Final residual = 4.3901e-07, No Iterations 3
DICPCG:  Solving for p, Initial residual = 0.047135, Final residual = 7.22096e-07, No Iterations 29
time step continuity errors : sum local = 8.5687e-10, global = 6.6009e-21, cumulative = 1.61216e-19
DICPCG:  Solving for p, Initial residual = 0.0108227, Final residual = 6.78693e-07, No Iterations 28
time step continuity errors : sum local = 8.32457e-10, global = 8.08983e-20, cumulative = 2.42114e-19
ExecutionTime = 9.39 s  ClockTime = 9 s

This makes it quite curious that the time step in controlDict is ignored though. Daniel, maybe you want to report this on Mantis @ OpenCFD, so they can look into this.

Best,

alberto January 7, 2012 16:47

Reported here: http://www.openfoam.com/mantisbt/view.php?id=382

lakeat January 7, 2012 16:56

Thanks, Alberto

alberto January 7, 2012 17:03

Quote:

Originally Posted by lakeat (Post 338271)
Thanks, Alberto

You are welcome. The behavior is indeed not what a user would expect, so I guess it's a bug (and one I haven't noticed in a loooong time!).

wyldckat January 8, 2012 17:01

Hi,

Just saw now Henry's answer on the bug report... ROFL... So another of my conclusions was correct. :rolleyes:
Basically it's one of those features were one should look at the code when no documentation is available :D Hurray for open source :)

I didn't test changing it during runtime because it looked that it wasn't humanly possible to do so with such a small case. But I stand corrected :)

Best regards,
Bruno

alberto January 8, 2012 20:58

Quote:

Originally Posted by wyldckat (Post 338357)
Hi,

Just saw now Henry's answer on the bug report... ROFL... So another of my conclusions was correct. :rolleyes:

Yes, the behaviour OpenFOAM has is desired.

Quote:

Basically it's one of those features were one should look at the code when no documentation is available :D Hurray for open source :)
At least the code is available and organised/readable :-D

Quote:

I didn't test changing it during runtime because it looked that it wasn't humanly possible to do so with such a small case. But I stand corrected :)
Yes, I used a small enough time-step in the first part of the run ;-)

Best,

lakeat January 9, 2012 12:04

Dear Henry,

How about this, let the code give an inconsistency warning for the users, something like:

"deltaT value inconsistency found between snapshot/uniform/time and system/controlDict, blahblahblah".

so to be more human/user oriented.

:)

PS: Sorry to speak here, because I found the bug report had been closed...


All times are GMT -4. The time now is 08:10.