Source code for viiapackage.reference_approach.viia_current_object

### ===================================================================================================================
###   Helper class for the current object
### ===================================================================================================================
# Copyright ©VIIA 2024

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

# General imports
from __future__ import annotations
from typing import TYPE_CHECKING

# 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.viiaSettings import ViiaSettings


### ===================================================================================================================
###   2. CLASS CurrentObject
### ===================================================================================================================

[docs]class CurrentObject: """ Helper class for storing the data from user for the current object."""
[docs] def __init__( self, cluster: str, cluster_main: str, construction_year: int, material_load_walls: str, most_floor_height: float, most_thickness_load_walls: float, nr_levels: int, other_floors_material: str, pga: float, consequence_class: str, typology: float, objectnumber_viia: str, objectpart: str): """ Input: - cluster (str): Cluster code for the current object, for example '4B'. - cluster_main (str): Main cluster code for the current object, for example '4'. - construction_year (int): Year of construction for the current object, for example 1999. - material_load_walls (str): Provide the material of the load-bearing walls for which the current objects are matched. Select from 'aerated concrete', 'concrete', 'clay masonry < 1945', 'clay masonry > 1945', 'calcium silicate > 1960', 'calcium silicate > 1985', 'HSB', 'modification wall' or 'timber'. - most_floor_height (float): Most common height of the load-bearing walls for which the current objects are matched, in [m]. This is the most common floor height (approx.) or in absence of a common height the maximum wall height at the ground level. If we have 4 floors with heights: 3, 3.19, 3.2, 2.7m, the most common floor height is 3.2m. If we have 4 floors with all different height: 3, 3.2, 3.5, 2.7, then the most common floor height is the height of the ground floor. - most_thickness_load_walls (float): Most common thickness of the load-bearing walls for which the current objects are matched, in [m]. For PSSEs walls if existing. Usually, the thickness of masonry PSSE is constant between floors but if not select the most common at the ground floor level. - nr_levels (int): Number of levels excluding the basement level and including storage/living area attics. A basement level is included if it covers all the footprint area of the object (excluding appendances) and is modelled for the analysis. Small attic with non-structural ceiling (so no storage/living area) is not considered as a level. - other_floors_material (str): Provide only the most dominant material for the floor materials, other than the ground floor, for which the current objects are matched. Select from 'concrete', 'masonry', 'timber' or 'other (structural)'. - pga (float): Value of the pga of the current object, in [g]. - consequence_class (str): Indicate the consequence class of the current object. E.g. 'CC1b' or 'CC2'. - typology (str): Name of the cluster of the current object, according NCG naming, for example 'Vrijstaand'. - objectnumber_viia (str): Number of the current VIIA-object, used for reporting only. - objectpart (str): Name of the current objectpart, used for reporting only. """ self.cluster = cluster self.cluster_main = cluster_main self.construction_year = construction_year self.material_load_walls = material_load_walls self.most_floor_height = most_floor_height self.most_thickness_load_walls = most_thickness_load_walls self.nr_levels = nr_levels self.other_floors_material = other_floors_material self.pga = pga self.consequence_class = consequence_class self.typology = typology self.objectnumber_viia = objectnumber_viia self.objectpart = objectpart
@property def cluster(self): return self.__cluster @cluster.setter def cluster(self, new_cluster: str): if not isinstance(new_cluster, str): raise TypeError("ERROR: The cluster of the current object should be provided as a string.") if len(new_cluster) == 1 and not new_cluster.isnumeric(): raise TypeError("ERROR: The cluster of the current object should be provided starting with number.") if len(new_cluster) > 1 and not new_cluster[:-1].isnumeric(): raise TypeError("ERROR: The cluster of the current object should be provided starting with number.") self.__cluster = new_cluster @property def construction_year(self): return self.__construction_year @construction_year.setter def construction_year(self, new_construction_year: int): if not isinstance(new_construction_year, int): raise TypeError("ERROR: The construction_year of the current object should be provided as an integer.") if 1000 > new_construction_year > 2022: raise TypeError("ERROR: The construction_year of the current object is expected between 1000 and 2022.") self.__construction_year = new_construction_year @property def material_load_walls(self): return self.__material_load_walls @material_load_walls.setter def material_load_walls(self, new_material_load_walls: str): if not isinstance(new_material_load_walls, str): raise TypeError( "ERROR: The material for the load-bearing walls of the current object should be provided " "as a string.") if new_material_load_walls not in [ 'aerated concrete', 'concrete', 'clay masonry < 1945', 'clay masonry > 1945', 'calcium silicate > 1960', 'calcium silicate > 1985', 'HSB', 'modification wall', 'timber', 'clay masonry']: raise ValueError( "ERROR: Input for the material of the load-bearing walls should be selected from 'aerated concrete', " "'concrete', 'clay masonry < 1945', 'clay masonry > 1945', 'calcium silicate > 1960'," "'calcium silicate > 1985', 'HSB', 'modification wall' or 'timber'. Provided was " f"{new_material_load_walls}.") if 'clay masonry' in new_material_load_walls: new_material_load_walls = 'clay masonry' if 'HSB' in new_material_load_walls: new_material_load_walls = 'timber' self.__material_load_walls = new_material_load_walls @property def most_floor_height(self): return self.__most_floor_height @most_floor_height.setter def most_floor_height(self, new_most_floor_height: float): if not isinstance(new_most_floor_height, (float, int)): raise TypeError( "ERROR: The height of the walls of the current object should be provided as a float.") if fem_smaller(new_most_floor_height, 0): raise ValueError("ERROR: The height of the walls of the current object should be larger than zero.") if fem_greater(new_most_floor_height, 20): raise ValueError("ERROR: The height of the walls of the current object is expected to be smaller.") self.__most_floor_height = new_most_floor_height @property def most_thickness_load_walls(self): return self.__most_thickness_load_walls @most_thickness_load_walls.setter def most_thickness_load_walls(self, new_most_thickness_load_walls: float): if not isinstance(new_most_thickness_load_walls, (float, int)): raise TypeError( "ERROR: The thickness of the walls of the current object should be provided as a float.") if fem_smaller(new_most_thickness_load_walls, 0.05): raise ValueError("ERROR: The thickness of the walls of the current object should be larger than 50mm.") if fem_greater(new_most_thickness_load_walls, 1): raise ValueError( "ERROR: The thickness of the walls of the current object is expected to be less than 1000mm.") self.__most_thickness_load_walls = new_most_thickness_load_walls @property def nr_levels(self): return self.__nr_levels @nr_levels.setter def nr_levels(self, new_nr_levels: int): if not isinstance(new_nr_levels, int): raise TypeError("ERROR: The number of storeys of the current object should be provided as an integer.") if new_nr_levels <= 0: raise ValueError("ERROR: The number of storeys of the current object should be larger than zero.") if new_nr_levels >= 10: raise ValueError("ERROR: The number of storeys of the current object is expected to be less than 10.") self.__nr_levels = new_nr_levels @property def other_floors_material(self): return self.__other_floors_material @other_floors_material.setter def other_floors_material(self, new_other_floors_material: str): if not isinstance(new_other_floors_material, str): raise TypeError( "ERROR: The material for the floors of the current object should be provided as a string.") if new_other_floors_material not in [ 'concrete', 'masonry', 'timber', 'other (structural)']: raise ValueError( "ERROR: Input for the material of the floors should be selected from 'concrete', 'masonry', 'timber' " f"or 'other (structural)'. Provided was {new_other_floors_material}.") self.__other_floors_material = new_other_floors_material @property def pga(self): return self.__pga @pga.setter def pga(self, new_pga: float): if not isinstance(new_pga, (float, int)): raise TypeError( "ERROR: The pga of the current object should be provided as a float.") if new_pga <= 0: raise ValueError("ERROR: The pga of the current object should be larger than zero.") if new_pga > 3: raise ValueError("ERROR: Thepga of the current object is expected to be smaller.") self.__pga = new_pga @property def consequence_class(self): return self.__consequence_class @consequence_class.setter def consequence_class(self, new_consequence_class: str): if not isinstance(new_consequence_class, str): raise TypeError("ERROR: The consequence-class of the current object should be provided as a string.") if new_consequence_class.upper() not in ViiaSettings.IMPORTANCE_FACTORS: raise TypeError( f"ERROR: The consequence-class of the current object should be selected from " f"{', '.join(ViiaSettings.IMPORTANCE_FACTORS.keys())}.") self.__consequence_class = new_consequence_class.upper() @property def typology(self): return self.__typology @typology.setter def typology(self, new_typology: str): if not isinstance(new_typology, str): raise TypeError("ERROR: The typology of the current object should be provided as a string.") self.__typology = new_typology @property def importance_factor(self) -> float: return ViiaSettings.IMPORTANCE_FACTORS[self.consequence_class] @property def design_pga(self) -> float: return self.importance_factor * self.pga
### =================================================================================================================== ### 3. Function to create the ReferenceObject instance ### ===================================================================================================================
[docs]def viia_current_object( project: ViiaProject, material_load_walls: str, most_floor_height: float, most_thickness_load_walls: float, nr_levels: int, other_floors_material: str) -> CurrentObject: """ Function to create the instance for the current object. It collects the data required from the project instance and the user input. Input: - project (obj): VIIA project object containing collections of fem objects and project variables. - material_load_walls (str): Provide the material of the load-bearing walls for which the current objects are matched. Select from 'aerated concrete', 'concrete', 'clay masonry < 1945', 'clay masonry > 1945', 'calcium sillicate > 1960', 'calcium sillicate > 1985', 'HSB', 'modification wall' or 'timber'. - most_floor_height (float): Most common height of the load-bearing walls for which the current objects are matched, in [m]. This is the most common floor height (approx.) or in absence of a common height the maximum wall height at the ground level. If we have 4 floors with heights: 3, 3.19, 3.2, 2.7m, the most common floor height is 3.2m. If we have 4 floors with all different height: 3, 3.2, 3.5, 2.7, then the most common floor height is the height of the ground floor. - most_thickness_load_walls (float): Most common thickness of the load-bearing walls for which the current objects are matched, in [mm]. For PSSEs walls if existing. Usually, the thickness of masonry PSSE is constant between floors but if not select the most common at the ground floor level. - nr_levels (int): Number of levels excluding the basement level and including storage/living area attics. A basement level is included if it covers all the footprint area of the object (excluding appendances) and is modelled for the analysis. Small attic with non-structural ceiling (so no storage/living area) is not considered as a level. - other_floors_material (str): Provide only the most dominant material for the floor materials, other than the ground floor, for which the current objects are matched. Select from 'concrete', 'masonry', 'timber' or 'other (structural)'. Output: - Returns the created current object as instance of the ReferenceObject class. Validation of the input is performed in the setters of the class. """ construction_year = int( project.project_information['oorspronkelijk_bouwjaar'].lower().replace('ca', '').replace('.', ''). replace(' ', '').replace('<', '').replace('>', '')) # Convert to units for wall thickness to meter most_thickness_load_walls = most_thickness_load_walls / 1E3 return CurrentObject( cluster=project.project_information['object_cluster_id']['cluster'], cluster_main=project.project_information['object_cluster_id']['hoofdgroep'], construction_year=construction_year, material_load_walls=material_load_walls, most_floor_height=most_floor_height, most_thickness_load_walls=most_thickness_load_walls, nr_levels=nr_levels, other_floors_material=other_floors_material, pga=project.project_information['pga'], consequence_class=project.project_information['consequence_class'], typology=project.project_information['object_cluster_id']['typologie'], objectnumber_viia=project.name, objectpart=project.project_information['objectdeel'])
### =================================================================================================================== ### 4. End of script ### ===================================================================================================================