# Diffusion
## Microsim
### Live player
<div class="microsim-player">
<iframe src="https://editor.p5js.org/sciencenibber/full/ZoDIpgATd" width="100%" height="620" frameborder="0" sandbox="allow-scripts allow-same-origin"></iframe>
</div>
<div class="microsim-fallback">
<img src="Microsims/thumbs/Diffusion.png" alt="Diffusion microsim poster" style="width:100%;border:1px solid #4445;border-radius:6px;">
<p><em>Live microsim (desktop) · <a href="https://editor.p5js.org/sciencenibber/sketches/ZoDIpgATd">open sketch in the p5.js editor</a></em></p>
</div>
**Editor URL:** https://editor.p5js.org/sciencenibber/sketches/ZoDIpgATd
**Description (100 words):**
A swarm of point particles starts clustered at the centre of a square box and undergoes a 2D random walk, where each frame every particle takes a Gaussian step of variance 2 D dt. The cloud spreads outward in real time as a 2D Gaussian, and the right-hand scope plots the swarm's mean-squared displacement versus time in yellow against the Einstein prediction <r^2> = 4 D t in magenta — the two lines should overlap exactly. Three sliders set bath temperature, viscosity, and particle count, with D recomputed through the Stokes-Einstein relation D = k_B T / (6 pi eta r). Six yellow tracer trails show individual random walks behind the swarm.
```js
// =====================================================================
// Diffusion.js -- Wikitube microsim
// Article: Diffusion en.wikitube.io/wiki/Diffusion
// Room: Helium Pattern: E (particles / random walk)
// ---------------------------------------------------------------------
// Idea: an interactive 2D random walk that visualises Fick's diffusion
// law from the bottom up. A swarm of point particles starts clustered
// at the centre of a square box. Each frame, every particle takes a
// Gaussian-distributed step whose variance encodes the diffusion
// coefficient D. Two things grow with time:
//
// * the visible cloud, spreading outward as a 2D Gaussian
// * the mean-squared-displacement (MSD) scope on the right
//
// The straight line on the MSD scope -- <r^2> = 4 D t in two
// dimensions -- is Einstein's 1905 result, recovered from a purely
// microscopic random walk in front of the reader. The animated cloud
// IS the solution of Fick's second law for a delta-function initial
// condition:
//
// d-phi/dt = D del^2 phi -> phi(r, t) = exp(-r^2 / 4 D t) / (4 pi D t)
//
// Two sliders drive the physics through the Stokes-Einstein relation
//
// D = k_B T / (6 pi eta r_p)
//
// letting the reader feel why a hot, low-viscosity bath spreads
// particles faster than a cold, treacly one. A third slider sets the
// particle count; a reset button re-clusters everyone at the origin
// and clears the MSD history.
//
// Helium connection
// -----------------
// Helium has the highest gaseous diffusion coefficient of any common
// species in air (~6.3 * 10^-5 m^2/s at STP) because of its tiny
// monatomic mass. That single fact powers helium leak detection -- a
// mass-spec sniffer can find a 10^-9 atm-cc/s leak through a weld in
// seconds, faster than any other tracer. Graham's law of effusion
// (rate proportional to 1/sqrt(M)) is the macroscopic shadow of the
// microscopic random walk this microsim animates.
//
// Visual layout (720 x 520 canvas)
// --------------------------------
// * top-left: HUD title + en.wikitube.io/wiki/Diffusion subtitle
// * top-right: control hints
// * left panel: particle box, drawn as a bordered square. Each
// particle is a small dot in the COLD palette,
// with a small subset of "trace" particles drawn
// with their full history (yellow trails).
// * right panel: MSD scope -- live <r^2> versus t, with the
// theoretical line <r^2> = 4 D t overplotted in
// the magenta accent.
// * bottom-left: live readouts (D, N, t, <r^2>)
// * bottom-right: canonical equation
// * bottom row: three sliders (T, viscosity, N) + reset button
//
// Conventions (Wikitube Betterfire Standard v0)
// ---------------------------------------------
// * single ARTICLE constant, single quotes
// * p5.disableFriendlyErrors = true
// * non-ASCII (Greek letters, dots, arrows) lives in COMMENTS ONLY;
// every text() string literal is plain ASCII
// * Energy-room palette (P5_JS_EDITOR section 4)
// * controls have explicit .position(x, y).size(w)
// * HUD drawn by drawHUD() called once per draw()
// =====================================================================
const ARTICLE = 'Diffusion';
const TITLE = ARTICLE.replace(/_/g, ' ');
p5.disableFriendlyErrors = true;
// ----- Energy room palette (P5_JS_EDITOR section 4) ------------------
const BG = 18;
const FG = 240;
const DIM = [240, 240, 240, 140];
const HOT = [220, 110, 60]; // hotter bath / fast spreading
const COLD = [60, 130, 220]; // particle dots (cool)
const STRUCT = [120, 130, 150]; // box walls, axes
const TRAJ = [240, 220, 80]; // tracer trails
const SCRATCH = [120, 120, 120, 60]; // grid lines
const ACCENT = [200, 100, 220]; // theoretical 4Dt line (magenta)
// ----- Canvas geometry ----------------------------------------------
const CANVAS_W = 720;
const CANVAS_H = 520;
// Particle box (left panel) and MSD scope (right panel).
// boxX/Y/W/H delimit the simulation domain in PIXELS; the physical
// domain is symmetric around its centre and one pixel ~= one nanometre
// for the slider ranges chosen below (so D ~ 1e3 nm^2/s reads as a
// visible spreading rate over a few seconds of wall-clock animation).
const boxX = 40, boxY = 70, boxW = 320, boxH = 320;
const scopeX = 400, scopeY = 70, scopeW = 280, scopeH = 320;
// ----- Physical constants (SI) ---------------------------------------
const K_B = 1.380649e-23; // J / K (exact, 2019 SI redefinition)
const R_PARTICLE_NM = 0.5; // nm, tracer-particle radius
// Visual time scaling. Real Stokes-Einstein D for a 0.5 nm sphere in
// water at 300 K is ~4 * 10^-10 m^2/s = 4 * 10^8 nm^2/s. We slow that
// down by a fixed factor for legibility; the math is still correct,
// just on a dilated clock.
const TIME_SCALE = 1e-7; // wall-clock seconds per simulated second
// ----- Simulation state ----------------------------------------------
let particles = []; // {x, y} in pixel/nm coordinates relative to box centre
let traceIdx = []; // indices of the half-dozen tracer particles
let traceHist = []; // per-tracer array of {x, y}
let msd = []; // ring buffer of {t, msd, theory}
let simT = 0; // simulated time, seconds
let lastReal = 0; // last performance.now() in millis
let resetBtn;
let tSlider, etaSlider, nSlider;
// Cached current diffusion coefficient (nm^2 / s), recomputed each frame.
let D_current = 0;
function setup() {
createCanvas(CANVAS_W, CANVAS_H);
pixelDensity(2);
textFont('system-ui');
// ----- Sliders (Betterfire rule: explicit position+size) ----------
// Temperature: 200-500 K, default 300 K
tSlider = createSlider(200, 500, 300, 1).position(60, 430).size(160);
// Viscosity: 0.2-5 mPa s, default 1.0 (water-like)
etaSlider = createSlider(0.2, 5.0, 1.0, 0.05).position(60, 460).size(160);
// Particle count: 100-2000, default 600
nSlider = createSlider(100, 2000, 600, 50).position(60, 490).size(160);
// Reset button: re-clusters all particles at the box centre and
// clears the MSD history. Sits to the right of the sliders.
resetBtn = createButton('reset cloud');
resetBtn.position(240, 430);
resetBtn.mousePressed(resetCloud);
resetCloud();
lastReal = millis();
}
function draw() {
background(BG);
// ----- 1. Read controls into named locals -------------------------
const T_K = tSlider.value(); // K
const eta = etaSlider.value() * 1e-3; // Pa s (slider is in mPa s)
const N = nSlider.value();
// Reconcile particle count with slider (add or trim).
syncParticleCount(N);
// ----- 2. Compute D via Stokes-Einstein ---------------------------
// D [m^2/s] = k_B T / (6 pi eta r)
// Convert to nm^2/s for the pixel/nm coordinate system.
const r_m = R_PARTICLE_NM * 1e-9;
const D_SI = (K_B * T_K) / (6 * Math.PI * eta * r_m);
const D_nm2 = D_SI * 1e18; // nm^2 / s
D_current = D_nm2;
// ----- 3. Advance simulation -------------------------------------
// Use real-clock dt clamped to avoid blowups on tab-resume, scaled
// by TIME_SCALE so the spreading is visible.
const now = millis();
const dtReal = Math.min((now - lastReal) / 1000, 0.05);
lastReal = now;
const dt = dtReal / TIME_SCALE; // simulated seconds per frame
// Per-step Gaussian standard deviation per axis: sigma = sqrt(2 D dt)
// (1D Wiener step variance is 2Dt; in 2D each axis gets its own).
const sigma = Math.sqrt(2 * D_nm2 * dt);
// Step every particle: x += N(0, sigma), y += N(0, sigma).
for (const p of particles) {
p.x += randomGaussian() * sigma;
p.y += randomGaussian() * sigma;
}
// Append the tracer positions to their per-particle history.
for (let k = 0; k < traceIdx.length; k++) {
const p = particles[traceIdx[k]];
if (!p) continue;
traceHist[k].push({ x: p.x, y: p.y });
if (traceHist[k].length > 200) traceHist[k].shift();
}
simT += dt;
// ----- 4. Mean squared displacement -------------------------------
// <r^2> averaged over the swarm. For a 2D random walk this should
// grow as 4 D t (4 = 2 dimensions x 2 from variance formula).
let s = 0;
for (const p of particles) s += p.x * p.x + p.y * p.y;
const msdNow = s / Math.max(particles.length, 1);
const theoryNow = 4 * D_nm2 * simT;
msd.push({ t: simT, msd: msdNow, theory: theoryNow });
if (msd.length > 800) msd.shift();
// ----- 5. Draw ----------------------------------------------------
drawParticleBox();
drawScope();
drawReadouts(T_K, eta, N);
drawHUD();
}
// =====================================================================
// Cloud / particle helpers
// =====================================================================
// Reset every particle to the box centre, choose a fresh tracer set,
// wipe the MSD ring buffer, and reset simulated time.
function resetCloud() {
const N = nSlider ? nSlider.value() : 600;
particles = [];
for (let i = 0; i < N; i++) particles.push({ x: 0, y: 0 });
// Pick six tracers uniformly across the particle index range.
traceIdx = [];
traceHist = [];
const NUM_TRACERS = 6;
for (let k = 0; k < NUM_TRACERS; k++) {
traceIdx.push(Math.floor((k + 0.5) * (N / NUM_TRACERS)));
traceHist.push([]);
}
msd = [];
simT = 0;
}
// Grow or shrink the particle array to match the requested count
// without disturbing the existing positions of survivors.
function syncParticleCount(N) {
if (particles.length === N) return;
if (particles.length < N) {
// Add new particles at the current cloud centroid so they don't
// visually jump in from the origin after the cloud has spread.
let cx = 0, cy = 0;
for (const p of particles) { cx += p.x; cy += p.y; }
cx /= Math.max(particles.length, 1);
cy /= Math.max(particles.length, 1);
while (particles.length < N) particles.push({ x: cx, y: cy });
} else {
particles.length = N;
}
// Re-seat tracer indices if any fell off the end.
for (let k = 0; k < traceIdx.length; k++) {
if (traceIdx[k] >= N) traceIdx[k] = Math.floor(Math.random() * N);
}
}
// =====================================================================
// Drawing
// =====================================================================
// Left panel: bordered box with all particles drawn as small dots,
// plus the trailing histories of the six tracer particles in yellow.
function drawParticleBox() {
// Box outline + grid.
noFill();
stroke(STRUCT);
strokeWeight(1);
rect(boxX, boxY, boxW, boxH);
stroke(...SCRATCH);
strokeWeight(1);
for (let g = 1; g < 4; g++) {
line(boxX + g * boxW / 4, boxY, boxX + g * boxW / 4, boxY + boxH);
line(boxX, boxY + g * boxH / 4, boxX + boxW, boxY + g * boxH / 4);
}
// Origin cross at box centre.
const cx = boxX + boxW / 2;
const cy = boxY + boxH / 2;
stroke(...DIM);
strokeWeight(1);
line(cx - 6, cy, cx + 6, cy);
line(cx, cy - 6, cx, cy + 6);
// Particles. nm coordinates map directly to pixels through
// a single scale factor so the box always fills its rectangle.
// The cloud's 1-sigma radius is sqrt(2 D t); we choose the
// visualisation scale so a 1-sigma cloud of size ~boxW/4 reads well.
const scale = computeBoxScale();
// Bulk swarm: small translucent COLD dots.
noStroke();
fill(COLD[0], COLD[1], COLD[2], 150);
for (const p of particles) {
const x = cx + p.x * scale;
const y = cy + p.y * scale;
if (x < boxX || x > boxX + boxW || y < boxY || y > boxY + boxH) continue;
rect(x - 0.75, y - 0.75, 1.5, 1.5);
}
// Tracer trails: yellow lines connecting the historical positions.
noFill();
stroke(TRAJ[0], TRAJ[1], TRAJ[2], 180);
strokeWeight(1);
for (let k = 0; k < traceHist.length; k++) {
const h = traceHist[k];
if (h.length < 2) continue;
beginShape();
for (const q of h) {
const x = cx + q.x * scale;
const y = cy + q.y * scale;
vertex(x, y);
}
endShape();
}
// Tracer current-position dots: brighter yellow.
noStroke();
fill(TRAJ);
for (const k of traceIdx) {
const p = particles[k];
if (!p) continue;
const x = cx + p.x * scale;
const y = cy + p.y * scale;
rect(x - 2, y - 2, 4, 4);
}
// Panel label.
noStroke();
fill(...DIM);
textAlign(LEFT, TOP);
textSize(11);
text('2D random walk', boxX + 6, boxY + 6);
}
// Pick a per-frame scale so the cloud's 3-sigma radius reads as about
// 40% of the box half-width. This lets the reader watch the cloud
// fill the box and then asymptote, rather than racing off the edge.
function computeBoxScale() {
const sigmaR_nm = Math.sqrt(Math.max(2 * D_current * simT, 1));
const target_px = boxW * 0.40;
return Math.min(target_px / (3 * sigmaR_nm), 4);
}
// Right panel: <r^2>(t) versus simulated time, with the theoretical
// straight line <r^2> = 4 D t overplotted.
function drawScope() {
// Frame.
noFill();
stroke(STRUCT);
strokeWeight(1);
rect(scopeX, scopeY, scopeW, scopeH);
// Determine axis ranges from the data so the trace fills the panel.
if (msd.length < 2) return;
const tMin = msd[0].t;
const tMax = Math.max(msd[msd.length - 1].t, tMin + 1e-9);
let yMax = 0;
for (const s of msd) yMax = Math.max(yMax, s.msd, s.theory);
if (yMax <= 0) yMax = 1;
// Faint grid (4 x 4).
stroke(...SCRATCH);
for (let g = 1; g < 4; g++) {
const xg = map(g, 0, 4, scopeX, scopeX + scopeW);
const yg = map(g, 0, 4, scopeY + scopeH, scopeY);
line(xg, scopeY, xg, scopeY + scopeH);
line(scopeX, yg, scopeX + scopeW, yg);
}
// Theoretical line <r^2> = 4 D t in magenta.
stroke(ACCENT);
strokeWeight(1.5);
noFill();
beginShape();
for (const s of msd) {
const x = map(s.t, tMin, tMax, scopeX, scopeX + scopeW);
const y = map(s.theory, 0, yMax, scopeY + scopeH, scopeY);
vertex(x, y);
}
endShape();
// Measured swarm MSD in yellow.
stroke(TRAJ);
strokeWeight(2);
noFill();
beginShape();
for (const s of msd) {
const x = map(s.t, tMin, tMax, scopeX, scopeX + scopeW);
const y = map(s.msd, 0, yMax, scopeY + scopeH, scopeY);
vertex(x, y);
}
endShape();
// Axis labels.
noStroke();
fill(...DIM);
textAlign(LEFT, TOP);
textSize(11);
text('<r^2> vs t', scopeX + 6, scopeY + 6);
textAlign(RIGHT, BOTTOM);
text('t [s]', scopeX + scopeW - 6, scopeY + scopeH - 4);
textAlign(LEFT, TOP);
text('<r^2> [nm^2]', scopeX + 6, scopeY + scopeH - 16);
// Legend.
fill(TRAJ);
rect(scopeX + scopeW - 110, scopeY + 22, 12, 4);
fill(...DIM);
textAlign(LEFT, TOP);
text('measured', scopeX + scopeW - 92, scopeY + 18);
fill(ACCENT);
rect(scopeX + scopeW - 110, scopeY + 38, 12, 4);
fill(...DIM);
text('4 D t', scopeX + scopeW - 92, scopeY + 34);
}
// Bottom-left readouts: live D, N, t, <r^2>, and slider labels.
function drawReadouts(T_K, eta_SI, N) {
noStroke();
textAlign(LEFT, BOTTOM);
// Slider labels (the values are read off the actual sliders).
fill(...DIM);
textSize(11);
text('T [K]: ' + nf(T_K, 0, 0), 230, 442);
text('eta [mPa s]: ' + nf(eta_SI * 1000, 1, 2), 230, 472);
text('N particles: ' + N, 230, 502);
// Live physics readouts at top of right panel.
fill(FG);
textAlign(LEFT, TOP);
textSize(12);
const D_disp = nf(D_current / 1e6, 0, 2); // 10^6 nm^2/s = 10^-12 m^2/s
text('D = ' + D_disp + ' x 10^6 nm^2/s', scopeX + 6, scopeY + 22);
text('t = ' + nf(simT, 0, 3) + ' s', scopeX + 6, scopeY + 40);
if (msd.length > 0) {
const last = msd[msd.length - 1];
const ratio = last.theory > 0 ? last.msd / last.theory : 0;
text('<r^2>/4Dt = ' + nf(ratio, 1, 2), scopeX + 6, scopeY + 58);
}
}
// =====================================================================
// HUD
// =====================================================================
function drawHUD() {
// Top-left: title + Wikitube URL (Betterfire Standard rule 2)
noStroke();
fill(FG);
textAlign(LEFT, TOP);
textSize(20);
text(TITLE, 14, 12);
fill(...DIM);
textSize(12);
text('Wikitube microsim . en.wikitube.io/wiki/Diffusion', 14, 36);
// Top-right: control hints (Betterfire Standard rule 3)
textAlign(RIGHT, TOP);
textSize(10);
text('drag sliders to retune D = k T / (6 pi eta r)', width - 14, 12);
text('yellow trails = tracer histories', width - 14, 24);
text('reset cloud to re-cluster at origin', width - 14, 36);
// Bottom-right: canonical equation (Betterfire Standard rule 4)
textAlign(RIGHT, BOTTOM);
fill(FG);
textSize(13);
text('<r^2> = 4 D t [Einstein 1905, 2D]', width - 14, height - 20);
fill(...DIM);
textSize(11);
text('d phi/dt = D del^2 phi [Fick 1855]', width - 14, height - 4);
}
// =====================================================================
// End of Diffusion.js -- Wikitube microsim, Helium room, Pattern E.
// =====================================================================
```
## Links (Wikipedia order)
<!-- injected from _registry/childlinks/Diffusion.json (2026-07-30T02:09:12Z) -->
`Advection` · `Albert_Einstein` · `Amount_of_substance` · `Anisotropic_diffusion` · `Area` · [[Artificial_intelligence]] · `Astronomy` · `Atomic_diffusion` · `Avogadro_constant` · `Biologist` · `Biology` · `Blood` · `Blood_vessel` · `Bohm_diffusion` · `Boltzmann_constant` · `Boltzmann_equation` · `Boussinesq_approximation_(buoyancy)` · `Brownian_motion` · `Butterworth-Heinemann` · `Carbon_dioxide` · `Carl_Wagner` · `Cementation_process` · `Chapman–Enskog_theory` · `Chemical_kinetics` · `Chemical_potential` · `Chemically_peculiar_star` · [[Chemistry]] · `Chinese_ceramics` · `Concentration` · `Conjugate_variables_(thermodynamics)` · `Continuity_equation` · `Convection` · `Convection–diffusion_equation` · `Course_of_Theoretical_Physics` · `Darcy's_law` · `Data_science` · `Diffusion-limited_aggregation` · `Diffusion_(disambiguation)` · `Diffusion_equation` · `Diffusion_model` · `Diffusion_process` · `Dimension` · `Dimensional_analysis` · `Dimensionless_quantity` · `Distance` · `Drift_velocity` · `Earth_Surface_Processes_and_Landforms` · `Earthenware` · `Economics` · `Effusion` · `Einstein_relation_(kinetic_theory)` · [[Electronics]] · `Elementary_charge` · `Entropic_force` · [[Entropy]] · `Evgeny_Lifshitz` · `Facilitated_diffusion` · `Fick's_laws_of_diffusion` · `Finance` · `Flux` · [[Force]] · `Free_entropy` · `Gas_constant` · `Gaseous_diffusion` · `Generative_model` · `George_de_Hevesy` · `Gibbs_free_energy` · `Glomerulus_(kidney)` · `Gradient` · `Heart` · `Heat_equation` · `Hemodialysis` · `Henry_Eyring_(chemist)` · `Ideal_gas_law` · [[Impulse_response]] · [[Information_theory]] · `Internal_energy` · `Interstitial_defect` · [[Iron]] · `Isobaric_counterdiffusion` · `Isothermal_process` · `Isotope_separation` · `Isotopes_of_lead` · `James_Clerk_Maxwell` · `John_Gamble_Kirkwood` · `Kinesis_(biology)` · [[Kinetic_theory_of_gases]] · `Langevin_equation` · `Laplace_operator` · `Lars_Onsager` · `Latent_variable_model` · `Latin` · `Lev_Landau` · `Linear_approximation` · `Ludwig_Boltzmann` · `Lévy_flight` · [[Machine_learning]] · `Marian_Smoluchowski` · `Marketing` · `Mass_diffusivity` · [[Materials_science]] · `Mean_free_path` · `Mean_squared_displacement` · `Mole_(unit)` · `Molecular_diffusion` · `Momentum_diffusion` · `Monolayer` · `Non-equilibrium_thermodynamics` · `Ohm's_law` · `Onsager_reciprocal_relations` · `Osmosis` · `Percolation_theory` · `Permeation` · `Physical_quantity` · [[Physics]] · `Pliny_the_Elder` · `Pressure` · `Pressure_gradient` · [[Probability]] · `Probability_theory` · `Pulmonary_alveolus` · `Random_walk` · `Robert_Boyle` · `Robert_Brown_(botanist,_born_1773)` · [[Rudolf_Clausius]] · [[Second_law_of_thermodynamics]] · `Self-diffusion` · `Sociology` · `Sorption` · `Spinodal_decomposition` · `Stained_glass` · `Statistics` · `Stellar_atmosphere` · `Stochastic_process` · `Surface_diffusion` · `Taxis` · `Temperature` · `Thermal_conduction` · `Thermal_oxidation` · `Thermodynamic_potential` · [[Thermodynamics]] · `Thomas_Graham_(chemist)` · `Thoracic_cavity` · `Transition_state_theory` · `Transport_coefficient` · `Transport_phenomena` · `Ultrafiltration` · `Vector_area` · [[Viscosity]] · [[Wayback_Machine]] · `White_dwarf` · `William_Chandler_Roberts-Austen` · `Yakov_Frenkel`
> **Room:** [[Helium]] · **Status:** ✅ shipped
## Overview
Diffusion is the net transport of particles from regions of higher concentration to regions of lower concentration driven by their random thermal motion. First described quantitatively by Adolf Fick in 1855, the process is governed by two laws. Fick's first law states that the diffusive flux is proportional to the negative concentration gradient, J = -D del-phi, where D is the diffusion coefficient with units of m^2/s. Combining this with mass conservation yields Fick's second law, the diffusion equation d-phi/dt = D del^2 phi, which is the parabolic [[Partial_differential_equation|partial differential equation]] that governs every spreading process from ink in water to dopants in silicon.
The microscopic origin is the random walk. Einstein's 1905 derivation showed that the mean squared displacement of a Brownian particle grows linearly with time: <x^2> = 2Dt in one dimension, 6Dt in three. The Stokes-Einstein relation D = kT/(6 pi eta r) ties the macroscopic coefficient to thermal [[Energy|energy]], [[Viscosity|viscosity]], and particle radius, and Perrin's 1908 measurement of suspended grains confirmed Avogadro's number through this route.
Helium diffuses faster than any other gas in air because of its low mass and small atomic radius, a fact Graham's law (rate proportional to 1/sqrt(M)) makes quantitative. This is why mass-spectrometer [[Leak_detection|leak detection]] uses helium as its tracer gas, and why helium escapes through glass, rubber, and polymer seals over months. Diffusion governs [[Neutron|neutron]] transport in reactors, semiconductor doping profiles, cellular nutrient uptake, and atmospheric pollutant dispersal.
## See also
- Room hub: [[Helium]]
- p5.js Editor conventions: P5 JS EDITOR
- Wiki root: MAIN
---
*Scaffolded by `generative-microsim` from row 180 of the Helium sheet on 2026-05-15T01:24:20Z.*
<!-- 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/Diffusion) : [Wikitube](https://en.wikitube.io/wiki/Diffusion)
## Previous hub tags
Tree parents: [[Helium]] · [[Oxygen]].
Legacy hubs: none.
---
*Sources: 1 legacy note. Minted wave 1, 2026-07-30 (v1.6 order).*