Source code for femethods.mesh
"""
Mesh module that will define the mesh.
"""
from typing import List, Sequence, TYPE_CHECKING
if TYPE_CHECKING: # pragma: no cover
from femethods.reactions import Reaction # noqa: F401 (unused import)
from femethods.loads import Load # noqa: F401 (unused import)
[docs]class Mesh(object):
"""define a mesh that will handle degrees-of-freedom (dof), element lengths
etc.
the input degree-of-freedom (dof) parameter is the degrees-of-freedom for
a single element
"""
def __init__(
self,
length: float,
loads: List["Load"],
reactions: List["Reaction"],
dof: int,
):
self._nodes = self.__get_nodes(length, loads, reactions)
self._lengths = self.__get_lengths()
self._num_elements = len(self.lengths)
self._dof = dof * self.num_elements + dof
@property
def nodes(self) -> Sequence[float]:
return self._nodes
@property
def dof(self) -> int:
"""
Degrees of freedom of the entire beam
Returns:
:obj:`int`: Read-only. Number of degrees of freedom of the beam
"""
return self._dof
@property
def lengths(self) -> List[float]:
"""
List of lengths of mesh elements
Returns:
:obj:`list`: Read-only. List of lengths of local mesh elements
"""
return self._lengths
@property
def num_elements(self) -> int:
"""
Number of mesh elements
Returns:
:obj:`int`: Read-only. Number of elements in mesh
"""
return self._num_elements
def __get_lengths(self) -> List[float]:
# Calculate the lengths of each element
lengths: List[float] = []
for k in range(len(self.nodes) - 1):
lengths.append(self.nodes[k + 1] - self.nodes[k])
return lengths
@staticmethod
def __get_nodes(
length: float, loads: List["Load"], reactions: List["Reaction"]
) -> Sequence[float]:
nodes: List[float] = [0] # ensure first node is always at zero (0)
# Ignore the type checking for the for loop adding lists of loads and
# lists of reactions. There is no + operator defined for these, but it
# will combine the lists using the built in list addition. Which is the
# desired behavior
# noinspection PyTypeChecker,Mypy
for item in loads + reactions: # type: ignore
nodes.append(item.location)
nodes.append(length) # ensure last node is at the end of the beam
nodes = list(set(nodes)) # remove duplicates
nodes.sort()
return nodes
def __str__(self) -> str:
s = (
"MESH PARAMETERS\n"
f"Number of elements: {self.num_elements}\n"
f"Node locations: {self.nodes}\n"
f"Element Lengths: {self.lengths}\n"
f"Total degrees of freedom: {self.dof}\n"
)
return s