bluemira.structural.model ========================= .. py:module:: bluemira.structural.model .. autoapi-nested-parse:: Finite element model Classes ------- .. autoapisummary:: bluemira.structural.model.BoundaryConditionMethod bluemira.structural.model.FiniteElementModel Functions --------- .. autoapisummary:: bluemira.structural.model.check_matrix_condition Module Contents --------------- .. py:class:: BoundaryConditionMethod(*args, **kwds) Bases: :py:obj:`enum.Enum` .. autoapi-inheritance-diagram:: bluemira.structural.model.BoundaryConditionMethod :parts: 1 :private-bases: Enumeration of Boundary Condition Methods. .. py:attribute:: PRZEMIENIECKI .. py:attribute:: DELETION .. py:method:: _missing_(value: str | BoundaryConditionMethod) -> BoundaryConditionMethod :classmethod: .. py:function:: check_matrix_condition(matrix: numpy.ndarray, digits: int) Checks the condition number of a matrix and warns if it is unsuitable for working with. :param matrix: The matrix to check the condition number of :param digits: The desired level of digit-precision (higher is less demanding) :raises StructuralError: If the stiffness matrix is singular or ill-conditioned .. py:class:: FiniteElementModel 3-D beam finite element model. The main interface object with other modules As such, all important functionality is brought to the surface here, hence the large number of class methods .. attribute:: geometry The geometry in the FiniteElementModel .. attribute:: load_case The load case applied in the FiniteElementModel .. attribute:: n_fixed_dofs The number of fixed degrees of freedom .. attribute:: fixed_dofs The fixed degrees of freedom .. attribute:: fixed_dof_ids The id_numbers of the fixed degrees of freedom .. py:attribute:: N_INTERP :value: 7 .. py:attribute:: cycle_sym_ids :value: [] .. py:attribute:: cycle_sym :value: None .. py:method:: set_geometry(geometry: bluemira.structural.geometry.Geometry) Set a Geometry in the FiniteElementModel :param geometry: The Geometry to add to the FiniteElementModel .. py:method:: add_node(x: float, y: float, z: float) -> int Adds a Node to the FiniteElementModel :param x: The node global x coordinate :param y: The node global y coordinate :param z: The node global z coordinate :rtype: The ID number of the node that was added .. py:method:: add_element(node_id1: int, node_id2: int, cross_section: bluemira.structural.crosssection.CrossSection, material: matproplib.material.Material | None = None, op_cond: matproplib.conditions.OperationalConditions | None = None) -> int Adds an Element to the FiniteElementModel :param node_id1: The ID number of the first node :param node_id2: The ID number of the second node :param cross_section: The CrossSection property object of the element :param material: The Material property object of the element :rtype: The ID number of the element that was added .. py:method:: add_coordinates(coords: bluemira.geometry.coordinates.Coordinates, cross_section: bluemira.structural.crosssection.CrossSection, material: matproplib.material.Material | None = None, op_cond: matproplib.conditions.OperationalConditions | None = None) Adds a Coordinates object to the FiniteElementModel :param coords: The coordinates to transform into connected Nodes and Elements :param cross_section: The cross section of all the Elements in the Coordinates :param material: The material of all the Elements in the Coordinates .. py:method:: add_support(node_id: int, *, dx: bool = False, dy: bool = False, dz: bool = False, rx: bool = False, ry: bool = False, rz: bool = False) Applies a support condition at a Node in the FiniteElementModel :param node_id: The id_number of the Node where to apply the condition :param dx: Whether or not the linear DOFs at the Node are constrained :param dy: Whether or not the linear DOFs at the Node are constrained :param dz: Whether or not the linear DOFs at the Node are constrained :param rx: Whether or not the rotational DOFs at the Node :param ry: Whether or not the rotational DOFs at the Node :param rz: Whether or not the rotational DOFs at the Node .. py:method:: find_supports() Find the support conditions in the FiniteElementModel. .. py:method:: apply_cyclic_symmetry(left_node_ids: list[int], right_node_ids: list[int], p1: numpy.typing.NDArray[numpy.float64] | None = None, p2: numpy.typing.NDArray[numpy.float64] | None = None) Applies a cyclic symmetry condition to the FiniteElementModel :param left_node_ids: The id numbers of the nodes on the left boundary :param right_node_ids: The id numbers of the nodes on the right boundary :param p1: The first point of the symmetry rotation axis :param p1: The second point of the symmetry rotation axis .. py:method:: apply_load_case(load_case: bluemira.structural.loads.LoadCase) Apply a load case to the FiniteElementModel. :param load_case: The load case to apply to the model. .. py:method:: add_node_load(node_id: int, load: float, load_type: str) Adds a node load to the FiniteElementModel :param node_id: The id_number of the Node to apply the load at :param load: The value of the load :param load_type: The type and axis of the load (from ['Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz']) .. py:method:: add_element_load(element_id: int, load: float, x: float, load_type: str) Adds an element point load to the FiniteElementModel :param element_id: The id_number of the Element to apply the load at :param load: The value of the load :param x: The parameterised and normalised distance along the element x-axis :param load_type: The type and axis of the load (from ['Fx', 'Fy', 'Fz', 'Mx', 'My', 'Mz']) .. py:method:: add_distributed_load(element_id: int, w: float, load_type: str) Adds a distributed load to the FiniteElementModel :param element_id: The id_number of the Element to apply the load at :param w: The value of the distributed load :param load_type: The type and axis of the load (from ['Fx', 'Fy', 'Fz']) .. py:method:: add_gravity_loads() Applies self-weight distributed loads to all members .. py:method:: clear_loads() Clears any applied loads to the model, and removes any displacements .. py:method:: clear_load_case() Clears the LoadCase applied to the model .. py:method:: _apply_load_case(load_case: bluemira.structural.loads.LoadCase) Applies a LoadCase to the FiniteElementModel. Maps individual loads to their respective Nodes and Elements. :param load_case: The list of loads to apply to the model :type load_case: LoadCase object .. py:method:: _get_nodal_forces() -> numpy.ndarray Calculates the total nodal forces (including forces applied at nodes and equivalent concentrated forces from element loads). :rtype: The global nodal force vector (6*n_nodes) .. py:method:: _get_reaction_forces() -> numpy.ndarray Calculates the reaction forces, applying them to each of the nodes and returning the full vector :rtype: The full reaction vector in global coordinates over all the nodes (6*n_nodes) .. py:method:: _math_checks(k_matrix: numpy.ndarray) Performs a series of checks on the model boundary conditions and the global stiffness matrix K, prior to the solution of the system of equations. :param k_matrix: The global stiffness matrix to be checked ((6*n_nodes, 6*n_nodes)) :raises StructuralError: DOFs less than 6 or never constrianed .. py:method:: _displacement_check(deflections: numpy.ndarray) Checks to see if the displacements are not too big relative to the size of the model. :param deflections: The vector of absolute displacements (6*n_nodes) .. py:method:: _apply_boundary_conditions(k: numpy.ndarray, p: numpy.ndarray, method: str = 'Przemieniecki') -> tuple[numpy.ndarray, numpy.ndarray] Applies the boundary conditions to the matrices to make the problem solvable. This is creation of the "reduced" stiffness matrix and force vector, Kr and Pr. :param k: The global stiffness matrix of the problem :param p: The global nodal force vector of the problem :returns: * *kr* -- The reduced global stiffness matrix of the problem * *pr* -- The reduced global nodal force vector of the problem .. py:method:: _apply_boundary_conditions_sparse(k, p) .. py:method:: _apply_displacements(u_r) Applies the displacements to the individual nodes in the Geometry .. py:method:: plot(ax=None, **kwargs) Plots the model geometry, boundary conditions, and loads .. py:method:: solve(load_case: bluemira.structural.loads.LoadCase | None = None, *, sparse: bool = False) -> bluemira.structural.result.Result Solves the system of linear equations for deflection and applies the deflections to the nodes and elements of the geometry :param load_case: Will default to the loads applied to the elements and nodes in the geometry :param sparse: Whether or not to use sparse matrices to solve :rtype: The result of the FE analysis with the applied LoadCase