Source code for viiapackage.strengthening.l4.l4i

### ===================================================================================================================
###   L4-I strengthening measure
### ===================================================================================================================
# Copyright ©VIIA 2024

### ===================================================================================================================
###   1. Import modules
### ===================================================================================================================

# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, Union
import math

# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.shapes import Wall
from rhdhv_fem.fem_math import fem_unit_vector, fem_greater, fem_smaller

# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
    from viiapackage.viiaStatus import ViiaProject
from viiapackage.strengthening.helper_functions import viia_check_shape_argument, viia_find_min_max_z, \
    viia_add_strengthening_shape, viia_check_measure_in_gmc


### ===================================================================================================================
###   2. Function to create L4-I strengthening measures
### ===================================================================================================================

[docs]def viia_l4i(project: ViiaProject, variant: int, wall: Union[Wall, str], explicit: bool = False): """ This function creates an L4-I-measure for a selected wall. It replaces a masonry wall with a timber frame wall (HSB). It will model the wall the same as the existing wall and thus 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. .. warning:: Function is currently not available, it requires updates, please send request to the VIIA automating team. 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. - explicit (bool): Not obligatory, default value is 'False'. In that case an equivalent wall is modelled. If 'True', the vertical wooden beams and multiplex sheets are modelled explicitly Output: - The strengthening measure is executed and the new wall is modelled in DIANA or SCIA. For example: >>> project.viia_l4i(wall) This example will apply the L4-I measure, which replaces masonry wall Wall5 with an equivalent timber frame wall. """ raise NotImplementedError("Function to apply L4-I measure is currently not available, script and UPR needs updates.") # Check if measure is in GMC measure_type = 'L4-I' 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_l4i') # Check if wall is masonry, otherwise return if "MW" not in wall_name: project.write_log( f"ERROR: This wall is not a masonry wall, L4-I measure can only be applied on masonry, " f"please check input wall {wall.name}.") return # Compute height of vertical wooden beams heightBeam = round(wall.geometry.thickness - 2 * project.project_specific['strengthening_measures']['L4-I']['thickness'] / 1000, 5) # Compute normalVector of wall, which can point either inward or outward normalVector = wall.normal_vector() # Compute normalVector that points outward, both are used to compute the eccentricities normalVectorOutward = wall.outward_vector() if explicit: # Find the length of the wall wallxmin = wall.points[0][0][0]; wallxmax = wall.points[0][0][0] wallymin = wall.points[0][0][1]; wallymax = wall.points[0][0][1] for i in range(1, len(wall.points[0])): if fem_greater(wallxmin, wall.points[0][i][0]): wallxmin = wall.points[0][i][0] if fem_greater(wall.points[0][i][0], wallxmax): wallxmax = wall.points[0][i][0] if fem_greater(wallymin, wall.points[0][i][1]): wallymin = wall.points[0][i][1] if fem_greater(wall.points[0][i][1], wallymax): wallymax = wall.points[0][i][1] wallDeltaX = wallxmax - wallxmin; wallDeltaY = wallymax - wallymin wallLength = math.sqrt(wallDeltaX * wallDeltaX + wallDeltaY * wallDeltaY) # Distribute beams of measure L4-I nrColumns = int(wallLength / project.project_specific['strengthening_measures']['L4-I']['ctc']) + 1 restWallLength = (wallLength - nrColumns * project.project_specific['strengthening_measures']['L4-I']['ctc']) / 2 if fem_smaller(restWallLength, project.ElementSize / 2): nrColumns -= 1 # Determine the centre point of the projected line of the wall centerPointX = wallxmin + wallDeltaX / 2 centerPointY = wallymin + wallDeltaY / 2 # Starting x- and y-coordinate of the first beam of the wall pointX = centerPointX - ((nrColumns - 1) / 2 * project.project_specific['strengthening_measures']['L4-I']['ctc'] / wallLength) * wallDeltaX pointY = centerPointY - ((nrColumns - 1) / 2 * project.project_specific['strengthening_measures']['L4-I']['ctc'] / wallLength) * wallDeltaY # Check for openings openings = [] if len(wall.points) > 1: for i in range(1, len(wall.points)): xmin = wall.points[i][0][0]; xmax = wall.points[i][0][0] ymin = wall.points[i][0][1]; ymax = wall.points[i][0][1] for j in range(1, len(wall.points[i])): if fem_greater(xmin, wall.points[i][j][0]): xmin = wall.points[i][j][0] if fem_greater(wall.points[i][j][0], xmax): xmax = wall.points[i][j][0] if fem_greater(ymin, wall.points[i][j][1]): ymin = wall.points[i][j][1] if fem_greater(wall.points[i][j][1], ymax): ymax = wall.points[i][j][1] deltaX = xmin - wallxmin; deltaY = ymin - wallymin r1 = math.sqrt(deltaX * deltaX + deltaY * deltaY) deltaX = xmax - wallxmin; deltaY = ymax - wallymin r2 = math.sqrt(deltaX * deltaX + deltaY * deltaY) openings.append([r1, r2]) # Name, material and geometry to be used for strengthening measure # The eccentricity is set in direction of normalvector of wall. It may be necessary to adjust this to the # negative direction depending on the location where the measure will be fitted. # Eccentricity is half the thickness of the wall and half of the column materialName = 'LIN-HOUT' localZAxis = '(' + str(round(wallDeltaX / wallLength, 3)) + ', ' + str( round(wallDeltaY / wallLength, 3)) + ', 0.0)' geometryName = \ 'KOLOM-' + str(int(heightBeam * 1000)) + 'x' + \ str(int(project.project_specific['strengthening_measures']['L4-I']['beam width'])) + '-' + localZAxis # Find starting number for column numbers maxColumnNr = 0 for column in project.collections.columns: columnNr = int(column.name.split('-')[-1]) if columnNr > maxColumnNr: maxColumnNr = columnNr # Create the object for the columns. Check for bottom and top, check for openings en check for length. counter = 1 for i in range(nrColumns): level = wall.name.split('-')[0] intersections = sorted(viia_find_min_max_z(wall.points[0], [pointX, pointY, 0])) if len(openings) > 0: for j in range(len(openings)): deltaX = pointX - wallxmin; deltaY = pointY - wallymin r = math.sqrt(deltaX * deltaX + deltaY * deltaY) if fem_smaller(openings[j][0], r) and fem_smaller(r, openings[j][1]): intOpening = viia_find_min_max_z(wall.points[j + 1], [pointX, pointY, 0]) intersections.append(intOpening[0]) intersections.append(intOpening[1]) intersections = sorted(intersections) for j in range(int(len(intersections) / 2)): bottomLevel = intersections[2 * j] topLevel = intersections[1 + 2 * j] nr = maxColumnNr + counter name = level + '-KOLOMMEN-L4I-' + materialName + '-' + str(int(heightBeam * 1000)) + 'x' + \ str(int(project.project_specific['strengthening_measures']['L4-I']['beam width'])) + '-' + str(nr) bottomPoint = [pointX, pointY, bottomLevel] topPoint = [pointX, pointY, topLevel] # if (topLevel - bottomLevel) > # project.project_specific['strengthening_measures']['L4-I']['minimum length']: column = Column(name, project.create_line([bottomPoint, topPoint]), materialName, geometryName) counter += 1 viia_add_strengthening_shape(shape=wall, strengthening_shape=column) pointX = pointX + project.project_specific['strengthening_measures']['L4-I']['ctc'] / wallLength * wallDeltaX pointY = pointY + project.project_specific['strengthening_measures']['L4-I']['ctc'] / wallLength * wallDeltaY # Create two thin walls of multiplex NewWallNameIn = wall.name.split('-')[0] + "-WANDEN-L4I-IN-LIN-HSB-" + \ str(int(project.project_specific['strengthening_measures']['L4-I']['thickness'])) + \ "-" + wall.name[-1] NewWallNameOut = wall.name.split('-')[0] + "-WANDEN-L4I-OUT-LIN-HSB-" + \ str(int(project.project_specific['strengthening_measures']['L4-I']['thickness'])) + \ "-" + wall.name[-1] NewMaterialName = "LIN-HOUT-PLAAT" # If normalVector points outward, EccentricityIn must have a negative Z-component if normalVectorOutward == normalVector: EccentricityIn =\ "-(0,0,-" + str(round(geometry.thickness / 2 - project.project_specific['strengthening_measures']['L4-I']['thickness'] / 2000, 3)) + ")" EccentricityOut =\ "-(0,0," + str(round(geometry.thickness / 2 - project.project_specific['strengthening_measures']['L4-I']['thickness'] / 2000, 3)) + ")" # If normalVector points inward, EccentricityIn must have a positive Z-component elif normalVectorOutward == fem_unit_vector([-normalVector[0], -normalVector[1], -normalVector[2]]): EccentricityIn =\ "-(0,0," + str(round(geometry.thickness / 2 - project.project_specific['strengthening_measures']['L4-I']['thickness'] / 2000, 3)) + ")" EccentricityOut =\ "-(0,0,-" + str(round(geometry.thickness / 2 - project.project_specific['strengthening_measures']['L4-I']['thickness'] / 2000, 3)) + ")" NewGeometryNameIn =\ "WAND-" + str(int(project.project_specific['strengthening_measures']['L4-I']['thickness'])) + \ "-(" + str(geometry.localAxis[0]) + "," + str(geometry.localAxis[1]) + ',' + str(geometry.localAxis[2]) + \ ')' + EccentricityIn NewGeometryNameOut =\ "WAND-" + str(int(project.project_specific['strengthening_measures']['L4-I']['thickness']))\ + "-(" + str(geometry.localAxis[0]) + "," \ + str(geometry.localAxis[1]) + ',' + str(geometry.localAxis[2]) + ')' + EccentricityOut # Update the wall object so it forms on of the two multiplex sheets _renewMaterialDictionary(NewMaterialName, wall.material, wall.name, wall.name) _renewGeometryDictionary(NewGeometryNameIn, wall.geometry, wall.name, wall.name) _renewDataDictionary(wall.data, wall.data, wall.name, wall.name) wall.material = NewMaterialName wall.geometry = NewGeometryNameIn # Assign new properties to wall wall.assignMaterial() wall.assignGeometry() wall.assignData() wall.setName(NewWallNameIn) # Add new wall as second multiplex sheet new_wall = Wall(NewWallNameOut, NewMaterialName, NewGeometryNameOut, wall.points) # Update wall attribute with strengthening measure wall.add_meta_data({'strengthening': measure_sub_type}) viia_add_strengthening_shape(shape=wall, strengthening_shape=new_wall) else: # Change wall names to HSB NewWallName = wall.name.split('-')[0] + "-WANDEN-L4I-LIN-HSB-" + str(int(geometry.thickness*1000)) + "-" + \ wall.name[-1] NewMaterialName = "LIN-HSB-" + \ str(project.project_specific['strengthening_measures']['L4-I']['thickness']/1000) + "-" + \ str(project.project_specific['strengthening_measures']['L4-I']['beam width']/1000) \ + "-" + str(heightBeam) + "-" + \ str(project.project_specific['strengthening_measures']['L4-I']['ctc']) NewGeometryName = "WANDHSB-" + str(int(geometry.thickness * 1000)) + "-(" + str(geometry.localAxis[0]) + "," \ + str(geometry.localAxis[1]) + ',' + str(geometry.localAxis[2]) + ')' NewDataName = "THINTE7" # Update the wall object _renewMaterialDictionary(NewMaterialName, wall.material, wall.name, wall.name) _renewGeometryDictionary(NewGeometryName, wall.geometry, wall.name, wall.name) _renewDataDictionary(wall.data, wall.data, wall.name, wall.name) wall.material = NewMaterialName wall.geometry = NewGeometryName wall.data = NewDataName # Set elementClassType to flat shell (other walls are of type curved shell) wall.elementClassType = "FLASHL" # Assign new properties to wall wall.assignMaterial() wall.assignGeometry() wall.assignData() wall.setName(NewWallName) # Update wall attribute with strengthening measure wall.add_meta_data({'strengthening': measure_sub_type}) # Notifications for user project.write_log(f"L4-I measure applied on wall {wall.name}.")
### =================================================================================================================== ### 3. End of script ### ===================================================================================================================