- Tobias Holzmann

# The Upwind Scheme

The following article is related to the Gauss Upwind scheme, implemented in OpenFOAM®. The article will describe the implementation to understand the usage and how the code works in that particular area. The Upwind Scheme is related to the limited surface interpolation schemes which is related to the surface Interpolation schemes. Thus, in OpenFOAM®, the upwind scheme is a limited schemes. In the code section below, it is shown that the limiter in use is zero.

## General Remarks

The Upwind Scheme (First Order Scheme)

The Upwind scheme produces so-called diffusive solutions. That means, the gradients of the quantity of interest is smooth and the solution is not accurate regarding sharp gradients - compare J.H. Ferziger and M. Perić, and the book of R. Schwarze. However, this scheme is the only available numerical discretization method that produces physical and valid values. With other words, the value of Φ is always between the real physical range. In our example, it is the interval [0:1]. The analysis of the investigation shows that the Upwind scheme is more diffusive if an angle between the flow direction and the normal surface vectors exists. If the flow field is parallel to the grid, no numerical diffusion occurs. Using the Taylor series expansion, it can be proven that the Upwind scheme is a the first order scheme; more accurate terms are cut off.

## The Results

Of The Numerical Analysis

## The Code

Upwind scheme

The Upwind scheme is implemented in the upwind class. The class defines the weights() and limiter() functions and inherits the limitedSurfaceInterpolationScheme class. The class named linearUpwind, linearUpwindV and PureUpwindFitScheme (see Doxygen) are inherits the Upwind class. In the header file of the class, the virtual limiter and weights functions are defined. Note: The limiter() function returns zero, thus, no limiter is applied.

```
//- Return the interpolation limiter
virtual tmp
``` limiter
(
const GeometricField&
) const
{
return tmp
(
new surfaceScalarField
(
IOobject
(
"upwindLimiter",
this->mesh().time().timeName(),
this->mesh(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
this->mesh(),
dimensionedScalar("upwindLimiter", dimless, 0.0)
)
);
}

The weights() functions return either 0 or 1 depending on the sign of the fluxes.

```
//- Return the interpolation weighting factors
tmp
``` weights() const
{
return pos0(this->faceFlux_);
}
//- Return the interpolation weighting factors
virtual tmp weights
(
const GeometricField&
) const
{
return weights();
}