# Technical Breakdown β€” Adaptive Isogrid Plate Lightweighting **Project:** Isogrid Dev Plate **Author:** Technical Lead πŸ”§ **Date:** 2026-02-18 **Status:** Architecture complete β€” Campaign 01 ready to run --- ## 1. Problem Formulation ### 1.1 Structural Configuration Flat plate with bolt holes, optimized by replacing solid material with an adaptive triangular isogrid. - 2 sandbox regions (sandbox_1, sandbox_2) β€” where ribs are generated and changed each iteration - Bolt holes: excluded from pocket generation (keepout zone around each hole) - Plate material: AL7075-T6 (confirmed 2026-02-18 β€” see material discrepancy note in Β§4.2) - 3D solid FEA already run (CHEXA/CTETRA, SOL 101) ### 1.2 Objective Function **Single-objective: minimize total plate mass.** ``` minimize: mass(params) subject to: max_von_mises ≀ Οƒ_allow = 100.6 MPa ``` > **No displacement constraint** β€” confirmed by Antoine 2026-02-18. The penalty approach: ```python penalty = 0.0 if max_stress > sigma_allow: penalty += 1e4 * ((max_stress / sigma_allow) - 1.0) ** 2 return mass_kg + penalty ``` --- ## 2. Design Variable Classification ### 2.1 Optimized Variables (8) β€” Atomizer design space These directly control rib pattern shape and density. Every trial samples all 8. | Variable | Range | Description | |----------|-------|-------------| | `eta_0` | [0.0, 0.4] | Baseline density offset β€” global rib density floor | | `alpha` | [0.3, 2.0] | Hole influence scale β€” how much ribs cluster around holes | | `beta` | [0.0, 1.0] | Edge influence scale β€” how much ribs reinforce the perimeter | | `gamma_stress` | [0.0, 1.5] | Stress feedback gain β€” how much FEA stress adds density | | `R_0` | [10, 100] mm | Base influence radius β€” how far hole influence spreads | | `R_edge` | [5, 40] mm | Edge influence radius β€” depth of perimeter reinforcement band | | `s_min` | [15, 35] mm | Minimum triangle edge length β†’ densest zone spacing (manufacturing floor: 15 mm) | | `s_max` | [40, 60] mm | Maximum triangle edge length β†’ sparsest zone spacing (lower bound 40 guarantees s_min < s_max) | **Total: 8 continuous variables.** Manageable for Optuna TPE; expect useful signal in 50–100 trials, convergence in 200–500. ### 2.2 Manufacturing Constraints (Fixed) β€” NOT optimized These are set from machining requirements and are fixed for the entire campaign. They can be adjusted between campaigns if the process changes. | Parameter | Fixed Value | Why Fixed | Manufacturing Basis | |-----------|------------|-----------|---------------------| | `t_min` | 2.5 mm | Minimum rib thickness: thinner ribs are not machinable and would break | CNC milling minimum land width | | `t_0` | 3.5 mm | Nominal rib thickness: baseline starting width before density scaling | Design intent | | `w_frame` | 5.0 mm | Perimeter frame width: solid band around the sandbox boundary | Edge seal, clamping, aesthetics | | `r_f` | 1.5 mm | Pocket fillet radius: corner radius on each pocket. **Sole pocket size filter.** | = tool radius. Smaller β†’ need smaller endmill | | `d_keep` | 1.2Γ— | Hole keepout multiplier: minimum clear distance = 1.2 Γ— hole diameter | Prevents thin walls around bolt holes | | `min_triangle_area` | 25.0 mmΒ² | Minimum pocketable triangle area | Below this: too small to machine β†’ skip as solid | > To change manufacturing constraints for a campaign, edit `MANUFACTURING_CONSTRAINTS` in > `optimization_engine/isogrid/study.py` and document the change here. ### 2.3 Math/Model Constants (Fixed) β€” NOT optimized These govern the mathematical form of the density field. Fixed at well-behaved defaults. Changing them would fundamentally change the shape of the density function. | Parameter | Fixed Value | Description | |-----------|------------|-------------| | `p` | 2.0 | Gaussian decay exponent (p=2 β†’ smooth Gaussian, p=1 β†’ exponential, p=4 β†’ box-like) | | `kappa` | 1.0 | Weight-to-radius coupling: heavier holes get proportionally larger influence radius | | `gamma` | 1.0 | Density-to-thickness coupling: t(x) = tβ‚€ Γ— (1 + Ξ³Β·Ξ·) | > Note: `gamma` here is the rib-thickness coupling, distinct from `gamma_stress` (stress feedback gain). --- ## 3. Density Field Formulation The full adaptive formula with stress feedback: ``` Ξ·(x,y) = clamp(0, 1, Ξ·β‚€ + Ξ±Β·I(x) + Ξ²Β·E(x) + Ξ³_stressΒ·S_stress(x)) ``` Where: - `I(x) = Ξ£α΅’ wα΅’ Β· exp(-(dα΅’/Rα΅’)^p)` β€” hole influence (sum over all bolt holes) - `E(x) = exp(-(d_edge/R_edge)^p)` β€” edge reinforcement - `S_stress(x)` β€” normalized FEA stress field from previous trial, ∈ [0..1] - `Rα΅’ = Rβ‚€ Β· (1 + ΞΊ Β· wα΅’)` β€” per-hole radius scales with hole weight Local spacing: `s(x) = s_max - (s_max - s_min) Β· Ξ·(x)` Local rib thickness: `t(x) = clip(tβ‚€ Β· (1 + Ξ³ Β· Ξ·(x)), t_min, t_max)` --- ## 4. FEA Pipeline Status ### 4.1 What Is Done | Step | Status | Notes | |------|--------|-------| | NX geometry extraction (`extract_sandbox.py`) | βœ… Done | geometry_sandbox_1.json, geometry_sandbox_2.json | | Python Brain (density β†’ profile) | βœ… Done | Gmsh Frontal-Delaunay, Shapely pockets | | NX rib import (`import_profile.py`) | βœ… Done | Update-in-place, preserves extrude reference | | 3D solid FEA (manual baseline) | βœ… Done | OP2 results available | | Stress field extraction (OP2 β†’ 2D) | βœ… Done | `optimization_engine/extractors/extract_stress_field_2d.py` | | Stress feedback field | βœ… Done | `optimization_engine/isogrid/stress_feedback.py` | | Atomizer study wiring | βœ… Done | `studies/01_v1_tpe/run_optimization.py` | | Campaign 01 execution | πŸ”΄ Not started | Run `run_optimization.py` | ### 4.2 FEA Configuration - **Solver:** NX Nastran, SOL 101 (linear static) - **Elements:** 3D solid (CHEXA, CTETRA, CPENTA) - **Stress units:** NX kg-mm-s outputs kPa β†’ extractor divides by 1000 β†’ MPa - **Material (optimization):** AL7075-T6 β€” Οƒ_yield = 503 MPa, ρ = 2810 kg/mΒ³, SF = 5 β†’ Οƒ_allow = 100.6 MPa - **Sandbox regions:** 2 (sandbox_1 is larger, sandbox_2 is smaller patch) > ⚠️ **Material discrepancy (Gap G-01):** The NX FEM model (MAT1 card in the DAT file) uses > E = 68.98 GPa and ρ = 2.711Γ—10⁻⁢ kg/mmΒ³, which correspond to **AL6061-T6** properties. > Optimization allowables and mass targets are based on **AL7075-T6** as confirmed by Antoine. > This discrepancy means FEA stiffness/mass are slightly underestimated. > Tracked as G-01 in CONTEXT.md β€” update MAT1 card before next FEA campaign. ### 4.3 Key FEA Files **NX model (reference copies β€” do NOT modify):** ``` projects/isogrid-dev-plate/models/ β”œβ”€β”€ ACS_Stack_Main_Plate_Iso_Project.prt ← Geometry part β”œβ”€β”€ ACS_Stack_Main_Plate_Iso_project_fem2_i.prt ← Idealized part (CRITICAL for mesh update) β”œβ”€β”€ ACS_Stack_Main_Plate_Iso_project_fem2.fem ← FEM (3D solid, CHEXA/CTETRA) β”œβ”€β”€ ACS_Stack_Main_Plate_Iso_project_sim2.sim ← SOL 101 simulation └── acs_stack_main_plate_iso_project_sim2-solution_1.op2 ← Baseline FEA results ``` **Working copies (used by optimizer):** ``` studies/01_v1_tpe/1_setup/model/ β”œβ”€β”€ ACS_Stack_Main_Plate_Iso_Project.prt β”œβ”€β”€ ACS_Stack_Main_Plate_Iso_project_fem2_i.prt β”œβ”€β”€ ACS_Stack_Main_Plate_Iso_project_fem2.fem β”œβ”€β”€ ACS_Stack_Main_Plate_Iso_project_sim2.sim └── adaptive_isogrid_data/ β”œβ”€β”€ geometry_sandbox_1.json ← Sandbox boundary + holes └── geometry_sandbox_2.json ``` **Python Brain (canonical location):** ``` optimization_engine/isogrid/ β”œβ”€β”€ density_field.py ← Ξ·(x) field computation β”œβ”€β”€ triangulation.py ← Gmsh Frontal-Delaunay mesh β”œβ”€β”€ pocket_profiles.py ← Inset + fillet pockets β”œβ”€β”€ stress_feedback.py ← StressFeedbackField (RBF interpolator) └── study.py ← PARAM_SPACE, MANUFACTURING_CONSTRAINTS, MATERIAL optimization_engine/extractors/ └── extract_stress_field_2d.py ← OP2+BDF β†’ 2D stress field ``` --- ## 5. Rib Pattern Variants Tested Three density field configurations were tested for visual review in NX: | Variant | Ξ± | Ξ² | Pockets (S1+S2) | Mass Est. | Character | |---------|---|---|----------------|-----------|-----------| | Balanced | 1.0 | 0.3 | 86 + 33 = 119 | ~2,790g | Good general pattern | | Edge-focused | 0.3 | 1.5 | 167 + 10 = 177 | ~2,328g | Dense perimeter, sparse center | | Hole-focused | 1.8 | 0.15 | 62 + 37 = 99 | ~3,025g | Dense around holes, thin edges | All three were imported to NX using the update-in-place workflow (sketch preserved, extrude reference maintained). --- ## 6. Algorithm Recommendation **Optuna TPE (Tree-structured Parzen Estimator)** β€” standard Atomizer configuration. | Property | Value | |----------|-------| | Design variables | 8 continuous | | Objective | 1 (minimize mass) | | Constraint | 1 (stress β€” penalty-based; no displacement constraint) | | Trials budget | 200 (Campaign 01) | | Estimated iteration time | ~90–120 sec (NX mesh + Nastran + extract) | | Total runtime estimate | ~8–10 hours for 200 trials | In V1, `gamma_stress` is sampled by TPE but has no effect (no S_prev stress field available). In V2 (sequential seeding), S_prev is loaded from the globally best previous trial; `gamma_stress` then actively reshapes the density field toward high-stress zones. No extra FEA per trial. --- ## 7. Next Steps | Priority | Action | Status | |----------|--------|--------| | βœ… DONE | `studies/01_v1_tpe/run_optimization.py` created | β€” | | βœ… DONE | Material confirmed: AL7075-T6, Οƒ_allow = 100.6 MPa (SF=5) | β€” | | βœ… DONE | Model files copied to `studies/01_v1_tpe/1_setup/model/` | β€” | | βœ… DONE | Geometry JSONs in `1_setup/model/adaptive_isogrid_data/` | β€” | | πŸ”΄ HIGH | Run Campaign 01: `python studies/01_v1_tpe/run_optimization.py` | Pending | | 🟑 MED | Update MAT1 card in NX model to AL7075-T6 properties (Gap G-01) | Pending | | 🟑 MED | Extract baseline solid plate mass (Gap G-02) | Pending | | 🟒 LOW | Benchmark single iteration time for runtime planning | Pending | --- *Technical Lead πŸ”§ β€” 8 parameters, physics-driven, stress-only constraint, ready to run.*