code wiki / (root) / nx_stress_test.nx

nx_stress_test.nx source

↩ module page · 86 lines · 3268 B

1// nx_stress_test.nx -- stress = force/area + per-material yield 2// classification against hand-computed reference cases. 3// 4// All Q14 throughout (force in Q14 N, area in Q14 m²). σ_Pa = F_q14 / A_q14 5// since Q14 cancels in the ratio. 6// 7// Closed-form invariants: 8// (a) Zero force on unit area: σ = 0 Pa. 9// (b) 100 N on 1 m² = 100 Pa. 10// F_q14 = 100 * 16384, A_q14 = 16384 → σ = 100*16384/16384 = 100 Pa. 11// (c) 100 N on 0.001 m² = 100000 Pa = 100 kPa. 12// (d) Zero area returns NULL (defensive). 13// (e) PLA yield = 50 MPa = 50000000 Pa. 14// (f) PEEK yield = 95 MPa, ultimate = 100 MPa. 15// (g) 25 MPa on PLA -> SAFE (< 50/2 = 25 MPa). 16// Actually 25 == yield/2 boundary; classifier uses `>=` so this 17// 18// is exactly WORKING. Let me use 24 MPa for SAFE. 19// (h) 30 MPa on PLA -> WORKING (>= 25, < 50). 20// (i) 50 MPa on PLA -> YIELDED. 21// (j) 70 MPa on PLA -> FRACTURED (>= 65 ultimate). 22// (k) Unknown material class (99) -> UNKNOWN_MAT verdict. 23// (l) MPa conversion: 50000000 Pa -> 50 MPa. 24// 25// expect_exit: 0 26// license_tier: ORIGINAL 27 28import "nx_syscalls.nx" 29import "nx_material_profile.nx" 30import "nx_stress.nx" 31 32const Q14: i64 = 16384 33 34func main() -> i64 { 35 // --- (a) zero force --- 36 let s0: *NxStress = nx_stress_from_force_area(0, Q14) 37 if s0.pa != 0 { return 10 } 38 39 // --- (b) 100 N / 1 m² = 100 Pa --- 40 let s100: *NxStress = nx_stress_from_force_area(100 * Q14, Q14) 41 if s100.pa != 100 { return 20 } 42 43 // --- (c) 100 N / 0.001 m² = 100000 Pa = 100 kPa --- 44 // 0.001 in Q14 = 16 (rounds 16.384 → 16; some Q14 loss) 45 let a_small: i64 = Q14 / 1000 // 16 46 let sk: *NxStress = nx_stress_from_force_area(100 * Q14, a_small) 47 // Expected: 100*16384/16 = 102400 Pa (slightly > 100000 due to rounding) 48 if sk.pa < 100000 { return 30 } 49 if sk.pa > 110000 { return 31 } 50 51 // --- (d) Zero area returns NULL --- 52 let s_bad: *NxStress = nx_stress_from_force_area(100 * Q14, 0) 53 if (s_bad as i64) != 0 { return 40 } 54 55 // --- (e) PLA yield = 50 MPa --- 56 if nx_stress_yield_pa(NX_MAT_PLA) != 50000000 { return 50 } 57 58 // --- (f) PEEK --- 59 if nx_stress_yield_pa(NX_MAT_PEEK) != 95000000 { return 60 } 60 if nx_stress_ultimate_pa(NX_MAT_PEEK) != 100000000 { return 61 } 61 62 // --- (g) 24 MPa on PLA -> SAFE --- 63 let s24mpa: *NxStress = nx_stress_new(24000000) 64 if nx_stress_classify(s24mpa, NX_MAT_PLA) != NX_STRESS_SAFE { return 70 } 65 66 // --- (h) 30 MPa on PLA -> WORKING --- 67 let s30mpa: *NxStress = nx_stress_new(30000000) 68 if nx_stress_classify(s30mpa, NX_MAT_PLA) != NX_STRESS_WORKING { return 80 } 69 70 // --- (i) 50 MPa on PLA -> YIELDED --- 71 let s50mpa: *NxStress = nx_stress_new(50000000) 72 if nx_stress_classify(s50mpa, NX_MAT_PLA) != NX_STRESS_YIELDED { return 90 } 73 74 // --- (j) 70 MPa on PLA -> FRACTURED --- 75 let s70mpa: *NxStress = nx_stress_new(70000000) 76 if nx_stress_classify(s70mpa, NX_MAT_PLA) != NX_STRESS_FRACTURED { return 100 } 77 78 // --- (k) Unknown material --- 79 if nx_stress_classify(s50mpa, 99) != NX_STRESS_UNKNOWN_MAT { return 110 } 80 81 // --- (l) MPa conversion --- 82 let s50: *NxStress = nx_stress_new(50000000) 83 if nx_stress_to_mpa(s50) != 50 { return 120 } 84 85 return 0 86}