Source code for viiapackage.strengthening.l4.l4o

### ===================================================================================================================
###   L4-O 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.shapes import Wall
from rhdhv_fem.fem_math import fem_directive_distance_coordinates, fem_find_intersections, fem_distance_coordinates, \
    fem_smaller

# 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-O strengthening measures
### ===================================================================================================================

[docs]def viia_l4o( project: ViiaProject, variant: int, wall: Union[Wall, str], offset_bottom: float = 0.1, offset_top: float = 0.1, strip_profile: str = '20x1.4'): """ This function creates an L4-O-measure (Quakeshield) for a selected wall. It adds the vertical CFRP-strips. It will model the beam 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. From '1' to '4', for 1.0m, 0.75m, 0.5m and 1.25m respectively. - 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 wooden beam to the bottom edge of the wall in [m]. - offset_top (float): Not obligatory, default value is 0.1m. This is the offset of the wooden beam to the bottom edge of the wall in [m]. - strip_profile (str): Specifies the profile of the CFRP strips. Not obligatory, all measure variants on the GMC have a standard of '20x1.4'. The alternatives are '30x1.4' and '30x2.5'. Output: - The strengthening measure is added to class of columns and modelled in DIANA or SCIA. For example: >>> project.viia_l4o(wall, variant=1) This example will apply the L4O measure with 20mm x 1.4mm CFRP strips spaced 1m . >>> project.viia_l4o(wall, variant=4, strip_profile='30x2.5') This example will apply the L4O measure with 30mm x 2.5mm CFRP strips spaced 1.25m . """ # Check if measure is in GMC measure_type = 'L4-O' measure_sub_type = f"{measure_type}-{int(variant)}" viia_check_measure_in_gmc(project=project, measure_sub_type=measure_sub_type) # Argument handling wall = viia_check_shape_argument(project, wall, 'viia_l4o') if not isinstance(wall, Wall): raise ValueError( f"ERROR: Input for the function should be a Wall. The function received a {type(wall)} instead.") strips_lst = [] # 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 ctc = project.project_specific['strengthening_measures']['L4-O']['ctc'][str(variant)] 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 for strip profile if strip_profile not in ['20x1.4', '30x1.4', '30x2.5']: project.write_log("WARNING: Check the input for the strip dimension. " "The available options are '20x1.4', '30x1.4', '30x2.5'. " "The measure L4-O will not be added.") return strips_lst # Material, Geometry and axis of the shapes used for strengthening measure material_name = project.project_specific['strengthening_measures']['L4-O']['material'] material = project.viia_materials(material_name) geometry_name = 'L4O-CFRPSTRIP-' + strip_profile geometry = project.viia_geometries(geometry_name) # Level level = wall.name.split('-')[0] # Create the columns (strips) of the strengthening measure counter = 0 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: For walls with openings, the CFRP strips at the locations of the openings are " "only applied below the openings.") # 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 parts of the strip 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-O']['minimum length']: reinf = project.create_line_reinforcement( name=f"{level}-KOLOMMEN-L4O-{material_name}-{strip_profile}-{nr + 1}", contour=project.create_line([bottom_point, top_point]), material=material, geometry=geometry, data=project.viia_create_datas('L4O')) viia_add_strengthening_shape(shape=wall, strengthening_shape=reinf) strips_lst.append(reinf) 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-O measure applied on wall {wall.name}, number of applied vertical strips: {str(counter)}.") return strips_lst
### =================================================================================================================== ### 3. End of script ### ===================================================================================================================