View Issue Details

IDProjectCategoryView StatusLast Update
0002904OpenFOAMBugpublic2018-04-25 22:25
Reporterwyldckat Assigned Towill  
PrioritylowSeverityminorReproducibilitysometimes
Status resolvedResolutionfixed 
Fixed in Versiondev 
Summary0002904: Rare bug: purgeWrite + SIMPLE.residualControl + stopping criteria also reached at writeTime ==> last time step is deleted
DescriptionI've always wondered if a bug could occur if the stopping criteria reached with 'SIMPLE.residualControl' were to be achieved in the same time step when it writes to disk when 'writeTime' is true. Yesterday I found out by mere chance what happens, when the solver finished without the respective written time step, due to 'purgeWrite' being set to 1 (or >= 1).

In the "Steps To Reproduce" section below, is the scenario of how it happens and how a tutorial case can be used to reproduce the issue. Here I'll outline the reason for the two issues that were revealed by this bug:


 1- Starting in the workflow, the call 'runTime.write()' made in 'simpleFoam' will write the time step, in accordance to 'writeInterval'. This will add the current time to the 'Foam::Time::previousWriteTimes_' short list, within 'Foam::Time::writeObject()'.

    * For me, it would keep in the list only the '300' time step, given that it was written every 100th time step.


 2- After that, the 'while' loop at the top will call 'simple.loop()', which will (among other things) check if the stopping criteria based on the residuals threshold has been met - for me, it was still on 300th time step. Notes on this method 'Foam::simpleControl::loop()':

   a. When 'criteriaSatisfied()', it will go through the following code section:

            // Set to finalise calculation
            time.writeAndEnd();

   b. The problem is that the method 'writeAndEnd()' will not just "set to finalise" as indicated by the comment, it will in fact call the method 'Foam::Time::writeAndEnd()', which will both set the 'stopAt_' and 'endTime_' variables, but it will also call the method 'writeNow()'.

   c. The method 'Foam::Time::writeNow()' will then set 'writeTime_ = true', but also calls 'write()'...

   d. Which in turn calls the same exact method that was called before by the solver via 'runTime.write()'.


 3- When then happens is that:

   i. The files are stored once again to disk (this is bug #2, redundant writing of the same files);

   ii. Along with the 'Foam::Time::previousWriteTimes_' short list being populated with two occurrences of the current time step - "(300 300)" in my case - which will result in 'previousWriteTimes_.size() > 1' and consequently deleting the first entry on that short list... which happens to be the same as the second entry... which is the bug #1: incorrect time-keeping in the short list.


I don't have a fix for this yet, given that there are several breaking points in this part of the code, further explored in the section "Additional Information" below.
Steps To Reproduce1. Have 'fvSolution.SIMPLE.residualControl' configured for stopping when the residuals are below a threshold value.

2. Have a common write control and interval for 'simpleFoam', e.g.:

    writeControl timeStep;

    writeInterval 100;

3. Have 'purgeWrite' set to 1.

4. Run the solver and have it (accidentally) converge on the same time step as when it writes a time step due to the 'writeInterval'. For me, it accidentally happened on the 300th step of a case yesterday.


In order to reproduce this in planned manner, use the tutorial case "incompressible/simpleFoam/pitzDaily" and change the settings in 'system/controlDict' as follows:

    -endTime 2000;
    +endTime 287;

    -writeInterval 100;
    +writeInterval 41;

    -purgeWrite 0;
    +purgeWrite 1;

The final time step could change depending on your architecture, given that I've had it converge on 287 or 288, depending on the machine+Linux Distribution, so don't forget to match the 'writeInterval' accordingly, e.g. 41 or 144 respectively.


While the case is running, take a look into the time folders being created and erased as intended, until it comes to the final time step, when the last time step folder simply disappears due to the 'purgeWrite'.
Additional InformationThe breaking points are:

 1. In the method 'Foam::Time::writeObject', the short list 'previousWriteTimes_' should be handled a bit better, namely in a way that it would ensure that the same time step is not logged twice.

 2. 'Foam::Time::write()' should not be allowed to write twice in the same time step... unless the programmer specifically wants to write additional fields that were not auto-written at first??

 3. In the method 'Foam::simpleControl::loop()', the comment "Set to finalise calculation" is not entirely true. So either the comment should be corrected to something like "Set to finalise calculation and forcefully write now" or the method 'Foam::writeAndEnd()' should not effectively write do disk directly and should only set the appropriate flags.


Given these 3 breaking points, I couldn't decide if the 3 issues should be explicitly fixed or if we should simply address the issue of not allowing 'Time::writeObject()' or 'Time::writeNow()' from writing twice the same time step (along with revising the comment in 'simpleControl::loop()'), which would solve both bugs on this report.



Furthermore, I haven't fully checked since which version this bug exists, but it seems to be present since the beginning of the 'OpenFOAM-dev' repository.
TagsNo tags attached.

Activities

will

2018-04-25 22:25

manager   ~0009524

Last edited: 2018-04-25 22:25

Thanks for the report. I can see and reproduce the issue.

In my opinion, Time::writeAndEnd isn't at fault, it does what I would expect it too; rather, the call made by the solution controls to writeAndEnd is too simplistic. The solution control run/loop functions' positions in the loop are well defined and are therefore able to check whether a write has been done, and quit or write-and-quit accordingly. I've fixed it so this is the case.

I have also protected addition into the previous write times so that a duplicate entry cannot occur. This isn't necessary for this bug, the above fix already covers it, but it's logical and safer.

Changes pushed to dev as commit b7d5bc98.

Issue History

Date Modified Username Field Change
2018-04-19 18:47 wyldckat New Issue
2018-04-25 22:25 will Assigned To => will
2018-04-25 22:25 will Status new => resolved
2018-04-25 22:25 will Resolution open => fixed
2018-04-25 22:25 will Fixed in Version => dev
2018-04-25 22:25 will Note Added: 0009524
2018-04-25 22:25 will Note Edited: 0009524