nx_ice_distribution.nx
buildroot/runtime/nx_ice_distribution.nx
about
nx_ice_distribution.nx -- THE CRYSTAL SIZE DISTRIBUTION, and the coupling
that nx_ice_recrystal had to assert because it did not have one.
===== WHY THIS EXISTS ============================================
nx_ice_recrystal models cycling damage as
V_new = V_old * (1 + phi * G)
where phi is the fraction of ice MASS that melts and refreezes on an
excursion -- derived honestly from the freezing curve -- and G is a
geometric coupling that was ASSERTED. That constant was flagged as the
organ's weak point, and it deserved the flag: it converts "this much mass
moved" into "the mean diameter grew this much", which is a statement about
the crystal size distribution, and the organ had no distribution.
★IT IS NOT A FREE PARAMETER. Given a distribution the whole step is
exact arithmetic:
1. Gibbs-Thomson orders the melting -- the smallest crystals have the
highest surface curvature, the most depressed local melting point,
and therefore go first. The order is physics, not a modelling choice.
2. Remove the smallest crystals until their cumulative MASS reaches
phi * M. Count how many crystals that took.
3. That mass refreezes onto the survivors, so total mass is unchanged
while the count has fallen.
4. Mean volume is mass over count, so it rises by exactly N / N'.
★★THE WHOLE POINT IS THAT THE NUMBER FRACTION IS NOT THE MASS FRACTION.
Small crystals are numerous and light. Removing a given fraction of the
MASS removes a much larger fraction of the COUNT, because it takes many
small crystals to make up that mass. A model that quietly equates the two
-- which is what a coupling of 1.0 does -- therefore UNDER-STATES how much
the mean size grows per cycle. Under-stating damage is the direction that
says a product is fine when it is not.
So this organ computes the coupling instead of asserting it, and
dist_coupling_error_permil measures how wrong the assertion was.
===== WHAT REMAINS ASSERTED ======================================
dependencies 1 imports · 1 importers
imports: nx_syscalls.nx
imported by: nx_labsci_svc.nx
structs
| 72 | struct IceDist |
consts
| 55 | const DIST_MAGIC_1200: i64 = 1200 |
| 56 | const DIST_MAGIC_2100: i64 = 2100 |
| 57 | const DIST_MAGIC_2600: i64 = 2600 |
| 58 | const DIST_MAGIC_2200: i64 = 2200 |
| 59 | const DIST_MAGIC_1300: i64 = 1300 |
| 60 | const DIST_MAGIC_3000000: i64 = 3000000 |
| 62 | const DIST_INVALID: i64 = 0 - 1 |
| 66 | const DIST_MAXBINS: i64 = 32 |
| 70 | const DIST_REF_BINS: i64 = 8 |
functions
| 78 | func dist_new(nbins: i64) -> *IceDist |
| 90 | func dist_set(s: *IceDist, i: i64, diameter: i64, count: i64) -> i64 called by 1: dist_reference |
| 104 | func dist_reference() -> *IceDist |
| 117 | func dist_profile_is_reference() -> i64 called by 1: lab_icecream_recrystal |
| 126 | func dist_is_ascending(s: *IceDist) -> i64 |
| 135 | func dist_total_count(s: *IceDist) -> i64 |
| 144 | func dist_total_mass(s: *IceDist) -> i64 |
| 156 | func dist_mean_diameter(s: *IceDist) -> i64 calls 1: dist_total_count |
| 174 | func dist_count_melted(s: *IceDist, phi_permil: i64) -> i64 |
| 207 | func dist_number_fraction_permil(s: *IceDist, phi_permil: i64) -> i64 |
| 223 | func dist_volume_growth_permil(s: *IceDist, phi_permil: i64) -> i64 |
| 238 | func dist_derived_coupling(s: *IceDist, phi_permil: i64) -> i64 |
| 248 | func dist_coupling_error_permil(s: *IceDist, phi_permil: i64, asserted: i64) -> i64 |
| 259 | func dist_asserted_is_conservative(s: *IceDist, phi_permil: i64, asserted: i64) -> i64 calls 1: dist_coupling_error_permil |
| 275 | func dist_apply_cycle(s: *IceDist, phi_permil: i64) -> i64 |