#pylint: disable=C0103,C0111,R0902
"""
All ungrouped properties are defined in this file. This includes:
* PFAST
* PGAP
* PLSOLID (SolidProperty)
* PSOLID (SolidProperty)
* PRAC2D (CrackProperty)
* PRAC3D (CrackProperty)
* PCONEAX (not done)
"""
from __future__ import (nested_scopes, generators, division, absolute_import,
print_function, unicode_literals)
from six.moves import range
from pyNastran.bdf.field_writer_8 import set_blank_if_default
from pyNastran.bdf.cards.baseCard import Property, Material
from pyNastran.bdf.bdfInterface.assign_type import (integer, integer_or_blank,
double, double_or_blank, string_or_blank, integer_string_or_blank, blank)
from pyNastran.bdf.field_writer_8 import print_card_8
from pyNastran.bdf.field_writer_16 import print_card_16
[docs]class PFAST(Property):
type = 'PFAST'
_field_map = {
1: 'pid', 2:'d', 3:'mcid', 4:'mflag',
5:'kt1', 6:'kt2', 7:'kt3',
8:'kr1', 9:'kr2', 10:'kr3',
11:'mass', 12:'ge'
}
def __init__(self, card=None, data=None, comment=''):
Property.__init__(self, card, data)
if comment:
self._comment = comment
if card:
#: Property ID
self.pid = integer(card, 1, 'pid')
#: diameter of the fastener
self.d = double(card, 2, 'd')
assert self.d > 0
#: Specifies the element stiffness coordinate system
self.mcid = integer_or_blank(card, 3, 'mcid', -1)
assert self.mcid >= -1
#: 0-absolute 1-relative
self.mflag = integer_or_blank(card, 4, 'mflag', 0)
assert self.mflag in [0, 1]
#: stiffness values in directions 1-3
self.kt1 = double(card, 5, 'kt1')
self.kt2 = double(card, 6, 'kt2')
self.kt3 = double(card, 7, 'kt3')
#: Rotational stiffness values in directions 1-3
self.kr1 = double_or_blank(card, 8, 'kr1', 0.0)
self.kr2 = double_or_blank(card, 9, 'kr2', 0.0)
self.kr3 = double_or_blank(card, 10, 'kr3', 0.0)
#: Lumped mass of fastener
self.mass = double_or_blank(card, 11, 'mass', 0.0)
#: Structural damping
self.ge = double_or_blank(card, 12, 'ge', 0.0)
assert len(card) <= 13, 'len(PFAST card) = %i' % len(card)
else:
raise NotImplementedError(data)
[docs] def cross_reference(self, model):
msg = ' which is required by PFAST pid=%s' % self.pid
self.mcid = model.Coord(self.mcid, msg)
[docs] def Mcid(self):
if isinstance(self.mcid, int):
return self.mcid
return self.mcid.cid
[docs] def Mass(self):
return self.mass
[docs] def raw_fields(self):
fields = ['PFAST', self.pid, self.d, self.Mcid(), self.mflag, self.kt1,
self.kt2, self.kt3, self.kr1, self.kr2, self.kr3, self.mass,
self.ge]
return fields
[docs] def repr_fields(self):
mcid = set_blank_if_default(self.mcid, -1)
mflag = set_blank_if_default(self.mflag, 0)
kr1 = set_blank_if_default(self.kr1, 0.0)
kr2 = set_blank_if_default(self.kr2, 0.0)
kr3 = set_blank_if_default(self.kr3, 0.0)
mass = set_blank_if_default(self.mass, 0.0)
ge = set_blank_if_default(self.ge, 0.0)
fields = ['PFAST', self.pid, self.d, mcid, mflag, self.kt1, self.kt2,
self.kt3, kr1, kr2, kr3, mass, ge]
return fields
[docs] def write_card(self, size=8, is_double=False):
card = self.repr_fields()
if size == 8:
return self.comment() + print_card_8(card)
return self.comment() + print_card_16(card)
[docs]class PGAP(Property):
type = 'PGAP'
_field_map = {
1: 'pid', 2:'u0', 3:'f0', 4:'ka', 5:'kb', 6:'kt', 7:'mu1',
8:'mu2', 9:'tmax', 10:'mar', 11:'trmin',
}
def __init__(self, card=None, data=None, comment=''):
"""
Defines the properties of the gap element (CGAP entry).
"""
Property.__init__(self, card, data)
if comment:
self._comment = comment
if card:
#: Property ID
self.pid = integer(card, 1, 'pid')
#: initial gap opening
self.u0 = double_or_blank(card, 2, 'u0', 0.)
#: preload
self.f0 = double_or_blank(card, 3, 'f0', 0.)
#: axial stiffness of closed gap
self.ka = double_or_blank(card, 4, 'ka', 1.e8)
#: axial stiffness of open gap
self.kb = double_or_blank(card, 5, 'kb', 1e-14 * self.ka)
#: static friction coeff
self.mu1 = double_or_blank(card, 7, 'mu1', 0.)
#: transverse stiffness of closed gap
self.kt = double_or_blank(card, 6, 'kt', self.mu1 * self.ka)
#: kinetic friction coeff
self.mu2 = double_or_blank(card, 8, 'mu2', self.mu1)
self.tmax = double_or_blank(card, 9, 'tmax', 0.)
self.mar = double_or_blank(card, 10, 'mar', 100.)
self.trmin = double_or_blank(card, 11, 'trmin', 0.001)
assert len(card) <= 12, 'len(PGAP card) = %i' % len(card)
else:
#(pid,u0,f0,ka,kb,kt,mu1,mu2,tmax,mar,trmin) = out
self.pid = data[0]
self.u0 = data[1]
self.f0 = data[2]
self.ka = data[3]
self.kb = data[4]
self.kt = data[5]
self.mu1 = data[6]
self.mu2 = data[7]
self.tmax = data[8]
self.mar = data[9]
self.trmin = data[10]
[docs] def _verify(self, xref=True):
pid = self.Pid()
assert isinstance(pid, int), 'pid=%r\n%s' % (pid, str(self))
[docs] def cross_reference(self, model):
pass
[docs] def raw_fields(self):
fields = ['PGAP', self.pid, self.u0, self.f0, self.ka, self.kb,
self.kt, self.mu1, self.mu2, self.tmax, self.mar, self.trmin]
return fields
[docs] def repr_fields(self):
u0 = set_blank_if_default(self.u0, 0.)
f0 = set_blank_if_default(self.f0, 0.)
ka = set_blank_if_default(self.ka, 1.e8)
kb = set_blank_if_default(self.kb, 1e-14 * self.ka)
kt = set_blank_if_default(self.kt, self.mu1 * self.ka)
mu1 = set_blank_if_default(self.mu1, 0.)
mu2 = set_blank_if_default(self.mu2, self.mu1)
tmax = set_blank_if_default(self.tmax, 0.)
mar = set_blank_if_default(self.mar, 100.)
trmin = set_blank_if_default(self.trmin, 0.001)
fields = ['PGAP', self.pid, u0, f0, ka, kb, kt, mu1, mu2,
tmax, mar, trmin]
return fields
[docs] def write_card(self, size=8, is_double=False):
card = self.repr_fields()
if size == 8:
return self.comment() + print_card_8(card)
return self.comment() + print_card_16(card)
[docs]class SolidProperty(Property):
def __init__(self, card, data):
Property.__init__(self, card, data)
[docs] def Rho(self):
return self.mid.rho
[docs]class PLSOLID(SolidProperty):
"""
Defines a fully nonlinear (i.e., large strain and large rotation)
hyperelastic solid element.
PLSOLID PID MID STR
PLSOLID 20 21
"""
type = 'PLSOLID'
_field_map = {
1: 'pid', 2:'mid', 3:'str',
}
def __init__(self, card=None, data=None, comment=''):
SolidProperty.__init__(self, card, data)
if comment:
self._comment = comment
if card:
#: Property ID
self.pid = integer(card, 1, 'pid')
#: Material ID
self.mid = integer(card, 2, 'mid')
#: Location of stress and strain output
self.str = string_or_blank(card, 3, 'str', 'GRID')
assert len(card) <= 4, 'len(PLSOLID card) = %i' % len(card)
else:
self.pid = data[0]
self.mid = data[1]
self.ge = data[2]
self.str = data[3]
if self.str not in ['GRID', 'GAUS']:
raise RuntimeError('STR="%s" doesnt have a valid stress/strain '
'output value set; valid=["GRID", "GAUS"]\n'
% self.str)
[docs] def cross_reference(self, model):
msg = ' which is required by PLSOLID pid=%s' % self.pid
self.mid = model.HyperelasticMaterial(self.mid, msg)
[docs] def raw_fields(self):
stress_strain = set_blank_if_default(self.str, 'GRID')
fields = ['PLSOLID', self.pid, self.Mid(), stress_strain]
return fields
[docs] def write_card(self, size=8, is_double=False):
card = self.repr_fields()
if size == 8:
return self.comment() + print_card_8(card)
return self.comment() + print_card_16(card)
[docs]class PSOLID(SolidProperty):
"""
PSOLID PID MID CORDM IN STRESS ISOP FCTN
PSOLID 1 1 0
PSOLID 2 100 6 TWO GRID REDUCED
"""
type = 'PSOLID'
_field_map = {
1: 'pid', 2:'mid', 3:'cordm', 4:'integ', 5:'stress',
6:'isop', 7:'fctn',
}
def __init__(self, card=None, data=None, comment=''):
SolidProperty.__init__(self, card, data)
if comment:
self._comment = comment
if card:
#: Property ID
self.pid = integer(card, 1, 'pid')
#: Material ID
self.mid = integer(card, 2, 'mid')
self.cordm = integer_or_blank(card, 3, 'cordm', 0)
self.integ = integer_string_or_blank(card, 4, 'integ')
#validIntegration = ['THREE', 'TWO', 'FULL', 'BUBBLE',
# 2, 3, None, 'REDUCED']
self.stress = integer_string_or_blank(card, 5, 'stress')
self.isop = integer_string_or_blank(card, 6, 'isop')
self.fctn = string_or_blank(card, 7, 'fctn', 'SMECH')
assert len(card) <= 8, 'len(PSOLID card) = %i' % len(card)
else:
self.pid = data[0]
self.mid = data[1]
self.cordm = data[2]
self.integ = data[3]
self.stress = data[4]
self.isop = data[5]
self.fctn = data[6]
if self.fctn == 'SMEC':
self.fctn = 'SMECH'
[docs] def E(self):
return self.mid.E()
[docs] def G(self):
return self.mid.G()
[docs] def Nu(self):
return self.mid.Nu()
[docs] def materials(self):
return [self.mid]
[docs] def _verify(self, xref=False):
pid = self.Pid()
mid = self.Mid()
assert isinstance(pid, int), 'pid=%r' % pid
assert isinstance(mid, int), 'mid=%r' % mid
if xref:
if self.mid.type not in ['MAT1', 'MAT4', 'MAT9', 'MAT10', 'MAT11']:
msg = 'mid=%i self.mid.type=%s' % (mid, self.mid.type)
raise TypeError(msg)
[docs] def _write_calculix(self, elementSet=999):
msg = '*SOLID SECTION,MATERIAL=M%s,ELSET=E_Mat%s\n' % (
self.mid, elementSet)
return msg
[docs] def raw_fields(self):
fields = ['PSOLID', self.pid, self.Mid(), self.cordm, self.integ,
self.stress, self.isop, self.fctn]
return fields
[docs] def repr_fields(self):
cordm = set_blank_if_default(self.cordm, 0)
fctn = set_blank_if_default(self.fctn, 'SMECH')
fields = ['PSOLID', self.pid, self.Mid(), cordm, self.integ,
self.stress, self.isop, fctn]
return fields
[docs] def write_card(self, size=8, is_double=False):
card = self.repr_fields()
# this card has integers & strings, so it uses...
return self.comment() + print_card_8(card)
[docs]class CrackProperty(Property):
def __init__(self, card, data):
Property.__init__(self, card, data)
[docs] def Mid(self):
if isinstance(self.mid, int):
return self.mid
return self.mid.mid
[docs] def write_card(self, size=8, is_double=False):
card = self.repr_fields()
if size == 8:
return self.comment() + print_card_8(card)
return self.comment() + print_card_16(card)
[docs]class PRAC2D(CrackProperty):
"""
CRAC2D Element Property
Defines the properties and stress evaluation techniques to be used with
the CRAC2D structural element.
"""
type = 'PRAC2D'
_field_map = {
1: 'pid', 2:'mid', 3:'thick', 4:'iPlane', 5:'nsm', 6:'gamma', 7:'phi',
}
def __init__(self, card=None, data=None, comment=''):
CrackProperty.__init__(self, card, data)
if comment:
self._comment = comment
if card:
#: Property ID
self.pid = integer(card, 1, 'pid')
#: Material ID
self.mid = integer(card, 2, 'mid')
self.thick = double(card, 3, 'thick')
#: Plane strain or plane stress option.
#: Use 0 for plane strain; 1 for plane stress. (Integer = 0 or 1)
self.iPlane = integer(card, 4, 'iPlane')
if self.iPlane not in [0, 1]:
raise RuntimeError('Invalid value for iPlane on PRAC2D, can '
'only be 0,1 iPlane=|%s|' % self.iPlane)
#: Non-structural mass per unit area.(Real >= 0.0; Default = 0)
self.nsm = double_or_blank(card, 5, 'nsm', 0.)
#: Exponent used in the displacement field. See Remark 4.
#: (Real; Default = 0.5)
self.gamma = double_or_blank(card, 6, 'gamma', 0.5)
#: Angle (in degrees) relative to the element x-axis along which
#: stress intensity factors are to be calculated. See Remark 4.
#: (Real; Default = 180.0)
self.phi = double_or_blank(card, 7, 'phi', 180.)
assert len(card) <= 8, 'len(PRAC2D card) = %i' % len(card)
else:
raise NotImplementedError(data)
[docs] def _verify(self, xref=True):
pid = self.Pid()
assert isinstance(pid, int)
[docs] def cross_reference(self, model):
msg = ' which is required by PRAC2D pid=%s' % self.pid
self.mid = model.Material(self.mid, msg) # MAT1, MAT2, MAT8
[docs] def raw_fields(self):
fields = ['PRAC2D', self.pid, self.Mid(), self.thick,
self.iPlane, self.nsm, self.gamma, self.phi]
return fields
[docs] def repr_fields(self):
nsm = set_blank_if_default(self.nsm, 0.)
gamma = set_blank_if_default(self.gamma, 0.5)
phi = set_blank_if_default(self.phi, 180.)
fields = ['PRAC2D', self.pid, self.Mid(), self.thick,
self.iPlane, nsm, gamma, phi]
return fields
[docs]class PRAC3D(CrackProperty):
"""
CRAC3D Element Property
Defines the properties of the CRAC3D structural element.
"""
type = 'PRAC3D'
_field_map = {
1: 'pid', 2:'mid', 3:'gamma', 4:'phi',
}
def __init__(self, card=None, data=None, comment=''):
CrackProperty.__init__(self, card, data)
if comment:
self._comment = comment
if card:
#: Property ID
self.pid = integer(card, 1, 'pid')
#: Material ID
self.mid = integer(card, 2, 'mid')
#: Exponent used in the displacement field. See Remark 4.
#: (Real; Default = 0.5)
self.gamma = double_or_blank(card, 3, 'gamma', 0.5)
#: Angle (in degrees) relative to the element x-axis along which
#: stress intensity factors are to be calculated. See Remark 4.
#: (Real; Default = 180.0)
self.phi = double_or_blank(card, 4, 'gamma', 180.)
assert len(card) <= 5, 'len(PRAC3D card) = %i' % len(card)
else:
raise NotImplementedError(data)
[docs] def _verify(self, xref=True):
pid = self.Pid()
assert isinstance(pid, int)
[docs] def cross_reference(self, model):
msg = ' which is required by PRAC3D pid=%s' % self.pid
self.mid = model.Material(self.mid, msg) # MAT1, MAT9
[docs] def raw_fields(self):
fields = ['PRAC3D', self.pid, self.Mid(), self.gamma, self.phi]
return fields
[docs] def repr_fields(self):
gamma = set_blank_if_default(self.gamma, 0.5)
phi = set_blank_if_default(self.phi, 180.)
fields = ['PRAC3D', self.pid, self.Mid(), gamma, phi]
return fields
[docs]class PCONEAX(Property):
type = 'PCONEAX'
_field_map = {
1: 'pid', 2:'mid1', 3:'t1', 4:'mid2', 5:'i', 6:'mid3', 7:'t2',
8: 'nsm', 9:'z1', 10:'z2',
}
[docs] def _update_field_helper(self, n, value):
if n <= 0:
msg = 'Field %r=%r is an invalid %s entry.' % (n, value, self.type)
raise KeyError(msg)
self.phi[n - 10] = value
def __init__(self, card=None, data=None, comment=''):
Property.__init__(self, card, data)
if comment:
self._comment = comment
if card:
#: Property ID
self.pid = integer(card, 1, 'pid')
#: Material ID
self.mid1 = integer_or_blank(card, 2, 'mid1', 0)
self.t1 = double_or_blank(card, 3, 't1')
self.mid2 = integer_or_blank(card, 4, 'mid2', 0)
if self.mid2 > 0:
self.i = double(card, 5, 'i')
assert self.i > 0.0
else:
self.i = blank(card, 5, 'i')
self.mid3 = integer(card, 6, 0)
if self.mid3 > 0:
self.t2 = double(card, 7, 't3')
assert self.t2 > 0.0
else:
self.t2 = blank(card, 7, 't3')
self.nsm = double(card, 8, 'nsm')
self.z1 = double(card, 9, 'z1')
self.z2 = double(card, 10, 'z2')
j = 1
self.phi = []
for i in range(11, len(card)):
phii = double(card, i, 'phi' % j)
self.phi.append(phii)
j += 1
else:
raise NotImplementedError(data)
[docs] def cross_reference(self, model):
msg = ' which is required by %s=%s' %(self.type, self.pid)
if self.mid1 > 0:
self.mid1 = model.Material(self.mid1, msg=msg)
if self.mid2 > 0:
self.mid2 = model.Material(self.mid2, msg=msg)
if self.mid3 > 0:
self.mid3 = model.Material(self.mid3, msg=msg)
[docs] def Mid1(self):
if isinstance(self.mid1, Material):
return self.mid1.mid
return self.mid1
[docs] def Mid2(self):
if isinstance(self.mid2, Material):
return self.mid2.mid
return self.mid2
[docs] def Mid3(self):
if isinstance(self.mid3, Material):
return self.mid3.mid
return self.mid3
[docs] def raw_fields(self):
fields = ['PCONEAX', self.pid, self.Mid1(), self.t1,
self.Mid2(), self.i, self.Mid3(), self.t2,
self.nsm, self.z1, self.z2] + self.phi
return fields
[docs] def repr_fields(self):
nsm = set_blank_if_default(self.nsm, 0.0)
mid1 = set_blank_if_default(self.Mid1(), 0)
mid2 = set_blank_if_default(self.Mid2(), 0)
mid3 = set_blank_if_default(self.Mid3(), 0)
i = set_blank_if_default(self.i, 0.0)
t1 = set_blank_if_default(self.t1, 0.0)
t2 = set_blank_if_default(self.t2, 0.0)
fields = ['PCONEAX', self.pid, mid1, t1, mid2, i, mid3, t2,
nsm, self.z1, self.z2] + self.phi
return fields
[docs] def write_card(self, size=8, is_double=False):
card = self.repr_fields()
if size == 8:
return self.comment() + print_card_8(card)
return self.comment() + print_card_16(card)