CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

updateCoeffs() and evaluate()

Register Blogs Community New Posts Updated Threads Search

Like Tree8Likes
  • 2 Post By wyldckat
  • 4 Post By tiam
  • 1 Post By wyldckat
  • 1 Post By Gerry Kan

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   September 24, 2013, 05:46
Default updateCoeffs() and evaluate()
  #1
New Member
 
Join Date: Nov 2012
Posts: 13
Rep Power: 14
lixx is on a distinguished road
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 is offline   Reply With Quote

Old   October 3, 2013, 05:00
Default
  #2
New Member
 
Join Date: Nov 2012
Posts: 13
Rep Power: 14
lixx is on a distinguished road
Hi anybody can help here? Or this is a really stupid question to ask?
lixx is offline   Reply With Quote

Old   October 5, 2013, 09:25
Default
  #3
Retired Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,981
Blog Entries: 45
Rep Power: 128
wyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to all
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
hua1015 and rajibroy like this.
__________________
wyldckat is offline   Reply With Quote

Old   April 29, 2015, 05:43
Default
  #4
Senior Member
 
Timofey Mukha
Join Date: Mar 2012
Location: Stockholm, Sweden
Posts: 119
Rep Power: 14
tiam is on a distinguished road
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.
tiam is offline   Reply With Quote

Old   May 3, 2015, 14:11
Default
  #5
Retired Super Moderator
 
Bruno Santos
Join Date: Mar 2009
Location: Lisbon, Portugal
Posts: 10,981
Blog Entries: 45
Rep Power: 128
wyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to allwyldckat is a name known to all
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 View Post
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
huangxianbei likes this.
wyldckat is offline   Reply With Quote

Old   February 10, 2020, 06:12
Default
  #6
Senior Member
 
Przemek
Join Date: Jun 2011
Posts: 249
Rep Power: 16
gaza is on a distinguished road
Quote:
Originally Posted by lixx View Post
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?
__________________
best regards
pblasiak
gaza is offline   Reply With Quote

Old   April 16, 2020, 13:49
Default
  #7
HPE
Senior Member
 
HPE's Avatar
 
Herpes Free Engineer
Join Date: Sep 2019
Location: The Home Under The Ground with the Lost Boys
Posts: 931
Rep Power: 13
HPE is on a distinguished road
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().
HPE is offline   Reply With Quote

Old   April 16, 2020, 17:17
Default
  #8
Senior Member
 
Przemek
Join Date: Jun 2011
Posts: 249
Rep Power: 16
gaza is on a distinguished road
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.
__________________
best regards
pblasiak
gaza is offline   Reply With Quote

Old   August 12, 2020, 15:36
Default
  #9
Senior Member
 
Reviewer #2
Join Date: Jul 2015
Location: Knoxville, TN
Posts: 141
Rep Power: 11
randolph is on a distinguished road
Hi,

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

Thanks,
Rdf
randolph is offline   Reply With Quote

Old   August 12, 2020, 16:21
Default
  #10
Senior Member
 
Gerry Kan's Avatar
 
Gerry Kan
Join Date: May 2016
Posts: 376
Rep Power: 11
Gerry Kan is on a distinguished road
Quote:
Originally Posted by randolph View Post
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.
Gerry Kan is offline   Reply With Quote

Old   August 12, 2020, 16:26
Default
  #11
Senior Member
 
Reviewer #2
Join Date: Jul 2015
Location: Knoxville, TN
Posts: 141
Rep Power: 11
randolph is on a distinguished road
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
randolph is offline   Reply With Quote

Old   August 12, 2020, 16:41
Default
  #12
Senior Member
 
Gerry Kan's Avatar
 
Gerry Kan
Join Date: May 2016
Posts: 376
Rep Power: 11
Gerry Kan is on a distinguished road
Quote:
Originally Posted by randolph View Post
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.
randolph likes this.
Gerry Kan is offline   Reply With Quote

Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Purposes of updateCoeffs, initEvaluate and evaluate....? philippose OpenFOAM Programming & Development 9 September 29, 2020 06:09
implementation of wallHeatTransfer BC Tobi OpenFOAM Programming & Development 1 August 8, 2012 09:21


All times are GMT -4. The time now is 10:52.