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/)
-   -   updateCoeffs() and evaluate() (https://www.cfd-online.com/Forums/openfoam-programming-development/123913-updatecoeffs-evaluate.html)

lixx September 24, 2013 04:46

updateCoeffs() and evaluate()
 
Hi Foamers,

I am confused with the two functions in boundary condition classes: updateCoeffs() and evaluate(). Sometimes updateCoeffs() is called, but in some BCs evaluate() is called (e.g., src/finiteVolume/fields/fvPatchFields/basic/fixedGradient/fixedGradientFvPatchField.C ). And in the body of evaluate(), there is a call to updateCoeffs() first.

Code:

template<class Type>
void fixedGradientFvPatchField<Type>::evaluate(const Pstream::commsTypes)
{
    if (!this->updated())
    {
        this->updateCoeffs();
    }

    Field<Type>::operator=
    (
        this->patchInternalField() + gradient_/this->patch().deltaCoeffs()
    );

    fvPatchField<Type>::evaluate();
}

So in practice, if I want to implement a new BC, which method should I implement? Or can I implement both? In what sequence they will be called when correctBoundaryCondition() is called?

Another problem is why sometimes a BC have to deal specially with the parallel mode (say, in src/finiteVolume/fields/fvPatchFields/derived/mappedFixedValue/mappedFixedValueFvPatchField.C, updateCoeffs()) while others don't have to do so? Is there guideline for this?

Many thanks,

Xianxiang

lixx October 3, 2013 04:00

Hi anybody can help here? Or this is a really stupid question to ask?

wyldckat October 5, 2013 08:25

Greetings Xianxiang,

When in doubt, check the code documentation: http://foam.sourceforge.net/docs/cpp/index.html

I did a quick search regarding each method and it should be somewhat self-explanatory from their documentation (namely the comments from the header files):
  • updateCoeffs:
    Quote:

    Update the coefficients associated with the patch field.
    In other words, it should update anything referent to the patch itself, such as porosity coefficients or something like that.
  • evaluate:
    Code:

    Evaluate the patch field.
    In other words, this method should take care of properly processing the flow on the patch.
In addition, I suggest that you have a broader look into how the other BCs work, to get a better idea on how to use this.

Best regards,
Bruno

tiam April 29, 2015 04:43

Hello!

Bruno, I think the matter is actually more involved, or, maybe I misunderstand something.

Both evaluate() and updateCoeffs() seem to do more or less the same thing. Calculate some stuff relevant to the boundary condition and then enforce the changes. The latter can take the form of an assignment via == or =, or through the change of some relevant parameters, like weights in the mixed b.c.

As indicated in this thread
here the evaluate() method seems to be implemented only in the highest levels of hierarchy and commonly deals with more "complicated" stuff like the case of coupled patches.

The updateCoeffs() seems to do all the complicated work in the classes that are further downstream in the hierarchy. I am personally looking at wall-functions for LES and the one that exists in OF implements everything in updateCoeffs(), including an iterative procedure to calculate u_tau at each face. In my view this definitely qualifies as "processing the flow", but maybe you meant something else.

The main relationship between the methods is that evaluate() always calls updateCoeffs(). In fvPatchField.C/H we have

Code:

template<class Type>
void Foam::fvPatchField<Type>::evaluate(const Pstream::commsTypes)
{
    if (!updated_)
    {
        updateCoeffs();
    }

    updated_ = false;
}

virtual void updateCoeffs()
{
    updated_ = true;
}

My understanding is that this means that calling updateCoeffs() explicitly (not via evaluate()) will prevent it for being called again. But I am not sure why that is needed, I would appreciate some insight! I also didn't find where the updated_ flag gets reset.

wyldckat May 3, 2015 13:11

Greetings Timofey,

I wrote that post about a year ago and today I still don't know everything about OpenFOAM ;)

The thread you mentioned does give some clearer insight:
Quote:

Originally Posted by deepsterblue (Post 337424)
initEvaluate / evaluate functions are used for boundary field evaluations that are interleaved with inter-processor communication. Take a look at GeometricBoundaryField.C to see how this works..

updateCoeffs basically ensures that boundaryField arrays are up-to-date when the next BC update during the matrix multiply takes place.

As for when the resetting of the "updated_" flag... I'll have to look into the code... OK:
  • In this file:
    Code:

    $FOAM_SRC/finiteVolume/fields/fvPatchFields/fvPatchField/fvPatchField.H
    it this description:
    Code:

            //- Update index used so that updateCoeffs is called only once during
            //  the construction of the matrix
            bool updated_;

  • The flag is set to true when "updateCoeffs()" is called and reset to false at the end of "evaluate()".
  • "evaluate()" is called by "GeometricField<Type, PatchField, GeoMesh>::GeometricBoundaryField::
    evaluate()"...
  • ... which in turn is called by "GeometricField<Type, PatchField, GeoMesh>::
    correctBoundaryConditions()".
  • The last one seems to be called whenever needed, although the likely suspects are the classes at "$FOAM_SRC/finiteVolume/fvMatrices", given the comment above for "updateCoeffs" regarding "construction of the matrix".
I suspect that the variable is only reset when "evaluate()" is done, because this means that it's usually the last operation that is meant to be performed when solving the fields, since it's expected that in the next solving step, everything should have changed values.

Best regards,
Bruno

gaza February 10, 2020 05:12

Quote:

Originally Posted by lixx (Post 453270)
Hi Foamers,

I am confused with the two functions in boundary condition classes: updateCoeffs() and evaluate(). Sometimes updateCoeffs() is called, but in some BCs evaluate() is called (e.g., src/finiteVolume/fields/fvPatchFields/basic/fixedGradient/fixedGradientFvPatchField.C ). And in the body of evaluate(), there is a call to updateCoeffs() first.

Code:

template<class Type>
void fixedGradientFvPatchField<Type>::evaluate(const Pstream::commsTypes)
{
    if (!this->updated())
    {
        this->updateCoeffs();
    }

    Field<Type>::operator=
    (
        this->patchInternalField() + gradient_/this->patch().deltaCoeffs()
    );

    fvPatchField<Type>::evaluate();
}

So in practice, if I want to implement a new BC, which method should I implement? Or can I implement both? In what sequence they will be called when correctBoundaryCondition() is called?

Another problem is why sometimes a BC have to deal specially with the parallel mode (say, in src/finiteVolume/fields/fvPatchFields/derived/mappedFixedValue/mappedFixedValueFvPatchField.C, updateCoeffs()) while others don't have to do so? Is there guideline for this?

Many thanks,

Xianxiang


Hi

I want to check value of a variable inside the updateCoeffs() function
however simple putting Info statement inside the code of the updateCoeffs() does not work


do you know how to do it?

HPE April 16, 2020 12:49

For future reference, quoted from https://www.openfoam.com/documentati...s.html#details:

Quote:

The difference between the methods is based on when the patch values are updated. When the condition is applied to a solution variable, the call to updateCoeffs() occurs as a preliminary step of the <matrix>.solve(). The evaluate() method is invoked after, or independent of the matrix solve, via a call to <field>.correctBoundaryConditions().

gaza April 16, 2020 16:17

Thank you for your response HPE. It will be useful.

Besides that I managed to use Info statement inside BC.
I do not know why it did not work earlier.
Maybe I compiled it in debug version and run opt version, by mistake.

randolph August 12, 2020 14:36

Hi,

So updateCoeffs() will affect the current solution and evaluate() will affect solution for the next step?

Thanks,
Rdf

Gerry Kan August 12, 2020 15:21

Quote:

Originally Posted by randolph (Post 780268)
So updateCoeffs() will affect the current solution and evaluate() will affect solution for the next step?

Dear Randolph:

No. Usually evaluate() makes a call to updateCoeffs() somewhere up the inheritance, where the updated_ flag (a boolean variable) is set to true.
In theory you can update your boundary condition with either function and the effects are the same, but using updateCoeffs() you could (potentially) take advantage of the updated_ flag so that the values are only updated once per time step, instead of once per (inner and outer) solver iteration.

Hope that helps, Gerry.

P.S. - I also agree with tiam (response #4 above). I leave all the heavy lifting to evaluate(), and have updateCoeffs() perform the final write to the solver coefficients.

randolph August 12, 2020 15:26

Gerry,

I see. We are on the same page.

However, in the fixedGradientFvPatchField,

there is no definition of updateCoeffs();

what will this->updateCoeffs(); do ?

Thanks,
Rdf

Gerry Kan August 12, 2020 15:41

Quote:

Originally Posted by randolph (Post 780275)
I see. We are on the same page.
However, in the fixedGradientFvPatchField,
there is no definition of updateCoeffs();
what will this->updateCoeffs(); do ?

Hallo Randolf:

this->updateCoeffs() calls the shallowest inherited virtual function definition. Since updateCoeffs() is not defined in fixedGradient, it will call the updateCoeffs() in fvPatchField, one level up the inheritance tree, which is defined. However, if you define your own updateCoeffs() in your variant of fixedGradient, this->updateCoeffs() will call that instead.

Also, if memory serves, fixedGradientFvPatchField::evaluate() calls its parent virtual function fvPatchField::evaluate(), which in turn calls fvPatchField::updateCoeffs(). fvPatchField::updateCoeffs() serves only to toggle the value of updated_ to true.

So this reinforces the idea that you can implement your B.C. in either function.

Hope that helps, Gerry.


All times are GMT -4. The time now is 15:38.