Source code for viiapackage.analyses.nlpo_helper_functions.viia_eccentricity_check

### ===================================================================================================================
###  FUNCTION: Check the eccentricity for NLPO according VIIA requirements
### ===================================================================================================================
# Copyright ©VIIA 2024

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

# General imports
from __future__ import annotations
from typing import TYPE_CHECKING, Dict

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

# References for functions and classes in the viiaPackage
if TYPE_CHECKING:
    from viiapackage.viiaStatus import ViiaProject
from viiapackage.analyses.nlpo_helper_functions.viia_center_of_mass_nlpo import viia_center_of_mass_nlpo
from viiapackage.analyses.nlpo_helper_functions.viia_center_of_rigidity import viia_center_of_rigidity
from viiapackage.analyses.nlpo_helper_functions.viia_locate_piers import viia_locate_piers
from viiapackage.analyses.nlpo_helper_functions.viia_effective_pier_shear_stiffness import \
    viia_effective_pier_shear_stiffness


### ===================================================================================================================
###   2. Function viia_eccentricity_check
### ===================================================================================================================

[docs]def viia_eccentricity_check(project: ViiaProject) -> Dict[str, Dict[str, Dict[str, float]]]: """ This function checks whether the eccentricity of a building is sufficiently small in order for the NPR to allow pushover analysis. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. Output: - Returns dictionary containing the results of all eccentricity checks performed. """ center_of_mass = viia_center_of_mass_nlpo(project=project) walls_n0 = [] for wall in project.collections.walls: if "N0" in wall.name: walls_n0.append(wall) piers = viia_locate_piers(project=project, walls=walls_n0) viia_effective_pier_shear_stiffness(project=project, piers=piers) center_of_rigidity = viia_center_of_rigidity(piers=piers) # TODO consider all the levels including the levels with [0,0,0] or they will be removed after you return # Calculate the eccentricity for each level eccentricity_dict = {} for level in center_of_mass: ecc_x = max(abs(center_of_mass[level]['x'] - center_of_rigidity['x']['Y_pos']), abs(center_of_mass[level]['x'] - center_of_rigidity['x']['Y_neg'])) ecc_y = max(abs(center_of_mass[level]['y'] - center_of_rigidity['y']['X_pos']), abs(center_of_mass[level]['y'] - center_of_rigidity['y']['X_neg'])) eccentricity_dict.update({level: [ecc_x, ecc_y]}) # Find the building width in x and y directions building_width_in_x = max([i.get_ref_point()[1] for i in project.collections.shape_nodes]) - \ min([i.get_ref_point()[1]for i in project.collections.shape_nodes]) building_width_in_y = max([i.get_ref_point()[0] for i in project.collections.shape_nodes]) - \ min([i.get_ref_point()[0]for i in project.collections.shape_nodes]) # TODO the definition of the x- and y- direction width needed to be confirmed accidental_eccentricity_x = 0.05 * building_width_in_x accidental_eccentricity_y = 0.05 * building_width_in_y # Calculate the threshold values of eccentricity level x_02b = 0.2 * building_width_in_x x_04b = 0.4 * building_width_in_x y_02b = 0.2 * building_width_in_y y_04b = 0.4 * building_width_in_y # Set the output dictionary for each level of x- and y- direction x_eccentricity_dict = {} y_eccentricity_dict = {} # Define the output parameters in x direction for level, value in eccentricity_dict.items(): x_eccentricity_dict[level] = {} if fem_smaller(value[1], x_02b): # TODO the definition of the x- and y- direction width needed to be confirmed x_eccentricity_dict[level].update({'Eccentricity type': 'Negligible'}) x_eccentricity_dict[level].update({'Eccentricity magnitude': round(value[1], 3)}) try: x_eccentricity_dict[level].update({'Eccentricity percentage of b': round( x_eccentricity_dict[level]['Eccentricity magnitude'] / building_width_in_x, 3)}) except ZeroDivisionError: x_eccentricity_dict[level].update({'Eccentricity percentage of b': 0.0}) project.write_log( f"The level of {level} is not existing, 0 will be returned as eccentricity for this level.") elif fem_greater(value[1], x_02b) and fem_smaller(value[1], y_04b): # TODO the definition of the x- and y- direction width needed to be confirmed x_eccentricity_dict[level].update({'Eccentricity type': 'Significant'}) x_eccentricity_dict[level].update({'Eccentricity magnitude': round(value[1] + accidental_eccentricity_x, 3)}) x_eccentricity_dict[level].update({'Eccentricity percentage of b': round( x_eccentricity_dict[level]['Eccentricity magnitude'] / building_width_in_x, 3)}) elif fem_greater(value[1], x_04b): # TODO the definition of the x- and y- direction width needed to be confirmed x_eccentricity_dict[level].update({'Eccentricity type': 'Severe'}) x_eccentricity_dict[level].update({'Eccentricity magnitude': round(value[1] + accidental_eccentricity_x, 3)}) x_eccentricity_dict[level].update({'Eccentricity percentage of b': round( x_eccentricity_dict[level]['Eccentricity magnitude'] / building_width_in_x, 3)}) # Define the output parameters in y direction for level, value in eccentricity_dict.items(): y_eccentricity_dict[level] = {} if fem_smaller(value[0], y_02b): # TODO the definition of the x- and y- direction width needed to be confirmed y_eccentricity_dict[level].update({'Eccentricity type': 'Negligible'}) y_eccentricity_dict[level].update({'Eccentricity magnitude': round(value[0], 3)}) try: y_eccentricity_dict[level].update({'Eccentricity percentage of b': round( y_eccentricity_dict[level]['Eccentricity magnitude'] / building_width_in_y, 3)}) except ZeroDivisionError: y_eccentricity_dict[level].update({'Eccentricity percentage of b': 0.0}) project.write_log( f"The level of {level} is not existing, 0 will be returned as eccentricity for this level.") elif fem_greater(value[0], y_02b) and fem_smaller(value[1], y_04b): # TODO the definition of the x- and y- direction width needed to be confirmed y_eccentricity_dict[level].update({'Eccentricity type': 'Significant'}) y_eccentricity_dict[level].update({'Eccentricity magnitude': round(value[0] + accidental_eccentricity_y, 3)}) y_eccentricity_dict[level].update({'Eccentricity percentage of b': round( y_eccentricity_dict[level]['Eccentricity magnitude'] / building_width_in_y, 3)}) elif fem_greater(value[0], y_04b): # TODO the definition of the x- and y- direction width needed to be confirmed y_eccentricity_dict[level].update({'Eccentricity type': 'Severe'}) y_eccentricity_dict[level].update({'Eccentricity magnitude': round(value[0] + accidental_eccentricity_y, 3)}) y_eccentricity_dict[level].update({'Eccentricity percentage of b': round( y_eccentricity_dict[level]['Eccentricity magnitude'] / building_width_in_y, 3)}) return {'X_direction': x_eccentricity_dict, 'Y_direction': y_eccentricity_dict}
### =================================================================================================================== ### 3. End of script ### ===================================================================================================================