#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
#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]
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 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 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