116 lines
3.7 KiB
Python
116 lines
3.7 KiB
Python
|
|
"""
|
||
|
|
Diagnostic script to inspect OP2 file contents
|
||
|
|
Helps identify what data is available and what's missing
|
||
|
|
"""
|
||
|
|
import sys
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
# Add project root to path
|
||
|
|
project_root = Path(__file__).resolve().parents[2]
|
||
|
|
sys.path.insert(0, str(project_root))
|
||
|
|
|
||
|
|
from pyNastran.op2.op2 import read_op2
|
||
|
|
|
||
|
|
# Path to OP2 file
|
||
|
|
op2_file = Path(__file__).parent / "1_setup" / "model" / "bracket_sim1-solution_1.op2"
|
||
|
|
|
||
|
|
if not op2_file.exists():
|
||
|
|
print(f"[ERROR] OP2 file not found: {op2_file}")
|
||
|
|
sys.exit(1)
|
||
|
|
|
||
|
|
print("="*70)
|
||
|
|
print("OP2 FILE DIAGNOSTIC")
|
||
|
|
print("="*70)
|
||
|
|
print(f"File: {op2_file}")
|
||
|
|
print(f"Size: {op2_file.stat().st_size:,} bytes")
|
||
|
|
print()
|
||
|
|
|
||
|
|
# Load OP2 file
|
||
|
|
print("[1/3] Loading OP2 file...")
|
||
|
|
op2 = read_op2(str(op2_file), debug=False)
|
||
|
|
print(" [OK] OP2 file loaded successfully")
|
||
|
|
print()
|
||
|
|
|
||
|
|
# Check for Grid Point Weight (Mass Properties)
|
||
|
|
print("[2/3] Checking for Grid Point Weight (GRDPNT)...")
|
||
|
|
if hasattr(op2, 'grid_point_weight'):
|
||
|
|
if op2.grid_point_weight:
|
||
|
|
gpw = op2.grid_point_weight
|
||
|
|
print(" [OK] Grid Point Weight data found!")
|
||
|
|
print()
|
||
|
|
print(" Available attributes:")
|
||
|
|
for attr in dir(gpw):
|
||
|
|
if not attr.startswith('_'):
|
||
|
|
print(f" - {attr}")
|
||
|
|
print()
|
||
|
|
|
||
|
|
# Check for MO matrix
|
||
|
|
if hasattr(gpw, 'MO'):
|
||
|
|
print(f" [OK] MO matrix found: {gpw.MO}")
|
||
|
|
if gpw.MO is not None and len(gpw.MO) > 0:
|
||
|
|
mass_ton = gpw.MO[0, 0]
|
||
|
|
mass_kg = mass_ton * 1000.0
|
||
|
|
print(f" [OK] Mass: {mass_kg:.6f} kg ({mass_ton:.6e} ton)")
|
||
|
|
else:
|
||
|
|
print(" [X] MO matrix is empty or None")
|
||
|
|
else:
|
||
|
|
print(" [X] MO matrix not found")
|
||
|
|
|
||
|
|
# Check for CG
|
||
|
|
if hasattr(gpw, 'cg'):
|
||
|
|
print(f" [OK] CG found: {gpw.cg}")
|
||
|
|
else:
|
||
|
|
print(" [!] CG not found")
|
||
|
|
|
||
|
|
# Check reference point
|
||
|
|
if hasattr(gpw, 'reference_point'):
|
||
|
|
print(f" [OK] Reference point: {gpw.reference_point}")
|
||
|
|
else:
|
||
|
|
print(" [!] Reference point not found")
|
||
|
|
else:
|
||
|
|
print(" [X] grid_point_weight attribute exists but is empty/None")
|
||
|
|
else:
|
||
|
|
print(" [X] No grid_point_weight attribute found")
|
||
|
|
print()
|
||
|
|
print(" GRDPNT output request is NOT enabled in Nastran")
|
||
|
|
print(" Solution:")
|
||
|
|
print(" 1. Open Bracket_fem1.fem in NX")
|
||
|
|
print(" 2. Enable GRDPNT in Case Control or Bulk Data")
|
||
|
|
print(" 3. Save the FEM file")
|
||
|
|
print(" 4. Re-run the optimization")
|
||
|
|
|
||
|
|
print()
|
||
|
|
|
||
|
|
# Check for Grid Point Forces
|
||
|
|
print("[3/3] Checking for Grid Point Forces (GPFORCE)...")
|
||
|
|
if hasattr(op2, 'grid_point_forces'):
|
||
|
|
if op2.grid_point_forces:
|
||
|
|
print(" [OK] Grid Point Forces data found!")
|
||
|
|
print(f" Subcases available: {list(op2.grid_point_forces.keys())}")
|
||
|
|
else:
|
||
|
|
print(" [X] grid_point_forces attribute exists but is empty")
|
||
|
|
else:
|
||
|
|
print(" [X] No grid_point_forces found (expected - using applied_force parameter)")
|
||
|
|
|
||
|
|
print()
|
||
|
|
print("="*70)
|
||
|
|
print("DIAGNOSIS COMPLETE")
|
||
|
|
print("="*70)
|
||
|
|
|
||
|
|
# Summary
|
||
|
|
print()
|
||
|
|
print("SUMMARY:")
|
||
|
|
has_mass = hasattr(op2, 'grid_point_weight') and op2.grid_point_weight
|
||
|
|
if has_mass:
|
||
|
|
print("[OK] Mass extraction should work")
|
||
|
|
else:
|
||
|
|
print("[X] Mass extraction will FAIL - GRDPNT not enabled")
|
||
|
|
print()
|
||
|
|
print("NEXT STEPS:")
|
||
|
|
print("1. In NX, open: studies/bracket_stiffness_optimization/1_setup/model/Bracket_fem1.fem")
|
||
|
|
print("2. Go to: File > Utilities > Customer Defaults")
|
||
|
|
print("3. Search for: GRDPNT")
|
||
|
|
print("4. OR: Add 'PARAM,GRDPNT,0' to Bulk Data section")
|
||
|
|
print("5. Save and close")
|
||
|
|
print("6. Re-run optimization")
|