59 lines
1.6 KiB
Python
59 lines
1.6 KiB
Python
|
|
"""
|
||
|
|
Extract von Mises stress from solid elements
|
||
|
|
Auto-generated by Atomizer Phase 3 - pyNastran Research Agent
|
||
|
|
|
||
|
|
Pattern: solid_stress
|
||
|
|
Element Type: CTETRA
|
||
|
|
Result Type: stress
|
||
|
|
API: model.ctetra_stress[subcase] or model.chexa_stress[subcase]
|
||
|
|
"""
|
||
|
|
|
||
|
|
from pathlib import Path
|
||
|
|
from typing import Dict, Any
|
||
|
|
import numpy as np
|
||
|
|
from pyNastran.op2.op2 import OP2
|
||
|
|
|
||
|
|
|
||
|
|
def extract_solid_stress(op2_file: Path, subcase: int = 1, element_type: str = 'ctetra'):
|
||
|
|
"""Extract stress from solid elements."""
|
||
|
|
from pyNastran.op2.op2 import OP2
|
||
|
|
import numpy as np
|
||
|
|
|
||
|
|
model = OP2()
|
||
|
|
model.read_op2(str(op2_file))
|
||
|
|
|
||
|
|
# Get stress object for element type
|
||
|
|
stress_attr = f"{element_type}_stress"
|
||
|
|
if not hasattr(model, stress_attr):
|
||
|
|
raise ValueError(f"No {element_type} stress results in OP2")
|
||
|
|
|
||
|
|
stress = getattr(model, stress_attr)[subcase]
|
||
|
|
itime = 0
|
||
|
|
|
||
|
|
# Extract von Mises if available
|
||
|
|
if stress.is_von_mises():
|
||
|
|
von_mises = stress.data[itime, :, 9] # Column 9 is von Mises
|
||
|
|
max_stress = float(np.max(von_mises))
|
||
|
|
|
||
|
|
# Get element info
|
||
|
|
element_ids = [eid for (eid, node) in stress.element_node]
|
||
|
|
max_stress_elem = element_ids[np.argmax(von_mises)]
|
||
|
|
|
||
|
|
return {
|
||
|
|
'max_von_mises': max_stress,
|
||
|
|
'max_stress_element': int(max_stress_elem)
|
||
|
|
}
|
||
|
|
else:
|
||
|
|
raise ValueError("von Mises stress not available")
|
||
|
|
|
||
|
|
|
||
|
|
if __name__ == '__main__':
|
||
|
|
# Example usage
|
||
|
|
import sys
|
||
|
|
if len(sys.argv) > 1:
|
||
|
|
op2_file = Path(sys.argv[1])
|
||
|
|
result = extract_solid_stress(op2_file)
|
||
|
|
print(f"Extraction result: {result}")
|
||
|
|
else:
|
||
|
|
print("Usage: python {sys.argv[0]} <op2_file>")
|