""" Extract maximum displacement from structural analysis Auto-generated by Atomizer Phase 3 - pyNastran Research Agent Pattern: displacement Element Type: General Result Type: displacement API: model.displacements[subcase] """ from pathlib import Path from typing import Dict, Any import numpy as np from pyNastran.op2.op2 import OP2 def extract_displacement(op2_file: Path, subcase: int = 1): """Extract displacement results from OP2 file.""" from pyNastran.op2.op2 import OP2 import numpy as np model = OP2() model.read_op2(str(op2_file)) # NX Nastran often uses empty string '' as subcase key available_subcases = list(model.displacements.keys()) if not available_subcases: raise ValueError(f"No displacement data found in OP2 file") # Use the first available subcase (often '' for NX Nastran) actual_subcase = available_subcases[0] disp = model.displacements[actual_subcase] itime = 0 # static case # Extract translation components txyz = disp.data[itime, :, :3] # [tx, ty, tz] # Calculate total displacement total_disp = np.linalg.norm(txyz, axis=1) max_disp = np.max(total_disp) # Get node info node_ids = [nid for (nid, grid_type) in disp.node_gridtype] max_disp_node = node_ids[np.argmax(total_disp)] return { 'max_displacement': float(max_disp), 'max_disp_node': int(max_disp_node), 'max_disp_x': float(np.max(np.abs(txyz[:, 0]))), 'max_disp_y': float(np.max(np.abs(txyz[:, 1]))), 'max_disp_z': float(np.max(np.abs(txyz[:, 2]))) } if __name__ == '__main__': # Example usage import sys if len(sys.argv) > 1: op2_file = Path(sys.argv[1]) result = extract_displacement(op2_file) print(f"Extraction result: {result}") else: print("Usage: python {sys.argv[0]} ")