BlidReview's picture
weights, code, eval script
bdce880 verified
|
Raw
History Blame Contribute Delete
7.52 kB

ezflow_v2/app β€” interactive web app (turbulent-RANS GNN predictor)

A self-contained FastAPI + Three.js app that predicts steady turbulent-RANS flow fields around a body in milliseconds with a choice of surrogate models, an interactive 3D viewer, slice planes, and a point-probe tool.

Self-contained under ezflow_v2/; separate from the v1 app (app/, port 8000) per the v1/v2 separation rule. The v2 app runs on port 8001.

python ezflow_v2/app/run_app.py        # -> http://127.0.0.1:8001 (opens a browser)

First prediction lazily loads the model(s) (the ensemble loads all three, ~10–20 s); every prediction after that runs in milliseconds. Requires the trained runs under ezflow_v2/gnn/_runs/ (rans_v5, hybrid, transolver) and the v2 env (torch 2.11+cu128, gmsh, trimesh, pyvista, fastapi, uvicorn).


What it does (pipeline)

geometry (procedural shape OR uploaded STL)
   β”‚
   β”œβ”€ premesh:  normalize to L=1  β†’  surface (true geometry if watertight, else
   β”‚            voxel envelope)   β†’  graded tet mesh (fine near body)
   β”‚
   β”œβ”€ graph:    nodes = mesh points;  features = geometry + (Re, yaw) ONLY
   β”‚            (same features.py as training β€” no solved field is ever an input)
   β”‚
   β”œβ”€ model:    GeoReNet / HybridFlow / Transolver / mean(G,T,H) ensemble
   β”‚
   └─ outputs:  per-node u, v, w, p, k, Ο‰, Ξ½_t  β†’  3D viewer + slice planes + probe

No CFD is run for a prediction. Inputs are the shape and the operating condition (Re, yaw) only; OpenFOAM is used solely offline to train the models.


Controls & features

Surrogate Model (dropdown)

Option Backed by run Params
mean(G,T,H) ensemble (default) average of the three below ~10.2M
HybridFlow _runs/hybrid 3.04M
GeoReNet _runs/rans_v5 3.28M
Transolver _runs/transolver 3.88M

The ensemble averages the three models per node (in the transformed target space). To add GINO: append "GINO": ["gino"] to MODELS in infer_app.py.

Mesh Resolution (dropdown) β€” the premesher

Preset Surface Near-body size Typical nodes Use
Coarse voxel envelope (vox 64) hβ‰ˆ0.12 ~3k fastest, smoothed
Medium (default) true geometry (watertight) hβ‰ˆ0.045 ~10k detail + training density
Fine true geometry hβ‰ˆ0.022 ~25k+ most detail (slower)
  • Watertight, genus-0 uploads keep their true surface (mirrors/edges survive) and are meshed with curvature-aware near-body refinement.
  • Non-watertight / complex bodies (e.g. DrivAer: open underbody, wheel wells) can't be parametrized into a clean external-flow solid, so they auto-fall-back to a robust voxel envelope (smooth shell) at the requested volume density. This is automatic β€” a complex STL will predict (as an envelope) rather than error.
  • Medium β‰ˆ the ~10k-node density the models were trained on (the sweet spot).

Geometry input

  • Simple Shape tab: cylinder / sphere / box / capsule / cone / torus (sliders).
  • Upload STL tab: drag-and-drop or browse any .stl (auto-normalized to L=1). Test geometries live in C:\dev\ezflow_eval\test_stls\.

Physics

Inlet speed, viscosity, density sliders β†’ Reynolds number (the only physical knob, Re = ρ U∞ L / ΞΌ), plus a yaw slider. Models were trained on Re β‰ˆ 5Γ—10²–1Γ—10⁡; predictions far outside that range are extrapolation.

Visualize Field (slice viewer)

All seven outputs are selectable: |U|, u, v, w, p, k, Ο‰, Ξ½_t. A slice plane (X/Y/Z axis + position slider) is colored by the chosen field; optional flow vectors on the slice. Color map is green (low) β†’ gold β†’ red (high); the legend shows the range and a non-dimensional unit label.

Mouse controls

  • Left-drag β€” rotate
  • Mouse-wheel scroll β€” zoom
  • Wheel-press (middle) drag β€” pan
  • Single left-click β€” set the rotation pivot at that point and probe values there

Point Query (probe)

Click any point in the 3D view β†’ the sidebar shows the predicted x,y,z and all field values (|U|, u, v, w, p, k, Ο‰, Ξ½_t) at the nearest node (/api/probe).

Display & View (right sidebar)

Body style (glass / wireframe / hidden), wind-tunnel box, slice grid lines, flow vectors, and view presets (3D / Side / Top / Front).


HTTP API

Endpoint Method Purpose
/ GET the app page
/api/models GET {models, default}
/api/predict POST (form) shape_type, model_name, resolution, Re, yaw_deg, shape params or file; returns coords, wall_tris, per-field ranges, geom_meta (incl. surface method/n_faces), mesh_meta (incl. resolution, n_nodes_approx), model {name, params_m, members}, bounds
/api/slice POST (json) {normal_axis, position, field_type} β†’ slice points/faces/scalars/vectors
/api/probe POST (json) {x, y, z} β†’ nearest-node {point, values{...}, velocity_vec}

All responses are sent with Cache-Control: no-store so the browser always loads the latest build (static assets are also versioned, ?v=N).


Files

  • run_app.py β€” launcher (port 8001).
  • serve.py β€” FastAPI: endpoints above, no-cache middleware, caches the current pyvista grid for slicing/probing.
  • infer_app.py β€” model loading (architecture rebuilt per checkpoint) + uniform ensemble; mesh_stl() (premesh + read) with the auto-fallback; predict_fields() (predicts on the full mesh β€” the models are mesh-density-robust β€” and returns physical fields via features.inverse_targets).
  • premesh.py β€” detail-preserving premesher: prepare_surface() (true geometry vs voxel envelope) + build_volume() (graded, curvature-aware gmsh mesh); PRESETS.
  • shape_generator.py β€” procedural watertight shapes (trimesh).
  • frontend/ β€” index.html, app.js (Three.js viewer, slicing, probe, colormap), style.css.

Geometry meshing reuses the shared, geometry-neutral gmsh tooling in datasets/gen/shapenet/ (same as infer_v5); it carries no v1 physics.


Caveats / limitations

  • Training fidelity: the models were trained on the smoothed envelope geometries (ModelNet shapes passed through the same voxel remesh). A high-detail mesh improves the geometry/visualization and lets the model run on a faithful body, but the model cannot fully exploit fine features it never saw (e.g. mirror wakes). True fine-detail prediction on complex cars would need retraining on high-fidelity geometry + CFD.
  • Complex/dirty STLs (open underbody, non-watertight) are served as a smooth envelope (see Mesh Resolution). In-app gmsh can't make them a clean external-flow solid; the CFD-grade route (snappyHexMesh) is out of scope for the interactive app.
  • Outputs are non-dimensional (U∞ = 1, ρ = 1, L = 1); labels reflect this (p/ρU∞², Ξ½_t/Ξ½, …).
  • Out-of-distribution geometry (e.g. ModelNet car/airplane, sharp finned bodies) and Reynolds numbers outside ~5Γ—10²–1Γ—10⁡ are extrapolation β€” interpret with care.

Troubleshooting

  • Page looks stale / controls unresponsive: hard-refresh once (Ctrl+Shift+R) or open an Incognito window. The server sends no-cache headers, so it stays fresh afterward.
  • An STL errors: it should auto-fall-back to the envelope; if not, try Coarse resolution (goes straight to the robust envelope).