# Solid mechanics ## Microsim <iframe src="https://editor.p5js.org/sciencenibber/full/xTHeUaxph" width="740" height="560" frameborder="0" title="Solid mechanics microsim"></iframe> <img src="../SPINTRONICS_Statics_Images/Solid_mechanics.png" alt="Solid_mechanics microsim"> - **Editor URL:** [Open in the p5.js editor](https://editor.p5js.org/sciencenibber/sketches/xTHeUaxph) - **Pattern:** **H** -- function-over-domain (engineering stress plotted against strain) driven alongside a deforming-specimen glyph - **Canvas:** 720 x 520, `pixelDensity(2)`; vanilla p5, no external libraries **Description (what it shows).** A round specimen is gripped between a fixed crosshead and a moving one. As the **applied-strain** slider advances (or you drag the operating point on the chart), the bar stretches, a dashed ghost marks its original gauge length, and a dimension line reports the current strain. The **stress-strain chart** plots the full virgin curve faintly, traces the path actually travelled in bold, and marks the **yield**, **ultimate** (UTS), and **fracture** landmarks; the initial slope is tagged `slope = E`. Past the yield point the bar turns from elastic **blue** to plastic **amber**; into necking it goes **red** and visibly pinches at the waist; at fracture it breaks into two grey halves. Pull back after yielding and a dashed **elastic unload line** of slope `E` peels off the curve down to the **permanent set** `eps_p`, which is also drawn as a marker on the specimen. A read-out panel reports the material's `E`, `sigma_y`, `sigma_u`, the current regime, the live `sigma`, `eps`, and the locked-in `eps_plastic`. A **material** selector switches between mild steel, aluminium 6061-T6, and annealed copper, and **reset** restores every control and the loading history. ```js // ===================================================================== // Article : Solid mechanics // Slug : Solid_mechanics // Wikitube : en.wikitube.io/wiki/Solid_mechanics // Category : SPINTRONICS / Statics (mechatronics & electronics hub) // Idea : Solid mechanics studies how a deformable solid responds to // load. The whole field hangs off ONE experiment -- pull a // bar and plot STRESS (sigma = F/A0) against STRAIN // (eps = dL/L0). The resulting curve has four acts: // (1) ELASTIC -- straight line, sigma = E*eps (Hooke), // fully recoverable; slope = E. // (2) YIELD -- the line bends over at sigma_y; the // solid starts to flow. // (3) PLASTIC -- strain hardening up to the ultimate // tensile strength sigma_u. // (4) NECKING -- engineering stress falls as the bar // thins locally, ending in FRACTURE. // Equation : sigma = E * eps (Hooke's law, elastic) // eps_plastic = eps_max - sigma_peak / E (permanent set) // Pattern : H -- function-over-domain (the stress-strain curve) driven // alongside a deforming-specimen glyph. // // THE LESSON THIS SIM IS BUILT TO TEACH (the "aha"): // Pull the bar (strain slider, or drag on the chart) and watch the // operating point climb the stress-strain curve while the specimen // stretches. Stay below yield and let go: the bar springs ALL the way // back -- elastic, reversible. Pull PAST yield and let go: the bar // unloads along a line of slope E and stops short of where it started // -- a PERMANENT SET is locked in (eps_plastic). Keep pulling and the // bar necks and breaks at fracture. Switch material (steel / aluminium // / copper) and the same four acts replay with a different modulus, // yield, strength, and ductility. That single curve IS solid // mechanics -- the constitutive law of a deformable solid, turned into // an instrument you play. // // Input-driven: noLoop() + redraw(); there is no animation loop at all, // so the editor loop-protect cannot trip. Every redraw is a slider / // drag / select / button event. // ===================================================================== const ARTICLE = "Solid_mechanics"; p5.disableFriendlyErrors = true; // ---- palette (Statics room: light schematic drafting sheet) --------- const BG = 248; // paper-white background const GRIDC = [226, 229, 234]; // faint construction grid const INKD = [40, 48, 62]; // dark ink: titles, axes const INKL = [120, 128, 140]; // light annotation ink const GRIP = [96, 104, 120]; // testing-machine grips const ELASC = [62, 132, 214]; // elastic regime (blue) const PLASC = [225, 150, 35]; // plastic regime (amber) const NECKC = [210, 70, 35]; // necking regime (red) const BREAKC = [150, 158, 170]; // fractured (gray) const CURVEC = [54, 64, 84]; // the stress-strain curve (slate) const GHOSTC = [176, 183, 193]; // original-length ghost const PERMC = [150, 92, 196]; // permanent-set marker (purple) // ---- canvas / layout (every constant derived from width & height) --- const CW = 720, CH = 520; let SPX, SPY; // specimen: left grip inner face (x), axis y let BARPX; // unstrained bar length in pixels let PX0, PX1, PY0, PY1; // stress-strain plot box let RX, RY, RW, RH; // results read-out panel let CTRLY; // first control row (y) // ---- materials (engineering stress-strain; SI: E in GPa, sigma in MPa) const MATS = [ { name: "Mild steel", E: 200, sigY: 250, sigU: 400, eU: 0.16, eF: 0.25, sigF: 300 }, { name: "Aluminium 6061-T6", E: 69, sigY: 276, sigU: 310, eU: 0.09, eF: 0.13, sigF: 295 }, { name: "Copper (annealed)", E: 117, sigY: 70, sigU: 220, eU: 0.34, eF: 0.45, sigF: 175 } ]; // ---- controls ------------------------------------------------------- let pullSld; // applied draw fraction 0..1 -> strain 0..eF let matSel; // material selector let resetBtn; // ---- live state (recomputed once per redraw; no per-frame allocation) let mi = 0; // material index let epsMax = 0; // largest strain ever applied this episode let broken = false; // fractured? let epsCur = 0, epsEff = 0; // commanded strain / effective (>= perm set) let sigma = 0; // current engineering stress (MPa) let epsPlast = 0; // locked-in permanent strain let loading = true; // on the virgin curve vs unloading let regime = "elastic"; // text label for the current act function setup() { createCanvas(CW, CH); pixelDensity(2); describe( "Solid-mechanics tension test. A specimen bar is pulled while the " + "stress-strain curve is traced live. Below the yield point the " + "response is elastic and fully recoverable (sigma = E*eps); past " + "yield the bar deforms plastically, hardens to its ultimate strength, " + "necks, and fractures. Unloading after yield follows a line of slope " + "E and leaves a permanent set. A slider sets the applied strain, a " + "selector switches material, and the operating point can be dragged " + "along the chart."); // layout derived from canvas size (never hard-coded coordinates) SPX = width * 0.255; // left grip inner face SPY = height * 0.255; // specimen axis (~133) BARPX = width * 0.205; // unstrained gauge length in px (~148) PX0 = width * 0.115; PX1 = width * 0.600; // plot box x PY0 = height * 0.405; PY1 = height * 0.695; // plot box y RX = width * 0.630; RY = PY0; RW = width - RX - 14; RH = PY1 - RY; CTRLY = height * 0.760; // first control row (~395) // --- controls (below the diagrams) ---------------------------------- const colx = 168, sw = 168; let y = CTRLY; pullSld = createSlider(0, 1, 0, 0.0005); pullSld.position(colx, y); pullSld.size(sw); y += 30; matSel = createSelect(); matSel.position(colx, y); matSel.size(sw + 6); y += 30; for (let i = 0; i < MATS.length; i++) matSel.option(MATS[i].name); matSel.selected(MATS[0].name); resetBtn = createButton("reset"); resetBtn.position(20, y); resetBtn.mousePressed(doReset); pullSld.input(redraw); matSel.changed(onMaterial); noLoop(); } // ===================================================================== // COMPUTE -- read controls once, walk the constitutive model. // ===================================================================== function compute() { const m = MATS[mi]; const Em = m.E * 1000; // Young's modulus in MPa const eY = m.sigY / Em; // yield strain epsCur = min(pullSld.value() * m.eF, m.eF); // advance the running peak while loading; fracture at eF if (!broken && epsCur >= epsMax) epsMax = min(epsCur, m.eF); if (!broken && epsMax >= m.eF - 1e-9) broken = true; // permanent set is set by how far we have ever stretched const sPeak = envelope(epsMax, m); epsPlast = max(0, epsMax - sPeak / Em); // you cannot shorten below the permanent set without compressing epsEff = max(epsCur, epsPlast); loading = epsEff >= epsMax - 1e-12; if (broken) { sigma = 0; } else if (loading) { sigma = envelope(epsEff, m); } else { sigma = Em * (epsEff - epsPlast); // elastic unload / reload line } // name the current act if (broken) { regime = "fractured"; } else if (!loading) { regime = "elastic unloading"; } else if (epsEff <= eY + 1e-9) { regime = "elastic (recoverable)"; } else if (epsEff <= m.eU) { regime = "plastic (strain hardening)"; } else { regime = "necking"; } } // virgin loading curve: engineering stress (MPa) for monotonic strain e function envelope(e, m) { const Em = m.E * 1000; const eY = m.sigY / Em; if (e <= 0) return 0; if (e <= eY) return Em * e; // elastic (Hooke) if (e <= m.eU) { // strain hardening const t = (e - eY) / (m.eU - eY); return m.sigY + (m.sigU - m.sigY) * (1 - (1 - t) * (1 - t)); } if (e <= m.eF) { // necking -> fracture const t = (e - m.eU) / (m.eF - m.eU); return m.sigU - (m.sigU - m.sigF) * pow(t, 1.5); } return m.sigF; } // chart mappings (strain -> px, stress -> px) function cx(e) { return map(e, 0, axisEps(), PX0, PX1); } function cy(s) { return map(s, 0, axisSig(), PY1, PY0); } function axisEps() { return MATS[mi].eF * 1.04; } function axisSig() { return MATS[mi].sigU * 1.20; } // ===================================================================== // DRAW // ===================================================================== function draw() { compute(); background(BG); drawGrid(); drawSpecimen(); // the deforming bar between the grips drawChart(); // the stress-strain curve + operating point drawReadout(); // numeric panel (E, sigma, eps, permanent set) drawBanner(); // one-line takeaway drawHUD(); // 4-part watermark, drawn last } // --------------------------------------------------------------------- // regime colour for the current operating point. // --------------------------------------------------------------------- function regimeColor() { const m = MATS[mi]; const eY = m.sigY / (m.E * 1000); if (broken) return BREAKC; if (epsEff <= eY + 1e-9) return ELASC; if (epsEff <= m.eU) return PLASC; return NECKC; } // --------------------------------------------------------------------- // Panel 1: the specimen bar (signature visual move -- it stretches, // necks, and breaks; a ghost shows the original gauge length). // --------------------------------------------------------------------- function drawSpecimen() { const m = MATS[mi]; const col = regimeColor(); const barH = 26; const necking = !broken && epsEff > m.eU; // ghost of the original (unstrained) gauge length push(); stroke(GHOSTC[0], GHOSTC[1], GHOSTC[2]); strokeWeight(1.2); drawingContext.setLineDash([4, 4]); noFill(); rect(SPX, SPY - barH / 2, BARPX, barH, 3); drawingContext.setLineDash([]); pop(); // grips: fixed crosshead on the left, moving crosshead on the right const xEnd = SPX + BARPX * (1 + epsEff); // current right inner face drawGrip(SPX, true, barH); drawGrip(xEnd, false, barH); if (broken) { drawFracturedBar(SPX, xEnd, barH); } else { drawIntactBar(SPX, xEnd, barH, col, necking, m); } // dimension line + strain read-out under the bar const dy = SPY + barH / 2 + 16; push(); stroke(INKL[0], INKL[1], INKL[2]); strokeWeight(1); line(SPX, dy, xEnd, dy); line(SPX, dy - 4, SPX, dy + 4); line(xEnd, dy - 4, xEnd, dy + 4); noStroke(); fill(INKD[0], INKD[1], INKD[2]); textSize(11); textAlign(CENTER, TOP); text("eps = " + nf(epsEff * 100, 0, 2) + " % (L = L0 * " + nf(1 + epsEff, 0, 3) + ")", (SPX + xEnd) / 2, dy + 4); pop(); // permanent-set marker: where the bar settles to once fully unloaded if (epsPlast > 1e-4 && !broken) { const xp = SPX + BARPX * (1 + epsPlast); push(); stroke(PERMC[0], PERMC[1], PERMC[2]); strokeWeight(1.4); drawingContext.setLineDash([3, 3]); line(xp, SPY - barH / 2 - 10, xp, SPY + barH / 2 + 6); drawingContext.setLineDash([]); noStroke(); fill(PERMC[0], PERMC[1], PERMC[2]); textSize(10); textAlign(CENTER, BOTTOM); text("permanent set", xp, SPY - barH / 2 - 11); pop(); } } function drawIntactBar(x0, x1, barH, col, necking, m) { const len = x1 - x0; push(); noStroke(); // Poisson-ish lateral contraction; extra local pinch once necking starts const baseW = barH * (1 - 0.18 * constrain(epsEff, 0, 0.45)); const neckFrac = necking ? constrain((epsEff - m.eU) / (m.eF - m.eU), 0, 1) : 0; drawingContext.shadowColor = "rgba(" + col[0] + "," + col[1] + "," + col[2] + ",0.30)"; drawingContext.shadowBlur = 8; fill(col[0], col[1], col[2]); beginShape(); const N = 40; for (let i = 0; i <= N; i++) { // top edge const s = i / N; const w = baseW * (1 - neckFrac * 0.62 * exp(-pow((s - 0.5) * 5.2, 2))); vertex(x0 + s * len, SPY - w / 2); } for (let i = N; i >= 0; i--) { // bottom edge const s = i / N; const w = baseW * (1 - neckFrac * 0.62 * exp(-pow((s - 0.5) * 5.2, 2))); vertex(x0 + s * len, SPY + w / 2); } endShape(CLOSE); drawingContext.shadowBlur = 0; pop(); } function drawFracturedBar(x0, x1, barH) { const m = MATS[mi]; const baseW = barH * 0.78; const gap = 16; const mid = (x0 + x1) / 2; push(); noStroke(); fill(BREAKC[0], BREAKC[1], BREAKC[2]); // left half, tapering to a jagged break face beginShape(); vertex(x0, SPY - baseW / 2); vertex(mid - gap, SPY - baseW * 0.16); vertex(mid - gap + 4, SPY); vertex(mid - gap, SPY + baseW * 0.16); vertex(x0, SPY + baseW / 2); endShape(CLOSE); // right half beginShape(); vertex(x1, SPY - baseW / 2); vertex(mid + gap, SPY - baseW * 0.16); vertex(mid + gap - 4, SPY); vertex(mid + gap, SPY + baseW * 0.16); vertex(x1, SPY + baseW / 2); endShape(CLOSE); fill(NECKC[0], NECKC[1], NECKC[2]); textSize(12); textStyle(BOLD); textAlign(CENTER, BOTTOM); text("FRACTURE", mid, SPY - baseW); textStyle(NORMAL); pop(); } function drawGrip(x, leftSide, barH) { const gw = 16, gh = barH + 22; push(); noStroke(); fill(GRIP[0], GRIP[1], GRIP[2]); const gx = leftSide ? x - gw : x; rect(gx, SPY - gh / 2, gw, gh, 2); stroke(255, 255, 255, 90); strokeWeight(1); // knurling for (let yy = SPY - gh / 2 + 4; yy < SPY + gh / 2 - 2; yy += 4) line(gx + 2, yy, gx + gw - 2, yy); pop(); } // --------------------------------------------------------------------- // Panel 2: the stress-strain curve -- the heart of the sim. // --------------------------------------------------------------------- function drawChart() { const m = MATS[mi]; const Em = m.E * 1000; const eY = m.sigY / Em; // plot frame + axes push(); noStroke(); fill(255); rect(PX0 - 4, PY0 - 6, (PX1 - PX0) + 8, (PY1 - PY0) + 12, 6); stroke(GRIDC[0], GRIDC[1], GRIDC[2]); strokeWeight(1); noFill(); rect(PX0 - 4, PY0 - 6, (PX1 - PX0) + 8, (PY1 - PY0) + 12, 6); stroke(190); strokeWeight(1.2); line(PX0, PY1, PX1, PY1); // x axis (strain) line(PX0, PY1, PX0, PY0); // y axis (stress) pop(); // faint full virgin envelope across the whole strain range push(); stroke(GHOSTC[0], GHOSTC[1], GHOSTC[2]); strokeWeight(1.4); noFill(); beginShape(); const N = 200; for (let i = 0; i <= N; i++) { const e = (i / N) * m.eF; vertex(cx(e), cy(envelope(e, m))); } endShape(); pop(); // the path actually traversed (0 -> epsMax), drawn bold push(); drawingContext.shadowColor = "rgba(54,64,84,0.25)"; drawingContext.shadowBlur = 6; stroke(CURVEC[0], CURVEC[1], CURVEC[2]); strokeWeight(2.6); noFill(); beginShape(); const M = 160; for (let i = 0; i <= M; i++) { const e = (i / M) * epsMax; vertex(cx(e), cy(envelope(e, m))); } endShape(); drawingContext.shadowBlur = 0; pop(); // elastic unload / reload line (slope E) when not on the virgin curve if (!loading && !broken && epsMax > eY) { push(); stroke(ELASC[0], ELASC[1], ELASC[2]); strokeWeight(1.8); drawingContext.setLineDash([5, 4]); line(cx(epsPlast), cy(0), cx(epsMax), cy(envelope(epsMax, m))); drawingContext.setLineDash([]); noStroke(); fill(PERMC[0], PERMC[1], PERMC[2]); textSize(10); textAlign(CENTER, TOP); text("eps_p", cx(epsPlast), cy(0) + 4); pop(); } // key landmarks: yield, ultimate, fracture markPoint(cx(eY), cy(m.sigY), ELASC, "yield " + m.sigY, RIGHT); markPoint(cx(m.eU), cy(m.sigU), PLASC, "UTS " + m.sigU, CENTER); drawFractureMark(cx(m.eF), cy(m.sigF)); // initial-slope tag (slope = E) push(); stroke(INKL[0], INKL[1], INKL[2]); strokeWeight(1); const e1 = eY * 0.85; line(cx(0), cy(0), cx(e1), cy(Em * e1)); noStroke(); fill(INKL[0], INKL[1], INKL[2]); textSize(9.5); textAlign(LEFT, BOTTOM); text("slope = E", cx(e1) + 3, cy(Em * e1) - 1); pop(); // operating point const opC = regimeColor(); push(); drawingContext.shadowColor = "rgba(" + opC[0] + "," + opC[1] + "," + opC[2] + ",0.55)"; drawingContext.shadowBlur = 10; stroke(255); strokeWeight(2); fill(opC[0], opC[1], opC[2]); circle(cx(epsEff), cy(sigma), 11); drawingContext.shadowBlur = 0; pop(); // axis labels + a couple of ticks push(); noStroke(); fill(INKD[0], INKD[1], INKD[2]); textSize(11); textAlign(CENTER, TOP); text("strain eps", (PX0 + PX1) / 2, PY1 + 6); textAlign(RIGHT, CENTER); push(); translate(PX0 - 30, (PY0 + PY1) / 2); rotate(-HALF_PI); textAlign(CENTER, BOTTOM); text("stress sigma [MPa]", 0, 0); pop(); fill(INKL[0], INKL[1], INKL[2]); textSize(9.5); textAlign(RIGHT, CENTER); text(nf(axisSig(), 0, 0), PX0 - 6, cy(axisSig()) + 4); text("0", PX0 - 6, cy(0)); textAlign(CENTER, TOP); text(nf(axisEps() * 100, 0, 0) + "%", cx(axisEps()), PY1 + 6); pop(); } function markPoint(px, py, col, label, ha) { push(); noStroke(); fill(col[0], col[1], col[2]); circle(px, py, 6); textSize(9.5); textStyle(BOLD); fill(col[0], col[1], col[2]); if (ha === RIGHT) { textAlign(LEFT, CENTER); text(label, px + 7, py - 7); } else { textAlign(CENTER, BOTTOM); text(label, px, py - 6); } textStyle(NORMAL); pop(); } function drawFractureMark(px, py) { push(); stroke(NECKC[0], NECKC[1], NECKC[2]); strokeWeight(2); line(px - 5, py - 5, px + 5, py + 5); line(px - 5, py + 5, px + 5, py - 5); noStroke(); fill(NECKC[0], NECKC[1], NECKC[2]); textSize(9.5); textStyle(BOLD); textAlign(CENTER, TOP); text("fracture", px, py + 6); textStyle(NORMAL); pop(); } // --------------------------------------------------------------------- // Panel 3: numeric read-out (right of the chart). // --------------------------------------------------------------------- function drawReadout() { const m = MATS[mi]; push(); noStroke(); fill(255); rect(RX, RY - 6, RW, RH + 12, 8); stroke(GRIDC[0], GRIDC[1], GRIDC[2]); strokeWeight(1); noFill(); rect(RX, RY - 6, RW, RH + 12, 8); pop(); const px = RX + 12; let y = RY + 4; noStroke(); textAlign(LEFT, TOP); fill(INKD[0], INKD[1], INKD[2]); textSize(12); textStyle(BOLD); text(m.name, px, y); textStyle(NORMAL); y += 18; fill(90); textSize(10.5); text("E = " + m.E + " GPa", px, y); y += 14; text("sigma_y = " + m.sigY + " MPa", px, y); y += 14; text("sigma_u = " + m.sigU + " MPa", px, y); y += 18; const opC = regimeColor(); fill(opC[0], opC[1], opC[2]); textStyle(BOLD); textSize(11); text(regime, px, y); textStyle(NORMAL); y += 17; fill(CURVEC[0], CURVEC[1], CURVEC[2]); textSize(11); text("sigma = " + nf(sigma, 0, 1) + " MPa", px, y); y += 15; text("eps = " + nf(epsEff * 100, 0, 2) + " %", px, y); y += 15; fill(PERMC[0], PERMC[1], PERMC[2]); text("eps_plastic = " + nf(epsPlast * 100, 0, 2) + " %", px, y); y += 17; fill(INKL[0], INKL[1], INKL[2]); textSize(9.5); if (broken) { text("specimen has fractured;", px, y); y += 12; text("press reset to test again", px, y); } else if (epsPlast > 1e-4) { text("release now -> bar keeps", px, y); y += 12; text(nf(epsPlast * 100, 0, 2) + "% of its stretch", px, y); } else { text("below yield: fully", px, y); y += 12; text("recoverable (springs back)", px, y); } } // --------------------------------------------------------------------- // Top banner (one-line takeaway). // --------------------------------------------------------------------- function drawBanner() { push(); textAlign(LEFT, TOP); textSize(12); textStyle(BOLD); noStroke(); fill(INKD[0], INKD[1], INKD[2]); text("Below yield a solid springs back; past yield, part of the stretch is locked in for good.", 14, 58); textStyle(NORMAL); pop(); } // --------------------------------------------------------------------- // 4-part self-identifying HUD watermark (drawn last). // --------------------------------------------------------------------- function drawHUD() { noStroke(); // (1) title block (top-left) textAlign(LEFT, TOP); fill(20); textSize(20); textStyle(BOLD); text("Solid mechanics", 14, 12); textStyle(NORMAL); fill(110); textSize(12); text("Wikitube microsim - en.wikitube.io/wiki/" + ARTICLE, 14, 38); // (2) control labels beside the inputs textAlign(LEFT, CENTER); fill(70); textSize(11); text("applied strain (pull)", 20, CTRLY + 11); text("material", 20, CTRLY + 41); // (3) control hint (bottom-left) textAlign(LEFT, BOTTOM); textSize(11); fill(95); text("pull the strain slider (or drag on the chart); past yield, pull back to see the permanent set; reset restores all", 14, height - 8); // (4) bottom-right equation footer (ASCII only) textAlign(RIGHT, BOTTOM); fill(80); textSize(11); text("sigma = E*eps (elastic) | eps_p = eps_max - sigma_peak/E", width - 12, height - 8); } // --------------------------------------------------------------------- // Faint construction grid (reference layer, under everything). // --------------------------------------------------------------------- function drawGrid() { stroke(GRIDC[0], GRIDC[1], GRIDC[2]); strokeWeight(1); for (let x = 0; x <= width; x += 36) line(x, 0, x, height); for (let y = 0; y <= height; y += 36) line(0, y, width, y); } // --------------------------------------------------------------------- // Interaction: drag inside the chart to command the strain. // --------------------------------------------------------------------- function inPlot() { return mouseX >= PX0 - 4 && mouseX <= PX1 + 4 && mouseY >= PY0 - 6 && mouseY <= PY1 + 8; } function setFromMouse() { const e = constrain(map(mouseX, PX0, PX1, 0, axisEps()), 0, MATS[mi].eF); pullSld.value(constrain(e / MATS[mi].eF, 0, 1)); redraw(); } function mousePressed() { if (inPlot()) setFromMouse(); } function mouseDragged() { if (inPlot()) setFromMouse(); } // --------------------------------------------------------------------- // Material change: reset the loading history for the new specimen. // --------------------------------------------------------------------- function onMaterial() { const want = matSel.selected(); for (let i = 0; i < MATS.length; i++) if (MATS[i].name === want) mi = i; epsMax = 0; broken = false; pullSld.value(0); redraw(); } // --------------------------------------------------------------------- // reset restores ALL state (strain, history, fracture flag). // --------------------------------------------------------------------- function doReset() { pullSld.value(0); epsMax = 0; broken = false; redraw(); } ``` ## Microsim log | Date | Version | Editor URL | Change summary | |------|---------|------------|----------------| | 2026-06-22 | v1 | [open](https://editor.p5js.org/sciencenibber/sketches/xTHeUaxph) | Initial Microsim Worklist build. Pattern H function-over-domain: a uniaxial tension test that traces engineering stress against strain through the elastic (Hooke) region, the yield point, plastic strain-hardening to the ultimate tensile strength, necking, and fracture, with an elastic unload line that exposes the permanent set, plus a material selector (mild steel / aluminium 6061-T6 / annealed copper). Verified before publish: pure ASCII, `node --check` clean, p5 reserved-name lint (only the required `setup`/`draw`/mouse lifecycle hooks), and a standalone constitutive-model test confirming Hooke linearity, `sigma_y`/`sigma_u`/`sigma_f` continuity, monotonic hardening then necking, full sub-yield recovery, and the `eps_p = eps_max - sigma_peak/E` permanent-set relation across all three materials. Published byte-perfect (in-editor doc SHA-256 == disk SHA-256), FES-clean console with auto-refresh on, input-driven `noLoop()`+`redraw()`. Saved via the File > Save menu item (JS click) after CDP `cmd+s` did not commit -- see `Security_Tripwires.md` (2026-06-22). | ## Links (Wikipedia order) <!-- injected from _registry/childlinks/Solid_mechanics.json (2026-07-30T02:09:12Z) --> `Acoustics` · `Adhesion` · `Adolf_Eugen_Fick` · [[Aerospace_engineering]] · `Alexander_Hrennikoff` · `Analytical_mechanics` · `Anatomy` · `Applied_mechanics` · `Applied_physics` · `Archimedes'_principle` · `Astrophysics` · `Atmosphere` · `Atmospheric_physics` · `Atomic,_molecular,_and_optical_physics` · `Atomic_physics` · `Augustin-Louis_Cauchy` · `Basic_research` · `Bending` · `Bernoulli's_principle` · `Biomechanics` · [[Biomedical_engineering]] · `Biophysics` · `Biotic_material` · `Blaise_Pascal` · `Boyle's_law` · `Branches_of_physics` · `Buckling` · `Buoyancy` · `Capillary_action` · `Carlo_Alberto_Castigliano` · `Castigliano's_method` · `Celestial_mechanics` · [[Chaos_theory]] · `Charles's_law` · `Chemical_physics` · [[Chemistry]] · `Chromatography` · [[Civil_engineering]] · `Classical_electromagnetism` · `Classical_mechanics` · `Classical_physics` · `Claude-Louis_Navier` · `Clausius–Duhem_inequality` · `Clifford_Truesdell` · `Cohesion_(chemistry)` · `Compatibility_(mechanics)` · `Composite_material` · `Computational_mechanics` · `Computational_physics` · `Condensed_matter_physics` · `Conservation_of_energy` · `Conservation_of_mass` · `Contact_mechanics` · `Continuum_mechanics` · `Course_of_Theoretical_Physics` · `Crystallography` · `Damage_mechanics` · `Daniel_Bernoulli` · `Deformation_(physics)` · [[Dynamical_systems_theory]] · `Elasticity_(physics)` · `Electrorheological_fluid` · [[Engineering_physics]] · `Euler–Bernoulli_beam_theory` · `Experimental_physics` · `Ferrofluid` · `Fibre-reinforced_plastic` · `Fick's_laws_of_diffusion` · `Finite_element_method` · `Finite_strain_theory` · `Fluid` · [[Fluid_dynamics]] · `Fluid_mechanics` · [[Force]] · [[Fracture_mechanics]] · `Friction` · `Frictional_contact_mechanics` · `Galileo_Galilei` · `Gas` · `Gay-Lussac's_law` · `Gel` · `General_relativity` · `Geology` · `Geometrical_optics` · `Geophysics` · `Graham's_law` · `Hagen–Poiseuille_equation` · `History_of_physics` · `Hooke's_law` · `Hydrostatics` · `Impact_(mechanics)` · `Infinitesimal_strain_theory` · [[Isaac_Newton]] · `Jacques_Charles` · `Joseph_Louis_Gay-Lussac` · `Leonardo_da_Vinci` · `Leonhard_Euler` · `Linear_elasticity` · `Liquid` · `Magnetohydrodynamics` · `Magnetorheological_fluid` · `Material_failure_theory` · [[Materials_science]] · `Mathematical_physics` · [[Mechanical_engineering]] · `Mechanical_equilibrium` · `Medical_physics` · `Mixing_(process_engineering)` · `Modern_physics` · `Molecular_physics` · `Mud` · `Navier–Stokes_equations` · [[Newton's_laws_of_motion]] · `Newtonian_fluid` · `Nobel_Prize_in_Physics` · `Non-Newtonian_fluid` · `Non-equilibrium_thermodynamics` · `Normal_force` · [[Nuclear_engineering]] · `Nuclear_physics` · `Optics` · `Outline_of_astrophysics` · `Particle_physics` · `Pascal's_law` · `Philosophy_of_physics` · `Physical_oceanography` · `Physical_optics` · [[Physics]] · `Physics_education` · `Physics_education_research` · [[Plasma_(physics)]] · `Plasticity_(physics)` · `Quantum_information_science` · [[Quantum_mechanics]] · `Reinforced_concrete` · `Relativistic_mechanics` · `Rheology` · `Rheometer` · `Rheometry` · `Richard_Courant` · `Rigid_body` · `Robert_Boyle` · `Robert_Hooke` · `Shear_force` · `Sir_George_Stokes,_1st_Baronet` · `Smart_fluid` · `Solid` · `Solid-state_physics` · `Special_relativity` · `Statistical_mechanics` · `Stephen_Timoshenko` · `Strain_(mechanics)` · [[Strength_of_materials]] · `Stress_(mechanics)` · `Structural_mechanics` · `Surface_tension` · `Temperature` · [[Tensor]] · `Theoretical_physics` · [[Thermodynamics]] · `Thomas_Graham_(chemist)` · `Timeline_of_fundamental_physics_discoveries` · `Two_New_Sciences` · `Vibration` · `Virtual_work` · `Viscoelasticity` · `Viscoplasticity` · [[Viscosity]] · `Walter_Noll` ## From the Real GENERATIVE library ![Solid mechanics](https://upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Galileo_Galilei_by_Ottavio_Leoni_Marucelliana_%28cropped%29.jpg/170px-Galileo_Galilei_by_Ottavio_Leoni_Marucelliana_%28cropped%29.jpg) *Solid mechanics — placed from the Real G.E.N.E.R.A.T.I.V.E. course library (STEM and Music room). Source: Wikimedia Commons (via Wikipedia article media). [Details & license](https://commons.wikimedia.org/wiki/File:Galileo_Galilei_by_Ottavio_Leoni_Marucelliana_%28cropped%29.jpg).* > Solid mechanics (also known as mechanics of solids) is the branch of continuum mechanics that studies the behavior of solid materials, especially their motion and deformation under the action of forces, temperature changes, phase changes, and other external or internal agents. ([Wikipedia](https://en.wikipedia.org/wiki/Solid_mechanics)) <!-- REAL-GENERATIVE-MEDIA:END --> <- Back to Spintronics · Branch: **S -- Statics** · Standard: MicroSim Best Practices > **Solid mechanics** is the branch of continuum mechanics that studies how solid, deformable bodies respond to load: how internal forces distribute as **stress**, how the body changes shape as **strain**, and whether that change is **recoverable** (elastic) or **permanent** (plastic), all the way to failure. It is the [[Science|science]] beneath strength of materials and structural engineering -- where statics stops the moment a body is allowed to deform, solid mechanics begins. ## Overview The whole field hangs off one experiment. Take a bar of original cross-section `A0` and gauge length `L0`, pull it with a force `F`, and record two numbers: the **[[Engineering|engineering]] stress** `sigma = F / A0` and the **engineering strain** `eps = dL / L0`. Plotting one against the other gives the **stress-strain curve**, the single most informative diagram in materials engineering, and it always tells the same four-act story. First an **elastic** region, a straight line whose slope is **Young's modulus** `E` -- here `sigma = E * eps` (Hooke's law) and every bit of stretch is recovered when the load is removed. Then a **yield point** `sigma_y`, where the line bends over and the material begins to flow. Then a **plastic** region of **strain hardening** that climbs to the **ultimate tensile strength** `sigma_u`. Finally **necking**, where the bar thins locally and the engineering stress falls until the specimen **fractures**. The conceptual heart of solid mechanics is the split between **elastic** and **plastic** behaviour, and the cleanest way to feel it is to load a bar and then let go. Unload from **below** the yield point and the operating point slides straight back down the elastic line to the origin: no harm done, fully reversible. Unload from **above** yield and the material relaxes along a line of the *same slope* `E`, but it stops short of the origin -- it has acquired a **permanent set** `eps_plastic = eps_max - sigma_peak / E`. That residual strain is the metal "remembering" the largest load it ever felt; reload it and you climb the elastic line back to the old peak before the curve yields again. This stress-strain relation is the material's **constitutive law**, and `E`, `sigma_y`, `sigma_u`, and the strain at fracture (its **ductility**) are the handful of numbers that characterise it -- which is why a stiff, modest-ductility [[Steel|steel]], a lower-modulus aluminium, and a soft, very ductile annealed [[Copper|copper]] each trace a recognisably different curve. This MicroSim turns the tension test into an instrument. Pull the **applied-strain** slider (or drag the operating point along the chart) and watch the specimen stretch while the curve is traced live; cross the yield point and pull **back** to see the elastic unload line peel off and leave a visible permanent set in the bar; keep pulling and the bar **necks** and **fractures**. A material selector swaps in mild steel, aluminium 6061-T6, or annealed copper, replaying the same four acts with a different modulus, yield, strength, and ductility, and **reset** restores the whole experiment. ## See also - Hub: Spintronics · Branch: **S -- Statics** - Related statics sims: [[Structural_engineering]] · [[Physical_system]] · [[Strength_of_materials]] · Cremona diagram · [[Force]] · Mechanical equilibrium - Standard: MicroSim Best Practices · editor workflow: P5 JS EDITOR - Index: MAIN _Poster image deferred to attended backfill: `SPINTRONICS_Statics_Images/Solid_mechanics.png` (headless runs cannot capture the canvas)._ Letters: flow · force · mined_science · circuit_symbols_iec · distribution · equilibrium · kanji_radicals · mined_electron See also (bridge flow x kanji_radicals): Electrical element See also (bridge flow x mined_science): Applied science <!-- REAL-GENERATIVE-MEDIA:START --> <!-- CRAFT-LINK:START g12 --> *Built to the [[WT!P5_js_Microsim_Master_Class|p5.js Master Class]].* <!-- CRAFT-LINK:END --> ## Wikipedia : Wikitube **Strict pair:** [Wikipedia](https://en.wikipedia.org/wiki/Solid_mechanics) : [Wikitube](https://en.wikitube.io/wiki/Solid_mechanics) ## Previous hub tags Tree parent: [[Reliability_engineering]]. Legacy hubs: `SPINTRONICS`. --- *Sources: 1 legacy note. Minted wave 1, 2026-07-30 (v1.6 order).*