2 * The available models: their MATLAB source, and the metadata the host owns.
3 *
4 * A model's *algorithm* lives in its .m file. Everything around it lives here:
5 * the parameter names the .m may take as arguments, their defaults and slider
6 * ranges, which grid fields to render, and the dealiasing degree. The .m
7 * declares nothing about these — it just names the parameters it wants, and
8 * `CompiledModel` matches each against this table.
9 *
10 * Naming convention, documented in each .m:
11 * `u`, `v`, ... grid fields the model computes and the app renders
12 * `U`, `V`, ... the corresponding spectral state (uppercase)
13 */
14import schnakenbergSource from '../../models/schnakenberg.m?raw';
591a4f5Reduce the Laplace-Beltrami matvec to 6 transforms per species per iterationDan Fortunato 15import schnakenbergAlg4Source from '../../models/schnakenberg_alg4.m?raw';
0af3386Reaction-diffusion on spherical-harmonic surfacesJeremy Magland 16import brusselatorSource from '../../models/brusselator.m?raw';
17import allencahnSource from '../../models/allencahn.m?raw';
19export type Params = Record<string, number>;
21/** A tunable scalar the .m may take as an argument. */
22export interface ParamSpec {
23 key: string;
24 label: string;
25 value: number;
26 min: number;
27 max: number;
28 step: number;
29}
31export interface MModel {
32 key: string;
33 label: string;
34 blurb: string;
35 /** Grid fields to render, one panel each. */
36 species: string[];
37 /** Spectral state names the .m advances. */
38 state: string[];
39 params: ParamSpec[];
40 /** Polynomial degree of the reaction in the fields, for grid dealiasing. */
41 pdeg: number;
42 /** Amplitude of the seeded perturbation handed to `init`. */
43 seedAmp: number;
44 /** MATLAB source — the algorithm itself. */
45 source: string;
46}
48/** Spectral state names follow the grid-field names, uppercased. */
49const stateFor = (species: string[]): string[] => species.map((s) => s.toUpperCase());
51const schnakenberg: MModel = {
52 key: 'schnakenberg',
53 label: 'Schnakenberg',
56 state: stateFor(['u', 'v']),
57 params: [
58 { key: 'a', label: 'a', value: 0.1, min: 0.01, max: 0.5, step: 0.01 },
59 { key: 'b', label: 'b', value: 0.9, min: 0.1, max: 2, step: 0.05 },
60 { key: 'D1', label: 'D₁', value: 4e-4, min: 1e-5, max: 5e-3, step: 1e-5 },
61 { key: 'D2', label: 'D₂', value: 8e-3, min: 1e-4, max: 5e-2, step: 1e-4 },
62 { key: 'dt', label: 'dt', value: 0.05, min: 0.005, max: 0.5, step: 0.005 },
63 ],
64 pdeg: 3,
65 seedAmp: 1e-2,
66 source: schnakenbergSource,
67};
591a4f5Reduce the Laplace-Beltrami matvec to 6 transforms per species per iterationDan Fortunato 69/**
70 * The same PDE and parameters as `schnakenberg`, with the implicit solve's
71 * geometric correction in its original Cartesian-gradient form (Algorithm 4,
72 * 12 transforms per species per iteration) instead of the flux form's 6
73 * (docs/reduced-transforms.md). Shipped as a live reference:
74 * the two must agree to fp32 accuracy on any surface, and the tests hold
75 * them to that.
76 */
77const schnakenbergAlg4: MModel = {
78 ...schnakenberg,
79 key: 'schnakenberg-alg4',
80 label: 'Schnakenberg (12-transform reference)',
81 blurb: 'Same spots, Algorithm-4 Laplace-Beltrami — for A/B against the flux form.',
82 source: schnakenbergAlg4Source,
83};
0af3386Reaction-diffusion on spherical-harmonic surfacesJeremy Magland 85const brusselator: MModel = {
86 key: 'brusselator',
87 label: 'Brusselator',
62e6cc4Simplify UI text and built-in .m script commentsJeremy Magland 88 blurb: 'Turing stripes and spots.',
90 state: stateFor(['u', 'v']),
91 params: [
92 { key: 'A', label: 'A', value: 3, min: 0.5, max: 6, step: 0.1 },
93 { key: 'B', label: 'B', value: 9, min: 1, max: 15, step: 0.25 },
94 { key: 'D1', label: 'D₁', value: 3.33e-3, min: 1e-4, max: 2e-2, step: 1e-4 },
95 { key: 'D2', label: 'D₂', value: 1.67e-2, min: 1e-3, max: 1e-1, step: 1e-3 },
96 { key: 'dt', label: 'dt', value: 0.02, min: 0.002, max: 0.1, step: 0.002 },
97 ],
98 pdeg: 3,
99 seedAmp: 1e-2,
100 source: brusselatorSource,
101};
103const allencahn: MModel = {
104 key: 'allencahn',
105 label: 'Allen–Cahn',
62e6cc4Simplify UI text and built-in .m script commentsJeremy Magland 106 blurb: 'One species: interfaces form, then coarsen.',
108 state: stateFor(['u']),
109 params: [
110 { key: 'eps2', label: 'ε²', value: 1e-3, min: 1e-4, max: 1e-2, step: 1e-4 },
111 { key: 'dt', label: 'dt', value: 0.02, min: 0.002, max: 0.2, step: 0.002 },
112 ],
113 pdeg: 3,
114 seedAmp: 1e-2,
115 source: allencahnSource,
116};
591a4f5Reduce the Laplace-Beltrami matvec to 6 transforms per species per iterationDan Fortunato 118export const mModels: MModel[] = [schnakenberg, brusselator, allencahn, schnakenbergAlg4];
0af3386Reaction-diffusion on spherical-harmonic surfacesJeremy Magland 119
120export const mModelByKey = (key: string): MModel | undefined =>
121 mModels.find((m) => m.key === key);
123export const defaultParams = (m: MModel): Params =>
124 Object.fromEntries(m.params.map((p) => [p.key, p.value]));
126/** Named parameter presets shown in the UI dropdown. The pattern length scale
127 * goes as 1/sqrt(D), so scaling both diffusivities moves the spot size without
128 * changing the dynamics. */
129export interface Preset {
130 key: string;
131 label: string;
132 modelKey: string;
133 /** Overrides applied on top of the model's default parameters. */
134 params?: Params;
135}
137export const presets: Preset[] = [
138 { key: 'schnak-spots', label: 'Schnakenberg — spots', modelKey: 'schnakenberg' },
139 {
140 key: 'schnak-coarse',
141 label: 'Schnakenberg — coarse spots',
142 modelKey: 'schnakenberg',
143 params: { D1: 1e-3, D2: 2e-2 },
144 },
145 {
146 key: 'schnak-fine',
147 label: 'Schnakenberg — fine spots',
148 modelKey: 'schnakenberg',
149 params: { D1: 1.6e-4, D2: 3.2e-3 },
150 },
151 { key: 'brussel', label: 'Brusselator — stripes & spots', modelKey: 'brusselator' },
152 { key: 'allencahn', label: 'Allen–Cahn — coarsening', modelKey: 'allencahn' },
591a4f5Reduce the Laplace-Beltrami matvec to 6 transforms per species per iterationDan Fortunato 153 {
154 key: 'schnak-alg4',
155 label: 'Schnakenberg — spots (12-transform reference)',
156 modelKey: 'schnakenberg-alg4',
157 },