code wiki / (root) / nx_icecream.nx

nx_icecream.nx

buildroot/runtime/nx_icecream.nx

22627 B568 linesdepth 2pulls 2 transitivereach 5 importersview sourcekind library
docsdependenciesstructsconstsfunctions

about

nx_icecream.nx -- FOOD-SCIENCE SUITE / FROZEN DESSERT rung. Computes what a frozen dessert mix will actually DO -- where it starts to freeze, how much of its water is ice at any serving temperature, whether it will go sandy, and whether it is legally ice cream -- from composition and physical chemistry, instead of trusting a recipe's "churn until thick". THE CORE IS ONE EQUATION, HONESTLY APPLIED. Freezing-point depression is colligative: dT = Kf * molality. Everything expensive follows from it: - As water freezes OUT, the remaining solution CONCENTRATES, so the freezing point keeps dropping. At equilibrium at temperature T, the unfrozen water is exactly the amount whose freezing point IS T. Since depression is inversely proportional to water for fixed solute: frozen_fraction = 1 - FPD_initial / |T| That is derived, not tabulated -- ic_frozen_water_permil. - Inverting it answers the question a recipe cannot: what cabinet temperature gives the scoopable ~72% ice I want, FOR THIS MIX? -- ic_serve_temp_for_frozen_permil. MEASURED against published freezing curves for a typical mix (FPD ~2.5 C): this model gives 51% frozen at -5 C (lit ~50%), 81% at -13 C (lit ~80%), 86% at -18 C (lit ~90%). It tracks well through the scooping range and runs ~4 points LOW in the deep-freeze tail, where ideal-solution theory stops holding (activity coefficients depart from 1 in a highly concentrated serum). Stated, not hidden. PAC IS DERIVED, POD CANNOT BE. The gelato trade's anti-freezing power index (PAC, sucrose = 100) is just a molecular-weight ratio, so this COMPUTES it -- ic_pac_from_mw reproduces the trade table exactly for the crystalline sugars (sucrose 100, dextrose 190, fructose 190, lactose 100). Sweetening power (POD) is psychophysical -- a measured human response, not a colligative property -- so it stays a cited table. Confusing the two is the classic formulation error: dextrose has ~1.9x the freezing power of sucrose but only ~0.7x the sweetness, which is exactly why it is the lever for a softer product without a sweeter one. All INTEGER. Suffixes: _q1 = x10, _q2 = x100, _q3 = x1000, _permil = x1000 (fraction), _milli_c = temperature x1000 in Celsius. Grounding (cited; researcher-groundable):

dependencies 1 imports · 4 importers

nx_syscalls.nx nx_icecream.nx nx_ice_recrystal.nx nx_icecream_bench_gate.nx nx_labsci_svc.nx nx_water_activity.nx

imports: nx_syscalls.nx

imported by: nx_ice_recrystal.nxnx_icecream_bench_gate.nxnx_labsci_svc.nxnx_water_activity.nx

structs

117struct NxIceMix

consts

54const IC_KF_WATER_Q3: i64 = 1860
57const IC_MW_SUCROSE_Q2: i64 = 34230
58const IC_MW_LACTOSE_Q2: i64 = 34230
59const IC_MW_MALTOSE_Q2: i64 = 34230
60const IC_MW_DEXTROSE_Q2: i64 = 18016
61const IC_MW_FRUCTOSE_Q2: i64 = 18016
62const IC_MW_INVERT_Q2: i64 = 18016 // 50/50 glucose+fructose, both 180.16
63const IC_MW_SORBITOL_Q2: i64 = 18217
64const IC_MW_NACL_Q2: i64 = 5844
68const IC_ANHYDROGLUCOSE_Q2: i64 = 16214
69const IC_WATER_MW_Q2: i64 = 1802
73const IC_MSNF_LACTOSE_PERMIL: i64 = 545 // 54.5% of MSNF is lactose
74const IC_MSNF_ASH_PERMIL: i64 = 80 // 8.0% of MSNF is mineral ash
80const IC_MILK_SALT_EFF_MW_Q2: i64 = 4000
84const IC_LACTOSE_SOL_Q1: i64 = 90
88const IC_FDA_MIN_MILKFAT_PERMIL: i64 = 100 // 10.0% milkfat
89const IC_FDA_MIN_MILK_SOLIDS_PERMIL: i64 = 200 // 20.0% total milk solids
90const IC_FDA_MIN_LB_PER_GAL_Q2: i64 = 450 // 4.5 lb/gal finished weight
91const IC_FDA_MIN_FOOD_SOLIDS_Q2: i64 = 160 // 1.6 lb food solids/gal
93const IC_ML_PER_GAL: i64 = 3785 // 1 US gallon = 3785.41 mL
94const IC_G_PER_LB: i64 = 454 // 1 lb = 453.59 g
98const IC_STYLE_UNCLASSIFIED: i64 = 0
99const IC_STYLE_SORBET: i64 = 1
100const IC_STYLE_GELATO: i64 = 2
101const IC_STYLE_ICE_CREAM: i64 = 3
102const IC_STYLE_LOWFAT: i64 = 4
104const IC_GELATO_MAX_OVERRUN_PCT: i64 = 50
105const IC_SORBET_MAX_FAT_PERMIL: i64 = 10 // under 1% fat = not a dairy ice
106const IC_LOWFAT_MIN_FAT_PERMIL: i64 = 20
109const IC_SCOOPABLE_FROZEN_PERMIL: i64 = 720

functions

128func nx_ice_mix_new() -> *NxIceMix
143func ic_total_solids_g(m: *NxIceMix) -> i64
152func ic_water_g(m: *NxIceMix) -> i64
159func ic_permil(part_g: i64, total_g: i64) -> i64
164func ic_fat_permil(m: *NxIceMix) -> i64 { return ic_permil(m.fat_g, m.total_g) }
165func ic_msnf_permil(m: *NxIceMix) -> i64 { return ic_permil(m.msnf_g, m.total_g) }
calls 1: ic_permil
166func ic_sugar_permil(m: *NxIceMix) -> i64 { return ic_permil(m.sugar_g, m.total_g) }
calls 1: ic_permil
168func ic_total_solids_permil(m: *NxIceMix) -> i64
174func ic_milk_solids_permil(m: *NxIceMix) -> i64
called by 1: ic_fda_milk_solids_ok calls 1: ic_permil
186func ic_pac_from_mw(mw_q2: i64) -> i64
called by 1: ic_pac_index
195func ic_syrup_mw_q2(de: i64) -> i64
204func ic_blend_mw_q2(g1: i64, mw1_q2: i64, g2: i64, mw2_q2: i64) -> i64
216func ic_blend_pod(g1: i64, pod1: i64, g2: i64, pod2: i64) -> i64
228func ic_pac_index(m: *NxIceMix) -> i64
called by 1: lab_icecream_freeze calls 1: ic_pac_from_mw
235func ic_pod_index(m: *NxIceMix) -> i64
251func ic_sugar_umol(m: *NxIceMix) -> i64
256func ic_lactose_g(m: *NxIceMix) -> i64
260func ic_lactose_umol(m: *NxIceMix) -> i64
265func ic_milk_salt_umol(m: *NxIceMix) -> i64
270func ic_total_solute_umol(m: *NxIceMix) -> i64
279func ic_fpd_milli_c(m: *NxIceMix) -> i64
289func ic_freezing_point_milli_c(m: *NxIceMix) -> i64
called by 1: lab_icecream_freeze calls 1: ic_fpd_milli_c
301func ic_frozen_water_permil(m: *NxIceMix, temp_milli_c: i64) -> i64
316func ic_serve_temp_for_frozen_permil(m: *NxIceMix, target_permil: i64) -> i64
327func ic_scoop_temp_milli_c(m: *NxIceMix) -> i64
333func ic_hardness_index(m: *NxIceMix, temp_milli_c: i64) -> i64
340func ic_lactose_per_100_water_q1(m: *NxIceMix) -> i64
347func ic_sandy_risk(m: *NxIceMix) -> i64
358func ic_max_msnf_g(water_g: i64) -> i64
368func ic_overrun_pct(vol_mix: i64, vol_frozen: i64) -> i64
376func ic_overrun_pct_by_weight(wt_mix: i64, wt_frozen: i64) -> i64
383func ic_product_density_q3(density_q3: i64, overrun_pct: i64) -> i64
390func ic_weight_lb_per_gal_q2(density_q3: i64, overrun_pct: i64) -> i64
434func ic_food_solids_permil(m: *NxIceMix) -> i64
441func ic_min_density_solids_q3(ts_permil: i64) -> i64
450func ic_min_density_weight_q3() -> i64
478func ic_ceiling_weight_pct(density_q3: i64) -> i64
485func ic_ceiling_solids_pct(density_q3: i64, ts_permil: i64) -> i64
501func ic_fda_food_solids_ok(m: *NxIceMix, overrun_pct: i64) -> i64
515func ic_fda_is_ice_cream2(m: *NxIceMix, overrun_pct: i64) -> i64
525func ic_fda_milkfat_ok(m: *NxIceMix) -> i64
531func ic_fda_milk_solids_ok(m: *NxIceMix) -> i64
537func ic_fda_weight_ok(m: *NxIceMix, overrun_pct: i64) -> i64
545func ic_fda_is_ice_cream(m: *NxIceMix, overrun_pct: i64) -> i64
554func ic_classify(m: *NxIceMix, overrun_pct: i64) -> i64
calls 1: ic_fat_permil