CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Post-Processing

snGradCorrection

Register Blogs Members List Search Today's Posts Mark Forums Read

Like Tree10Likes
  • 2 Post By bigphil
  • 4 Post By bigphil
  • 3 Post By cnsidero
  • 1 Post By bigphil

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   September 17, 2012, 08:32
Default snGradCorrection
  #1
New Member
 
Eskil Aursand
Join Date: Sep 2012
Posts: 7
Rep Power: 14
eskila is on a distinguished road
Hello,
I am trying to modify a utility to get the normal gradient of a scalar field at boundaries. I was getting some strange results from using fvc::snGrad, and i read in the Programmers Guide that one might benefit from using fvc::snGradCorrection if the mesh is not orthogonal (which is the case here). I tried this, but when compiling the utility I get the error:

error: ‘snGradCorrection’ is not a member of ‘Foam::fvc’

I'm a beginner with OpenFOAM, and haven't delved too deeply into its code yet, so I'm a little lost on how to find out what I'm doing wrong. Any help will be appreciated.
eskila is offline   Reply With Quote

Old   September 17, 2012, 09:30
Default
  #2
Super Moderator
 
bigphil's Avatar
 
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,091
Rep Power: 34
bigphil will become famous soon enoughbigphil will become famous soon enough
Hi,

there is no fvc::snGradCorrection, but you can use fvc::snGrad and then set snGradSchemes to corrected in your fvSchemes. This will calculate the surface normal gradient with non-orthogonal correction.

As regards snGrad at the boundaries, by default OpenFOAM sets non-orthogonal correction to zero at the boundary (see Jasak Thesis) so the accuracy is only good on orthogonal grids. If you do need correction at the boundaries, you need to implement custom boundary conditions with non-orthogonal correction.

Philip
fumiya and randolph like this.
bigphil is offline   Reply With Quote

Old   September 17, 2012, 10:33
Default
  #3
New Member
 
Eskil Aursand
Join Date: Sep 2012
Posts: 7
Rep Power: 14
eskila is on a distinguished road
Let me see if i've understood you:
fvc::snGrad may be corrected for non-orthogonal meshes, but it will be no use for me if i'm only interested in the boundaries?

snGradSchemes in the system/fvSchemes of my case was already set to "corrected". Is this what is used by my custom utility?
eskila is offline   Reply With Quote

Old   September 17, 2012, 11:07
Default
  #4
Super Moderator
 
bigphil's Avatar
 
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,091
Rep Power: 34
bigphil will become famous soon enoughbigphil will become famous soon enough
Quote:
Originally Posted by eskila View Post
snGradSchemes in the system/fvSchemes of my case was already set to "corrected". Is this what is used by my custom utility?
When you use fvc::snGrad it checks your fvScheme for what method to use. If it finds corrected then it will use non-orthogonal correction.

Quote:
Originally Posted by eskila View Post
Let me see if i've understood you:
fvc::snGrad may be corrected for non-orthogonal meshes, but it will be no use for me if i'm only interested in the boundaries?
Each boundary patch can implement its own method to calculate the boundary snGrad so fvc::snGrad uses the values calculated by the boundary fvPatchField. So if you mesh contains fixedValue patches, then snGrad is given by (code taken from fvPatchField.C):
Code:
00176 // Return gradient at boundary
00177 template<class Type>
00178 Foam::tmp<Foam::Field<Type> > Foam::fvPatchField<Type>::snGrad() const
00179 {
00180     return (*this - patchInternalField())*patch_.deltaCoeffs();
00181 }
As can be seen, this assumes that the cell is orthogonal to the boundary.

Therefore if you are interested in orthogonal correction at the boundaries, you could implement a custom boundary condition where you define the snGrad as (taken from fixedDisplacementFvPatchVectorField.C found here):
Code:
 115     const fvPatchField<tensor>& gradField =
 116         patch().lookupPatchField<volTensorField, tensor>
 117         (
 118             "grad(" +fieldName_ + ")"
 119         );
 120 
 121     vectorField n = this->patch().nf();
 122     vectorField delta = this->patch().delta();
 123 
 124     //- correction vector
 125     vectorField k = delta - n*(n&delta);
 126 
 127     return 
 128     (
 129         *this 
 130       - (patchInternalField() + (k&gradField.patchInternalField()))
 131       )*this->patch().deltaCoeffs();
However, I believe non-orthogonal correction has been set to zero for a reason (for fluids anyway, solids need this correction).

Philip
fumiya, randolph, scleakey and 1 others like this.
bigphil is offline   Reply With Quote

Old   August 30, 2013, 06:52
Default corrected snGradient
  #5
Member
 
Join Date: Oct 2012
Posts: 47
Rep Power: 14
sh.d is on a distinguished road
Hi
i want to discrete momentom Eqn and i need formulation of corrected sngradient in OF.
please help me
sh.d is offline   Reply With Quote

Old   October 15, 2018, 22:05
Default
  #6
Senior Member
 
Reviewer #2
Join Date: Jul 2015
Location: Knoxville, TN
Posts: 141
Rep Power: 11
randolph is on a distinguished road
Philip,

What could be the reason you think?

Thanks,
Rdf
randolph is offline   Reply With Quote

Old   October 17, 2018, 07:05
Default
  #7
Super Moderator
 
bigphil's Avatar
 
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,091
Rep Power: 34
bigphil will become famous soon enoughbigphil will become famous soon enough
Hi Rdf,

I am not sure of the reason; for the diffusion operator, it can make a big difference e.g. look at the gradT field with laplacianFoam on a mesh with non-orthogonal cells near the boundary.

In fact, as far as I know, some forks of OpenFOAM (e.g. Caelus) enable this boundary non-orthogonal correction by default for all physics.

Philip

Last edited by bigphil; October 17, 2018 at 07:05. Reason: typo: replace graddT with gradT
bigphil is offline   Reply With Quote

Old   October 17, 2018, 08:48
Default
  #8
Senior Member
 
Reviewer #2
Join Date: Jul 2015
Location: Knoxville, TN
Posts: 141
Rep Power: 11
randolph is on a distinguished road
Quote:
Originally Posted by bigphil View Post
When you use fvc::snGrad it checks your fvScheme for what method to use. If it finds corrected then it will use non-orthogonal correction.


Each boundary patch can implement its own method to calculate the boundary snGrad so fvc::snGrad uses the values calculated by the boundary fvPatchField. So if you mesh contains fixedValue patches, then snGrad is given by (code taken from fvPatchField.C):
Code:
00176 // Return gradient at boundary
00177 template<class Type>
00178 Foam::tmp<Foam::Field<Type> > Foam::fvPatchField<Type>::snGrad() const
00179 {
00180     return (*this - patchInternalField())*patch_.deltaCoeffs();
00181 }
As can be seen, this assumes that the cell is orthogonal to the boundary.

Therefore if you are interested in orthogonal correction at the boundaries, you could implement a custom boundary condition where you define the snGrad as (taken from fixedDisplacementFvPatchVectorField.C found here):
Code:
 115     const fvPatchField<tensor>& gradField =
 116         patch().lookupPatchField<volTensorField, tensor>
 117         (
 118             "grad(" +fieldName_ + ")"
 119         );
 120 
 121     vectorField n = this->patch().nf();
 122     vectorField delta = this->patch().delta();
 123 
 124     //- correction vector
 125     vectorField k = delta - n*(n&delta);
 126 
 127     return 
 128     (
 129         *this 
 130       - (patchInternalField() + (k&gradField.patchInternalField()))
 131       )*this->patch().deltaCoeffs();
However, I believe non-orthogonal correction has been set to zero for a reason (for fluids anyway, solids need this correction).

Philip
Hi Philip,

Does Foam::fvPatchField<Type>::snGrad() only excuted when the fixedValue is used?

Here is my observation with fvPatchField<Type>::snGrad() and I do not exactly sure about what is the use of the fvPatchField<Type>::snGrad().

First, in the fixedValueFvPatchField.C, there is no fvPatchField<Type>::snGrad(). While, in the fixedGradientFvPatchField.H, fvPatchField<Type>::snGrad() return the gradient that you defined. Am I missing something?

Second, fvPatchField<Type>::snGrad() only referenced by wall functions and snGradScheme< Type >::snGrad().

Third, where does the solver need the fvPatchField<Type>::snGrad()? I thought the BC condition only impact the solution through the function valueInternalCoeffs, valueBoundaryCoeffs, gradientInternalCoeffs(), and gradientBoundaryCoeffs().
randolph is offline   Reply With Quote

Old   October 17, 2018, 09:13
Default
  #9
Senior Member
 
Chris Sideroff
Join Date: Mar 2009
Location: Ottawa, ON, CAN
Posts: 434
Rep Power: 22
cnsidero is on a distinguished road
Quote:
Originally Posted by bigphil View Post
In fact, as far as I know, some forks of OpenFOAM (e.g. Caelus) enable this boundary non-orthogonal correction by default for all physics.
It's not on by default. It can be enabled in the laplacianSchemes dictionary with the following syntax using, for example, the Laplacian of a scalar T:

Code:
laplacian(DT,T) Gauss linear secondOrderCorrected;
Basically use secondOrderCorrected as the snGrad scheme with the Laplacian term of interest. We performed a fairly exhaustive verification using method of manufactured solutions to prove it provides 2nd order accuracy on the boundaries. Refer to my talk from the Ann Arbour OF workshop:

https://sourceforge.net/projects/ope...t-OFW10-77.pdf

Note: With a fixed gradient BC it can recover 2nd order using only the least squares gradient reconstruction. Using the standard Gauss gradient reconstruction, 2nd order not possible because the boundary face value is unknown. We therefore implemented a corrected Gauss gradient, corrGauss, which iterates to improve the accuracy. The default is 2 iterations and improves the accuracy to somewhere between 1st and 2nd order.

-Chris
bigphil, manu305 and randolph like this.
cnsidero is offline   Reply With Quote

Old   October 17, 2018, 21:24
Default
  #10
Senior Member
 
Reviewer #2
Join Date: Jul 2015
Location: Knoxville, TN
Posts: 141
Rep Power: 11
randolph is on a distinguished road
Here are two papers for the future reference

A case-study in open-source CFD code verification, Part I: Convergence rate loss diagnosis

https://www.sciencedirect.com/scienc...78475417303774

A case-study in open-source CFD code verification. Part II: Boundary condition non-orthogonal correction

https://www.sciencedirect.com/scienc...78475417303762
randolph is offline   Reply With Quote

Old   October 21, 2018, 13:51
Default
  #11
Super Moderator
 
bigphil's Avatar
 
Philip Cardiff
Join Date: Mar 2009
Location: Dublin, Ireland
Posts: 1,091
Rep Power: 34
bigphil will become famous soon enoughbigphil will become famous soon enough
Hi randolph,

See my replies below.

Quote:
Originally Posted by randolph View Post
Does Foam::fvPatchField<Type>::snGrad() only excuted when the fixedValue is used?
fvPatchField<Type>::snGrad() is executed for all derived boundary conditions classes that do not override it or explicitly call it. As you have seen, fixedGradient overrides the snGrad function, whereas fixedValue does not.

Quote:
Originally Posted by randolph View Post
Here is my observation with fvPatchField<Type>::snGrad() and I do not exactly sure about what is the use of the fvPatchField<Type>::snGrad().

First, in the fixedValueFvPatchField.C, there is no fvPatchField<Type>::snGrad(). While, in the fixedGradientFvPatchField.H, fvPatchField<Type>::snGrad() return the gradient that you defined. Am I missing something?
Both fixedValueFvPatchField.C and fixedGradientFvPatchField.H derive from fvPatchField, and the snGrad function is a virtual function. fixedGradient overrides the function because by definition fixedGradient "knows" the snGrad at the boundary i.e. the specified boundary gradient is the surface-normal gradient (snGrad); while fixedValue does not know the snGrad and so it does not override the snGrad function. I suggest you revise C++ virtual functions.

Quote:
Originally Posted by randolph View Post
Second, fvPatchField<Type>::snGrad() only referenced by wall functions and snGradScheme< Type >::snGrad().
It is used in other places as well: any time you need the boundary surface normal gradient e.g. when we call fvc::grad, we will need to calculate the gradient at the boundary, and the standard approach in OpenFOAM is to overwrite the snGrad at the boundary using the snGrad boundary condition function.

Quote:
Originally Posted by randolph View Post
Third, where does the solver need the fvPatchField<Type>::snGrad()? I thought the BC condition only impact the solution through the function valueInternalCoeffs, valueBoundaryCoeffs, gradientInternalCoeffs(), and gradientBoundaryCoeffs().
The solution value and gradient of the solution value can also affect the solution, particularly when the solution field boundary conditions are "corrected" after solving i.e. U.correctBoundaryConditions(): this will call the "evaluate()" function for all boundary conditions, which may in turn call snGrad, depending on the boundary condition.
Also, I said above, it will affect the calculation of the gradient field.

Hope it helps,
Philip
randolph likes this.
bigphil is offline   Reply With Quote

Old   October 21, 2018, 14:22
Default
  #12
Senior Member
 
Reviewer #2
Join Date: Jul 2015
Location: Knoxville, TN
Posts: 141
Rep Power: 11
randolph is on a distinguished road
Quote:
Originally Posted by bigphil View Post
Hi randolph,

See my replies below.



fvPatchField<Type>::snGrad() is executed for all derived boundary conditions classes that do not override it or explicitly call it. As you have seen, fixedGradient overrides the snGrad function, whereas fixedValue does not.



Both fixedValueFvPatchField.C and fixedGradientFvPatchField.H derive from fvPatchField, and the snGrad function is a virtual function. fixedGradient overrides the function because by definition fixedGradient "knows" the snGrad at the boundary i.e. the specified boundary gradient is the surface-normal gradient (snGrad); while fixedValue does not know the snGrad and so it does not override the snGrad function. I suggest you revise C++ virtual functions.


It is used in other places as well: any time you need the boundary surface normal gradient e.g. when we call fvc::grad, we will need to calculate the gradient at the boundary, and the standard approach in OpenFOAM is to overwrite the snGrad at the boundary using the snGrad boundary condition function.


The solution value and gradient of the solution value can also affect the solution, particularly when the solution field boundary conditions are "corrected" after solving i.e. U.correctBoundaryConditions(): this will call the "evaluate()" function for all boundary conditions, which may in turn call snGrad, depending on the boundary condition.
Also, I said above, it will affect the calculation of the gradient field.

Hope it helps,
Philip
Philip,

Thank you very much! It is much clear to me now!

Rdf
randolph is offline   Reply With Quote

Old   October 23, 2018, 10:33
Default
  #13
Senior Member
 
Reviewer #2
Join Date: Jul 2015
Location: Knoxville, TN
Posts: 141
Rep Power: 11
randolph is on a distinguished road
Hi Philip,

I spend some time reading the implementation of the snGrad(). However, I have some trouble with understanding the calling sequence. For example, the fixed gradient, which is defined as:
Code:
             
//- Return gradient at boundary
             virtual tmp<Field<Type>> snGrad() const
             {
                 return gradient_;
             }
But here is the calling diagram. I do not see the code where this function snGrad() call the other functions as shown in the diagram.



I am noob in both C++ and OpenFoam. I am very new to the handling of a unstrucured non-orthogonal grid. Could you please help me to understand the implementation of snGrad(). Particularly, how exactly the snGrad() work with other functions, such as valueInternalCoeffs(), valueBoundaryCoeffs(),gradientInternalCoeffs(), gradientBoundaryCoeffs(), to influent the solution.

Thanks,
Rdf
randolph is offline   Reply With Quote

Reply

Tags
gradients, openfoam 2.1.x, post-processing

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

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
snGradCorrection doubtsincfd OpenFOAM 0 September 30, 2011 23:55


All times are GMT -4. The time now is 20:16.