import { createElement } from 'react' import type { Chapter } from '../../ui/types.ts' import driver from '../twodim/driver.m?raw' import script from './fivepoint.m?raw' import text from './text.md?raw' import { Fields2D, type Single2DOut } from '../twodim/panels.tsx' import { Convergence, fmtErr, type SweepOut } from '../onedim/panels.tsx' import { EXACT2D_CONTROL } from '../shared.ts' import type { Control } from '../../ui/types.ts' const PAR_CONTROL: Control = { kind: 'slider', key: 'par', label: 'shape parameter', min: 1, max: 8, step: 1, format: (v) => String(v), } export const ch05: Chapter = { id: 'five-point', nav: 'The five-point Laplacian', part: 'Two dimensions', title: 'The five-point Laplacian', blurb: 'Harmonic functions as ground truth, the standard stencil, and the cost of solving the system as it comes.', text, labs: [ { id: 'solve', title: 'One solve, and the error field', caption: 'The shape parameter is the degree k for poly, the wavenumber k for wave, and the distance from the square for log.', driver, script, editorOpen: true, controls: [ EXACT2D_CONTROL, PAR_CONTROL, { kind: 'slider', key: 'N', label: 'N', values: [8, 12, 16, 24, 32, 40], min: 8, max: 40 }, ], defaults: { kind: 'expsin', par: 1, mode: 'single', mid: 1, N: 24, maxpix: 97 }, render: (d: Single2DOut) => createElement(Fields2D, { data: d }), summary: (d: Single2DOut) => [ { label: 'unknowns', value: String(d.unknowns) }, { label: 'max error', value: fmtErr(d.maxerr) }, ], }, { id: 'cost', title: 'Second order, at O(N⁶)', caption: 'Five resolutions. The last one is a 2209 by 2209 dense solve and takes a few seconds in a browser.', driver, script, manual: true, controls: [EXACT2D_CONTROL, PAR_CONTROL], defaults: { kind: 'expsin', par: 1, mode: 'sweep', ns: [4, 8, 16, 32, 48], nmaxs: [48], timed: 1 }, render: (d: SweepOut) => createElement(Convergence, { data: d, style: { slots: ['fd2'], refs: [{ p: -2, label: 'slope −2' }] }, }), summary: (d: SweepOut) => [ { label: 'finest error', value: fmtErr(d.E[0][d.E[0].length - 1]) }, { label: 'time for that', value: `${((d.T[0][d.T[0].length - 1] ?? 0) / 1000).toFixed(2)} s`, }, ], }, ], }