### ===================================================================================================================
### Create boundary spring for line-shapes in static analyses
### ===================================================================================================================
# Copyright ©VIIA 2024
### ===================================================================================================================
### 1. Import modules
### ===================================================================================================================
# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, List, Union
# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.fem_math import fem_flip_vector, fem_local_axes_system, fem_vector_in_plane
from rhdhv_fem.shapes import Column, Beam, Lines, Surfaces
from rhdhv_fem.connections import BoundarySpring
from rhdhv_fem.fem_tools import fem_find_object
# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
from viiapackage.viiaStatus import ViiaProject
### ===================================================================================================================
### 2. Function to create the boundary spring for static analysis
### ===================================================================================================================
[docs]def viia_create_all_boundary_springs_for_static_analysis(
project: ViiaProject, spring_stiffness: float = 20, exclude_shapes: List[Lines] = None) -> List[BoundarySpring]:
"""
Creates boundary springs at the ends of Beams and Columns. These supports are needed to prevent rotation around the
longitudinal axis of those shapes during static calculation. Note the data model TORSTI only works during transient
analyses in DIANA.
Input:
- project (obj): VIIA project object containing collections of fem objects and project variables.
- spring_stiffness (float): Rotational stiffness, in [Nm/rad] for the boundary springs. Default value 20 Nm/rad.
- exclude_shapes (list of obj): List of object references for line-shapes (beams and columns) to be excluded
from the boundary spring application.
Output:
- List of all the created boundary springs.
"""
# Collect the list of shapes to apply boundary springs on, remove ant excluded shapes
if exclude_shapes is not None:
if not isinstance(exclude_shapes, list):
exclude_shapes = [exclude_shapes]
else:
exclude_shapes = []
shapes = [shape for shape in project.collections.beams + project.collections.columns if shape not in exclude_shapes]
return viia_create_boundary_springs_for_static_analysis(
project=project, shapes=shapes, spring_stiffness=spring_stiffness)
[docs]def viia_create_boundary_springs_for_static_analysis(
project: ViiaProject, shapes: List[Union[Beam, Column]], spring_stiffness: float = 20) \
-> List[BoundarySpring]:
"""
Creates boundary springs at the ends of the given shapes (columns and beams). These supports are needed to prevent
rotation around the longitudinal axis of those shapes during static calculation. Note the data model TORSTI only
works during transient analyses in DIANA.
Input:
- project (obj): VIIA project object containing collections of fem objects and project variables.
- shapes (list of objects): Shapes for which the boundary springs should be made.
- spring_stiffness (float): Stiffness [Nm/rad] for the boundary springs.
Output:
- Returns list of all the created boundary springs.
"""
def _check_nodes(_shape, _node):
conn_shapes = [
connecting_shape for connecting_shape in _node.get_shapes() if isinstance(connecting_shape, Surfaces)]
return conn_shapes and not any([fem_vector_in_plane(
vector=_shape.contour.get_direction().vector, plane=conn_shape.contour.get_points(),
precision=_shape.project.check_precision) for conn_shape in conn_shapes])
# Create material for rotational spring
material = project.viia_materials(f'LIN-ROTVEER-{spring_stiffness}')
# Mapping dictionary for direction and geometry objects
direction_vs_local_axes = {}
# Loop through all shapes with the applicable data
created_boundary_springs = []
for shape in shapes:
# Only beams and columns have to be checked
if isinstance(shape, (Beam, Column)):
# Check the start-node
apply_on_node_start = _check_nodes(shape, shape.contour.node_start)
apply_on_node_end = _check_nodes(shape, shape.contour.node_end)
# Check if beam does not require springs
if not (apply_on_node_start or apply_on_node_end):
continue
# Get direction of the beam and make it to positive with respect to x-direction
direction_vector = shape.contour.get_direction().vector
if direction_vector[0] < 0 or (direction_vector[0] == 0 and direction_vector[2] < 0):
direction_vector = fem_flip_vector(direction_vector)
direction = project.create_direction(direction_vector)
if direction in direction_vs_local_axes:
axes = direction_vs_local_axes[direction]
else:
axes = fem_local_axes_system(x_axis=direction.vector)
axes = [direction, project.create_direction(axes[1]), project.create_direction(axes[2])]
direction_vs_local_axes[direction] = axes
# Create geometry if not already made
geometry = project.viia_geometries('ROTVEER')
# Get current max if
max_id = project.find_max_id(collection=project.collections.boundary_springs)
# Create supports
if apply_on_node_end:
created_boundary_springs.append(
project.create_boundary_spring(
name=f'{shape.layer.name}-StaticRotSupport-{max_id + 1}',
connecting_shapes={
'source_connecting_shape': shape, 'source_shape_geometry': shape.contour.node_end},
material=material, geometry=geometry, axes=axes))
max_id += 1
if apply_on_node_start:
created_boundary_springs.append(
project.create_boundary_spring(
name=f'{shape.layer.name}-StaticRotSupport-{max_id + 1}',
connecting_shapes={
'source_connecting_shape': shape, 'source_shape_geometry': shape.contour.node_start},
material=material, geometry=geometry, axes=axes))
# Add to group for static rotational supports
group = fem_find_object(reference='StaticRotSupportGroup', collection=project.collections.groups)
if group:
group.connections += created_boundary_springs
else:
project.create_group(name='StaticRotSupportGroup', connections=created_boundary_springs)
# Return the created boundary springs
return created_boundary_springs
### ===================================================================================================================
### 3. End of script
### ===================================================================================================================