Skip to content

Spatial derivatives

Staggered grid layout

staggered grid

To avoid the development of spurious modes in the pressure solve, the velocity field is housed on a staggered grid, as shown in the above schematic. The pressure field pr is stored at the cell midpoints, on the grid defined by the coordinates (xm(k), ym(j), zm(i)). We also store the temperature field temp (and if used the humidity field qhum) at the cell midpoints. The velocity components are then discretised on their corresponding cell edges.

The boundaries of the domain are specified to lie on the grid of the cell edges, so for example (if the x-domain size is set as alx3=1)

xc[1]=0,xc[nx]=1. x_c[1] = 0, \qquad x_c[n_x] = 1 .

The cell mid-points are always defined as

xm[k]=xc[k]+xc[k+1]2, x_m[k] = \frac{x_c[k] + x_c[k+1]}{2} ,

whether the grid is stretched or uniform. The grids in yy and zz must always be uniformly spaced so that Fourier transforms can be performed in the pressure solver, but the grids in xx can be non-uniform. Their stretching is defined by the input parameters str3 and istr3.

Finite difference method on non-uniform grids

In the case of a uniform grid of grid spacing Δx\Delta x, it is straightforward to obtain a finite-difference expression for the second derivative of a function f(x)f(x) accurate to second order in Δx\Delta x:

f(xk)fk+12fk+fk1Δx2+O(Δx2). f''(x_k) \approx \frac{f_{k+1}-2f_k + f_{k-1}}{ {\Delta x}^2} + O({\Delta x}^2).

Here we have written fk=f(xk)f_k=f(x_k) for values of the function on the discrete grid xk=kΔxx_k=k\Delta x.

When using a stretched grid, as we do in AFiD to resolve thin boundary layers, the spacing between grid points is non-uniform, and we must modify this expression. By Taylor expanding f(x)f(x) about xkx_k, we obtain the following expression for the second derivative:

f(xk)=2δ++δ[fk+1fkδ+fkfk1δ], f''(x_k) = \frac{2}{\delta_+ + \delta_-} \left[\frac{f_{k+1}-f_k}{\delta_+} - \frac{f_k - f_{k-1}}{\delta_-} \right] ,

where δ+=xk+1xk\delta_+=x_{k+1}-x_k and δ=xkxk1\delta_- = x_k - x_{k-1} are the grid spacings either side of xkx_k. Note that if δ+=δ\delta_+=\delta_-, we recover the previous expression used for a uniform grid. This expression is used by the subroutine second_derivative_coeff to generate the relevant difference coefficients for each variable.

Boundary conditions

The boundary points need to be treated with care in the code, since the second derivative is the only term in which the boundary values are specified in the numerics. The expression for the derivative is essentially unchanged, except that at for example the lower boundary we must introduce a "ghost point" x0=x1x_0=-x_1. We then determine the value of ff at this ghost point based on the type of boundary condition imposed:

f0=2af1iff(0)=a,f0=f1iff(0)=0. f_0 = 2a - f_1 \quad \textrm{if} \quad f(0) = a, \qquad \qquad f_0 = f_1 \quad \textrm{if} \quad f'(0) = 0 .

We determine the nature of the boundary conditions via the variables inslws/n (for v,wv,w), TfixS/N (for TT), and SfixS/N (for SS) from the input file bou.in. Note that u=0u=0 and xϕ=0\partial_x \phi=0 are always imposed. Currently, the values of the boundary conditions for TT and SS are hard-coded in SetTempBCs and SetSalBCs. This may want to be changed in the future to allow more control from the input file. Note that the boundary values are added to the derivative expression directly in the subroutines ImplicitAndUpdateXX.