/ concept-collection / mesh-pde-solver
Sign in
concept-collection / mesh-pde-solver
mesh-pde-solver / README.md
69 lines · 3.2 KBPreviewCodeBlameHistoryRaw
1# mesh-pde-solver
3Upload a quadrilateral surface mesh, pick a PDE, tweak its right-hand side
4and coefficients, and solve it **on the surface** — entirely in your browser.
5The mesh is converted to Gmsh format with [meshio](https://github.com/nschloe/meshio)
6(via [Pyodide](https://pyodide.org)), and the PDE is solved by
7[surfacefun](https://github.com/danfortunato/surfacefun) running on
8[numbl](https://numbl.org), a MATLAB-compatible runtime, in a web worker.
9The solution renders in a rotatable 3D view (drag to rotate, scroll to zoom).
11## PDEs
13- **Poisson (Laplace–Beltrami)** — Δu = f. On a closed surface the problem is
14 rank-deficient: f is projected to mean zero and the mean-zero solution is
15 returned. On an open surface, zero Dirichlet data is imposed.
16- **Helmholtz (variable coefficient)** — (Δ + c)u = f with c(x, y, z) an
17 arbitrary expression.
19The right-hand side f and coefficient c are MATLAB expressions in the surface
20coordinates x, y, z (elementwise operators: `.*`, `.^`, …), with presets to
21start from. The polynomial order per patch is adjustable (accuracy vs. time).
23## Meshes
25Uploads go through meshio, so any of `.msh .vtk .vtu .obj .off .ply .inp
26.mesh .bdf .avs` works — but the mesh **must contain quadrilateral cells**
27(surfacefun computes on quad patches; triangle-only meshes are rejected).
28Two sample meshes are bundled. The converted Gmsh file can be downloaded.
29Whether the surface is closed or open is detected from the edge connectivity.
31## How it works
331. `src/mesh/` — meshio in Pyodide parses the upload, keeps the quad cells,
34 and writes a canonical Gmsh MSH 2.2 ASCII file plus preview arrays.
352. `src/engine/` — a managed numbl session (`createNumblSession` from
36 `numbl/browser`): numbl owns the worker and VFS, bootstraps the
37 [mip](https://github.com/mip-org) package manager, and runs
38 [`matlab/main.m`](matlab/main.m), which begins with
39 `mip load --install surfacefun`. The script opens a placeholder `uihtml`
40 figure that is never rendered — it is the event bridge: the host writes
41 `mesh.msh` into the VFS and dispatches `solve` events; the script solves
42 and sends per-patch data back.
433. `matlab/solve_pde.m` — parses the mesh (`load_gmsh_quads.m`), builds a
44 `surfacemesh` from the quads, `resample`s it to the requested order, and
45 solves with `surfaceop`.
464. `src/render/SurfaceView.tsx` — three.js view of the quad mesh or the
47 per-patch solution grids with a parula colormap.
49The first visit downloads the Python runtime (~15 MB, browser-cached) and
50the surfacefun/chebfun packages (~28 MB). Installed MATLAB packages persist
51in IndexedDB across page loads (numbl wipes them after 24 h of inactivity),
52so later visits skip the package downloads.
54## Development
56```bash
57npm install
58npm run dev # local dev server
59npm run build # static build in dist/
60npm run engine-test # headless solver check in Node (no browser)
61python3 scripts/make_samples.py # regenerate public/samples/
62```
64The engine test runs the exact MATLAB project the worker runs, shimming
65numbl's synchronous-XHR `websave`/`webread` with curl (responses cached in
66`.cache/`), and checks a Poisson solve against an exact spherical-harmonic
67solution.
69Requires numbl >= 0.4.9 (the `numbl/browser` managed-session entry).
moveopenescclose