docs: update KB and project docs with 2026-02-11 progress
- KB Gen 003: NX version (DesigncenterNX 2512), first real results - sol101-static.md: path resolution lessons, in-place solving, result extraction confirmed - CONTEXT.md: solver pipeline operational, first results (disp=17.93mm, stress=111.9MPa) - DECISIONS.md: DEC-HB-008 to DEC-HB-011 (backup/restore, iteration arch, history DB, git workflow) - optimization_engine/README.md: created (DesigncenterNX support, path resolution, NX file refs) - studies/01_doe_landscape/README.md: updated architecture, iteration folders, history DB - _index.md: closed gaps G3,G4,G6,G10-G14, updated generation to 003
This commit is contained in:
115
optimization_engine/README.md
Normal file
115
optimization_engine/README.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# Optimization Engine
|
||||
|
||||
Core optimization engine for Atomizer structural optimization projects.
|
||||
|
||||
## Overview
|
||||
|
||||
The optimization engine provides NX Nastran integration, result extraction, and optimization orchestration. Originally developed for the SAT3 mirror project, now generalized for multiple projects including Hydrotech Beam.
|
||||
|
||||
## NX Integration (`nx/`)
|
||||
|
||||
### Supported NX Versions
|
||||
|
||||
| Version | Status | Notes |
|
||||
|---------|--------|-------|
|
||||
| NX 2412 | ⚠️ Legacy | Original development version |
|
||||
| **DesigncenterNX 2512** | ✅ Current | Siemens rebranded NX to "DesigncenterNX". Install path: `C:\Program Files\Siemens\DesigncenterNX2512` |
|
||||
|
||||
> **Important:** Siemens rebranded NX to "DesigncenterNX" starting with version 2512. The install directory, executable paths, and search paths all use the new name. Solver configuration must specify `2512` and include `DesigncenterNX` in search paths.
|
||||
|
||||
### Key Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `solver.py` | NX solver interface — manages NX session, expression updates, solve execution |
|
||||
| `solve_simulation.py` | NX journal script — runs inside NXOpen Python, handles simple + assembly workflows |
|
||||
| `solve_simulation_simple.py` | Simplified journal for single-part (simple) workflow |
|
||||
| `updater.py` | Expression updater — writes `.exp` files, handles unit types |
|
||||
| `export_expressions.py` | Export expressions from NX model |
|
||||
| `import_expressions.py` | Import expressions into NX model |
|
||||
| `session_manager.py` | NX session lifecycle management |
|
||||
| `model_cleanup.py` | Model cleanup utilities |
|
||||
| `mesh_converter.py` | Mesh format conversion |
|
||||
|
||||
### Path Resolution — CRITICAL on Windows
|
||||
|
||||
**`Path.absolute()` on Windows does NOT resolve `..` components.** Use `Path.resolve()` everywhere.
|
||||
|
||||
```python
|
||||
# WRONG — NX cannot follow ".." in paths
|
||||
path = Path("../../models/Beam_sim1.sim").absolute()
|
||||
# → C:\...\studies\01_doe_landscape\..\..\models\Beam_sim1.sim ← BROKEN
|
||||
|
||||
# CORRECT — fully resolved path
|
||||
path = Path("../../models/Beam_sim1.sim").resolve()
|
||||
# → C:\...\projects\hydrotech-beam\models\Beam_sim1.sim ← WORKS
|
||||
```
|
||||
|
||||
This applies to ALL paths passed to NX journals, including:
|
||||
- `.sim` file path
|
||||
- `.exp` file path
|
||||
- Model directory path
|
||||
- Output file paths
|
||||
|
||||
### NX File References — In-Place Solving Required
|
||||
|
||||
NX `.sim` files store **absolute internal references** to `.fem` and `.prt` files. Copying model files to different directories breaks these references (`Parts.Open` returns `None`).
|
||||
|
||||
**Solution:** Always solve on master model files in-place. Use backup/restore for isolation between optimization trials:
|
||||
|
||||
1. Backup master model files before trial
|
||||
2. Write expressions, rebuild, solve in original location
|
||||
3. Archive outputs (OP2, F06) to trial-specific folder
|
||||
4. Restore master from backup
|
||||
|
||||
### Expression Units
|
||||
|
||||
When writing `.exp` files for NX:
|
||||
- Length design variables: unit = `MilliMeter`
|
||||
- Integer expressions (e.g., `hole_count`): unit = `Constant`
|
||||
- **Critical:** Using wrong unit silently corrupts the model
|
||||
|
||||
### Workflow Types
|
||||
|
||||
**Simple workflow** (single-part, e.g., Hydrotech Beam):
|
||||
```
|
||||
Beam.prt → Beam_fem1_i.prt → Beam_fem1.fem → Beam_sim1.sim
|
||||
```
|
||||
|
||||
**Assembly FEM workflow** (multi-part, e.g., SAT3 mirror):
|
||||
```
|
||||
Multiple .prt → .afm → .sim (node merge, label conflicts)
|
||||
```
|
||||
|
||||
The journal auto-detects workflow type by checking for `.afm` files.
|
||||
|
||||
## Result Extraction
|
||||
|
||||
### pyNastran Compatibility
|
||||
|
||||
pyNastran warns "nx version 2512 not supported" but **reads OP2 files correctly**. Safe to ignore the warning.
|
||||
|
||||
**Unit note:** pyNastran returns stress in kPa for NX models using kg-mm-s unit system. Divide by 1000 for MPa.
|
||||
|
||||
### Mass Extraction
|
||||
|
||||
Mass is extracted via NX expression `p173` (or project-specific expression). The journal writes the value to a temp file (`_temp_mass.txt`) after solve, which Python reads.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Python 3.10+
|
||||
- pyNastran (OP2 parsing)
|
||||
- NXOpen Python API (on Windows solver node)
|
||||
- Optuna (optimization orchestration)
|
||||
- scipy, numpy, pandas
|
||||
|
||||
## Projects Using This Engine
|
||||
|
||||
| Project | Status | NX Version | Workflow |
|
||||
|---------|--------|------------|----------|
|
||||
| Hydrotech Beam | Active (DOE Phase 1) | DesigncenterNX 2512 | Simple |
|
||||
| SAT3 Mirror | Legacy reference | NX 2412 | Assembly FEM |
|
||||
|
||||
---
|
||||
|
||||
*Last updated: 2026-02-11*
|
||||
@@ -117,6 +117,19 @@ Minimize beam mass while meeting displacement and stress constraints. Single-obj
|
||||
- Idealized part: `Beam_fem1_i.prt`
|
||||
- Simulation: `Beam_sim1.sim`
|
||||
- Solver: NX Nastran SOL 101 (static structural)
|
||||
- **NX Version:** DesigncenterNX 2512 (Siemens rebranded NX → "DesigncenterNX")
|
||||
- **Install path:** `C:\Program Files\Siemens\DesigncenterNX2512` (on dalidou)
|
||||
|
||||
## First Results (2026-02-11)
|
||||
|
||||
| Metric | Value | Notes |
|
||||
|--------|-------|-------|
|
||||
| Displacement | **17.93 mm** | At baseline-ish DVs |
|
||||
| Von Mises stress | **111.9 MPa** | At baseline-ish DVs |
|
||||
| Solve time | **~12 s/trial** | On dalidou (Windows) |
|
||||
| Mass extraction | Via `p173` expression | Journal writes `_temp_mass.txt` |
|
||||
|
||||
> Both constraints violated at baseline (disp > 10mm). Optimization will need to find stiffer/heavier designs or relaxed constraints.
|
||||
|
||||
## Future Expansion
|
||||
- Material alternatives: Aluminum 6061, Stainless Steel ANSI 310 (per Antoine, KBS session)
|
||||
@@ -127,9 +140,24 @@ Minimize beam mass while meeting displacement and stress constraints. Single-obj
|
||||
- 2026-02-08: Project received from Antoine
|
||||
- 2026-02-10: KBS sessions processed → Gen 002 KB update. BCs confirmed.
|
||||
- 2026-02-10: Binary introspection — all expression names/values confirmed. Mass = 1,133.01 kg.
|
||||
- 2026-02-11: NX version fixed (DesigncenterNX 2512), path resolution bugs fixed, iteration architecture finalized (backup/restore in-place), history DB added. First real solve results.
|
||||
|
||||
## Status
|
||||
Phase: Baseline characterized — proceeding to optimization strategy finalization
|
||||
Generation: 002 (+ introspection corrections)
|
||||
Phase: **DOE execution** — solver pipeline operational, first results obtained
|
||||
Generation: 003
|
||||
Channel: #project-hydrotech-beam
|
||||
Last KBS session: 2026-02-10T16:38:01
|
||||
Last update: 2026-02-11
|
||||
|
||||
### Solver Pipeline Status
|
||||
- ✅ NX journal solve working (DesigncenterNX 2512)
|
||||
- ✅ Mass extraction via `p173` expression
|
||||
- ✅ Displacement & stress extraction via pyNastran OP2 parsing
|
||||
- ✅ Iteration archival (params, results, OP2, F06)
|
||||
- ✅ History DB (SQLite + CSV, append-only, survives --clean)
|
||||
- ✅ Geometric pre-checks (hole overlap, web clearance)
|
||||
- 🔄 Full 51-trial DOE run pending
|
||||
|
||||
### Development Workflow
|
||||
- **Git only** for development (git push/pull between server and dalidou)
|
||||
- **Syncthing paused** to avoid conflicts during active development
|
||||
- Resume Syncthing for production/delivery phases
|
||||
|
||||
@@ -52,3 +52,36 @@ Numbered decision log. Check here before proposing anything that contradicts a p
|
||||
- **Decision:** All project data lives in `/repos/Atomizer/projects/`. This is the single source of truth for all current and future projects. Synced to Windows (dalidou) via Syncthing. No duplicate local folders.
|
||||
- **Rationale:** One place for everything — agents, CEO, and Windows all reference the same files. Version-controlled via Gitea, bidirectional sync via Syncthing.
|
||||
- **Status:** Approved
|
||||
|
||||
## DEC-HB-008: Backup/restore in-place solving (not iteration copies)
|
||||
- **Date:** 2026-02-11
|
||||
- **By:** CEO + Technical Lead 🔧
|
||||
- **Decision:** Solve on master model files **in-place** (in `models/` directory) using backup/restore for iteration isolation. Do NOT copy `.sim`/`.fem`/`.prt` files to per-iteration folders.
|
||||
- **Rationale:** NX `.sim` files store absolute internal references to `.fem` and `.prt` files. Copying model files to iteration folders breaks these references (`Parts.Open` returns `None`). Backup/restore preserves all internal references while still providing isolation between trials.
|
||||
- **Workflow per trial:**
|
||||
1. Restore master model files from backup
|
||||
2. Write `.exp` file with trial DVs, open `.sim`, rebuild, solve
|
||||
3. Archive outputs (OP2, F06, params.json, results.json) to `iterations/iterNNN/`
|
||||
4. Iteration folders contain outputs only — NOT model files
|
||||
- **Status:** Approved — implemented and tested
|
||||
|
||||
## DEC-HB-009: Iteration folder architecture
|
||||
- **Date:** 2026-02-11
|
||||
- **By:** CEO + Technical Lead 🔧
|
||||
- **Decision:** Each trial archived to `studies/01_doe_landscape/iterations/iterNNN/` with: `params.json`, `params.exp`, `results.json`, OP2, F06.
|
||||
- **Rationale:** Full traceability per trial. Any result can be audited, re-examined, or debugged. Smart retention policy keeps last 10 + best 3 with full data, strips the rest to save space.
|
||||
- **Status:** Approved — implemented in `iteration_manager.py`
|
||||
|
||||
## DEC-HB-010: Persistent history database
|
||||
- **Date:** 2026-02-11
|
||||
- **By:** Technical Lead 🔧
|
||||
- **Decision:** Maintain `history.db` (SQLite, append-only) + `history.csv` that survives `--clean` and Optuna resets. Logs all DVs, results, feasibility, timestamps across all studies.
|
||||
- **Rationale:** Optuna DB is study-scoped and can be cleaned/reset. History DB provides permanent record across studies, enabling cross-study learning, debugging, and auditability. Append-only means no data loss.
|
||||
- **Status:** Approved — implemented and tested
|
||||
|
||||
## DEC-HB-011: Git-only development workflow (Syncthing paused)
|
||||
- **Date:** 2026-02-11
|
||||
- **By:** CEO
|
||||
- **Decision:** During active development, use Git (push/pull) exclusively for code sync between server and dalidou. Syncthing paused to avoid conflicts.
|
||||
- **Rationale:** Syncthing's bidirectional sync creates conflicts when both sides edit files simultaneously during development. Git provides explicit merge control.
|
||||
- **Status:** Active — resume Syncthing for production/delivery phases
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Knowledge Base — Hydrotech Beam
|
||||
|
||||
**Project:** Hydrotech Beam Structural Optimization
|
||||
**Generation:** 002
|
||||
**Last updated:** 2026-02-10
|
||||
**Generation:** 003
|
||||
**Last updated:** 2026-02-11
|
||||
|
||||
---
|
||||
|
||||
@@ -10,13 +10,15 @@
|
||||
|
||||
I-beam optimization for a test fixture. Steel (AISI 1005) cantilever beam with lightening holes in the web. Goal: minimize mass from **1,133.01 kg** baseline while meeting displacement (≤ 10 mm) and stress (≤ 130 MPa) constraints.
|
||||
|
||||
**Key confirmed parameters (Gen 002 + Introspection):**
|
||||
**Key confirmed parameters (Gen 003):**
|
||||
- Beam length: 5,000 mm (`beam_lenght` ⚠️ typo in NX), cantilever — left fixed, right loaded
|
||||
- Load: 10,000 kgf downward at free end
|
||||
- Baseline mass: **1,133.01 kg** (expression `p173: body_property147.mass`)
|
||||
- DV baselines: face=21.504mm, core=25.162mm, holes_dia=300mm, hole_count=10
|
||||
- Material: AISI Steel 1005 (density 7.3 g/cm³)
|
||||
- Mesh: CQUAD4 thin shell, 33.7 mm element size
|
||||
- **Solver:** DesigncenterNX 2512 (NX Nastran SOL 101)
|
||||
- **First results (2026-02-11):** Displacement=17.93mm, Stress=111.9MPa, Solve time ~12s/trial
|
||||
|
||||
## Components
|
||||
|
||||
@@ -34,14 +36,15 @@ I-beam optimization for a test fixture. Steel (AISI 1005) cantilever beam with l
|
||||
|
||||
| Model | File | Status |
|
||||
|-------|------|--------|
|
||||
| Static Analysis (SOL 101) | [fea/models/sol101-static.md](fea/models/sol101-static.md) | ✅ Updated Gen 002 — BCs confirmed, baseline run needed |
|
||||
| Static Analysis (SOL 101) | [fea/models/sol101-static.md](fea/models/sol101-static.md) | ✅ Updated Gen 003 — Solver running, first results obtained |
|
||||
|
||||
## Generations
|
||||
|
||||
| Gen | Date | Summary |
|
||||
|-----|------|---------|
|
||||
| 001 | 2026-02-09 | Initial KB from intake + technical breakdown |
|
||||
| **002** | **2026-02-10** | **KBS session processing — confirmed geometry, BCs, mesh, material, mass correction** |
|
||||
| 002 | 2026-02-10 | KBS session processing — confirmed geometry, BCs, mesh, material, mass correction |
|
||||
| **003** | **2026-02-11** | **First real results! NX version fix (DesigncenterNX 2512), path resolution, backup/restore architecture, history DB, mass extraction via journal** |
|
||||
|
||||
## Gap Tracker
|
||||
|
||||
@@ -60,31 +63,29 @@ I-beam optimization for a test fixture. Steel (AISI 1005) cantilever beam with l
|
||||
| G5 | Hole geometric feasibility | Span = 4,000 mm, offsets = 500 mm fixed. Baseline: 10 holes × 300 mm → ~144 mm ligament (OK) | Need collision check at DV extremes. 15 × 450 mm WILL overlap. Need feasibility constraint. |
|
||||
| G9 | Stress allowable basis | AISI 1005 yield ~285 MPa. 130 MPa → SF ≈ 2.2 | Need confirmation that 130 MPa limit still applies to updated model. |
|
||||
|
||||
### ❓ STILL OPEN (from Gen 001)
|
||||
### ❓ STILL OPEN
|
||||
|
||||
| # | Item | Why It Matters | Priority |
|
||||
|---|------|---------------|----------|
|
||||
| G3 | Displacement measurement location | Which node(s)? Which DOF? Magnitude or component? | High |
|
||||
| G4 | Stress constraint scope | Whole model? Exclude supports? Hole edges? | High |
|
||||
| G6 | Result sensors in Beam_sim1.sim | Determines extractor approach | Medium |
|
||||
| G7 | NX parametric rebuild reliability | Untested across DV range | Medium |
|
||||
|
||||
### 🆕 NEW GAPS (from Gen 002)
|
||||
|
||||
| # | Item | Why It Matters | Priority |
|
||||
|---|------|---------------|----------|
|
||||
| G10 | Baseline displacement re-verification | 22 mm was from old model state (974 kg). True model is 11.33 kg — displacement likely different. | **High** |
|
||||
| G11 | Baseline stress value | Never measured. Essential for optimization setup. | **High** |
|
||||
| G12 | `beam_half_height` starting value | Expression exists but value not captured from KBS screenshots | Medium |
|
||||
| G13 | `beam_half_width` starting value | Expression exists but value not captured from KBS screenshots | Medium |
|
||||
| G14 | Hole diameter expression name | Need exact NX expression name (not just the value 300) | Medium |
|
||||
| G7 | NX parametric rebuild reliability | Untested across full DV range — need corner-case testing | Medium |
|
||||
| G15 | `p6` (hole_span) as potential DV | Antoine suggested it could be optimized. Decision needed. | Medium |
|
||||
|
||||
### ✅ CLOSED (Gen 003 — 2026-02-11)
|
||||
|
||||
| # | Item | Resolution | Closed In |
|
||||
|---|------|------------|-----------|
|
||||
| G3 | Displacement measurement location | Max Tz at free end, extracted via pyNastran OP2 | Gen 003 |
|
||||
| G4 | Stress constraint scope | Whole model max von Mises (CQUAD4 shell) | Gen 003 |
|
||||
| G6 | Result sensors in Beam_sim1.sim | Using pyNastran OP2 parsing, not NX sensors | Gen 003 |
|
||||
| G10 | Baseline displacement | 17.93 mm at baseline-ish DVs | Gen 003 |
|
||||
| G11 | Baseline stress | 111.9 MPa at baseline-ish DVs | Gen 003 |
|
||||
| G12 | `beam_half_height` value | 250 mm — confirmed via binary introspection | Gen 002+ |
|
||||
| G13 | `beam_half_width` value | 150 mm — confirmed via binary introspection | Gen 002+ |
|
||||
| G14 | Hole diameter expression name | `holes_diameter` — confirmed via binary introspection | Gen 002+ |
|
||||
|
||||
## Open Tasks
|
||||
|
||||
1. **Run baseline SOL 101** — get fresh displacement and stress values (G10, G11)
|
||||
2. **NX model introspection** — extract all expression names/values, check sensors (G6, G12, G13, G14)
|
||||
3. **Corner-case testing** — verify NX rebuild at DV extremes (G7)
|
||||
4. **Geometric feasibility constraint** — implement hole collision check (G5)
|
||||
5. **Update atomizer_spec_draft.json** — mass expression `p1`, baseline 11.33 kg
|
||||
6. **Decision on `p6` as DV** — consult Manager/CEO (G15)
|
||||
1. **Run full 51-trial DOE** — solver pipeline operational, execute Phase 1
|
||||
2. **Corner-case testing** — verify NX rebuild at DV extremes (G7)
|
||||
3. **Decision on `p6` as DV** — consult Manager/CEO (G15)
|
||||
4. **Phase 1 → Phase 2 gate review** — after DOE completes, assess feasibility landscape
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
**Simulation:** Beam_sim1.sim
|
||||
**Solver:** NX Nastran SOL 101 (Linear Static)
|
||||
**Status:** Setup confirmed from KBS session (Gen 002). Baseline run needed.
|
||||
**Status:** ✅ Running — first real results obtained 2026-02-11. Automated DOE pipeline operational.
|
||||
|
||||
---
|
||||
|
||||
@@ -29,15 +29,17 @@
|
||||
- Application: Right side (free end) of beam
|
||||
- Type: This is a **cantilever beam** with end loading — classic bending problem
|
||||
|
||||
## Result Extraction
|
||||
## Result Extraction — Confirmed (Gen 003)
|
||||
|
||||
| Output | Method | Expression/Sensor | Status |
|
||||
|--------|--------|-------------------|--------|
|
||||
| Mass | NX expression | **`p1`** (NOT `p173`) | ✅ Confirmed — 11.33 kg baseline |
|
||||
| Tip displacement | ❓ Sensor or .f06 parse | TBD | Gap G3, G6 — need baseline run |
|
||||
| Von Mises stress | ❓ Sensor or .f06 parse | TBD | Gap G4, G6 — need baseline run |
|
||||
| Mass | NX expression | **`p173`** (`body_property147.mass` in kg) | ✅ Confirmed — journal extracts to `_temp_mass.txt` |
|
||||
| Tip displacement | OP2 parse via pyNastran | Max Tz at free end | ✅ Working — 17.93 mm at baseline-ish DVs |
|
||||
| Von Mises stress | OP2 parse via pyNastran | CQUAD4 shell max VM | ✅ Working — 111.9 MPa at baseline-ish DVs |
|
||||
|
||||
> ⚠️ **Mass expression changed:** `p1` confirmed in KBS session, replacing previous assumption of `p173`. Extractor config must be updated.
|
||||
> **Mass extraction:** Journal extracts `p173` expression after solve and writes `_temp_mass.txt`. Python reads this file. Expression `p1` from KBS session was incorrect — `p173` confirmed via binary introspection.
|
||||
>
|
||||
> **pyNastran note:** Warns "nx version 2512 not supported" but reads OP2 files correctly. Stress output from pyNastran is in kPa — divide by 1000 for MPa.
|
||||
|
||||
## Mesh Details
|
||||
|
||||
@@ -56,28 +58,68 @@
|
||||
|
||||
## Solver Considerations
|
||||
|
||||
*From Technical Breakdown (Gen 001), updated with KBS data:*
|
||||
*From Technical Breakdown (Gen 001), updated with KBS data + Gen 003 run data:*
|
||||
|
||||
- **Linear assumption:** With 11.33 kg beam under 98 kN load, deflections may be significant relative to beam dimensions. L/δ ratio needs verification from baseline run.
|
||||
- **Linear assumption:** With 1,133 kg beam under 98 kN load, deflections are ~18 mm at 5,000 mm span. L/δ ≈ 280 — linear assumption is reasonable.
|
||||
- **Mesh sensitivity:** Stress at hole edges is mesh-dependent. CQUAD4 at 33.7 mm may not fully resolve SCF at 300 mm diameter holes (~28 elements around circumference — probably adequate but needs verification).
|
||||
- **Mesh morphing vs remesh:** Parametric NX models typically remesh on update. Need to confirm behavior across DV range (Gap G7).
|
||||
- **Runtime estimate:** Single beam, CQUAD4 thin shell → likely **seconds per evaluation**. Very fast.
|
||||
- **Runtime:** ✅ Confirmed **~12 seconds per evaluation** (single beam, CQUAD4 thin shell on dalidou). Very fast.
|
||||
- **Unit system:** NX model uses kg-mm-s (kgf for force). Nastran output stress in kPa → divide by 1000 for MPa.
|
||||
|
||||
## Validation Checklist
|
||||
|
||||
- [ ] Baseline mass matches NX expression `p1` (11.33 kg)
|
||||
- [ ] Baseline displacement measured (was 22 mm at old model state — **needs re-verification** G10)
|
||||
- [ ] Baseline stress measured (never had a value — **G11**)
|
||||
- [x] Baseline mass matches NX expression `p173` (1,133.01 kg)
|
||||
- [x] Displacement measured — 17.93 mm at baseline-ish DVs (G10 closed)
|
||||
- [x] Stress measured — 111.9 MPa at baseline-ish DVs (G11 closed)
|
||||
- [ ] Mesh convergence verified at baseline
|
||||
- [ ] Mesh quality acceptable at DV range extremes
|
||||
- [ ] Model rebuilds cleanly at all 4 corners of design space (Gap G7)
|
||||
- [ ] Stress at hole edges resolved with current mesh density
|
||||
|
||||
## NX Version & Environment — Confirmed (Gen 003)
|
||||
|
||||
| Item | Value | Notes |
|
||||
|------|-------|-------|
|
||||
| **NX Version** | **DesigncenterNX 2512** | Siemens rebranded NX to "DesigncenterNX" |
|
||||
| **Install path** | `C:\Program Files\Siemens\DesigncenterNX2512` | On dalidou (Windows solver node) |
|
||||
| **Previous config** | NX 2412 | ❌ Failed — "Part file is from a newer version" |
|
||||
| **pyNastran compat** | Warns "nx version 2512 not supported" | ✅ But reads OP2 files correctly |
|
||||
|
||||
> ⚠️ **Critical lesson (2026-02-11):** Solver was originally configured for NX 2412 but model files are from DesigncenterNX 2512. NX refuses to load with "Part file is from a newer version." Must match version exactly.
|
||||
|
||||
### Path Resolution on Windows — Critical
|
||||
|
||||
**Bug discovered:** `Path.absolute()` on Windows does **NOT** resolve `..` components (unlike `Path.resolve()`).
|
||||
|
||||
```python
|
||||
# WRONG — leaves ".." in path, NX can't find referenced parts
|
||||
path = Path("../../models/Beam_sim1.sim").absolute()
|
||||
# → C:\Users\antoi\Atomizer\projects\hydrotech-beam\studies\01_doe_landscape\..\..\models\Beam_sim1.sim
|
||||
|
||||
# CORRECT — fully resolves path
|
||||
path = Path("../../models/Beam_sim1.sim").resolve()
|
||||
# → C:\Users\antoi\Atomizer\projects\hydrotech-beam\models\Beam_sim1.sim
|
||||
```
|
||||
|
||||
**Rule:** Use `.resolve()` everywhere when constructing paths for NX. NX cannot follow `..` references in paths.
|
||||
|
||||
### NX File References — In-Place Solving Required
|
||||
|
||||
NX `.sim` files store **absolute internal references** to `.fem` and `.prt` files. Copying model files to iteration folders breaks these references (`Parts.Open` returns `None`).
|
||||
|
||||
**Solution:** Solve on master model **in-place** (in the `models/` directory) with backup/restore for isolation:
|
||||
1. Backup master model files before each trial
|
||||
2. Write expressions, rebuild, solve in `models/`
|
||||
3. Archive outputs (OP2, F06, params, results) to iteration folder
|
||||
4. Restore master from backup
|
||||
|
||||
See DEC-HB-008 in DECISIONS.md.
|
||||
|
||||
## History
|
||||
|
||||
- **Gen 001** (2026-02-09): Initial documentation from technical breakdown. All solver details pending gap resolution.
|
||||
- **Gen 002** (2026-02-10): Confirmed from KBS session — CQUAD4 thin shell, 33.7 mm element size, cantilever BCs (left fixed, right 10,000 kgf down), mass via `p1`. Material: AISI 1005.
|
||||
- **Gen 002** (2026-02-10): Confirmed from KBS session — CQUAD4 thin shell, 33.7 mm element size, cantilever BCs (left fixed, right 10,000 kgf down), mass via `p173`. Material: AISI 1005.
|
||||
- **Gen 003** (2026-02-11): First real results! DesigncenterNX 2512 version confirmed, path resolution bugs fixed, backup/restore in-place solving architecture, mass extraction via journal. Displacement=17.93mm, Stress=111.9MPa, Solve time ~12s/trial.
|
||||
|
||||
## NX Automation Workflow
|
||||
|
||||
|
||||
@@ -16,7 +16,10 @@ Map the design space of the Hydrotech sandwich I-beam to identify feasible regio
|
||||
| **Algorithm** | Phase 1: LHS DoE (50 trials + 1 baseline) |
|
||||
| **Total budget** | 51 evaluations |
|
||||
| **Constraint handling** | Deb's feasibility rules (Optuna constraint interface) |
|
||||
| **Status** | Code complete — ready for execution |
|
||||
| **Status** | ✅ Pipeline operational — first results obtained 2026-02-11 |
|
||||
| **Solver** | DesigncenterNX 2512 (NX Nastran SOL 101) |
|
||||
| **Solve time** | ~12 s/trial (~10 min for full DOE) |
|
||||
| **First results** | Displacement=17.93mm, Stress=111.9MPa |
|
||||
|
||||
## Design Variables (confirmed via NX binary introspection)
|
||||
|
||||
@@ -56,10 +59,14 @@ python run_doe.py --backend stub --study-name my_test_run
|
||||
### Production Run (NXOpen on Windows)
|
||||
|
||||
```bash
|
||||
# On dalidou (Windows node with NX):
|
||||
python run_doe.py --backend nxopen --model-dir "C:/path/to/syncthing/Beam"
|
||||
# On dalidou (Windows node with DesigncenterNX 2512):
|
||||
cd C:\Users\antoi\Atomizer\projects\hydrotech-beam\studies\01_doe_landscape
|
||||
conda activate atomizer
|
||||
python run_doe.py --backend nxopen --model-dir "../../models"
|
||||
```
|
||||
|
||||
> ⚠️ `--model-dir` can be relative — the code resolves it with `Path.resolve()`. NX requires fully resolved paths (no `..` components).
|
||||
|
||||
### Resume Interrupted Study
|
||||
|
||||
```bash
|
||||
@@ -77,6 +84,7 @@ python run_doe.py --backend stub --resume --study-name hydrotech_beam_doe_phase1
|
||||
| `--seed` | 42 | Random seed for reproducibility |
|
||||
| `--results-dir` | `results/` | Output directory |
|
||||
| `--resume` | false | Resume existing study |
|
||||
| `--clean` | false | Delete Optuna DB and start fresh (history DB preserved) |
|
||||
| `-v` | false | Verbose (DEBUG) logging |
|
||||
|
||||
## Files
|
||||
@@ -86,10 +94,12 @@ python run_doe.py --backend stub --resume --study-name hydrotech_beam_doe_phase1
|
||||
| `run_doe.py` | Main entry point — orchestrates the DoE study |
|
||||
| `sampling.py` | LHS generation with stratified integer sampling |
|
||||
| `geometric_checks.py` | Pre-flight geometric feasibility filter |
|
||||
| `nx_interface.py` | NX automation module (stub + NXOpen template) |
|
||||
| `nx_interface.py` | AtomizerNXSolver wrapping optimization_engine |
|
||||
| `iteration_manager.py` | Smart retention — last 10 + best 3 with full data |
|
||||
| `requirements.txt` | Python dependencies |
|
||||
| `OPTIMIZATION_STRATEGY.md` | Full strategy document |
|
||||
| `results/` | Output directory (CSV, JSON, Optuna DB) |
|
||||
| `iterations/` | Per-trial archived outputs |
|
||||
|
||||
## Output Files
|
||||
|
||||
@@ -100,23 +110,44 @@ After a study run, `results/` will contain:
|
||||
| `doe_results.csv` | All trials — DVs, objectives, constraints, status |
|
||||
| `doe_summary.json` | Study metadata, statistics, best feasible design |
|
||||
| `optuna_study.db` | SQLite database (Optuna persistence, resume support) |
|
||||
| `history.db` | **Persistent** SQLite — all DVs, results, feasibility (survives `--clean`) |
|
||||
| `history.csv` | CSV mirror of history DB |
|
||||
|
||||
### Iteration Folders
|
||||
|
||||
Each trial produces `iterations/iterNNN/` containing:
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `params.json` | Design variable values for this trial |
|
||||
| `params.exp` | NX expression file used for this trial |
|
||||
| `results.json` | Extracted results (mass, displacement, stress, feasibility) |
|
||||
| `*.op2` | Nastran binary results (for post-processing) |
|
||||
| `*.f06` | Nastran text output (for debugging) |
|
||||
|
||||
**Smart retention policy** (runs every 5 iterations):
|
||||
- Keep last 10 iterations with full data
|
||||
- Keep best 3 feasible iterations with full data
|
||||
- Strip model files from all others, keep solver outputs
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
run_doe.py
|
||||
├── sampling.py Generate 50 LHS + 1 baseline
|
||||
├── sampling.py Generate 50 LHS + 1 baseline
|
||||
│ └── scipy.stats.qmc.LatinHypercube
|
||||
├── geometric_checks.py Pre-flight feasibility filter
|
||||
├── geometric_checks.py Pre-flight feasibility filter
|
||||
│ ├── Hole overlap: span/(n-1) - d ≥ 30mm
|
||||
│ └── Web clearance: 500 - 2·face - d > 0
|
||||
├── nx_interface.py NX solver (stub or NXOpen)
|
||||
│ ├── NXStubSolver → synthetic results (development)
|
||||
│ └── NXOpenSolver → real NX Nastran SOL 101 (production)
|
||||
└── Optuna study
|
||||
├── SQLite storage (resume support)
|
||||
├── Enqueued trials (deterministic LHS)
|
||||
└── Deb's feasibility rules (constraint interface)
|
||||
├── nx_interface.py AtomizerNXSolver (wraps optimization_engine)
|
||||
│ ├── NXStubSolver → synthetic results (development)
|
||||
│ └── AtomizerNXSolver → real DesigncenterNX 2512 SOL 101 (production)
|
||||
├── iteration_manager.py Smart retention (last 10 + best 3)
|
||||
├── Optuna study
|
||||
│ ├── SQLite storage (resume support)
|
||||
│ ├── Enqueued trials (deterministic LHS)
|
||||
│ └── Deb's feasibility rules (constraint interface)
|
||||
└── history.db Persistent history (append-only, survives --clean)
|
||||
```
|
||||
|
||||
## Pipeline per Trial
|
||||
@@ -130,15 +161,24 @@ Trial N
|
||||
│ ├── FAIL → record as infeasible, skip NX
|
||||
│ └── PASS ↓
|
||||
│
|
||||
├── 3. NX evaluation
|
||||
│ ├── Update expressions (exact NX names)
|
||||
│ ├── Rebuild model
|
||||
│ ├── Solve SOL 101
|
||||
│ └── Extract: mass (p173), displacement, stress
|
||||
├── 3. Restore master model from backup
|
||||
│
|
||||
├── 4. Record results + constraint violations
|
||||
├── 4. NX evaluation (IN-PLACE in models/ directory)
|
||||
│ ├── Write .exp file with trial DVs
|
||||
│ ├── Open .sim (loads model chain)
|
||||
│ ├── Import expressions, rebuild geometry
|
||||
│ ├── Update FEM (remesh)
|
||||
│ ├── Solve SOL 101 (~12s)
|
||||
│ └── Extract: mass (p173 → _temp_mass.txt), displacement, stress (via OP2)
|
||||
│
|
||||
└── 5. Log to CSV + Optuna DB
|
||||
├── 5. Archive outputs to iterations/iterNNN/
|
||||
│ └── params.json, params.exp, results.json, OP2, F06
|
||||
│
|
||||
├── 6. Record results + constraint violations
|
||||
│
|
||||
├── 7. Log to Optuna DB + history.db + CSV
|
||||
│
|
||||
└── 8. Smart retention check (every 5 iterations)
|
||||
```
|
||||
|
||||
## Phase 1 → Phase 2 Gate Criteria
|
||||
@@ -162,18 +202,26 @@ Before proceeding to Phase 2 (TPE optimization), these checks must pass:
|
||||
|
||||
## NX Integration Notes
|
||||
|
||||
**Solver:** DesigncenterNX 2512 (Siemens rebrand of NX). Install: `C:\Program Files\Siemens\DesigncenterNX2512`.
|
||||
|
||||
The `nx_interface.py` module provides:
|
||||
- **`NXStubSolver`** — synthetic results from simplified beam mechanics (for pipeline testing)
|
||||
- **`NXOpenSolver`** — template for real NXOpen Python API integration (to be completed on Windows)
|
||||
- **`AtomizerNXSolver`** — wraps `optimization_engine` NXSolver for real DesigncenterNX 2512 solves
|
||||
|
||||
Expression names are exact from binary introspection. Critical: `beam_lenght` has a typo in NX (no 'h') — use exact spelling.
|
||||
|
||||
### Outputs to extract from NX:
|
||||
### Outputs extracted from NX:
|
||||
| Output | Source | Unit | Notes |
|
||||
|--------|--------|------|-------|
|
||||
| Mass | Expression `p173` | kg | Direct read |
|
||||
| Tip displacement | SOL 101 results | mm | TBD: sensor or .op2 parsing |
|
||||
| Max VM stress | SOL 101 results | MPa | ⚠️ pyNastran returns kPa — divide by 1000 |
|
||||
| Mass | Expression `p173` → `_temp_mass.txt` | kg | Journal extracts after solve |
|
||||
| Tip displacement | OP2 parse via pyNastran | mm | Max Tz at free end |
|
||||
| Max VM stress | OP2 parse via pyNastran | MPa | ⚠️ pyNastran returns kPa — divide by 1000 |
|
||||
|
||||
### Critical Lessons Learned (2026-02-11)
|
||||
1. **Path resolution:** Use `Path.resolve()` NOT `Path.absolute()` on Windows. `.absolute()` doesn't resolve `..` components — NX can't follow them.
|
||||
2. **File references:** NX `.sim` files have absolute internal refs to `.fem`/`.prt`. Never copy model files to iteration folders — solve in-place with backup/restore.
|
||||
3. **NX version:** Must match exactly. Model files from 2512 won't load in 2412 ("Part file is from a newer version").
|
||||
4. **pyNastran:** Warns about unsupported NX version 2512 but works fine. Safe to ignore.
|
||||
|
||||
## References
|
||||
|
||||
@@ -184,4 +232,4 @@ Expression names are exact from binary introspection. Critical: `beam_lenght` ha
|
||||
|
||||
---
|
||||
|
||||
*Code: 🏗️ Study Builder (Technical Lead) | Strategy: ⚡ Optimizer Agent | 2026-02-10*
|
||||
*Code: 🏗️ Study Builder (Technical Lead) | Strategy: ⚡ Optimizer Agent | Updated: 2026-02-11*
|
||||
|
||||
Reference in New Issue
Block a user