/ concept-collection / surfacefun-interactive
Sign in
concept-collection / surfacefun-interactive

Comparing changes

Swap
main is 4 commits ahead of claude/issue-2-20260604-1535. Create pull request
Add claude_args for model configuration
Jeremy Magland committed
bdda5d7
3 changed files+26−44
.github/workflows/claude.ymlmodified+2−0View file
@@ -47,4 +47,6 @@ jobs:
4747 # See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
4848 # or https://code.claude.com/docs/en/cli-reference for available options
4949 # claude_args: '--allowed-tools Bash(gh pr *)'
50+ claude_args: |
51+ --model claude-opus-4-8
5052
vector_field_demo.mmodified+7−4View file
@@ -1,11 +1,14 @@
11 % Interactive vector field on a spherical surface.
22 %
3-% Displays a tangent vector field (arrows) on a sphere. Use the Arrow scale
4-% slider to make arrows larger or smaller — scaling is instant (no MATLAB
5-% round-trip). Drag the surface to rotate; scroll to zoom.
3+% Displays a dense divergence-free tangent vector field on a sphere.
4+% The field v = (x(y^2-z^2), y(z^2-x^2), z(x^2-y^2)) is the surface
5+% curl of F = xyz: eight swirling vortex regions separated by saddle
6+% points at the cube-face centres. sphere(16) gives 6 x 16^2 = 1536
7+% arrows. Use the Arrow scale slider to resize; drag to rotate, scroll
8+% to zoom.
69
710 mip load --install flatironinstitute/flatironinstitute/surfacefun
811
9-dom = surfacemesh.sphere(4); % sphere with 4×4 patches per cube face
12+dom = surfacemesh.sphere(16); % 16-point Chebyshev grid, 6 patches
1013
1114 vector_field_viewer(dom);
vector_field_viewer.mmodified+17−40View file
@@ -14,10 +14,14 @@ uihtml(gl, 'HTMLSource', html, 'Data', data);
1414 end
1515
1616 function data = build_data(dom)
17-%BUILD_DATA Pack surface patches and a sampled tangent vector field.
18-% Samples one arrow per patch at the patch center. The vector field is the
19-% tangential projection of (1, 0, 0) onto the surface — a smooth "wind"
20-% field that vanishes near the poles and is strongest near the equator.
17+%BUILD_DATA Pack surface patches and a dense divergence-free tangent vector field.
18+% Samples every collocation point across all patches. The field is the
19+% stream-function field for F = xyz:
20+% v = (x(y^2-z^2), y(z^2-x^2), z(x^2-y^2))
21+% It is automatically tangent to the unit sphere (v·n = 0) and
22+% divergence-free. The flow has 8 vortex centres at the cube vertices and
23+% 6 saddle points at the cube-face centres, producing eight distinct
24+% swirling regions whose index sum satisfies the Poincare-Hopf theorem.
2125
2226 np = length(dom);
2327 px = cell(1, np);
@@ -29,42 +33,15 @@ for k = 1:np
2933 pz{k} = real(dom.z{k}(:).');
3034 end
3135
32-% Sample one tangent vector at the center of each patch.
33-vx = zeros(1, np);
34-vy = zeros(1, np);
35-vz = zeros(1, np);
36-uu = zeros(1, np);
37-vv = zeros(1, np);
38-ww = zeros(1, np);
36+% Collect ALL collocation points across every patch.
37+all_x = horzcat(px{:});
38+all_y = horzcat(py{:});
39+all_z = horzcat(pz{:});
3940
40-for k = 1:np
41- n = size(dom.x{k}, 1);
42- mid = ceil(n / 2);
43- cx = real(dom.x{k}(mid, mid));
44- cy = real(dom.y{k}(mid, mid));
45- cz = real(dom.z{k}(mid, mid));
46-
47- % Outward unit normal (sphere: normal = normalised position)
48- r = sqrt(cx^2 + cy^2 + cz^2);
49- nx = cx / r; ny = cy / r; nz = cz / r;
50-
51- % Tangential projection of (1, 0, 0)
52- dot_val = nx; % (1,0,0) · normal
53- tu = 1 - dot_val * nx;
54- tv = - dot_val * ny;
55- tw = - dot_val * nz;
56-
57- % Normalise so all arrows have the same base length
58- tmag = sqrt(tu^2 + tv^2 + tw^2);
59- if tmag > 1e-10
60- tu = tu / tmag;
61- tv = tv / tmag;
62- tw = tw / tmag;
63- end
64-
65- vx(k) = cx; vy(k) = cy; vz(k) = cz;
66- uu(k) = tu; vv(k) = tv; ww(k) = tw;
67-end
41+% Stream-function vector field v = n x grad_S(xyz) on the unit sphere.
42+uu = all_x .* (all_y.^2 - all_z.^2);
43+vv = all_y .* (all_z.^2 - all_x.^2);
44+ww = all_z .* (all_x.^2 - all_y.^2);
6845
6946 data = struct();
7047 data.type = 'vectorfield';
@@ -73,5 +50,5 @@ data.x = px;
7350 data.y = py;
7451 data.z = pz;
7552 data.npatches = np;
76-data.vectors = struct('x', vx, 'y', vy, 'z', vz, 'u', uu, 'v', vv, 'w', ww);
53+data.vectors = struct('x', all_x, 'y', all_y, 'z', all_z, 'u', uu, 'v', vv, 'w', ww);
7754 end
moveopenescclose