### ===================================================================================================================
### L4-F strengthening measure
### ===================================================================================================================
# Copyright ©VIIA 2024
### ===================================================================================================================
### 1. Import modules
### ===================================================================================================================
# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, Union
from copy import deepcopy
# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.fem_math import fem_directive_distance_coordinates, fem_find_intersections, fem_distance_coordinates,\
fem_smaller
from rhdhv_fem.shapes import Wall
# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
from viiapackage.viiaStatus import ViiaProject
from viiapackage.shape_operations import viia_get_wall_horizontal_direction
from viiapackage.strengthening.helper_functions import viia_check_shape_argument, viia_add_strengthening_shape, \
viia_check_measure_in_gmc
### ===================================================================================================================
### 2. Function to create L4-F strengthening measures
### ===================================================================================================================
[docs]def viia_l4f(
project: ViiaProject, variant: int, wall: Union[Wall, str], offset_bottom: float = 0.1,
offset_top: float = 0.1, flip: bool = False):
"""
This function creates an L4-F-measure for a selected wall. It adds vertical wooden beams (including eccentricity)
It will model the column if it is of certain length and not in openings. The wall should be vertical, but angled in
horizontal plane is okay. Also the top and bottom do not have to be straight.
Input:
- project (obj): VIIA project object containing collections of fem objects and project variables.
- variant (int): The variant number of the measure that is in the GMC.
- wall (obj): The object reference of the wall that has to be strengthened.
Alternative (str): Name of the wall to be strengthened.
- offset_bottom (float): Not obligatory, default value is 0.1m. This is the offset of the steel beam to the
bottom edge of the wall opening in [m].
- offset_top (float): Not obligatory, default value is 0.1m. This is the offset of the steel beam to the top
edge of the wall opening in [m].
- flip (bool): Default value is False, indicating that the columns created have an eccentricity applied in the
direction of the local z-axis of the wall. If set to True, the eccentricity will be applied in the opposite
direction.
Output:
- The strengthening measure is added to class of columns and modelled in DIANA or SCIA.
"""
# Check if measure is in GMC
measure_type = 'L4-F'
measure_sub_type = f"{measure_type}-{int(variant)}"
viia_check_measure_in_gmc(project=project, measure_sub_type=measure_sub_type)
# Warning
project.write_log("WARNING: Eccentricities are currently not applied.")
# Argument handling
wall = viia_check_shape_argument(project, wall, 'viia_l4f')
if not isinstance(wall, Wall):
raise ValueError(
f"ERROR: Input for the function should be a Wall. The function received a {type(wall)} instead.")
# Compute the vector pointing outwards of the wall (outward of the complete building)
# This is needed for computing the eccentricities
outward_direction_vector = wall.normal_vector()
# Calculate the length of the wall
point_copy = deepcopy(wall.contour.get_points())
# Sort reference point (always the lowest x and y)
ref_point = wall.contour.get_points()[0]
y_axis = wall.y_axis_direction().vector
distances = []
bool_vec = False
points = deepcopy(wall.contour.get_points())
for point in points:
delta_z = ref_point[2] - point[2]
point[0] = point[0] + y_axis[0] * delta_z / y_axis[2]
point[1] = point[1] + y_axis[1] * delta_z / y_axis[2]
point[2] = ref_point[2]
distances.append(fem_directive_distance_coordinates(
coordinates1=ref_point, coordinates2=point, direction=viia_get_wall_horizontal_direction(wall=wall).vector))
wall_length = max(distances) - min(distances)
# Check the moving vector
move_vec = []
if any(i < 0 for i in distances):
move_vec = [-i for i in viia_get_wall_horizontal_direction(wall=wall).vector]
bool_vec = True
# Distribute beams of measure L4-F
ctc = project.project_specific['strengthening_measures']['L4-F']['center-to-center']
nr_columns = int(wall_length / ctc) + 1
rest_wall_length = (wall_length - nr_columns * ctc) / 2
if fem_smaller(rest_wall_length, project.elementsize / 2):
nr_columns -= 1
# Determine the centre point of the projected line of the wall
center_point_x = \
(ref_point[0] + min(distances) * viia_get_wall_horizontal_direction(wall=wall).vector[0] +
ref_point[0] + max(distances) * viia_get_wall_horizontal_direction(wall=wall).vector[0]) / 2
center_point_y = \
(ref_point[1] + min(distances) * viia_get_wall_horizontal_direction(wall=wall).vector[1] +
ref_point[1] + max(distances) * viia_get_wall_horizontal_direction(wall=wall).vector[1]) / 2
# Starting x- and y-coordinate of the first beam of the wall
point_x = \
center_point_x - ((nr_columns - 1) / 2 * ctc / wall_length) * \
(ref_point[0] + min(distances) * viia_get_wall_horizontal_direction(wall=wall).vector[0] - \
ref_point[0] + max(distances) * viia_get_wall_horizontal_direction(wall=wall).vector[0])
point_y = \
center_point_y - ((nr_columns - 1) / 2 * ctc / wall_length) * \
(ref_point[1] + min(distances) * viia_get_wall_horizontal_direction(wall=wall).vector[1] - \
ref_point[1] + max(distances) * viia_get_wall_horizontal_direction(wall=wall).vector[1])
# Check if point_x and point_y are in the same direction with element axis
# Material of the shapes used for strengthening measure
material_name = project.project_specific['strengthening_measures']['L4-F']['material']
material = project.viia_materials(material_name)
# Geometry of the shapes used for strengthening measure
geometry_name = 'KOLOM-' + project.project_specific['strengthening_measures']['L4-F']['column-profile']
geometry = project.viia_geometries(geometry_name)
geometry.name = 'KOLOM-L4F-' + project.project_specific['strengthening_measures']['L4-F']['column-profile']
# Calculate the eccentricity
eccentricity = (wall.geometry.geometry_model.thickness + geometry.geometry_model.height) / 2
if flip:
eccentricity = -1 * eccentricity
# Data properties for the shapes
data = project.viia_create_datas('THINTE3')
# Level
level = wall.name.split('-')[0]
# Create the columns of the strengthening measure
counter = 0
columns_lst = []
for nr in range(nr_columns):
# Calculate the intersections of the line with the contour
intersections = fem_find_intersections(
point=[point_x, point_y, ref_point[2]], direction=y_axis, surface=point_copy)
# Sort for z-coordinate
intersection_dic = {}
intersection_z = []
for i in range(len(intersections)):
intersection_dic[intersections[i][2]] = intersections[i]
intersection_z.append(intersections[i][2])
# Warning for if openings are present
if wall.openings:
project.write_log(
"WARNING: To strengthen the wall with openings, the L4-G measure should be applied. Timber columns are "
"added below the opening now, however please add the necessary elements for L4-G. This functionality is"
" currently unavailable.")
# Calculate the intersection of the line with openings
if wall.openings:
for opening in wall.openings:
opening_points_copy = deepcopy(opening.get_points())
intersection_openings = fem_find_intersections([point_x, point_y, ref_point[2]], y_axis,
opening_points_copy)
if intersection_openings:
# Sort for z-coordinate
for i in range(len(intersection_openings)):
intersection_dic[intersection_openings[i][2]] = intersection_openings[i]
intersection_z.append(intersection_openings[i][2])
intersection_z.sort()
# Calculate all column (parts)
for i in range(0, len(intersection_z), 2):
if not intersection_z[i] == intersection_z[i + 1]:
bottom_point = intersection_dic[intersection_z[i]]
top_point = intersection_dic[intersection_z[i + 1]]
# Adjust for the bottom and top offset
for j in range(3):
bottom_point[j] += abs(y_axis[j]) * offset_bottom
top_point[j] -= abs(y_axis[j]) * offset_top
# Check for minimum length
length = fem_distance_coordinates(bottom_point, top_point)
if length >= \
project.project_specific['strengthening_measures']['L4-F']['minimum length of column']:
line = project.create_line([bottom_point, top_point])
created_column = project.create_column(
name=f"{level}-KOLOMMEN-L4F-WAND-{wall.name.split('-')[-1]}-{material_name}-"
f"{geometry_name}-{nr + 1}",
contour=line,
material=material,
geometry=geometry,
data=data)
created_column.element_z_axis = project.create_direction(outward_direction_vector)
created_column.add_geometry_eccentricity(y=eccentricity)
viia_add_strengthening_shape(shape=wall, strengthening_shape=created_column)
columns_lst.append(created_column)
counter += 1
if bool_vec:
point_x += ctc * move_vec[0]
point_y += ctc * move_vec[1]
else:
point_x += ctc * viia_get_wall_horizontal_direction(wall=wall).vector[0]
point_y += ctc * viia_get_wall_horizontal_direction(wall=wall).vector[1]
# Update wall attribute with strengthening measure
if counter > 1:
wall.add_meta_data({'strengthening': measure_sub_type})
# Notifications for user
project.write_log(f"L4-F measure applied on wall ({wall.name}) number of applied vertical columns: {counter-1}.")
return columns_lst
### ===================================================================================================================
### 3. End of script
### ===================================================================================================================