Coverage for teaser/logic/retrofit.py: 92%
37 statements
« prev ^ index » next coverage.py v7.4.4, created at 2025-04-29 16:01 +0000
« prev ^ index » next coverage.py v7.4.4, created at 2025-04-29 16:01 +0000
1import itertools
3from teaser.logic.buildingobjects.building import Building
4import teaser.data.utilities as datahandling
7def generate_buildings_for_all_element_combinations(
8 project_add_building_function: callable,
9 add_building_function_kwargs: dict,
10 elements: list = None,
11 retrofit_choices: list = None
12):
13 """
14 Generate buildings for all possible combinations of
15 retrofit statuses for specified building elements.
17 This function creates multiple variations of a building based
18 on different retrofit options for specified building elements.
19 It's designed to work with TABULA archetypes.
21 Parameters
22 ----------
23 project_add_building_function : callable
24 Function to add a building to the project.
25 add_building_function_kwargs : dict
26 Keyword arguments for the add_building function.
27 elements : list, optional
28 List of building elements to consider for retrofit.
29 Defaults to ['outer_walls', 'windows', 'rooftops', 'ground_floors'].
30 retrofit_choices : list, optional
31 List of retrofit options to consider.
32 Defaults to ['standard', 'retrofit', 'adv_retrofit'].
34 Returns
35 -------
36 list: A list of names of the generated buildings.
38 Raises
39 ------
40 ValueError: If unsupported elements or retrofit choices are provided, or if the
41 construction data is not from TABULA DE or DK.
43 Note
44 ----
45 This function only works with TABULA DE or DK construction data.
46 """
47 construction_data = datahandling.ConstructionData(
48 add_building_function_kwargs["construction_data"]
49 )
50 if not construction_data.is_tabula_de() and not construction_data.is_tabula_dk():
51 raise ValueError(
52 "Given option to retrofit all combinations "
53 "is only implemented for TABULA archetypes."
54 )
56 # Define mapping for later naming
57 retrofit_dict = {'standard': 0, 'retrofit': 1, 'adv_retrofit': 2}
58 possible_elements = ['outer_walls', 'windows', 'rooftops', "ground_floors"]
60 if elements is None:
61 elements = ['outer_walls', 'windows', 'rooftops', "ground_floors"]
62 if retrofit_choices is None:
63 retrofit_choices = list(retrofit_dict.keys())
64 unsupported_elements = set(elements).difference(possible_elements)
65 if unsupported_elements:
66 raise ValueError(
67 "The following elements are not supported: " + ", ".join(unsupported_elements)
68 )
69 unsupported_choices = set(retrofit_choices).difference(retrofit_dict.keys())
70 if unsupported_choices:
71 raise ValueError(
72 "The following retrofit_choices are not supported: " + ", ".join(unsupported_choices)
73 )
75 # Generate all possible combinations of retrofit statuses for each element
76 combinations = itertools.product(retrofit_choices, repeat=len(elements))
78 # Create a list to store the resulting dictionaries
79 combinations = [
80 {
81 element: status
82 for element, status in zip(elements, combo)
83 }
84 for combo in combinations
85 ]
87 generated_building_names = []
88 for element_retrofit_stats in combinations:
89 # Code for retrofit status OiWiRiGi with i from 0 to 2
90 retrofit_code = ''.join(
91 f"{element[0]}{retrofit_dict[retrofit_option]}"
92 for element, retrofit_option in element_retrofit_stats.items()
93 )
94 modified_function_kwargs = add_building_function_kwargs.copy()
95 modified_function_kwargs["name"] += f"_{retrofit_code}"
96 building = project_add_building_function(**modified_function_kwargs)
97 component_based_retrofit(building=building, element_retrofit_stats=element_retrofit_stats)
98 generated_building_names.append(modified_function_kwargs["name"])
99 return generated_building_names
102def component_based_retrofit(building: Building, element_retrofit_stats: dict):
103 """
104 Apply component-based retrofits to a building based on specified retrofit statuses.
106 This function applies retrofits to specific building elements (e.g., walls, windows)
107 based on the provided retrofit statuses.
109 Parameters
110 ----------
111 building : Building
112 The building object to be retrofitted.
113 element_retrofit_stats : dict
114 A dictionary specifying the retrofit status for each
115 building element. Keys are element names (e.g., 'outer_walls'),
116 and values are retrofit options (e.g., 'standard', 'retrofit').
118 Note
119 ----
120 This function modifies the building object in-place.
121 Only elements with 'standard' retrofit option are processed.
122 """
123 for zone in building.thermal_zones:
124 for element, retrofit_option in element_retrofit_stats.items():
125 if retrofit_option == "standard":
126 continue
127 for wall_count in getattr(zone, element):
128 wall_count.load_type_element(
129 year=building.year_of_construction,
130 construction=wall_count.construction_data.replace(
131 "standard",
132 retrofit_option
133 )
134 )