Files
Atomizer/docs/generated/EXTRACTORS.md
Antoine 0e04457539 feat: Implement Agentic Architecture for robust session workflows
Phase 1 - Session Bootstrap:
- Add .claude/ATOMIZER_CONTEXT.md as single entry point for new sessions
- Add study state detection and task routing

Phase 2 - Code Deduplication:
- Add optimization_engine/base_runner.py (ConfigDrivenRunner)
- Add optimization_engine/generic_surrogate.py (ConfigDrivenSurrogate)
- Add optimization_engine/study_state.py for study detection
- Add optimization_engine/templates/ with registry and templates
- Studies now require ~50 lines instead of ~300

Phase 3 - Skill Consolidation:
- Add YAML frontmatter metadata to all skills (versioning, dependencies)
- Consolidate create-study.md into core/study-creation-core.md
- Update 00_BOOTSTRAP.md, 01_CHEATSHEET.md, 02_CONTEXT_LOADER.md

Phase 4 - Self-Expanding Knowledge:
- Add optimization_engine/auto_doc.py for auto-generating documentation
- Generate docs/generated/EXTRACTORS.md (27 extractors documented)
- Generate docs/generated/TEMPLATES.md (6 templates)
- Generate docs/generated/EXTRACTOR_CHEATSHEET.md

Phase 5 - Subagent Implementation:
- Add .claude/commands/study-builder.md (create studies)
- Add .claude/commands/nx-expert.md (NX Open API)
- Add .claude/commands/protocol-auditor.md (config validation)
- Add .claude/commands/results-analyzer.md (results analysis)

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-07 14:52:25 -05:00

1028 lines
25 KiB
Markdown

# Atomizer Extractor Library
*Auto-generated: 2025-12-07 12:53*
This document is automatically generated from the extractor source code.
---
## Quick Reference
| Extractor | Category | Phase | Description |
|-----------|----------|-------|-------------|
| `check_force_equilibrium` | forces | Phase 2 | Check if reaction forces balance applied loads (equilibrium |
| `extract_reaction_component` | forces | Phase 2 | Extract maximum absolute value of a specific reaction compon |
| `extract_spc_forces` | forces | Phase 2 | Extract SPC (reaction) forces from boundary conditions. |
| `extract_total_reaction_force` | forces | Phase 2 | Convenience function to extract total reaction force magnitu |
| `extract_frequencies` | general | Phase 3 | Extract natural frequencies from modal analysis F06 file. |
| `extract_part_material` | general | Phase 1 | Convenience function to extract just material info. |
| `PartMassExtractor` | mass | Phase 1 | Class-based extractor for part mass and material with cachin |
| `extract_part_mass` | mass | Phase 1 | Convenience function to extract just the mass in kg. |
| `extract_part_mass_material` | mass | Phase 1 | Extract mass and material properties from NX part file. |
| `extract_modal_mass` | modal | Phase 3 | Extract modal effective mass from F06 file. |
| `get_first_frequency` | modal | Phase 3 | Get first natural frequency from F06 file. |
| `get_modal_mass_ratio` | modal | Phase 3 | Get cumulative modal mass ratio for first n modes. |
| `ZernikeExtractor` | optical | Phase 1 | Complete Zernike analysis extractor for telescope mirror opt |
| `extract_zernike_filtered_rms` | optical | Phase 1 | Extract filtered RMS WFE - the primary metric for mirror opt |
| `extract_zernike_from_op2` | optical | Phase 1 | Convenience function to extract Zernike metrics from OP2. |
| `extract_zernike_relative_rms` | optical | Phase 1 | Extract relative filtered RMS between two subcases. |
| `extract_strain_energy` | strain | Phase 2 | Extract strain energy from structural elements. |
| `extract_strain_energy_density` | strain | Phase 2 | Extract strain energy density (energy per volume). |
| `extract_total_strain_energy` | strain | Phase 2 | Convenience function to extract total strain energy. |
| `extract_max_principal_stress` | stress | Phase 2 | Convenience function to extract maximum principal stress. |
| `extract_min_principal_stress` | stress | Phase 2 | Convenience function to extract minimum principal stress. |
| `extract_principal_stress` | stress | Phase 2 | Extract principal stresses from solid or shell elements. |
| `extract_solid_stress` | stress | Phase 1 | Extract stress from solid elements. |
| `extract_heat_flux` | thermal | Phase 3 | Extract element heat flux from thermal analysis OP2 file. |
| `extract_temperature` | thermal | Phase 3 | Extract nodal temperatures from thermal analysis OP2 file. |
| `extract_temperature_gradient` | thermal | Phase 3 | Extract temperature gradients from thermal analysis. |
| `get_max_temperature` | thermal | Phase 3 | Get maximum temperature from OP2 file. |
---
## Forces Extractors
### `check_force_equilibrium`
**Module**: `optimization_engine.extractors.extract_spc_forces`
**Phase**: Phase 2
**Parameters**:
- `op2_file`
- `applied_load` = `None`
- `tolerance` = `1.0`
**Description**:
```
Check if reaction forces balance applied loads (equilibrium check).
In a valid static analysis, sum of reactions should equal applied loads.
Args:
op2_file: Path to .op2 file
applied_load: Optional dict of applied loads {'fx': N, 'fy': N, 'fz': N}
tolerance: Tolerance for equilibrium check (default 1.0 N)
Returns:
dict: {
'in_equilibrium': Boolean,
'reaction_sum': [fx, fy, fz],
'imbalance': [dx, dy, dz] (if applied_load provided),
'max_imbalance': Maximum component imbalance
}
```
---
### `extract_reaction_component`
**Module**: `optimization_engine.extractors.extract_spc_forces`
**Phase**: Phase 2
**Parameters**:
- `op2_file`
- `component` = `fz`
- `subcase` = `1`
**Description**:
```
Extract maximum absolute value of a specific reaction component.
Args:
op2_file: Path to .op2 file
component: 'fx', 'fy', 'fz', 'mx', 'my', 'mz'
subcase: Subcase ID
Returns:
Maximum absolute value of the specified component
```
---
### `extract_spc_forces`
**Module**: `optimization_engine.extractors.extract_spc_forces`
**Phase**: Phase 2
**Parameters**:
- `op2_file`
- `subcase` = `1`
- `component` = `total`
**Description**:
```
Extract SPC (reaction) forces from boundary conditions.
SPC forces are the reaction forces at constrained nodes. They balance
the applied loads and indicate load path through the structure.
Args:
op2_file: Path to .op2 file
subcase: Subcase ID (default 1)
component: Which component(s) to return:
- 'total': Resultant force magnitude (sqrt(fx^2+fy^2+fz^2))
- 'fx', 'fy', 'fz': Individual force components
- 'mx', 'my', 'mz': Individual moment components
- 'force': Vector sum of forces only
- 'moment': Vector sum of moments only
Returns:
dict: {
'total_reaction': Total reaction force magnitude,
'max_reaction': Maximum nodal reaction,
'max_reaction_node': Node ID with max reaction,
'sum_fx': Sum of Fx at all nodes,
'sum_fy': Sum of Fy at all nodes,
'sum_fz': Sum of Fz at all nodes,
'sum_mx': Sum of Mx at all nodes,
'sum_my': Sum of My at all nodes,
'sum_mz': Sum of Mz at all nodes,
'node_reactions': Dict of {node_id: [fx,fy,fz,mx,my,mz]},
'num_constrained_nodes': Number of nodes with SPCs,
'subcase': Subcase ID,
'units': 'N, N-mm (model units)'
}
Example:
>>> result = extract_spc_forces('model.op2')
>>> print(f"Total reaction: {result['total_reaction']:.2f} N")
>>> print(f"Sum Fz: {result['sum_fz']:.2f} N")
```
---
### `extract_total_reaction_force`
**Module**: `optimization_engine.extractors.extract_spc_forces`
**Phase**: Phase 2
**Parameters**:
- `op2_file`
- `subcase` = `1`
**Description**:
```
Convenience function to extract total reaction force magnitude.
Args:
op2_file: Path to .op2 file
subcase: Subcase ID
Returns:
Total reaction force magnitude (N)
```
---
## General Extractors
### `extract_frequencies`
**Module**: `optimization_engine.extractors.extract_modal_mass`
**Phase**: Phase 3
**Parameters**:
- `f06_file`
- `n_modes` = `None`
**Description**:
```
Extract natural frequencies from modal analysis F06 file.
Simpler version of extract_modal_mass that just gets frequencies.
Args:
f06_file: Path to F06 file
n_modes: Number of modes to extract (default: all)
Returns:
dict: {
'success': bool,
'frequencies': list of frequencies in Hz,
'mode_count': int,
'first_frequency': float,
'error': str or None
}
```
---
### `extract_part_material`
**Module**: `optimization_engine.extractors.extract_part_mass_material`
**Phase**: Phase 1
**Parameters**:
- `prt_file`
- `properties_file` = `None`
**Description**:
```
Convenience function to extract just material info.
Args:
prt_file: Path to .prt file
properties_file: Optional explicit path to temp file
Returns:
Dictionary with 'name', 'density', 'density_unit'
Example:
>>> mat = extract_part_material('model.prt')
>>> print(f"Material: {mat['name']}, Density: {mat['density']}")
Material: Steel_304, Density: 7.93e-06
```
---
## Mass Extractors
### `PartMassExtractor`
**Module**: `optimization_engine.extractors.extract_part_mass_material`
**Phase**: Phase 1
**Parameters**:
- `prt_file`
- `properties_file` = `None`
**Description**:
```
Class-based extractor for part mass and material with caching.
Use this when you need to extract properties from multiple parts
or want to cache results.
Example:
>>> extractor = PartMassExtractor('model.prt')
>>> result = extractor.extract()
>>> print(result['mass_kg'])
1.234
```
---
### `extract_part_mass`
**Module**: `optimization_engine.extractors.extract_part_mass_material`
**Phase**: Phase 1
**Parameters**:
- `prt_file`
- `properties_file` = `None`
**Description**:
```
Convenience function to extract just the mass in kg.
Args:
prt_file: Path to .prt file
properties_file: Optional explicit path to temp file
Returns:
Mass in kilograms (float)
Example:
>>> mass = extract_part_mass('model.prt')
>>> print(f"Mass: {mass:.3f} kg")
Mass: 1.234 kg
```
---
### `extract_part_mass_material`
**Module**: `optimization_engine.extractors.extract_part_mass_material`
**Phase**: Phase 1
**Parameters**:
- `prt_file`
- `properties_file` = `None`
**Description**:
```
Extract mass and material properties from NX part file.
This function reads from a temp JSON file that must be created by
running the NX journal: nx_journals/extract_part_mass_material.py
Args:
prt_file: Path to .prt file (used to locate temp file)
properties_file: Optional explicit path to _temp_part_properties.json
If not provided, looks in same directory as prt_file
Returns:
Dictionary containing:
- 'mass_kg': Mass in kilograms (float)
- 'mass_g': Mass in grams (float)
- 'volume_mm3': Volume in mm^3 (float)
- 'surface_area_mm2': Surface area in mm^2 (float)
- 'center_of_gravity_mm': [x, y, z] in mm (list)
- 'moments_of_inertia': {'Ixx', 'Iyy', 'Izz', 'unit'} or None
- 'material': {'name', 'density', 'density_unit'} (dict)
- 'num_bodies': Number of solid bodies (int)
Raises:
FileNotFoundError: If prt file or temp properties file not found
ValueError: If temp file has invalid format or extraction failed
Example:
>>> result = extract_part_mass_material('model.prt')
>>> print(f"Mass: {result['mass_kg']:.3f} kg")
Mass: 1.234 kg
>>> print(f"Material: {result['material']['name']}")
Material: Aluminum_6061
Note:
Before calling this function, you must run the NX journal to
create the temp file:
```
run_journal.exe extract_part_mass_material.py model.prt
```
```
---
## Modal Extractors
### `extract_modal_mass`
**Module**: `optimization_engine.extractors.extract_modal_mass`
**Phase**: Phase 3
**Parameters**:
- `f06_file`
- `mode` = `None`
- `direction` = `all`
**Description**:
```
Extract modal effective mass from F06 file.
Modal effective mass indicates how much of the total mass participates
in each mode for each direction. Important for:
- Base excitation problems
- Seismic analysis
- Random vibration
Args:
f06_file: Path to the F06 results file
mode: Mode number to extract (1-indexed). If None, returns all modes.
direction: Direction(s) to extract:
'x', 'y', 'z' - single direction
'all' - all directions (default)
'total' - sum of all directions
Returns:
dict: {
'success': bool,
'modes': list of mode data (if mode=None),
'modal_mass_x': float (kg) - effective mass in X,
'modal_mass_y': float (kg) - effective mass in Y,
'modal_mass_z': float (kg) - effective mass in Z,
'modal_mass_rx': float (kg·m²) - rotational mass about X,
'modal_mass_ry': float (kg·m²) - rotational mass about Y,
'modal_mass_rz': float (kg·m²) - rotational mass about Z,
'participation_x': float (0-1) - participation factor X,
'participation_y': float (0-1) - participation factor Y,
'participation_z': float (0-1) - participation factor Z,
'frequency': float (Hz) - natural frequency,
'cumulative_mass_x': float - cumulative mass fraction X,
'cumulative_mass_y': float - cumulative mass fraction Y,
'cumulative_mass_z': float - cumulative mass fraction Z,
'total_mass': float (kg) - total model mass,
'error': str or None
}
Example:
>>> result = extract_modal_mass("modal_analysis.f06", mode=1)
>>> if result['success']:
... print(f"Mode 1 frequency: {result['frequency']:.2f} Hz")
... print(f"X participation: {result['participation_x']*100:.1f}%")
```
---
### `get_first_frequency`
**Module**: `optimization_engine.extractors.extract_modal_mass`
**Phase**: Phase 3
**Parameters**:
- `f06_file`
**Description**:
```
Get first natural frequency from F06 file.
Convenience function for optimization constraints.
Returns 0 if extraction fails.
Args:
f06_file: Path to F06 file
Returns:
float: First natural frequency in Hz, or 0 on failure
```
---
### `get_modal_mass_ratio`
**Module**: `optimization_engine.extractors.extract_modal_mass`
**Phase**: Phase 3
**Parameters**:
- `f06_file`
- `direction` = `z`
- `n_modes` = `10`
**Description**:
```
Get cumulative modal mass ratio for first n modes.
This indicates what fraction of total mass participates in the
first n modes. Important for determining if enough modes are included.
Args:
f06_file: Path to F06 file
direction: Direction ('x', 'y', or 'z')
n_modes: Number of modes to include
Returns:
float: Cumulative mass ratio (0-1), or 0 on failure
```
---
## Optical Extractors
### `ZernikeExtractor`
**Module**: `optimization_engine.extractors.extract_zernike`
**Phase**: Phase 1
**Parameters**:
- `op2_path`
- `bdf_path` = `None`
- `displacement_unit` = `mm`
- `n_modes` = `50`
- `filter_orders` = `4`
**Description**:
```
Complete Zernike analysis extractor for telescope mirror optimization.
This class handles:
- Loading OP2 displacement results
- Matching with BDF geometry
- Computing Zernike coefficients and RMS metrics
- Multi-subcase analysis (different gravity orientations)
- Relative metrics between subcases
Example usage in optimization:
extractor = ZernikeExtractor(op2_file, bdf_file)
# For single-objective optimization (minimize filtered RMS at 20 deg)
result = extractor.extract_subcase('20')
objective = result['filtered_rms_nm']
# For multi-subcase optimization
all_results = extractor.extract_all_subcases()
```
---
### `extract_zernike_filtered_rms`
**Module**: `optimization_engine.extractors.extract_zernike`
**Phase**: Phase 1
**Parameters**:
- `op2_file`
- `bdf_file` = `None`
- `subcase` = `1`
- `kwargs`
**Description**:
```
Extract filtered RMS WFE - the primary metric for mirror optimization.
Filtered RMS removes piston, tip, tilt, and defocus (modes 1-4),
which can be corrected by alignment and focus adjustment.
Args:
op2_file: Path to OP2 file
bdf_file: Path to BDF geometry (auto-detected if None)
subcase: Subcase identifier
**kwargs: Additional arguments for ZernikeExtractor
Returns:
Filtered RMS WFE in nanometers
```
---
### `extract_zernike_from_op2`
**Module**: `optimization_engine.extractors.extract_zernike`
**Phase**: Phase 1
**Parameters**:
- `op2_file`
- `bdf_file` = `None`
- `subcase` = `1`
- `displacement_unit` = `mm`
- `n_modes` = `50`
- `filter_orders` = `4`
**Description**:
```
Convenience function to extract Zernike metrics from OP2.
This is the main entry point for optimization objectives.
Args:
op2_file: Path to OP2 results file
bdf_file: Path to BDF geometry (auto-detected if None)
subcase: Subcase identifier
displacement_unit: Unit of displacement in OP2
n_modes: Number of Zernike modes
filter_orders: Low-order modes to filter
Returns:
Dict with:
- 'global_rms_nm': Global RMS WFE in nanometers
- 'filtered_rms_nm': Filtered RMS (low orders removed)
- 'defocus_nm', 'astigmatism_rms_nm', etc.: Individual aberrations
```
---
### `extract_zernike_relative_rms`
**Module**: `optimization_engine.extractors.extract_zernike`
**Phase**: Phase 1
**Parameters**:
- `op2_file`
- `target_subcase`
- `reference_subcase`
- `bdf_file` = `None`
- `kwargs`
**Description**:
```
Extract relative filtered RMS between two subcases.
Useful for analyzing gravity-induced deformation relative to
a reference orientation (e.g., polishing position).
Args:
op2_file: Path to OP2 file
target_subcase: Subcase to analyze
reference_subcase: Reference subcase
bdf_file: Path to BDF geometry
**kwargs: Additional arguments for ZernikeExtractor
Returns:
Relative filtered RMS WFE in nanometers
```
---
## Strain Extractors
### `extract_strain_energy`
**Module**: `optimization_engine.extractors.extract_strain_energy`
**Phase**: Phase 2
**Parameters**:
- `op2_file`
- `subcase` = `1`
- `element_type` = `None`
- `top_n` = `10`
**Description**:
```
Extract strain energy from structural elements.
Strain energy (U) is a measure of the work done to deform the structure:
U = 0.5 * integral(sigma * epsilon) dV
High strain energy density indicates highly stressed regions.
Args:
op2_file: Path to .op2 file
subcase: Subcase ID (default 1)
element_type: Filter by element type (e.g., 'ctetra', 'chexa', 'cquad4')
If None, returns total from all elements
top_n: Number of top elements to return by strain energy
Returns:
dict: {
'total_strain_energy': Total strain energy (all elements),
'mean_strain_energy': Mean strain energy per element,
'max_strain_energy': Maximum element strain energy,
'max_energy_element': Element ID with max strain energy,
'top_elements': List of (element_id, energy) tuples,
'energy_by_type': Dict of {element_type: total_energy},
'num_elements': Total element count,
'subcase': Subcase ID,
'units': 'N-mm (model units)'
}
Example:
>>> result = extract_strain_energy('model.op2')
>>> print(f"Total strain energy: {result['total_strain_energy']:.2f} N-mm")
>>> print(f"Highest energy element: {result['max_energy_element']}")
```
---
### `extract_strain_energy_density`
**Module**: `optimization_engine.extractors.extract_strain_energy`
**Phase**: Phase 2
**Parameters**:
- `op2_file`
- `subcase` = `1`
- `element_type` = `ctetra`
**Description**:
```
Extract strain energy density (energy per volume).
Strain energy density is useful for identifying critical regions
and for material utilization optimization.
Args:
op2_file: Path to .op2 file
subcase: Subcase ID
element_type: Element type to analyze
Returns:
dict: {
'max_density': Maximum strain energy density,
'mean_density': Mean strain energy density,
'total_energy': Total strain energy,
'units': 'N/mm^2 (MPa equivalent)'
}
Note:
This requires element volume data which may not always be available.
Falls back to energy-only metrics if volume is unavailable.
```
---
### `extract_total_strain_energy`
**Module**: `optimization_engine.extractors.extract_strain_energy`
**Phase**: Phase 2
**Parameters**:
- `op2_file`
- `subcase` = `1`
**Description**:
```
Convenience function to extract total strain energy.
Args:
op2_file: Path to .op2 file
subcase: Subcase ID
Returns:
Total strain energy (N-mm)
```
---
## Stress Extractors
### `extract_max_principal_stress`
**Module**: `optimization_engine.extractors.extract_principal_stress`
**Phase**: Phase 2
**Parameters**:
- `op2_file`
- `subcase` = `1`
- `element_type` = `ctetra`
**Description**:
```
Convenience function to extract maximum principal stress.
Args:
op2_file: Path to .op2 file
subcase: Subcase ID
element_type: Element type
Returns:
Maximum principal stress value (tension positive)
```
---
### `extract_min_principal_stress`
**Module**: `optimization_engine.extractors.extract_principal_stress`
**Phase**: Phase 2
**Parameters**:
- `op2_file`
- `subcase` = `1`
- `element_type` = `ctetra`
**Description**:
```
Convenience function to extract minimum principal stress.
For solid elements, returns sigma3 (most compressive).
For shell elements, returns sigma2.
Args:
op2_file: Path to .op2 file
subcase: Subcase ID
element_type: Element type
Returns:
Minimum principal stress value (compression negative)
```
---
### `extract_principal_stress`
**Module**: `optimization_engine.extractors.extract_principal_stress`
**Phase**: Phase 2
**Parameters**:
- `op2_file`
- `subcase` = `1`
- `element_type` = `ctetra`
- `principal` = `max`
**Description**:
```
Extract principal stresses from solid or shell elements.
Principal stresses are the eigenvalues of the stress tensor,
ordered as: sigma1 >= sigma2 >= sigma3 (o1 >= o2 >= o3)
Args:
op2_file: Path to .op2 file
subcase: Subcase ID (default 1)
element_type: Element type ('ctetra', 'chexa', 'cquad4', 'ctria3')
principal: Which principal stress to return:
- 'max': Maximum principal (sigma1, tension positive)
- 'mid': Middle principal (sigma2)
- 'min': Minimum principal (sigma3, compression negative)
- 'all': Return all three principals
Returns:
dict: {
'max_principal': Maximum principal stress value,
'min_principal': Minimum principal stress value,
'mid_principal': Middle principal stress (if applicable),
'max_element': Element ID with maximum principal,
'min_element': Element ID with minimum principal,
'von_mises_max': Max von Mises for comparison,
'element_type': Element type used,
'subcase': Subcase ID,
'units': 'MPa (model units)'
}
Example:
>>> result = extract_principal_stress('model.op2', element_type='ctetra')
>>> print(f"Max tension: {result['max_principal']:.2f} MPa")
>>> print(f"Max compression: {result['min_principal']:.2f} MPa")
```
---
### `extract_solid_stress`
**Module**: `optimization_engine.extractors.extract_von_mises_stress`
**Phase**: Phase 1
**Parameters**:
- `op2_file`
- `subcase` = `1`
- `element_type` = `ctetra`
**Description**:
```
Extract stress from solid elements.
```
---
## Thermal Extractors
### `extract_heat_flux`
**Module**: `optimization_engine.extractors.extract_temperature`
**Phase**: Phase 3
**Parameters**:
- `op2_file`
- `subcase` = `1`
- `element_type` = `all`
**Description**:
```
Extract element heat flux from thermal analysis OP2 file.
Args:
op2_file: Path to the OP2 results file
subcase: Subcase number
element_type: Element type to extract ('all', 'ctetra', 'chexa', etc.)
Returns:
dict: {
'success': bool,
'max_heat_flux': float (W/mm² or model units),
'min_heat_flux': float,
'avg_heat_flux': float,
'max_element_id': int,
'element_count': int,
'unit': str,
'error': str or None
}
```
---
### `extract_temperature`
**Module**: `optimization_engine.extractors.extract_temperature`
**Phase**: Phase 3
**Parameters**:
- `op2_file`
- `subcase` = `1`
- `nodes` = `None`
- `return_field` = `False`
**Description**:
```
Extract nodal temperatures from thermal analysis OP2 file.
Args:
op2_file: Path to the OP2 results file
subcase: Subcase number to extract (default: 1)
nodes: Optional list of specific node IDs to extract.
If None, extracts all nodes.
return_field: If True, include full temperature field in result
Returns:
dict: {
'success': bool,
'max_temperature': float (K or °C depending on model units),
'min_temperature': float,
'avg_temperature': float,
'max_node_id': int (node with max temperature),
'min_node_id': int (node with min temperature),
'node_count': int,
'temperatures': dict (node_id: temp) - only if return_field=True,
'unit': str ('K' or 'C'),
'subcase': int,
'error': str or None
}
Example:
>>> result = extract_temperature("thermal_analysis.op2", subcase=1)
>>> if result['success']:
... print(f"Max temp: {result['max_temperature']:.1f} K at node {result['max_node_id']}")
... print(f"Temperature range: {result['min_temperature']:.1f} - {result['max_temperature']:.1f} K")
```
---
### `extract_temperature_gradient`
**Module**: `optimization_engine.extractors.extract_temperature`
**Phase**: Phase 3
**Parameters**:
- `op2_file`
- `subcase` = `1`
- `method` = `nodal_difference`
**Description**:
```
Extract temperature gradients from thermal analysis.
Computes temperature gradients based on nodal temperature differences.
This is useful for identifying thermal stress hot spots.
Args:
op2_file: Path to the OP2 results file
subcase: Subcase number
method: Gradient calculation method:
- 'nodal_difference': Max temperature difference between adjacent nodes
- 'element_based': Gradient within elements (requires mesh connectivity)
Returns:
dict: {
'success': bool,
'max_gradient': float (K/mm or temperature units/length),
'avg_gradient': float,
'temperature_range': float (max - min temperature),
'gradient_location': tuple (node_id_hot, node_id_cold),
'error': str or None
}
Note:
For accurate gradients, element-based calculation requires mesh connectivity
which may not be available in all OP2 files. The nodal_difference method
provides an approximation based on temperature range.
```
---
### `get_max_temperature`
**Module**: `optimization_engine.extractors.extract_temperature`
**Phase**: Phase 3
**Parameters**:
- `op2_file`
- `subcase` = `1`
**Description**:
```
Get maximum temperature from OP2 file.
Convenience function for use in optimization constraints.
Returns inf if extraction fails.
Args:
op2_file: Path to OP2 file
subcase: Subcase number
Returns:
float: Maximum temperature or inf on failure
```
---