Source code for fem2d.elements.beam_hinges

"""
Beam with hinges module defining beam elements with internal moment releases.
"""

from fem2d.elements.beam import BeamElement
import numpy as np


[docs] class BeamWithHingesElement(BeamElement): """ Beam element that allows specifying internal moment releases (hinges) at ends i and/or j. Attributes ---------- hinge_i : bool Whether end i has a moment release (hinge). hinge_j : bool Whether end j has a moment release (hinge). """ def __init__( self, eid, node_i, node_j, material, area, inertia, hinge_i=False, hinge_j=False ): """ Initialize a BeamWithHingesElement. Parameters ---------- eid : int or str Unique identifier of the element. node_i : Node Start node. node_j : Node End node. material : ElasticMaterial Material definition. area : float Cross-sectional area. inertia : float Moment of inertia. hinge_i : bool, optional Whether end i has a hinge. Defaults to False. hinge_j : bool, optional Whether end j has a hinge. Defaults to False. """ super().__init__(eid, node_i, node_j, material, area, inertia) self.hinge_i = hinge_i self.hinge_j = hinge_j
[docs] def local_stiffness(self): """ Compute local stiffness matrix taking moment releases into account. Returns ------- numpy.ndarray 6x6 local stiffness matrix. Raises ------ NotImplementedError If only a single hinge is specified (not yet fully implemented). """ k_full = super().local_stiffness() if not self.hinge_i and not self.hinge_j: return k_full # Apply releases: zero moment at hinge ends. # This requires condensing out the rotational DOFs at released ends. # For simplicity, we'll implement the common case of a beam with both ends hinged. # The resulting stiffness is then a truss‑like element with axial stiffness only, # but that's exactly what a truss element does. So for hinges, you might simply use TrussElement. # A more sophisticated implementation would keep the bending terms but allow moment release. # Here we'll return a modified matrix (for illustration): if self.hinge_i and self.hinge_j: # Both ends hinged -> axial only k = np.zeros((6, 6)) k[0, 0] = k[0, 3] = k[3, 0] = k[3, 3] = ( self.area * self.material.E / self.length ) return k # Single hinge: you'd need to condense the rotation at that end. # This is more involved and usually done by solving for the rotation in terms of translations. # For brevity, we'll skip the full implementation here. raise NotImplementedError("Single hinge not yet implemented")