algorythmtechnologies commited on
Commit
947d4a1
·
verified ·
1 Parent(s): d957b16

Upload folder using huggingface_hub

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ datasets/synthetic_nozzles.json filter=lfs diff=lfs merge=lfs -text
datasets/advanced_physics.py ADDED
@@ -0,0 +1,215 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ AlgoRythm Prandtl Aero — Advanced Physics Encoding
3
+ Encodes "Actual Geometry" and "Laws of Physics" into the dataset.
4
+ Includes:
5
+ 1. Von Mises Stress Criteria
6
+ 2. L-PBF Overhang Analysis (Geometric Manufacturing Constraints)
7
+ 3. Thermal Distortion Prediction
8
+ 4. Local Curvature Analysis
9
+ """
10
+ import math
11
+ import numpy as np
12
+
13
+ # === 1. STRUCTURAL MECHANICS (Von Mises) ===
14
+
15
+ def calc_von_mises_stress(sigma_xx, sigma_yy, sigma_zz, tau_xy, tau_yz, tau_zx):
16
+ """
17
+ Calculates Von Mises Yield Criterion stress.
18
+ σ_v = sqrt(0.5 * [(σ_x - σ_y)² + (σ_y - σ_z)² + (σ_z - σ_x)² + 6(τ_xy² + τ_yz² + τ_zx²)])
19
+ """
20
+ term1 = (sigma_xx - sigma_yy)**2 + (sigma_yy - sigma_zz)**2 + (sigma_zz - sigma_xx)**2
21
+ term2 = 6 * (tau_xy**2 + tau_yz**2 + tau_zx**2)
22
+ return math.sqrt(0.5 * (term1 + term2))
23
+
24
+ def check_yield_criterion(sigma_vm, yield_strength, safety_factor=1.25):
25
+ """True/False check if design yields under load."""
26
+ limit = yield_strength / safety_factor
27
+ return sigma_vm < limit, limit
28
+
29
+ # === 2. GEOMETRIC MANUFACTURING LAWS (L-PBF) ===
30
+
31
+ def calc_max_overhang_angle(material_key):
32
+ """
33
+ Returns the maximum self-supporting angle (degrees from horizontal)
34
+ before support structures are required.
35
+ """
36
+ # Standard rule: 45 degrees is safe.
37
+ # High performance alloys can sometimes do 35-40 with parameter tuning.
38
+ if "Ti6Al4V" in material_key: return 35.0
39
+ if "Inconel" in material_key: return 45.0
40
+ if "Copper" in material_key: return 45.0 # Copper sags easily
41
+ return 45.0
42
+
43
+ def analyze_geometry_printability(geometry_type, angle_deg):
44
+ """
45
+ Determines if a geometric feature honors the "Law of Gravity" in printing.
46
+ Returns: (Pass/Fail, Explanation)
47
+ """
48
+ limit = 45.0
49
+ if angle_deg < limit:
50
+ return False, f"FAIL: Angle {angle_deg}° < {limit}° limit. Will collapse due to gravity/thermal stress."
51
+ return True, f"PASS: Angle {angle_deg}° is self-supporting."
52
+
53
+ # === 3. THERMAL LAWS ===
54
+
55
+ def predict_thermal_distortion(L_mm, dT, CTE):
56
+ """
57
+ Predicts linear thermal expansion/distortion.
58
+ δ = L * α * ΔT
59
+ """
60
+ delta = L_mm * CTE * dT
61
+ return delta
62
+
63
+ def calc_residual_stress_buildup(E_GPa, CTE, dT):
64
+ """
65
+ Estimates residual stress from rapid cooling in L-PBF.
66
+ σ = E * α * ΔT (Simplified 1D constraint)
67
+ """
68
+ sigma = (E_GPa * 1e9) * CTE * dT
69
+ return sigma / 1e6 # MPa
70
+
71
+ # === 4. ROCKET PROPULSION LAWS ===
72
+
73
+ def calc_characteristic_velocity(Pc_Pa, At_m2, mdot_kg_s):
74
+ """
75
+ Calculates Characteristic Velocity (c*).
76
+ c* = (Pc * At) / mdot
77
+ Measure of combustion efficiency.
78
+ """
79
+ if mdot_kg_s <= 0: return 0.0
80
+ c_star = (Pc_Pa * At_m2) / mdot_kg_s
81
+ return c_star
82
+
83
+ def calc_thrust_coefficient(k, epsilon, Pa_Pa, Pc_Pa):
84
+ """
85
+ Calculates Thrust Coefficient (Cf) using ideal rocket theory.
86
+ k: Specific heat ratio (gamma)
87
+ epsilon: Nozzle area expansion ratio (Ae/At)
88
+ """
89
+ # Ideal Cf equation
90
+ term1 = (2 * k**2 / (k - 1))
91
+ term2 = (2 / (k + 1)) ** ((k + 1) / (k - 1))
92
+ term3 = 1 - (Pa_Pa / Pc_Pa) ** ((k - 1) / k)
93
+
94
+ # Simple check for pressure values
95
+ if Pc_Pa <= 0 or Pa_Pa < 0: return 0.0
96
+ if term3 < 0: term3 = 0 # Over-expanded separation risk
97
+
98
+ Cf_ideal = math.sqrt(term1 * term2 * term3)
99
+
100
+ # Add pressure term correction: + epsilon * (Pe/Pc - Pa/Pc)
101
+ # Simplified here to just the momentum term for robustness
102
+ return Cf_ideal
103
+
104
+ def calc_isp(F_N, mdot_kg_s, g0=9.80665):
105
+ """
106
+ Calculates Specific Impulse (Isp).
107
+ Isp = F / (mdot * g0)
108
+ """
109
+ if mdot_kg_s <= 0: return 0.0
110
+ return F_N / (mdot_kg_s * g0)
111
+
112
+ # === 5. FLUID DYNAMICS (Refined) ===
113
+
114
+ def calc_pressure_drop_darcy(f, L_m, Dh_m, rho_kg_m3, v_m_s):
115
+ """
116
+ Darcy-Weisbach Equation for pressure loss.
117
+ dP = f * (L/D) * (rho * v^2 / 2)
118
+ """
119
+ if Dh_m <= 0: return float('inf')
120
+ dP = f * (L_m / Dh_m) * (0.5 * rho_kg_m3 * v_m_s**2)
121
+ return dP
122
+
123
+ def calc_bartz_heat_flux(D_t_m, Pc_Pa, c_star, Pr, mu_gas, cp_gas, T_comb_K):
124
+ """
125
+ Simplified Bartz Reference:
126
+ h_g = 0.026 / D_t^0.2 * (mu^0.2 * cp / Pr^0.6) * (Pc / c*)^0.8
127
+ Returns approx h_g (W/m2K)
128
+ Note: Highly sensitive to units.
129
+ """
130
+ # Simplified proportionality for dataset generation stability
131
+ # Real formulation requires Mach number correction factor sigma
132
+ try:
133
+ term1 = 0.026 / (D_t_m ** 0.2)
134
+ term2 = (mu_gas**0.2 * cp_gas) / (Pr**0.6)
135
+ term3 = (Pc_Pa / c_star) ** 0.8
136
+ h_g = term1 * term2 * term3
137
+ return h_g
138
+ except:
139
+ return 0.0
140
+
141
+ # === 6. MATERIAL SCIENCE (Temperature Dependent) ===
142
+
143
+ def get_material_properties(material_key, temp_K):
144
+ """
145
+ Returns (YieldStrength_MPa, ThermalCond_W_mK) at specific temperature.
146
+ Data approximated from standard aerospace alloys.
147
+ """
148
+ # Inconel 718
149
+ if "Inconel" in material_key:
150
+ # Yield drops with Temp
151
+ if temp_K < 800: return 1100.0, 11.4
152
+ if temp_K < 1000: return 900.0, 22.0
153
+ return 200.0, 25.0 # Dead at >1000K
154
+
155
+ # GRCop-84 (Copper Alloy)
156
+ if "Copper" in material_key or "GRCop" in material_key:
157
+ if temp_K < 600: return 400.0, 320.0
158
+ if temp_K < 900: return 200.0, 300.0
159
+ return 50.0, 280.0
160
+
161
+ # Ti6Al4V
162
+ if "Ti64" in material_key or "Titanium" in material_key:
163
+ if temp_K < 600: return 800.0, 6.7
164
+ return 100.0, 12.0 # Titanium burns/weakens fast
165
+
166
+ return 500.0, 20.0 # Generic steel fallback
167
+
168
+ # === 7. AEROSPACE LAWS ===
169
+
170
+ def check_margin_of_safety_aerospace(allowable, load, factor=1.4):
171
+ """
172
+ Standard Aerospace MoS calculation.
173
+ MoS = (Allowable / (Load * Factor)) - 1
174
+ Must be > 0.
175
+ """
176
+ if load <= 0: return 99.9 # No load = Safe
177
+ mos = (allowable / (load * factor)) - 1
178
+ return mos
179
+
180
+ def calc_critical_crack_length(K1c, sigma_applied):
181
+ """
182
+ Griffith Crack Theory approximation.
183
+ a_c = (1/pi) * (K1c / sigma)^2
184
+ """
185
+ if sigma_applied <= 0: return float('inf')
186
+ # K1c is Fracture Toughness (MPa sqrt(m))
187
+ return (1.0 / math.pi) * (K1c / sigma_applied)**2 * 1000 # mm
188
+
189
+ # === 8. SELF-CORRECTION LOGIC (The "Noyron" Brain) ===
190
+
191
+ def suggest_correction(param_name, current_val, deviation_ratio, limit):
192
+ """
193
+ Returns a physics-based suggestion to fix a failed constraint.
194
+ Example: Stress is 1.5x Yield -> Suggest increasing Wall Thickness by 1.6x.
195
+ """
196
+ if "Stress" in param_name or "MoS" in param_name:
197
+ # If Stress is high, Thickness must increase.
198
+ # sigma ~ 1/t^2 (bending) or 1/t (hoop). Assume 1/t (conservative).
199
+ # new_t = old_t * (stress / yield) * safety_factor
200
+ correction_factor = deviation_ratio * 1.2 # +20% buffer
201
+ new_val = current_val * correction_factor
202
+ return f"Increase Wall Thickness to {new_val:.2f}mm (Factor {correction_factor:.2f}x)"
203
+
204
+ if "Temp" in param_name or "Heat" in param_name:
205
+ # If Temp is high, cooling must increase.
206
+ return f"Increase Cooling Flow or Channel Depth by {deviation_ratio*1.1:.2f}x"
207
+
208
+ if "Deflection" in param_name:
209
+ # Deflection ~ 1/t^3.
210
+ # new_t = old_t * (deflection / allowable)^(1/3)
211
+ correction_factor = (deviation_ratio)**(1.0/3.0) * 1.15
212
+ new_val = current_val * correction_factor
213
+ return f"Increase Rib/Wall Thickness to {new_val:.2f}mm (Stiffness increase)"
214
+
215
+ return "Check Physics Model."
datasets/advanced_structures_dataset.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "id": "heatx_001",
4
+ "input": "Design counter-flow heat exchanger for 50kW thermal load with water coolant",
5
+ "reasoning": "[REQUIREMENTS_PARSE]\n- Heat load (Q): 50 kW\n- Coolant: Water\n- Type: Counter-flow tube-in-tube\n\n[PHYSICS_DERIVATION]\n\nStep 1: LMTD Calculation\nT_hot_in = 150°C, T_hot_out = 80°C\nT_cold_in = 20°C, T_cold_out = 60°C\n$\\Delta T_1 = 150 - 60 = 90°C$\n$\\Delta T_2 = 80 - 20 = 60°C$\n$LMTD = \\frac{90-60}{\\ln(90/60)} = 74.1°C$\n\nStep 2: Overall Heat Transfer\nU = 1500 W/(m²·K) (water-water)\n$A = \\frac{Q}{U \\cdot LMTD} = \\frac{50000}{1500 \\times 74.1} = 0.45$ m²\n\nStep 3: Tube Sizing\nInner tube: D_i = 20mm, D_o = 25mm\nOuter tube: D_i = 40mm\nLength: L = A/(π·D) = 7.2m\n\n[CONSTRAINT_VALIDATION]\n✓ Re_inner = 25000 > 10000 (turbulent)\n✓ Pressure drop = 0.5 bar < 1 bar limit",
6
+ "output": "using PicoGK;\nusing System.Numerics;\n\nnamespace AlgoRythm.RedRock.HeatExchangers\n{\n public class CounterFlowHX\n {\n const float INNER_TUBE_ID = 20.0f;\n const float INNER_TUBE_OD = 25.0f;\n const float OUTER_TUBE_ID = 40.0f;\n const float OUTER_TUBE_OD = 45.0f;\n const float LENGTH = 7200.0f;\n \n public static Voxels GenerateHeatExchanger()\n {\n Voxels voxHX = new Voxels();\n Vector3 start = new Vector3(0,0,0);\n Vector3 end = new Vector3(0,0,LENGTH);\n \n // Outer tube\n Voxels outer = Voxels.voxSphere(start, OUTER_TUBE_OD/2);\n Voxels outerInner = Voxels.voxSphere(start, OUTER_TUBE_ID/2);\n outer.BoolSubtract(outerInner);\n voxHX.BoolAdd(outer);\n \n // Inner tube\n Voxels inner = Voxels.voxSphere(start, INNER_TUBE_OD/2);\n Voxels innerInner = Voxels.voxSphere(start, INNER_TUBE_ID/2);\n inner.BoolSubtract(innerInner);\n voxHX.BoolAdd(inner);\n \n return voxHX;\n }\n }\n}"
7
+ },
8
+ {
9
+ "id": "lattice_001",
10
+ "input": "Generate gyroid lattice infill for lightweight structural component, 30% relative density",
11
+ "reasoning": "[REQUIREMENTS_PARSE]\n- Lattice type: Gyroid (TPMS)\n- Relative density: 30%\n- Purpose: Structural lightweighting\n\n[PHYSICS_DERIVATION]\n\nStep 1: Gyroid Implicit Function\n$f(x,y,z) = \\sin(x)\\cos(y) + \\sin(y)\\cos(z) + \\sin(z)\\cos(x)$\n\nStep 2: Wall Thickness for 30% Density\nFor gyroid: $\\rho_{rel} = 0.5 + 0.5 \\cdot \\text{erf}(t/\\sigma)$\nSolving for ρ = 0.3: t = 0.8mm at 5mm unit cell\n\nStep 3: Unit Cell Period\n$\\lambda = 5$ mm (good for SLM printing)\nScaling factor: $k = 2\\pi/\\lambda$\n\n[CONSTRAINT_VALIDATION]\n✓ Wall thickness 0.8mm > 0.4mm (SLM min)\n✓ Cell size 5mm suitable for powder removal",
12
+ "output": "using PicoGK;\nusing System.Numerics;\n\nnamespace AlgoRythm.RedRock.Lattices\n{\n public class GyroidLattice : IImplicit\n {\n float m_fPeriod = 5.0f;\n float m_fThickness = 0.8f;\n \n public float fValue(Vector3 vec)\n {\n float k = 2.0f * (float)Math.PI / m_fPeriod;\n float x = vec.X * k;\n float y = vec.Y * k;\n float z = vec.Z * k;\n \n float gyroid = (float)(Math.Sin(x)*Math.Cos(y) + \n Math.Sin(y)*Math.Cos(z) + \n Math.Sin(z)*Math.Cos(x));\n return gyroid - m_fThickness;\n }\n \n public static Voxels GenerateGyroid(BBox3 bounds)\n {\n GyroidLattice lattice = new GyroidLattice();\n return new Voxels(lattice, bounds);\n }\n }\n}"
13
+ }
14
+ ]
datasets/generate_dataset.py ADDED
@@ -0,0 +1,1073 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ AlgoRythm Prandtl Aero — Deterministic Dataset Generator v2.0
3
+ Generates physics-first training data with correct PicoGK API patterns.
4
+ All internal calculations in SI, output geometry in mm (PicoGK convention).
5
+ """
6
+ import json, math, random
7
+ from typing import Dict, List
8
+ from physics_core import *
9
+ import universal_csg
10
+ import advanced_physics # NEW: Strict Physics Encoding
11
+
12
+ random.seed(42) # Reproducible dataset
13
+
14
+ # ============================================================
15
+ # PROBLEM TYPE 1: BELL NOZZLE DESIGN
16
+ # ============================================================
17
+ def gen_bell_nozzle(thrust_N, Pc_bar, propellant, eps=None):
18
+ p = PROPELLANTS[propellant]
19
+ gamma = p["gamma"]
20
+ if eps is None:
21
+ eps = random.choice([8, 12, 16, 20, 30, 40, 50, 60, 80])
22
+
23
+ pe_ratio = calc_exit_pressure(gamma, eps)
24
+ Cf = calc_thrust_coefficient(gamma, eps, 1.0, pe_ratio)
25
+ At_m2 = calc_throat_area(thrust_N, Pc_bar, Cf)
26
+ Dt_mm = throat_area_to_diameter_mm(At_m2)
27
+ De_mm = calc_exit_diameter_mm(Dt_mm, eps)
28
+ mdot = calc_mass_flow(thrust_N, p["Isp_vac"])
29
+ Ln_mm = calc_nozzle_length_mm(Dt_mm, De_mm)
30
+ cstar_calc = calc_cstar(p["Tc"], gamma, p["Rspec"])
31
+
32
+ mat = "Inconel_718" if Pc_bar > 80 else ("C103_Niobium" if Pc_bar < 20 else "Inconel_625")
33
+ wall_t = select_wall_thickness_mm(Pc_bar, Dt_mm, mat)
34
+ hoop = calc_hoop_stress_MPa(Pc_bar, Dt_mm, wall_t)
35
+ mos = calc_margin_of_safety(MATERIALS[mat]["sigma_y_MPa"], hoop)
36
+ q_throat = calc_bartz_heat_flux(Pc_bar, Dt_mm, p["cstar"], mdot, p["Tc"], gamma)
37
+
38
+ ref_name, ref_Dt, valid = validate_against_reference(thrust_N, Pc_bar, propellant, Dt_mm)
39
+ ref_note = f"Validated against {ref_name} (Dt={ref_Dt}mm)" if ref_name else "No close reference engine"
40
+
41
+ lpbf = LPBF_PARAMS.get(mat, LPBF_PARAMS["Inconel_718"])
42
+
43
+ input_text = f"Design a bell nozzle for a {thrust_N/1000:.1f} kN {propellant} rocket engine at {Pc_bar} bar chamber pressure with expansion ratio {eps}:1."
44
+
45
+ reasoning = f"""[ENGINEER_COGNITION]
46
+ Analyzing the design space for a {thrust_N/1000:.1f} kN {propellant} engine at Pc={Pc_bar} bar.
47
+
48
+ The isentropic flow relations govern this design. At the throat, flow must reach exactly Mach 1.0 (choked condition). The area ratio epsilon={eps}:1 determines the exit Mach number and pressure ratio.
49
+
50
+ I begin with the thrust coefficient. Using the specific heat ratio gamma={gamma} for {propellant} combustion products:
51
+ - Exit pressure ratio Pe/Pc = {pe_ratio:.6f}
52
+ - Thrust coefficient Cf = {Cf:.4f}
53
+
54
+ **Step 1: Throat Sizing (Critical Dimension)**
55
+ A* = F / (Pc × Cf) = {thrust_N} / ({Pc_bar*1e5:.0f} × {Cf:.4f}) = {At_m2*1e6:.4f} mm²
56
+ D* = sqrt(4A*/π) = {Dt_mm:.2f} mm
57
+ {ref_note}
58
+
59
+ **Step 2: Exit Geometry**
60
+ De = D* × sqrt(ε) = {Dt_mm:.2f} × sqrt({eps}) = {De_mm:.2f} mm
61
+ Nozzle Length (80% Rao bell) = {Ln_mm:.2f} mm
62
+
63
+ **Step 3: Mass Flow (Saint-Venant)**
64
+ mdot = F / (Isp × g0) = {thrust_N} / ({p['Isp_vac']} × 9.807) = {mdot:.4f} kg/s
65
+ c* verification = {cstar_calc:.1f} m/s (spec: {p['cstar']} m/s)
66
+
67
+ **Step 4: Structural Analysis**
68
+ Material: {mat} (σ_y = {MATERIALS[mat]['sigma_y_MPa']} MPa)
69
+ Wall thickness: {wall_t:.2f} mm (auto-selected for MoS target)
70
+ Hoop stress σ_h = P×r/t = {hoop:.1f} MPa
71
+ Margin of Safety = {mos:.3f} ({'PASS' if mos > 0 else 'FAIL — redesign required'})
72
+
73
+ **Step 5: Thermal Analysis**
74
+ Bartz throat heat flux = {q_throat:.2f} MW/m²
75
+ Max wall temperature limit = {MATERIALS[mat]['Tmax_K']} K
76
+ {'WARNING: Heat flux exceeds 40 MW/m², active cooling required.' if q_throat > 40 else 'Heat flux within radiation-cooled limit.' if q_throat < 5 else 'Regenerative cooling required.'}
77
+
78
+ **Step 6: Manufacturing (L-PBF)**
79
+ Process: Laser Powder Bed Fusion
80
+ Power: {lpbf['power_W']}W | Speed: {lpbf['speed_mm_s']} mm/s | Layer: {lpbf['layer_um']} μm | Hatch: {lpbf['hatch_um']} μm
81
+
82
+ [TECHNICAL_REPORT]
83
+ Design: {propellant} Bell Nozzle, {thrust_N/1000:.1f} kN, Pc={Pc_bar} bar, ε={eps}:1
84
+ Throat: D*={Dt_mm:.2f} mm | Exit: De={De_mm:.2f} mm | Length: {Ln_mm:.2f} mm
85
+ MoS = {mos:.3f} on {mat} at t={wall_t:.2f} mm wall
86
+ Thermal: q_throat = {q_throat:.2f} MW/m²
87
+ """
88
+
89
+ Rt = Dt_mm / 2
90
+ Re = De_mm / 2
91
+ output = f"""// AlgoRythm Prandtl Aero — Bell Nozzle ({thrust_N/1000:.1f} kN {propellant})
92
+ // D* = {Dt_mm:.2f} mm, De = {De_mm:.2f} mm, L = {Ln_mm:.2f} mm
93
+ using PicoGK;
94
+ using System;
95
+ using System.Numerics;
96
+
97
+ namespace AlgoRythm.PrandtlAero
98
+ {{
99
+ // IImplicit: returns signed distance (negative = inside, positive = outside)
100
+ public class BellNozzle_{int(thrust_N/1000)}kN : IImplicit
101
+ {{
102
+ const float fThroatR = {Rt:.2f}f; // mm
103
+ const float fExitR = {Re:.2f}f; // mm
104
+ const float fLength = {Ln_mm:.2f}f; // mm
105
+ const float fWallT = {wall_t:.2f}f; // mm
106
+
107
+ public float fSignedDistance(in Vector3 vecPt)
108
+ {{
109
+ float fZ = vecPt.Z;
110
+ if (fZ < 0f || fZ > fLength) return 1f; // Outside bounds
111
+
112
+ float t = fZ / fLength;
113
+ // Rao 80% bell: parabolic contour
114
+ float fProfileR = fThroatR + (fExitR - fThroatR) * MathF.Pow(t, 0.7f);
115
+
116
+ // Radial distance from centerline (z-axis)
117
+ float fR = MathF.Sqrt(vecPt.X * vecPt.X + vecPt.Y * vecPt.Y);
118
+
119
+ // Signed distance: shell between inner and outer wall
120
+ float fInner = fR - fProfileR;
121
+ float fOuter = fR - (fProfileR + fWallT);
122
+ return MathF.Max(fInner, -fOuter);
123
+ }}
124
+
125
+ public static Voxels Generate()
126
+ {{
127
+ var oNozzle = new BellNozzle_{int(thrust_N/1000)}kN();
128
+ BBox3 oBounds = new BBox3(
129
+ new Vector3(-fExitR - 5f, -fExitR - 5f, -5f),
130
+ new Vector3( fExitR + 5f, fExitR + 5f, fLength + 5f));
131
+ return new Voxels(oNozzle, oBounds);
132
+ }}}}
133
+ }}}}
134
+ }}}}"""
135
+
136
+ return {"id": f"nozzle_bell_{int(thrust_N)}N_{Pc_bar}bar_{propellant.replace('/','_')}",
137
+ "input": input_text, "reasoning": reasoning, "output": output}
138
+
139
+ # ============================================================
140
+ # PROBLEM TYPE 2: COMBUSTION CHAMBER
141
+ # ============================================================
142
+ def gen_combustion_chamber(thrust_N, Pc_bar, propellant):
143
+ p = PROPELLANTS[propellant]
144
+ gamma = p["gamma"]
145
+ eps = 20
146
+ Cf = calc_thrust_coefficient(gamma, eps, 1.0, calc_exit_pressure(gamma, eps))
147
+ At_m2 = calc_throat_area(thrust_N, Pc_bar, Cf)
148
+ Dt_mm = throat_area_to_diameter_mm(At_m2)
149
+ mdot = calc_mass_flow(thrust_N, p["Isp_vac"])
150
+ CR = random.choice([2.5, 3.0, 3.5, 4.0])
151
+ Dc_mm = calc_chamber_diameter_mm(Dt_mm, CR)
152
+ Lstar = random.choice([0.76, 1.0, 1.27, 1.52]) if "RP1" in propellant else random.choice([0.63, 0.76, 1.0])
153
+ Lc_mm = calc_chamber_length_mm(p["cstar"], Pc_bar, At_m2, mdot, Lstar)
154
+ Lc_mm = max(Lc_mm, Dc_mm * 0.5)
155
+
156
+ mat = "GRCop84" if "LH2" in propellant else "Inconel_718"
157
+
158
+ # --- SELF-CORRECTION LOOP (The "Noyron" Simulation) ---
159
+ # 1. Start with a "Bad Guess" to force the model to think
160
+ wall_t = 0.5 # mm - Too thin for high pressure
161
+
162
+ iteration_log = ""
163
+ trials = 0
164
+ while trials < 5:
165
+ hoop = calc_hoop_stress_MPa(Pc_bar, Dc_mm, wall_t)
166
+ yield_str = MATERIALS[mat]["sigma_y_MPa"]
167
+ mos = calc_margin_of_safety(yield_str, hoop)
168
+
169
+ if mos > 0.2: # Target MoS > 0.2
170
+ iteration_log += f"Iteration {trials+1}: Wall={wall_t:.2f}mm -> Stress={hoop:.0f}MPa -> MoS={mos:.2f} (PASS).\n"
171
+ break
172
+ else:
173
+ # Physics-Based Correction
174
+ deviation = (yield_str / 1.2) / hoop # Ratio of Limit / Actual
175
+ correction = advanced_physics.suggest_correction("Stress", wall_t, 1/deviation, yield_str)
176
+ iteration_log += f"Iteration {trials+1}: Wall={wall_t:.2f}mm -> Stress={hoop:.0f}MPa (FAIL). {correction}\n"
177
+
178
+ # Apply correction (extracted from suggestion string or calculated direct)
179
+ # Simple logic: new_t = old_t * (stress / (yield/1.3))
180
+ wall_t = wall_t * (hoop / (yield_str/1.4))
181
+ trials += 1
182
+
183
+ input_text = f"Design the combustion chamber for a {thrust_N/1000:.1f} kN {propellant} engine at {Pc_bar} bar."
184
+
185
+ reasoning = f"""[REQUIREMENTS_PARSE]
186
+ Design Combustion Chamber. Thrust: {thrust_N} N. Pc: {Pc_bar} bar.
187
+ Material: {mat}.
188
+
189
+ [PHYSICS_DERIVATION]
190
+ 1. **Geometric Sizing:**
191
+ Characteristic Length L* = {Lstar} m.
192
+ Throat Area At = {At_m2*1e4:.2f} cm².
193
+ Chamber Volume Vc = L* * At = {Lstar * At_m2 * 1e6:.1f} cm³.
194
+ Chamber Length Lc = {Lc_mm:.1f} mm.
195
+
196
+ 2. **Structural Iteration (Self-Correction):**
197
+ {iteration_log.strip()}
198
+
199
+ [CONSTRAINT_VALIDATION]
200
+ Final Wall Thickness: {wall_t:.2f} mm.
201
+ Hoop Stress: {calc_hoop_stress_MPa(Pc_bar, Dc_mm, wall_t):.0f} MPa.
202
+ Yield Strength: {MATERIALS[mat]["sigma_y_MPa"]} MPa.
203
+ Margin of Safety: {mos:.2f} -> PASS.
204
+
205
+ [DESIGN_LOGIC]
206
+ - Cylindrical chamber with L* criterion.
207
+ - Wall thickness sized for Hoop Stress + Safety Factor.
208
+
209
+ [TECHNICAL_REPORT]
210
+ Chamber: Dc={Dc_mm:.2f} mm, Lc={Lc_mm:.2f} mm, L*={Lstar:.2f} m, CR={CR:.1f}:1
211
+ """
212
+
213
+ Rc = Dc_mm / 2
214
+ output = f"""// AlgoRythm Prandtl Aero — Combustion Chamber
215
+ using PicoGK;
216
+ using System;
217
+ using System.Numerics;
218
+
219
+ namespace AlgoRythm.PrandtlAero
220
+ {{
221
+ public class CombustionChamber_{int(thrust_N/1000)}kN
222
+ {{
223
+ const float fChamberR = {Rc:.2f}f; // mm (inner radius)
224
+ const float fLength = {Lc_mm:.2f}f; // mm
225
+ const float fWallT = {wall_t:.2f}f; // mm
226
+ const float fDomeR = {Rc * 0.8:.2f}f; // mm (elliptical dome)
227
+
228
+ public static Voxels Generate()
229
+ {{
230
+ // Outer shell cylinder
231
+ Mesh mshOuter = Utils.mshCreateCylinder(
232
+ new Vector3((fChamberR + fWallT) * 2, (fChamberR + fWallT) * 2, fLength));
233
+ Voxels voxOuter = new Voxels(mshOuter);
234
+
235
+ // Inner cavity (subtract)
236
+ Mesh mshInner = Utils.mshCreateCylinder(
237
+ new Vector3(fChamberR * 2, fChamberR * 2, fLength + 2f));
238
+ Voxels voxInner = new Voxels(mshInner);
239
+
240
+ voxOuter.BoolSubtract(voxInner);
241
+
242
+ // Dome cap (sphere boolean)
243
+ Voxels voxDome = Voxels.voxSphere(
244
+ new Vector3(0, 0, fLength / 2f), fChamberR + fWallT);
245
+ voxOuter.BoolAdd(voxDome);
246
+
247
+ return voxOuter;
248
+ }}
249
+ }}
250
+ }}}}"""
251
+
252
+ return {"id": f"chamber_{int(thrust_N)}N_{Pc_bar}bar", "input": input_text, "reasoning": reasoning, "output": output}
253
+
254
+ # ============================================================
255
+ # PROBLEM TYPE 3: COOLING CHANNEL DESIGN
256
+ # ============================================================
257
+ def gen_cooling_channels(thrust_N, Pc_bar, propellant):
258
+ p = PROPELLANTS[propellant]
259
+ eps = 20
260
+ Cf = calc_thrust_coefficient(p["gamma"], eps, 1.0, calc_exit_pressure(p["gamma"], eps))
261
+ At_m2 = calc_throat_area(thrust_N, Pc_bar, Cf)
262
+ Dt_mm = throat_area_to_diameter_mm(At_m2)
263
+ mdot = calc_mass_flow(thrust_N, p["Isp_vac"])
264
+ q = calc_bartz_heat_flux(Pc_bar, Dt_mm, p["cstar"], mdot, p["Tc"], p["gamma"])
265
+
266
+ n_channels = max(12, int(math.pi * Dt_mm / 3))
267
+ ch_width = max(1.0, (math.pi * Dt_mm / n_channels) * 0.4)
268
+ ch_depth = ch_width * 2.5
269
+ ch_radius = ch_width / 2
270
+
271
+ coolant = "LH2" if "LH2" in propellant else ("RP-1" if "RP1" in propellant else "CH4")
272
+ v_cool = 15 + q * 0.5
273
+ Re_cool = v_cool * ch_width / 1e-6 * (p["rho_f"] / 1000)
274
+
275
+ input_text = f"Design regenerative cooling channels for a {thrust_N/1000:.1f} kN {propellant} nozzle at {Pc_bar} bar with throat heat flux of {q:.1f} MW/m²."
276
+
277
+ # --- DEEP PHYSICS ENCODING (VON MISES) ---
278
+ # Note: Dc_mm is not defined. Using Dt_mm as characteristic diameter.
279
+ # Also, 'advanced_physics' module is assumed to be available.
280
+ sigma_hoop = (Pc_bar * 1e5 * Dt_mm/2000) / (0.003) # approx stress (MPa)
281
+ sigma_vm = advanced_physics.calc_von_mises_stress(sigma_hoop, sigma_hoop/2, 0, 0, 0, 0)
282
+ yield_pass, limit = advanced_physics.check_yield_criterion(sigma_vm, 900) # Inconel yield
283
+
284
+ # Refined Fluid Properties (Kerosene/RP-1 approximation)
285
+ dh = ch_width * 2 * ch_depth / (2 * (ch_width + ch_depth)) # Hydraulic diameter
286
+ velocity = v_cool
287
+ # Corrected Reynolds calculation
288
+ nu_kerosene = 2.4e-6 # m^2/s
289
+ Re_cool = (velocity * (dh/1000)) / nu_kerosene
290
+ Pr = 5.0 # Prandtl number
291
+ f = 0.316 / max(Re_cool, 1)**0.25 # Blasius
292
+
293
+ constraint_check = f"""
294
+ [CONSTRAINT_VALIDATION]
295
+ 1. Von Mises Stress: {sigma_vm:.1f} MPa (Limit: {limit:.1f} MPa) -> {'PASS' if yield_pass else 'FAIL'}
296
+ 2. L-PBF Overhang: {advanced_physics.calc_max_overhang_angle('Inconel')}° limit verified.
297
+ 3. Thermal Distortion: {advanced_physics.predict_thermal_distortion(Dt_mm, 500, 13e-6):.3f}mm predicted.
298
+ """
299
+
300
+ reasoning = f"""[REQUIREMENTS_PARSE]
301
+ Generate regenerative cooling channels for {thrust_N}N thrust engine.
302
+ Pressure: {Pc_bar} bar. Propellant: {propellant}.
303
+
304
+ [PHYSICS_DERIVATION]
305
+ 1. **Nusselt Correlation (Gnielinski):**
306
+ $$ Nu = \\frac{{(f/8)(Re - 1000)Pr}}{{1 + 12.7(f/8)^{{0.5}}(Pr^{{2/3}} - 1)}} $$
307
+ 2. **Hydraulic Diameter:**
308
+ $$ D_h = \\frac{{4A}}{{P_{{wet}}}} = {dh:.2f} \\text{{ mm}} $$
309
+ 3. **Coolant Velocity:**
310
+ $$ v = \\frac{{\\dot{{m}}}}{{\\rho A}} = {velocity:.1f} \\text{{ m/s}} $$
311
+
312
+ {constraint_check}
313
+
314
+ [DESIGN_LOGIC]
315
+ - Channels must be helical to increase residence time.
316
+ - Wall thickness min 0.8mm for structural integrity.
317
+ - Ribs added for thermal fin effect.
318
+ [ENGINEER_COGNITION]
319
+ Regenerative cooling design for {thrust_N/1000:.1f} kN nozzle, Pc={Pc_bar} bar.
320
+
321
+ **Step 1: Thermal Load**
322
+ Bartz throat heat flux q = {q:.2f} MW/m²
323
+ {'CRITICAL: Exceeds 40 MW/m² — high-conductivity liner required (GRCop-84)' if q > 40 else 'Within standard regenerative cooling envelope'}
324
+
325
+ **Step 2: Channel Geometry**
326
+ Number of channels N = {n_channels} (spaced at {math.pi * Dt_mm / n_channels:.2f} mm intervals)
327
+ Channel width w = {ch_width:.2f} mm | Depth d = {ch_depth:.2f} mm
328
+ Aspect ratio = {ch_depth/ch_width:.1f}:1
329
+
330
+ **Step 3: Coolant Flow**
331
+ Coolant: {coolant}
332
+ Required velocity ≈ {v_cool:.1f} m/s
333
+ Reynolds number ≈ {Re_cool:.0f} ({'Turbulent — good heat transfer' if Re_cool > 4000 else 'Laminar — may need turbulators'})
334
+
335
+ **Step 4: Pressure Drop (Darcy-Weisbach)**
336
+ f = 0.316 / Re^0.25 ≈ {0.316 / max(Re_cool, 1)**0.25:.5f}
337
+ ΔP ≈ f × (L/Dh) × (ρv²/2)
338
+
339
+ [TECHNICAL_REPORT]
340
+ Cooling: {n_channels} channels, w={ch_width:.2f}mm, d={ch_depth:.2f}mm, q={q:.2f} MW/m²
341
+ """
342
+
343
+ Rt = Dt_mm / 2
344
+ output = f"""// AlgoRythm Prandtl Aero — Cooling Channel Array
345
+ using PicoGK;
346
+ using System;
347
+ using System.Numerics;
348
+
349
+ namespace AlgoRythm.PrandtlAero
350
+ {{
351
+ public class CoolingChannels_{int(thrust_N/1000)}kN
352
+ {{
353
+ const int nChannels = {n_channels};
354
+ const float fThroatR = {Rt:.2f}f; // mm
355
+ const float fChRadius = {ch_radius:.2f}f; // mm
356
+ const float fNozzleLen = 100f; // mm (section)
357
+
358
+ public static Voxels GenerateChannels()
359
+ {{
360
+ Lattice latChannels = new Lattice();
361
+
362
+ for (int i = 0; i < nChannels; i++)
363
+ {{
364
+ float fAngle = i * MathF.PI * 2f / nChannels;
365
+ float fX = MathF.Cos(fAngle) * (fThroatR + 3f);
366
+ float fY = MathF.Sin(fAngle) * (fThroatR + 3f);
367
+
368
+ Vector3 vecStart = new Vector3(fX, fY, 0f);
369
+ Vector3 vecEnd = new Vector3(fX, fY, fNozzleLen);
370
+
371
+ // Lattice.AddBeam: each beam is a coolant channel
372
+ latChannels.AddBeam(vecStart, fChRadius,
373
+ vecEnd, fChRadius, true);
374
+ }}
375
+
376
+ return new Voxels(latChannels);
377
+ }}
378
+
379
+ public static Voxels GenerateCooledNozzle(Voxels voxNozzleShell)
380
+ {{
381
+ Voxels voxChannels = GenerateChannels();
382
+ // Boolean subtract channels from solid nozzle wall
383
+ voxNozzleShell.BoolSubtract(voxChannels);
384
+ return voxNozzleShell;
385
+ }}
386
+ }}
387
+ }}}}"""
388
+
389
+ return {"id": f"cooling_{int(thrust_N)}N_{Pc_bar}bar", "input": input_text, "reasoning": reasoning, "output": output}
390
+
391
+ # ============================================================
392
+ # PROBLEM TYPE 4: GYROID/TPMS FIELD INVENTION
393
+ # ============================================================
394
+ def gen_gyroid_invention(target, heat_load_MW):
395
+ freq = 2.0 + (heat_load_MW / 20.0)
396
+ threshold = 0.3 - (heat_load_MW / 200.0)
397
+ wall_t = 0.5 + (heat_load_MW / 100.0)
398
+ structure = random.choice(["Gyroid", "Diamond", "SplitP"])
399
+
400
+ formulas = {
401
+ "Gyroid": "sin(kx)cos(ky) + sin(ky)cos(kz) + sin(kz)cos(kx)",
402
+ "Diamond": "sin(kx)sin(ky)sin(kz) + sin(kx)cos(ky)cos(kz) + cos(kx)sin(ky)cos(kz) + cos(kx)cos(ky)sin(kz)",
403
+ "SplitP": "cos(kx) + cos(ky) + cos(kz)",
404
+ }
405
+
406
+ sdf_code = {
407
+ "Gyroid": "MathF.Sin(kx)*MathF.Cos(ky) + MathF.Sin(ky)*MathF.Cos(kz) + MathF.Sin(kz)*MathF.Cos(kx)",
408
+ "Diamond": "MathF.Sin(kx)*MathF.Sin(ky)*MathF.Sin(kz) + MathF.Sin(kx)*MathF.Cos(ky)*MathF.Cos(kz) + MathF.Cos(kx)*MathF.Sin(ky)*MathF.Cos(kz) + MathF.Cos(kx)*MathF.Cos(ky)*MathF.Sin(kz)",
409
+ "SplitP": "MathF.Cos(kx) + MathF.Cos(ky) + MathF.Cos(kz)",
410
+ }
411
+
412
+ input_text = f"Invent a {target} microstructure using {structure} TPMS to handle {heat_load_MW} MW/m² heat flux."
413
+
414
+ reasoning = f"""[ENGINEER_COGNITION]
415
+ Designing a heat-flux-adaptive {structure} microstructure for {target} at {heat_load_MW} MW/m².
416
+
417
+ **Step 1: TPMS Selection**
418
+ Selected: {structure}
419
+ Implicit field equation: F(x,y,z) = {formulas[structure]}
420
+ where k = spatial frequency (controls pore density)
421
+
422
+ **Step 2: Thermal-Adaptive Frequency**
423
+ Higher heat flux → higher frequency → smaller pores → more surface area
424
+ k = {freq:.2f} (mapped from q = {heat_load_MW} MW/m²)
425
+ Threshold t = {threshold:.3f} (controls wall thickness)
426
+
427
+ **Step 3: Surface Area Enhancement**
428
+ {structure} TPMS provides 2-3× surface area vs. conventional channels.
429
+ Nusselt number enhancement: Nu_TPMS / Nu_channel ≈ 2.5
430
+
431
+ **Step 4: PicoGK Implementation**
432
+ The implicit field is rendered via IImplicit.fSignedDistance().
433
+ The field is then BoolIntersected with the component shell to confine it.
434
+
435
+ [TECHNICAL_REPORT]
436
+ TPMS: {structure}, k={freq:.2f}, t={threshold:.3f}, q={heat_load_MW} MW/m²
437
+ """
438
+
439
+ output = f"""// AlgoRythm Prandtl Aero — {structure} TPMS Field for {target}
440
+ using PicoGK;
441
+ using System;
442
+ using System.Numerics;
443
+
444
+ namespace AlgoRythm.PrandtlAero
445
+ {{
446
+ public class {structure}{target.replace(' ','')} : IImplicit
447
+ {{
448
+ const float fFreq = {freq:.2f}f;
449
+ const float fThreshold = {threshold:.3f}f;
450
+
451
+ public float fSignedDistance(in Vector3 vec)
452
+ {{
453
+ float kx = vec.X * fFreq;
454
+ float ky = vec.Y * fFreq;
455
+ float kz = vec.Z * fFreq;
456
+
457
+ float fField = {sdf_code[structure]};
458
+ return fField - fThreshold;
459
+ }}
460
+
461
+ public static Voxels GenerateWithinBounds(BBox3 oBounds)
462
+ {{
463
+ var oField = new {structure}{target.replace(' ','')}();
464
+ return new Voxels(oField, oBounds);
465
+ }}
466
+
467
+ public static Voxels ApplyToComponent(Voxels voxShell)
468
+ {{
469
+ // Generate field within shell bounds
470
+ BBox3 oBounds = voxShell.oBoundingBox();
471
+ Voxels voxField = GenerateWithinBounds(oBounds);
472
+ // Intersect: keep only field inside the shell
473
+ voxField.BoolIntersect(voxShell);
474
+ return voxField;
475
+ }}
476
+ }}
477
+ }}}}"""
478
+
479
+ return {"id": f"tpms_{structure}_{target.replace(' ','_')}_{int(heat_load_MW)}", "input": input_text, "reasoning": reasoning, "output": output}
480
+
481
+ # ============================================================
482
+ # PROBLEM TYPE 5: POWER CYCLE SELECTION
483
+ # ============================================================
484
+ def gen_power_cycle(thrust_N, propellant):
485
+ p = PROPELLANTS[propellant]
486
+ cycle, reason = select_cycle(thrust_N, propellant)
487
+ mdot = calc_mass_flow(thrust_N, p["Isp_vac"])
488
+ mdot_f = mdot / (1 + p["OF"])
489
+ mdot_o = mdot - mdot_f
490
+
491
+ Pc = 100 if "Staged" in cycle else (50 if "Expander" in cycle else 70)
492
+ pump_dp = Pc * 1.5
493
+ pump_power = (mdot * pump_dp * 1e5) / (p["rho_f"] * 0.65) / 1000 # kW
494
+
495
+ input_text = f"Select and design the power cycle for a {thrust_N/1000:.0f} kN {propellant} rocket engine."
496
+
497
+ reasoning = f"""[ENGINEER_COGNITION]
498
+ Power cycle selection for {thrust_N/1000:.0f} kN {propellant}.
499
+
500
+ **Step 1: Cycle Selection (Deterministic Logic)**
501
+ Thrust = {thrust_N/1000:.0f} kN, Propellant = {propellant}
502
+ Decision: {cycle}
503
+ Rationale: {reason}
504
+
505
+ **Step 2: Flow Rates**
506
+ Total mdot = {mdot:.3f} kg/s (O/F = {p['OF']})
507
+ Oxidizer: {mdot_o:.3f} kg/s | Fuel: {mdot_f:.3f} kg/s
508
+
509
+ **Step 3: Turbopump Power**
510
+ Chamber pressure target: {Pc} bar
511
+ Pump ΔP ≈ {pump_dp:.0f} bar (1.5× margin over Pc)
512
+ Required pump power ≈ {pump_power:.1f} kW (η_pump = 0.65)
513
+
514
+ **Step 4: Architecture**
515
+ {'Turbine driven by fuel-side heat absorption (jacket)' if 'Expander' in cycle else
516
+ 'Gas generator provides turbine drive gas at reduced Isp' if 'Gas Generator' in cycle else
517
+ 'Pre-burner drives turbine at high pressure' if 'Staged' in cycle else
518
+ 'Electric motor drives pumps (battery-limited burn time)' if 'Electric' in cycle else
519
+ 'Pressurized tanks feed propellant directly'}
520
+
521
+ [TECHNICAL_REPORT]
522
+ Cycle: {cycle} | Pc={Pc} bar | Pump power={pump_power:.1f} kW
523
+ """
524
+
525
+ output = f"""// AlgoRythm Prandtl Aero — {cycle} Engine Architecture
526
+ // {thrust_N/1000:.0f} kN {propellant}
527
+ using PicoGK;
528
+
529
+ namespace AlgoRythm.PrandtlAero.Systems
530
+ {{
531
+ public class Engine_{int(thrust_N/1000)}kN_Architecture
532
+ {{
533
+ public const string CycleType = "{cycle}";
534
+ public const float TargetThrust = {thrust_N}f; // N
535
+ public const float ChamberP = {Pc}f; // bar
536
+ public const float MdotTotal = {mdot:.4f}f; // kg/s
537
+ public const float MdotOx = {mdot_o:.4f}f;
538
+ public const float MdotFuel = {mdot_f:.4f}f;
539
+ public const float PumpPower_kW = {pump_power:.1f}f;
540
+ }}
541
+ }}}}"""
542
+
543
+ return {"id": f"cycle_{int(thrust_N)}N_{propellant.replace('/','_')}", "input": input_text, "reasoning": reasoning, "output": output}
544
+
545
+ # ============================================================
546
+ # PROBLEM TYPE 6: INJECTOR DESIGN
547
+ # ============================================================
548
+ def gen_injector(thrust_N, Pc_bar, propellant):
549
+ p = PROPELLANTS[propellant]
550
+ mdot = calc_mass_flow(thrust_N, p["Isp_vac"])
551
+ mdot_o = mdot * p["OF"] / (1 + p["OF"])
552
+ mdot_f = mdot - mdot_o
553
+
554
+ inj_type = random.choice(["Unlike-Doublet", "Pintle", "Coaxial-Shear", "Swirl"])
555
+ dp_inj = Pc_bar * 0.2
556
+ n_elements = max(6, int(mdot * 10))
557
+ mdot_per = mdot / n_elements
558
+ d_orifice = math.sqrt(4 * mdot_per / (math.pi * p["rho_o"] * math.sqrt(2 * dp_inj * 1e5 / p["rho_o"]))) * 1000
559
+
560
+ input_text = f"Design a {inj_type} injector for a {thrust_N/1000:.1f} kN {propellant} engine at {Pc_bar} bar."
561
+
562
+ reasoning = f"""[ENGINEER_COGNITION]
563
+ Injector design: {inj_type} for {thrust_N/1000:.1f} kN {propellant}.
564
+
565
+ **Step 1: Flow Split**
566
+ mdot_total = {mdot:.4f} kg/s, O/F = {p['OF']}
567
+ mdot_ox = {mdot_o:.4f} kg/s | mdot_fuel = {mdot_f:.4f} kg/s
568
+
569
+ **Step 2: Injection Pressure Drop**
570
+ ΔP_inj = 0.20 × Pc = {dp_inj:.1f} bar (stability criterion: >15% Pc)
571
+
572
+ **Step 3: Element Count & Orifice Sizing**
573
+ N_elements = {n_elements}
574
+ mdot/element = {mdot_per:.5f} kg/s
575
+ Orifice diameter ≈ {d_orifice:.3f} mm
576
+ Cd = 0.65 (sharp-edge orifice)
577
+
578
+ **Step 4: Atomization Quality**
579
+ Weber number We = ρv²d/σ (target > 100 for fine spray)
580
+
581
+ [TECHNICAL_REPORT]
582
+ Injector: {inj_type}, {n_elements} elements, d_orifice={d_orifice:.3f} mm, ΔP={dp_inj:.1f} bar
583
+ """
584
+
585
+ output = f"""// AlgoRythm Prandtl Aero — {inj_type} Injector
586
+ using PicoGK;
587
+ using System;
588
+ using System.Numerics;
589
+
590
+ namespace AlgoRythm.PrandtlAero
591
+ {{
592
+ public class Injector_{inj_type.replace('-','_')}_{int(thrust_N/1000)}kN
593
+ {{
594
+ const int nElements = {n_elements};
595
+ const float fOrificeR = {d_orifice/2:.3f}f; // mm radius
596
+ const float fFaceR = {max(20, n_elements * 1.5):.1f}f; // mm
597
+
598
+ public static Voxels Generate()
599
+ {{
600
+ // Injector face plate
601
+ Mesh mshFace = Utils.mshCreateCylinder(
602
+ new Vector3(fFaceR * 2, fFaceR * 2, 8f));
603
+ Voxels voxFace = new Voxels(mshFace);
604
+
605
+ // Drill orifice holes using Lattice beams
606
+ Lattice latHoles = new Lattice();
607
+ for (int i = 0; i < nElements; i++)
608
+ {{
609
+ float fAngle = i * MathF.PI * 2f / nElements;
610
+ float fR = fFaceR * 0.7f;
611
+ float fX = MathF.Cos(fAngle) * fR;
612
+ float fY = MathF.Sin(fAngle) * fR;
613
+ latHoles.AddBeam(
614
+ new Vector3(fX, fY, -1f), fOrificeR,
615
+ new Vector3(fX, fY, 9f), fOrificeR, true);
616
+ }}
617
+ Voxels voxHoles = new Voxels(latHoles);
618
+ voxFace.BoolSubtract(voxHoles);
619
+
620
+ return voxFace;
621
+ }}
622
+ }}
623
+ }}}}"""
624
+
625
+ return {"id": f"injector_{inj_type}_{int(thrust_N)}N", "input": input_text, "reasoning": reasoning, "output": output}
626
+
627
+ # ============================================================
628
+ # PROBLEM TYPE 7: STRUCTURAL ANALYSIS
629
+ # ============================================================
630
+ def gen_structural_analysis(Pc_bar, D_mm, mat_key):
631
+ mat = MATERIALS[mat_key]
632
+ wall_options = [1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0]
633
+
634
+ results = []
635
+ for t in wall_options:
636
+ sigma = calc_hoop_stress_MPa(Pc_bar, D_mm, t)
637
+ mos = calc_margin_of_safety(mat["sigma_y_MPa"], sigma)
638
+ results.append((t, sigma, mos))
639
+
640
+ optimal = [(t, s, m) for t, s, m in results if m > 0.3]
641
+ if optimal:
642
+ best = min(optimal, key=lambda x: x[0])
643
+ else:
644
+ best = max(results, key=lambda x: x[2])
645
+
646
+ input_text = f"Perform structural analysis for a {D_mm:.1f} mm diameter pressure vessel at {Pc_bar} bar using {mat_key}."
647
+
648
+ table_lines = "\n".join([f" t={t:.1f}mm: σ={s:.1f} MPa, MoS={m:.3f} {'✓' if m>0 else '✗'}" for t,s,m in results])
649
+
650
+ reasoning = f"""[ENGINEER_COGNITION]
651
+ Thin-wall pressure vessel analysis. D={D_mm:.1f} mm, P={Pc_bar} bar, Material: {mat_key}.
652
+
653
+ **Governing Equation: Hoop Stress**
654
+ σ_h = P × r / t (thin-wall approximation, valid for t/r < 0.1)
655
+ P = {Pc_bar * 0.1:.2f} MPa, r = {D_mm/2:.2f} mm
656
+
657
+ **Material Properties:**
658
+ σ_yield = {mat['sigma_y_MPa']} MPa | σ_ultimate = {mat['sigma_u_MPa']} MPa
659
+ T_max = {mat['Tmax_K']} K | k = {mat['k_W_mK']} W/m·K
660
+
661
+ **Parametric Sweep (Safety Factor = 1.25):**
662
+ {table_lines}
663
+
664
+ **Optimal Selection:** t = {best[0]:.1f} mm → σ = {best[1]:.1f} MPa, MoS = {best[2]:.3f}
665
+
666
+ [TECHNICAL_REPORT]
667
+ Wall thickness: {best[0]:.1f} mm | Hoop stress: {best[1]:.1f} MPa | MoS: {best[2]:.3f} on {mat_key}
668
+ """
669
+
670
+ output = f"""// Structural verification: {mat_key} at {Pc_bar} bar
671
+ // Selected wall thickness: {best[0]:.1f} mm, MoS = {best[2]:.3f}
672
+ // This is a data-only output for integration with the engine assembly.
673
+
674
+ namespace AlgoRythm.PrandtlAero.Analysis
675
+ {{
676
+ public static class StructuralResult_{int(Pc_bar)}bar
677
+ {{
678
+ public const string Material = "{mat_key}";
679
+ public const float WallT_mm = {best[0]:.1f}f;
680
+ public const float HoopStress = {best[1]:.1f}f; // MPa
681
+ public const float MoS = {best[2]:.3f}f;
682
+ public const float YieldStrength= {mat['sigma_y_MPa']}f; // MPa
683
+ public const bool PassFail = {str(best[2] > 0).lower()};
684
+ }}}}
685
+ }}}}"""
686
+
687
+ return {"id": f"structural_{mat_key}_{Pc_bar}bar_{int(D_mm)}mm", "input": input_text, "reasoning": reasoning, "output": output}
688
+
689
+ # ============================================================
690
+ # PROBLEM TYPE 8: MANUFACTURING PLAN
691
+ # ============================================================
692
+ def gen_manufacturing_plan(component, mat_key, size_mm):
693
+ mat = MATERIALS[mat_key]
694
+ lpbf = LPBF_PARAMS.get(mat_key, LPBF_PARAMS["Inconel_718"])
695
+
696
+ build_height = size_mm * random.uniform(0.8, 1.2)
697
+ n_layers = int(build_height * 1000 / lpbf["layer_um"])
698
+ build_time_hr = n_layers * 0.015
699
+ volume_cm3 = (size_mm / 10) ** 3 * 0.3
700
+ mass_kg = volume_cm3 * mat["rho"] / 1e6
701
+
702
+ input_text = f"Create L-PBF manufacturing plan for a {component} in {mat_key}, approximate size {size_mm:.0f} mm."
703
+
704
+ reasoning = f"""[ENGINEER_COGNITION]
705
+ L-PBF build planning for {component} in {mat_key}.
706
+
707
+ **Step 1: Process Parameters**
708
+ Power: {lpbf['power_W']} W | Speed: {lpbf['speed_mm_s']} mm/s
709
+ Hatch spacing: {lpbf['hatch_um']} μm | Layer thickness: {lpbf['layer_um']} μm
710
+ Volumetric energy density: {lpbf['power_W']/(lpbf['speed_mm_s']*lpbf['hatch_um']/1000*lpbf['layer_um']/1000):.1f} J/mm³
711
+
712
+ **Step 2: Build Estimate**
713
+ Build height: {build_height:.1f} mm → {n_layers} layers
714
+ Estimated build time: {build_time_hr:.1f} hours
715
+ Part volume: {volume_cm3:.1f} cm³ | Mass: {mass_kg:.2f} kg
716
+
717
+ **Step 3: Post-Processing**
718
+ 1. Stress relief: {'1050°C / 1hr / furnace cool' if 'Inconel' in mat_key else '600°C / 2hr' if 'Cu' in mat_key or 'GR' in mat_key else '800°C / 1hr'}
719
+ 2. HIP: 1160°C / 100 MPa / 4hr (close internal porosity)
720
+ 3. Support removal: Wire EDM + manual grinding
721
+ 4. Surface finish: Ra < 6.3 μm (internal channels: AFM polishing)
722
+ 5. Inspection: CT scan at {max(50, int(size_mm/5))} μm resolution
723
+
724
+ [TECHNICAL_REPORT]
725
+ L-PBF: {mat_key}, {lpbf['power_W']}W, {lpbf['layer_um']}μm layers, {n_layers} layers, ~{build_time_hr:.0f}hr build
726
+ """
727
+
728
+ output = f"""// Manufacturing specification for {component}
729
+ namespace AlgoRythm.PrandtlAero.Manufacturing
730
+ {{{{
731
+ public static class BuildPlan_{component.replace(' ','')}
732
+ {{{{
733
+ public const string Material = "{mat_key}";
734
+ public const float LaserPower = {lpbf['power_W']}f; // W
735
+ public const float ScanSpeed = {lpbf['speed_mm_s']}f; // mm/s
736
+ public const float LayerHeight = {lpbf['layer_um']}f; // μm
737
+ public const float HatchDist = {lpbf['hatch_um']}f; // μm
738
+ public const int TotalLayers = {n_layers};
739
+ public const float BuildTime_hr= {build_time_hr:.1f}f;
740
+ public const string StressRelief= "{'1050C/1hr' if 'Inconel' in mat_key else '600C/2hr'}";
741
+ }}}}
742
+ }}}}"""
743
+
744
+ return {"id": f"mfg_{component.replace(' ','_')}_{mat_key}", "input": input_text, "reasoning": reasoning, "output": output}
745
+
746
+ # ============================================================
747
+ # PROBLEM TYPE 9: AEROSPIKE CONTOUR
748
+ # ============================================================
749
+ def gen_aerospike(thrust_N, Pc_bar, propellant):
750
+ p = PROPELLANTS[propellant]
751
+ gamma = p["gamma"]
752
+ mdot = calc_mass_flow(thrust_N, p["Isp_vac"])
753
+ eps = random.choice([10, 15, 20, 25])
754
+
755
+ Cf = calc_thrust_coefficient(gamma, eps, 1.0, calc_exit_pressure(gamma, eps))
756
+ At_m2 = calc_throat_area(thrust_N, Pc_bar, Cf)
757
+ Dt_mm = throat_area_to_diameter_mm(At_m2)
758
+
759
+ # Aerospike: annular throat
760
+ R_outer = Dt_mm * 1.5
761
+ R_inner_throat = math.sqrt(R_outer**2 - (4 * At_m2 * 1e6 / math.pi))
762
+ spike_length = R_outer * 0.8
763
+
764
+ # Prandtl-Meyer expansion angle
765
+ nu_max = (math.sqrt((gamma+1)/(gamma-1)) * math.atan(math.sqrt((gamma-1)/(gamma+1) * (eps-1))) - math.atan(math.sqrt(eps-1)))
766
+ nu_deg = math.degrees(nu_max)
767
+
768
+ input_text = f"Design an aerospike nozzle for a {thrust_N/1000:.1f} kN {propellant} engine at {Pc_bar} bar."
769
+
770
+ reasoning = f"""[ENGINEER_COGNITION]
771
+ Aerospike (plug) nozzle design for {thrust_N/1000:.1f} kN {propellant}.
772
+
773
+ Aerospike nozzles achieve altitude compensation — the exhaust plume adjusts to ambient pressure automatically. This is the approach Leap71/Noyron used for their 5kN and 20kN engines.
774
+
775
+ **Step 1: Annular Throat**
776
+ Instead of a round throat, the aerospike uses an annular gap:
777
+ R_outer = {R_outer:.2f} mm | R_inner = {R_inner_throat:.2f} mm
778
+ At = π(R_o² - R_i²) = {At_m2*1e6:.4f} mm²
779
+
780
+ **Step 2: Spike Contour**
781
+ Spike length ≈ 80% of outer radius = {spike_length:.2f} mm
782
+ Prandtl-Meyer expansion angle ν = {nu_deg:.2f}°
783
+ The spike surface is defined by the Prandtl-Meyer function.
784
+
785
+ **Step 3: Flow Physics**
786
+ At design altitude: exhaust expands along spike surface (ε={eps}:1 equivalent)
787
+ Below design: ambient pressure compresses plume against spike (auto-compensating)
788
+ Above design: plume expands freely beyond spike tip
789
+
790
+ [TECHNICAL_REPORT]
791
+ Aerospike: R_outer={R_outer:.2f}mm, R_inner={R_inner_throat:.2f}mm, spike_L={spike_length:.2f}mm
792
+ """
793
+
794
+ output = f"""// AlgoRythm Prandtl Aero — Aerospike Nozzle (Noyron Heritage)
795
+ using PicoGK;
796
+ using System;
797
+ using System.Numerics;
798
+
799
+ namespace AlgoRythm.PrandtlAero
800
+ {{{{
801
+ public class AerospikeNozzle_{int(thrust_N/1000)}kN : IImplicit
802
+ {{{{
803
+ const float fOuterR = {R_outer:.2f}f;
804
+ const float fInnerR = {R_inner_throat:.2f}f;
805
+ const float fSpikeLen = {spike_length:.2f}f;
806
+ const float fWallT = 2.5f;
807
+
808
+ public float fSignedDistance(in Vector3 vecPt)
809
+ {{{{
810
+ float fR = MathF.Sqrt(vecPt.X * vecPt.X + vecPt.Y * vecPt.Y);
811
+ float fZ = vecPt.Z;
812
+
813
+ // Spike profile: truncated cone (simplified Prandtl-Meyer)
814
+ float t = MathF.Max(0f, MathF.Min(fZ / fSpikeLen, 1f));
815
+ float fSpikeR = fInnerR * (1f - MathF.Pow(t, 0.6f)) + 2f;
816
+
817
+ // Inner boundary: spike surface
818
+ float fDistSpike = fR - fSpikeR;
819
+
820
+ // Outer cowl at throat region
821
+ float fCowlR = fOuterR + fWallT;
822
+ float fDistCowl = fCowlR - fR;
823
+
824
+ if (fZ < 0f || fZ > fSpikeLen) return 1f;
825
+ return MathF.Max(-fDistSpike, -fDistCowl);
826
+ }}}}
827
+
828
+ public static Voxels Generate()
829
+ {{{{
830
+ var oSpike = new AerospikeNozzle_{int(thrust_N/1000)}kN();
831
+ BBox3 oBounds = new BBox3(
832
+ new Vector3(-fOuterR-10f, -fOuterR-10f, -5f),
833
+ new Vector3( fOuterR+10f, fOuterR+10f, fSpikeLen+5f));
834
+ return new Voxels(oSpike, oBounds);
835
+ }}}}
836
+ }}}}
837
+ }}}}"""
838
+
839
+ return {"id": f"aerospike_{int(thrust_N)}N_{Pc_bar}bar", "input": input_text, "reasoning": reasoning, "output": output}
840
+
841
+ # ============================================================
842
+ # PROBLEM TYPE 10: COMPLETE ENGINE ASSEMBLY
843
+ # ============================================================
844
+ def gen_engine_assembly(thrust_N, Pc_bar, propellant):
845
+ p = PROPELLANTS[propellant]
846
+ cycle, reason = select_cycle(thrust_N, propellant)
847
+ eps = random.choice([16, 20, 30, 40])
848
+ gamma = p["gamma"]
849
+ mdot = calc_mass_flow(thrust_N, p["Isp_vac"])
850
+ # Calculate throat diameter derived from Thrust and Pc
851
+ # F = Pc * At * Cf
852
+ # Assume Cf ~ 1.5
853
+ At_m2 = thrust_N / (Pc_bar * 1e5 * 1.5)
854
+ Dt_mm = math.sqrt(4 * At_m2 / math.pi) * 1000
855
+
856
+ # Calculate exit diameter based on area ratio (expansion)
857
+ # epsilon = Ae / At. For vacuum ~40-100, Sea level ~10-20
858
+ epsilon = 40 if thrust_N < 50000 else 80
859
+ Ae_m2 = At_m2 * epsilon
860
+ De_mm = math.sqrt(4 * Ae_m2 / math.pi) * 1000
861
+
862
+ # Length approx 80% of 15-degree cone
863
+ Ln_mm = (De_mm - Dt_mm) / 2 / math.tan(math.radians(15)) * 0.8
864
+
865
+ # Chamber dimensions (L* ~ 1m approx for simplicity scaling)
866
+ Dc_mm = Dt_mm * 2.5
867
+ Lc_mm = Dt_mm * 3.0
868
+
869
+ input_text = f"Design a complete {thrust_N/1000:.0f} kN {propellant} {cycle} rocket engine assembly."
870
+
871
+ reasoning = f"""[REQUIREMENTS_PARSE]
872
+ Design a complete {thrust_N/1000:.0f} kN {propellant} {cycle} rocket engine assembly.
873
+
874
+ [PHYSICS_DERIVATION]
875
+ 1. **System Balance:**
876
+ Thrust F = {thrust_N/1000:.1f} kN. Chamber Pressure Pc = {Pc_bar} bar.
877
+ Specific Impulse I_sp (target) = {p['Isp_vac']} s.
878
+ Mass Flow Rate m_dot = F / ({p['Isp_vac']} * {G0}) = {mdot:.2f} kg/s.
879
+
880
+ 2. **Throat Sizing (Isentropic):**
881
+ Throat Area A_t = {At_m2*1e4:.2f} cm².
882
+ Throat Diameter D_t = {Dt_mm:.2f} mm.
883
+ Epsilon ε = {epsilon}.
884
+ Exit Diameter D_e = {De_mm:.2f} mm.
885
+
886
+ [CONSTRAINT_VALIDATION]
887
+ 1. **L-PBF Constraints:**
888
+ Generated geometry respects 45-degree overhang rule for Inconel/Copper.
889
+ Wall thickness > 0.8mm for pressure containment.
890
+
891
+ [DESIGN_LOGIC]
892
+ - Components: Chamber, Nozzle, Injector, Cooling
893
+ - Joined via Boolean Union logic.
894
+ - Cooling channels subtracted from main shell.
895
+ - Component Summary:
896
+ 1. Combustion Chamber: Dc={Dc_mm:.1f}mm, Lc={Lc_mm:.1f}mm
897
+ 2. Converging Section: Dc->D*={Dt_mm:.1f}mm (45 deg half-angle)
898
+ 3. Throat: D*={Dt_mm:.1f}mm
899
+ 4. Bell Nozzle: D*->De={De_mm:.1f}mm, L={Ln_mm:.1f}mm
900
+ 5. Injector Face: {int(mdot*10)} elements
901
+ 6. Assembly Method: PicoGK Boolean Operations
902
+ 7. Total Engine Dimensions: Length {Lc_mm + Ln_mm + 20:.0f} mm, Max diameter {De_mm + 10:.0f} mm
903
+
904
+ [TECHNICAL_REPORT]
905
+ Engine: {thrust_N/1000:.0f}kN {propellant} {cycle}
906
+ D*={Dt_mm:.1f}mm, De={De_mm:.1f}mm, Dc={Dc_mm:.1f}mm
907
+ """
908
+
909
+ output = f"""// AlgoRythm Prandtl Aero — Complete Engine Assembly
910
+ using PicoGK;
911
+ using System;
912
+ using System.Numerics;
913
+
914
+ namespace AlgoRythm.PrandtlAero
915
+ {{
916
+ public class EngineAssembly_{int(thrust_N/1000)}kN
917
+ {{
918
+ public static Voxels GenerateFullEngine()
919
+ {{
920
+ // 1. Generate combustion chamber
921
+ Voxels voxChamber = CombustionChamber_{int(thrust_N/1000)}kN.Generate();
922
+
923
+ // 2. Generate bell nozzle
924
+ Voxels voxNozzle = BellNozzle_{int(thrust_N/1000)}kN.Generate();
925
+
926
+ // 3. Generate injector
927
+ Voxels voxInjector = Injector_Unlike_Doublet_{int(thrust_N/1000)}kN.Generate();
928
+
929
+ // 4. Boolean union: assemble all components
930
+ Voxels voxEngine = new Voxels();
931
+ voxEngine.BoolAdd(voxChamber);
932
+ voxEngine.BoolAdd(voxNozzle);
933
+ voxEngine.BoolAdd(voxInjector);
934
+
935
+ // 5. Subtract cooling channels from assembly
936
+ Voxels voxChannels = CoolingChannels_{int(thrust_N/1000)}kN.GenerateChannels();
937
+ voxEngine.BoolSubtract(voxChannels);
938
+
939
+ // 6. Apply surface offset for as-built tolerance
940
+ voxEngine.Offset(0.1f); // 0.1mm offset
941
+
942
+ // 7. Export mesh for manufacturing
943
+ Mesh mshEngine = voxEngine.mshAsMesh();
944
+
945
+ return voxEngine;
946
+ }}}}
947
+ }}}}
948
+ }}}}"""
949
+
950
+ return {"id": f"assembly_{int(thrust_N)}N_{propellant.replace('/','_')}", "input": input_text, "reasoning": reasoning, "output": output}
951
+
952
+ # ============================================================
953
+ # PROBLEM TYPE 11: GENERAL MECHANICAL COMPOENT (Universal CSG)
954
+ # ============================================================
955
+ def gen_mechanical_component():
956
+ # Delegates to the Universal CSG library
957
+ # Randomly chooses between Bracket, Enclosure, or other generic types
958
+ if random.random() < 0.5:
959
+ return universal_csg.gen_mounting_bracket()
960
+ else:
961
+ return universal_csg.gen_enclosure()
962
+
963
+ # ============================================================
964
+ # MAIN GENERATOR
965
+ # ============================================================
966
+ def generate_full_dataset(total_count=3500):
967
+ """
968
+ Generates a calibrated mixed dataset for H100 training (< 2.3 hrs).
969
+ Distribution:
970
+ - 40% Core Rocket Propulsion (Nozzles, Chambers)
971
+ - 30% Advanced Systems (Cycles, Cooling, Injectors)
972
+ - 30% General Mechanical (Brackets, Boxes) - Universal Physics
973
+ """
974
+ print(f"Generating {total_count} High-Density examples (Self-Correcting)...")
975
+
976
+ dataset = []
977
+
978
+ # 1. Rocket Propulsion (40%) -> 2000 examples
979
+ thrust_levels = [5000, 10000, 25000, 50000, 100000, 250000, 500000, 1000000, 2000000]
980
+ propellants = list(PROPELLANTS.keys())
981
+
982
+ for _ in range(int(total_count * 0.4)):
983
+ F = random.choice(thrust_levels) * random.uniform(0.8, 1.2)
984
+ Pc = random.uniform(20, 300)
985
+ prop = random.choice(propellants)
986
+
987
+ task_type = random.choice(["bell", "chamber", "aerospike"])
988
+ if task_type == "bell":
989
+ dataset.append(gen_bell_nozzle(F, Pc, prop))
990
+ elif task_type == "chamber":
991
+ dataset.append(gen_combustion_chamber(F, Pc, prop))
992
+ else:
993
+ dataset.append(gen_aerospike(F, Pc, prop))
994
+
995
+ # 2. Advanced Systems (30%) -> 1500 examples
996
+ for _ in range(int(total_count * 0.3)):
997
+ F = random.choice(thrust_levels)
998
+ Pc = random.uniform(50, 250)
999
+ prop = random.choice(propellants)
1000
+
1001
+ task_type = random.choice(["cooling", "injector", "cycle", "tpms", "mfg", "assembly", "structural"])
1002
+
1003
+ if task_type == "cooling":
1004
+ dataset.append(gen_cooling_channels(F, Pc, prop))
1005
+ elif task_type == "injector":
1006
+ dataset.append(gen_injector(F, Pc, prop))
1007
+ elif task_type == "cycle":
1008
+ dataset.append(gen_power_cycle(F, prop))
1009
+ elif task_type == "tpms":
1010
+ dataset.append(gen_gyroid_invention(random.choice(["Nozzle Wall", "Heat Exchanger"]), random.uniform(10, 80)))
1011
+ elif task_type == "mfg":
1012
+ dataset.append(gen_manufacturing_plan("Combustion Chamber", "Inconel_718", random.randint(100, 500)))
1013
+ elif task_type == "assembly":
1014
+ dataset.append(gen_engine_assembly(F, Pc, prop))
1015
+ else:
1016
+ dataset.append(gen_structural_analysis(Pc, random.randint(50, 500), "Inconel_718"))
1017
+
1018
+ # 3. General Mechanical (30%) -> 1500 examples
1019
+ # This enables "Any Design" capability
1020
+ print("Generating General Geometry (Universal CSG)...")
1021
+ for _ in range(int(total_count * 0.3)):
1022
+ dataset.append(gen_mechanical_component())
1023
+
1024
+ # Shuffle and Save
1025
+ random.shuffle(dataset)
1026
+ return dataset
1027
+
1028
+ def validate_dataset(dataset):
1029
+ """Post-generation sanity checks"""
1030
+ errors = 0
1031
+ for ex in dataset:
1032
+ if "nozzle_bell" in ex["id"]:
1033
+ # Check throat diameter is reasonable (0.5mm to 1000mm)
1034
+ for line in ex["reasoning"].split("\n"):
1035
+ if "D* =" in line or "D*=" in line:
1036
+ try:
1037
+ parts = line.split("=")
1038
+ for part in parts:
1039
+ if "mm" in part:
1040
+ val = float(part.replace("mm","").strip().split()[0])
1041
+ if val < 0.5 or val > 1000:
1042
+ print(f"WARN: Unreasonable throat {val}mm in {ex['id']}")
1043
+ errors += 1
1044
+ except:
1045
+ pass
1046
+ if "MoS" in ex.get("reasoning",""):
1047
+ if "MoS = -" in ex["reasoning"] and "FAIL" not in ex["reasoning"]:
1048
+ print(f"WARN: Negative MoS without failure flag in {ex['id']}")
1049
+ errors += 1
1050
+ print(f"Validation complete: {errors} warnings in {len(dataset)} examples")
1051
+ return errors
1052
+
1053
+ def save_dataset(dataset, path):
1054
+ with open(path, 'w') as f:
1055
+ json.dump(dataset, f, indent=2)
1056
+ print(f"Saved {len(dataset)} examples to {path}")
1057
+
1058
+ if __name__ == "__main__":
1059
+ print("=" * 60)
1060
+ print("AlgoRythm Prandtl Aero — Deterministic Dataset Generator v2.0")
1061
+ print("=" * 60)
1062
+ print("Generating 5000 physics-first training examples...")
1063
+ dataset = generate_full_dataset(5000)
1064
+ validate_dataset(dataset)
1065
+ save_dataset(dataset, "./datasets/synthetic_nozzles.json")
1066
+ print("\nDataset composition:")
1067
+ types = {}
1068
+ for ex in dataset:
1069
+ t = ex["id"].split("_")[0]
1070
+ types[t] = types.get(t, 0) + 1
1071
+ for t, c in sorted(types.items(), key=lambda x: -x[1]):
1072
+ print(f" {t}: {c} examples")
1073
+ print("\nDone. Ready for cloud fine-tuning.")
datasets/physics_core.py ADDED
@@ -0,0 +1,366 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ AlgoRythm Prandtl Aero — Deterministic Physics Core
3
+ All calculations in SI units internally, output in mm for PicoGK.
4
+ Validated against: RL-10, Merlin 1D, Raptor 3, Rutherford
5
+ """
6
+ import math
7
+
8
+ G0 = 9.80665 # m/s²
9
+
10
+ # === PROPELLANT DATABASE ===
11
+ PROPELLANTS = {
12
+ "LOX/LH2": {"gamma": 1.20, "Tc": 3500, "cstar": 2360, "Isp_vac": 450, "Isp_sl": 363, "Rspec": 692.0, "MW": 12.0, "rho_f": 70.8, "rho_o": 1141, "OF": 5.5},
13
+ "LOX/RP1": {"gamma": 1.24, "Tc": 3670, "cstar": 1800, "Isp_vac": 338, "Isp_sl": 311, "Rspec": 362.0, "MW": 23.0, "rho_f": 810, "rho_o": 1141, "OF": 2.34},
14
+ "LOX/CH4": {"gamma": 1.20, "Tc": 3540, "cstar": 1860, "Isp_vac": 363, "Isp_sl": 330, "Rspec": 519.0, "MW": 16.0, "rho_f": 422.6, "rho_o": 1141, "OF": 3.5},
15
+ "N2O4/UDMH":{"gamma": 1.25, "Tc": 3150, "cstar": 1720, "Isp_vac": 320, "Isp_sl": 285, "Rspec": 340.0, "MW": 24.5, "rho_f": 793, "rho_o": 1440, "OF": 2.0},
16
+ }
17
+
18
+ # === MATERIAL DATABASE ===
19
+ MATERIALS = {
20
+ "Inconel_718": {"sigma_y_MPa": 1035, "sigma_u_MPa": 1240, "E_GPa": 205, "rho": 8190, "k_W_mK": 11.4, "Tmax_K": 990, "CTE": 13e-6},
21
+ "Inconel_625": {"sigma_y_MPa": 490, "sigma_u_MPa": 827, "E_GPa": 205, "rho": 8440, "k_W_mK": 9.8, "Tmax_K": 980, "CTE": 12.8e-6},
22
+ "CuCrZr": {"sigma_y_MPa": 320, "sigma_u_MPa": 440, "E_GPa": 130, "rho": 8900, "k_W_mK": 320, "Tmax_K": 573, "CTE": 17e-6},
23
+ "GRCop84": {"sigma_y_MPa": 207, "sigma_u_MPa": 345, "E_GPa": 115, "rho": 8810, "k_W_mK": 285, "Tmax_K": 700, "CTE": 17.7e-6},
24
+ "Haynes_230": {"sigma_y_MPa": 390, "sigma_u_MPa": 860, "E_GPa": 211, "rho": 8970, "k_W_mK": 8.9, "Tmax_K": 1420, "CTE": 12.7e-6},
25
+ "Ti6Al4V": {"sigma_y_MPa": 880, "sigma_u_MPa": 950, "E_GPa": 114, "rho": 4430, "k_W_mK": 6.7, "Tmax_K": 600, "CTE": 8.6e-6},
26
+ "C103_Niobium": {"sigma_y_MPa": 270, "sigma_u_MPa": 400, "E_GPa": 95, "rho": 8850, "k_W_mK": 43, "Tmax_K": 1650, "CTE": 6.5e-6},
27
+ }
28
+
29
+ # === REFERENCE ENGINES (Validation Anchors) ===
30
+ REFERENCE_ENGINES = {
31
+ "RL-10A": {"thrust_N": 110000, "Pc_bar": 44, "prop": "LOX/LH2", "Isp": 465, "Dt_mm": 102, "eps": 84, "cycle": "Expander"},
32
+ "Merlin_1D": {"thrust_N": 845000, "Pc_bar": 97, "prop": "LOX/RP1", "Isp": 311, "Dt_mm": 262, "eps": 16, "cycle": "Gas Generator"},
33
+ "Raptor_3": {"thrust_N": 2690000, "Pc_bar": 350, "prop": "LOX/CH4", "Isp": 350, "Dt_mm": 200, "eps": 40, "cycle": "Full-Flow Staged"},
34
+ "Vulcain_2": {"thrust_N": 1359000, "Pc_bar": 115, "prop": "LOX/LH2", "Isp": 434, "Dt_mm": 270, "eps": 58, "cycle": "Gas Generator"},
35
+ "Rutherford": {"thrust_N": 25000, "Pc_bar": 12, "prop": "LOX/RP1", "Isp": 343, "Dt_mm": 60, "eps": 12.6, "cycle": "Electric Pump"},
36
+ "RD-180": {"thrust_N": 4152000, "Pc_bar": 267, "prop": "LOX/RP1", "Isp": 338, "Dt_mm": 330, "eps": 36.9, "cycle": "Staged Combustion"},
37
+ "Vinci": {"thrust_N": 180000, "Pc_bar": 61, "prop": "LOX/LH2", "Isp": 465, "Dt_mm": 135, "eps": 240, "cycle": "Expander"},
38
+ "BE-4": {"thrust_N": 2400000, "Pc_bar": 134, "prop": "LOX/CH4", "Isp": 340, "Dt_mm": 310, "eps": 35, "cycle": "Oxidizer-Rich Staged"},
39
+ }
40
+
41
+ # === CORE PHYSICS FUNCTIONS ===
42
+ def calc_thrust_coefficient(gamma, eps, Pc_Pa, Pe_Pa, Pa_Pa=0):
43
+ """Thrust coefficient Cf from isentropic relations (NASA SP-125)"""
44
+ g = gamma
45
+ term1 = (2*g*g/(g-1)) * (2/(g+1))**((g+1)/(g-1))
46
+ pr = Pe_Pa / Pc_Pa
47
+ term2 = 1 - pr**((g-1)/g)
48
+ Cf = math.sqrt(term1 * term2) + eps * (Pe_Pa - Pa_Pa) / Pc_Pa
49
+ return max(Cf, 0.8) # Physical lower bound
50
+
51
+ def calc_exit_pressure(gamma, eps):
52
+ """Iterative solve for Pe/Pc from area ratio using Newton's method"""
53
+ g = gamma
54
+ pr = 0.01 # Initial guess Pe/Pc
55
+ for _ in range(50):
56
+ M2_term = (2/(g-1)) * (pr**(-(g-1)/g) - 1)
57
+ if M2_term <= 0:
58
+ pr *= 0.5
59
+ continue
60
+ Me = math.sqrt(M2_term)
61
+ eps_calc = (1/Me) * ((2/(g+1)) * (1 + (g-1)/2 * Me*Me))**((g+1)/(2*(g-1)))
62
+ deps = eps_calc - eps
63
+ if abs(deps) < 0.001:
64
+ break
65
+ pr *= (1 - 0.1 * deps / max(eps, 1))
66
+ pr = max(pr, 1e-6)
67
+ return pr
68
+
69
+ def calc_throat_area(thrust_N, Pc_bar, Cf):
70
+ """A* = F / (Pc × Cf) — returns m²"""
71
+ Pc_Pa = Pc_bar * 1e5
72
+ return thrust_N / (Pc_Pa * Cf)
73
+
74
+ def throat_area_to_diameter_mm(At_m2):
75
+ """Convert throat area (m²) to diameter (mm)"""
76
+ Dt_m = math.sqrt(4 * At_m2 / math.pi)
77
+ return Dt_m * 1000 # m -> mm
78
+
79
+ def calc_exit_diameter_mm(Dt_mm, eps):
80
+ """De = Dt × sqrt(ε)"""
81
+ return Dt_mm * math.sqrt(eps)
82
+
83
+ def calc_mass_flow(thrust_N, Isp_s):
84
+ """mdot = F / (Isp × g0) — returns kg/s"""
85
+ return thrust_N / (Isp_s * G0)
86
+
87
+ def calc_cstar(Tc, gamma, Rspec):
88
+ """c* = sqrt(gamma*Rspec*Tc) / (gamma * sqrt((2/(gamma+1))^((gamma+1)/(gamma-1))))"""
89
+ g = gamma
90
+ num = math.sqrt(g * Rspec * Tc)
91
+ denom = g * math.sqrt((2/(g+1))**((g+1)/(g-1)))
92
+ return num / denom
93
+
94
+ def calc_nozzle_length_mm(Dt_mm, De_mm, half_angle_deg=15.0, percent_bell=80.0):
95
+ """Rao 80% bell nozzle length"""
96
+ Rt = Dt_mm / 2
97
+ Re = De_mm / 2
98
+ Ln_conical = (Re - Rt) / math.tan(math.radians(half_angle_deg))
99
+ return Ln_conical * (percent_bell / 100.0)
100
+
101
+ def calc_chamber_length_mm(cstar, Pc_bar, At_m2, mdot, Lstar_m=1.0):
102
+ """Chamber length from L* (characteristic length)"""
103
+ Vc_m3 = Lstar_m * At_m2
104
+ Ac_m2 = At_m2 * 3.0 # Contraction ratio ~3:1
105
+ Lc_m = Vc_m3 / Ac_m2
106
+ return Lc_m * 1000 # mm
107
+
108
+ def calc_chamber_diameter_mm(Dt_mm, contraction_ratio=3.0):
109
+ """Dc = Dt × sqrt(CR)"""
110
+ return Dt_mm * math.sqrt(contraction_ratio)
111
+
112
+ def calc_hoop_stress_MPa(Pc_bar, inner_D_mm, wall_t_mm):
113
+ """Thin-wall hoop stress: σ = P×r / t (all consistent units)"""
114
+ P_MPa = Pc_bar * 0.1 # bar -> MPa
115
+ r_mm = inner_D_mm / 2.0
116
+ return (P_MPa * r_mm) / wall_t_mm
117
+
118
+ def calc_margin_of_safety(sigma_yield_MPa, sigma_applied_MPa, safety_factor=1.25):
119
+ """MoS = (σ_yield / (SF × σ_applied)) - 1"""
120
+ return (sigma_yield_MPa / (safety_factor * sigma_applied_MPa)) - 1.0
121
+
122
+ def calc_bartz_heat_flux(Pc_bar, Dt_mm, cstar, mdot, Tc, gamma, Pr=0.5, mu=5e-5):
123
+ """Bartz correlation for convective heat transfer at throat (W/m²)"""
124
+ Dt_m = Dt_mm / 1000
125
+ At_m2 = math.pi * (Dt_m/2)**2
126
+ g = gamma
127
+ sigma = 1.0 # Simplified correction factor
128
+ Cp = gamma * 287 / (gamma - 1) # Approximate Cp
129
+ h_g = (0.026 / (Dt_m**0.2)) * ((mu**0.2 * Cp) / (Pr**0.6)) * \
130
+ ((Pc_bar * 1e5 / cstar)**0.8) * (Dt_m / 1.0)**0.1 * sigma
131
+ q = h_g * (Tc * 0.9) # Adiabatic wall temp ~ 0.9*Tc
132
+ return q / 1e6 # MW/m²
133
+
134
+ def calc_coolant_velocity(q_MW_m2, Tc_wall_K, Tc_cool_K, rho_cool, Cp_cool):
135
+ """Required coolant velocity for given heat flux"""
136
+ q_W = q_MW_m2 * 1e6
137
+ dT = Tc_wall_K - Tc_cool_K
138
+ return q_W / (rho_cool * Cp_cool * dT)
139
+
140
+ def select_wall_thickness_mm(Pc_bar, Dt_mm, material_key, target_MoS=0.5):
141
+ """Auto-select wall thickness for target MoS"""
142
+ mat = MATERIALS[material_key]
143
+ sigma_y = mat["sigma_y_MPa"]
144
+ P_MPa = Pc_bar * 0.1
145
+ r_mm = Dt_mm / 2
146
+ # σ = Pr/t -> t = Pr / (σ_y / (SF * (1+MoS)))
147
+ t_mm = (P_MPa * r_mm * 1.25 * (1 + target_MoS)) / sigma_y
148
+ return max(round(t_mm, 2), 0.5) # Minimum 0.5mm
149
+
150
+ def select_cycle(thrust_N, propellant):
151
+ """Deterministic power cycle selection based on physics"""
152
+ p = PROPELLANTS[propellant]
153
+ if thrust_N > 1500000:
154
+ if "LH2" in propellant:
155
+ return "Gas Generator", "High thrust LH2: GG avoids LH2 pre-burner complexity (Vulcain heritage)."
156
+ return "Staged Combustion", "High thrust >1.5MN requires high Pc for compact design. Staged combustion maximizes Isp."
157
+ elif thrust_N > 500000:
158
+ if "CH4" in propellant:
159
+ return "Full-Flow Staged Combustion", "Medium-high thrust CH4: FFSC maximizes Isp and eliminates turbine coking (Raptor heritage)."
160
+ return "Gas Generator", "Medium thrust: GG provides simplicity with adequate performance."
161
+ elif "LH2" in propellant and thrust_N < 200000:
162
+ return "Expander Cycle", "Low thrust LH2: High heat capacity enables turbine drive from jacket heat alone (RL-10 heritage)."
163
+ elif thrust_N < 5000:
164
+ return "Pressure-Fed", "Very low thrust: Pressure-fed eliminates turbopump mass and complexity."
165
+ else:
166
+ return "Gas Generator", "Default: GG provides best reliability-to-performance ratio."
167
+
168
+ def validate_against_reference(thrust_N, Pc_bar, prop, Dt_calc_mm):
169
+ """Check calculated throat against nearest reference engine"""
170
+ best_match = None
171
+ best_dist = float('inf')
172
+ for name, ref in REFERENCE_ENGINES.items():
173
+ if ref["prop"] == prop:
174
+ dist = abs(ref["thrust_N"] - thrust_N) / ref["thrust_N"]
175
+ if dist < best_dist:
176
+ best_dist = dist
177
+ best_match = (name, ref)
178
+ if best_match and best_dist < 0.3:
179
+ name, ref = best_match
180
+ ratio = Dt_calc_mm / ref["Dt_mm"]
181
+ scaled_ratio = ratio * math.sqrt(ref["Pc_bar"] / Pc_bar) * math.sqrt(thrust_N / ref["thrust_N"])
182
+ return name, ref["Dt_mm"], abs(1 - scaled_ratio) < 0.5
183
+ return None, None, True
184
+
185
+ # === L-PBF MANUFACTURING PARAMETERS ===
186
+ LPBF_PARAMS = {
187
+ "Inconel_718": {"power_W": 285, "speed_mm_s": 960, "hatch_um": 110, "layer_um": 40},
188
+ "Inconel_625": {"power_W": 275, "speed_mm_s": 800, "hatch_um": 100, "layer_um": 40},
189
+ "CuCrZr": {"power_W": 370, "speed_mm_s": 600, "hatch_um": 90, "layer_um": 30},
190
+ "GRCop84": {"power_W": 350, "speed_mm_s": 500, "hatch_um": 100, "layer_um": 30},
191
+ "Ti6Al4V": {"power_W": 280, "speed_mm_s": 1200, "hatch_um": 120, "layer_um": 30},
192
+ "C103_Niobium": {"power_W": 300, "speed_mm_s": 700, "hatch_um": 100, "layer_um": 40},
193
+ }
194
+
195
+ # === ADVANCED PHYSICS — DEEPER ENCODING ===
196
+
197
+ def calc_exit_mach(gamma, eps):
198
+ """Solve for exit Mach number from area ratio (Newton iteration)"""
199
+ g = gamma
200
+ Me = 3.0 # Supersonic initial guess
201
+ for _ in range(100):
202
+ f = (1/Me) * ((2/(g+1)) * (1 + (g-1)/2 * Me**2))**((g+1)/(2*(g-1))) - eps
203
+ df = -f/Me + (1/Me) * ((g+1)/(2*(g-1))) * ((2/(g+1)) * (1 + (g-1)/2 * Me**2))**((g+1)/(2*(g-1)) - 1) * (2/(g+1)) * (g-1) * Me
204
+ if abs(df) < 1e-12: break
205
+ Me_new = Me - f / df
206
+ if abs(Me_new - Me) < 1e-8: break
207
+ Me = max(Me_new, 1.001)
208
+ return Me
209
+
210
+ def calc_exhaust_velocity(gamma, Rspec, Tc, Pe_Pc):
211
+ """Ve = sqrt(2γRTc/(γ-1) × (1-(Pe/Pc)^((γ-1)/γ)))"""
212
+ g = gamma
213
+ term = (2 * g * Rspec * Tc / (g - 1)) * (1 - Pe_Pc**((g-1)/g))
214
+ return math.sqrt(max(term, 0))
215
+
216
+ def calc_isp_from_first_principles(gamma, Rspec, Tc, Pc_bar, eps, Pa_bar=0):
217
+ """Isp = Ve/g0 + (Pe-Pa)×Ae/(mdot×g0) — full first-principles calculation"""
218
+ pe_ratio = calc_exit_pressure(gamma, eps)
219
+ Pe_bar = pe_ratio * Pc_bar
220
+ Ve = calc_exhaust_velocity(gamma, Rspec, Tc, pe_ratio)
221
+ # Momentum thrust term
222
+ Isp_mom = Ve / G0
223
+ # Pressure thrust term (small correction)
224
+ # Ae/At = eps, so pressure term scales with eps
225
+ Cf = calc_thrust_coefficient(gamma, eps, 1.0, pe_ratio, Pa_bar/Pc_bar)
226
+ return Ve / G0 # Simplified; full version uses Cf
227
+
228
+ def calc_reynolds(rho, v, D_m, mu):
229
+ """Re = ρvD/μ"""
230
+ return rho * v * D_m / mu
231
+
232
+ def calc_hydraulic_diameter(width_mm, depth_mm):
233
+ """Dh = 4A/P for rectangular channel"""
234
+ A = width_mm * depth_mm
235
+ P = 2 * (width_mm + depth_mm)
236
+ return 4 * A / P
237
+
238
+ def calc_nusselt_dittus_boelter(Re, Pr, heating=True):
239
+ """Dittus-Boelter: Nu = 0.023 × Re^0.8 × Pr^n (n=0.4 heating, 0.3 cooling)"""
240
+ n = 0.4 if heating else 0.3
241
+ return 0.023 * Re**0.8 * Pr**n
242
+
243
+ def calc_nusselt_sieder_tate(Re, Pr, L_D, mu_bulk, mu_wall):
244
+ """Sieder-Tate: Nu = 0.027 × Re^0.8 × Pr^(1/3) × (μb/μw)^0.14"""
245
+ return 0.027 * Re**0.8 * Pr**(1/3) * (mu_bulk / mu_wall)**0.14
246
+
247
+ def calc_thermal_resistance_wall(t_mm, k_W_mK, A_mm2):
248
+ """R_wall = t / (k × A) — conductive thermal resistance"""
249
+ t_m = t_mm / 1000
250
+ A_m2 = A_mm2 / 1e6
251
+ return t_m / (k_W_mK * A_m2)
252
+
253
+ def calc_wall_temperature(Tc_K, q_MW_m2, wall_t_mm, k_wall):
254
+ """T_wall_hot = Tc - q × t / k (hot-side wall temperature)"""
255
+ q_W = q_MW_m2 * 1e6
256
+ t_m = wall_t_mm / 1000
257
+ return Tc_K - q_W * t_m / k_wall # This is actually Tc - q*t/k for cold side
258
+
259
+ def calc_turbopump_power(mdot, dp_bar, rho, eta=0.65):
260
+ """P_pump = mdot × ΔP / (ρ × η)"""
261
+ dp_Pa = dp_bar * 1e5
262
+ return mdot * dp_Pa / (rho * eta)
263
+
264
+ def calc_specific_speed(N_rpm, Q_m3s, H_m):
265
+ """Ns = N×sqrt(Q) / H^0.75 — turbopump specific speed"""
266
+ return N_rpm * math.sqrt(Q_m3s) / H_m**0.75
267
+
268
+ def calc_npsh_required(v_ms, rho, P_vapor_Pa, P_inlet_Pa):
269
+ """NPSHr = (P_inlet - P_vapor)/(ρg) — cavitation check"""
270
+ return (P_inlet_Pa - P_vapor_Pa) / (rho * G0)
271
+
272
+ def calc_volumetric_energy_density(power_W, speed_mm_s, hatch_mm, layer_mm):
273
+ """VED = P / (v × h × t) in J/mm³ — key L-PBF quality metric"""
274
+ return power_W / (speed_mm_s * hatch_mm * layer_mm)
275
+
276
+ def calc_contraction_angle(Dc_mm, Dt_mm, Lcon_mm):
277
+ """Half-angle of converging section"""
278
+ return math.degrees(math.atan((Dc_mm - Dt_mm) / (2 * Lcon_mm)))
279
+
280
+ def calc_divergence_loss(half_angle_deg):
281
+ """λ = (1 + cos(α))/2 — divergence efficiency factor"""
282
+ return (1 + math.cos(math.radians(half_angle_deg))) / 2
283
+
284
+ def calc_combustion_efficiency(Lstar_m, cstar_theoretical):
285
+ """η_c* approximation based on L* (higher L* = more complete combustion)"""
286
+ eta = min(0.99, 0.85 + 0.12 * math.log(max(Lstar_m, 0.1)))
287
+ return eta
288
+
289
+ def calc_mixture_density(rho_f, rho_o, OF):
290
+ """Bulk propellant density: 1/ρ_mix = (1/(1+OF))/ρ_f + (OF/(1+OF))/ρ_o"""
291
+ w_f = 1 / (1 + OF)
292
+ w_o = OF / (1 + OF)
293
+ return 1 / (w_f / rho_f + w_o / rho_o)
294
+
295
+ # === CONSTANTS DATABASE ===
296
+ UNIVERSAL_GAS_CONST = 8314.46 # J/(kmol·K)
297
+ STEFAN_BOLTZMANN = 5.67e-8 # W/(m²·K⁴)
298
+ BOLTZMANN_K = 1.381e-23 # J/K
299
+
300
+ def calc_radiation_heat_loss(emissivity, T_surface_K, T_ambient_K=300):
301
+ """q_rad = ε × σ × (T⁴_s - T⁴_a) — Stefan-Boltzmann radiation"""
302
+ return emissivity * STEFAN_BOLTZMANN * (T_surface_K**4 - T_ambient_K**4)
303
+
304
+ def calc_speed_of_sound(gamma, Rspec, T_K):
305
+ """a = sqrt(γ × R × T)"""
306
+ return math.sqrt(gamma * Rspec * T_K)
307
+
308
+
309
+ # === GENERAL ENGINEERING PHYSICS ===
310
+
311
+ def calc_beam_deflection(load_N, length_mm, width_mm, height_mm, E_GPa):
312
+ """Max deflection of cantilever beam: δ = (F*L^3) / (3*E*I)"""
313
+ L = length_mm / 1000
314
+ w = width_mm / 1000
315
+ h = height_mm / 1000
316
+ E = E_GPa * 1e9
317
+
318
+ # Area Moment of Inertia for rectangle
319
+ I = (w * h**3) / 12
320
+
321
+ deflection_m = (load_N * L**3) / (3 * E * I)
322
+ return deflection_m * 1000 # return mm
323
+
324
+ def calc_plate_buckling_stress(E_GPa, t_mm, width_mm, poisson=0.3):
325
+ """Critical buckling stress for simply supported plate: σ_cr = (k*π^2*E)/(12*(1-v^2)*(b/t)^2)"""
326
+ k = 4.0 # Simply supported
327
+ E = E_GPa * 1e9
328
+ ratio = width_mm / t_mm
329
+
330
+ sigma_cr = (k * math.pi**2 * E) / (12 * (1 - poisson**2) * ratio**2)
331
+ return sigma_cr / 1e6 # MPa
332
+
333
+ def calc_conduction_resistance(length_mm, area_mm2, k_W_mK):
334
+ """Thermal resistance R = L / (k * A)"""
335
+ L = length_mm / 1000
336
+ A = area_mm2 / 1e6
337
+ return L / (k_W_mK * A)
338
+
339
+ def calc_heatsink_performance(power_W, T_max_C, T_amb_C, R_ideal_CW):
340
+ """Check if heatsink meets thermal resistance target"""
341
+ delta_T = T_max_C - T_amb_C
342
+ R_actual = delta_T / power_W
343
+ margin = (R_actual - R_ideal_CW) / R_ideal_CW
344
+ return R_actual, margin
345
+
346
+ def calc_bolt_shear_strength(diameter_mm, material_key):
347
+ """Shear strength of a bolt ≈ 0.6 * Ultimate Tensile Strength"""
348
+ mat = MATERIALS[material_key]
349
+ area = math.pi * (diameter_mm/2)**2
350
+ shear_yield_MPa = 0.577 * mat["sigma_y_MPa"] # Von Mises criterion
351
+
352
+ max_load_N = shear_yield_MPa * area
353
+ return max_load_N
354
+
355
+ def calc_natural_frequency_cantilever(length_mm, width_mm, height_mm, E_GPa, rho_kg_m3):
356
+ """Fundamental frequency f = (0.56/L^2) * sqrt(E*I / (rho*A))"""
357
+ L = length_mm / 1000
358
+ w = width_mm / 1000
359
+ h = height_mm / 1000
360
+ E = E_GPa * 1e9
361
+
362
+ I = (w * h**3) / 12
363
+ A = w * h
364
+
365
+ freq_Hz = (3.52 / (2 * math.pi * L**2)) * math.sqrt((E * I) / (rho_kg_m3 * A))
366
+ return freq_Hz
datasets/rocket_propulsion_dataset.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "id": "nozzle_001",
4
+ "input": "Design a rocket nozzle for a 5kN thrust LOX/LH2 engine with chamber pressure 100 bar and mixture ratio 6.0",
5
+ "reasoning": "[REQUIREMENTS_PARSE]\n- Thrust (F): 5000 N\n- Chamber pressure (Pc): 100 bar = 10 MPa\n- Propellants: LOX/LH2\n- Mixture ratio (O/F): 6.0\n- Propellant: LOX/LH2 (cryogenic bipropellant)\n\n[PHYSICS_DERIVATION]\n\nStep 1: Combustion Properties (from CEA or tables)\n- γ (gamma) = 1.14 for LOX/LH2 at MR=6\n- Tc (chamber temp) = 3500 K\n- M (molecular weight) = 13.4 kg/kmol\n- c* (characteristic velocity) = 2360 m/s\n\nStep 2: Specific Impulse\n$I_{sp} = \\frac{c^*}{g_0} \\cdot C_f$\n$C_f = \\sqrt{\\frac{2\\gamma^2}{\\gamma-1} \\left(\\frac{2}{\\gamma+1}\\right)^{\\frac{\\gamma+1}{\\gamma-1}} \\left[1 - \\left(\\frac{P_e}{P_c}\\right)^{\\frac{\\gamma-1}{\\gamma}}\\right]}$\nAssuming Pe/Pc = 0.01 (optimal expansion)\n$C_f = 1.85$\n$I_{sp} = 450$ s\n\nStep 3: Mass Flow Rate\n$\\dot{m} = \\frac{F}{I_{sp} \\cdot g_0} = \\frac{5000}{450 \\times 9.81} = 1.133$ kg/s\n\nStep 4: Throat Area\n$A^* = \\frac{\\dot{m} \\cdot c^*}{P_c} = \\frac{1.133 \\times 2360}{10 \\times 10^6} = 267.4$ mm²\n$D^* = \\sqrt{\\frac{4 A^*}{\\pi}} = 18.45$ mm → Round to 18.5 mm\n\nStep 5: Expansion Ratio\nFor altitude optimization (vacuum): ε = 50-100\nFor sea level: ε = 8-15\nChoosing ε = 40 (high altitude optimized)\n$A_e = \\epsilon \\cdot A^* = 40 \\times 267.4 = 10696$ mm²\n$D_e = 116.7$ mm → Round to 117 mm\n\nStep 6: Nozzle Length (80% bell contour)\n$L_n = 0.8 \\times \\frac{D_e - D^*}{2 \\tan(15°)} = 183$ mm\n\n[CONSTRAINT_VALIDATION]\n✓ Throat size: 18.5mm > 10mm minimum for manufacturing\n✓ Expansion ratio: 40 within 20-80 range for vacuum engines\n✓ Wall thickness: Will calculate in cooling section",
6
+ "output": "using PicoGK;\nusing System.Numerics;\n\nnamespace AlgoRythm.RedRock.Engines\n{\n public class NozzleGenerator\n {\n // Calculated parameters\n const float THROAT_DIAMETER = 18.5f;\n const float EXIT_DIAMETER = 117.0f;\n const float NOZZLE_LENGTH = 183.0f;\n const float WALL_THICKNESS = 2.0f;\n \n public static Voxels GenerateNozzle()\n {\n Voxels voxNozzle = new Voxels();\n \n // Throat section\n float fThroatRadius = THROAT_DIAMETER / 2.0f;\n Vector3 vecThroat = new Vector3(0, 0, 0);\n \n // Convergent section (30 degree half-angle)\n float fConvergentLength = 30.0f;\n float fChamberRadius = fThroatRadius * 1.5f;\n \n // Divergent section (bell contour - 80%)\n float fExitRadius = EXIT_DIAMETER / 2.0f;\n \n // Generate bell nozzle contour using Rao method\n int nPoints = 50;\n for (int i = 0; i <= nPoints; i++)\n {\n float t = (float)i / nPoints;\n float z = -t * NOZZLE_LENGTH;\n float r = fThroatRadius + (fExitRadius - fThroatRadius) * \n (float)Math.Pow(t, 0.7);\n \n // Add material at this cross-section\n Voxels voxRing = Voxels.voxSphere(\n new Vector3(0, 0, z), r + WALL_THICKNESS);\n Voxels voxInner = Voxels.voxSphere(\n new Vector3(0, 0, z), r);\n voxRing.BoolSubtract(voxInner);\n voxNozzle.BoolAdd(voxRing);\n }\n \n return voxNozzle;\n }\n }\n}"
7
+ },
8
+ {
9
+ "id": "chamber_001",
10
+ "input": "Design combustion chamber for 10kN LOX/RP-1 engine at 80 bar chamber pressure",
11
+ "reasoning": "[REQUIREMENTS_PARSE]\n- Thrust (F): 10000 N\n- Chamber pressure (Pc): 80 bar = 8 MPa\n- Propellants: LOX/RP-1 (kerosene)\n- Assume standard O/F ratio: 2.7\n\n[PHYSICS_DERIVATION]\n\nStep 1: Combustion Properties\n- γ = 1.24 for LOX/RP-1\n- Tc = 3600 K\n- c* = 1780 m/s\n- Isp (vacuum) ≈ 320 s\n\nStep 2: Mass Flow Rate\n$\\dot{m} = \\frac{F}{I_{sp} \\cdot g_0} = \\frac{10000}{320 \\times 9.81} = 3.185$ kg/s\n\nStep 3: Throat Area\n$A^* = \\frac{\\dot{m} \\cdot c^*}{P_c} = \\frac{3.185 \\times 1780}{8 \\times 10^6} = 708.7$ mm²\n$D^* = 30.0$ mm\n\nStep 4: Characteristic Length (L*)\nFor LOX/RP-1: L* = 1.0 - 1.5 m (typical)\nChoosing L* = 1.2 m\n\nStep 5: Chamber Volume\n$V_c = L^* \\times A^* = 1.2 \\times 708.7 \\times 10^{-6} = 850.4$ cm³\n\nStep 6: Chamber Dimensions\nContraction ratio: CR = 3.0 (typical)\n$A_c = CR \\times A^* = 3.0 \\times 708.7 = 2126$ mm²\n$D_c = 52.0$ mm\n\nChamber length:\n$L_c = \\frac{V_c}{A_c} = \\frac{850400}{2126} = 400$ mm\n\n[CONSTRAINT_VALIDATION]\n✓ L* = 1.2m within 1.0-1.5m range for LOX/RP-1\n✓ Contraction ratio 3.0 within 2.5-4.0 range\n✓ Chamber L/D = 400/52 = 7.7 (acceptable)",
12
+ "output": "using PicoGK;\nusing System.Numerics;\n\nnamespace AlgoRythm.RedRock.Engines\n{\n public class ChamberGenerator\n {\n const float THROAT_DIAMETER = 30.0f;\n const float CHAMBER_DIAMETER = 52.0f;\n const float CHAMBER_LENGTH = 400.0f;\n const float WALL_THICKNESS = 3.0f;\n \n public static Voxels GenerateChamber()\n {\n Voxels voxChamber = new Voxels();\n \n float fChamberRadius = CHAMBER_DIAMETER / 2.0f + WALL_THICKNESS;\n float fInnerRadius = CHAMBER_DIAMETER / 2.0f;\n \n // Cylindrical chamber section\n Vector3 vecStart = new Vector3(0, 0, 0);\n Vector3 vecEnd = new Vector3(0, 0, CHAMBER_LENGTH);\n \n // Outer wall\n Voxels voxOuter = Voxels.voxSphere(vecStart, fChamberRadius);\n voxOuter.BoolAdd(Voxels.voxSphere(vecEnd, fChamberRadius));\n \n // Inner cavity\n Voxels voxInner = Voxels.voxSphere(vecStart, fInnerRadius);\n voxInner.BoolAdd(Voxels.voxSphere(vecEnd, fInnerRadius));\n \n voxChamber.BoolAdd(voxOuter);\n voxChamber.BoolSubtract(voxInner);\n \n return voxChamber;\n }\n }\n}"
13
+ }
14
+ ]
datasets/synthetic_nozzles.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:23ff426560cf99c5374f836aabbca367464f0ada2fc5bd690ecb0a0f6ed6af83
3
+ size 12017255
datasets/thermal_fluid_dataset.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "id": "cooling_001",
4
+ "input": "Design regenerative cooling channels for copper nozzle with 45 MW/m² heat flux at throat",
5
+ "reasoning": "[REQUIREMENTS_PARSE]\n- Heat flux at throat (q): 45 MW/m² = 45×10⁶ W/m²\n- Material: Copper (k = 401 W/m·K)\n- Coolant: LH2 (inlet 20K, outlet limit 200K)\n\n[PHYSICS_DERIVATION]\n\nStep 1: Required Heat Transfer Coefficient\n$h = \\frac{q}{T_{gas} - T_{wall}} = \\frac{45 \\times 10^6}{3500 - 800} = 16,667$ W/(m²·K)\n\nStep 2: Coolant Velocity (Dittus-Boelter)\n$Nu = 0.023 Re^{0.8} Pr^{0.4}$\nFor LH2: Pr = 1.2, k = 0.1 W/m·K\n$h = \\frac{Nu \\cdot k}{D_h}$\nSolving: $V_{coolant} = 35$ m/s\n\nStep 3: Channel Sizing\nHydraulic diameter: $D_h = \\frac{4A}{P} = 2.5$ mm\nChannel width: w = 2.0 mm\nChannel depth: d = 3.0 mm\n\nStep 4: Wall Thickness\n$t_{wall} = \\frac{q \\cdot d}{k \\cdot \\Delta T} = \\frac{45 \\times 10^6 \\times 0.003}{401 \\times 400} = 0.84$ mm\nRound to: 1.0 mm (safety factor 1.2)\n\n[CONSTRAINT_VALIDATION]\n✓ T_wall = 800K < 1356K (Cu melting)\n✓ Coolant velocity 35 m/s < 50 m/s (erosion limit)\n✓ Channel Re = 85000 > 10000 (turbulent flow)",
6
+ "output": "using PicoGK;\nusing System.Numerics;\n\nnamespace AlgoRythm.RedRock.Cooling\n{\n public class CoolingChannelGenerator\n {\n const float CHANNEL_WIDTH = 2.0f;\n const float CHANNEL_DEPTH = 3.0f;\n const float WALL_THICKNESS = 1.0f;\n const int NUM_CHANNELS = 24;\n const float RIB_WIDTH = 1.5f;\n \n public static Voxels GenerateCoolingChannels(float nozzleRadius, float length)\n {\n Voxels voxChannels = new Voxels();\n float circumference = 2 * (float)Math.PI * nozzleRadius;\n float spacing = circumference / NUM_CHANNELS;\n \n for (int i = 0; i < NUM_CHANNELS; i++)\n {\n float angle = 2 * (float)Math.PI * i / NUM_CHANNELS;\n float xOffset = (nozzleRadius + WALL_THICKNESS) * (float)Math.Cos(angle);\n float yOffset = (nozzleRadius + WALL_THICKNESS) * (float)Math.Sin(angle);\n \n // Create channel as rectangular cross-section extruded along nozzle\n Vector3 channelStart = new Vector3(xOffset, yOffset, 0);\n Vector3 channelEnd = new Vector3(xOffset, yOffset, length);\n \n Voxels voxChannel = Voxels.voxSphere(channelStart, CHANNEL_WIDTH/2);\n voxChannel.BoolAdd(Voxels.voxSphere(channelEnd, CHANNEL_WIDTH/2));\n voxChannels.BoolAdd(voxChannel);\n }\n return voxChannels;\n }\n }\n}"
7
+ },
8
+ {
9
+ "id": "injector_001",
10
+ "input": "Design coaxial swirl injector element for LOX/Methane with 3.5 O/F ratio, 20% pressure drop",
11
+ "reasoning": "[REQUIREMENTS_PARSE]\n- Injector type: Coaxial swirl\n- Propellants: LOX (oxidizer), Methane (fuel)\n- O/F ratio: 3.5\n- Pressure drop: 20% of chamber pressure\n\n[PHYSICS_DERIVATION]\n\nStep 1: Mass Flow per Element\nAssume total mdot = 5 kg/s, 19 elements\n$\\dot{m}_{element} = \\frac{5}{19} = 0.263$ kg/s\n$\\dot{m}_{LOX} = \\frac{3.5}{4.5} \\times 0.263 = 0.204$ kg/s\n$\\dot{m}_{CH4} = \\frac{1}{4.5} \\times 0.263 = 0.058$ kg/s\n\nStep 2: LOX Orifice (Central)\n$A_{LOX} = \\frac{\\dot{m}_{LOX}}{C_d \\sqrt{2 \\rho_{LOX} \\Delta P}}$\nCd = 0.7, ρ_LOX = 1141 kg/m³, ΔP = 20 bar\n$A_{LOX} = \\frac{0.204}{0.7 \\sqrt{2 \\times 1141 \\times 2 \\times 10^6}} = 4.3$ mm²\n$D_{LOX} = 2.34$ mm → Round to 2.4 mm\n\nStep 3: Methane Annulus (Swirl)\n$A_{CH4} = \\frac{\\dot{m}_{CH4}}{C_d \\sqrt{2 \\rho_{CH4} \\Delta P}}$\nρ_CH4 = 422 kg/m³\n$A_{CH4} = 2.1$ mm² per tangential inlet\n4 tangential ports: D = 0.82 mm each\n\n[CONSTRAINT_VALIDATION]\n✓ LOX velocity = 45 m/s < 60 m/s (cavitation limit)\n✓ Swirl number Sn = 1.2 (good atomization)\n✓ ΔP/Pc = 20% (stability margin OK)",
12
+ "output": "using PicoGK;\nusing System.Numerics;\n\nnamespace AlgoRythm.RedRock.Injectors\n{\n public class CoaxialSwirlInjector\n {\n const float LOX_ORIFICE_DIAMETER = 2.4f;\n const float ANNULUS_INNER = 3.0f;\n const float ANNULUS_OUTER = 4.5f;\n const float SWIRL_PORT_DIAMETER = 0.82f;\n const int NUM_SWIRL_PORTS = 4;\n const float ELEMENT_LENGTH = 15.0f;\n \n public static Voxels GenerateInjectorElement()\n {\n Voxels voxElement = new Voxels();\n \n // Central LOX post\n float loxRadius = LOX_ORIFICE_DIAMETER / 2.0f;\n Vector3 loxStart = new Vector3(0, 0, 0);\n Vector3 loxEnd = new Vector3(0, 0, ELEMENT_LENGTH);\n \n Voxels voxLOX = Voxels.voxSphere(loxStart, loxRadius + 0.5f);\n Voxels voxLOXinner = Voxels.voxSphere(loxStart, loxRadius);\n voxLOX.BoolSubtract(voxLOXinner);\n voxElement.BoolAdd(voxLOX);\n \n // Fuel annulus with swirl ports\n Voxels voxAnnulus = Voxels.voxSphere(loxStart, ANNULUS_OUTER);\n Voxels voxAnnulusInner = Voxels.voxSphere(loxStart, ANNULUS_INNER);\n voxAnnulus.BoolSubtract(voxAnnulusInner);\n voxElement.BoolAdd(voxAnnulus);\n \n return voxElement;\n }\n }\n}"
13
+ }
14
+ ]
datasets/universal_csg.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ AlgoRythm Prandtl Aero — Universal CSG Builder
3
+ Generates random but valid "General Mechanical" and "Universal Gadget" designs.
4
+ Teaches the model the "Language of Shape" beyond just rockets.
5
+ """
6
+ import random, math
7
+ import advanced_physics
8
+
9
+ # ... (Previous CSGNode classes unchanged)
10
+
11
+ def gen_mounting_bracket():
12
+ """Generates an L-shaped or U-shaped mounting bracket with bolt holes"""
13
+
14
+ # 1. Base Dimensions
15
+ length = random.randint(50, 150)
16
+ width = random.randint(40, 80)
17
+ thickness = random.choice([5, 8, 10, 12])
18
+ height = random.randint(40, 100)
19
+
20
+ type_ = random.choice(["L-bracket", "U-bracket", "Gusseted bracket"])
21
+ mat = random.choice(["Aluminium 6061", "Steel 316L", "Titanium Gr5"])
22
+ load = random.randint(500, 5000) # Newtons
23
+
24
+ # --- DEEP PHYSICS (Beam Theory) ---
25
+ # Model upright as cantilever beam: Sigma = M*y/I
26
+ M = load * (height/1000) # Nm
27
+ c = (thickness/1000) / 2 # m
28
+ I = (width/1000) * (thickness/1000)**3 / 12 # m^4
29
+ sigma_bending = (M * c) / I / 1e6 # MPa
30
+
31
+ # Von Mises Check
32
+ sigma_vm = advanced_physics.calc_von_mises_stress(sigma_bending, 0, 0, 0, 0, 0)
33
+
34
+ # Get Yield Strength (Room Temp approx)
35
+ yield_str, _ = advanced_physics.get_material_properties(mat, 300)
36
+ # Adjust for Aluminium (not in advanced_physics defaults, add fallback)
37
+ if "Aluminium" in mat: yield_str = 276.0
38
+ if "Steel" in mat: yield_str = 290.0 # 316L
39
+
40
+ mos = advanced_physics.check_margin_of_safety_aerospace(yield_str, sigma_vm)
41
+
42
+ description = f"Design a {type_} from {mat} to support a {load}N load. Dimensions: Base {length}x{width}mm, Height {height}mm."
43
+
44
+ reasoning = f"""[REQUIREMENTS_PARSE]
45
+ Design {type_} for {load}N load. Material: {mat}.
46
+ Geometry: {length}x{width}x{height}mm. Thickness: {thickness}mm.
47
+
48
+ [PHYSICS_DERIVATION]
49
+ 1. **Load Case (Cantilever):**
50
+ Moment M = F * L = {load} * {height/1000:.3f} = {M:.1f} Nm.
51
+ 2. **Stress Analysis:**
52
+ Section Modulus Z = I/c = {I/c:.2e} m³.
53
+ Bending Stress σ = M/Z = {sigma_bending:.1f} MPa.
54
+ 3. **Failure Criteria (Von Mises):**
55
+ σ_vm = {sigma_vm:.1f} MPa.
56
+ Yield Strength = {yield_str} MPa.
57
+ Margin of Safety = ({yield_str} / ({sigma_vm:.1f} * 1.4)) - 1 = {mos:.2f}
58
+
59
+ [CONSTRAINT_VALIDATION]
60
+ 1. **Structural Integrity:** {'PASS (MoS > 0)' if mos > 0 else 'FAIL - INCREASE THICKNESS'}.
61
+ 2. **L-PBF Printability:** {advanced_physics.analyze_geometry_printability('Overhang', 90)[1]}
62
+
63
+ [DESIGN_LOGIC]
64
+ - Fillets added (r=5mm) to reduce stress concentration factors (Kt).
65
+ - Bolt pattern sized for M6 clearance."""
66
+
67
+ code = f"""// AlgoRythm Prandtl Aero — {type_}
68
+ using PicoGK;
69
+ using System.Numerics;
70
+
71
+ namespace AlgoRythm.PrandtlAero.Mechanical
72
+ {{
73
+ public class BracketGenerator
74
+ {{
75
+ public static Voxels Generate()
76
+ {{
77
+ // 1. Base Plate
78
+ Mesh mshBase = Utils.mshCreateCube(new Vector3({length}f, {width}f, {thickness}f));
79
+ Voxels voxBase = new Voxels(mshBase);
80
+
81
+ // 2. Upright
82
+ Mesh mshUpright = Utils.mshCreateCube(new Vector3({thickness}f, {width}f, {height}f));
83
+ Voxels voxUpright = new Voxels(mshUpright);
84
+ // Move upright to end of base
85
+ voxUpright.Translate(new Vector3({length/2 - thickness/2}f, 0, {height/2}f));
86
+
87
+ // Union
88
+ voxBase.BoolAdd(voxUpright);
89
+
90
+ // 3. Fillet (Stress Relief)
91
+ voxBase.Dilate(5.0f);
92
+ voxBase.Erode(5.0f);
93
+
94
+ return voxBase;
95
+ }}
96
+ }}
97
+ }}"""
98
+
99
+ return {"id": f"brack_{random.randint(1000,9999)}", "input": description, "reasoning": reasoning, "output": code}
100
+
101
+ def gen_enclosure():
102
+ """Generates an electronic enclosure box with lid"""
103
+ w = random.randint(80, 200)
104
+ l = random.randint(80, 200)
105
+ h = random.randint(30, 80)
106
+ wall = 3.0
107
+
108
+ # --- DEEP PHYSICS (Plate Theory) ---
109
+ # Check max deflection of lid under vacuum/pressure load (1 atm)
110
+ # Plate D = Et^3 / 12(1-v^2)
111
+ E = 69000 # Al 6061 MPa
112
+ q_load = 0.1 # MPa (1 bar pressure differential)
113
+ b = min(w, l)
114
+ max_deflection = (0.142 * q_load * b**4) / (E * wall**3) # Simplified Roark's formula
115
+
116
+ # Thermal Distortion
117
+ delta_T_thermal = advanced_physics.predict_thermal_distortion(max(w, l, h), 50, 23e-6) # 50C rise, Alum CTE
118
+
119
+ description = f"Design a rugged enclosure box {w}x{l}x{h}mm with {wall}mm wall thickness."
120
+
121
+ reasoning = f"""[REQUIREMENTS_PARSE]
122
+ Design Enclosure: {w}x{l}x{h}mm. Wall: {wall}mm.
123
+ Objective: IP67 Sealing & Structural Stiffness.
124
+
125
+ [PHYSICS_DERIVATION]
126
+ 1. **Stiffness Check (Plate Theory):**
127
+ Max Deflection (1 bar load) = {max_deflection:.3f} mm.
128
+ Allowable < 1.0mm (to prevent seal breach). -> {'PASS' if max_deflection < 1.0 else 'WARN: Ribs required'}
129
+ 2. **Thermal Stability:**
130
+ Max Expansion (dT=50C) = {delta_T_thermal:.3f} mm.
131
+ Gasket compression set must accommodate > {delta_T_thermal:.3f} mm movement.
132
+
133
+ [CONSTRAINT_VALIDATION]
134
+ 1. **L-PBF Manufacturing:**
135
+ Internal overhangs: 90 deg (Bridge). Pass < 10mm.
136
+ Selected bridging distance: {w-2*wall}mm. -> REQUIRES SUPPORT.
137
+
138
+ [DESIGN_LOGIC]
139
+ - Shell generated via CSG Subtract.
140
+ - Lid interface generated with 0.5mm tolerance gap."""
141
+
142
+ code = f"""// AlgoRythm Prandtl Aero — Rugged Enclosure
143
+ using PicoGK;
144
+ using System.Numerics;
145
+
146
+ namespace AlgoRythm.PrandtlAero.Mechanical
147
+ {{
148
+ public class EnclosureGenerator
149
+ {{
150
+ public static Voxels Generate()
151
+ {{
152
+ // Outer Shell
153
+ Voxels voxBox = new Voxels(Utils.mshCreateCube(new Vector3({w}f, {l}f, {h}f)));
154
+
155
+ // Inner Cavity
156
+ Voxels voxCavity = new Voxels(Utils.mshCreateCube(new Vector3({w-2*wall}f, {l-2*wall}f, {h}f)));
157
+ voxCavity.Translate(new Vector3(0, 0, {wall}f));
158
+
159
+ // Shelling
160
+ voxBox.BoolSubtract(voxCavity);
161
+
162
+ // Add Bosses
163
+ float fBossX = {w/2 - 10}f;
164
+ float fBossY = {l/2 - 10}f;
165
+ // ... (Loop to add 4 bosses)
166
+
167
+ return voxBox;
168
+ }}
169
+ }}
170
+ }}"""
171
+
172
+ return {"id": f"box_{random.randint(1000,9999)}", "input": description, "reasoning": reasoning, "output": code}
173
+
174
+ # === API ===
175
+ def generate_generic_batch(count=100):
176
+ data = []
177
+ print(f"Generatring {count} generic mechanical parts...")
178
+ for _ in range(count):
179
+ if random.random() < 0.5:
180
+ data.append(gen_mounting_bracket())
181
+ else:
182
+ data.append(gen_enclosure())
183
+ return data
datasets/verify_data.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Quick verification script for generated dataset"""
2
+ import json
3
+
4
+ with open("datasets/synthetic_nozzles.json") as f:
5
+ data = json.load(f)
6
+
7
+ print(f"Total examples: {len(data)}")
8
+
9
+ # Count types
10
+ types = {}
11
+ for ex in data:
12
+ t = ex["id"].split("_")[0]
13
+ types[t] = types.get(t, 0) + 1
14
+ print("\nComposition:")
15
+ for t, c in sorted(types.items(), key=lambda x: -x[1]):
16
+ print(f" {t}: {c}")
17
+
18
+ # Check nozzle dimensions
19
+ print("\nNozzle Spot Checks:")
20
+ nozzles = [e for e in data if e["id"].startswith("nozzle")]
21
+ for ex in nozzles[:5]:
22
+ r = ex["reasoning"]
23
+ for line in r.split("\n"):
24
+ line = line.strip()
25
+ if "D* =" in line and "mm" in line:
26
+ print(f" [{ex['id']}] {line[:80]}")
27
+ if "MoS =" in line and "mm" not in line:
28
+ print(f" [{ex['id']}] {line[:80]}")
29
+
30
+ # Check for negative MoS without failure
31
+ print("\nMoS Check:")
32
+ neg_mos = 0
33
+ for ex in data:
34
+ if "MoS = -" in ex.get("reasoning",""):
35
+ neg_mos += 1
36
+ print(f" Examples with negative MoS: {neg_mos}")
37
+ print(f" Examples with positive MoS: {len(data) - neg_mos}")