Skip to main content

Playground · research instrument

Signal

Online FEA Solver

Hand-built 2-D finite element solver in the browser. CST triangles and bar elements, dense K assembly, Gaussian elimination Ku=F, Von Mises HSL heatmap, scaled displacement vectors, procedural creaks and fracture snap with viewport flash. Pick cantilever, plate with hole, or truss — tune load, direction, and PLA/Al/Steel presets.

Independent research instrument — not claimed as MakerPortal shipped product code. Methods, equations, assumptions, and limitations are disclosed so you can inspect what the page does and does not establish.

FEA Controls

Mesh & Geometry

Load — N & Direction

Point load applied at tip; plate uses edge distribution, truss at top chord mid.

Material — Linear elastic

K size
Nodes / Elems
Max U
Max σ_vm
Yield util
Solve ms

1 — Mesh (undef) · 2 — Stress colormap · 3 — Deformed + displacement vectors

Mesh canvas

Von Mises heatmap HSL 240→0

lowhigh

Deformation (scaled) + vectors

◼ fixed BC→ load FColor = σ_vmArrow len = |U|
Assembly K_e
CST + bar EA/L
Strain ε = B·u
B from b_i,c_i
Criterion
σ_vm < σ_y

Anatomy of the lab

Mesh → K → Ku=F → stress

  1. Geometry: Cantilever L×H grid nx×ny quads split to 2 CST each; plate with hole rejects elements with centroid r<R_hole; truss builds nodes at chords and diagonals.
  2. Local K_e: CST B=(1/2A)[b_i,0;c_i ...], D plane-stress. Bar formula EA/L with cx,cy rotates to global.
  3. Assembly: K[2*i+di, 2*j+dj] += Ke_local[3*i+di,3*j+dj]. F tip = [F·cosθ, F·sinθ]. Fixed left edge Dirichlet ux=uy=0.
  4. Reduction: Free DOF list → K_ff, F_f → Gaussian elimination with pivoting O((2N)³) — capped at ~800 DOF for interactivity.
  5. Post: u_e extracted → ε=B·u, σ=D·ε → σ_vm. Max σ colored, displacement scaled by user ×.

CST B matrix & Von Mises

B=12A[b10b20b300c10c20c3c1b1c2b2c3b3],σvm=σx2σxσy+σy2+3τxy2B=\frac{1}{2A}\begin{bmatrix}b_1&0&b_2&0&b_3&0\\0&c_1&0&c_2&0&c_3\\c_1&b_1&c_2&b_2&c_3&b_3\end{bmatrix},\quad \sigma_{vm}=\sqrt{\sigma_x^2-\sigma_x\sigma_y+\sigma_y^2+3\tau_{xy}^2}

b_i = y_j-y_k, c_i = x_k-x_j cyclic. D scaled by E/(1-ν²).

Visual-audio coupling

  • Mesh canvas: original nodes light, fixed nodes dark squares, triangles thin stroke. Keeps undeformed reference.
  • Stress canvas: each triangle filled with HSL mapping h = 240°·(1 - σ_norm)^0.85 → continuous blue-cyan-yellow-red. Edge highlight at yield.
  • Deform canvas: positions p_def = p₀ + scale·U. Optional wireframe + displacement vectors arrow_len ∝ |U| / max|U| capped.
  • Audio: WebAudio. Creaks when 0.65<σ_max/σ_y<1.0: white noise buffer 180 ms → BPF 1100 Hz Q8 + 2200 Hz parallel, gain=r²·0.34. Fracture when σ_max>σ_y: 85 ms snap highpass 2.8 kHz + down-chirp osc 1400→60 Hz, master gain 0.85, triggers flash.
  • Viewport flash: overlay div background radial rgba(255,60,60,0.42) animate flash 460 ms, canvas transform shake 8 px.

Bar element & global K

k=EAL, Ke=k[cx2cxcycx2cxcycxcycy2cxcycy2cx2cxcycx2cxcycxcycy2cxcycy2], Kij+=Kek=\frac{EA}{L},\ K_e=k\begin{bmatrix}c_x^2&c_xc_y&-c_x^2&-c_xc_y\\c_xc_y&c_y^2&-c_xc_y&-c_y^2\\-c_x^2&-c_xc_y&c_x^2&c_xc_y\\-c_xc_y&-c_y^2&c_xc_y&c_y^2\end{bmatrix},\ K_{ij}\mathrel{+}=K_e

The math and physics, in full

Element stiffness

KeCST=tABTDB,D=E1ν2[1ν0ν10001ν2]K_e^{CST}=tA B^T D B,\quad D=\frac{E}{1-\nu^2}\begin{bmatrix}1&\nu&0\\\nu&1&0\\0&0&\frac{1-\nu}{2}\end{bmatrix}

CST = constant strain triangle, plane-stress.

System

Kglobalu=F,Kffuf=Ff (Dirichlet reduced),σ=DBueK_{global}u=F,\quad K_{ff}u_f=F_f\ \text{(Dirichlet reduced)},\quad \sigma=DBu_e

Von Mises & Yield

σvm=12[(σ1σ2)2+(σ2σ3)2+(σ3σ1)2]=σx2σxσy+σy2+3τ2<σy\sigma_{vm}=\sqrt{\tfrac12[(\sigma_1-\sigma_2)^2+(\sigma_2-\sigma_3)^2+(\sigma_3-\sigma_1)^2]} =\sqrt{\sigma_x^2-\sigma_x\sigma_y+\sigma_y^2+3\tau^2}<\sigma_y

Gear behind this build

FEA stack · 5 picks

Hardware picks5

More gear across every app: the full Gear list →

Hardware Kit Builder

Build the physical hardware platform. Select your components below to generate a live, real-time bill of materials and build instructions.

Build this lab

From FEA to moving hardware

SparkFun does not stock Prusa/Bambu printers — use XRP + Inventor’s Kit for real mechanical load paths, plus PLA for printed fixtures.

Prices shown were retrieved from the Amazon Product Advertising API on 19 July 2026 and are indicative only — the price and availability on Amazon at the time of purchase apply.

Estimated total

$242

Prices from Amazon catalog cache · may change

Open primary listing ↗

Kit Total

Buy ↗

Core solver — TypeScript

// CST plane-stress triangle
function cstStiffness(x1,y1,x2,y2,x3,y3, E, nu, t){
  const A = 0.5*Math.abs((x2-x1)*(y3-y1) - (x3-x1)*(y2-y1)) + 1e-12;
  const b1=y2-y3, b2=y3-y1, b3=y1-y2;
  const c1=x3-x2, c2=x1-x3, c3=x2-x1;
  const inv2A = 1/(2*A);
  const B = [
    [b1*inv2A, 0,        b2*inv2A, 0,        b3*inv2A, 0       ],
    [0,        c1*inv2A, 0,        c2*inv2A, 0,        c3*inv2A],
    [c1*inv2A, b1*inv2A, c2*inv2A, b2*inv2A, c3*inv2A, b3*inv2A]
  ];
  const eFac = E/(1-nu*nu);
  const D = [ [eFac, eFac*nu, 0],
              [eFac*nu, eFac, 0],
              [0,0, eFac*(1-nu)/2] ];
  const Bt = transpose(B); // 6x3
  const DB = mul(D,B);     // 3x6
  const Ke = mulScalar( mul(Bt, DB), t*A ); // 6x6
  return {Ke, B, D, A};
}
// Bar element K_e = EA/L * [c^2 cs -c^2 -cs; ...]
function barStiffness(x1,y1,x2,y2, E, Asec){
  const dx=x2-x1, dy=y2-y1; const L=Math.hypot(dx,dy)||1e-9;
  const cx=dx/L, cy=dy/L; const k=E*Asec/L;
  const Ke=[
    [ k*cx*cx,  k*cx*cy, -k*cx*cx, -k*cx*cy],
    [ k*cx*cy,  k*cy*cy, -k*cx*cy, -k*cy*cy],
    [-k*cx*cx, -k*cx*cy,  k*cx*cx,  k*cx*cy],
    [-k*cx*cy, -k*cy*cy,  k*cx*cy,  k*cy*cy]
  ];
  return {Ke, L, cx, cy};
}
// Gaussian elimination with partial pivoting
function solveLinear(K, F){
  const n=F.length; const A=K.map(r=>r.slice()); const b=F.slice();
  for(let i=0;i<n;i++){
    let maxRow=i, maxV=Math.abs(A[i][i]);
    for(let r=i+1;r<n;r++) if(Math.abs(A[r][i])>maxV){maxV=Math.abs(A[r][i]); maxRow=r;}
    if(maxV<1e-12) continue;
    if(maxRow!==i){ [A[i],A[maxRow]]=[A[maxRow],A[i]]; [b[i],b[maxRow]]=[b[maxRow],b[i]]; }
    const piv=A[i][i];
    for(let r=i+1;r<n;r++){
      const f=A[r][i]/piv; if(Math.abs(f)<1e-14) continue;
      for(let c=i;c<n;c++) A[r][c]-=f*A[i][c];
      b[r]-=f*b[i];
    }
  }
  const x=new Array(n).fill(0);
  for(let i=n-1;i>=0;i--){
    let s=b[i];
    for(let j=i+1;j<n;j++) s-=A[i][j]*x[j];
    x[i]=Math.abs(A[i][i])<1e-12?0:s/A[i][i];
  }
  return x;
}
// Von Mises plane stress
function vonMises(sx, sy, txy){ return Math.sqrt(sx*sx - sx*sy + sy*sy + 3*txy*txy); }

Frequently asked questions

What element formulation are you using?

2D plane-stress Constant Strain Triangle (CST) with 3 nodes, 6 DOF per element, plus 2-node bar element for truss mode. B matrix uses b_i = y_j - y_k, c_i = x_k - x_j divided by 2A. D = E/(1-ν²) [[1,ν,0],[ν,1,0],[0,0,(1-ν)/2]]. K_e = t·A·Bᵀ·D·B for thickness t. Bar element uses K_e = (EA/L) [[c²,cs,-c²,-cs],[cs,s²,-cs,-s²],[-c²,-cs,c²,cs],[-cs,-s²,cs,s²]].

How is K assembled and solved?

Global K is dense (2N×2N) up to ~800 DOF. Each local K_e added via DOF mapping 2*node+{0:ux,1:uy}. Fixed DOFs removed to form reduced K_ff·u_f = F_f solved by Gaussian elimination with partial pivoting. After solve u maps back with u_constrained=0. Strains ε=B·u_e, stresses σ=D·ε per element.

How is Von Mises computed for plane stress?

σ_vm = √(σ_x² - σ_x·σ_y + σ_y² + 3·τ_xy²). For bar elements σ_y=τ=0 so σ_vm=|σ_x|. Color maps HSL 240°→0° (blue→red) via norm σ_vm/ maxσ. Yield check triggers snap when max σ_vm > σ_yield.

Why does audio creak before fracture?

Creaks are filtered noise bursts through bandpass 900-2500 Hz Q≈7, gain proportional to utilization r=σ_max/σ_yield when 0.65<r<1.0. Stochastic trigger ~1.2Hz at r=0.85 scaled. Fracture snap is 80 ms white noise highpassed at 3 kHz + down-chirp 1200→80 Hz oscillator, with viewport flash CSS keyframe and 0.6s shake.

What are the model limitations?

Linear elasticity only, small deformations, no plasticity hardening, no contact. CST locks for ν→0.5. Plane stress assumes thin plate; no out-of-plane bending stiffness for beam — so deflection is membrane-dominated, order-of-magnitude correct but not Euler-Bernoulli. Mesh density <20×8 keeps solve < ~16 ms in JS. Yield is von Mises criterion only.

Shareable still

The instrument, captured—not illustrated.

This 16:9 frame is rendered from the real browser instrument above. It is the page's canonical preview for image search, link unfurls, and posts that need to show what the tool actually does.

Download 1280 × 720 JPEG
FEA Structural Dynamics Lab — live MakerPortal instrument screenshot
Canonical capture · real UI · no generated scientific artwork