Source code for viiapackage.reference_approach.reference_wall.ref_wall_oop

### ===================================================================================================================
###   CLASS: RefWallOOP
### ===================================================================================================================
# Copyright ©VIIA 2024

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

# General imports
from typing import Dict, Union, Optional, List

# References for functions and classes in the rhdhv_fem package
from rhdhv_fem.shapes import Wall
from rhdhv_fem.fem_math import fem_perpendicular_vectors, fem_is_close
from rhdhv_fem.shapes.surfaces.roof import Roof
from rhdhv_fem.fem_config import Config

# References for functions and classes in the viiaPackage
from viiapackage.viiaGeneral import _viia_find_upper_floor_of_wall
from viiapackage.reference_approach.reference_wall.current_wall import CurrentWall
from viiapackage.reference_approach.reference_wall.ref_wall import RefWall


### ===================================================================================================================
###   2. Ref wall oop class
### ===================================================================================================================

[docs]class RefWallOOP(RefWall): """ Class for the data of the reference walls. These are compared to the current wall.""" # Class property for the current wall referenced current_wall: CurrentWall = None
[docs] def __init__(self, wall: Wall, measures: str, segment_width: float, segment_nr: Optional[int] = None): """ Input: - wall (Wall): Object reference of the wall from the reference object. Should be an instance of Wall class. - measures (str): All the measures in string format that have been applied to the object. - segment_width (float): Width of the wall between two lateral supporting walls, in [m]. In case of no segmentations due to supporting walls, the total width of the wall is used. - segment_nr (int): Number of the segment of the wall (starting at 1). Default value None, which is the case if the wall is not split. """ # Name if segment_nr: name = f'{wall.name} (Segment {segment_nr})' else: name = wall.name # Segments self.__segment_nr = segment_nr # Openings if wall.openings is None: self.__openings = 0 else: self.__openings = len(wall.openings) # Size of openings self.__size_of_openings = self.calc_size_of_openings(wall) # Wall vector self.__wall_vector = wall.contour.get_normal_vector() # Floor spanning direction self.__floor_spanning_direction = self.calc_floor_spanning_direction(wall) # Roof spanning direction self.__roof_spanning_direction = self.calc_roof_spanning_direction(wall) # Overburden load self.__overburden_load = self.calc_overburden_load(wall) super().__init__(wall=wall, measures=measures, name=name, width=segment_width)
@property def score_thickness(self) -> float: """ Method of 'RefWallOOP' to calculate score for comparison of the thickness of the walls.""" return max([100 - abs((self.thickness - self.current_wall.thickness / 1E3) / self.current_wall.thickness / 1E3) * 100, 0]) @property def score_width(self) -> float: """ Method of 'RefWallOOP' to calculate score for comparison of the total length of the walls.""" return max([100 - abs((self.width - self.current_wall.width) / self.current_wall.width) * 100, 0]) @property def score_height(self) -> float: """ Method of 'RefWallOOP' to calculate score for comparison of the total height of the walls.""" return max([100 - abs((self.height - self.current_wall.height) / self.current_wall.height) * 100, 0]) @property def score_density(self) -> float: """ Method of 'RefWallOOP' to calculate score for comparison of the density of the walls.""" return max([100 - abs((self.density - self.current_wall.density) / self.current_wall.density) * 100, 0]) @property def score_material(self) -> float: """ Method of 'RefWallOOP' to calculate score for comparison of the material of the walls.""" # Check if materials are the same (and lin_check) if self.current_wall.material in self.material: if ('LIN' in self.current_wall.material) == ('LIN' in self.material): return 100 return 50 return 0 @property def score_wall_type(self) -> float: """ Method of 'RefWallOOP' to calculate score for comparison of the wall-type (inner or facade) of the walls.""" if self.wall_type == self.current_wall.wall_type: return 100 return 0 @property def openings(self) -> int: """ Method of 'RefWallOOP' to calculate the number of opening of each wall.""" return self.__openings @property def score_openings(self) -> float: """ Method of 'RefWallOOP' to calculate score for comparison of the opening of the walls.""" if self.openings == self.current_wall.openings: return 100 return 0
[docs] def calc_size_of_openings(self, wall) -> List[list]: """ Method of 'RefWallOOP' to calculate the size of the opening(s) of each wall.""" opening_dimensions = [] if wall.openings: for opening in wall.openings: wall_opening_min_max = opening.get_min_max() width = max([abs(wall_opening_min_max['x-max'] - wall_opening_min_max['x-min']), abs(wall_opening_min_max['y-max'] - wall_opening_min_max['y-min'])]) height = abs(wall_opening_min_max['z-max'] - wall_opening_min_max['z-min']) opening_dimensions.append([round(width, 2), round(height, 2)]) return opening_dimensions
@property def size_of_openings(self) -> List[list]: """ Method of 'RefWallOOP' to calculate the number of opening of each wall.""" return self.__size_of_openings @property def score_opening_size(self) -> float: """ Method of 'RefWallOOP' to calculate score for comparison of the size of the opening of the walls.""" if self.current_wall.openings > 0: if all(directions in self.size_of_openings for directions in self.current_wall.size_of_openings): return 100 elif any(directions in self.size_of_openings for directions in self.current_wall.size_of_openings): return 50 return 0 @property def wall_vector(self): """ Method of 'RefWallOOP' to determine the vector of the current wall.""" return self.__wall_vector @property def floor_spanning_direction(self) -> list: """ Method of 'RefWallOOP' to determine the spanning direction of the floors.""" return self.__floor_spanning_direction
[docs] def calc_floor_spanning_direction(self, wall) -> list: """ Method of 'RefWallOOP' to determine the spanning direction of the connected floors compared to the wall.""" #Connected floors connected_floors = [floor for floor in _viia_find_upper_floor_of_wall(wall) if ('DUMMY' not in floor.name)] floor_spanning_direction = [] if len(connected_floors) > 0: for floor in connected_floors: if 'BETON' in floor.name: floor_spanning_direction.append('Perpendicular') else: floor_x_axis = floor.element_x_axis floor_spanning_direction.append('Parallel' if fem_perpendicular_vectors( floor_x_axis.vector, self.wall_vector) else 'Perpendicular') return floor_spanning_direction
@property def score_floor_spanning(self) -> float: """ Method of 'RefWallOOP' to calculate score for comparison of the floor spanning compared to the walls.""" if self.current_wall.floor_spanning_direction in self.floor_spanning_direction: return 100 return 0 @property def roof_spanning_direction(self): """ Method of 'RefWallOOP' to determine the spanning direction of the floors.""" return self.__roof_spanning_direction
[docs] def calc_roof_spanning_direction(self, wall) -> list: """ Method of 'RefWallOOP' to determine the spanning direction of the connected roof compared to the wall.""" # Connected roofs connected_roofs = [ shape for shape in wall.project.collections.shapes if (shape is not wall and isinstance(shape, Roof) and wall.get_connecting_lines(shape))] roof_spanning_direction = [] if len(connected_roofs) > 0: for roof in connected_roofs: roof_x_axis = roof.element_x_axis roof_spanning_direction.append('Parallel' if fem_perpendicular_vectors( roof_x_axis.vector, self.wall_vector) else 'Perpendicular') return roof_spanning_direction
@property def score_roof_spanning(self) -> float: """ Method of 'RefWallOOP' to calculate score for comparison of the roof spanning compared to the walls.""" if self.current_wall.roof_spanning_direction in self.roof_spanning_direction: return 100 return 0 @property def overburden_load(self) -> float: """ Method of 'RefWallOOP' to determine the spanning direction of the floor compared to the current wall.""" return self.__overburden_load
[docs] def calc_overburden_load(self, wall) -> float: """ Method of 'RefWallOOP' to determine the spanning direction of the floor compared to the current wall.""" #Connected floors connected_floors = [floor for floor in _viia_find_upper_floor_of_wall(wall) if ('DUMMY' not in floor.name)] # Connected roofs connected_roofs = [ shape for shape in wall.project.collections.shapes if (shape is not wall and isinstance(shape, Roof) and wall.get_connecting_lines(shape))] ov_load = 0 if len(connected_floors) > 0 and 'Perpendicular' in self.floor_spanning_direction: for floor in connected_floors: floor_min_max = floor.contour.get_min_max() width = abs(floor_min_max['x-max'] - floor_min_max['x-min']) length = abs(floor_min_max['y-max'] - floor_min_max['y-min']) floor_weight = floor.geometry.geometry_model.thickness * floor.material.mass_density * 9.81 if list(map(abs, self.wall_vector)) == [1.0, 0.0, 0.0]: ov_load += (floor_weight * width / 4) / 1000 if 'BETON' in floor.name else \ (floor_weight * width / 2) / 1000 elif list(map(abs, self.wall_vector)) == [0.0, 1.0, 0.0]: ov_load += (floor_weight * length / 4) / 1000 if 'BETON' in floor.name else \ (floor_weight * length / 2) / 1000 if len(connected_roofs) > 0 and 'Perpendicular' in self.roof_spanning_direction: for roof in connected_roofs: roof_min_max = roof.contour.get_min_max() width = abs(roof_min_max['x-max'] - roof_min_max['x-min']) length = abs(roof_min_max['y-max'] - roof_min_max['y-min']) roof_weight = roof.geometry.geometry_model.thickness * roof.material.mass_density * 9.81 if list(map(abs, self.wall_vector)) == [1.0, 0.0, 0.0]: ov_load += (roof_weight * width) / 1000 elif list(map(abs, self.wall_vector)) == [0.0, 1.0, 0.0]: ov_load += (roof_weight * length) / 1000 return ov_load
@property def score_ov_load(self) -> float: """ Method of 'RefWallOOP' to calculate score for comparison of the overburden loads of the walls.""" current_wall_overburden_load = self.current_wall.overburden_load if fem_is_close(self.current_wall.overburden_load, 0): current_wall_overburden_load = 1/(10**Config.CHECK_PRECISION) return max([100 - abs((self.overburden_load - current_wall_overburden_load) / current_wall_overburden_load) * 100, 0]) @property def score(self) -> float: """ Method of 'RefWallOOP' to calculate total score for comparison of the current wall and reference wall.""" scores = [score for score in [ self.score_thickness, self.score_width, self.score_height, self.score_density, self.score_openings, self.score_material, self.score_wall_type, self.score_floor_spanning, self.score_roof_spanning, self.score_ov_load] if score is not None] return sum(scores) / len(scores)
[docs] def to_report(self) -> Dict[str, Union[str, float]]: """ Method of 'RefWallOOP' to convert data for the report.""" return { 'Object part': self.objectpart, 'Wall name': self.name, 'Layer': self.layer, 'Wall ID': self.wall_id, 'Material': self.material, 'Density [kg/m3]': self.density, 'Thickness [mm]': self.thickness * 1000, 'Width [m]': self.width, 'Height [m]': self.height, 'Wall type': self.wall_type, 'Measures in object part': self.measures, 'Openings': self.openings, 'Size of Openings': self.size_of_openings, 'Floor Spanning': self.floor_spanning_direction, 'Roof Spanning': self.roof_spanning_direction, 'Overburden Load': self.overburden_load}
[docs] def to_score(self) -> Dict[str, Union[str, float]]: """ Method of 'RefWallOOP' to score the wall.""" return { 'Score: thickness': self.score_thickness, 'Score: width': self.score_width, 'Score: height': self.score_height, 'Score: density': self.score_density, 'Score: material': self.score_material, 'Score: wall type': self.score_wall_type, 'Score: openings': self.score_openings, 'Score: opening size': self.score_opening_size, 'Score: floor spanning': self.score_floor_spanning, 'Score: roof spanning': self.score_roof_spanning, 'Score: ov load': self.score_ov_load, 'Total Score': self.score}
[docs] def to_table(self) -> Dict[str, Union[str, float]]: """ Method of 'RefWallOOP' to convert data for a table.""" return { 'objectpart': self.objectpart, 'name': self.name, 'layer': self.layer, 'wall_ID': self.wall_id, 'material': self.material, 'density': self.density, 'thickness': self.thickness, 'width': self.width, 'height': self.height, 'wall_type': self.wall_type}
### =================================================================================================================== ### 3. End of script ### ===================================================================================================================