Source code for femethods.reactions

"""
The reactions module defines different reaction classes

A reaction is required to support an element to resist any input forces.

There are two types of reactions that are defined.

    * PinnedReaction, allows rotational displacement only
    * FixedReaction, does not allow any displacement

"""
from typing import Optional, Tuple

from femethods.core._common import Forces

BOUNDARY_CONDITIONS = Tuple[Optional[int], Optional[int]]


[docs]class Reaction(Forces): """Base class for all reactions The Reaction class defines general properties related to all reaction types. Parameters: location (:obj:`float`): the axial location of the reaction along the length of the beam. .. note:: Any force or moment values that where calculated values are invalidated (set to :obj:`None`) any time the location is set. Attributes: force (:obj:`float | None`): the force of the reaction after it has been calculated moment (:obj:`float | None`): The moment of the reaction after it has been calculated """ name = "" def __init__(self, location: float): super().__init__(magnitude=None, location=location) self.force = None self.moment = None self._boundary: BOUNDARY_CONDITIONS = (None, None) @property def boundary(self) -> BOUNDARY_CONDITIONS: return self._boundary @property def location(self) -> float: """ Location of the reaction along the length of the beam The units of the length property is the same as the units of the beam length. The value of the location must be a positive value that is less than or equal to the length of the beam, or it will raise a ValueError. .. note:: The force and moment values are set to :obj:`None` any time the location is set. """ return self._location @location.setter def location(self, location: float) -> None: # The location is overloading the location property in Forces so that # the reaction can be invalidated when the location is changed if location < 0: # location cannot be a negative number raise ValueError("location must be positive!") self.invalidate() self._location = location @property def value(self) -> Tuple[Optional[float], Optional[float]]: """ Simple tuple of force and moment Returns: :obj:`tuple` (force, moment) """ return self.force, self.moment
[docs] def invalidate(self) -> None: """Invalidate the reaction values This will set the force and moment values to :obj:`None` To be used whenever the parameters change and the reaction values are no longer valid. """ self.force, self.moment = (None, None)
def __str__(self) -> str: return ( f"{self.__class__.__name__}\n" f" Location: {self.location}\n" f" Force: {self.force}\n" f" Moment: {self.moment}\n" ) def __repr__(self) -> str: return f"{self.__class__.__name__}(location={self.location})" def __eq__(self, other: object) -> bool: if not isinstance(other, self.__class__): return False if ( self.location == other.location and self.force == other.force and self.moment == other.moment ): return True return False
[docs]class PinnedReaction(Reaction): """ A PinnedReaction allows rotation displacements only A PinnedReaction represents a pinned, frictionless pivot that can resist motion both normal and axial directions to the beam. It will not resist moments. The deflection of a beam at the PinnedReaction is always zero, but the angle is free to change Parameters: location (:obj:`float`): the axial location of the reaction along the length of the beam Attributes: name (:obj:`str`): short name of the reaction (pinned). Used internally .. warning:: The **name** attribute is used internally. **Do not change this value!** """ name = "pinned" def __init__(self, location: float): super().__init__(location) # limit the vertical displacement but allow rotation self._boundary: BOUNDARY_CONDITIONS = (0, None)
[docs]class FixedReaction(Reaction): """ A FixedReaction does not allow any displacement or change in angle A FixedReaction resists both force and moments. The displacement and the angle are both constrained and must be zero at the reaction point. FixedReactions are typically applied at the ends of a Beam. Parameters: location (:obj:`float`): the axial location of the reaction along the length of the beam Attributes: name (:obj:`str`): short name of the reaction (fixed). Used internally .. warning:: The **name** attribute is used internally. **Do not change this value!** """ name = "fixed" def __init__(self, location: float): super().__init__(location) # do not allow vertical or rotational displacement self._boundary: BOUNDARY_CONDITIONS = (0, 0)