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/)
-   -   What is the trigger of the function objects?? (https://www.cfd-online.com/Forums/openfoam-programming-development/144913-what-trigger-function-objects.html)

Sylv November 24, 2014 03:58

What is the trigger of the function objects??
 
Dear foamer,

In any solver, one can add some function objects in the controlDict. They are triggered at the end of each solver timestep. In the solvers, I guess that the triggering line of code is "runTime.write()". Is that true?

Is it possible to trigger a function object at a different location in the source code? For example, I want to extract the field average of a LES run just after the prediction loop of pimpleFoam (after UEqu.H). What kind of code can I add to trigger a funcObj call?

Best,
Marcel

floquation November 26, 2014 08:35

1 Attachment(s)
(Below I take v2.3.x as my version.)

As part of my internship, I duck into the lagrangian library for which I looked into both FunctionObjects and CloudFunctionObjects. Attached you'll find a qualitative UML diagram showing the calling sequence of methods. The top-left of the image is the execution of a FunctionObject.

Tracing FunctionObjects, one may find the following in "OpenFOAM-2.3.x / src / OpenFOAM / db / Time / Time.C."

Code:

bool Foam::Time::run() const
{
  ...
  if (timeIndex_ == startTimeIndex_)
  {
      functionObjects_.start();
  }
  else
  {
      functionObjects_.execute();
  }
  ...
}

So, functionObjects are executed via the runTime.run() command in a solver.

While I have never tried executing them elsewhere, I see that the Time class does have a getter for the functionObjects list, so you should be able to retrieve that list and thus execute functionObjects whenever you want.

So something like...
Code:

runTime.functionObjects().execute();
will execute all functionObjects at that time.

To only execute a specific functionObject, you need to do something like...
Code:

label id = runTime.functionObjects().findObjectID(name); //Warning: returns -1 if "name" does not exist.
runTime.functionobjects()[id].execute(forceWrite); //Warning: fatal error if id is out of bounds (e.g. -1)

which uses the methods from:
OpenFOAM-2.3.x / src / OpenFOAM / db / functionObjects / functionObjectList / functionObjectList.C
and "forceWrite" is an optional boolean with defaults 'false'.


Disclaimer: I did not test the above code (I don't have access to OF right now). I reasoned from the source code. Try it yourself.

hoseinr59 September 3, 2016 15:29

Quote:

Originally Posted by floquation (Post 521205)
(Below I take v2.3.x as my version.)

As part of my internship, I duck into the lagrangian library for which I looked into both FunctionObjects and CloudFunctionObjects. Attached you'll find a qualitative UML diagram showing the calling sequence of methods. The top-left of the image is the execution of a FunctionObject.
.
.
.


Disclaimer: I did not test the above code (I don't have access to OF right now). I reasoned from the source code. Try it yourself.

I am trying to access the forceCoeffs inside the solver. The execute function triggers the OpenFOAM::forceCoeffs.write() which is a virtual boolean type function and I can not change the type to return the forceCoeffs value.

Is there any way I can access forces in the solver ?

salehi144 October 30, 2020 09:17

Hi,

It is an old question, but for the people who might be interested (Based on OpenFOAM-v2007):

I can see that Kevin answered the question correctly. Just to put it in another way, the functionObjects are called inside the run() function from the time class. For example, let's consider the pimpleFoam solver. The solver loop starts with:

Code:

    while (runTime.run())
    {
        #include "readDyMControls.H"
        #include "CourantNo.H"
        #include "setDeltaT.H"

        ++runTime;

The runTime object inherits from Time class in which run() function is defined. If you look at the function somewhere this piece of code is called:
Code:

            if (timeIndex_ == startTimeIndex_)
            {
                addProfiling(functionObjects, "functionObjects.start()");
                functionObjects_.start();
            }
            else
            {
                addProfiling(functionObjects, "functionObjects.execute()");
                functionObjects_.execute();
            }


Therefore, the functionObjects are called at the beginning of each loop and not at the end. In this way, they are also called after the final time step.

The simpleFoam solver is also similar. But first the loop() function is called and the run() function is called inside the loop().

Best
Saeed

mostanad November 28, 2021 21:54

Quote:

Originally Posted by salehi144 (Post 786376)
Hi,

It is an old question, but for the people who might be interested (Based on OpenFOAM-v2007):

I can see that Kevin answered the question correctly. Just to put it in another way, the functionObjects are called inside the run() function from the time class. For example, let's consider the pimpleFoam solver. The solver loop starts with:

Code:

    while (runTime.run())
    {
        #include "readDyMControls.H"
        #include "CourantNo.H"
        #include "setDeltaT.H"

        ++runTime;

The runTime object inherits from Time class in which run() function is defined. If you look at the function somewhere this piece of code is called:
Code:

            if (timeIndex_ == startTimeIndex_)
            {
                addProfiling(functionObjects, "functionObjects.start()");
                functionObjects_.start();
            }
            else
            {
                addProfiling(functionObjects, "functionObjects.execute()");
                functionObjects_.execute();
            }

Therefore, the functionObjects are called at the beginning of each loop and not at the end. In this way, they are also called after the final time step.

The simpleFoam solver is also similar. But first the loop() function is called and the run() function is called inside the loop().

Best
Saeed


Hi Saeed,


I know this post belongs to some time ago, and now we know where functionObjects are triggered. However, this brings an important question about functionObjects.



The question is about how to have access to a function in a functionObject?


I have a "forces" functionObject which writes the postProcessing files at the end of time step and also within the terminal. I am using OF 5.x, which is showing me this function for output files in the forces.C:


Code:

bool Foam::functionObjects::forces::write()
{
    calcForcesMoment();

    if (Pstream::master())
    {
        logFiles::write();

        writeForces();

        writeBins();

        Log << endl;
    }
    return true;
}

However, it shows me another function which is my of interest as well: forceEff()

Code:

Foam::vector Foam::functionObjects::forces::forceEff() const
{
    return sum(force_[0]) + sum(force_[1]) + sum(force_[2]);
}

So the question is whether it is possible to call this function within my icoFoam solver?


Hint: I have seen its usage in rigidBodyMeshMotion.


Thank you for your help and consideration.

xiaoxiao January 18, 2022 07:20

Hi there, I have the same question as you do. Have you successfully called this forceEff function? I really dont know how to do it:(


All times are GMT -4. The time now is 02:11.