fem-analysis
FEM Analysis Skill (FreeFEM++ + PyVista)
Overview
End-to-end FEM analysis pipeline (macOS / Linux / WSL):
- Model & Mesh: Generate FreeFEM++
.edpcode from natural language - Solve: Execute FreeFEM++ and capture results
- Visualize: PyVista rendering for publication-quality images
- Evaluate: AI reviews visualization (self-check loop)
Platform Notes
macOS
FreeFEM++ on macOS
FreeFEM++ is installed via Homebrew. The binary name may differ by version:
# Check which is available
which FreeFem++ || which freefem++
Homebrew paths (Apple Silicon): /opt/homebrew/bin/FreeFem++
Homebrew paths (Intel Mac): /usr/local/bin/FreeFem++
PyVista on macOS
macOS has native OpenGL support — no xvfb needed.
For off-screen rendering (Claude Code sessions, CI, SSH):
import os
os.environ["PYVISTA_OFF_SCREEN"] = "true" # BEFORE importing pyvista
import pyvista as pv
pv.OFF_SCREEN = True
For interactive display (direct terminal use): PyVista auto-detects display on macOS — no special setup needed.
matplotlib on macOS
# Off-screen (Claude Code / SSH):
import matplotlib
matplotlib.use("Agg")
# Interactive (iTerm2 / Terminal.app):
# auto-selects "MacOSX" backend — no config needed
Linux / WSL
FreeFEM++ on Linux/WSL
sudo apt update && sudo apt install -y freefem++
Binary path: /usr/bin/FreeFem++ (apt version)
PyVista on Linux/WSL (headless)
WSL and headless Linux require xvfb for off-screen rendering:
sudo apt install -y libgl1-mesa-glx xvfb
For off-screen rendering:
import os
os.environ["PYVISTA_OFF_SCREEN"] = "true" # BEFORE importing pyvista
import pyvista as pv
pv.OFF_SCREEN = True
If rendering still fails, wrap the command with xvfb-run:
xvfb-run python src/visualize.py
matplotlib on Linux/WSL
import matplotlib
matplotlib.use("Agg") # Always use Agg in headless environments
Available Tools
- FreeFEM++ 4.x — PDE solver (
brew install freefemon macOS /sudo apt install freefem++on Linux) - gmsh — Advanced mesh generation (
brew install gmsh/sudo apt install gmsh) - Python 3.10+ — via uv or system package manager
- PyVista + VTK — 3D visualization (native arm64 wheels on Apple Silicon)
- meshio — Mesh format conversion
- Node.js 18+ — React Viewer (via fnm or package manager)
Workflow
Step 1: Problem Understanding
Clarify with user if needed: geometry, physics type, materials, BCs, desired output.
Step 2: Generate FreeFEM++ Code
Read the appropriate reference first:
references/elasticity_2d.md— Plane stress/strainreferences/thermal_2d.md— Heat conductionreferences/poisson_2d.md— Poisson/Laplacereferences/stokes_2d.md— Stokes flowreferences/topology_optimization.md— SIMP, Level-Set, Topological Derivativereferences/shape_optimization.md— Parametric, Geometric, FreeFEM optimizers (BFGS/IPOPT/NLopt)references/h1_gradient_method.md— Azegami H1 gradient method (Traction Method): gradient/Newton/theta methods, domain/boundary integral formulationsreferences/cmap_examples.md— CMAP official toolbox code examples (Geometric / Level-Set / Homogenization)
CRITICAL: iovtk plugin is NOT available on this system. Always use text-based output:
savemesh(Th, "mesh.msh");
{ ofstream f("solution.txt"); for(int i=0; i<Vh.ndof; i++) f << u[][i] << endl; }
P2→P1 projection: When solving with P2, project before saving:
fespace Wh(Th, P1);
Wh ux = u; // P2 → P1 projection
Step 3: Execute
FreeFem++ problem.edp 2>&1
If not in PATH:
/opt/homebrew/bin/FreeFem++ problem.edp 2>&1 # macOS Apple Silicon
/usr/local/bin/FreeFem++ problem.edp 2>&1 # macOS Intel
/usr/bin/FreeFem++ problem.edp 2>&1 # Linux/WSL (apt)
Step 4: Visualize with PyVista
Use scripts/ff_mesh_reader.py for mesh parsing and scripts/visualize.py for rendering.
Set os.environ["PYVISTA_OFF_SCREEN"] = "true" BEFORE importing pyvista in Claude Code sessions.
Step 5: AI Self-Evaluation Loop
viewthe screenshot- Check: deformation direction, stress concentration locations, BC satisfaction, mesh adequacy
- If issues → fix .edp → re-run → re-visualize
- Present final result
Step 6: Interactive 3D (Optional)
Export mesh+solution as JSON → React artifact with Three.js/Plotly for rotation/zoom.
Common Gotchas
- iovtk unavailable → always use text output + Python conversion
- Set PYVISTA_OFF_SCREEN before import (Claude Code sessions)
- Auto-scale deformation:
scale = 0.1 * L / max_displacement - FreeFem .msh is NOT gmsh format — use custom parser in scripts/
- Boundary labels: 1=bottom, 2=right, 3=top, 4=left (rectangle convention)
- Homebrew binary name: Check
FreeFem++vsfreefem++(case varies by version) - Apple Silicon (arm64): VTK/PyVista wheels are native — no Rosetta needed
- macOS Gatekeeper: First run may need
xattr -d com.apple.quarantine $(which FreeFem++)
Local Dev Setup
See references/project_setup.md for full scaffold instructions (macOS with Homebrew / Linux with apt).