2026-02-19 08:00:15 +00:00
|
|
|
|
# Study 01 — TPE v1: Isogrid Mass Minimization (Campaign 01)
|
|
|
|
|
|
|
|
|
|
|
|
**Parent project:** [isogrid-dev-plate](../../README.md)
|
|
|
|
|
|
**Context:** [../../CONTEXT.md](../../CONTEXT.md)
|
|
|
|
|
|
**Status:** Ready to run — not yet started
|
|
|
|
|
|
**Created:** 2026-02-18
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 1. Overview
|
|
|
|
|
|
|
|
|
|
|
|
This is the first optimization campaign for the ACS Stack Main Plate isogrid lightweighting project.
|
|
|
|
|
|
It uses Optuna TPE (Tree-structured Parzen Estimator) with a budget of 200 trials.
|
|
|
|
|
|
|
|
|
|
|
|
**Goal:** Find the set of 8 density-field parameters that minimizes total plate mass subject to a
|
|
|
|
|
|
stress constraint (σ_max ≤ 100.6 MPa, AL7075-T6, SF=5).
|
|
|
|
|
|
|
|
|
|
|
|
Each trial: Python Brain generates a triangular isogrid rib pattern → NX imports it into the sketch
|
|
|
|
|
|
→ NX Nastran solves SOL 101 → extractors pull mass from the idealized part and max stress from the OP2.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 2. Engineering Problem
|
|
|
|
|
|
|
|
|
|
|
|
**Client:** ACS — Attitude Control System, spacecraft structural assembly
|
|
|
|
|
|
**Part:** Main structural plate (AL7075-T6)
|
|
|
|
|
|
**Challenge:** Remove as much material as possible from the plate interior via an isogrid rib pattern,
|
|
|
|
|
|
while keeping peak stress within the allowable under the primary axial load case.
|
|
|
|
|
|
|
|
|
|
|
|
**Load case:** FZ = 1,372.9 N, linear static (SOL 101), Subcase 1
|
|
|
|
|
|
**Material:** AL7075-T6 — σ_yield = 503 MPa, ρ = 2810 kg/m³, SF = 5 → σ_allow = 100.6 MPa
|
|
|
|
|
|
|
|
|
|
|
|
The rib pattern is generated in 2 sandbox regions. Ribs automatically cluster around bolt holes
|
|
|
|
|
|
and the plate perimeter based on physics-inspired density field parameters.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 3. Mathematical Formulation
|
|
|
|
|
|
|
|
|
|
|
|
### Objective
|
|
|
|
|
|
```
|
|
|
|
|
|
minimize mass_kg(η₀, α, β, γ_stress, R₀, R_edge, s_min, s_max)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Constraint
|
|
|
|
|
|
```
|
|
|
|
|
|
subject to σ_max ≤ 100.6 MPa (stress only — no displacement constraint)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Penalty
|
|
|
|
|
|
```
|
|
|
|
|
|
objective_value = mass_kg + penalty
|
|
|
|
|
|
|
|
|
|
|
|
penalty = 1e4 × ((σ_max / σ_allow) − 1)² if σ_max > σ_allow
|
|
|
|
|
|
= 0 otherwise
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### Design Variables
|
|
|
|
|
|
|
|
|
|
|
|
| Variable | Low | High | Units | Description |
|
|
|
|
|
|
|----------|-----|------|-------|-------------|
|
|
|
|
|
|
| `eta_0` | 0.0 | 0.4 | — | Baseline density offset |
|
|
|
|
|
|
| `alpha` | 0.3 | 2.0 | — | Hole influence scale |
|
|
|
|
|
|
| `beta` | 0.0 | 1.0 | — | Edge influence scale |
|
|
|
|
|
|
| `gamma_stress` | 0.0 | 1.5 | — | FEA stress feedback gain |
|
|
|
|
|
|
| `R_0` | 10 | 100 | mm | Base hole influence radius |
|
|
|
|
|
|
| `R_edge` | 5 | 40 | mm | Edge influence radius |
|
2026-02-20 08:00:17 +00:00
|
|
|
|
| `s_min` | 15 | 35 | mm | Min cell size (densest) — manufacturing floor: 15 mm |
|
|
|
|
|
|
| `s_max` | 40 | 60 | mm | Max cell size (sparsest) — lower bound 40 guarantees s_min < s_max |
|
2026-02-19 08:00:15 +00:00
|
|
|
|
|
|
|
|
|
|
Fixed parameters (manufacturing constraints + math constants): see `optimization_engine/isogrid/study.py`.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 4. Optimization Algorithm
|
|
|
|
|
|
|
|
|
|
|
|
| Property | Value |
|
|
|
|
|
|
|----------|-------|
|
|
|
|
|
|
| Algorithm | Optuna TPE (Tree-structured Parzen Estimator) |
|
|
|
|
|
|
| Sampler seed | 42 |
|
|
|
|
|
|
| Direction | Minimize |
|
|
|
|
|
|
| N startup trials | 10 (random exploration before TPE kicks in) |
|
|
|
|
|
|
| Trial budget | 200 |
|
|
|
|
|
|
| Storage | SQLite — `3_results/study.db` |
|
|
|
|
|
|
| Study name | `isogrid_01_v1_tpe` |
|
|
|
|
|
|
|
|
|
|
|
|
TPE splits past trials at each parameter into "good" (low objective) and "bad" (high objective) groups,
|
|
|
|
|
|
then samples from the "good" region. With 8 continuous variables and 200 trials this is well within
|
|
|
|
|
|
TPE's effective range.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 5. Result Extraction
|
|
|
|
|
|
|
|
|
|
|
|
| Quantity | Extractor | Source |
|
|
|
|
|
|
|----------|-----------|--------|
|
|
|
|
|
|
| Mass | `extract_part_mass_material(_i.prt)` | `_temp_part_properties.json` written by `solve_simulation.py` journal |
|
|
|
|
|
|
| Max von Mises | `extract_solid_stress(op2_file, subcase=1)` | OP2 binary from Nastran solve |
|
|
|
|
|
|
|
|
|
|
|
|
Mass is extracted from the **idealized part** (`_fem2_i.prt`), not estimated by the Brain.
|
|
|
|
|
|
The NX journal writes a JSON temp file after each solve; the extractor reads it back.
|
|
|
|
|
|
|
|
|
|
|
|
> ⚠️ NX FEM model uses AL6061 material properties (E≈68.98 GPa, ρ=2.711e-6 kg/mm³).
|
|
|
|
|
|
> Mass extraction is therefore slightly low (~4% underestimate vs AL7075-T6).
|
|
|
|
|
|
> Tracked as Gap G-01 in CONTEXT.md.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 6. Study Structure
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
studies/01_v1_tpe/
|
|
|
|
|
|
├── README.md ← You are here
|
|
|
|
|
|
├── STUDY_REPORT.md ← Post-run results (fill after campaign)
|
|
|
|
|
|
├── check_preflight.py ← Quick validation before running
|
|
|
|
|
|
├── run_optimization.py ← Main optimization loop
|
|
|
|
|
|
│
|
|
|
|
|
|
├── 1_setup/ ← Model files (working copies — modified by NX each trial)
|
|
|
|
|
|
│ └── model/
|
|
|
|
|
|
│ ├── ACS_Stack_Main_Plate_Iso_Project.prt
|
|
|
|
|
|
│ ├── ACS_Stack_Main_Plate_Iso_project_fem2_i.prt ← CRITICAL
|
|
|
|
|
|
│ ├── 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 (from NX)
|
|
|
|
|
|
│ ├── geometry_sandbox_2.json
|
|
|
|
|
|
│ ├── rib_profile_sandbox_1.json ← Written per trial (current)
|
|
|
|
|
|
│ └── rib_profile_sandbox_2.json
|
|
|
|
|
|
│
|
|
|
|
|
|
├── 2_iterations/ ← Per-trial logs (auto-created at runtime)
|
|
|
|
|
|
│ ├── trial_0001/
|
|
|
|
|
|
│ │ ├── params.json ← Sampled design variables
|
|
|
|
|
|
│ │ ├── results.json ← mass, stress, SF, objective
|
|
|
|
|
|
│ │ ├── rib_profile_sandbox_1.json ← Rib geometry (copy)
|
|
|
|
|
|
│ │ └── rib_profile_sandbox_2.json
|
|
|
|
|
|
│ └── trial_NNNN/
|
|
|
|
|
|
│ └── ...
|
|
|
|
|
|
│
|
|
|
|
|
|
└── 3_results/ ← Optimization database + summary outputs
|
|
|
|
|
|
└── study.db ← Optuna SQLite (created on first run)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 7. Quick Start
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Step 1: Verify everything is ready
|
|
|
|
|
|
C:\Users\antoi\anaconda3\envs\atomizer\python.exe \
|
|
|
|
|
|
projects/isogrid-dev-plate/studies/01_v1_tpe/check_preflight.py
|
|
|
|
|
|
|
|
|
|
|
|
# Step 2: Launch
|
|
|
|
|
|
C:\Users\antoi\anaconda3\envs\atomizer\python.exe \
|
|
|
|
|
|
projects/isogrid-dev-plate/studies/01_v1_tpe/run_optimization.py
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
See [../../playbooks/01_FIRST_RUN.md](../../playbooks/01_FIRST_RUN.md) for full step-by-step including
|
|
|
|
|
|
monitoring, failure handling, and post-run analysis.
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 8. Expected Runtime
|
|
|
|
|
|
|
|
|
|
|
|
| Component | Estimate |
|
|
|
|
|
|
|-----------|----------|
|
|
|
|
|
|
| Brain (triangulation + pockets) | ~3–10 s |
|
|
|
|
|
|
| NX import journal | ~15–30 s |
|
|
|
|
|
|
| NX remesh + Nastran solve | ~60–90 s |
|
|
|
|
|
|
| Extraction (mass + stress) | ~1–3 s |
|
|
|
|
|
|
| **Total per trial** | **~90–120 s** |
|
|
|
|
|
|
| **200 trials** | **~8–10 hours** |
|
|
|
|
|
|
|
|
|
|
|
|
Actual per-trial time will vary with mesh complexity (pocket count affects remesh time).
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 9. Success Criteria
|
|
|
|
|
|
|
|
|
|
|
|
| Criterion | Target |
|
|
|
|
|
|
|-----------|--------|
|
|
|
|
|
|
| Mass reduction vs baseline | > 10% (aspirational: > 20%) |
|
|
|
|
|
|
| Feasibility rate | > 80% of trials (σ ≤ 100.6 MPa) |
|
|
|
|
|
|
| Best trial SF | ≥ 5.0 (σ_max ≤ 100.6 MPa) |
|
|
|
|
|
|
| Convergence | Best mass stable over last 50 trials |
|
|
|
|
|
|
|
|
|
|
|
|
Baseline solid plate mass: TBD (Gap G-02 — run `extract_part_mass_material` on unmodified model).
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
## 10. Results
|
|
|
|
|
|
|
|
|
|
|
|
> **[Campaign 01 not yet started]**
|
|
|
|
|
|
>
|
|
|
|
|
|
> Fill in after run. See [STUDY_REPORT.md](STUDY_REPORT.md) for the result template.
|
|
|
|
|
|
|
|
|
|
|
|
| Metric | Value |
|
|
|
|
|
|
|--------|-------|
|
|
|
|
|
|
| Status | 🔴 Not started |
|
|
|
|
|
|
| Trials completed | 0 / 200 |
|
|
|
|
|
|
| Best mass | — |
|
|
|
|
|
|
| Best trial | — |
|
|
|
|
|
|
| Best σ_max | — |
|
|
|
|
|
|
| Best SF | — |
|
|
|
|
|
|
| Feasibility rate | — |
|
|
|
|
|
|
| Runtime | — |
|