code wiki / (root) / nx_pillar_physics_test.nx

nx_pillar_physics_test.nx source

↩ module page · 96 lines · 4931 B

1// nx_pillar_physics_test.nx -- verify cantilever moment + load-proportional 2// footprint sizing EXCEEDS industry constant-diameter baseline. 3// 4// Closed-form invariants: 5// (a) Zero/negative load → 0 moment 6// (b) Moment scales linearly with mass (2× mass → 2× moment) 7// (c) Moment scales linearly with arm (2× arm → 2× moment) 8// (d) Zero/negative moment → MIN footprint (industry baseline) 9// (e) Light load PLA → footprint == MIN (matches industry) 10// (f) Heavy load PLA → footprint > MIN (industry would underbuild) 11// (g) MONOTONIC: heavier load → larger footprint 12// (h) MATERIAL-AWARE: same load, stiffer material → smaller footprint 13// (industry uses SAME footprint regardless of material -- their gap) 14// (i) Runaway load clamped to MAX_FOOT (no infinite growth) 15// (j) Convenience nx_pillar_footprint_for_load matches direct math 16// 17// expect_exit: 0 18// license_tier: ORIGINAL 19 20import "nx_syscalls.nx" 21import "nx_material_profile.nx" 22import "nx_pillar_physics.nx" 23 24const Q14: i64 = 16384 25 26func main() -> i64 { 27 let pla: *NxMaterialProfile = nx_material_profile_generic_pla() 28 let abs_: *NxMaterialProfile = nx_material_profile_generic_abs() 29 let peek: *NxMaterialProfile = nx_material_profile_generic_peek() 30 31 // --- (a) Zero/negative load → 0 moment --- 32 if nx_cantilever_moment(0, 10 * Q14) != 0 { return 10 } 33 if nx_cantilever_moment(10 * Q14, 0) != 0 { return 11 } 34 if nx_cantilever_moment(-1, 10 * Q14) != 0 { return 12 } 35 if nx_cantilever_moment(10 * Q14, -1) != 0 { return 13 } 36 37 // --- (b) Linear in mass: 2× mass → 2× moment --- 38 let m1: i64 = nx_cantilever_moment(1 * Q14, 5 * Q14) 39 let m2: i64 = nx_cantilever_moment(2 * Q14, 5 * Q14) 40 if m2 != 2 * m1 { return 20 } 41 42 // --- (c) Linear in arm: 2× arm → 2× moment --- 43 let m3: i64 = nx_cantilever_moment(3 * Q14, 4 * Q14) 44 let m4: i64 = nx_cantilever_moment(3 * Q14, 8 * Q14) 45 if m4 != 2 * m3 { return 30 } 46 47 // --- (d) Zero moment → MIN footprint --- 48 let yield_pla: i64 = pla.tensile_yield_mpa_q14 49 let f_zero: i64 = nx_pillar_min_footprint(0, yield_pla, NX_MAT_PILLAR_SAFETY_Q14) 50 if f_zero != NX_MAT_PILLAR_MIN_FOOT_Q14 { return 40 } 51 52 // --- (e) Light load PLA: footprint should be MIN (clamped) --- 53 let light_moment: i64 = nx_cantilever_moment(1 * Q14, 1 * Q14) // 1 g·mm 54 let f_light: i64 = nx_pillar_min_footprint(light_moment, yield_pla, 55 NX_MAT_PILLAR_SAFETY_Q14) 56 if f_light != NX_MAT_PILLAR_MIN_FOOT_Q14 { return 50 } 57 58 // --- (f) Heavy load PLA: footprint should exceed MIN --- 59 let heavy_moment: i64 = nx_cantilever_moment(10 * Q14, 10 * Q14) // 100 g·mm 60 let f_heavy: i64 = nx_pillar_min_footprint(heavy_moment, yield_pla, 61 NX_MAT_PILLAR_SAFETY_Q14) 62 if f_heavy <= NX_MAT_PILLAR_MIN_FOOT_Q14 { return 60 } 63 64 // --- (g) Monotonic: heavier > lighter (across non-clamped range) --- 65 let m_mid: i64 = nx_cantilever_moment(5 * Q14, 5 * Q14) // 25 g·mm 66 let m_heavy: i64 = nx_cantilever_moment(10 * Q14, 10 * Q14) // 100 g·mm 67 let f_mid: i64 = nx_pillar_min_footprint(m_mid, yield_pla, NX_MAT_PILLAR_SAFETY_Q14) 68 let f_heavy_g: i64 = nx_pillar_min_footprint(m_heavy, yield_pla, NX_MAT_PILLAR_SAFETY_Q14) 69 if f_heavy_g <= f_mid { return 70 } 70 71 // --- (h) Material-aware: stiffer material → smaller footprint 72 // (under same load that's NOT clamped to MIN/MAX for both) 73 let yield_abs: i64 = abs_.tensile_yield_mpa_q14 // 20 MPa (soft) 74 let yield_peek: i64 = peek.tensile_yield_mpa_q14 // 95 MPa (stiff) 75 let same_moment: i64 = heavy_moment // 100 g·mm 76 let f_abs: i64 = nx_pillar_min_footprint(same_moment, yield_abs, NX_MAT_PILLAR_SAFETY_Q14) 77 let f_peek: i64 = nx_pillar_min_footprint(same_moment, yield_peek, NX_MAT_PILLAR_SAFETY_Q14) 78 if f_abs <= f_peek { return 80 } 79 // Industry note: Orca/Bambu/Cura/Prusa would all emit identical pillars 80 // here because they don't read material yield. We size them differently. 81 82 // --- (i) Runaway load: footprint clamped to MAX, doesn't overflow --- 83 let huge_moment: i64 = nx_cantilever_moment(1000 * Q14, 1000 * Q14) // 1e6 g·mm 84 let f_huge: i64 = nx_pillar_min_footprint(huge_moment, yield_pla, 85 NX_MAT_PILLAR_SAFETY_Q14) 86 if f_huge != NX_MAT_PILLAR_MAX_FOOT_Q14 { return 90 } 87 88 // --- (j) Convenience matches direct --- 89 let conv: i64 = nx_pillar_footprint_for_load(10 * Q14, 10 * Q14, pla) 90 let direct_m: i64 = nx_cantilever_moment(10 * Q14, 10 * Q14) 91 let direct_f: i64 = nx_pillar_min_footprint(direct_m, yield_pla, 92 NX_MAT_PILLAR_SAFETY_Q14) 93 if conv != direct_f { return 100 } 94 95 return 0 96}