Densify evaluation set to 289 points; evaluation-point overlay now a toggle, default off
6 changed files+38−22
docs/problems/laplace-dirichlet-2d.mdmodified+5−5View file
@@ -50,9 +50,9 @@ site's interactive views, but such runs are not recorded.
5050
5151 ## What is scored
5252
53-Each instance fixes 65 evaluation points: 16 rays at angles
54-θ_j = 2πj/16 + 0.13 (j = 0, …, 15), radial fractions
55-ρ ∈ {0.25, 0.5, 0.75, 0.9} along each ray (the point at fraction ρ on ray
53+Each instance fixes 289 evaluation points: 32 rays at angles
54+θ_j = 2πj/32 + 0.13 (j = 0, …, 31), radial fractions
55+ρ ∈ {0.1, 0.2, …, 0.9} along each ray (the point at fraction ρ on ray
5656 θ is ρ r(θ) (cos θ, sin θ)), ordered radius-major, plus the origin last.
5757 The solver returns u at exactly these points. Reported errors are
5858
@@ -95,10 +95,10 @@ manifest) and prob is a struct with fields
9595 | `prob.curveD` | first derivative of the curve with respect to t |
9696 | `prob.curveDD` | second derivative |
9797 | `prob.g` | `@(t) -> g`, Dirichlet data at boundary parameter t |
98-| `prob.evalXY` | 65×2, the evaluation points |
98+| `prob.evalXY` | 289×2, the evaluation points |
9999 | `prob.vizXY` | m×2, visualization grid points (m = 0 when not requested) |
100100
101-The return value is a struct: `out.uEval` (65×1, required) and
101+The return value is a struct: `out.uEval` (289×1, required) and
102102 `out.uGrid` (m×1; `[]` when `prob.vizXY` is empty). The solver must not
103103 reconstruct the sources analytically or otherwise special-case the known
104104 solution; submissions are reviewed for this.
src/app/components/DomainView.tsxmodified+2−2View file
@@ -55,7 +55,7 @@ export function DomainView({ inst }: { inst: Laplace2dInstance }) {
5555 ctx.fillStyle = token("--text-2");
5656 for (const p of evalPoints(inst)) {
5757 ctx.beginPath();
58- ctx.arc(X(p.x), Y(p.y), 2, 0, 2 * Math.PI);
58+ ctx.arc(X(p.x), Y(p.y), 1.4, 0, 2 * Math.PI);
5959 ctx.fill();
6060 }
6161
@@ -83,7 +83,7 @@ export function DomainView({ inst }: { inst: Laplace2dInstance }) {
8383 <figure style={{ margin: 0 }}>
8484 <canvas ref={canvasRef} />
8585 <figcaption className="field-caption" style={{ maxWidth: 360 }}>
86- The domain, the 65 evaluation points where solutions are scored
86+ The domain, the evaluation points where solutions are scored
8787 (dots), and the exact solution's sources a distance {inst.d} outside
8888 the boundary (crosses).
8989 </figcaption>
src/app/components/SolutionSection.tsxmodified+17−2View file
@@ -41,6 +41,7 @@ export function SolutionSection({ inst }: { inst: Laplace2dInstance }) {
4141 const [busy, setBusy] = useState(false);
4242 const [error, setError] = useState<string | null>(null);
4343 const [computed, setComputed] = useState<Computed | null>(null);
44+ const [showMarks, setShowMarks] = useState(false);
4445
4546 const exact = useMemo(() => exactGridValues(inst), [inst]);
4647
@@ -113,6 +114,14 @@ export function SolutionSection({ inst }: { inst: Laplace2dInstance }) {
113114 <button className="primary" onClick={compute} disabled={busy}>
114115 {busy ? "computing…" : "Compute in this browser"}
115116 </button>
117+ <label className="small">
118+ <input
119+ type="checkbox"
120+ checked={showMarks}
121+ onChange={(e) => setShowMarks(e.target.checked)}
122+ />{" "}
123+ show evaluation points on the error map
124+ </label>
116125 </div>
117126 {error && <p className="small" style={{ color: "var(--series-2)" }}>{error}</p>}
118127 <div className="row">
@@ -139,9 +148,15 @@ export function SolutionSection({ inst }: { inst: Laplace2dInstance }) {
139148 inst={inst}
140149 values={errField}
141150 mode="logmag"
142- overlayPoints={marks}
151+ overlayPoints={showMarks ? marks : undefined}
143152 title="Pointwise error (log scale)"
144- caption="Absolute difference from the exact solution; the color scale spans 8 decades below the maximum. Dots mark the 65 evaluation points where the reported errors are measured."
153+ caption={
154+ "Absolute difference from the exact solution; the color scale " +
155+ "spans 8 decades below the maximum." +
156+ (showMarks
157+ ? ` Dots mark the ${marks.length} evaluation points where the reported errors are measured.`
158+ : "")
159+ }
145160 />
146161 )}
147162 </div>
src/app/pages/ProblemPage.tsxmodified+2−2View file
@@ -339,8 +339,8 @@ export function ProblemPage({ problemId }: { problemId: string }) {
339339 Compute one solve at a chosen resolution and compare the field with
340340 the exact solution, on a shared color scale. The error map shows the
341341 absolute pointwise difference on a log scale; the errors reported in
342- the results above are measured at the 65 evaluation points, marked
343- as dots on the error map.
342+ the results above are measured at the evaluation points, which can
343+ be shown on the error map.
344344 </p>
345345 <SolutionSection inst={inst} />
346346 </>
src/problems/laplace2d/exact.tsmodified+6−6View file
@@ -49,15 +49,15 @@ export function exactU(inst: Laplace2dInstance, x: number, y: number): number {
4949 return u;
5050 }
5151
52-/** The 65 evaluation points: 16 rays, radial fractions
53- * [0.25, 0.5, 0.75, 0.9], plus the origin. Order matches
54- * build_problem.m: radius outer, angle inner, origin last. */
52+/** The 289 evaluation points: 32 rays, radial fractions 0.1..0.9, plus
53+ * the origin. Order matches build_problem.m: radius outer, angle inner,
54+ * origin last. */
5555 export function evalPoints(inst: Laplace2dInstance): { x: number; y: number }[] {
56- const rho = [0.25, 0.5, 0.75, 0.9];
56+ const rho = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9];
5757 const pts: { x: number; y: number }[] = [];
5858 for (const r of rho) {
59- for (let j = 0; j < 16; j++) {
60- const th = (2 * Math.PI * j) / 16 + 0.13;
59+ for (let j = 0; j < 32; j++) {
60+ const th = (2 * Math.PI * j) / 32 + 0.13;
6161 const rr = r * boundaryR(inst, th);
6262 pts.push({ x: rr * Math.cos(th), y: rr * Math.sin(th) });
6363 }
src/problems/laplace2d/matlab/build_problem.mmodified+6−5View file
@@ -18,7 +18,7 @@ function prob = build_problem(a, k, d, wantGrid)
1818 % curveD @(t) -> [x' y'] first derivative
1919 % curveDD @(t) -> [x'' y''] second derivative
2020 % g @(t) -> g Dirichlet data at boundary parameter t
21-% evalXY 65 x 2 points where uEval is required
21+% evalXY 289 x 2 points where uEval is required
2222 % vizXY m x 2 grid points where uGrid is requested
2323 % (m = 0 when no visualization is wanted)
2424
@@ -41,10 +41,11 @@ prob.curveDD = @(t) [(-a*k*k*cos(k*t) - 1 - a*cos(k*t)).*cos(t) + 2*a*k*sin(k*t)
4141 (-a*k*k*cos(k*t) - 1 - a*cos(k*t)).*sin(t) - 2*a*k*sin(k*t).*cos(t)];
4242 prob.g = @(t) laplace2d_bdata(t, a, k, sx, sy, c);
4343
44-% Evaluation points: 16 rays, 4 radial fractions, plus the origin.
45-% The rule must match evalPoints() in src/problems/laplace2d/exact.ts.
46-rho = [0.25; 0.5; 0.75; 0.9];
47-th = 2*pi*(0:15)'/16 + 0.13;
44+% Evaluation points: 32 rays, radial fractions 0.1..0.9, plus the origin
45+% (289 points). The rule must match evalPoints() in
46+% src/problems/laplace2d/exact.ts.
47+rho = (1:9)'/10;
48+th = 2*pi*(0:31)'/32 + 0.13;
4849 pts = zeros(numel(rho)*numel(th) + 1, 2);
4950 idx = 1;
5051 for i = 1:numel(rho)