Source code for anastruct.fem.plotter.element

import math
from typing import TYPE_CHECKING, Tuple

import numpy as np

if TYPE_CHECKING:
    from anastruct.fem.elements import Element


[docs] def plot_values_deflection( element: "Element", factor: float, linear: bool = False ) -> Tuple[np.ndarray, np.ndarray]: """Determines the plotting values for deflection Args: element (Element): Element to plot factor (float): Factor by which to multiply the plotting values perpendicular to the elements axis. linear (bool, optional): If True, the bending in between the elements is determined. Defaults to False. Returns: Tuple[np.ndarray, np.ndarray]: x and y values """ ux1 = element.node_1.ux * factor uy1 = -element.node_1.uy * factor ux2 = element.node_2.ux * factor uy2 = -element.node_2.uy * factor x1 = element.vertex_1.x + ux1 y1 = element.vertex_1.y + uy1 x2 = element.vertex_2.x + ux2 y2 = element.vertex_2.y + uy2 if element.type == "general" and not linear: assert element.deflection is not None n = len(element.deflection) x_val = np.linspace(x1, x2, n) y_val = np.linspace(y1, y2, n) x_val = x_val + element.deflection * math.sin(element.angle) * factor y_val = y_val + element.deflection * -math.cos(element.angle) * factor else: # truss element has no bending x_val = np.array([x1, x2]) y_val = np.array([y1, y2]) return x_val, y_val
[docs] def plot_values_bending_moment( element: "Element", factor: float, n: int ) -> Tuple[np.ndarray, np.ndarray]: """Determines the plotting values for bending moment Args: element (Element): Element to plot factor (float): Factor by which to multiply the plotting values perpendicular to the elements axis. n (int): Number of points to plot Returns: Tuple[np.ndarray, np.ndarray]: x and y values """ # Determine forces for horizontal element.angle = 0 T_left = element.node_1.Tz T_right = -element.node_2.Tz sin = math.sin(-element.angle) cos = math.cos(-element.angle) # apply angle ai x1 = element.vertex_1.x + T_left * sin * factor y1 = element.vertex_1.y + T_left * cos * factor x2 = element.vertex_2.x + T_right * sin * factor y2 = element.vertex_2.y + T_right * cos * factor interpolate = np.linspace(0, 1, n) dx = x2 - x1 dy = y2 - y1 # determine moment for 0 < x < length of the element x_val = x1 + interpolate * dx y_val = y1 + interpolate * dy if element.q_load or element.dead_load: qi = element.all_qp_load[0] q = element.all_qp_load[1] x = interpolate * element.l q_part = ( -((qi - q) / (6 * element.l)) * x**3 + (qi / 2) * x**2 - (((2 * qi) + q) / 6) * element.l * x ) x_val += sin * q_part * factor y_val += cos * q_part * factor x_val = np.append(x_val, element.vertex_2.x) y_val = np.append(y_val, element.vertex_2.y) x_val = np.insert(x_val, 0, element.vertex_1.x) y_val = np.insert(y_val, 0, element.vertex_1.y) return x_val, y_val
[docs] def plot_values_axial_force( element: "Element", factor: float, n: int ) -> Tuple[np.ndarray, np.ndarray]: """Determines the plotting values for axial force Args: element (Element): Element to plot factor (float): Factor by which to multiply the plotting values perpendicular to the elements axis. n (int): Number of points to plot Returns: Tuple[np.ndarray, np.ndarray]: x and y values """ # Determine forces for horizontal element.angle = 0 assert element.N_1 is not None assert element.N_2 is not None N1 = element.N_1 N2 = element.N_2 cos = math.cos(0.5 * math.pi + element.angle) sin = math.sin(0.5 * math.pi + element.angle) # apply angle ai x1 = element.vertex_1.x + N1 * cos * factor y1 = element.vertex_1.y + N1 * sin * factor x2 = element.vertex_2.x + N2 * cos * factor y2 = element.vertex_2.y + N2 * sin * factor interpolate = np.linspace(0, 1, n) dx = x2 - x1 dy = y2 - y1 # determine axial force for 0 < x < length of the element x_val = x1 + interpolate * dx y_val = y1 + interpolate * dy if element.q_load or element.dead_load: qni = element.all_qn_load[0] qn = element.all_qn_load[1] x = interpolate * element.l qn_part = (qn - qni) / (2 * element.l) * (element.l - x) * x x_val += cos * qn_part * factor y_val += sin * qn_part * factor x_val = np.append(x_val, element.vertex_2.x) y_val = np.append(y_val, element.vertex_2.y) x_val = np.insert(x_val, 0, element.vertex_1.x) y_val = np.insert(y_val, 0, element.vertex_1.y) return x_val, y_val
[docs] def plot_values_shear_force( element: "Element", factor: float ) -> Tuple[np.ndarray, np.ndarray]: """Determines the plotting values for shear force Args: element (Element): Element to plot factor (float): Factor by which to multiply the plotting values perpendicular to the elements axis. Returns: Tuple[np.ndarray, np.ndarray]: x and y values """ x1 = element.vertex_1.x y1 = element.vertex_1.y x2 = element.vertex_2.x y2 = element.vertex_2.y assert element.shear_force is not None n = len(element.shear_force) # apply angle ai interpolate = np.linspace(0, 1, n) dx = x2 - x1 dy = y2 - y1 x_val = x1 + interpolate * dx y_val = y1 + interpolate * dy sin = math.sin(-element.angle) cos = math.cos(-element.angle) x_val += sin * element.shear_force * factor y_val += cos * element.shear_force * factor x_val = np.append(x_val, element.vertex_2.x) y_val = np.append(y_val, element.vertex_2.y) x_val = np.insert(x_val, 0, element.vertex_1.x) y_val = np.insert(y_val, 0, element.vertex_1.y) return x_val, y_val
[docs] def plot_values_element(element: "Element") -> Tuple[np.ndarray, np.ndarray]: """Determines the plotting values for the element itself (e.g. for plot_structure()) Args: element (Element): Element to plot Returns: Tuple[np.ndarray, np.ndarray]: x and y values """ x_val = np.array([element.vertex_1.x, element.vertex_2.x]) y_val = np.array([element.vertex_1.y, element.vertex_2.y]) return x_val, y_val