Source code for pyNastran.op2.tables.oef_forces.oef_thermal_objects

#pylint disable=C0103,C0301
import numpy as np

from pyNastran.utils.numpy_utils import integer_types
from pyNastran.op2.result_objects.op2_objects import BaseElement
from pyNastran.f06.f06_formatting import (
    write_float_13e, write_floats_13e, _eigenvalue_header)
from pyNastran.op2.result_objects.op2_objects import get_times_dtype
from pyNastran.op2.result_objects.element_table_object import RealElementTableArray


[docs] class Real1DHeatFluxArray(BaseElement): """1-ROD, 2-BEAM, 3-TUBE, 10-CONROD, 34-BAR, 69-BEND""" def __init__(self, data_code, is_sort1, isubcase, dt): self.element_type = None self.element_name = None BaseElement.__init__(self, data_code, isubcase) #self.code = [self.format_code, self.sort_code, self.s_code] #self.ntimes = 0 # or frequency/mode #self.ntotal = 0 self.nelements = 0 # result specific self.itotal = 0 self.ielement = 0 if not is_sort1: raise NotImplementedError('SORT2') @property def is_real(self) -> bool: """is the result real?""" return True @property def is_complex(self) -> bool: """is the result complex?""" return False def _reset_indices(self) -> None: self.itotal = 0 self.ielement = 0
[docs] def get_headers(self) -> list[str]: headers = [ 'xgrad', 'ygrad', 'zgrad', 'xflux', 'yflux', 'zflux' ] return headers
#def get_headers(self): #headers = ['axial', 'torque'] #return headers
[docs] def build(self): """sizes the vectorized attributes of the Real1DHeatFluxArray""" #print('ntimes=%s nelements=%s ntotal=%s' % (self.ntimes, self.nelements, self.ntotal)) if self.is_built: return assert self.ntimes > 0, 'ntimes=%s' % self.ntimes assert self.nelements > 0, 'nelements=%s' % self.nelements assert self.ntotal > 0, 'ntotal=%s' % self.ntotal #self.names = [] self.nelements //= self.ntimes self.itime = 0 self.ielement = 0 self.itotal = 0 #self.ntimes = 0 #self.nelements = 0 #print("ntimes=%s nelements=%s ntotal=%s" % (self.ntimes, self.nelements, self.ntotal)) dtype, idtype, fdtype = get_times_dtype(self.nonlinear_factor, self.size, self.analysis_fmt) self._times = np.zeros(self.ntimes, dtype=self.analysis_fmt) self.element = np.zeros(self.nelements, dtype=idtype) self.element_data_type = np.empty(self.nelements, dtype='|U8') #[xgrad, ygrad, zgrad, xflux, yflux, zflux] self.data = np.zeros((self.ntimes, self.ntotal, 6), dtype=fdtype)
[docs] def build_dataframe(self): """creates a pandas dataframe""" import pandas as pd headers = self.get_headers() assert 0 not in self.element if self.nonlinear_factor not in (None, np.nan): #LoadStep 1.0 #ElementID Item #14 xgrad 0.000000e+00 # ygrad 1.401298e-45 # zgrad 1.401298e-45 # xflux -0.000000e+00 # yflux 1.401298e-45 # zflux 1.401298e-45 #15 xgrad -2.842171e-14 column_names, column_values = self._build_dataframe_transient_header() data_frame = self._build_pandas_transient_elements( column_values, column_names, headers, self.element, self.data) else: # ElementID xgrad ygrad ... xflux yflux zflux # 0 1 3.670189 1.401298e-45 ... -2.202113 1.401298e-45 1.401298e-45 # 1 2 2.427845 1.401298e-45 ... -1.456707 1.401298e-45 1.401298e-45 # 2 3 0.282165 1.401298e-45 ... -0.169299 1.401298e-45 1.401298e-45 # 3 4 0.276702 1.401298e-45 ... -0.166021 1.401298e-45 1.401298e-45 # 4 5 -0.059711 1.401298e-45 ... 0.035827 1.401298e-45 1.401298e-45 # 5 6 -0.156313 1.401298e-45 ... 0.093788 1.401298e-45 1.401298e-45 # 6 7 -0.042596 1.401298e-45 ... 0.025558 1.401298e-45 1.401298e-45 # 7 8 -2.334058 1.401298e-45 ... 1.400435 1.401298e-45 1.401298e-45 # 8 9 -3.946891 1.401298e-45 ... 2.368135 1.401298e-45 1.401298e-45 df1 = pd.DataFrame(self.element) df1.columns = ['ElementID'] df2 = pd.DataFrame(self.data[0]) df2.columns = headers data_frame = df1.join(df2) #data_frame = pd.Panel(self.data, #major_axis=self.element, #minor_axis=headers).to_frame() #data_frame.columns.names = ['Static'] #data_frame.index.names = ['ElementID', 'Item'] self.data_frame = data_frame
def __eq__(self, table): # pragma: no cover self._eq_header(table) assert self.is_sort1 == table.is_sort1 if not np.array_equal(self.element, table.element): assert self.element.shape == table.element.shape, 'element shape=%s table.shape=%s' % (self.element.shape, table.element.shape) msg = 'table_name=%r class_name=%s\n' % (self.table_name, self.__class__.__name__) msg += '%s\n' % str(self.code_information()) msg += 'Eid, EType\n' for (eid, etype, eid2, etype2) in zip(self.element, self.element_data_type, table.element, table.element_data_type): msg += '(%s, %s), (%s, %s)\n' % (eid, etype, eid2, etype2) print(msg) raise ValueError(msg) if not np.array_equal(self.data, table.data): msg = 'table_name=%r class_name=%s\n' % (self.table_name, self.__class__.__name__) msg += '%s\n' % str(self.code_information()) i = 0 for itime in range(self.ntimes): for ie, e in enumerate(self.element): eid = e t1 = self.data[itime, ie, :] t2 = table.data[itime, ie, :] (xgrad1, ygrad1, zgrad1, xflux1, yflux1, zflux1) = t1 (xgrad2, ygrad2, zgrad2, xflux2, yflux2, zflux2) = t2 if not np.array_equal(t1, t2): msg += ( '%s (%s, %s, %s, %s, %s, %s)\n' ' (%s, %s, %s, %s, %s, %s)\n' % ( eid, xgrad1, ygrad1, zgrad1, xflux1, yflux1, zflux1, xgrad2, ygrad2, zgrad2, xflux2, yflux2, zflux2, )) i += 1 if i > 10: print(msg) raise ValueError(msg) #print(msg) if i > 0: raise ValueError(msg) return True def add_sort1(self, dt, eid, etype, xgrad, ygrad, zgrad, xflux, yflux, zflux): """unvectorized method for adding SORT1 transient data""" assert self.sort_method == 1, self assert isinstance(eid, integer_types) and eid > 0, 'dt=%s eid=%s' % (dt, eid) self._times[self.itime] = dt self.element[self.ielement] = eid self.element_data_type[self.ielement] = etype self.data[self.itime, self.ielement, :] = [xgrad, ygrad, zgrad, xflux, yflux, zflux] self.ielement += 1
[docs] def get_stats(self, short: bool=False) -> list[str]: if not self.is_built: return [ f'<{self.__class__.__name__}>; table_name={self.table_name!r}\n', f' ntimes: {self.ntimes:d}\n', f' ntotal: {self.ntotal:d}\n', ] nelements = self.nelements ntimes = self.ntimes #ntotal = self.ntotal msg = [] if self.nonlinear_factor not in (None, np.nan): # transient msg.append(' type=%s ntimes=%i nelements=%i\n' % (self.__class__.__name__, ntimes, nelements)) ntimes_word = 'ntimes' else: msg.append(' type=%s nelements=%i\n' % (self.__class__.__name__, nelements)) ntimes_word = '1' headers = self.get_headers() n = len(headers) msg.append(' data: [%s, nelements, %i] where %i=[%s]\n' % ( ntimes_word, n, n, str(', '.join(headers)))) msg.append(f' data.shape = {self.data.shape}\n') #msg.append(' element type: %s\n' % self.element_type) #msg.append(' element name: %s\n ' % self.element_name) msg += self.get_data_code() return msg
[docs] def write_f06(self, f06_file, header=None, page_stamp='PAGE %s', page_num: int=1, is_mag_phase: bool=False, is_sort1: bool=True): if header is None: header = [] msg_temp = [ ' F I N I T E E L E M E N T T E M P E R A T U R E G R A D I E N T S A N D F L U X E S \n' ' \n' ' ELEMENT-ID EL-TYPE X-GRADIENT Y-GRADIENT Z-GRADIENT X-FLUX Y-FLUX Z-FLUX\n' #' 10 ROD -1.889713E+02 3.779427E+04' ] ntimes = self.data.shape[0] eids = self.element etype = self.element_data_type for itime in range(ntimes): dt = self._times[itime] # TODO: rename this... header = _eigenvalue_header(self, header, itime, ntimes, dt) f06_file.write(''.join(header + msg_temp)) xgrad = self.data[itime, :, 0] #ygrad = self.data[itime, :, 1] #zgrad = self.data[itime, :, 2] xflux = self.data[itime, :, 1] #yflux = self.data[itime, :, 4] #zflux = self.data[itime, :, 5] for (eid, etypei, xgradi, xfluxi) in zip(eids, etype, xgrad, xflux): (sxgradi, sxfluxi) = write_floats_13e([xgradi, xfluxi]) # TODO: hopa is probably the wrong type f06_file.write(' %8i %8s %-13s %-13s %-13s %s\n' % ( eid, etypei, sxgradi, '', '', sxfluxi)) f06_file.write(page_stamp % page_num) page_num += 1 return page_num - 1
[docs] class RealHeatFlux_2D_3DArray(RealElementTableArray): def __init__(self, data_code, is_sort1, isubcase, dt): RealElementTableArray.__init__(self, data_code, is_sort1, isubcase, dt)
[docs] def build_dataframe(self): """creates a pandas dataframe""" import pandas as pd headers = self.get_headers() #nelements = self.element.shape[0]# // 2 if self.nonlinear_factor not in (None, np.nan): #Time 0.0 10.0 #ElementID Item #1 grad1 0.0 -1.734723e-18 # grad2 0.0 -1.301043e-18 # grad3 0.0 1.951564e-18 # flux1 -0.0 3.538836e-16 # flux2 -0.0 2.654127e-16 # flux3 -0.0 -3.981190e-16 column_names, column_values = self._build_dataframe_transient_header() data_frame = self._build_pandas_transient_elements( column_values, column_names, headers, self.element, self.data) else: df1 = pd.DataFrame(self.element) df1.columns = ['ElementID'] df2 = pd.DataFrame(self.data[0]) df2.columns = headers data_frame = df1.join(df2) #print(self.data_frame) self.data_frame = data_frame
[docs] def write_f06(self, f06_file, header=None, page_stamp='PAGE %s', page_num: int=1, is_mag_phase: bool=False, is_sort1: bool=True): if header is None: header = [] words = [ ' F I N I T E E L E M E N T T E M P E R A T U R E G R A D I E N T S A N D F L U X E S \n \n', ' ELEMENT-ID EL-TYPE X-GRADIENT Y-GRADIENT Z-GRADIENT X-FLUX Y-FLUX Z-FLUX\n'] #' \n', #' POINT ID. TYPE T1 T2 T3 R1 R2 R3\n'] #words += self.get_table_marker() if self.nonlinear_factor not in (None, np.nan): return self._write_f06_transient_block(words, header, page_stamp, page_num, f06_file, is_mag_phase=is_mag_phase, is_sort1=is_sort1) return self._write_f06_block(words, header, page_stamp, page_num, f06_file, is_mag_phase=is_mag_phase, is_sort1=is_sort1)
[docs] def get_headers(self) -> list[str]: return ['grad1', 'grad2', 'grad3', 'flux1', 'flux2', 'flux3']
[docs] class RealConvHeatFluxArray(BaseElement): # 107-CHBDYE 108-CHBDYG 109-CHBDYP def __init__(self, data_code, is_sort1, isubcase, dt): self.element_type = None self.element_name = None BaseElement.__init__(self, data_code, isubcase) #self.code = [self.format_code, self.sort_code, self.s_code] #self.ntimes = 0 # or frequency/mode #self.ntotal = 0 self.nelements = 0 # result specific self.ielement = 0 self.itotal = 0 if not is_sort1: raise NotImplementedError('SORT2') @property def is_real(self) -> bool: """is the result real?""" return True @property def is_complex(self) -> bool: """is the result complex?""" return False def _reset_indices(self) -> None: self.itotal = 0 self.ielement = 0
[docs] def get_headers(self) -> list[str]: headers = [ 'free_conv', 'free_conv_k', ] return headers
[docs] def build(self): """sizes the vectorized attributes of the RealConvHeatFluxArray""" #print('ntimes=%s nelements=%s ntotal=%s' % (self.ntimes, self.nelements, self.ntotal)) assert self.ntimes > 0, 'ntimes=%s' % self.ntimes assert self.nelements > 0, 'nelements=%s' % self.nelements assert self.ntotal > 0, 'ntotal=%s' % self.ntotal #self.names = [] self.nelements //= self.ntimes self.itime = 0 self.ielement = 0 self.itotal = 0 #self.ntimes = 0 #self.nelements = 0 #print("ntimes=%s nelements=%s ntotal=%s" % (self.ntimes, self.nelements, self.ntotal)) dtype, idtype, fdtype = get_times_dtype(self.nonlinear_factor, self.size, self.analysis_fmt) self._times = np.zeros(self.ntimes, dtype=self.analysis_fmt) self.element_node = np.zeros((self.nelements, 2), dtype=idtype) #[free_conv, free_conv_k] self.data = np.zeros((self.ntimes, self.ntotal, 2), dtype=fdtype)
[docs] def build_dataframe(self): """creates a pandas dataframe""" import pandas as pd # TODO: fix me headers = self.get_headers() #assert 0 not in self.element element_node = [ self.element_node[:, 0], self.element_node[:, 1], ] if self.nonlinear_factor not in (None, np.nan): column_names, column_values = self._build_dataframe_transient_header() #data_frame = self._build_pandas_transient_elements( #column_values, column_names, #headers, self.element, self.data) #print(data_frame) data_frame = pd.Panel(self.data, items=column_values, major_axis=element_node, minor_axis=headers).to_frame() data_frame.columns.names = column_names else: # >=25.0 #Static free_conv free_conv_k #ElementID NodeID #1 0 -0.166667 10.0 #2 0 -0.166667 10.0 #3 0 -0.166667 10.0 #4 0 -0.166667 10.0 #5 0 -0.166667 10.0 #6 0 -0.166667 10.0 # <v24.2 #Static 0 #ElementID Node Item #1 0 free_conv -0.166667 # free_conv_k 10.000000 #2 0 free_conv -0.166667 # free_conv_k 10.000000 index = pd.MultiIndex.from_arrays(self.element_node.T, names=['ElementID', 'NodeID']) data_frame = pd.DataFrame(self.data[0], columns=headers, index=index) data_frame.columns.names = ['Static'] #data_frame = pd.Panel(self.data, #major_axis=element_node, #minor_axis=headers).to_frame() #data_frame.columns.names = ['Static'] #data_frame.index.names = ['ElementID', 'Node', 'Item'] self.data_frame = data_frame
def __eq__(self, table): # pragma: no cover self._eq_header(table) assert self.is_sort1 == table.is_sort1 if not np.array_equal(self.data, table.data): msg = 'table_name=%r class_name=%s\n' % (self.table_name, self.__class__.__name__) msg += '%s\n' % str(self.code_information()) i = 0 eids = self.element_node[:, 0] for itime in range(self.ntimes): for ie, e in enumerate(eids): eid = e t1 = self.data[itime, ie, :] t2 = table.data[itime, ie, :] (free_conv1, free_conv_k1) = t1 (free_conv2, free_conv_k2) = t2 if not np.array_equal(t1, t2): msg += ( '%s (%s, %s) (%s, %s)\n' % ( eid, free_conv1, free_conv_k1, free_conv2, free_conv_k2, )) i += 1 if i > 10: print(msg) raise ValueError(msg) #print(msg) if i > 0: raise ValueError(msg) return True def add_sort1(self, dt, eid, cntl_node, free_conv, free_conv_k): """unvectorized method for adding SORT1 transient data""" assert self.sort_method == 1, self assert isinstance(eid, integer_types) and eid > 0, 'dt=%s eid=%s' % (dt, eid) self._times[self.itime] = dt self.element_node[self.ielement, :] = [eid, cntl_node] self.data[self.itime, self.ielement, :] = [free_conv, free_conv_k] self.ielement += 1
[docs] def get_stats(self, short: bool=False) -> list[str]: if not self.is_built: return [ f'<{self.__class__.__name__}>; table_name={self.table_name!r}\n', f' ntimes: {self.ntimes:d}\n', f' ntotal: {self.ntotal:d}\n', ] nelements = self.nelements ntimes = self.ntimes #ntotal = self.ntotal msg = [] if self.nonlinear_factor not in (None, np.nan): # transient msg.append(' type=%s ntimes=%i nelements=%i\n' % (self.__class__.__name__, ntimes, nelements)) ntimes_word = 'ntimes' else: msg.append(' type=%s nelements=%i\n' % (self.__class__.__name__, nelements)) ntimes_word = '1' headers = self.get_headers() n = len(headers) msg.append(' data: [%s, nelements, %i] where %i=[%s]\n' % ( ntimes_word, n, n, str(', '.join(headers)))) msg.append(f' data.shape = {self.data.shape}\n') msg.append(' element type: %s\n' % self.element_type) msg.append(' element name: %s\n' % self.element_name) msg += self.get_data_code() return msg
[docs] def write_f06(self, f06_file, header=None, page_stamp='PAGE %s', page_num: int=1, is_mag_phase: bool=False, is_sort1: bool=True): if header is None: header = [] msg_temp = [ #' F I N I T E E L E M E N T T E M P E R A T U R E G R A D I E N T S A N D F L U X E S ' #' ' #' ELEMENT-ID EL-TYPE X-GRADIENT Y-GRADIENT Z-GRADIENT X-FLUX Y-FLUX Z-FLUX' #' 1 QUAD4 -8.372393E-01 1.776357E-15 8.372393E-01 -1.776357E-15' ' RealConvHeatFluxArray\n' ' ELEMENT-ID FREE-CONVECTION CONTROL-NODE FREE-CONVECTION-K\n' ] ntimes = self.data.shape[0] eids = self.element_node[:, 0] nids = self.element_node[:, 1] for itime in range(ntimes): dt = self._times[itime] # TODO: rename this... header = _eigenvalue_header(self, header, itime, ntimes, dt) f06_file.write(''.join(header + msg_temp)) # [free_conv, free_conv_k] free_conv = self.data[itime, :, 0] free_conv_k = self.data[itime, :, 1] for (eid, nid, free_convi, free_conv_ki) in zip(eids, nids, free_conv, free_conv_k): f06_file.write(' %8i %-13s %-13s %s\n' % ( eid, write_float_13e(free_convi), nid, write_float_13e(free_conv_ki) )) f06_file.write(page_stamp % page_num) page_num += 1 return page_num - 1
[docs] class RealChbdyHeatFluxArray(BaseElement): # 107-CHBDYE 108-CHBDYG 109-CHBDYP def __init__(self, data_code, is_sort1, isubcase, dt): self.element_type = None self.element_name = None BaseElement.__init__(self, data_code, isubcase) #self.code = [self.format_code, self.sort_code, self.s_code] #self.ntimes = 0 # or frequency/mode #self.ntotal = 0 self.nelements = 0 # result specific self.ielement = 0 self.itotal = 0 if not is_sort1: raise NotImplementedError('SORT2') @property def is_real(self) -> bool: """is the result real?""" return True @property def is_complex(self) -> bool: """is the result complex?""" return False @property def nnodes_per_element(self) -> int: return 1 def _reset_indices(self) -> None: self.itotal = 0 self.ielement = 0
[docs] def get_headers(self) -> list[str]: headers = [ 'fapplied', 'free_conv', 'force_conv', 'frad', 'ftotal', ] return headers
[docs] def build(self): """sizes the vectorized attributes of the RealChbdyHeatFluxArray""" #print('ntimes=%s nelements=%s ntotal=%s' % (self.ntimes, self.nelements, self.ntotal)) if self.is_built: return assert self.ntimes > 0, 'ntimes=%s' % self.ntimes assert self.nelements > 0, 'nelements=%s' % self.nelements assert self.ntotal > 0, 'ntotal=%s' % self.ntotal #self.names = [] self.nelements //= self.ntimes self.itime = 0 self.ielement = 0 self.itotal = 0 #self.ntimes = 0 #self.nelements = 0 #print("ntimes=%s nelements=%s ntotal=%s" % (self.ntimes, self.nelements, self.ntotal)) dtype, idtype, fdtype = get_times_dtype(self.nonlinear_factor, self.size, self.analysis_fmt) self._times = np.zeros(self.ntimes, dtype=self.analysis_fmt) self.element = np.zeros(self.nelements, dtype=idtype) self.element_type = np.empty(self.nelements, dtype='|U8') #[fapplied, free_conv, force_conv, frad, ftotal] self.data = np.zeros((self.ntimes, self.ntotal, 5), dtype=fdtype)
[docs] def build_dataframe(self): """creates a pandas dataframe""" import pandas as pd headers = self.get_headers() assert 0 not in self.element if self.nonlinear_factor not in (None, np.nan): #Time 0.0 10.0 #ElementID Item #10 fapplied 0.0 0.000000 # free_conv 0.0 499.376068 # force_conv 0.0 0.000000 # frad 0.0 0.000000 # ftotal 0.0 499.376068 #20 fapplied 0.0 0.000000 column_names, column_values = self._build_dataframe_transient_header() data_frame = self._build_pandas_transient_elements( column_values, column_names, headers, self.element, self.data) else: # >=25.0 #Static fapplied free_conv force_conv frad ftotal #ElementID #1 0.166667 -0.166667 0.0 0.0 0.0 #2 0.166667 -0.166667 0.0 0.0 0.0 #3 0.166667 -0.166667 0.0 0.0 0.0 #4 0.166667 -0.166667 0.0 0.0 0.0 #5 0.166667 -0.166667 0.0 0.0 0.0 #6 0.166667 -0.166667 0.0 0.0 0.0 # # <=24.2 #Static 0 #ElementID Item #1 fapplied 0.166667 # free_conv -0.166667 # force_conv 0.000000 # frad 0.000000 # ftotal 0.000000 data_frame = pd.DataFrame(self.data[0], columns=headers, index=self.element) data_frame.index.name = 'ElementID' data_frame.columns.names = ['Static'] #data_frame = pd.Panel(self.data, major_axis=self.element, minor_axis=headers).to_frame() #data_frame.columns.names = ['Static'] #data_frame.index.names = ['ElementID', 'Item'] self.data_frame = data_frame
def __eq__(self, table): # pragma: no cover self._eq_header(table) assert self.is_sort1 == table.is_sort1 if not np.array_equal(self.data, table.data): msg = 'table_name=%r class_name=%s\n' % (self.table_name, self.__class__.__name__) msg += '%s\n' % str(self.code_information()) i = 0 for itime in range(self.ntimes): for ie, e in enumerate(self.element): eid = e t1 = self.data[itime, ie, :] t2 = table.data[itime, ie, :] (fapplied1, free_conv1, force_conv1, frad1, ftotal1) = t1 (fapplied2, free_conv2, force_conv2, frad2, ftotal2) = t2 if not np.array_equal(t1, t2): msg += ( '%s (%s, %s, %s, %s, %s)\n' ' (%s, %s, %s, %s, %s)\n' % ( eid, fapplied1, free_conv1, force_conv1, frad1, ftotal1, fapplied2, free_conv2, force_conv2, frad2, ftotal2, )) i += 1 if i > 10: print(msg) raise ValueError(msg) #print(msg) if i > 0: raise ValueError(msg) return True def add_sort1(self, dt, eid, etype, fapplied, free_conv, force_conv, frad, ftotal): """unvectorized method for adding SORT1 transient data""" assert self.sort_method == 1, self assert isinstance(eid, integer_types) and eid > 0, 'dt=%s eid=%s' % (dt, eid) self._times[self.itime] = dt self.element[self.ielement] = eid self.element_type[self.ielement] = etype self.data[self.itime, self.ielement, :] = [fapplied, free_conv, force_conv, frad, ftotal] self.ielement += 1
[docs] def get_stats(self, short: bool=False) -> list[str]: if not self.is_built: return [ f'<{self.__class__.__name__}>; table_name={self.table_name!r}\n', f' ntimes: {self.ntimes:d}\n', f' ntotal: {self.ntotal:d}\n', ] nelements = self.nelements ntimes = self.ntimes #ntotal = self.ntotal msg = [] if self.nonlinear_factor not in (None, np.nan): # transient msg.append(' type=%s ntimes=%i nelements=%i\n' % (self.__class__.__name__, ntimes, nelements)) ntimes_word = 'ntimes' else: msg.append(' type=%s nelements=%i\n' % (self.__class__.__name__, nelements)) ntimes_word = '1' headers = self.get_headers() n = len(headers) msg.append(' data: [%s, nelements, %i] where %i=[%s]\n' % (ntimes_word, n, n, str(', '.join(headers)))) msg.append(f' data.shape = {self.data.shape}\n') #msg.append(' element type: %s\n' % self.element_type) #msg.append(' element name: %s\n' % self.element_name) msg += self.get_data_code() return msg
[docs] def write_f06(self, f06_file, header=None, page_stamp: str='PAGE %s', page_num: int=1, is_mag_phase: bool=False, is_sort1: bool=True): if header is None: header = [] assert self.is_sort1 == True, self.is_sort1 msg_temp = [ ' H E A T F L O W I N T O H B D Y E L E M E N T S (CHBDY)\n' ' \n' ' ELEMENT-ID APPLIED-LOAD FREE-CONVECTION FORCED-CONVECTION RADIATION TOTAL\n' #' 60 0.000000E+00 1.641941E+02 0.000000E+00 0.000000E+00 1.641941E+02' ] #(elem_name, msg_temp) = self.get_f06_header(is_mag_phase=is_mag_phase, is_sort1=is_sort1) #(ntimes, ntotal, two) = self.data.shape ntimes = self.data.shape[0] eids = self.element for itime in range(ntimes): dt = self._times[itime] # TODO: rename this... header = _eigenvalue_header(self, header, itime, ntimes, dt) f06_file.write(''.join(header + msg_temp)) # [fapplied, free_conv, force_conv, frad, ftotal] fapplied = self.data[itime, :, 0] free_conv = self.data[itime, :, 1] force_conv = self.data[itime, :, 2] frad = self.data[itime, :, 3] ftotal = self.data[itime, :, 4] for (eid, fappliedi, free_convi, force_convi, fradi, ftotali) in zip( eids, fapplied, free_conv, force_conv, frad, ftotal): #vals2 = write_floats_13e( #[fappliedi, free_convi, force_convi, fradi, ftotali]) #[sfapplied, sfree_conv, sforce_conv, sfrad, sftotal] = vals2 f06_file.write(' %8i %13E %13E %13E %13E %13E\n' % ( eid, fappliedi, free_convi, force_convi, fradi, ftotali)) f06_file.write(page_stamp % page_num) page_num += 1 return page_num - 1
[docs] class RealHeatFluxVUShellArray(BaseElement): def __init__(self, data_code, is_sort1, isubcase, dt): self.nonlinear_factor = np.nan self.table_name = None self.approach_code = None self.analysis_code = None BaseElement.__init__(self, data_code, isubcase, apply_data_code=True) # no double inheritance unused_sort1 = self.is_sort1 #self.dt = dt #self.code = [self.format_code, self.sort_code, self.s_code] #self.ntimes = 0 # or frequency/mode self.ntotal = 0 self.nelements = 0 # result specific @property def is_real(self) -> bool: """is the result real?""" return True @property def is_complex(self) -> bool: """is the result complex?""" return False
[docs] def data_type(self) -> str: return 'float32'
[docs] def get_stats(self, short: bool=False) -> list[str]: if not self.is_built: return [ f'<{self.__class__.__name__}>; table_name={self.table_name!r}\n', f' ntimes: {self.ntimes:d}\n', f' ntotal: {self.ntotal:d}\n', ] #ngrids = len(self.gridTypes) msg = [] unused_ntimesi, ntotal = self.data.shape[:2] ntimes = len(self._times) nelements = self.element.shape[0] nmajor = self.ntimes nminor = self.ntotal if self.is_sort1: assert nmajor == ntimes, 'ntimes=%s expected=%s' % (nmajor, ntimes) assert nminor == ntotal, 'ntotal=%s expected=%s' % (nminor, nelements) else: assert nmajor == nelements, 'nelements=%s expected=%s' % (nmajor, nelements) assert nminor == ntotal, 'ntotal=%s expected=%s' % (nminor, ntimes) msg.append(' isubcase = %s\n' % self.isubcase) if self.nonlinear_factor not in (None, np.nan): # transient msg.append(' type=%s ntimes=%s nelements=%s\n' % (self.__class__.__name__, ntimes, nelements)) else: msg.append(' type=%s nelements=%s\n' % (self.__class__.__name__, nelements)) headers = ', '.join(self._get_headers()) #msg.append(' data: [%s] shape=%s dtype=%s\n' #% (headers, [int(i) for i in self.data.shape], self.data.dtype)) msg.append(' data: [%s] shape=%s dtype=%s\n' % (headers, [int(i) for i in self.data.shape], self.data.dtype)) msg += self.get_data_code() return msg
@property def headers(self): return ['xgrad', 'ygrad', 'zgrad', 'xflux', 'yflux', 'zflux'] def _get_headers(self): return self.headers def _reset_indices(self) -> None: self.itotal = 0 self.ielement = 0
[docs] def build(self): """sizes the vectorized attributes of the ElementTableArray""" #print('nelements=%s ntimes=%s sort1?=%s ntotal=%s -> _nelements=%s' % ( #self.nelements, self.ntimes, self.is_sort1, #self.ntotal, self.nelements)) self.nelements //= self.ntimes self.itime = 0 self.itotal = 0 if self.is_sort1: ntimes = self.ntimes nelements = self.ntotal nx = ntimes ny = self.ntotal #print("ntimes=%s nelements=%s" % (ntimes, nelements)) if self.is_sort2: #unused_ntotal = self.ntotal nelements = self.ntimes ntimes = self.ntotal nx = nelements ny = ntimes #print("ntotal=%s nelements=%s ntimes=%s" % (ntotal, nelements, ntimes)) self._times = np.zeros(ntimes, dtype=self._times_dtype) #self.types = array(self.nelements, dtype='|S1') self.element = np.zeros(nelements, dtype='int32') self.element_parent_coord_icord = np.zeros((nelements, 4), dtype='int32') #self.element_data_type = empty(nelements, dtype='|U8') #[xgrad, ygrad, zgrad, xflux, yflux, zflux] self.data = np.zeros((nx, ny, 6), self.data_type())
def __eq__(self, table): # pragma: no cover assert self.is_sort1 == table.is_sort1 is_nan = (self.nonlinear_factor is not None and np.isnan(self.nonlinear_factor) and np.isnan(table.nonlinear_factor)) if not is_nan: assert self.nonlinear_factor == table.nonlinear_factor assert self.ntotal == table.ntotal assert self.table_name == table.table_name, 'table_name=%r table.table_name=%r' % (self.table_name, table.table_name) assert self.approach_code == table.approach_code if not is_nan: assert np.array_equal(self._times, table._times), 'ename=%s-%s times=%s table.times=%s' % ( self.element_name, self.element_type, self._times, table._times) if not np.array_equal(self.element, table.element): assert self.element.shape == table.element.shape, 'shape=%s table.shape=%s' % (self.element.shape, table.element.shape) msg = 'table_name=%r class_name=%s\n' % (self.table_name, self.__class__.__name__) msg += '%s\n' % str(self.code_information()) msg += 'eid:' for (eid, eid2) in zip(self.element, table.element): msg += '%s, %s\n' % (eid, eid2) print(msg) raise ValueError(msg) if not np.array_equal(self.element_parent_coord_icord, table.element_parent_coord_icord): assert self.element_parent_coord_icord.shape == table.element_parent_coord_icord.shape, 'shape=%s table.shape=%s' % (self.element.shape, table.element.shape) msg = 'table_name=%r class_name=%s\n' % (self.table_name, self.__class__.__name__) msg += '%s\n' % str(self.code_information()) msg += 'element_parent_coord_icord:' for (epci1, epci2) in zip(self.element_parent_coord_icord, table.element_parent_coord_icord): msg += '%s, %s\n' % (epci1, epci2) print(msg) raise ValueError(msg) if not np.array_equal(self.data, table.data): msg = 'table_name=%r class_name=%s\n' % (self.table_name, self.__class__.__name__) msg += '%s\n' % str(self.code_information()) ntimes = self.data.shape[0] i = 0 if self.is_sort1: for itime in range(ntimes): for ieid, eid in enumerate(self.element): t1 = self.data[itime, ieid, :] t2 = table.data[itime, ieid, :] (tx1, ty1, tz1, rx1, ry1, rz1) = t1 (tx2, ty2, tz2, rx2, ry2, rz2) = t2 if not np.allclose(t1, t2): #if not np.array_equal(t1, t2): msg += '%s\n (%s, %s, %s, %s, %s, %s)\n (%s, %s, %s, %s, %s, %s)\n' % ( eid, tx1, ty1, tz1, rx1, ry1, rz1, tx2, ty2, tz2, rx2, ry2, rz2) i += 1 if i > 10: print(msg) raise ValueError(msg) else: raise NotImplementedError(self.is_sort2) if i > 0: print(msg) raise ValueError(msg) return True def add_sort1(self, dt, eid, parent, coord, unused_icord, unused_theta, xgrad, ygrad, zgrad, xflux, yflux, zflux): """unvectorized method for adding SORT1 transient data""" assert self.sort_method == 1, self assert isinstance(eid, integer_types) and eid > 0, 'dt=%s eid=%s' % (dt, eid) # itotal - the node number # itime - the time/frequency step # the times/freqs self._times[self.itime] = dt self.element[self.itotal] = eid #print(eid, parent, coord, icord) # icord is a string? self.element_parent_coord_icord[self.itotal] = [eid, parent, coord, 0] #self.element_data_type[self.itotal] = etype self.data[self.itime, self.itotal, :] = [xgrad, ygrad, zgrad, xflux, yflux, zflux] self.itotal += 1
#def write_f06(self, f06_file, header=None, page_stamp='PAGE %s', #page_num: int=1, is_mag_phase: bool=False, is_sort1: bool=True): #pass