centered_2nd_uniform

Family
finite_difference
Grid family
cartesian
Kind
scheme
Accuracy
O(dx²)
Applies to
grad(u), dim=x
Rule file
discretizations/finite_difference/centered_2nd_uniform.json
Tags
#finite-difference #centered #uniform #P0

Lowering

The rule is the canonical exemplar of an ESD linear scheme that lowers a §4.2 PDE operator to a closed arrayop expression in the §4.2 op vocabulary. There are no scheme-specific coefficient blobs and no off-spec selector / offset fields — applies_to matches against grad (itself a §4.2 op), and the lowering is a single arrayop whose body combines index, +, -, *, and /. ESS bindings (any binding) can evaluate the lowering by walking the AST.

applies_to:  grad(u, dim=x)
replacement: arrayop(
               output_idx = [$x],
               expr       = (index($u, $x+1) − index($u, $x−1)) / (2·dx),
               args       = [$u]
             )

After pattern-variable substitution ($u → u, $x → i), the lowering at each interior cell reduces to

$$\left(\frac{\partial u}{\partial x}\right)_i \;\approx\; \frac{u_{i+1} - u_{i-1}}{2\,\Delta x}.$$

Boundary conditions

Boundary handling is read from the domain’s boundary_conditions block (esm-spec §11.5) at lowering time and applied as downstream rewrite rules over concrete indices — there is no bc:* op embedded in the lowered AST. The pattern is:

Domain BCIndex transformation applied to $u[$x ± 1]
periodicmod($x ± 1 + N, N) (see periodic_bc)
dirichlet / constantBoundary cells read the prescribed value via index into a fill row
zero_gradient / neumannMirror the in-range neighbor (min/max clamp on the index)

Each transformation is a separate rule that fires at the boundary cells. The centered_2nd_uniform rule itself stays BC-agnostic — its replacement is the interior closed form. The lowering pipeline (rule application + BC rewrites) takes the (grid_family, BC list) pair from the domain and emits index expressions that respect the declared BCs.

Truncation derivation

Symmetric Taylor expansion of the two neighbors about \(x_i\),

$$u_{i\pm 1} \;=\; u_i \;\pm\; \Delta x\,u'_i \;+\; \tfrac{\Delta x^{2}}{2}\,u''_i \;\pm\; \tfrac{\Delta x^{3}}{6}\,u'''_i \;+\; \tfrac{\Delta x^{4}}{24}\,u^{(4)}_i \;\pm\; \cdots,$$

cancels the even-order terms when subtracted, giving

$$\frac{u_{i+1} - u_{i-1}}{2\,\Delta x} \;=\; u'_i \;+\; \tfrac{\Delta x^{2}}{6}\,u'''_i \;+\; O(\Delta x^{4}).$$

The scheme is therefore second-order accurate, with a purely dispersive leading error \(\tfrac{\Delta x^{2}}{6}\,u'''(x)\) and no numerical diffusion — contrast with upwind_1st, whose one-sided stencil introduces an explicit diffusive \((\Delta x / 2)\,u''(x)\) term.

Convergence

Empirical convergence — slope ≈ −2 on log-log
L∞ error of the centered stencil applied to u(x) = sin(2πx) on a periodic [0, 1] domain, sampled at cell centers. Empirical slope matches the expected −2 reference line.

The fixture under discretizations/finite_difference/centered_2nd_uniform/fixtures/convergence/ sets expected_min_order = 1.9 to tolerate minor pre-asymptotic drift on the 16 → 32 → 64 → 128 sequence. ESS’s mms_convergence walks the replacement-form rule through its arrayop / broadcast evaluator (no scheme-specific kernels), so the sweep runs directly against the closed §4.2 lowering described above.