crystal-test.js
42 lines · in natura-src-1.0.0.zip as natura/crystal-test.js · a test
// crystal-test.js -- assertions for CRYSTALLIZATION (nucleation + grain growth; cooling rate sets grain size).
// Run: node crystal-test.js
const N = require('./natura.js');
const { makeCrystal } = require('./crystal.js');
const { World, UNITS } = N;
const DAY = UNITS.DAY;
let pass = 0, fail = 0;
const ok = (c, m) => { if (c) pass++; else { fail++; console.log(' FAIL: ' + m); } };
const GRID = 80;
const solidify = (cfg) => { const w = World({ seed: 2, systems: [makeCrystal(Object.assign({ N: GRID, seed: 2 }, cfg))] });
for (let i = 0; i < 400 && w.fields().crystal.solidFraction < 1; i++) w.step(DAY); return w.fields().crystal; };
console.log('crystal assertions:');
// 1. DETERMINISM
{
const a = solidify({ coolRate: 4 }), b = solidify({ coolRate: 4 });
let same = a.grainCount === b.grainCount; for (let k = 0; k < GRID * GRID && same; k++) if (a.grain[k] !== b.grain[k]) same = false;
ok(same, 'same seed -> identical microstructure (reproducible)');
}
// 2. IT FULLY SOLIDIFIES -- the melt is entirely consumed into grains, tiling the whole
{
const f = solidify({ coolRate: 4 });
ok(f.solidFraction >= 1 && f.grainCount * f.meanGrainSize >= GRID * GRID - 1, 'the melt fully solidifies into a grain mosaic (' + f.grainCount + ' grains tile ' + (GRID * GRID) + ' cells)');
}
// 3. THE LAW -- FAST cooling gives MANY SMALL grains; SLOW cooling gives FEW LARGE ones (grain size ~ 1/nucleation)
{
const fast = solidify({ coolRate: 30 }), slow = solidify({ coolRate: 1.2 });
ok(fast.grainCount > slow.grainCount * 3, 'fast cooling nucleates FAR more grains (' + fast.grainCount + ' vs ' + slow.grainCount + ')');
ok(fast.meanGrainSize < slow.meanGrainSize, 'and so its grains are SMALLER -- cooling rate sets grain size (' + fast.meanGrainSize + ' vs ' + slow.meanGrainSize + ' cells)');
}
// 4. A SLOW COOL makes a FEW BIG crystals (the geode's cathedral) -- at least one large grain
{
const slow = solidify({ coolRate: 0.6 });
ok(slow.grainCount < 30 && slow.meanGrainSize > 200, 'a slow cool grows a few big crystals (' + slow.grainCount + ' grains, mean ' + slow.meanGrainSize + ' cells)');
}
console.log(`\n${pass} passed, ${fail} failed`);
process.exit(fail ? 1 : 0);