Files
Atomizer/examples/test_stress_fix.py
Anto01 723b71e60b fix: Complete stress extraction fix for NX Nastran OP2 files
THREE critical fixes applied:

1. API Access Pattern
   - Support dotted attribute names (e.g., 'stress.chexa_stress')
   - Compatible with newer pyNastran versions (NX 2412.5)
   - Fallback to older API formats for compatibility

2. Correct Von Mises Index
   - Solid elements (CHEXA, CTETRA, CPENTA): index 9
   - Shell elements (CQUAD4, CTRIA3): last column
   - Data structure: [oxx, oyy, ozz, txy, tyz, txz, o1, o2, o3, von_mises]

3. Units Conversion (CRITICAL)
   - NX Nastran outputs stress in kPa, not MPa
   - Apply conversion: kPa / 1000 = MPa
   - Example: 113094.73 kPa -> 113.09 MPa

Test Results:
- Before: 0.00 MPa (FAIL)
- After:  113.09 MPa at element 83 (SUCCESS)

Files modified:
- optimization_engine/result_extractors/op2_extractor_example.py

Test files added:
- examples/test_stress_direct.py
- examples/test_stress_fix.py
- examples/debug_op2_stress.py
- STRESS_EXTRACTION_FIXED.md
- TESTING_STRESS_FIX.md
2025-11-15 11:18:03 -05:00

66 lines
2.1 KiB
Python

"""
Quick test to verify stress extraction fix for CHEXA elements.
Run this in test_env:
conda activate test_env
python examples/test_stress_fix.py
"""
from pathlib import Path
import sys
project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root))
from optimization_engine.result_extractors.extractors import stress_extractor, displacement_extractor
if __name__ == "__main__":
op2_path = project_root / "examples/bracket/bracket_sim1-solution_1.op2"
print("="*60)
print("STRESS EXTRACTION FIX VERIFICATION")
print("="*60)
print(f"OP2 file: {op2_path}")
print()
# Test displacement (we know this works - 0.315 mm)
print("--- Displacement (baseline test) ---")
try:
disp_result = displacement_extractor(op2_path)
print(f"Max displacement: {disp_result['max_displacement']:.6f} mm")
print(f"Node ID: {disp_result['max_node_id']}")
print("OK Displacement extractor working")
except Exception as e:
print(f"ERROR: {e}")
print()
# Test stress (should now return 122.91 MPa, not 0.0)
print("--- Stress (FIXED - should show ~122.91 MPa) ---")
try:
stress_result = stress_extractor(op2_path)
print(f"Max von Mises: {stress_result['max_von_mises']:.2f} MPa")
print(f"Element ID: {stress_result['element_id']}")
print(f"Element type: {stress_result['element_type']}")
# Verify fix worked
if stress_result['max_von_mises'] > 100.0:
print()
print("SUCCESS! Stress extraction fixed!")
print(f"Expected: ~122.91 MPa")
print(f"Got: {stress_result['max_von_mises']:.2f} MPa")
elif stress_result['max_von_mises'] == 0.0:
print()
print("FAIL: Still returning 0.0 - fix not working")
else:
print()
print(f"WARNING: Got {stress_result['max_von_mises']:.2f} MPa - verify if correct")
except Exception as e:
print(f"ERROR: {e}")
import traceback
traceback.print_exc()
print()
print("="*60)