Truss - Linear truss 3D element with analytical integration (pyfe3d.truss)#

Note

The BeamC element is recommended because of the better physical representation.

Note

The Truss element does not support linear buckling analysis.

Defines the two-node element Truss, with six degrees-of-freedom per node, its probe TrussProbe and TrussData, which gives the number of sparse entries per element of each structural matrix. The cross-section and material properties are given by a BeamProp object.

class pyfe3d.truss.Truss#

Truss 3D element for axial- and torsion-only behavior

Nodal connectivity for the truss element:

______   --> u  ->>- rx
1    2

Note

The BeamC is recommended because of the better physical representation.

The constructor stores p in probe, sets eid, pid, n1, n2, c1 and c2 to -1, and sets the init_k_* positions, length and the rotation matrix to 0. The methods use the attributes updated by the others: update_rotation_matrix() reads c1 and c2; update_probe_xe() reads the rotation matrix and updates length; update_KC0(), update_M() and update_probe_finte() read length and the rotation matrix; update_probe_finte() also reads probe.ue, updated by update_probe_ue().

Parameters:
pTrussProbe object

Probe of the element, stored in probe. It can be shared with other elements.

Attributes:
eid,int

Element identification number.

pid,int

Property identification number.

length,double

Element length, dimension length. Updated by update_length().

r11, r12, r13, r21, r22, r23, r31, r32, r33double

Entries \(T_{ij}\) of the transformation matrix \(\boldsymbol{T}_{3\times 3}\) from element to global coordinates, whose columns are the element axes. Dimensionless.

c1, c2int

Position of each node in the global stiffness matrix, i.e. of the first of its 6 degrees-of-freedom. The coordinates of the node are read from the position c1//2 or c2//2 of the array of nodal coordinates.

n1, n2int

Node identification number.

init_k_KC0, init_k_Mint

Position in the arrays storing the sparse data for the structural matrices, where the entries of this element start, see TrussData for their number.

probe,TrussProbe object

Pointer to the probe.

Methods

update_KC0(self, long[, long[, double[, ...)

Update sparse vectors for linear constitutive stiffness matrix KC0

update_M(self, long[, long[, double[, ...)

Update sparse vectors for mass matrix M

update_fint(self, double[, BeamProp prop)

Update the internal force vector

update_length(self)

Update element length

update_probe_finte(self, BeamProp prop)

Update the internal force vector of the probe

update_probe_ue(self, double[)

Update the local displacement vector of the probe of the element

update_probe_xe(self, double[)

Update the 3D coordinates of the probe of the element

update_rotation_matrix(self, double[)

Update the rotation matrix of the element

Notes

The strain energy of the element is

\[U = \frac{1}{2} \int_0^L \left( E A u_{,x}^2 + G J {r_x}_{,x}^2 \right) dx\]

where \(E A\) and \(G J\) are the entries C[0, 0] and C[3, 3] of the sectional stiffness matrix C of BeamProp, i.e. E*A and the torsional stiffness GJ when C is not set; the other entries of C, e.g. the extension-twist coupling C[0, 3], are not used. The axial displacement \(u\) and the twist rotation \(r_x\) are interpolated linearly between the nodes, in the element coordinate system, and \(L\) = length. The transverse translations \(v\), \(w\) and the rotations \(r_y\), \(r_z\) have no stiffness and must be supported by other elements or by boundary conditions; the element has no geometric stiffness matrix. The matrices and the internal forces are computed in element coordinates and transformed to global coordinates with the transformation matrix of the element, \(\boldsymbol{K} = \boldsymbol{T} \boldsymbol{K}_e \boldsymbol{T}^\top\), where \(\boldsymbol{T}\) is block diagonal with four copies of the matrix \(\boldsymbol{T}_{3\times 3}\) of the entries \(T_{ij}\) stored in r11, ..., r33, whose columns are the element axes.

c1#

c1: ‘int’

c2#

c2: ‘int’

eid#

eid: ‘int’

init_k_KC0#

init_k_KC0: ‘int’

init_k_M#

init_k_M: ‘int’

length#

length: ‘double’

n1#

n1: ‘int’

n2#

n2: ‘int’

pid#

pid: ‘int’

probe#

probe: pyfe3d.truss.TrussProbe

r11#

r11: ‘double’

r12#

r12: ‘double’

r13#

r13: ‘double’

r21#

r21: ‘double’

r22#

r22: ‘double’

r23#

r23: ‘double’

r31#

r31: ‘double’

r32#

r32: ‘double’

r33#

r33: ‘double’

update_KC0(self, long[: :1] KC0r, long[: :1] KC0c, double[: :1] KC0v, BeamProp prop, int update_KC0v_only=0) → void#

Update sparse vectors for linear constitutive stiffness matrix KC0

The 72 entries of the matrix of the element, in global coordinates, are written at the positions init_k_KC0 to init_k_KC0 + 71: the row and column indices, built from c1 and c2, are stored in KC0r and KC0c, and the values are added to those already in KC0v. The matrix is computed from length, the rotation matrix and C[0, 0] and C[3, 3] of the sectional stiffness matrix of prop, see the notes of Truss. length and the rotation matrix must be updated before, see update_rotation_matrix() and update_probe_xe().

Parameters:
KC0rnp.array

Array to store row positions of sparse values. 1-D array of integers of the C type long, of size at least init_k_KC0 + 72.

KC0cnp.array

Array to store column positions of sparse values. Same type and size as KC0r.

KC0vnp.array

Array to store sparse values. 1-D array of floats of size at least init_k_KC0 + 72.

propBeamProp object

Beam property object from where the stiffness and mass attributes are read from.

update_KC0v_onlyint, optional

The default 0 means that the row and column indices KC0r and KC0c should also be updated. Any other value will only update the stiffness matrix values KC0v.

Notes

In element coordinates, KC0 is the Hessian of the strain energy given in the notes of Truss, with the entries \(\pm E A/L\) between the axial translations and \(\pm G J/L\) between the twist rotations of the two nodes.

update_M(self, long[: :1] Mr, long[: :1] Mc, double[: :1] Mv, BeamProp prop, int mtype=0) → void#

Update sparse vectors for mass matrix M

For the Truss element, the inertial terms intrho, intrhoy, intrhoz, intrhoy2 and intrhoz2 of the beam property are important.

The entries of the matrix of the element, in global coordinates, are written from the position init_k_M: 144 entries with mtype=0 and 36 entries with mtype=1. The row and column indices, built from c1 and c2, are stored in Mr and Mc, and the values are added to those already in Mv. The matrix is computed from length, the rotation matrix and the inertial terms above. length and the rotation matrix must be updated before, see update_rotation_matrix() and update_probe_xe().

Parameters:
Mrnp.array

Array to store row positions of sparse values. 1-D array of integers of the C type long, of size at least init_k_M + 144 (init_k_M + 36 with mtype=1).

Mcnp.array

Array to store column positions of sparse values. Same type and size as Mr.

Mvnp.array

Array to store sparse values. 1-D array of floats, of the same size as Mr.

propBeamProp object

Beam property object from where the inertial attributes are read.

mtypeint, optional

0 for consistent mass matrix, 1 for lumped mass matrix. Default 0. The element has no reduced-integration mass matrix, 2.

Raises:
ValueError

If mtype is not 0 or 1.

Notes

The mass matrices come from the kinetic energy of the rigid cross section, whose point \((y, z)\) has the displacements \(u_x = u\), \(u_y = v - z r_x\) and \(u_z = w + y r_x\), with the three translations and the twist rotation \(r_x\) interpolated linearly:

\[T = \frac{1}{2} \int_0^L \Big[ m (\dot{u}^2 + \dot{v}^2 + \dot{w}^2) - 2 m_z \dot{v} \dot{r}_x + 2 m_y \dot{w} \dot{r}_x + (m_{yy} + m_{zz}) \dot{r}_x^2 \Big] dx\]

with \(m\) = intrho, \(m_y\) = intrhoy, \(m_z\) = intrhoz, \(m_{yy}\) = intrhoy2 and \(m_{zz}\) = intrhoz2. The coupling terms, \(-m_z\) between \(v\) and \(r_x\) and \(+m_y\) between \(w\) and \(r_x\), are those of BeamLR.update_M() and BeamC.update_M(). The rotations \(r_y\) and \(r_z\) have no inertia. mtype=0 gives the consistent mass matrix, the Hessian of \(T\) with respect to the nodal velocities, integrated exactly along the element. mtype=1 gives the lumped mass matrix, diagonal in element coordinates: at each node \(L m/2\) for the three translations and \(L (m_{yy} + m_{zz})/2\) for \(r_x\), without the coupling terms of \(m_y\) and \(m_z\).

The lumped mass matrix follows the lumped mass matrix by Lobatto integration of Brockman (1987) [1], p. 2348, adapted to the beam: the two-point Gauss-Lobatto quadrature of \(T\), whose points are the nodes, gives a diagonal matrix only without the first moments of the density, which are therefore dropped. The consistent mass matrix is the integral of Petyt (2010) [2], Sec. 3.3, Eqs. (3.58) and (3.59), for each linearly interpolated field, e.g. \(L m/6\) times \([2, 1; 1, 2]\) for each translation, and Sec. 3.4, Eq. (3.102), with \(m_{yy} + m_{zz}\) in place of \(\rho I_x\), for the twist \(r_x\).

References

[1]

Brockman, R. A., 1987, “Dynamics of the Bilinear Mindlin Plate Element,” Int. J. Numer. Methods Eng., 24(12), pp. 2343–2356. https://onlinelibrary.wiley.com/doi/pdf/10.1002/nme.1620241208

[2]

Petyt, M., 2010, Introduction to Finite Element Vibration Analysis, 2nd ed., Cambridge University Press, Cambridge. https://doi.org/10.1017/CBO9780511761195

update_fint(self, double[: :1] fint, BeamProp prop) → void#

Update the internal force vector

Calls update_probe_finte(prop), transforms the forces and moments of probe.finte to global coordinates with the rotation matrix and adds them to fint at the positions c1 to c1 + 5 and c2 to c2 + 5. The displacements probe.ue must be updated before, see update_probe_ue().

Parameters:
fintnp.array

Array that is updated in place with the internal forces. The internal forces stored in fint are calculated in global coordinates. Method update_probe_finte() is called to update the parameter finte of the TrussProbe with the internal forces in local coordinates. 1-D array of size 6*M, for \(M\) nodes in the model.

propBeamProp object

Beam property object from where the stiffness and mass attributes are read from.

update_length(self) → void#

Update element length

The distance between the two nodes, computed from the coordinates probe.xe in the element coordinate system, is stored in the attribute length. Called by update_probe_xe().

update_probe_finte(self, BeamProp prop) → void#

Update the internal force vector of the probe

The attribute finte is updated with the TrussProbe the internal forces in local coordinates. While using this function, mind that the probe can be shared amongst more than one finite element, depending how you defined them, meaning that the probe will always safe the values from the last udpate.

Note

The finte attribute of object TrussProbe is updated, accessible using .probe.finte.

The 12 values of finte are overwritten. They are computed from length, from C[0, 0] and C[3, 3] of the sectional stiffness matrix of prop, see the notes of Truss, and from the displacements probe.ue, which must be updated before, see update_probe_xe() and update_probe_ue(). Only the axial forces and the torsion moments are not zero.

Parameters:
propBeamProp object

Beam property object from where the stiffness and mass attributes are read from.

update_probe_ue(self, double[: :1] u) → void#

Update the local displacement vector of the probe of the element

Note

The ue attribute of object TrussProbe is updated, accessible using .probe.ue.

The translations and rotations of the two nodes, read from u at the positions c1 to c1 + 5 and c2 to c2 + 5, are transformed to the element coordinate system with the transpose \(\boldsymbol{T}_{3\times 3}^\top\) of the transformation matrix, which must be updated before, see update_rotation_matrix().

Parameters:
uarray-like

Array with global displacements, for a total of \(M\) nodes in the model, this array will be arranged as: \(u_1, v_1, w_1, {r_x}_1, {r_y}_1, {r_z}_1, u_2, v_2, w_2, {r_x}_2, {r_y}_2, {r_z}_2, ..., u_M, v_M, w_M, {r_x}_M, {r_y}_M, {r_z}_M\). Translations of dimension length and rotations, 1-D array of size 6*M.

update_probe_xe(self, double[: :1] x) → void#

Update the 3D coordinates of the probe of the element

Note

The xe attribute of object TrussProbe is updated, accessible using .probe.xe.

The coordinates of the two nodes, read from x at the positions c1//2 and c2//2, are transformed to the element coordinate system with the transpose \(\boldsymbol{T}_{3\times 3}^\top\) of the transformation matrix, which must be updated before, see update_rotation_matrix(). Then update_length() is called, updating length.

Parameters:
xarray-like

Array with global nodal coordinates, for a total of \(M\) nodes in the model, this array will be arranged as: \(x_1, y_1, z_1, x_2, y_2, z_2, ..., x_M, y_M, z_M\). Dimension length, 1-D array of size 3*M.

update_rotation_matrix(self, double[: :1] x) → void#

Update the rotation matrix of the element

Attributes r11,r12,r13,r21,r22,r23,r31,r32,r33 are updated, with the entries \(T_{ij}\) of the transformation matrix \(\boldsymbol{T}_{3\times 3}\) from element to global coordinates, whose columns are the element axes.

The element coordinate system is determined, identifying the \(ijk\) components of each axis: \({x_e}_i, {x_e}_j, {x_e}_k\); \({y_e}_i, {y_e}_j, {y_e}_k\); \({z_e}_i, {z_e}_j, {z_e}_k\).

The element \(x\) axis goes from node 1 to node 2, whose coordinates are read from x at the positions c1//2 and c2//2. The \(z\) axis is normal to the \(x\) axis and to the vector obtained by a cyclic permutation of the components of the \(x\) axis, (xj, xk, xi), the \(y\) axis completes the right-handed system, and the three axes are normalized.

Parameters:
xarray-like

Array with global nodal coordinates, for a total of \(M\) nodes in the model, this array will be arranged as: \(x_1, y_1, z_1, x_2, y_2, z_2, ..., x_M, y_M, z_M\). Dimension length, 1-D array of size 3*M.

class pyfe3d.truss.TrussData#

Used to allocate memory for the sparse matrices.

Each attribute is the number of entries that one Truss element writes in the arrays of rows, columns and values of a sparse matrix, at the consecutive positions that start at its init_k_KC0 or init_k_M. The constructor takes no argument and sets the values below.

Attributes:
KC0_SPARSE_SIZEint

KC0_SPARSE_SIZE: ‘int’

M_SPARSE_SIZEint

M_SPARSE_SIZE: ‘int’

KC0_SPARSE_SIZE#

KC0_SPARSE_SIZE: ‘int’

M_SPARSE_SIZE#

M_SPARSE_SIZE: ‘int’

class pyfe3d.truss.TrussProbe#

Probe used for local coordinates, local displacements, local stresses etc

The idea behind using a probe is to avoid allocating larger memory buffers per finite element. The memory buffers are allocated per probe, and one probe can be shared amongst many finite elements, with the information being updated and retrieved on demand.

Note

The probe can be shared amongst more than one finite element, depending on how you defined them. Mind that the probe will always safe the values from the last udpate.

The constructor takes no argument and allocates the arrays below, filled with zeros.

Attributes:
xearray-like

xe: ‘double[::1]’

uearray-like

ue: ‘double[::1]’

finte,array-like

Array of size NUM_NODES*DOF=12 containing the element internal forces corresponding to the degrees-of-freedom described by ue, forces and moments. Updated by Truss.update_probe_finte().

finte#

finte: ‘double[::1]’

ue#

ue: ‘double[::1]’

xe#

xe: ‘double[::1]’