/ concept-collection / turing-surface-cache
Sign in
concept-collection / turing-surface-cache
turing-surface-cache / src / cache / options.ts
80 lines · 3.0 KBBlameHistoryRaw
1/**
2 * The discrete parameter space.
3 *
4 * Every knob the app offers is a choice from a short enumerated list, so a run
5 * is fully identified by a small tuple of exact values — which is what makes
6 * the cloud cache work: the same choices always produce the same cache key
7 * (src/cache/spec.ts), with no floating-point formatting ambiguity, because
8 * the values *are* these list entries, never something typed or interpolated.
9 *
10 * The numerical-scheme knobs (lmax, niter, seed wavelength) are fixed in this
11 * version rather than offered, but they are recorded in the spec and the cache
12 * key all the same, so making them choices later invalidates nothing.
13 */
14import type { Params } from '../mgpu/registry.ts';
16export interface DiscreteChoice {
17 key: string;
18 label: string;
19 /** The allowed values, in display order. */
20 values: number[];
21 /** Default — must be one of `values`. */
22 value: number;
25/** Model parameter choices (Schnakenberg). */
26export const MODEL_CHOICES: DiscreteChoice[] = [
27 { key: 'a', label: 'a', values: [0.05, 0.1, 0.15, 0.2], value: 0.1 },
28 { key: 'b', label: 'b', values: [0.7, 0.9, 1.1, 1.3], value: 0.9 },
29 { key: 'D1', label: 'D₁', values: [1.6e-4, 4e-4, 1e-3], value: 4e-4 },
30 { key: 'D2', label: 'D₂', values: [3.2e-3, 8e-3, 2e-2], value: 8e-3 },
31 { key: 'dt', label: 'dt', values: [0.02, 0.05, 0.1], value: 0.05 },
32];
34/** Geometry parameter choices, by geometry key. The sphere has none. */
35export const GEOMETRY_CHOICES: Record<string, DiscreteChoice[]> = {
36 sphere: [],
37 ellipsoid: [
38 { key: 'ax', label: 'a', values: [0.6, 1, 1.5], value: 1.5 },
39 { key: 'ay', label: 'b', values: [0.6, 1, 1.5], value: 1 },
40 { key: 'az', label: 'c', values: [0.6, 1, 1.5], value: 0.6 },
41 ],
42 peanut: [
43 { key: 'waist', label: 'waist', values: [0.4, 0.6, 0.8], value: 0.6 },
44 { key: 'stretch', label: 'stretch', values: [0, 0.6, 1.2], value: 0.6 },
45 ],
46};
48export const SEED_CHOICE: DiscreteChoice = {
49 key: 'seed',
50 label: 'seed',
51 values: [1, 2, 3, 4, 5],
52 value: 1,
53};
55/**
56 * End times, in simulation-time units. Every entry is an exact multiple of
57 * every dt choice, so a run to any of them lands on a whole number of steps —
58 * and a run to a later one passes exactly through the earlier ones. That is
59 * where the along-the-way cache snapshots come from, and, in the other
60 * direction, why a computation can warm-start from the longest cached
61 * shorter run of the same spec.
62 */
63export const T_END_CHOICE: DiscreteChoice = {
64 key: 'tEnd',
65 label: 'end time',
66 values: [100, 200, 400, 800, 1600],
67 value: 100,
68};
70/** Fixed numerical-scheme settings (recorded in every spec and cache key). */
71export const LMAX = 63;
72export const NITER = 8;
73export const LAM3 = 0.5;
75export const defaultChoiceParams = (choices: DiscreteChoice[]): Params =>
76 Object.fromEntries(choices.map((c) => [c.key, c.value]));
78/** Display formatting: exact and compact ("4e-4", "0.05"). */
79export const fmtChoice = (v: number): string =>
80 v !== 0 && Math.abs(v) < 0.01 ? v.toExponential() : String(v);
moveopenescclose