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/)
-   -   How to handle errors in a function object and stop the simulation? (https://www.cfd-online.com/Forums/openfoam-programming-development/190869-how-handle-errors-function-object-stop-simulation.html)

MakisH July 24, 2017 18:10

How to handle errors in a function object and stop the simulation?
 
I am creating a custom function object, in which I want to have some checks (e.g. in the read() function for the user input) and exit the simulation with an error if something goes wrong.

I managed to output an error, using the FatalErrorIn() macro:
Code:

FatalErrorIn("myFunctionObject::myFunction()") << "This is my error message." << nl << exit(FatalError);
This indeed exits the function object, but the simulation continues running, simply without executing the function object's code.

I tried to use the stopAt() method (before the exit()) to stop the simulation manually:
Code:

runTime_.stopAt(Time::saNoWriteNow);
but this does not force the simulation to exit with an error code.

How could I stop the simulation from the functionObject, but with a failure exit code?

MakisH September 1, 2017 12:34

How to stop the simulation immediately?
 
Apart from the fact that OpenFOAM catches the functionObject's errors as "Warnings" (i.e. exiting the functionObject but not the solver itself), I have another relevant question.

The stopAt() method can take one of the following values as an argument:

Code:

saEndTime    stop when Time reaches the prescribed endTime
saNoWriteNow  set endTime to stop immediately w/o writing
saWriteNow    set endTime to stop immediately w/ writing
saNextWrite  stop the next time data are written

(see this in the Source Code Guide)

I understand that the saNoWriteNow is the "most urgent" one. However, the solver still performs another iteration and executes the execute() method of the functionObject once more before it finishes.

Is there a better way to stop the simulation immediately? I hope that this is an interesting question.

Zeppo September 3, 2017 09:06

What if you use abort() instead of exit()?

MakisH September 3, 2017 09:18

This works, but is it a good practice? Is it used anywhere else in OpenFOAM or third-party function objects?

I guess you mean the C++ abort(), because I don't find such an OpenFOAM function.

Zeppo September 3, 2017 16:23

When you write
Code:

FatalErrorIn("myFunctionObject::myFunction()") << "This is my error message." << nl << exit(FatalError);
actually you are working with an object FatalError of class error
Code:

274 // Global error definitions
275
276 Foam::error Foam::FatalError("--> FOAM FATAL ERROR: ");

Class error is an OF wrapper for termination functions from C. Look at the sources:
https://cpp.openfoam.org/v3/a07673_source.html#l00168

MakisH September 4, 2017 05:46

You are right, there is an OpenFOAM abort(). In the beginning I didn't see that method...

However, it still catches the fatal error as a warning and continues the simulation:

Code:

--> FOAM Warning :
    From function bool Foam::functionObjectList::read()
    in file db/functionObjects/functionObjectList/functionObjectList.C at line 675
    Caught FatalError
--> FOAM FATAL ERROR:
This is my error message.


MakisH September 4, 2017 11:10

A "hacky" way to gracefully stop the simulation would also be to set the end time to the current time (or even to zero):

Code:

const_cast<Time&>(runTime_).setEndTime(runTime_.value());
where "runTime_" is the functionObject's reference to the runTime object of the solver.

This will not call any "end()" method of this or other function objects.

Is there any reason to not do it this way?

MakisH September 5, 2017 11:58

I found something interesting:

the behavior I described happens only in the read() method, as the Foam::functionObjectList::read() catches any exceptions.

Using the macro FatalErrorInFunction works normally in the functionObject's execute() and the rest of the methods.

In my case, the code I had in my read() can also go in the start() [correction: start() doesn't exist for a functionObject itself], so my specific problem is solved. Thank you for the help! :-D

edit: Actually it can't, since Foam::functionObjectList::start() simply calls Foam::functionObjectList::read()... :-/


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