CFD Online Discussion Forums

CFD Online Discussion Forums (https://www.cfd-online.com/Forums/)
-   OpenFOAM Programming & Development (https://www.cfd-online.com/Forums/openfoam-programming-development/)
-   -   Print percentage through run in stdout (in transient solvers) (https://www.cfd-online.com/Forums/openfoam-programming-development/238771-print-percentage-through-run-stdout-transient-solvers.html)

reverseila October 2, 2021 06:21

Print percentage through run in stdout (in transient solvers)
 
Hi everyone,

I guess the title is self-explanatory. For that, one must query the following:

1. current time
2. calculate number of steps (based on the "endTime" and "deltaT")

knowing these two we can do a simple calculation:

Code:

percentage = current time / No. steps * 100
How to access these values a in openfoam solver, so that I can print them for each loop?

Tobermory October 2, 2021 17:16

Probably best to do this as a functionObject rather than editing the solver: drop the following into a file system/printFracRun:

Code:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                |
  \\      /  F ield        | OpenFOAM: The Open Source CFD Toolbox
  \\    /  O peration    | Website:  https://openfoam.org
    \\  /    A nd          | Version:  dev
    \\/    M anipulation  |
-------------------------------------------------------------------------------
Description
    codedFunctionObject to calculate how far trhough a run the solver is and to
    print it out to the screen (as a %, with 1dp).
   
    To use, copy to system folder and add the following to the functions{} subdict
    of controlDict:
                #include        "printFracRun"

\*---------------------------------------------------------------------------*/

func1
{
        libs            ( "libutilityFunctionObjects.so" );
        type            coded;
        name            printFracRun;
        writeControl    timeStep;
        writeInterval  1;
        codeWrite      #{
                scalar startTime = mesh().time().startTime().value();
                scalar endTime = mesh().time().endTime().value();
                scalar currentTime = mesh().time().value();
                scalar pctComplete = int(10 * 100 * (currentTime - startTime) / (endTime - startTime))/10.0;  //note: no check for div by zero!
                Info<< "[printFracRun]: simulation is " << pctComplete << "% complete." << endl;
        #};
}

and add the following into your controlDict (if you already have a functions section, just add the include line):

Code:

functions {
                #include        "printFracRun"
}

That should do the trick, although note that I have been lazy/naughty and have not coded in a check for divide by zero. Good luck!

reverseila October 3, 2021 10:25

Your idea is even better. No need to calculate the number of time steps, and It works like a charm! Thanks a lot!

I think the division by zero only happens when the latestTime is set and its value is the same as the endTime, meaning it only happens when one mistakenly starts a finished run. So I guess no need to be worried about it.

Is it possible to change the precision with something like “setprecision(x)” (I set the writePrecision to 18, and it prints so many decimal points)?

I tested Foam::setprecision(3) and std::setprecision(3) and it didn't compile, simply because they are not a member of corresponding namespaces.

Tobermory October 3, 2021 12:29

Glad that worked for you!

Quote:

Originally Posted by reverseila (Post 813481)
I think the division by zero only happens when latestTime is set and its value is the same as the endTime, meaning it only happens when one mistakenly starts a finished run.

Yes - it would be simple to add some extra lines to check if endTime==currentTime, and if so assume 100% complete, otherwise use the coding I already have ... that would avoid the divZero.


Quote:

Is it possible to change the precision with something like “setprecision(x)” (I set the writePrecision to 18, and it prints so many decimal points)?

I tested Foam::setprecision(3) and it didn't compile, simply because it is not a member of ‘Foam’
Possibly - you'd need to add the relevant header for inclusion. Although, thinking on this some more, the stream handling in OF is done with its own class system so you might find it's already implemented (check out: https://cpp.openfoam.org/v4/OSstream...ce.html#l00291).

Tobermory October 3, 2021 12:43

Okay - well, you learn something new every day! Yes - you can use the std c++ setprecision command. This seems to work:

Code:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                |
  \\      /  F ield        | OpenFOAM: The Open Source CFD Toolbox
  \\    /  O peration    | Website:  https://openfoam.org
    \\  /    A nd          | Version:  dev
    \\/    M anipulation  |
-------------------------------------------------------------------------------
Description
    codedFunctionObject to calculate how far trhough a run the solver is and to
    print it out to the screen (as a %, with 1dp).
   
    To use, copy to system folder and add the following to the functions{} subdict
    of controlDict:
                #include        "printFracRun"

\*---------------------------------------------------------------------------*/

func1
{
        libs            ( "libutilityFunctionObjects.so" );
        type            coded;
        name            printFracRun;
        writeControl    timeStep;
        writeInterval  1;
    codeInclude
    #{
        #include "IOmanip.H"
    #};
        codeWrite      #{
                scalar startTime = mesh().time().startTime().value();
                scalar endTime = mesh().time().endTime().value();
                scalar currentTime = mesh().time().value();
                scalar pctComplete = 0;
                if (startTime == endTime) {
                        pctComplete = 100.0;
                } else {
                        pctComplete = 100 * (currentTime - startTime) / (endTime - startTime);
                }
                Info << setprecision(3);
                Info<< "[printFracRun]: simulation is " << pctComplete << "% complete." << endl;
        #};
}

Edited: fixed a mistake above, in red

reverseila October 3, 2021 15:32

Quote:

Originally Posted by Tobermory (Post 813484)
Code:

codeInclude
#{
        #include "IOmanip.H"
#};


This is awesome! In the meantime I was wondering how to include a header file in a dictionary, that you also add it to the code!

BTW, how did you find out this header file (“IOmanip.H”) should be added?

Tobermory October 4, 2021 03:44

Aaah, that was from a quick google search. The great thing about this forum is that it has been running for long enough that someone has probably had the same question as you at some stage!

Happy to help - this question caught my interest since I had wanted to do some functionObject coding last year using the simulation time, but couldn't work out how to do it at the time ... turns out it was easy all along!

reverseila October 4, 2021 09:11

Yes, this forum is ancient :)

I believe it is possible to find them via Doxygen, not sure how to query, though.

This is my first “functionObject” experience! I'm looking forward to using it for on-the-fly post-processing.


All times are GMT -4. The time now is 04:39.