code wiki / (root) / nx_heat_conduction2d.nx

nx_heat_conduction2d.nx source

↩ module page · 82 lines · 3142 B

1// nx_heat_conduction2d.nx -- FOOD-SCIENCE SUITE / NUMERICAL HEAT TRANSFER. 2// A real 2-D transient conduction solver (explicit finite difference) for 3// the retort cold spot: a square of food, surface held at the retort 4// temperature, interior starting cold, relaxing over time. This steps the 5// suite from analytical (Biot/Fourier) toward numerical simulation -- the 6// honest 3-D CFD gap shrinks from "nothing" to "2-D transient". 7// 8// INTEGER-EXACT by design: at the explicit-stability limit (mesh Fourier 9// number Fo = 1/4) the 2-D update is EXACTLY the average of the four 10// neighbours -- T_new[i,j] = (T[up]+T[dn]+T[lf]+T[rt]) / 4 -- so no float 11// and no stability blow-up. Dirichlet boundary (surface temp) fixed; 12// interior relaxes toward it; the centre is the cold spot. 13// 14// THE exceed vs the field: not depth over COMSOL, but a sovereign, 15// integer-deterministic transient field solve that composes with the 16// preservation cook (once the cold spot reaches the lethal temperature the 17// 12-D clock can start) -- no license, bit-reproducible. 18// 19// grounded: explicit_finite_difference_heat_equation + fo_quarter_stability 20// genealogy_id: numerical_heat_transfer + nishi_food_science_suite 21 22import "nx_syscalls.nx" 23 24// Run an N x N grid: surface (border) held at surf, interior init at init, 25// nsteps explicit updates. Returns the centre (cold-spot) temperature. 26func hc2d_run(N: i64, surf: i64, init: i64, nsteps: i64) -> i64 { 27 if N < 3 { return init } 28 let a: *i64 = sys_mmap(N * N * 8) as *i64 29 let b: *i64 = sys_mmap(N * N * 8) as *i64 30 // initialise: border = surf, interior = init (both buffers). 31 var i: i64 = 0 32 while i < N { 33 var j: i64 = 0 34 while j < N { 35 var t: i64 = init 36 if i == 0 { t = surf } 37 if i == N - 1 { t = surf } 38 if j == 0 { t = surf } 39 if j == N - 1 { t = surf } 40 a[i * N + j] = t 41 b[i * N + j] = t 42 j = j + 1 43 } 44 i = i + 1 45 } 46 var s: i64 = 0 47 while s < nsteps { 48 var ii: i64 = 1 49 while ii < N - 1 { 50 var jj: i64 = 1 51 while jj < N - 1 { 52 let up: i64 = a[(ii - 1) * N + jj] 53 let dn: i64 = a[(ii + 1) * N + jj] 54 let lf: i64 = a[ii * N + (jj - 1)] 55 let rt: i64 = a[ii * N + (jj + 1)] 56 b[ii * N + jj] = (up + dn + lf + rt) / 4 57 jj = jj + 1 58 } 59 ii = ii + 1 60 } 61 // copy the freshly-computed interior back into a (border untouched). 62 var ki: i64 = 1 63 while ki < N - 1 { 64 var kj: i64 = 1 65 while kj < N - 1 { 66 a[ki * N + kj] = b[ki * N + kj] 67 kj = kj + 1 68 } 69 ki = ki + 1 70 } 71 s = s + 1 72 } 73 let c: i64 = N / 2 74 return a[c * N + c] 75} 76 77// Has the cold spot reached pct% of the way from init to surf? 78func hc2d_penetrated(center: i64, surf: i64, init: i64, pct: i64) -> i64 { 79 if surf <= init { return 0 } 80 if (center - init) * 100 >= pct * (surf - init) { return 1 } 81 return 0 82}