# Atomizer NX Open Automation Roadmap

## Plan de Match: Hooks, Extractors & Manipulators pour Optimisation FEA

**Date**: 2025-12-06
**Version**: 2.0 (merged with ATOMIZER_NXOPEN_MASTER_PLAN.md)
**Objectif**: Définir l'ensemble des fonctionnalités NX Open à implémenter pour un framework d'optimisation structurelle/thermique complet, basé sur la règle 80/20.

---

## Quick Reference: NX Open API Index

### Core Classes (verified via MCP)

| Class | Page ID | Primary Use |
|-------|---------|-------------|
| `NXOpen.Session` | a03318.html | Session singleton, part access |
| `NXOpen.Part` | a02434.html | Part operations, expressions |
| `NXOpen.BasePart` | a00266.html | Base class, common methods |
| `NXOpen.CAE.CaeSession` | a10510.html | CAE session, utilities |
| `NXOpen.CAE.FemPart` | - | FEM part, mesh access |
| `NXOpen.CAE.SimPart` | - | Simulation part, solutions |

### Key Collections & Managers (from NXOpen.Part)

| Manager | Access | Purpose |
|---------|--------|---------|
| `Expressions` | `part.Expressions` | Expression management |
| `MeasureManager` | `part.MeasureManager()` | Mass properties |
| `Bodies` | `part.Bodies()` | Body collection |
| `Features` | `part.Features()` | Feature collection |
| `MaterialManager` | `part.MaterialManager()` | Material assignment |

### CAE Managers (from NXOpen.CAE.CaeSession)

| Manager | Access | Purpose |
|---------|--------|---------|
| `MaterialUtils` | `cae_session.MaterialUtils()` | CAE material utilities |
| `AssociationUtils` | `cae_session.AssociationUtils()` | Geometry-FEM association |
| `PenetrationCheckManager` | `cae_session.PenetrationCheckManager()` | Contact check |

---

## 1. Analyse de l'Industrie MDO

### Fonctionnalités Standard (ce que font les concurrents)

| Fonctionnalité | HyperStudy | modeFRONTIER | HEEDS | OpenMDAO | Atomizer (actuel) |
|----------------|------------|--------------|-------|----------|-------------------|
| DOE (LHS, Sobol, etc.) | ✓ | ✓ | ✓ | ✓ | ✓ |
| Optimisation mono-objectif | ✓ | ✓ | ✓ | ✓ | ✓ |
| Multi-objectif (Pareto) | ✓ | ✓ | ✓ | ✓ | ✓ |
| Surrogate Models | ✓ | ✓ | ✓ | ✓ | ✓ (NN) |
| Kriging/Gaussian Process | ✓ | ✓ | ✓ | ✓ | ❌ |
| Robustesse/Fiabilité (RBDO) | ✓ | ✓ | ❌ | ✓ | ❌ |
| Sensibilité paramétrique | ✓ | ✓ | ✓ | ✓ | Partiel |
| Topology Optimization | ✓ | ❌ | ❌ | ❌ | ❌ |
| Workflow visuel | ✓ | ✓ | ✓ | ❌ | ❌ |
| Interface NX native | ❌ | ❌ | ✓ | ❌ | ✓ |

### Sources
- [Altair HyperStudy](https://altair.com/hyperstudy/)
- [modeFRONTIER](https://engineering.esteco.com/modefrontier/)
- [OpenMDAO](https://openmdao.org/)
- [M4 Engineering NXOpen Example](https://www.m4-engineering.com/automating-load-case-combination-and-enveloping-in-simcenter-3d-using-nxopen-python/)

---

## 2. Capacités Simcenter 13500

### Modules Disponibles avec ta Licence

| Module | Description | Utilisable pour Optimisation |
|--------|-------------|------------------------------|
| **NX Nastran Basic** | Static, Modal, Buckling | ✓ Priorité haute |
| **NX Nastran Dynamic** | Frequency/Transient Response | ✓ Priorité moyenne |
| **NX Nastran Thermal** | Heat Transfer (steady/transient) | ✓ Priorité haute |
| **NX Nastran Optimization** | SOL 200 (taille, forme) | ✓ Priorité moyenne |
| **Simcenter 3D Pre/Post** | Meshing, Results | ✓ Indispensable |

### Types d'Analyses Supportées

1. **Structurel Linéaire** (SOL 101)
   - Static stress/displacement
   - Reaction forces

2. **Modal** (SOL 103)
   - Natural frequencies
   - Mode shapes
   - Modal effective mass

3. **Buckling** (SOL 105)
   - Critical load factors
   - Buckling mode shapes

4. **Thermique** (SOL 153/159)
   - Steady-state heat transfer
   - Transient thermal
   - Thermal stress coupling

5. **Dynamique** (SOL 108/109/111/112)
   - Frequency response
   - Transient response
   - Random response

---

## 3. Architecture des Hooks NX Open

### 3.1 Hooks de Manipulation CAD (Priorité 1)

```
optimization_engine/
└── hooks/
    └── nx_cad/
        ├── __init__.py
        ├── part_manager.py      # Open/Save/Close parts
        ├── expression_manager.py # Get/Set expressions
        ├── feature_manager.py    # Suppress/Unsuppress features
        ├── geometry_query.py     # Query geometry (mass, volume, area)
        └── assembly_manager.py   # Component positioning
```

| Hook | Description | API NX Open | Priorité |
|------|-------------|-------------|----------|
| `open_part(path)` | Ouvrir une pièce | `Session.Parts.OpenBase()` | P1 |
| `close_part(save=False)` | Fermer une pièce | `Part.Close()` | P1 |
| `set_expression(name, value)` | Modifier expression | `Expression.SetValue()` | P1 |
| `get_expression(name)` | Lire expression | `Expression.Value` | P1 |
| `update_model()` | Mettre à jour le modèle | `Session.UpdateManager.DoUpdate()` | P1 |
| `suppress_feature(name)` | Supprimer feature | `Feature.Suppress()` | P2 |
| `get_mass_properties()` | Masse, CG, inertie | `MeasureManager.NewMassProperties()` | P1 |
| `export_parasolid(path)` | Exporter géométrie | `Part.SaveAs()` | P2 |

### 3.2 Hooks FEM/Meshing (Priorité 2)

```
optimization_engine/
└── hooks/
    └── nx_fem/
        ├── __init__.py
        ├── mesh_manager.py       # Create/Update mesh
        ├── material_manager.py   # Assign materials
        ├── property_manager.py   # Shell/Solid properties
        ├── boundary_conditions.py # Loads & constraints
        └── connection_manager.py  # Connectors, contacts
```

| Hook | Description | API NX Open | Priorité |
|------|-------------|-------------|----------|
| `create_tet_mesh(body, size)` | Mailler en tétra | `MeshManager.CreateMesh3d()` | P1 |
| `update_mesh()` | Régénérer maillage | `FEModel.UpdateMesh()` | P1 |
| `set_material(mesh, mat_name)` | Assigner matériau | `PhysicalProperty.SetMaterial()` | P1 |
| `create_shell_property(t)` | Propriété shell | `PhysicalPropertyCollection.CreateShellProperty()` | P2 |
| `apply_force(nodes, vector)` | Appliquer force | `LoadCollection.CreateForce()` | P1 |
| `apply_constraint(nodes, dof)` | Appliquer contrainte | `ConstraintCollection.CreateConstraint()` | P1 |
| `create_contact(faces1, faces2)` | Contact surfaces | `ConnectionCollection.CreateSurfaceContact()` | P2 |

### 3.3 Hooks Simulation/Solve (Priorité 1)

```
optimization_engine/
└── hooks/
    └── nx_sim/
        ├── __init__.py
        ├── solution_manager.py   # Create/Run solutions
        ├── solve_manager.py      # Submit solver jobs
        └── result_manager.py     # Access results
```

| Hook | Description | API NX Open | Priorité |
|------|-------------|-------------|----------|
| `create_solution(type, name)` | Créer solution | `SimSolutionCollection.CreateSolution()` | P1 |
| `solve(solution)` | Lancer solveur | `SimSolution.Solve()` | P1 |
| `solve_batch(bdf_path)` | Nastran en batch | `subprocess` + run_nastran | P1 |
| `get_solve_status()` | Statut du solve | `SimSolution.SolveStatus` | P1 |
| `export_bdf(path)` | Exporter deck Nastran | `SimSolution.ExportSolver()` | P1 |

---

## 4. Architecture des Extractors

### 4.0 Current Implementation Status (as of 2025-12-06)

```
optimization_engine/extractors/
├── __init__.py
├── extract_displacement.py      # ✓ extract_displacement()
├── extract_von_mises_stress.py  # ✓ extract_solid_stress()
├── extract_frequency.py         # ✓ extract_frequency()
├── extract_mass.py              # ✓ extract_generic()
├── extract_mass_from_bdf.py     # ✓ extract_mass_from_bdf()
├── extract_mass_from_expression.py  # ✓ extract_mass_from_expression()
├── extract_part_mass_material.py    # ✓ PartMassExtractor (NX Open via journal)
├── bdf_mass_extractor.py        # ✓ BDFMassExtractor class
├── op2_extractor.py             # ✓ OP2Extractor class (mass, grid forces, loads)
├── field_data_extractor.py      # ✓ FieldDataExtractor class
├── extract_zernike.py           # ✓ ZernikeExtractor class (advanced)
├── extract_zernike_surface.py   # ✓ SurfaceZernikeExtractor class
└── zernike_helpers.py           # ✓ Helper functions
```

### 4.1 Extractors Structurels (Priorité 1)

| Extractor | Output | Source | Priorité | Status | File |
|-----------|--------|--------|----------|--------|------|
| `extract_displacement(op2, subcase)` | mm | OP2 | P1 | ✓ | extract_displacement.py |
| `extract_solid_stress(op2, subcase, elem_type)` | MPa | OP2 | P1 | ✓ | extract_von_mises_stress.py |
| `extract_mass_from_bdf(bdf)` | kg | BDF | P1 | ✓ | bdf_mass_extractor.py |
| `extract_mass_from_op2(op2)` | kg | OP2 | P1 | ✓ | op2_extractor.py |
| `extract_grid_point_forces(op2)` | N | OP2 | P1 | ✓ | op2_extractor.py |
| `extract_displacement_field(op2)` | [mm] | OP2 | P1 | ✓ | field_data_extractor.py |
| `extract_principal_stress(elem)` | MPa | OP2 | P2 | ❌ | - |
| `extract_strain(elem)` | - | OP2 | P2 | ❌ | - |
| `extract_strain_energy(elem)` | J | OP2 | P2 | ❌ | - |

### 4.2 Extractors Modaux (Priorité 2)

| Extractor | Output | Source | Priorité | Status | File |
|-----------|--------|--------|----------|--------|------|
| `extract_frequency(op2, subcase, mode)` | Hz | OP2 | P1 | ✓ | extract_frequency.py |
| `extract_modal_mass(mode)` | kg | F06 | P2 | ❌ | - |
| `extract_mode_shape(mode, nodes)` | [mm] | OP2 | P3 | ❌ | - |
| `extract_mac_matrix(modes)` | [0-1] | Calc | P3 | ❌ | - |

### 4.3 Extractors Thermiques (Priorité 2)

| Extractor | Output | Source | Priorité | Status | File |
|-----------|--------|--------|----------|--------|------|
| `extract_temperature(node)` | °C/K | OP2/F06 | P2 | ❌ | - |
| `extract_max_temperature()` | °C/K | OP2/F06 | P2 | ❌ | - |
| `extract_heat_flux(elem)` | W/m² | OP2/F06 | P2 | ❌ | - |
| `extract_thermal_stress(elem)` | MPa | OP2/F06 | P2 | ❌ | - |

### 4.4 Extractors Géométriques (CAD) (Priorité 1) - NX Open

| Extractor | Output | Source | Priorité | Status | File |
|-----------|--------|--------|----------|--------|------|
| `extract_part_mass_material(prt)` | kg, material | NX Open | P1 | ✓ | extract_part_mass_material.py |
| `extract_part_mass(prt)` | kg | NX Open | P1 | ✓ | extract_part_mass_material.py |
| `extract_part_material(prt)` | string | NX Open | P1 | ✓ | extract_part_mass_material.py |
| `extract_mass_from_expression(prt)` | kg | NX Open | P1 | ✓ | extract_mass_from_expression.py |
| `extract_volume()` | mm³ | NX Open | P2 | ❌ | - |
| `extract_surface_area()` | mm² | NX Open | P2 | ❌ | - |
| `extract_center_of_gravity()` | [mm] | NX Open | P2 | ❌ | - |
| `extract_inertia_tensor()` | kg·mm² | NX Open | P3 | ❌ | - |

**NX Open APIs for CAD Extraction**:
- `part.MeasureManager()` - Main entry point for mass properties
- `MeasureManager.NewMassProperties()` - Create mass measurement
- `MasProperties.Mass`, `.CenterOfGravity`, `.MomentsOfInertia`

### 4.5 Extractors Buckling (Priorité 3)

| Extractor | Output | Source | Priorité | Status | File |
|-----------|--------|--------|----------|--------|------|
| `extract_buckling_factor(mode)` | - | F06 | P3 | ❌ | - |
| `extract_critical_load()` | N | F06 | P3 | ❌ | - |

### 4.6 Extractors Zernike (Spécialisé Optique) ✓

| Extractor | Output | Source | Priorité | Status | File |
|-----------|--------|--------|----------|--------|------|
| `ZernikeExtractor.extract_subcase()` | coeffs | OP2 | P1 | ✓ | extract_zernike.py |
| `ZernikeExtractor.extract_relative()` | delta_coeffs | OP2 | P1 | ✓ | extract_zernike.py |
| `extract_zernike_from_op2()` | coeffs | OP2 | P1 | ✓ | extract_zernike.py |
| `extract_zernike_filtered_rms()` | RMS(nm) | OP2 | P1 | ✓ | extract_zernike.py |
| `SurfaceZernikeExtractor.extract_from_op2()` | coeffs | OP2 | P1 | ✓ | extract_zernike_surface.py |

**Usage**: Mirror/lens deformation optimization using Zernike polynomial decomposition

---

## 5. Manipulateurs Avancés

### 5.1 Manipulateurs de Forme (Shape Optimization)

```
optimization_engine/
└── manipulators/
    ├── morpher.py           # Morphing mesh/géométrie
    ├── ffd.py               # Free-Form Deformation
    └── surface_offset.py    # Offset surfaces
```

| Manipulator | Description | Priorité |
|-------------|-------------|----------|
| `morph_nodes(nodes, displacements)` | Morphing direct | P3 |
| `ffd_box(control_points)` | Déformation FFD | P3 |
| `offset_faces(faces, distance)` | Offset paramétrique | P2 |

### 5.2 Manipulateurs Topologiques (Future)

| Manipulator | Description | Priorité |
|-------------|-------------|----------|
| `apply_density_filter(elements)` | SIMP filtering | P4 |
| `extract_iso_surface(density)` | Topology to geometry | P4 |
| `create_lattice_infill(region)` | Lattice génération | P4 |

---

## 6. Plan d'Implémentation 80/20

### Phase 1: Fondations ✓ COMPLETED
**Objectif**: Stabiliser le workflow de base

| # | Tâche | Fichier | Status |
|---|-------|---------|--------|
| 1.1 | Expression manipulation via .exp file | `nx_updater.py` | ✓ |
| 1.2 | Mass extraction from BDF | `bdf_mass_extractor.py` | ✓ |
| 1.3 | Mass extraction from NX Open | `extract_part_mass_material.py` | ✓ |
| 1.4 | Displacement extraction | `extract_displacement.py` | ✓ |
| 1.5 | Von Mises stress extraction | `extract_von_mises_stress.py` | ✓ |
| 1.6 | Frequency extraction | `extract_frequency.py` | ✓ |

### Phase 1b: NX Open Hooks ✓ COMPLETED (2025-12-06)
**Objectif**: Create direct NX Open Python hooks for CAD/FEM operations
**Location**: `optimization_engine/hooks/nx_cad/`

| # | Tâche | API (verified via MCP) | Status | File |
|---|-------|------------------------|--------|------|
| 1b.1 | Hook: `open_part` / `close_part` / `save_part` | `Session.Parts.OpenBase()`, `Part.Close()`, `Part.Save()` | ✓ | part_manager.py |
| 1b.2 | Hook: `get_expression` / `set_expression` / `set_expressions` | `part.Expressions`, `Expressions.Edit()` | ✓ | expression_manager.py |
| 1b.3 | Hook: `update_model` (integrated) | `Session.UpdateManager.DoUpdate()` | ✓ | expression_manager.py |
| 1b.4 | Hook: `get_mass_properties` / `get_bodies` / `get_volume` | `MeasureManager.NewMassProperties()` | ✓ | geometry_query.py |
| 1b.5 | Hook: `suppress_feature` / `unsuppress_feature` | `Feature.Suppress()`, `Feature.Unsuppress()` | ✓ | feature_manager.py |
| 1b.6 | Hook: `save_part_as` (export) | `Part.SaveAs()` | ✓ | part_manager.py |

### Phase 2: Workflow Complet ✓ COMPLETED
**Objectif**: Automatiser le cycle CAD → FEM → Results

| # | Tâche | API / Fichier | Status |
|---|-------|---------------|--------|
| 2.1 | BDF export via NX Open | `solver_manager.export_bdf()` | ✓ |
| 2.2 | Batch solver launch | `subprocess` + NX run_solver | ✓ (external) |
| 2.3 | Principal stress extraction | `extract_principal_stress()` | ✓ |
| 2.4 | Strain energy extraction | `extract_strain_energy()` | ✓ |
| 2.5 | Reaction force extraction | `extract_spc_forces()` | ✓ |
| 2.6 | **Model Introspection** | `model_introspection.py` | ✓ |

**Files Created (2025-12-06):**
- `optimization_engine/hooks/nx_cae/solver_manager.py` - BDF export & solve hooks
- `optimization_engine/extractors/extract_principal_stress.py` - Principal stress (σ1, σ2, σ3)
- `optimization_engine/extractors/extract_strain_energy.py` - Element strain energy
- `optimization_engine/extractors/extract_spc_forces.py` - Reaction forces at BCs
- `optimization_engine/hooks/nx_cad/model_introspection.py` - **Comprehensive model introspection**

**Phase 2 Introspection Feature (2025-12-06):**
The model introspection module provides comprehensive extraction of:
- **Part (.prt)**: Expressions, bodies, mass properties, features, materials
- **Simulation (.sim)**: Solutions, boundary conditions, loads, materials, mesh info, output requests
- **Results (.op2)**: Available results (displacement, stress, strain, SPC forces, frequencies), subcases

Usage:
```python
from optimization_engine.hooks.nx_cad.model_introspection import (
    introspect_part,
    introspect_simulation,
    introspect_op2,
    introspect_study
)

# Introspect entire study
study_info = introspect_study("studies/my_study/")
```

### Phase 3: Multi-Physique ✓ COMPLETED (Core Extractors)
**Objectif**: Support thermique et dynamique
**Priority**: P1 (High) - Extends optimization to thermal/dynamic domains

| # | Tâche | API / Fichier | Status | Priority |
|---|-------|---------------|--------|----------|
| 3.1 | Temperature extraction | `extract_temperature.py` | ✓ | P1 |
| 3.2 | Thermal gradient extraction | `extract_temperature_gradient()` | ✓ | P1 |
| 3.3 | Thermal stress extraction | OP2 + thermal subcase | ✓ (via E3) | P1 |
| 3.4 | Modal mass extraction | `extract_modal_mass.py` | ✓ | P1 |
| 3.5 | Heat flux extraction | `extract_heat_flux()` | ✓ | P2 |
| 3.6 | Thermal BC setup hook | `NXOpen.CAE.LoadCollection` | ❌ | P2 |
| 3.7 | Thermo-mechanical coupling | Multi-step solve | ❌ | P3 |

**Files Created (2025-12-06):**
- `optimization_engine/extractors/extract_temperature.py` - Temperature, gradient, heat flux (E15-E17)
- `optimization_engine/extractors/extract_modal_mass.py` - Modal effective mass from F06 (E18)
- `optimization_engine/extractors/test_phase3_extractors.py` - Phase 3 test suite

**Phase 3 Implementation Guide:**

#### 3.1 Temperature Extraction
```python
# Target API (pyNastran)
from pyNastran.op2.op2 import read_op2

op2 = read_op2(op2_file)
temperatures = op2.temperatures  # TEMP subcase results

def extract_temperature(op2_file, subcase=1, nodes=None):
    """Extract nodal temperatures from thermal analysis.

    Returns:
        dict: {
            'max_temperature': float (°C or K),
            'min_temperature': float,
            'avg_temperature': float,
            'temperatures': {node_id: temp, ...}
        }
    """
```

#### 3.2 Thermal Gradient Extraction
```python
def extract_thermal_gradient(op2_file, subcase=1):
    """Extract temperature gradients from thermal analysis.

    Returns:
        dict: {
            'max_gradient': float (K/mm),
            'avg_gradient': float,
            'gradient_location': int (element_id)
        }
    """
```

#### 3.3 Thermal Stress Extraction
```python
def extract_thermal_stress(op2_file, subcase=1, element_type='ctetra'):
    """Extract stress from thermal-mechanical analysis.

    Notes:
        - Requires coupled thermal-structural solution
        - Uses temperature field as load

    Returns:
        dict: Similar to extract_solid_stress but from thermal loading
    """
```

#### 3.4 Modal Mass Extraction
```python
def extract_modal_mass(f06_file, mode_number=1):
    """Extract modal effective mass from F06 file.

    Returns:
        dict: {
            'modal_mass_x': float (kg),
            'modal_mass_y': float,
            'modal_mass_z': float,
            'participation_factor': float
        }
    """
```

**Expected Outputs After Phase 3:**
- New extractors: `extract_temperature.py`, `extract_thermal_gradient.py`, `extract_modal_mass.py`
- Updated protocol SYS_12: Add E15-E18 for thermal extractors
- New study templates: Thermal optimization, thermo-mechanical optimization

### Phase 4: AtomizerField Integration (from Master Plan)
**Objectif**: Neural network surrogate for field prediction

| # | Tâche | Description | Status |
|---|-------|-------------|--------|
| 4.1 | Mesh Graph Builder | GNN graph from FEM mesh | ❌ |
| 4.2 | Training Data Exporter | Mesh + BC + results package | ❌ |
| 4.3 | Field Mapper | GNN predictions → NX format | ❌ |
| 4.4 | Sample Validation | Check convergence/quality | ❌ |

### Phase 5: Surrogates & Advanced
**Objectif**: Kriging, topology, lattice

| # | Tâche | Status |
|---|-------|--------|
| 5.1 | Gaussian Process / Kriging surrogate | ❌ |
| 5.2 | SOL 200 interface (native topo) | ❌ |
| 5.3 | Lattice infill generation | ❌ |
| 5.4 | FFD morphing | ❌ |

---

## 7. Classes NX Open Clés (Verified via MCP)

### Session & Part Access

```python
import NXOpen

# Session singleton
session = NXOpen.Session.GetSession()

# Part access
work_part = session.Parts.Work           # Current work part (Part object)
display_part = session.Parts.Display     # Display part
all_parts = session.Parts                # PartCollection

# Key Part methods (from a02434.html):
expressions = work_part.Expressions      # ExpressionCollection
bodies = work_part.Bodies()              # BodyCollection
features = work_part.Features()          # FeatureCollection
measure_mgr = work_part.MeasureManager() # For mass properties
material_mgr = work_part.MaterialManager() # Material assignment
```

### Expression Manipulation

```python
# Find expression by name
expr = work_part.Expressions.FindObject("width")

# Get value
value = expr.Value  # float
units = expr.Units  # Unit object

# Set value (with units)
unit = work_part.UnitCollection.FindObject("MilliMeter")
work_part.Expressions.EditWithUnits(expr, unit, "50.0")

# Import from .exp file (batch update - robust method)
work_part.Expressions.ImportFromFile(
    exp_path,
    NXOpen.ExpressionCollection.ExportMode.Replace
)

# Update model after changes
session.UpdateManager.DoUpdate(session.SetUndoMark(...))
```

### Mass Properties

```python
# Create mass measurement
mass_props = work_part.MeasureManager().NewMassProperties(
    accuracy,           # int: 0.97-0.99 typical
    infoUnits,          # MassPropertiesInfo for units
    bodies              # Array of Body objects
)

# Get properties
mass = mass_props.Mass          # float (kg)
cog = mass_props.CenterOfGravity  # Point3d (x,y,z)
inertia = mass_props.MomentsOfInertia  # Matrix3x3
volume = mass_props.Volume      # float (mm³)
area = mass_props.SurfaceArea   # float (mm²)
```

### CAE/FEM Access

```python
from NXOpen.CAE import CaeSession

# CAE session utilities (from a10510.html)
cae_session = session.CaeSession()  # Returns CaeSession

# Key CaeSession methods:
material_utils = cae_session.MaterialUtils()           # MaterialUtilities
association_utils = cae_session.AssociationUtils()     # AssociationUtilities
mesh_mapping = cae_session.MeshMappingUtils()          # MeshMapping.Utils
penetration_mgr = cae_session.PenetrationCheckManager() # PenetrationCheck.Manager

# FEM/SIM parts
fem_part = work_part  # When .fem is work part
sim_part = work_part  # When .sim is work part

# Access mesh (from FemPart)
mesh_manager = fem_part.MeshManager
for mesh in mesh_manager.GetMeshes():
    nodes = mesh.GetNodes()
    elements = mesh.GetElements()

# Access solutions (from SimPart)
sim_simulation = sim_part.FindObject("Simulation")
for solution in sim_simulation.Solutions:
    name = solution.Name
    sol_type = solution.SolutionType
    solution.Solve()  # Run solver
```

### Feature Manipulation

```python
# Get feature by name
feature = work_part.Features.FindObject("FEATURE_NAME")

# Suppress/unsuppress
feature.Suppress()
feature.Unsuppress()

# Get expression-linked features
for expr in feature.GetExpressions():
    print(expr.Name, expr.Value)
```

---

## 8. Structure de Fichiers Finale

```
optimization_engine/
├── hooks/
│   ├── __init__.py
│   ├── nx_cad/
│   │   ├── __init__.py
│   │   ├── part_manager.py
│   │   ├── expression_manager.py
│   │   ├── feature_manager.py
│   │   ├── geometry_query.py
│   │   └── assembly_manager.py
│   ├── nx_fem/
│   │   ├── __init__.py
│   │   ├── mesh_manager.py
│   │   ├── material_manager.py
│   │   ├── property_manager.py
│   │   ├── boundary_conditions.py
│   │   └── connection_manager.py
│   └── nx_sim/
│       ├── __init__.py
│       ├── solution_manager.py
│       ├── solve_manager.py
│       └── result_manager.py
├── extractors/
│   ├── __init__.py
│   ├── displacement.py       # ✓
│   ├── stress.py             # À améliorer
│   ├── strain.py             # Nouveau
│   ├── frequency.py          # ✓
│   ├── modal_mass.py         # Nouveau
│   ├── temperature.py        # Nouveau
│   ├── reaction_force.py     # Nouveau
│   ├── cad_mass.py           # Nouveau (NX Open)
│   ├── cad_volume.py         # Nouveau
│   └── zernike/              # ✓
└── manipulators/
    ├── __init__.py
    ├── morpher.py            # Future
    └── ffd.py                # Future
```

---

## 9. Métriques de Succès

### Phase 1 Complete When: ✓ ACHIEVED
- [x] Peut ouvrir/fermer pièce NX via Python ✓ (part_manager.py)
- [x] Peut modifier expressions et update ✓ (expression_manager.py)
- [x] Peut extraire masse depuis CAD (pas BDF) ✓ (geometry_query.py)
- [x] Extrait stress max fiable de tous les éléments ✓ (extract_von_mises_stress.py)

### Phase 2 Complete When: ✓ ACHIEVED (2025-12-06)
- [x] Workflow complet: expression → BDF → solve → extract ✓
- [x] Support de toutes les contraintes mécaniques ✓ (principal stress, SPC forces)
- [x] Extraction de strain energy fonctionnelle ✓ (extract_strain_energy.py)
- [x] **Model Introspection**: Full model analysis capability ✓ (model_introspection.py)

### Phase 3 Complete When: ✓ CORE ACHIEVED (2025-12-06)
- [x] Temperature extraction from OP2 functional ✓ (extract_temperature.py)
- [x] Thermal gradient extraction functional ✓ (extract_temperature_gradient)
- [x] Heat flux extraction functional ✓ (extract_heat_flux)
- [x] Modal mass extraction from F06 functional ✓ (extract_modal_mass.py)
- [ ] At least one thermal optimization study runs successfully
- [ ] Thermo-mechanical coupling documented
- [ ] Thermal BC setup hook (NXOpen.CAE)

---

## 10. Références

### Documentation NX Open (via MCP)

**MCP Tools for NX Open Documentation**:
```
mcp__siemens-docs__nxopen_get_class(className)  # Get class doc
mcp__siemens-docs__nxopen_get_index(indexType)  # Browse class index
mcp__siemens-docs__nxopen_fetch_page(pagePath)  # Fetch any page
mcp__siemens-docs__siemens_docs_list()          # List available resources
```

**Key Page IDs**:
| Class | Page ID | URL Path |
|-------|---------|----------|
| Session | a03318.html | `/nxopen_python_ref/a03318.html` |
| Part | a02434.html | `/nxopen_python_ref/a02434.html` |
| BasePart | a00266.html | `/nxopen_python_ref/a00266.html` |
| CaeSession | a10510.html | `/nxopen_python_ref/a10510.html` |
| Class Index | classes.html | `/nxopen_python_ref/classes.html` |
| Function Index | functions_*.html | `/nxopen_python_ref/functions_m.html` (etc.) |

### Ressources Externes
- [NXJournaling.com](https://nxjournaling.com/) - NX Open examples and tutorials
- [NXOpen TSE](https://nxopentsedocumentation.thescriptingengineer.com/) - The Scripting Engineer docs
- [PyNastran Documentation](https://pynastran-git.readthedocs.io/) - OP2/BDF parsing
- [NAFEMS Python FEA Course](https://www.nafems.org/training/e-learning/python-for-fea-automation-and-optimization/)

### Papers & Academic
- Kriging for FEA Optimization: [Springer](https://link.springer.com/article/10.1007/s00158-019-02211-z)
- OpenMDAO Framework: [NASA Technical Report](https://openmdao.org/)
- SIMP Topology Optimization: Bendsøe & Sigmund methods

### Related Atomizer Documentation
- [ATOMIZER_NXOPEN_MASTER_PLAN.md](../07_DEVELOPMENT/ATOMIZER_NXOPEN_MASTER_PLAN.md) - Detailed API specs
- [SYS_12_EXTRACTOR_LIBRARY.md](../protocols/system/SYS_12_EXTRACTOR_LIBRARY.md) - Extractor catalog
- [MCP Server README](../../mcp-server/README.md) - Siemens docs proxy setup

---

## 11. Version History

| Version | Date | Changes |
|---------|------|---------|
| 1.0 | 2025-12-06 | Initial roadmap from industry research |
| 2.0 | 2025-12-06 | Merged with ATOMIZER_NXOPEN_MASTER_PLAN.md, added verified MCP API mappings, updated extractor status |
| 2.1 | 2025-12-06 | **Phase 1b Complete**: NX Open hooks implemented (part_manager, expression_manager, geometry_query, feature_manager) |
| 2.2 | 2025-12-06 | **Phase 2 Complete**: Principal stress, strain energy, SPC forces extractors + solver_manager |
| 2.3 | 2025-12-06 | **Model Introspection**: Added comprehensive model_introspection.py for full part/sim/op2 analysis |
| 2.4 | 2025-12-06 | **Phase 3 Prepared**: Detailed roadmap for thermal/dynamic extractors with implementation guide |
| 2.5 | 2025-12-06 | **Phase 3 Core Complete**: Temperature (E15-E17) and modal mass (E18) extractors implemented |

---

*Generated with assistance from Claude Code using MCP Siemens Documentation tools*
