from o3seespy.command.element.base_element import ElementBase
[docs]class ZeroLength(ElementBase):
"""
The ZeroLength Element Class
This command is used to construct a zeroLength element object, which is defined by two nodes at the same location.
The nodes are connected by multiple UniaxialMaterial objects to represent the force-deformation relationship for the
element.
"""
op_type = 'zeroLength'
def __init__(self, osi, ele_nodes, mats: list=None, dirs: list=None, r_flag: float=None, orient: list=None):
"""
Initial method for ZeroLength
Parameters
----------
osi: o3seespy.OpenSeesInstance
ele_nodes: list
A list of two element nodes
mats: list, optional
A list of objects associated with previously-defined uniaxial_materials
dirs: list, optional
A list of material directions: * 1,2,3 - translation along local x,y,z axes, respectively; * 4,5,6 -
rotation about local x,y,z axes, respectively
r_flag: float, optional
Optional, default = 0 * ``rflag`` = 0 no rayleigh damping (default)
orient: list, optional
[x1, x2, x3, y1, y2, y3] to define local x and y directions.
Note that compression is loading in the axis direction (when loading the first node).
i.e. orient = [-1, 0, 0, 0, -1, 0] results in compression in the left and downward dirs.
Examples
--------
>>> import o3seespy as o3
>>> osi = o3.OpenSeesInstance(ndm=2)
>>> coords = [[0, 0], [0, 0]]
>>> ele_nodes = [o3.node.Node(osi, *coords[x]) for x in range(2)]
>>> bilinear_mat = o3.uniaxial_material.Steel01(osi, fy=300., e0=200.0e3, b=0.01)
>>> o3.element.ZeroLength(osi, ele_nodes, mats=[bilinear_mat], dirs=[o3.cc.DOF2D_X], r_flag=1)
"""
self.osi = osi
self.ele_node_tags = [x.tag for x in ele_nodes]
self.ele_nodes = ele_nodes
if mats is None:
self.mats = None
self.mat_tags = None
else:
self.mats = mats
self.mat_tags = [x.tag for x in mats]
self.dirs = dirs
if r_flag is None:
self.r_flag = None
else:
self.r_flag = float(r_flag)
self.orient = orient
osi.n_ele += 1
self._tag = osi.n_ele
self._parameters = [self.op_type, self._tag, *self.ele_node_tags]
if getattr(self, 'mats') is not None:
self._parameters += ['-mat', *self.mat_tags]
if getattr(self, 'dirs') is not None:
self._parameters += ['-dir', *self.dirs]
if getattr(self, 'r_flag') is not None:
self._parameters += ['-doRayleigh', self.r_flag]
if getattr(self, 'orient') is not None:
self._parameters += ['-orient', *self.orient]
self.to_process(osi)
[docs]class ZeroLengthND(ElementBase):
"""
The ZeroLengthND Element Class
This command is used to construct a zeroLengthND element object, which is defined by two nodes at the same location.
The nodes are connected by a single NDMaterial object to represent the force-deformation relationship for the element.
"""
op_type = 'zeroLengthND'
def __init__(self, osi, ele_nodes, mat, uni, orient: list=None):
"""
Initial method for ZeroLengthND
Parameters
----------
osi: o3seespy.OpenSeesInstance
ele_nodes: list
A list of two element nodes
mat: obj
Object associated with previously-defined ndmaterial object
uni: obj
Object associated with previously-defined uniaxial_material object which may be used to represent uncoupled
behavior orthogonal to the plane of the ndmaterial response. see notes 2 and 3.
orient: list, optional
Either [x1, x2, x3] to define local x direction
or [x1, x2, x3, y1, y2, y3] to define local x and y direction
Examples
--------
>>> import o3seespy as o3
>>> # Example is currently not working
>>> osi = o3.OpenSeesInstance(ndm=2)
>>> coords = [[0, 0], [0, 0]]
>>> ele_nodes = [o3.node.Node(osi, *coords[x]) for x in range(2)]
>>> mat = o3.nd_material.ElasticIsotropic(osi, 1.0, 0.3)
>>> uni = o3.uniaxial_material.Elastic(osi, 1.0)
>>> o3.element.ZeroLengthND(osi, ele_nodes=ele_nodes, mat=mat, uni=uni, orient=[1, 2, 3, 4, 5, 6])
"""
self.osi = osi
self.ele_node_tags = [x.tag for x in ele_nodes]
self.ele_nodes = ele_nodes
self.mat = mat
self.uni = uni
self.orient = orient
osi.n_ele += 1
self._tag = osi.n_ele
self._parameters = [self.op_type, self._tag, *self.ele_node_tags, self.mat.tag, self.uni.tag]
if getattr(self, 'orient') is not None:
self._parameters += ['-orient', *self.orient]
self.to_process(osi)
[docs]class ZeroLengthSection(ElementBase):
"""
The ZeroLengthSection Element Class
This command is used to construct a zero length element object, which is defined by two nodes at the same location.
The nodes are connected by a single section object to represent the force-deformation relationship for the element.
"""
op_type = 'zeroLengthSection'
def __init__(self, osi, ele_nodes, sec, r_flag: float=None, orient: list=None):
"""
Initial method for ZeroLengthSection
Parameters
----------
osi: o3seespy.OpenSeesInstance
ele_nodes: list
A list of two element nodes
sec: obj
Object associated with previously-defined section object
r_flag: float, optional
Optional, default = 0 * ``rflag`` = 0 no rayleigh damping (default) * ``rflag`` = 1 include rayleigh damping
orient: list, optional
Examples
--------
>>> import o3seespy as o3
>>> osi = o3.OpenSeesInstance(ndm=2)
>>> coords = [[0, 0], [0, 0]]
>>> ele_nodes = [o3.node.Node(osi, *coords[x]) for x in range(2)]
>>> sec = o3.section.Elastic2D(osi, 10.0, 1.0, 1.0)
>>> o3.element.ZeroLengthSection(osi, ele_nodes=ele_nodes, sec=sec, r_flag=1.0, orient=[1])
"""
self.osi = osi
self.ele_node_tags = [x.tag for x in ele_nodes]
self.ele_nodes = ele_nodes
self.sec = sec
if r_flag is None:
self.r_flag = None
else:
self.r_flag = float(r_flag)
self.orient = orient
osi.n_ele += 1
self._tag = osi.n_ele
self._parameters = [self.op_type, self._tag, *self.ele_node_tags, self.sec.tag]
if getattr(self, 'r_flag') is not None:
self._parameters += ['-doRayleigh', self.r_flag]
if getattr(self, 'orient') is not None:
self._parameters += ['-orient', *self.orient]
self.to_process(osi)
[docs]class CoupledZeroLength(ElementBase):
"""
The CoupledZeroLength Element Class
"""
op_type = 'CoupledZeroLength'
def __init__(self, osi, ele_nodes, dirn1, dirn2, mat, r_flag=1):
"""
Initial method for CoupledZeroLength
Parameters
----------
osi: o3seespy.OpenSeesInstance
ele_nodes: list
A list of two element nodes
dirn1: int
The two directions, 1 through ndof.
dirn2: int
The two directions, 1 through ndof.
mat: obj
Objects associated with previously-defined uniaxial_material
r_flag: float, optional
Optional, default = 0 * ``rflag`` = 0 no rayleigh damping (default) * ``rflag`` = 1 include rayleigh damping
Examples
--------
>>> import o3seespy as o3
>>> osi = o3.OpenSeesInstance(ndm=2)
>>> coords = [[0, 0], [0, 0]]
>>> ele_nodes = [o3.node.Node(osi, *coords[x]) for x in range(2)]
>>> mat = o3.uniaxial_material.Elastic(osi, 1.0)
>>> o3.element.CoupledZeroLength(osi, ele_nodes=ele_nodes, dirn1=1, dirn2=1, mat=mat, r_flag=1)
"""
self.osi = osi
self.ele_node_tags = [x.tag for x in ele_nodes]
self.ele_nodes = ele_nodes
self.dirn1 = int(dirn1)
self.dirn2 = int(dirn2)
self.mat = mat
self.r_flag = float(r_flag)
osi.n_ele += 1
self._tag = osi.n_ele
self._parameters = [self.op_type, self._tag, *self.ele_node_tags, self.dirn1, self.dirn2, self.mat.tag, self.r_flag]
self.to_process(osi)
[docs]class ZeroLengthInterface2Ddof(ElementBase):
"""
The ZeroLengthInterface2Ddof Element Class
"""
op_type = 'zeroLengthInterface2D'
def __init__(self, osi, sdof, mdof, kn, kt, phi, s_nd_num: int=None, m_nd_num: int=None, nodes: list=None):
"""
Initial method for ZeroLengthInterface2Ddof
Parameters
----------
osi: o3seespy.OpenSeesInstance
sdof: int
Slave and master degree of freedom
mdof: int
Slave and master degree of freedom
kn: float
Penalty in normal direction
kt: float
Penalty in tangential direction
phi: float
Friction angle in degrees
s_nd_num: int, optional
Number of slave nodes
m_nd_num: int, optional
Number of master nodes
nodes: list, optional
Slave and master node objects respectively
Examples
--------
>>> import o3seespy as o3
>>> # Example is currently not working
>>> osi = o3.OpenSeesInstance(ndm=2)
>>> nodes = [1, 1]
>>> o3.element.ZeroLengthInterface2Ddof(osi, s_nd_num=1, m_nd_num=1, sdof=1, mdof=1, nodes=nodes, kn=1.0, kt=1.0, phi=1.0)
"""
self.osi = osi
if s_nd_num is None:
self.s_nd_num = None
else:
self.s_nd_num = int(s_nd_num)
if m_nd_num is None:
self.m_nd_num = None
else:
self.m_nd_num = int(m_nd_num)
self.sdof = int(sdof)
self.mdof = int(mdof)
if nodes is None:
self.nodes = None
else:
self.nodes = [x.tag for x in nodes]
self.kn = float(kn)
self.kt = float(kt)
self.phi = float(phi)
osi.n_ele += 1
self._tag = osi.n_ele
self._parameters = [self.op_type, self._tag, '-dof', self.sdof, self.mdof, self.kn, self.kt, self.phi]
if getattr(self, 's_nd_num') is not None:
self._parameters += ['-sNdNum', self.s_nd_num]
if getattr(self, 'm_nd_num') is not None:
self._parameters += ['-mNdNum', self.m_nd_num]
if getattr(self, 'nodes') is not None:
self._parameters += ['-Nodes', *self.nodes]
self.to_process(osi)
[docs]class ZeroLengthImpact3D(ElementBase):
"""
The ZeroLengthImpact3D Element Class
This command constructs a node-to-node zero-length contact element in 3D space to simulate the impact/pounding and
friction phenomena.
"""
op_type = 'zeroLengthImpact3D'
def __init__(self, osi, ele_nodes, direction, init_gap, friction_ratio, kt, kn, kn2, delta_y, cohesion):
"""
Initial method for ZeroLengthImpact3D
Parameters
----------
osi: o3seespy.OpenSeesInstance
ele_nodes: list
A list of a constrained and a retained nodes * ``1`` if out-normal vector of master plane points to +x
direction * ``2`` if out-normal vector of master plane points to +y direction * ``3`` if out-normal vector of
master plane points to +z direction
direction: None
init_gap: float
Initial gap between master plane and slave plane
friction_ratio: float
Friction ratio in two tangential directions (parallel to master and slave planes)
kt: float
Penalty in two tangential directions
kn: float
Penalty in normal direction (normal to master and slave planes)
kn2: float
Penalty in normal direction after yielding based on hertz impact model
delta_y: float
Yield deformation based on hertz impact model
cohesion: float
Cohesion, if no cohesion, it is zero
Examples
--------
>>> import o3seespy as o3
>>> osi = o3.OpenSeesInstance(ndm=2)
>>> coords = [[0, 0], [1, 0], [1, 1], [0, 1]]
>>> ele_nodes = [o3.node.Node(osi, *coords[x]) for x in range(4)]
>>> o3.element.ZeroLengthImpact3D(osi, ele_nodes=ele_nodes, direction=1, init_gap=1.0, friction_ratio=1.0, kt=1.0, kn=1.0, kn2=1.0, delta_y=1.0, cohesion=1.0)
"""
self.osi = osi
self.ele_node_tags = [x.tag for x in ele_nodes]
self.ele_nodes = ele_nodes
self.direction = direction
self.init_gap = float(init_gap)
self.friction_ratio = float(friction_ratio)
self.kt = float(kt)
self.kn = float(kn)
self.kn2 = float(kn2)
self.delta_y = float(delta_y)
self.cohesion = float(cohesion)
osi.n_ele += 1
self._tag = osi.n_ele
self._parameters = [self.op_type, self._tag, *self.ele_node_tags, self.direction, self.init_gap, self.friction_ratio, self.kt, self.kn, self.kn2, self.delta_y, self.cohesion]
self.to_process(osi)