feat: Add Phase 2 & 3 physics extractors for multi-physics optimization
Phase 2 - Structural Analysis: - extract_principal_stress: σ1, σ2, σ3 principal stresses from OP2 - extract_strain_energy: Element and total strain energy - extract_spc_forces: Reaction forces at boundary conditions Phase 3 - Multi-Physics: - extract_temperature: Nodal temperatures from thermal OP2 (SOL 153/159) - extract_temperature_gradient: Thermal gradient approximation - extract_heat_flux: Element heat flux from thermal analysis - extract_modal_mass: Modal effective mass from F06 (SOL 103) - get_first_frequency: Convenience function for first natural frequency Documentation: - Updated SYS_12_EXTRACTOR_LIBRARY.md with E12-E18 specifications - Updated NX_OPEN_AUTOMATION_ROADMAP.md marking Phase 3 complete - Added test_phase3_extractors.py for validation All extractors follow consistent API pattern returning Dict with success, data, and error fields for robust error handling. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
717
docs/plans/NX_OPEN_AUTOMATION_ROADMAP.md
Normal file
717
docs/plans/NX_OPEN_AUTOMATION_ROADMAP.md
Normal file
@@ -0,0 +1,717 @@
|
||||
# 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*
|
||||
Reference in New Issue
Block a user