The iPython notebook for this demo can be found in:
In [1]:
import os
import pandas as pd
import pyNastran
from pyNastran.op2.op2 import read_op2
pkg_path = pyNastran.__path__[0]
model_path = os.path.join(pkg_path, '..', 'models')
In [2]:
solid_bending_op2 = os.path.join(model_path, 'solid_bending', 'solid_bending.op2')
solid_bending = read_op2(solid_bending_op2, combine=False, debug=False)
print(solid_bending.displacements.keys())
In [3]:
solid_bending_op2 = os.path.join(model_path, 'solid_bending', 'solid_bending.op2')
solid_bending2 = read_op2(solid_bending_op2, combine=True, debug=False)
print(solid_bending2.displacements.keys())
The keys cannot be "combined" despite us telling the program that it was OK. We'll get the following values that we need to handle.
if trans_word == 'LOAD STEP': # nonlinear statics
analysis_code = 10
elif trans_word in ['TIME', 'TIME STEP']: # TODO check name
analysis_code = 6
elif trans_word == 'EIGENVALUE': # normal modes
analysis_code = 2
elif trans_word == 'FREQ': # TODO check name
analysis_code = 5
elif trans_word == 'FREQUENCY':
analysis_code = 5
elif trans_word == 'COMPLEX EIGENVALUE':
analysis_code = 9
else:
raise NotImplementedError('transient_word=%r is not supported...' % trans_word)
You can do buckling as one subcase or two subcases (makes parsing it a lot easier!).
However, you have to do this once you start messing around with superelements or multi-step optimization.
For optimization, sometimes Nastran will downselect elements and do an optimization on that and print out a subset of the elements. At the end, it will rerun an analysis to double check the constraints are satisfied. It does not always do multi-step optimization.
In [4]:
op2_filename = os.path.join(model_path, 'sol_101_elements', 'buckling_solid_shell_bar.op2')
model = read_op2(op2_filename, combine=True, debug=False, build_dataframe=True)
In [5]:
stress_keys = model.cquad4_stress.keys()
print (stress_keys)
# isubcase, analysis_code, sort_method, count, subtitle
key0 = (1, 1, 1, 0, 'DEFAULT1')
key1 = (1, 8, 1, 0, 'DEFAULT1')
Keys:
Similarly:
In [6]:
stress_static = model.cquad4_stress[key0].data_frame
stress_transient = model.cquad4_stress[key1].data_frame
# The final calculated factor:
# Is it a None or not?
# This defines if it's static or transient
print('stress_static.nonlinear_factor = %s' % model.cquad4_stress[key0].nonlinear_factor)
print('stress_transient.nonlinear_factor = %s' % model.cquad4_stress[key1].nonlinear_factor)
print('data_names = %s' % model.cquad4_stress[key1].data_names)
print('loadsteps = %s' % model.cquad4_stress[key1].lsdvmns)
print('eigenvalues = %s' % model.cquad4_stress[key1].eigrs)
In [7]:
# Sets default precision of real numbers for pandas output\n"
pd.set_option('precision', 2)
stress_static.head(20)
Out[7]:
In [8]:
# Sets default precision of real numbers for pandas output\n"
pd.set_option('precision', 3)
#import numpy as np
#np.set_printoptions(formatter={'all':lambda x: '%g'})
stress_transient.head(20)
Out[8]: