Source code for viiapackage.strengthening.l4.l4f

### ===================================================================================================================
###   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 ### ===================================================================================================================