Neural Acceleration (MLP Surrogate): - Add run_nn_optimization.py with hybrid FEA/NN workflow - MLP architecture: 4-layer (64->128->128->64) with BatchNorm/Dropout - Three workflow modes: - --all: Sequential export->train->optimize->validate - --hybrid-loop: Iterative Train->NN->Validate->Retrain cycle - --turbo: Aggressive single-best validation (RECOMMENDED) - Turbo mode: 5000 NN trials + 50 FEA validations in ~12 minutes - Separate nn_study.db to avoid overloading dashboard Performance Results (bracket_pareto_3obj study): - NN prediction errors: mass 1-5%, stress 1-4%, stiffness 5-15% - Found minimum mass designs at boundary (angle~30deg, thick~30mm) - 100x speedup vs pure FEA exploration Protocol Operating System: - Add .claude/skills/ with Bootstrap, Cheatsheet, Context Loader - Add docs/protocols/ with operations (OP_01-06) and system (SYS_10-14) - Update SYS_14_NEURAL_ACCELERATION.md with MLP Turbo Mode docs NX Automation: - Add optimization_engine/hooks/ for NX CAD/CAE automation - Add study_wizard.py for guided study creation - Fix FEM mesh update: load idealized part before UpdateFemodel() New Study: - bracket_pareto_3obj: 3-objective Pareto (mass, stress, stiffness) - 167 FEA trials + 5000 NN trials completed - Demonstrates full hybrid workflow 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
290 lines
10 KiB
Markdown
290 lines
10 KiB
Markdown
# Extractors Catalog Module
|
||
|
||
**Last Updated**: December 5, 2025
|
||
**Version**: 1.0
|
||
**Type**: Optional Module
|
||
|
||
This module documents all available extractors in the Atomizer framework. Load this when the user asks about result extraction or needs to understand what extractors are available.
|
||
|
||
---
|
||
|
||
## When to Load
|
||
|
||
- User asks "what extractors are available?"
|
||
- User needs to extract results from OP2/BDF files
|
||
- Setting up a new study with custom extraction needs
|
||
- Debugging extraction issues
|
||
|
||
---
|
||
|
||
## PR.1 Extractor Catalog
|
||
|
||
| ID | Extractor | Module | Function | Input | Output | Returns |
|
||
|----|-----------|--------|----------|-------|--------|---------|
|
||
| E1 | **Displacement** | `optimization_engine.extractors.extract_displacement` | `extract_displacement(op2_file, subcase=1)` | `.op2` | mm | `{'max_displacement': float, 'max_disp_node': int, 'max_disp_x/y/z': float}` |
|
||
| E2 | **Frequency** | `optimization_engine.extractors.extract_frequency` | `extract_frequency(op2_file, subcase=1, mode_number=1)` | `.op2` | Hz | `{'frequency': float, 'mode_number': int, 'eigenvalue': float, 'all_frequencies': list}` |
|
||
| E3 | **Von Mises Stress** | `optimization_engine.extractors.extract_von_mises_stress` | `extract_solid_stress(op2_file, subcase=1, element_type='cquad4')` | `.op2` | MPa | `{'max_von_mises': float, 'max_stress_element': int}` |
|
||
| E4 | **BDF Mass** | `optimization_engine.extractors.bdf_mass_extractor` | `extract_mass_from_bdf(bdf_file)` | `.dat`/`.bdf` | kg | `float` (mass in kg) |
|
||
| E5 | **CAD Expression Mass** | `optimization_engine.extractors.extract_mass_from_expression` | `extract_mass_from_expression(prt_file, expression_name='p173')` | `.prt` + `_temp_mass.txt` | kg | `float` (mass in kg) |
|
||
| E6 | **Field Data** | `optimization_engine.extractors.field_data_extractor` | `FieldDataExtractor(field_file, result_column, aggregation)` | `.fld`/`.csv` | varies | `{'value': float, 'stats': dict}` |
|
||
| E7 | **Stiffness** | `optimization_engine.extractors.stiffness_calculator` | `StiffnessCalculator(field_file, op2_file, force_component, displacement_component)` | `.fld` + `.op2` | N/mm | `{'stiffness': float, 'displacement': float, 'force': float}` |
|
||
| E11 | **Part Mass & Material** | `optimization_engine.extractors.extract_part_mass_material` | `extract_part_mass_material(prt_file)` | `.prt` | kg + dict | `{'mass_kg': float, 'volume_mm3': float, 'material': {'name': str}, ...}` |
|
||
|
||
**For Zernike extractors (E8-E10)**, see the [zernike-optimization module](./zernike-optimization.md).
|
||
|
||
---
|
||
|
||
## PR.2 Extractor Code Snippets (COPY-PASTE)
|
||
|
||
### E1: Displacement Extraction
|
||
|
||
```python
|
||
from optimization_engine.extractors.extract_displacement import extract_displacement
|
||
|
||
disp_result = extract_displacement(op2_file, subcase=1)
|
||
max_displacement = disp_result['max_displacement'] # mm
|
||
max_node = disp_result['max_disp_node'] # Node ID
|
||
```
|
||
|
||
**Return Dictionary**:
|
||
```python
|
||
{
|
||
'max_displacement': 0.523, # Maximum magnitude (mm)
|
||
'max_disp_node': 1234, # Node ID with max displacement
|
||
'max_disp_x': 0.123, # X component at max node
|
||
'max_disp_y': 0.456, # Y component at max node
|
||
'max_disp_z': 0.234 # Z component at max node
|
||
}
|
||
```
|
||
|
||
### E2: Frequency Extraction
|
||
|
||
```python
|
||
from optimization_engine.extractors.extract_frequency import extract_frequency
|
||
|
||
# Get first mode frequency
|
||
freq_result = extract_frequency(op2_file, subcase=1, mode_number=1)
|
||
frequency = freq_result['frequency'] # Hz
|
||
|
||
# Get all frequencies
|
||
all_freqs = freq_result['all_frequencies'] # List of all mode frequencies
|
||
```
|
||
|
||
**Return Dictionary**:
|
||
```python
|
||
{
|
||
'frequency': 125.4, # Requested mode frequency (Hz)
|
||
'mode_number': 1, # Mode number requested
|
||
'eigenvalue': 6.21e5, # Eigenvalue (rad/s)^2
|
||
'all_frequencies': [125.4, 234.5, 389.2, ...] # All mode frequencies
|
||
}
|
||
```
|
||
|
||
### E3: Stress Extraction
|
||
|
||
```python
|
||
from optimization_engine.extractors.extract_von_mises_stress import extract_solid_stress
|
||
|
||
# For shell elements (CQUAD4, CTRIA3)
|
||
stress_result = extract_solid_stress(op2_file, subcase=1, element_type='cquad4')
|
||
|
||
# For solid elements (CTETRA, CHEXA)
|
||
stress_result = extract_solid_stress(op2_file, subcase=1, element_type='ctetra')
|
||
|
||
max_stress = stress_result['max_von_mises'] # MPa
|
||
```
|
||
|
||
**Return Dictionary**:
|
||
```python
|
||
{
|
||
'max_von_mises': 187.5, # Maximum von Mises stress (MPa)
|
||
'max_stress_element': 5678, # Element ID with max stress
|
||
'mean_stress': 45.2, # Mean stress across all elements
|
||
'stress_distribution': {...} # Optional: full distribution data
|
||
}
|
||
```
|
||
|
||
### E4: BDF Mass Extraction
|
||
|
||
```python
|
||
from optimization_engine.extractors.bdf_mass_extractor import extract_mass_from_bdf
|
||
|
||
mass_kg = extract_mass_from_bdf(str(dat_file)) # kg
|
||
```
|
||
|
||
**Note**: Calculates mass from element properties and material density in the BDF/DAT file.
|
||
|
||
### E5: CAD Expression Mass
|
||
|
||
```python
|
||
from optimization_engine.extractors.extract_mass_from_expression import extract_mass_from_expression
|
||
|
||
mass_kg = extract_mass_from_expression(model_file, expression_name="p173") # kg
|
||
```
|
||
|
||
**Note**: Requires `_temp_mass.txt` to be written by solve journal. The expression name is the NX expression that contains the mass value.
|
||
|
||
### E6: Field Data Extraction
|
||
|
||
```python
|
||
from optimization_engine.extractors.field_data_extractor import FieldDataExtractor
|
||
|
||
# Create extractor
|
||
extractor = FieldDataExtractor(
|
||
field_file="results.fld",
|
||
result_column="Temperature",
|
||
aggregation="max" # or "min", "mean", "sum"
|
||
)
|
||
|
||
result = extractor.extract()
|
||
value = result['value'] # Aggregated value
|
||
stats = result['stats'] # Full statistics
|
||
```
|
||
|
||
### E7: Stiffness Calculation
|
||
|
||
```python
|
||
# Simple stiffness from displacement (most common)
|
||
applied_force = 1000.0 # N - MUST MATCH YOUR MODEL'S APPLIED LOAD
|
||
stiffness = applied_force / max(abs(max_displacement), 1e-6) # N/mm
|
||
|
||
# Or using StiffnessCalculator for complex cases
|
||
from optimization_engine.extractors.stiffness_calculator import StiffnessCalculator
|
||
|
||
calc = StiffnessCalculator(
|
||
field_file="displacement.fld",
|
||
op2_file="results.op2",
|
||
force_component="Fz",
|
||
displacement_component="Tz"
|
||
)
|
||
result = calc.calculate()
|
||
stiffness = result['stiffness'] # N/mm
|
||
```
|
||
|
||
### E11: Part Mass & Material Extraction
|
||
|
||
```python
|
||
from optimization_engine.extractors import extract_part_mass_material, extract_part_mass
|
||
|
||
# Full extraction with all properties
|
||
result = extract_part_mass_material(prt_file)
|
||
mass_kg = result['mass_kg'] # kg
|
||
volume = result['volume_mm3'] # mm³
|
||
area = result['surface_area_mm2'] # mm²
|
||
cog = result['center_of_gravity_mm'] # [x, y, z] mm
|
||
material = result['material']['name'] # e.g., "Aluminum_2014"
|
||
|
||
# Simple mass-only extraction
|
||
mass_kg = extract_part_mass(prt_file) # kg
|
||
```
|
||
|
||
**Return Dictionary**:
|
||
```python
|
||
{
|
||
'mass_kg': 0.1098, # Mass in kg
|
||
'mass_g': 109.84, # Mass in grams
|
||
'volume_mm3': 39311.99, # Volume in mm³
|
||
'surface_area_mm2': 10876.71, # Surface area in mm²
|
||
'center_of_gravity_mm': [0, 42.3, 39.6], # CoG in mm
|
||
'material': {
|
||
'name': 'Aluminum_2014', # Material name (or None)
|
||
'density': None, # Density if available
|
||
'density_unit': 'kg/mm^3'
|
||
},
|
||
'num_bodies': 1 # Number of solid bodies
|
||
}
|
||
```
|
||
|
||
**Prerequisites**: Run the NX journal first to create the temp file:
|
||
```bash
|
||
run_journal.exe nx_journals/extract_part_mass_material.py -args model.prt
|
||
```
|
||
|
||
---
|
||
|
||
## Extractor Selection Guide
|
||
|
||
| Need | Extractor | When to Use |
|
||
|------|-----------|-------------|
|
||
| Max deflection | E1 | Static analysis displacement check |
|
||
| Natural frequency | E2 | Modal analysis, resonance avoidance |
|
||
| Peak stress | E3 | Strength validation, fatigue life |
|
||
| FEM mass | E4 | When mass is from mesh elements |
|
||
| CAD mass | E5 | When mass is from NX expression |
|
||
| Temperature/Custom | E6 | Thermal or custom field results |
|
||
| k = F/δ | E7 | Stiffness maximization |
|
||
| Wavefront error | E8-E10 | Telescope/mirror optimization |
|
||
| Part mass + material | E11 | Direct from .prt file with material info |
|
||
|
||
---
|
||
|
||
## Engineering Result Types
|
||
|
||
| Result Type | Nastran SOL | Output File | Extractor |
|
||
|-------------|-------------|-------------|-----------|
|
||
| Static Stress | SOL 101 | `.op2` | E3: `extract_solid_stress` |
|
||
| Displacement | SOL 101 | `.op2` | E1: `extract_displacement` |
|
||
| Natural Frequency | SOL 103 | `.op2` | E2: `extract_frequency` |
|
||
| Buckling Load | SOL 105 | `.op2` | `extract_buckling` |
|
||
| Modal Shapes | SOL 103 | `.op2` | `extract_mode_shapes` |
|
||
| Mass | - | `.dat`/`.bdf` | E4: `bdf_mass_extractor` |
|
||
| Stiffness | SOL 101 | `.fld` + `.op2` | E7: `stiffness_calculator` |
|
||
|
||
---
|
||
|
||
## Common Objective Formulations
|
||
|
||
### Stiffness Maximization
|
||
- k = F/δ (force/displacement)
|
||
- Maximize k or minimize 1/k (compliance)
|
||
- Requires consistent load magnitude across trials
|
||
|
||
### Mass Minimization
|
||
- Extract from BDF element properties + material density
|
||
- Units: typically kg (NX uses kg-mm-s)
|
||
|
||
### Stress Constraints
|
||
- Von Mises < σ_yield / safety_factor
|
||
- Account for stress concentrations
|
||
|
||
### Frequency Constraints
|
||
- f₁ > threshold (avoid resonance)
|
||
- Often paired with mass minimization
|
||
|
||
---
|
||
|
||
## Adding New Extractors
|
||
|
||
When the study needs result extraction not covered by existing extractors (E1-E10):
|
||
|
||
```
|
||
STEP 1: Check existing extractors in this catalog
|
||
├── If exists → IMPORT and USE it (done!)
|
||
└── If missing → Continue to STEP 2
|
||
|
||
STEP 2: Create extractor in optimization_engine/extractors/
|
||
├── File: extract_{feature}.py
|
||
├── Follow existing extractor patterns
|
||
└── Include comprehensive docstrings
|
||
|
||
STEP 3: Add to __init__.py
|
||
└── Export functions in optimization_engine/extractors/__init__.py
|
||
|
||
STEP 4: Update this module
|
||
├── Add to Extractor Catalog table
|
||
└── Add code snippet
|
||
|
||
STEP 5: Document in SYS_12_EXTRACTOR_LIBRARY.md
|
||
```
|
||
|
||
See [EXT_01_CREATE_EXTRACTOR](../../docs/protocols/extensions/EXT_01_CREATE_EXTRACTOR.md) for full guide.
|
||
|
||
---
|
||
|
||
## Cross-References
|
||
|
||
- **System Protocol**: [SYS_12_EXTRACTOR_LIBRARY](../../docs/protocols/system/SYS_12_EXTRACTOR_LIBRARY.md)
|
||
- **Extension Guide**: [EXT_01_CREATE_EXTRACTOR](../../docs/protocols/extensions/EXT_01_CREATE_EXTRACTOR.md)
|
||
- **Zernike Extractors**: [zernike-optimization module](./zernike-optimization.md)
|
||
- **Core Skill**: [study-creation-core](../core/study-creation-core.md)
|