refactor: Engine updates and NX hooks improvements

optimization_engine:
- Updated nx_solver.py with improvements
- Enhanced solve_simulation.py
- Updated extractors/__init__.py
- Improved NX CAD hooks (expression_manager, feature_manager,
  geometry_query, model_introspection, part_manager)
- Enhanced NX CAE solver_manager hook

Documentation:
- Updated OP_01_CREATE_STUDY.md protocol
- Updated SYS_12_EXTRACTOR_LIBRARY.md

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2025-12-20 13:47:21 -05:00
parent 7c700c4606
commit 274081d977
12 changed files with 698 additions and 48 deletions

View File

@@ -31,26 +31,44 @@ This protocol guides you through creating a complete Atomizer optimization study
## Quick Reference
**Required Outputs**:
| File | Purpose | Location |
|------|---------|----------|
| `optimization_config.json` | Design vars, objectives, constraints | `1_setup/` |
| `run_optimization.py` | Execution script | Study root |
| `README.md` | Engineering documentation | Study root |
| `STUDY_REPORT.md` | Results template | Study root |
**Required Outputs** (ALL MANDATORY - study is INCOMPLETE without these):
| File | Purpose | Location | Priority |
|------|---------|----------|----------|
| `optimization_config.json` | Design vars, objectives, constraints | `1_setup/` | 1 |
| `run_optimization.py` | Execution script | Study root | 2 |
| **`README.md`** | Engineering documentation | Study root | **3 - NEVER SKIP** |
| `STUDY_REPORT.md` | Results template | Study root | 4 |
**CRITICAL**: README.md is MANDATORY for every study. A study without README.md is INCOMPLETE.
**Study Structure**:
```
studies/{study_name}/
studies/{geometry_type}/{study_name}/
├── 1_setup/
│ ├── model/ # NX files (.prt, .sim, .fem)
│ └── optimization_config.json
├── 2_results/ # Created during run
├── 2_iterations/ # FEA trial folders (iter1, iter2, ...)
├── 3_results/ # Optimization outputs (study.db, logs)
├── README.md # MANDATORY
├── STUDY_REPORT.md # MANDATORY
└── run_optimization.py
```
**IMPORTANT: Studies are organized by geometry type**:
| Geometry Type | Folder | Examples |
|---------------|--------|----------|
| M1 Mirror | `studies/M1_Mirror/` | m1_mirror_adaptive_V14, m1_mirror_cost_reduction_V3 |
| Simple Bracket | `studies/Simple_Bracket/` | bracket_stiffness_optimization |
| UAV Arm | `studies/UAV_Arm/` | uav_arm_optimization |
| Drone Gimbal | `studies/Drone_Gimbal/` | drone_gimbal_arm_optimization |
| Simple Beam | `studies/Simple_Beam/` | simple_beam_optimization |
| Other/Test | `studies/_Other/` | training_data_export_test |
When creating a new study:
1. Identify the geometry type (mirror, bracket, beam, etc.)
2. Place study under the appropriate `studies/{geometry_type}/` folder
3. For new geometry types, create a new folder with descriptive name
---
## Detailed Steps
@@ -357,6 +375,34 @@ _To be filled after run_
_To be filled after analysis_
```
### Step 7b: Capture Baseline Geometry Images (Recommended)
For better documentation, capture images of the starting geometry using the NX journal:
```bash
# Capture baseline images for study documentation
"C:\Program Files\Siemens\DesigncenterNX2512\NXBIN\run_journal.exe" ^
"C:\Users\antoi\Atomizer\nx_journals\capture_study_images.py" ^
-args "path/to/model.prt" "1_setup/" "model_name"
```
This generates:
- `1_setup/{model_name}_Top.png` - Top view
- `1_setup/{model_name}_iso.png` - Isometric view
**Include in README.md**:
```markdown
## Baseline Geometry
![Model - Top View](1_setup/model_name_Top.png)
*Top view description*
![Model - Isometric View](1_setup/model_name_iso.png)
*Isometric view description*
```
**Journal location**: `nx_journals/capture_study_images.py`
### Step 8: Validate NX Model File Chain
**CRITICAL**: NX simulation files have parent-child dependencies. ALL linked files must be copied to the study folder.
@@ -394,16 +440,26 @@ _To be filled after analysis_
### Step 9: Final Validation Checklist
Before running:
**CRITICAL**: Study is NOT complete until ALL items are checked:
- [ ] NX files exist in `1_setup/model/`
- [ ] **ALL child parts copied** (especially `*_i.prt`)
- [ ] Expression names match model
- [ ] Config validates (JSON schema)
- [ ] `run_optimization.py` has no syntax errors
- [ ] README.md has all 11 sections
- [ ] **README.md exists** (MANDATORY - study is incomplete without it!)
- [ ] README.md contains: Overview, Objectives, Constraints, Design Variables, Settings, Usage, Structure
- [ ] STUDY_REPORT.md template exists
**README.md Minimum Content**:
1. Overview/Purpose
2. Objectives with weights
3. Constraints (if any)
4. Design variables with ranges
5. Optimization settings
6. Usage commands
7. Directory structure
---
## Examples

View File

@@ -55,6 +55,8 @@ The Extractor Library provides centralized, reusable functions for extracting ph
| E16 | Thermal Gradient | `extract_temperature_gradient()` | .op2 | K/mm |
| E17 | Heat Flux | `extract_heat_flux()` | .op2 | W/mm² |
| E18 | Modal Mass | `extract_modal_mass()` | .f06 | kg |
| **Phase 4 (2025-12-19)** | | | | |
| E19 | Part Introspection | `introspect_part()` | .prt | dict |
---
@@ -581,6 +583,109 @@ ratio = get_modal_mass_ratio(f06_file, direction='z', n_modes=10) # 0-1
---
## Phase 4 Extractors (2025-12-19)
### E19: Part Introspection (Comprehensive)
**Module**: `optimization_engine.extractors.introspect_part`
Comprehensive introspection of NX .prt files. Extracts everything available from a part in a single call.
**Prerequisites**: Uses PowerShell with proper license server setup (see LAC workaround).
```python
from optimization_engine.extractors import (
introspect_part,
get_expressions_dict,
get_expression_value,
print_introspection_summary
)
# Full introspection
result = introspect_part("path/to/model.prt")
# Returns: {
# 'success': bool,
# 'part_file': str,
# 'expressions': {
# 'user': [{'name', 'value', 'rhs', 'units', 'type'}, ...],
# 'internal': [...],
# 'user_count': int,
# 'total_count': int
# },
# 'mass_properties': {
# 'mass_kg': float,
# 'mass_g': float,
# 'volume_mm3': float,
# 'surface_area_mm2': float,
# 'center_of_gravity_mm': [x, y, z]
# },
# 'materials': {
# 'assigned': [{'name', 'body', 'properties': {...}}],
# 'available': [...]
# },
# 'bodies': {
# 'solid_bodies': [{'name', 'is_solid', 'attributes': [...]}],
# 'sheet_bodies': [...],
# 'counts': {'solid', 'sheet', 'total'}
# },
# 'attributes': [{'title', 'type', 'value'}, ...],
# 'groups': [{'name', 'member_count', 'members': [...]}],
# 'features': {
# 'total_count': int,
# 'by_type': {'Extrude': 5, 'Revolve': 2, ...}
# },
# 'datums': {
# 'planes': [...],
# 'csys': [...],
# 'axes': [...]
# },
# 'units': {
# 'base_units': {'Length': 'MilliMeter', ...},
# 'system': 'Metric (mm)'
# },
# 'linked_parts': {
# 'loaded_parts': [...],
# 'fem_parts': [...],
# 'sim_parts': [...],
# 'idealized_parts': [...]
# }
# }
# Convenience functions
expr_dict = get_expressions_dict(result) # {'name': value, ...}
pocket_radius = get_expression_value(result, 'Pocket_Radius') # float
# Print formatted summary
print_introspection_summary(result)
```
**What It Extracts**:
- **Expressions**: All user and internal expressions with values, RHS formulas, units
- **Mass Properties**: Mass, volume, surface area, center of gravity
- **Materials**: Material names and properties (density, Young's modulus, etc.)
- **Bodies**: Solid and sheet bodies with their attributes
- **Part Attributes**: All NX_* system attributes plus user attributes
- **Groups**: Named groups and their members
- **Features**: Feature tree summary by type
- **Datums**: Datum planes, coordinate systems, axes
- **Units**: Base units and unit system
- **Linked Parts**: FEM, SIM, idealized parts loaded in session
**Use Cases**:
- Study setup: Extract actual expression values for baseline
- Debugging: Verify model state before optimization
- Documentation: Generate part specifications
- Validation: Compare expected vs actual parameter values
**NX Journal Execution** (LAC Workaround):
```python
# CRITICAL: Use PowerShell with [Environment]::SetEnvironmentVariable()
# NOT cmd /c SET or $env: syntax (these fail)
powershell -Command "[Environment]::SetEnvironmentVariable('SPLM_LICENSE_SERVER', '28000@server', 'Process'); & 'run_journal.exe' 'introspect_part.py' -args 'model.prt' 'output_dir'"
```
---
## Implementation Files
```
@@ -603,11 +708,13 @@ optimization_engine/extractors/
├── extract_spc_forces.py # E14 (Phase 2)
├── extract_temperature.py # E15, E16, E17 (Phase 3)
├── extract_modal_mass.py # E18 (Phase 3)
├── introspect_part.py # E19 (Phase 4)
├── test_phase2_extractors.py # Phase 2 tests
└── test_phase3_extractors.py # Phase 3 tests
nx_journals/
── extract_part_mass_material.py # E11 NX journal (prereq)
── extract_part_mass_material.py # E11 NX journal (prereq)
└── introspect_part.py # E19 NX journal (comprehensive introspection)
```
---
@@ -620,3 +727,4 @@ nx_journals/
| 1.1 | 2025-12-06 | Added Phase 2: E12 (principal stress), E13 (strain energy), E14 (SPC forces) |
| 1.2 | 2025-12-06 | Added Phase 3: E15-E17 (thermal), E18 (modal mass) |
| 1.3 | 2025-12-07 | Added Element Type Selection Guide; documented shell vs solid stress columns |
| 1.4 | 2025-12-19 | Added Phase 4: E19 (comprehensive part introspection) |