""" Extract mass from Nastran BDF/DAT file as fallback when OP2 doesn't have GRDPNT """ from pathlib import Path from typing import Dict, Any import re def extract_mass_from_bdf(bdf_file: Path) -> Dict[str, Any]: """ Extract mass from Nastran BDF file by parsing material and element definitions. This is a fallback when OP2 doesn't have PARAM,GRDPNT output. Args: bdf_file: Path to .dat or .bdf file Returns: dict: { 'mass_kg': total mass in kg, 'mass_g': total mass in grams, 'method': 'bdf_calculation' } """ bdf_file = Path(bdf_file) if not bdf_file.exists(): raise FileNotFoundError(f"BDF file not found: {bdf_file}") # Parse using pyNastran BDF reader from pyNastran.bdf.bdf import read_bdf model = read_bdf(str(bdf_file), validate=False, xref=True, punch=False, encoding='utf-8', log=None, debug=False, mode='msc') # Calculate total mass by summing element masses # model.mass_properties() returns (mass, cg, inertia) mass_properties = model.mass_properties() mass_ton = mass_properties[0] # Mass in tons (ton-mm-sec) # NX Nastran typically uses ton-mm-sec units mass_kg = mass_ton * 1000.0 # Convert tons to kg mass_g = mass_kg * 1000.0 # Convert kg to grams return { 'mass_kg': mass_kg, 'mass_g': mass_g, 'mass_ton': mass_ton, 'method': 'bdf_calculation', 'units': 'ton-mm-sec (converted to kg/g)' } if __name__ == '__main__': import sys if len(sys.argv) > 1: bdf_file = Path(sys.argv[1]) result = extract_mass_from_bdf(bdf_file) print(f"Mass from BDF: {result['mass_kg']:.6f} kg ({result['mass_g']:.3f} g)") else: print(f"Usage: python {sys.argv[0]} ")