The LimitedLinear Scheme

The following article is related to the Limited scheme, implemented in OpenFOAM®. The article will describe the implementation to understand the usage and how the code works in that particular area. The LimitedScheme Schemes are related to the limited surface Interpolation schemes and apply a limiter to the calculation. These schemes are also known as NVD/TVD schemes (Normalized Variable Diminishing and Total Variation Diminishing). Thus, in OpenFOAM®, all LimitedScheme schemes are related to the limited surface interpolation schemes (such as the Upwind scheme). However, compared to the Upwind or LinearUpwind scheme, here a limiter is applied. As already said, these schemes represent the NVD/TVD scheme section.

General Remarks

The Limited Scheme (Second Order Scheme)

The Limited scheme (LimitedLinear) calculates a limiter that is applied to the field to avoid non-physical values, compare J.H. Ferziger and M. Perić. The numerical analysis below demonstrates that the applied limiter introduces stability. This can be directly proved, if the Linear scheme is used for the calculation. The calculated values of Φ are in the range of the defined interval [0:1]. Due to numerical errors, it is possible to get values lower or higher than the threshold. The order of magnitude of the error is in the range of 10-e13 (in this example). The comparison of this study shows, that one should prefer the usage of limited schemes rather than the pure Linear scheme. Especially if the mesh is non-orthogonal.

The Results

Of The Numerical Analysis

Structured Grid (0°)

20 x 20 numerical cells

Structured Grid (0°)

40 x 40 numerical cells

Structured Grid (0°)

80 x 80 numerical cells

Data Analysis

Comparison

Structured Grid (45°)

20 x 20 numerical cells

Structured Grid (45°)

40 x 40 numerical cells

Structured Grid (45°)

80 x 80 numerical cells

Data Analysis

Comparison

Unstructured Grid

20 x 20 numerical cells

Unstructured Grid

40 x 40 numerical cells

Unstructured Grid

80 x 80 numerical cells

Data Analysis

Comparison

Polygon Grid

20 x 20 numerical cells

Polygon Grid

40 x 40 numerical cells

Polygon Grid

80 x 80 numerical cells

Data Analysis

Comparison

Grid Comparison

20 x 20 numerical cells

Grid Comparison

40 x 40 numerical cells

Grid Comparison

80 x 80 numerical cells

The Code

Limited scheme

The Limited scheme is implemented in the LimitedScheme class. The class inherits the limitedSurfaceInterpolationScheme class in which the weights() and limiter() functions are defined. However, the limiter() function is overwritten by the LimitedScheme class which returns the interpolation weighting factors. The weights function is given in the Upwind scheme article. The limiter is calculated in the LimitedScheme class. As one can see in the limiter() function, a calcLimiter() function is called in which the limiter is calculated.

template< class Type, class Limiter, template< class> class LimitFunc>
 Foam::tmp< Foam::surfaceScalarField>
 Foam::LimitedScheme< Type, Limiter, LimitFunc>::limiter
 (
     const GeometricField& phi
 ) const
 {
    //- Code removed
    ...
		
         calcLimiter(phi, limiterField);
 
         return limiterField;
    }

The calcLimiter() function is evaluated as given below. 

 template class LimitFunc>
 void Foam::LimitedScheme::calcLimiter
 (
     const GeometricField& phi,
     surfaceScalarField& limiterField
 ) const
 {
     const fvMesh& mesh = this->mesh();
 
     tmp>
         tlPhi = LimitFunc()(phi);
 
     const GeometricField&
         lPhi = tlPhi();
 
     tmp>
         tgradc(fvc::grad(lPhi));
     const GeometricField&
         gradc = tgradc();
 
     const surfaceScalarField& CDweights = mesh.surfaceInterpolation::weights();
 
     const labelUList& owner = mesh.owner();
     const labelUList& neighbour = mesh.neighbour();
 
     const vectorField& C = mesh.C();
 
     scalarField& pLim = limiterField.primitiveFieldRef();
 
     forAll(pLim, face)
     {
         label own = owner[face];
         label nei = neighbour[face];
 
         pLim[face] = Limiter::limiter
         (
             CDweights[face],
             this->faceFlux_[face],
             lPhi[own],
             lPhi[nei],
             gradc[own],
             gradc[nei],
             C[nei] - C[own]
         );
				 
     //- Code removed (Boundary related code)
     ...
  }

Support Holzmann CFD for more information