@@ -208,6 +208,61 @@ struct VanAlbada {
208208 }
209209};
210210
211+ /* !
212+ * WENO3-JS (Jiang-Shu) reconstruction to cell faces
213+ *
214+ * This is a third-order essentially non-oscillatory reconstruction using two
215+ * candidate second-order polynomials and smoothness-weighted blending.
216+ *
217+ * Unlike TVD slope limiters (e.g. ``MC``), WENO reconstruction is generally
218+ * smooth (differentiable) for all inputs, but it does not enforce strict
219+ * monotonicity.
220+ *
221+ * Uses only the three-point stencil (`m`, `c`, `p`), so it is a drop-in
222+ * replacement anywhere `Stencil1D` is populated with those values.
223+ */
224+ struct WENO3 {
225+ void operator ()(Stencil1D& n) {
226+ // Right face (between c and p): value from cell c (left state at i+1/2)
227+ const BoutReal p0_r = 0.5 * (-n.m + 3.0 * n.c );
228+ const BoutReal p1_r = 0.5 * (n.c + n.p );
229+
230+ const BoutReal beta0_r = SQ (n.c - n.m );
231+ const BoutReal beta1_r = SQ (n.p - n.c );
232+
233+ // Left face (between m and c): value from cell c (right state at i-1/2)
234+ const BoutReal p0_l = 0.5 * (-n.p + 3.0 * n.c );
235+ const BoutReal p1_l = 0.5 * (n.m + n.c );
236+
237+ const BoutReal beta0_l = beta1_r;
238+ const BoutReal beta1_l = beta0_r;
239+
240+ // Smoothness parameter (scaled to local variation)
241+ const BoutReal eps = 1e-12 * (beta0_r + beta1_r) + 1e-30 ;
242+
243+ // Linear weights for WENO3-JS
244+ constexpr BoutReal d0 = 1.0 / 3.0 ;
245+ constexpr BoutReal d1 = 2.0 / 3.0 ;
246+
247+ // Right face weights
248+ const BoutReal a0_r = d0 / SQ (eps + beta0_r);
249+ const BoutReal a1_r = d1 / SQ (eps + beta1_r);
250+ const BoutReal wsum_r = a0_r + a1_r;
251+ const BoutReal w0_r = a0_r / wsum_r;
252+ const BoutReal w1_r = a1_r / wsum_r;
253+
254+ // Left face weights (mirrored)
255+ const BoutReal a0_l = d0 / SQ (eps + beta0_l);
256+ const BoutReal a1_l = d1 / SQ (eps + beta1_l);
257+ const BoutReal wsum_l = a0_l + a1_l;
258+ const BoutReal w0_l = a0_l / wsum_l;
259+ const BoutReal w1_l = a1_l / wsum_l;
260+
261+ n.R = w0_r * p0_r + w1_r * p1_r;
262+ n.L = w0_l * p0_l + w1_l * p1_l;
263+ }
264+ };
265+
211266/* !
212267 * Communicate fluxes between processors
213268 * Takes values in guard cells, and adds them to cells
0 commit comments