As an illustration, let's first derive for uniform grids the centered, first-order, finite-difference coefficients accurate to fourth-order in Δx. The fourth-order-accurate, uniformly sampled, centered finite-difference derivative u′(x0) is equivalent to the derivative of the unique polynomial that passes through u(x) at sampled points {x−2,x−1,x0,x1,x2}, where xi=x0+iΔx.
The Taylor series expansion of a function u(x) about a point x0 is given by
u(x)=∞∑n=0u(n)(x0)n!(x−x0)n,where u(n)(x0) is the nth derivative of u evaluated at point x0. Based on this, we can immediately write the Taylor expansion of f at a point x=x0+jΔx. In this case,
u(x0+jΔx)=∞∑n=0u(n)(x0)n!(jΔx)n, or equivalently:uj=∞∑n=0u(n)0n!(jΔx)n.Our goal is to compute u(1)(x0)=u′0 at some point x0, with a dominant error term proportional to (Δx)4. We accomplish this by Taylor expanding u(xj) about x=x0 for j∈{−2,−1,0,1,2}, each up to the n=5 term.
u−2=u0−(2Δx)u′0+(2Δx)22u″0−(2Δx)33!u‴0+(2Δx)44!u(4)0+O((Δx)5)u−1=u0−(Δx)u′0+(Δx)22u″0−(Δx)33!u‴0+(Δx)44!u(4)0+O((Δx)5)u0=u0u1=u0+(Δx)u′0+(Δx)22u″0+(Δx)33!u‴0+(Δx)44!u(4)0+O((Δx)5)u2=u0+(2Δx)u′0+(2Δx)22u″0+(2Δx)33!u‴0+(2Δx)44!u(4)0+O((Δx)5)Let's combine the above equations to find coefficients aj such that (a−2u−2+a−1u−1...)/(Δx)=u′0+O((Δx)4).
(a−2u−2+a−1u−1+a0u0+a1u1+a2u2)/(Δx)=(u0−(2Δx)u′0+(2Δx)22u″0−(2Δx)33!u‴0+(2Δx)44!u(4)0)a−2+(u0−(Δx)u′0+(Δx)22u″0−(Δx)33!u‴0+(Δx)44!u(4)0)a−1+(u0)a0+(u0+(Δx)u′0+(Δx)22u″0+(Δx)33!u‴0+(Δx)44!u(4)0)a1+(u0+(2Δx)u′0+(2Δx)22u″0+(2Δx)33!u‴0+(2Δx)44!u(4)0)a2First notice that each time we take a derivative in the Taylor expansion, we multiply by a Δx. Notice that this helps to keep the units consistent (e.g., if x were in units of meters). Let's just absorb those Δx's into the derivatives (we will extract them again later) and rearrange terms.
a−2u−2+a−1u−1+a0u0+a1u1+a2u2=(a−2+a−1+a0+a1+a2)×u0+(−2a−2−a−1+a1+2a2)×u′0+(22a−2+a−1+a1+22a2)/2!×u″0+(−23a−2−a−1+a1+23a2)/3!×u‴0=u′0In order for the above to hold true for any nonzero values of {u0,u′0,u″0,u‴0,u(4)0}, the following set of equations must also hold: 0=a−2+a−1+a0+a1+a21=−2a−2−a−1+a1+2a20×2!=22a−2+a−1+a1+22a20×3!=−23a−2−a−1+a1+23a20×4!=24a−2+a−1+a1+23a2.
Now we write this expression in matrix form (note that 0!=1). (0×0!1×1!0×2!0×3!0×4!)=(11111(−2)1(−1)1012(−2)2(−1)20122(−2)3(−1)30123(−2)4(−1)40124)(a−2a−1a0a1a2)
So we have reduced the computation of finite difference coefficients to the inversion of an N×N matrix equation. Notice that the elements of the matrix will vary from the one given above if the grid spacing is not constant, but are otherwise invariant to Δx.
The inverted matrix reads (01/12−1/24−1/121/240−2/32/31/6−1/610−5/401/402/32/3−1/6−1/60−1/12−1/241/121/24).
The coefficients for the Mth derivative can be immediately read by multiplying the (M+1)st column by M!/(Δx)M. For example, the zeroth derivative at point x0 is given by
0!(Δx)0×(0u−2+0u−1+u0+0u1+0u2)=u0,which is exact. The first derivative finite difference approximation at point x0 is given by
1!(Δx)1×(112(u−2−u2)+23(−u−1+u1))≈(∂xu)0,and the second derivative finite difference approximation at point x0 is given by
2!(Δx)2×(−124(u−2+u2)+23(u−1+u1)−54u0)≈(∂2xu)0.In short, this matrix yields the finite difference derivative coefficients with the lowest possible error given a stencil size of 5 gridpoints. It can be shown by analyzing cancellations in higher order terms of the Taylor series expansions that the first and second derivative coefficients are correct to (Δx)4 and the third and fourth derivatives are correct to (Δx)2.
NRPy+ implements this simple matrix inversion strategy to evaluate finite difference coefficients.
The following code cell converts this Jupyter notebook into a proper, clickable LATEX-formatted PDF file. After the cell is successfully run, the generated PDF may be found in the root NRPy+ tutorial directory, with filename Tutorial-How_NRPy_Computes_Finite_Difference_Coeffs.pdf. (Note that clicking on this link may not work; you may need to open the PDF file through another means.)
import cmdline_helper as cmd # NRPy+: Multi-platform Python command-line interface
cmd.output_Jupyter_notebook_to_LaTeXed_PDF("Tutorial-How_NRPy_Computes_Finite_Difference_Coeffs")