Skip to content

Commit c0f22eb

Browse files
authored
Create build_airflownetwork.py
1 parent 34419b3 commit c0f22eb

1 file changed

Lines changed: 220 additions & 0 deletions

File tree

scripts/build_airflownetwork.py

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
import json
2+
import argparse
3+
import math
4+
5+
if __name__ == '__main__':
6+
7+
parser = argparse.ArgumentParser(description='.')
8+
parser.add_argument('epJSON', metavar='EPJSON')
9+
parser.add_argument('-o', '--output', dest='output_file', action='store',
10+
default='afn.epJSON', help='file to store output in')
11+
parser.add_argument('-v', '--verbose', dest='verbose', action='store_true',
12+
help='operate verbosely')
13+
args = parser.parse_args()
14+
15+
fp = open(args.epJSON, 'r')
16+
model = json.load(fp)
17+
fp.close()
18+
19+
window_objects = ['Window', 'Window:Interzone', 'FenestrationSurface:Detailed']
20+
door_objects = ['Door', 'GlazedDoor', 'Door:Interzone', 'GlazedDoor:Interzone']
21+
22+
simple_window_objects = ['Window',
23+
'Window:Interzone']
24+
simple_door_objects = ['Door',
25+
'GlazedDoor',
26+
'Door:Interzone',
27+
'GlazedDoor:Interzone']
28+
fenestration_objects = ['FenestrationSurface:Detailed']
29+
simple_wall_objects = ['Wall:Exterior',
30+
'Wall:Interzone',
31+
#'Wall:Underground',
32+
'Wall:Adiabatic']
33+
simple_envelope_objects = ['Wall:Exterior']
34+
simple_partition_objects = ['Wall:Interzone',
35+
'Wall:Adiabatic']
36+
simple_roofceiling_objects = ['Roof',
37+
'Ceiling:Adiabatic',
38+
'Ceiling:Interzone']
39+
simple_roof_objects = ['Roof']
40+
simple_ceiling_objects = ['Ceiling:Adiabatic',
41+
'Ceiling:Interzone']
42+
simple_floor_objects = ['Floor:Adiabatic',
43+
#'Floor:GroundContact',
44+
'Floor:Interzone']
45+
detailed_wall_objects = ['BuildingSurface:Detailed',
46+
'Wall:Detailed']
47+
detailed_roofceiling_objects = ['RoofCeiling:Detailed']
48+
detailed_floor_objects = ['Floor:Detailed']
49+
50+
surface_handler = {'Window': Surface.from_envelope,
51+
'Window:Interzone': Surface.from_partition,
52+
'Door': Surface.from_envelope,
53+
'GlazedDoor': Surface.from_envelope,
54+
'Door:Interzone': Surface.from_partition,
55+
'GlazedDoor:Interzone': Surface.from_partition,
56+
'FenestrationSurface:Detailed': Surface.from_detailed_fenestration}
57+
58+
windows = {}
59+
for el in window_objects:
60+
number = 0
61+
try:
62+
these_windows = model[el]
63+
number = len(these_windows)
64+
windows[el] = these_windows
65+
except:
66+
pass
67+
if args.verbose:
68+
print("Found %d '%s' window-type objects" % (number, el))
69+
70+
doors = {}
71+
for el in door_objects:
72+
number = 0
73+
try:
74+
these_doors = model[el]
75+
number = len(these_doors)
76+
doors[el] = these_doors
77+
except:
78+
pass
79+
if args.verbose:
80+
print("Found %d '%s' door-type objects" % (number, el))
81+
82+
n_zones = len(model['Zone'])
83+
interzonal_area = []
84+
keys = list(model['Zone'].keys())
85+
zone_lookup = {}
86+
for i in range(n_zones):
87+
interzonal_area.append(n_zones*[0.0])
88+
zone_lookup[keys[i]] = i
89+
90+
# Handle opaque surfaces
91+
surfaces = []
92+
93+
for type in simple_envelope_objects:
94+
for name,obj in model.get(type, {}).items():
95+
surfaces.append(Surface.from_envelope(model, type, name, obj, None))
96+
97+
for type in simple_partition_objects:
98+
objects = model.get(type, {})
99+
keys = list(objects.keys())
100+
for name in keys:
101+
obj = model[type][name]
102+
result = Surface.from_detailed(model, type, name, obj, None)
103+
surfaces.append(result)
104+
if result.other is not None:
105+
keys.remove(result.other.surface_name)
106+
107+
for type in detailed_wall_objects:
108+
objects = model.get(type, {})
109+
keys = list(objects.keys())
110+
for name in keys:
111+
obj = model[type][name]
112+
result = Surface.from_detailed(model, type, name, obj, None)
113+
if result is not None:
114+
surfaces.append(result)
115+
if result.other is not None:
116+
keys.remove(result.other.surface_name)
117+
118+
# Split into internal/external surfaces
119+
envelope_leakage_name = 'Envelope Leakage'
120+
interzone_leakage_name = 'Interzone Leakage'
121+
envelope_surfaces = []
122+
interzone_surfaces = []
123+
for surf in surfaces:
124+
if surf.other is not None:
125+
surf.component_name = interzone_leakage_name
126+
interzone_surfaces.append(surf)
127+
else:
128+
surf.component_name = envelope_leakage_name
129+
envelope_surfaces.append(surf)
130+
131+
# Handle window and door surfaces
132+
if 'FenestrationSurface:Detailed' in windows:
133+
for obj in windows['FenestrationSurface:Detailed'].values():
134+
repair_fenestration_surface_detailed(obj)
135+
envelope_opening_name = 'Envelope Opening'
136+
interzone_opening_name = 'Interzone Opening'
137+
interzone_doors_and_windows = []
138+
envelope_doors_and_windows = []
139+
allowed_parents = envelope_surfaces + interzone_surfaces
140+
for type, objects in windows.items():
141+
for name, obj in objects.items():
142+
result = surface_handler[type](model, type, name, obj, allowed_parents)
143+
if result is not None:
144+
if result.other is not None:
145+
result.component_name = interzone_opening_name
146+
interzone_doors_and_windows.append(result)
147+
else:
148+
result.component_name = envelope_opening_name
149+
envelope_doors_and_windows.append(result)
150+
151+
# Account for surface areas of openings in parent surfaces
152+
for opening_surface in interzone_doors_and_windows + envelope_doors_and_windows:
153+
if opening_surface.parent is not None:
154+
new_area = opening_surface.parent.area - opening_surface.area
155+
assert new_area > 0.0
156+
opening_surface.parent.area = new_area
157+
else:
158+
# Is this an error? Need to verify
159+
pass
160+
161+
162+
# Sum up interzone areas
163+
for surf in interzone_surfaces:
164+
i = zone_lookup[surf.zone]
165+
j = zone_lookup[surf.other.zone]
166+
#print(surf.name,i,j, surf.zone, surf.other.zone)
167+
interzonal_area[i][j] += surf.area
168+
interzonal_area[j][i] += surf.area
169+
170+
max_interzonal_area = 0.0
171+
for i in range(n_zones):
172+
for j in range(i+1, n_zones):
173+
max_interzonal_area = max(max_interzonal_area, interzonal_area[i][j])
174+
175+
if verbose:
176+
print(interzonal_area)
177+
print(max_interzonal_area)
178+
179+
max_envelope_area = 0.0
180+
for surf in envelope_surfaces:
181+
max_envelope_area = max(max_envelope_area, surf.area)
182+
183+
# Set up the components
184+
coefficient = 0.01
185+
envelope_leakage = Crack(name=envelope_leakage_name, coef=coefficient * max_envelope_area)
186+
interzone_leakage = Crack(name=interzone_leakage_name, coef=2*coefficient * max_interzonal_area)
187+
envelope_opening = SimpleOpening(name=envelope_opening_name, coef=coefficient)
188+
interzone_opening = SimpleOpening(name=envelope_opening_name, coef=coefficient)
189+
190+
# Set up the factors
191+
for surf in envelope_surfaces:
192+
surf.window_door_opening_factor_or_crack_factor = surf.area/max_envelope_area
193+
194+
# Set up the factors
195+
for surf in interzone_surfaces:
196+
surf.window_door_opening_factor_or_crack_factor = surf.area/max_interzonal_area
197+
198+
# Add to the model
199+
model['AirflowNetwork:MultiZone:Surface'] = {}
200+
for obj in envelope_surfaces + interzone_surfaces + interzone_doors_and_windows + envelope_doors_and_windows:
201+
model['AirflowNetwork:MultiZone:Surface'][obj.name] = obj.to_json()
202+
203+
model['AirflowNetwork:MultiZone:Surface:Crack'] = {
204+
envelope_leakage.name: envelope_leakage.to_json(),
205+
interzone_leakage.name: interzone_leakage.to_json()
206+
}
207+
208+
model['AirflowNetwork:MultiZone:Component:SimpleOpening'] = {
209+
envelope_opening.name: envelope_opening.to_json(),
210+
interzone_opening.name: interzone_opening.to_json()
211+
}
212+
213+
model['AirflowNetwork:MultiZone:Zone'] = {}
214+
for name in model['Zone'].keys():
215+
model['AirflowNetwork:MultiZone:Zone'][name+'_AFN'] = {'zone_name': 'name'}
216+
217+
fp = open(args.output_file, 'w')
218+
json.dump(model, fp)
219+
fp.close()
220+

0 commit comments

Comments
 (0)