"""
defines:
- RealNonlinearPlateArray
"""
from math import isnan
from itertools import count, cycle
import numpy as np
from pyNastran.utils.numpy_utils import integer_types
from pyNastran.op2.result_objects.op2_objects import get_times_dtype
from pyNastran.op2.tables.oes_stressStrain.real.oes_objects import OES_Object
from pyNastran.f06.f06_formatting import _eigenvalue_header, write_float_11e, write_float_13e
[docs]
class RealNonlinearPlateArray(OES_Object):
"""tested by elements/loadstep_elements.op2"""
def __init__(self, data_code, is_sort1, isubcase, dt):
OES_Object.__init__(self, data_code, isubcase, apply_data_code=True)
#self.code = [self.format_code, self.sort_code, self.s_code]
#self.ntimes = 0 # or frequency/mode
#self.ntotal = 0
self.ielement = 0
self.nelements = 0 # result specific
self.nnodes = None
@property
def is_real(self) -> bool:
return True
@property
def is_complex(self) -> bool:
return False
@property
def nnodes_per_element(self) -> int:
if self.element_type == 88: # Tria3-nonlinear
nnodes_per_element = 1
elif self.element_type == 90: # Quad4-nonlinear
nnodes_per_element = 1
#elif self.element_type == 144:
#nnodes_per_element = 5
#elif self.element_type == 64: # CQUAD8
#nnodes_per_element = 5
#elif self.element_type == 82: # CQUADR
#nnodes_per_element = 5
#elif self.element_type == 70: # CTRIAR
#nnodes_per_element = 4
#elif self.element_type == 75: # CTRIA6
#nnodes_per_element = 4
else:
raise NotImplementedError('name=%r type=%s' % (self.element_name, self.element_type))
return nnodes_per_element
def _reset_indices(self) -> None:
self.itotal = 0
self.ielement = 0
@property
def is_stress(self):
return True
#def is_bilinear(self):
#if self.element_type in [33, 74]: # CQUAD4, CTRIA3
#return False
#elif self.element_type in [144, 64, 82, 70, 75]: # CQUAD4
#return True
#else:
#raise NotImplementedError(f'name={self.element_name} type={self.element_type}')
[docs]
def build(self):
"""sizes the vectorized attributes of the RealNonlinearPlateArray"""
#print("self.ielement = %s" % self.ielement)
#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 = []
nnodes_per_element = self.nnodes_per_element
nnodes_per_element = 1
self.nnodes = nnodes_per_element
#self.nelements //= nnodes_per_element
if self.nelements % self.ntimes != 0:
msg = 'nelements=%s ntimes=%s nelements/ntimes=%s' % (
self.nelements, self.ntimes, self.nelements / float(self.ntimes))
#return
raise RuntimeError(msg)
if self.is_sort1:
self.nelements //= self.ntimes
self.itime = 0
self.ielement = 0
self.itotal = 0
#self.ntimes = 0
#self.nelements = 0
if self.is_sort1:
ntimes = self.ntimes
ntotal = self.ntotal
nelements = self.nelements
else:
nelements = self.ntimes
ntimes = self.nelements // self.ntimes // 2
#print("RealNonlinearPlateArray: name=%s type=%s nnodes_per_element=%s ntimes=%s nelements=%s ntotal=%s" % (
#self.element_name, self.element_type, nnodes_per_element, self.ntimes, self.nelements, self.ntotal))
# ntotal = self.ntotal // ntimes
ntotal = nelements * 2 # self.nnodes_per_element
self.ntimes = ntimes
self.nelements = nelements
#print("-> ntimes=%s nelements=%s ntotal=%s" % (
#ntimes, nelements, ntotal))
assert nelements > 0, nelements
assert ntotal > 0, ntotal
#print("***name=%s type=%s nnodes_per_element=%s ntimes=%s nelements=%s ntotal=%s" % (
#self.element_name, self.element_type, nnodes_per_element, self.ntimes, self.nelements, self.ntotal))
dtype, idtype, fdtype = get_times_dtype(self.nonlinear_factor, self.size, self.analysis_fmt)
self._times = np.zeros(ntimes, dtype=self.analysis_fmt)
self.element = np.zeros(nelements, dtype=idtype)
#[fiber_dist, oxx, oyy, ozz, txy, es, eps, ecs, exx, eyy, ezz, etxy]
self.data = np.zeros((ntimes, ntotal, 12), dtype=fdtype)
[docs]
def build_dataframe(self):
"""creates a pandas dataframe"""
import pandas as pd
nelements = self.element.shape[0]
nelements2 = self.data.shape[1]
is_two_layers = nelements * 2 == nelements2
headers = self.get_headers()
if is_two_layers:
names = ['ElementID', 'Location', 'Item']
element = np.vstack([self.element, self.element]).T.flatten()
if self.is_fiber_distance:
fiber_distance = ['Top', 'Bottom'] * nelements
else:
fiber_distance = ['Mean', 'Curvature'] * nelements
fd = np.array(fiber_distance, dtype='unicode')
element_fd = [
element,
fd,
]
iheader = 0
else:
names = ['ElementID', 'Item']
element_fd = [self.element]
iheader = 0
if self.nonlinear_factor not in (None, np.nan):
# TODO: this varies depending on ???
# - TestOP2.test_cgap_01
# - TestOP2.test_bdf_op2_other_24
#
#LoadStep 1.0
#ElementID Location Item
#7401 Top fiber_distance -1.200000e+00
# Bottom oxx -1.161999e+04
# Top oyy 1.450191e-01
# Bottom ozz 0.000000e+00
# Top txy 4.668588e-05
# Bottom eff_plastic_strain 1.162006e+04
# Top eff_plastic_strain 0.000000e+00
# Bottom eff_creep_strain 0.000000e+00
# Top exx -1.162003e-02
# Bottom eyy 3.486142e-03
# Top ezz 0.000000e+00
# Bottom exy 1.213833e-10
# Top fiber_distance 1.200000e+00
# Bottom oxx -1.161999e+04
# Top oyy 1.449644e-01
# Bottom ozz 0.000000e+00
# Top txy -4.668589e-05
# Bottom eff_plastic_strain 1.162006e+04
# Top eff_plastic_strain 0.000000e+00
# Bottom eff_creep_strain 0.000000e+00
# Top exx -1.162003e-02
# Bottom eyy 3.486142e-03
# Top ezz 0.000000e+00
# Bottom exy -1.213833e-10
#
#LoadStep 0.25 0.50
#ElementID Item
#1 oxx 1.725106e-05 1.075969e-05
# oyy 1.500000e+06 3.000000e+06
# ozz 0.000000e+00 0.000000e+00
# txy -1.751084e-10 2.152285e-09
# eff_plastic_strain 1.500000e+06 3.000000e+06
#... ... ...
#100 eff_creep_strain 0.000000e+00 0.000000e+00
# exx -2.024292e-06 -4.048583e-06
# eyy 6.747639e-06 1.349528e-05
# ezz 0.000000e+00 0.000000e+00
# exy 0.000000e+00 0.000000e+00
column_names, column_values = self._build_dataframe_transient_header()
#element = np.vstack([self.element, self.element]).T.flatten()
#element = self.element
#data_frame = self._build_pandas_transient_elements(
#column_values, column_names,
#headers, element, self.data[:, :, 1:])
data_frame = self._build_pandas_transient_element_node(
column_values, column_names,
headers[iheader:], element_fd, self.data[:, :, iheader:],
from_tuples=False, from_array=True,
names=names,
)
else:
# option B - nice!
df1 = pd.DataFrame(self.element).T
df1.columns = ['ElementID']
df2 = pd.DataFrame(self.data[0, :, 1:])
df2.columns = headers
data_frame = df1.join(df2)
data_frame = data_frame.reset_index().set_index(['ElementID'])
self.data_frame = data_frame
[docs]
def add_new_eid_sort1(self, dt, eid, etype, fd, sx, sy, sz, txy, es, eps, ecs, ex, ey, ez, exy):
self.element[self.ielement] = eid
self.ielement += 1
self.add_sort1(dt, eid, etype, fd, sx, sy, sz, txy, es, eps, ecs, ex, ey, ez, exy)
[docs]
def add_new_eid_sort2(self, dt, eid, etype, fd, sx, sy, sz, txy, es, eps, ecs, ex, ey, ez, exy):
ielement = self.itime
self.element[ielement] = eid
#self.ielement += 1
self.add_sort2(dt, eid, etype, fd, sx, sy, sz, txy, es, eps, ecs, ex, ey, ez, exy)
def add_sort1(self, dt, eid, etype, fd, sx, sy, sz, txy, es, eps, ecs, ex, ey, ez, exy):
"""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)
if isnan(fd):
fd = 0.
if isnan(sz):
sz = 0.
if isnan(ez):
ez = 0.
self._times[self.itime] = dt
#if self.ielement == 10:
#print(self.element_node[:10, :])
#raise RuntimeError()
#[fiber_dist, oxx, oyy, ozz, txy, es, eps, ecs, exx, eyy, ezz, etxy]
assert eid == self.element[self.ielement - 1], 'eid=%s self.element[i-1]=%s' % (eid, self.element[self.ielement - 1])
self.data[self.itime, self.itotal, :] = [fd, sx, sy, sz, txy, es, eps, ecs, ex, ey, ez, exy]
self.itotal += 1
def add_sort2(self, dt, eid, etype, fd, sx, sy, sz, txy, es, eps, ecs, ex, ey, ez, exy):
"""unvectorized method for adding SORT2 transient data"""
assert self.sort_method == 2, self
assert isinstance(eid, integer_types) and eid > 0, 'dt=%s eid=%s' % (dt, eid)
if isnan(fd):
fd = 0.
if isnan(sz):
sz = 0.
if isnan(ez):
ez = 0.
ntimes = len(self._times)
nelement = len(self.element)
ntotal = self.data.shape[1]
ilayer = self.itotal % 2
ielement = self.itime
itotal = self.itotal % ntotal
itime = self.itotal // nelement // 2
#itotal = self.ielement
#try:
self._times[itime] = dt
#except:
#pass
utimes = np.round(np.unique(self._times), 3) # .tolist()
#print('[%s]' % (', '.join('%g' % val for val in utimes)), '; n=%s' % len(utimes))
#[fiber_dist, oxx, oyy, ozz, txy, es, eps, ecs, exx, eyy, ezz, etxy]
#print(f'RealNonlinearPlateArray: itime={itime}/{ntimes} ielement={ielement}/{nelement} ilayer={ilayer} itotal={itotal}/{ntotal} -> dt={dt:<-5g} eid={eid}')
#assert eid == self.element[ielement - 1], 'eid=%s self.element[i-1]=%s' % (eid, self.element[self.ielement - 1])
self.data[itime, itotal, :] = [fd, sx, sy, sz, txy, es, eps, ecs, ex, ey, ez, exy]
self.itotal += 1
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 ielem, eid in enumerate(self.element):
t1 = self.data[itime, ielem, :]
t2 = table.data[itime, ielem, :]
# TODO: this name order is wrong
#[fiber_dist, oxx, oyy, ozz, txy, es, eps, ecs, exx, eyy, ezz, etxy]
(fiber_distance1, oxx1, oyy1, ozz1, txy1, exx1, eyy1, ezz1, exy1, es1, eps1, ecs1) = t1
(fiber_distance2, oxx2, oyy2, ozz2, txy2, exx2, eyy2, ezz2, exy2, es2, eps2, ecs2) = t2
# vm stress can be NaN for some reason...
if not np.array_equal(t1, t2):
eid_spaces = ' ' * (len(str(eid)))
msg += (
# eid fd ox oy oz txy ex ey ez exy es eps ecs1
'%s (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n'
'%s (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n' % (
eid,
fiber_distance1, oxx1, oyy1, ozz1, txy1, exx1, eyy1, ezz1, exy1, es1, eps1, ecs1,
eid_spaces,
fiber_distance2, oxx2, oyy2, ozz2, txy2, exx2, eyy2, ezz2, exy2, es2, eps2, ecs2))
i += 1
if i > 10:
print(msg)
raise ValueError(msg)
#print(msg)
if i > 0:
raise ValueError(msg)
return True
[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
nnodes = self.nnodes
ntotal = self.ntotal
nlayers = 2
nelements = self.ntotal // self.nnodes // 2
msg = []
if self.nonlinear_factor not in (None, np.nan): # transient
msgi = ' type=%s ntimes=%i nelements=%i nnodes_per_element=%i nlayers=%i ntotal=%i, table_name=%s\n' % (
self.__class__.__name__, ntimes, nelements, nnodes, nlayers, ntotal, self.table_name_str)
ntimes_word = 'ntimes'
else:
msgi = ' type=%s nelements=%i nnodes_per_element=%i nlayers=%i ntotal=%i\n' % (
self.__class__.__name__, nelements, nnodes, nlayers, ntotal)
ntimes_word = '1'
msg.append(msgi)
headers = self.get_headers()
n = len(headers)
msg.append(' data: [%s, ntotal, %i] where %i=[%s]\n' % (ntimes_word, n, n,
str(', '.join(headers))))
msg.append(' data.shape=%s\n' % str(self.data.shape))
msg.append(f' element type: {self.element_name}-{self.element_type}\n')
msg += self.get_data_code()
return msg
[docs]
def write_f06(self, f06_file, header=None, page_stamp='PAGE %s', page_num=1,
is_mag_phase=False, is_sort1=True):
if header is None:
header = []
#msg, nnodes, cen = _get_plate_msg(self)
if self.element_type == 88:
msg = [
' N O N L I N E A R S T R E S S E S I N T R I A N G U L A R E L E M E N T S ( T R I A 3 )\n'
' \n'
' ELEMENT FIBER STRESSES/ TOTAL STRAINS EQUIVALENT EFF. STRAIN EFF. CREEP\n'
' ID DISTANCE X Y Z XY STRESS PLASTIC/NLELAST STRAIN\n'
]
elif self.element_type == 90:
msg = [
' N O N L I N E A R S T R E S S E S I N Q U A D R I L A T E R A L E L E M E N T S ( Q U A D 4 )\n'
' \n'
' ELEMENT FIBER STRESSES/ TOTAL STRAINS EQUIVALENT EFF. STRAIN EFF. CREEP\n'
' ID DISTANCE X Y Z XY STRESS PLASTIC/NLELAST STRAIN\n'
#'0 1 -2.500000E-02 -4.829193E+00 -1.640651E-05 -1.907010E-04 4.829185E+00 0.0 0.0\n'
#' -4.829188E-05 1.448741E-05 -4.958226E-09\n'
#' 2.500000E-02 4.770547E+00 1.493975E-04 1.907012E-04 4.770473E+00 0.0 0.0\n'
#' 4.770502E-05 -1.431015E-05 4.958231E-09\n'
]
else: # pragma: no cover
raise NotImplementedError('element_name=%s self.element_type=%s' % (self.element_name, self.element_type))
#msg = [
#' N O N L I N E A R S T R E S S E S I N Q U A D R I L A T E R A L E L E M E N T S ( Q U A D 4 )\n'
#' \n'
#' ELEMENT FIBER STRESSES/ TOTAL STRAINS EQUIVALENT EFF. STRAIN EFF. CREEP\n'
#' ID DISTANCE X Y Z XY STRESS PLASTIC/NLELAST STRAIN\n'
#'0 1 -2.500000E-02 -4.829193E+00 -1.640651E-05 -1.907010E-04 4.829185E+00 0.0 0.0\n'
#' -4.829188E-05 1.448741E-05 -4.958226E-09\n'
#' 2.500000E-02 4.770547E+00 1.493975E-04 1.907012E-04 4.770473E+00 0.0 0.0\n'
#' 4.770502E-05 -1.431015E-05 4.958231E-09\n'
#]
# write the f06
ntimes = self.data.shape[0]
eids = self.element
#cen_word = 'CEN/%i' % nnodes
for itime in range(ntimes):
dt = self._times[itime]
header = _eigenvalue_header(self, header, itime, ntimes, dt)
f06_file.write(''.join(header + msg))
#print("self.data.shape=%s itime=%s ieids=%s" % (str(self.data.shape), itime, str(ieids)))
#[fiber_dist, oxx, oyy, ozz, txy, es, eps, ecs, exx, eyy, ezz, etxy]
fiber_dist = self.data[itime, :, 0]
oxx = self.data[itime, :, 1]
oyy = self.data[itime, :, 2]
ozz = self.data[itime, :, 3]
txy = self.data[itime, :, 4]
es = self.data[itime, :, 5]
eps = self.data[itime, :, 6]
ecs = self.data[itime, :, 7]
exx = self.data[itime, :, 8]
eyy = self.data[itime, :, 9]
ezz = self.data[itime, :, 10]
exy = self.data[itime, :, 11]
for (i, eid, fdi, oxxi, oyyi, ozzi, txyi, exxi, eyyi, ezzi, exyi, esi, epsi, ecsi) in zip(
cycle([0, 1]), eids, fiber_dist, oxx, oyy, ozz, txy, exx, eyy, ezz, exy, es, eps, ecs):
#[fdi, oxxi, oyyi, txyi, major, minor, ovmi] = write_floats_13e(
#[fdi, oxxi, oyyi, txyi, major, minor, ovmi])
#' ELEMENT FIBER STRESSES/ TOTAL STRAINS EQUIVALENT EFF. STRAIN EFF. CREEP\n'
#' ID DISTANCE X Y Z XY STRESS PLASTIC/NLELAST STRAIN\n'
#'0 1 -2.500000E-02 -4.829193E+00 -1.640651E-05 -1.907010E-04 4.829185E+00 0.0 0.0\n'
#' -4.829188E-05 1.448741E-05 -4.958226E-09\n'
#' 2.500000E-02 4.770547E+00 1.493975E-04 1.907012E-04 4.770473E+00 0.0 0.0\n'
#' 4.770502E-05 -1.431015E-05 4.958231E-09\n'
if i == 0:
f06_file.write(
'0 %8i %-13s %-13s %-13s %-13s %-13s %-13s %s\n'
' %-13s %-13s %s\n' % (
# A
# ELEMENT FIBER XYZ STRESS EQUIVALENT EFF.STRAIN EFF.CREEP\n'
eid, write_float_13e(fdi),
write_float_13e(oxxi), write_float_13e(oyyi),
#write_float_13e(ozzi),
write_float_13e(txyi),
write_float_13e(esi), write_float_13e(epsi),
write_float_13e(ecsi),
write_float_13e(exxi), write_float_13e(eyyi),
#write_float_13e(ezzi),
write_float_13e(exyi),
))
else:
f06_file.write(
' %-13s %-13s %-13s %-13s %-13s %-13s %s\n'
' %-13s %-13s %s\n' % (
write_float_13e(fdi),
write_float_13e(oxxi), write_float_13e(oyyi),
#write_float_13e(ozzi),
write_float_13e(txyi),
write_float_13e(esi), write_float_13e(epsi),
write_float_13e(ecsi),
write_float_13e(exxi), write_float_13e(eyyi),
#write_float_13e(ezzi),
write_float_13e(exyi),
)
)
f06_file.write(page_stamp % page_num)
page_num += 1
return page_num - 1
[docs]
class RealNonlinearSolidArray(OES_Object):
"""tested by elements/loadstep_elements.op2"""
def __init__(self, data_code, is_sort1, isubcase, dt):
OES_Object.__init__(self, data_code, isubcase, apply_data_code=True)
#self.code = [self.format_code, self.sort_code, self.s_code]
#self.ntimes = 0 # or frequency/mode
#self.ntotal = 0
self.ielement = 0
self.nelements = 0 # result specific
self.nnodes = None
@property
def is_real(self) -> bool:
return True
@property
def is_complex(self) -> bool:
return False
@property
def nnodes_per_element(self) -> int:
if self.element_type == 85: # CTETRANL
nnodes_per_element = 5
elif self.element_type == 91: # CPENTANL
nnodes_per_element = 7
elif self.element_type == 93: # CHEXANL
nnodes_per_element = 9
elif self.element_type == 256: # CPYRAMNL
nnodes_per_element = 6
else:
raise NotImplementedError('name=%r type=%s' % (self.element_name, self.element_type))
return nnodes_per_element
def _reset_indices(self) -> None:
self.itotal = 0
self.ielement = 0
@property
def is_stress(self):
return True
#def is_bilinear(self):
#if self.element_type in [33, 74]: # CQUAD4, CTRIA3
#return False
#elif self.element_type in [144, 64, 82, 70, 75]: # CQUAD4
#return True
#else:
#raise NotImplementedError(f'name={self.element_name} type={self.element_type}')
[docs]
def build(self):
"""sizes the vectorized attributes of the RealNonlinearPlateArray"""
#print("self.ielement = %s" % self.ielement)
#print(f'ntimes={self.ntimes} nelements={self.nelements} ntotal={self.ntotal} - {self.element_name}')
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 = []
nnodes_per_element = self.nnodes_per_element
#nnodes_per_element = 1
self.nnodes = nnodes_per_element
#self.nelements //= nnodes_per_element
if self.nelements % self.ntimes != 0:
msg = 'nelements=%s ntimes=%s nelements/ntimes=%s' % (
self.nelements, self.ntimes, self.nelements / float(self.ntimes))
raise RuntimeError(msg)
if self.is_sort1:
self.nelements //= self.ntimes
assert self.nelements > 0
self.itime = 0
self.ielement = 0
self.itotal = 0
#self.ntimes = 0
#self.nelements = 0
if self.is_sort1:
ntimes = self.ntimes
#nelements = self.nelements
ntotal = self.ntotal
else:
nelements = self.ntimes
ntimes = self.nelements // self.ntimes
#print("RealNonlinearSolidArray: name=%s type=%s nnodes_per_element=%s ntimes=%s nelements=%s ntotal=%s" % (
#self.element_name, self.element_type, nnodes_per_element, self.ntimes, self.nelements, self.ntotal))
# ntotal = self.ntotal // ntimes
ntotal = nelements * self.nnodes_per_element
self.ntimes = ntimes
self.nelements = nelements
#print("-> ntimes=%s nelements=%s ntotal=%s" % (
#ntimes, nelements, ntotal))
#import sys
#sys.stdout.flush()
assert nelements > 0, nelements
assert ntotal > 0, ntotal
dtype, idtype, fdtype = get_times_dtype(self.nonlinear_factor, self.size, self.analysis_fmt)
self._times = np.zeros(ntimes, dtype=self.analysis_fmt)
self.element_node = np.zeros((ntotal, 2), dtype=idtype)
#[sx, sy, sz, sxy, syz, sxz, se, eps, ecs,
# ex, ey, ez, exy, eyz, exz]
self.data = np.full((ntimes, ntotal, 15), np.nan, dtype=fdtype)
#def build_dataframe(self):
#"""creates a pandas dataframe"""
#import pandas as pd
#headers = self.get_headers()[1:]
##nelements = self.element.shape[0]
#if self.nonlinear_factor not in (None, np.nan):
#column_names, column_values = self._build_dataframe_transient_header()
#self.data_frame = pd.Panel(self.data[:, :, 1:], items=column_values, major_axis=self.element, minor_axis=headers).to_frame()
#self.data_frame.columns.names = column_names
#self.data_frame.index.names = ['ElementID', 'Item']
#else:
## option B - nice!
#df1 = pd.DataFrame(self.element).T
#df1.columns = ['ElementID']
#df2 = pd.DataFrame(self.data[0, :, 1:])
#df2.columns = headers
#self.data_frame = df1.join(df2)
#self.data_frame = self.data_frame.reset_index().set_index(['ElementID'])
#print(self.data_frame)
def add_sort1(self, dt, eid, grid,
sx, sy, sz, sxy, syz, sxz, se, eps, ecs,
ex, ey, ez, exy, eyz, exz):
"""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)
#if isnan(fd):
#fd = 0.
#if isnan(sz):
#sz = 0.
#if isnan(ez):
#ez = 0.
self._times[self.itime] = dt
#if self.ielement == 10:
#print(self.element_node[:10, :])
#raise RuntimeError()
#[fiber_dist, oxx, oyy, ozz, txy, es, eps, ecs, exx, eyy, ezz, etxy]
#assert eid == self.element[self.ielement - 1], 'eid=%s self.element[i-1]=%s' % (eid, self.element[self.ielement - 1])
#print(self.element_node.shape, self.itotal)
self.element_node[self.itotal, :] = [eid, grid]
#a = [sx, sy, sz, sxy, syz, sxz, se, eps, ecs,
#ex, ey, ez, exy, eyz, exz]
self.data[self.itime, self.itotal, :] = [sx, sy, sz, sxy, syz, sxz, se, eps, ecs,
ex, ey, ez, exy, eyz, exz]
self.itotal += 1
def add_sort2(self, dt, eid, grid,
sx, sy, sz, sxy, syz, sxz, se, eps, ecs,
ex, ey, ez, exy, eyz, exz):
"""unvectorized method for adding SORT2 transient data"""
assert self.sort_method == 2, self
assert isinstance(eid, integer_types) and eid > 0, 'dt=%s eid=%s' % (dt, eid)
#if isnan(fd):
#fd = 0.
#if isnan(sz):
#sz = 0.
#if isnan(ez):
#ez = 0.
itime = self.itotal // self.nnodes_per_element
ntimes = self.ntimes
itotal = self.itime * self.nnodes_per_element + self.itotal % self.nnodes_per_element
ntotal = len(self.element_node)
#print(f'RealNonlinearSolidArray: itime={itime}/{ntimes} itotal={itotal}/{ntotal} -> dt={dt} eid={eid} nid={grid}')
self._times[itime] = dt
#if self.ielement == 10:
#print(self.element_node[:10, :])
#raise RuntimeError()
#[fiber_dist, oxx, oyy, ozz, txy, es, eps, ecs, exx, eyy, ezz, etxy]
#assert eid == self.element[self.ielement - 1], 'eid=%s self.element[i-1]=%s' % (eid, self.element[self.ielement - 1])
#print(self.element_node.shape, self.itotal)
#self.element[ielement] = eid
self.element_node[itotal, :] = [eid, grid]
#a = [sx, sy, sz, sxy, syz, sxz, se, eps, ecs,
#ex, ey, ez, exy, eyz, exz]
self.data[itime, itotal, :] = [sx, sy, sz, sxy, syz, sxz, se, eps, ecs,
ex, ey, ez, exy, eyz, exz]
#print(self.element_node.tolist())
self.itotal += 1
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 = f'table_name={self.table_name!r} class_name={self.__class__.__name__}\n'
msg += '%s\n' % str(self.code_information())
i = 0
eids = self.element_node[:, 0]
nids = self.element_node[:, 1]
for itime in range(self.ntimes):
for ielem, eid, nid in zip(count(), eids, nids):
t1 = self.data[itime, ielem, :]
t2 = table.data[itime, ielem, :]
# TODO: this name order is wrong?
#[sx, sy, sz, sxy, syz, sxz, se, eps, ecs,
# ex, ey, ez, exy, eyz, exz]
t1, t2 = nan_filter(t1, t2)
(sx1, sy1, sz1, sxy1, syz1, sxz1, se1, eps1, ecs1, ex1, ey1, ez1, exy1, eyz1, exz1) = t1
(sx2, sy2, sz2, sxy2, syz2, sxz2, se2, eps2, ecs2, ex2, ey2, ez2, exy2, eyz2, exz2) = t2
if not np.array_equal(t1, t2):
eid_spaces = ' ' * (len(str(eid)))
msg += (
# eid sx, sy, sz,sxy,syz,sxz, se,eps,ecs, ex, ey, ez, exy, eyz, exz
'%s (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n'
'%s (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)\n' % (
eid,
sx1, sy1, sz1, sxy1, syz1, sxz1, se1, eps1, ecs1, ex1, ey1, ez1, exy1, eyz1, exz1,
eid_spaces,
sx2, sy2, sz2, sxy2, syz2, sxz2, se2, eps2, ecs2, ex2, ey2, ez2, exy2, eyz2, exz2))
i += 1
if i > 10:
print(msg)
raise ValueError(msg)
#print(msg)
if i > 0:
raise ValueError(msg)
return True
[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
nnodes = self.nnodes
ntotal = self.ntotal
#ntotal = self.ntotal * nnodes
msg = []
if self.nonlinear_factor not in (None, np.nan): # transient
msgi = ' type=%s ntimes=%i nelements=%i nnodes_per_element=%i ntotal=%i, table_name=%s\n' % (
self.__class__.__name__, ntimes, nelements, nnodes, ntotal, self.table_name_str)
ntimes_word = 'ntimes'
else:
msgi = ' type=%s nelements=%i nnodes_per_element=%i ntotal=%i\n' % (
self.__class__.__name__, nelements, nnodes, ntotal)
ntimes_word = '1'
msg.append(msgi)
headers = self.get_headers()
n = len(headers)
msg.append(' data: [%s, ntotal, %i] where %i=[%s]\n' % (ntimes_word, n, n,
str(', '.join(headers))))
msg.append(' data.shape=%s\n' % str(self.data.shape))
msg.append(f' element type: {self.element_name}-{self.element_type}\n')
msg += self.get_data_code()
return msg
[docs]
def write_f06(self, f06_file, header=None, page_stamp='PAGE %s', page_num=1,
is_mag_phase=False, is_sort1=True): # pragma: no cover
if header is None:
header = []
#raise NotImplementedError('RealNonlinearSolidArray.write_f06')
#msg, nnodes, cen = _get_plate_msg(self)
#if self.element_type == 85:
##etype = 'CTETRANL'
#nnodes_per_element = 5
#elif self.element_type == 91:
##etype = 'CPENTANL'
#nnodes_per_element = 7
#elif self.element_type == 93:
##etype = 'CHEXANL'
#nnodes_per_element = 9
#else:
#raise NotImplementedError('name=%r type=%s' % (self.element_name, self.element_type))
if self.element_type == 85:
msg = [
' N O N L I N E A R S T R E S S E S I N T E T R A H E D R O N S O L I D E L E M E N T S ( T E T R A )'
' \n'
' ELEMENT GRID/ POINT STRESSES/ TOTAL STRAINS EQUIVALENT EFF. STRAIN EFF. CREEP\n'
' ID GAUSS ID X Y Z XY YZ ZX STRESS PLAS/NLELAS STRAIN\n'
]
elif self.element_type == 91:
msg = [
' N O N L I N E A R S T R E S S E S I N P E N T A H E D R O N S O L I D E L E M E N T S ( P E N T A )'
' \n'
' ELEMENT GRID/ POINT STRESSES/ TOTAL STRAINS EQUIVALENT EFF. STRAIN EFF. CREEP\n'
' ID GAUSS ID X Y Z XY YZ ZX STRESS PLAS/NLELAS STRAIN\n'
]
elif self.element_type == 93:
msg = [
' N O N L I N E A R S T R E S S E S I N H E X A H E D R O N S O L I D E L E M E N T S ( H E X A )\n'
' \n'
' ELEMENT GRID/ POINT STRESSES/ TOTAL STRAINS EQUIVALENT EFF. STRAIN EFF. CREEP\n'
' ID GAUSS ID X Y Z XY YZ ZX STRESS PLAS/NLELAS STRAIN\n'
#'0 1 GRID CENTER 1.0000E+04 1.5916E-12 1.3642E-12 -3.5862E-13 8.3400E-14 0.0 1.0000E+04 0.0 0.0'
#' 1.5626E-03 -4.6877E-04 -4.6877E-04 -1.4569E-19 3.3881E-20 0.0'
#' 1 1.0000E+04 -1.8190E-12 4.5475E-13 -6.3308E-13 7.4789E-13 -4.6225E-13 1.0000E+04 0.0 0.0'
#' 1.5626E-03 -4.6877E-04 -4.6877E-04 -2.5719E-19 3.0383E-19 -1.8779E-19'
]
elif self.element_type == 256:
msg = [
' N O N L I N E A R S T R E S S E S I N P Y R A M I D S O L I D E L E M E N T S ( P Y R A M )\n'
' \n'
' ELEMENT GRID/ POINT STRESSES/ TOTAL STRAINS EQUIVALENT EFF. STRAIN EFF. CREEP\n'
' ID GAUSS ID X Y Z XY YZ ZX STRESS PLAS/NLELAS STRAIN\n'
]
else: # pragma: no cover
raise NotImplementedError('element_name=%s self.element_type=%s' % (self.element_name, self.element_type))
# write the f06
ntimes = self.data.shape[0]
eids = self.element_node[:, 0]
nids = self.element_node[:, 1]
#cen_word = 'CEN/%i' % nnodes
for itime in range(ntimes):
dt = self._times[itime]
header = _eigenvalue_header(self, header, itime, ntimes, dt)
f06_file.write(''.join(header + msg))
#print("self.data.shape=%s itime=%s ieids=%s" % (str(self.data.shape), itime, str(ieids)))
#oxx, oyy, ozz, txy, tyz, txz, se, eps, ecs,
#exx, eyy, ezz, exy, eyz, exz
oxx = self.data[itime, :, 0]
oyy = self.data[itime, :, 1]
ozz = self.data[itime, :, 2]
txy = self.data[itime, :, 3]
tyz = self.data[itime, :, 4]
txz = self.data[itime, :, 5]
se = self.data[itime, :, 6]
eps = self.data[itime, :, 7]
ecs = self.data[itime, :, 8]
exx = self.data[itime, :, 9]
eyy = self.data[itime, :, 10]
ezz = self.data[itime, :, 11]
exy = self.data[itime, :, 12]
eyz = self.data[itime, :, 13]
exz = self.data[itime, :, 14]
#oxx, oyy, ozz, txy, tyz, txz, se, eps, ecs,
#exx, eyy, ezz, exy, eyz, exz
for (eid, nid, oxxi, oyyi, ozzi, txyi, tyzi, txzi, sei, epsi, ecsi,
exxi, eyyi, ezzi, exyi, eyzi, exzi) in zip(
eids, nids, oxx, oyy, ozz, txy, tyz, txz, se, eps, ecs,
exx, eyy, ezz, exy, eyz, exz):
#' ELEMENT FIBER STRESSES/ TOTAL STRAINS EQUIVALENT EFF. STRAIN EFF. CREEP\n'
#' ID DISTANCE X Y Z XY STRESS PLASTIC/NLELAST STRAIN\n'
#'0 1 GRID CENTER 1.0000E+04 1.5916E-12 1.3642E-12 -3.5862E-13 8.3400E-14 0.0 1.0000E+04 0.0 0.0'
#' 1.5626E-03 -4.6877E-04 -4.6877E-04 -1.4569E-19 3.3881E-20 0.0'
#' 1 1.0000E+04 -1.8190E-12 4.5475E-13 -6.3308E-13 7.4789E-13 -4.6225E-13 1.0000E+04 0.0 0.0'
#' 1.5626E-03 -4.6877E-04 -4.6877E-04 -2.5719E-19 3.0383E-19 -1.8779E-19'
if nid == 0:
#nid = ' CENTER'
#assert len(nid) == 8
f06_file.write(
'0%8i GRID CENTER %-11s %-11s %-11s %-11s %-11s %-11s %-11s %-11s %s\n'
' %-11s %-11s %-11s %-11s %-11s %-11s\n' % (
# A
#oxxi, oyyi, ozzi, txyi, tyzi, txzi, sei, epsi, ecsi,
#exxi, eyyi, ezzi, exyi, eyzi, exzi
# ELEMENT FIBER XYZ STRESS EQUIVALENT EFF.STRAIN EFF.CREEP\n'
eid,
write_float_11e(oxxi), write_float_11e(oyyi), write_float_11e(ozzi),
write_float_11e(txyi), write_float_11e(tyzi), write_float_11e(txzi),
write_float_11e(sei), write_float_11e(epsi), write_float_11e(ecsi),
write_float_11e(exxi), write_float_11e(eyyi), write_float_11e(ezzi),
write_float_11e(exyi), write_float_11e(eyzi), write_float_11e(exzi),
)
)
else:
f06_file.write(
' %8s %8s %-11s %-11s %-11s %-11s %-11s %-11s %-11s %-11s %s\n'
' %-11s %-11s %-11s %-11s %-11s %s\n' % (
# A
#oxxi, oyyi, ozzi, txyi, tyzi, txzi, sei, epsi, ecsi,
#exxi, eyyi, ezzi, exyi, eyzi, exzi
# ELEMENT FIBER XYZ STRESS EQUIVALENT EFF.STRAIN EFF.CREEP\n'
'', nid,
write_float_11e(oxxi), write_float_11e(oyyi), write_float_11e(ozzi),
write_float_11e(txyi), write_float_11e(tyzi), write_float_11e(txzi),
write_float_11e(sei), write_float_11e(epsi), write_float_11e(ecsi),
write_float_11e(exxi), write_float_11e(eyyi), write_float_11e(ezzi),
write_float_11e(exyi), write_float_11e(eyzi), write_float_11e(exzi),
)
)
f06_file.write(page_stamp % page_num)
page_num += 1
return page_num - 1
[docs]
def nan_filter(t1, t2):
is_nan1 = np.isnan(t1)
is_nan2 = np.isnan(t2)
assert np.array_equal(is_nan1, is_nan2)
t1[is_nan1] = 0.
t2[is_nan1] = 0.
return t1, t2