honeybee-energy 1.116.106__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. honeybee_energy/__init__.py +24 -0
  2. honeybee_energy/__main__.py +4 -0
  3. honeybee_energy/_extend_honeybee.py +145 -0
  4. honeybee_energy/altnumber.py +21 -0
  5. honeybee_energy/baseline/__init__.py +2 -0
  6. honeybee_energy/baseline/create.py +608 -0
  7. honeybee_energy/baseline/data/__init__.py +1 -0
  8. honeybee_energy/baseline/data/constructions.csv +64 -0
  9. honeybee_energy/baseline/data/fen_ratios.csv +15 -0
  10. honeybee_energy/baseline/data/lpd_building.csv +21 -0
  11. honeybee_energy/baseline/data/pci_2016.csv +22 -0
  12. honeybee_energy/baseline/data/pci_2019.csv +22 -0
  13. honeybee_energy/baseline/data/pci_2022.csv +22 -0
  14. honeybee_energy/baseline/data/shw.csv +21 -0
  15. honeybee_energy/baseline/pci.py +512 -0
  16. honeybee_energy/baseline/result.py +371 -0
  17. honeybee_energy/boundarycondition.py +128 -0
  18. honeybee_energy/cli/__init__.py +69 -0
  19. honeybee_energy/cli/baseline.py +475 -0
  20. honeybee_energy/cli/edit.py +327 -0
  21. honeybee_energy/cli/lib.py +1154 -0
  22. honeybee_energy/cli/result.py +810 -0
  23. honeybee_energy/cli/setconfig.py +124 -0
  24. honeybee_energy/cli/settings.py +569 -0
  25. honeybee_energy/cli/simulate.py +380 -0
  26. honeybee_energy/cli/translate.py +1714 -0
  27. honeybee_energy/cli/validate.py +224 -0
  28. honeybee_energy/config.json +11 -0
  29. honeybee_energy/config.py +842 -0
  30. honeybee_energy/construction/__init__.py +1 -0
  31. honeybee_energy/construction/_base.py +374 -0
  32. honeybee_energy/construction/air.py +325 -0
  33. honeybee_energy/construction/dictutil.py +89 -0
  34. honeybee_energy/construction/dynamic.py +607 -0
  35. honeybee_energy/construction/opaque.py +460 -0
  36. honeybee_energy/construction/shade.py +319 -0
  37. honeybee_energy/construction/window.py +1096 -0
  38. honeybee_energy/construction/windowshade.py +847 -0
  39. honeybee_energy/constructionset.py +1655 -0
  40. honeybee_energy/dictutil.py +56 -0
  41. honeybee_energy/generator/__init__.py +5 -0
  42. honeybee_energy/generator/loadcenter.py +204 -0
  43. honeybee_energy/generator/pv.py +535 -0
  44. honeybee_energy/hvac/__init__.py +21 -0
  45. honeybee_energy/hvac/_base.py +124 -0
  46. honeybee_energy/hvac/_template.py +270 -0
  47. honeybee_energy/hvac/allair/__init__.py +22 -0
  48. honeybee_energy/hvac/allair/_base.py +349 -0
  49. honeybee_energy/hvac/allair/furnace.py +168 -0
  50. honeybee_energy/hvac/allair/psz.py +131 -0
  51. honeybee_energy/hvac/allair/ptac.py +163 -0
  52. honeybee_energy/hvac/allair/pvav.py +109 -0
  53. honeybee_energy/hvac/allair/vav.py +128 -0
  54. honeybee_energy/hvac/detailed.py +337 -0
  55. honeybee_energy/hvac/doas/__init__.py +28 -0
  56. honeybee_energy/hvac/doas/_base.py +345 -0
  57. honeybee_energy/hvac/doas/fcu.py +127 -0
  58. honeybee_energy/hvac/doas/radiant.py +329 -0
  59. honeybee_energy/hvac/doas/vrf.py +81 -0
  60. honeybee_energy/hvac/doas/wshp.py +91 -0
  61. honeybee_energy/hvac/heatcool/__init__.py +23 -0
  62. honeybee_energy/hvac/heatcool/_base.py +177 -0
  63. honeybee_energy/hvac/heatcool/baseboard.py +61 -0
  64. honeybee_energy/hvac/heatcool/evapcool.py +72 -0
  65. honeybee_energy/hvac/heatcool/fcu.py +92 -0
  66. honeybee_energy/hvac/heatcool/gasunit.py +53 -0
  67. honeybee_energy/hvac/heatcool/radiant.py +269 -0
  68. honeybee_energy/hvac/heatcool/residential.py +77 -0
  69. honeybee_energy/hvac/heatcool/vrf.py +54 -0
  70. honeybee_energy/hvac/heatcool/windowac.py +70 -0
  71. honeybee_energy/hvac/heatcool/wshp.py +62 -0
  72. honeybee_energy/hvac/idealair.py +699 -0
  73. honeybee_energy/internalmass.py +310 -0
  74. honeybee_energy/lib/__init__.py +1 -0
  75. honeybee_energy/lib/_loadconstructions.py +194 -0
  76. honeybee_energy/lib/_loadconstructionsets.py +117 -0
  77. honeybee_energy/lib/_loadmaterials.py +83 -0
  78. honeybee_energy/lib/_loadprogramtypes.py +125 -0
  79. honeybee_energy/lib/_loadschedules.py +87 -0
  80. honeybee_energy/lib/_loadtypelimits.py +64 -0
  81. honeybee_energy/lib/constructions.py +207 -0
  82. honeybee_energy/lib/constructionsets.py +95 -0
  83. honeybee_energy/lib/materials.py +67 -0
  84. honeybee_energy/lib/programtypes.py +125 -0
  85. honeybee_energy/lib/schedules.py +61 -0
  86. honeybee_energy/lib/scheduletypelimits.py +31 -0
  87. honeybee_energy/load/__init__.py +1 -0
  88. honeybee_energy/load/_base.py +190 -0
  89. honeybee_energy/load/daylight.py +397 -0
  90. honeybee_energy/load/dictutil.py +47 -0
  91. honeybee_energy/load/equipment.py +771 -0
  92. honeybee_energy/load/hotwater.py +543 -0
  93. honeybee_energy/load/infiltration.py +460 -0
  94. honeybee_energy/load/lighting.py +480 -0
  95. honeybee_energy/load/people.py +497 -0
  96. honeybee_energy/load/process.py +472 -0
  97. honeybee_energy/load/setpoint.py +816 -0
  98. honeybee_energy/load/ventilation.py +550 -0
  99. honeybee_energy/material/__init__.py +1 -0
  100. honeybee_energy/material/_base.py +166 -0
  101. honeybee_energy/material/dictutil.py +59 -0
  102. honeybee_energy/material/frame.py +367 -0
  103. honeybee_energy/material/gas.py +1087 -0
  104. honeybee_energy/material/glazing.py +854 -0
  105. honeybee_energy/material/opaque.py +1351 -0
  106. honeybee_energy/material/shade.py +1360 -0
  107. honeybee_energy/measure.py +472 -0
  108. honeybee_energy/programtype.py +723 -0
  109. honeybee_energy/properties/__init__.py +1 -0
  110. honeybee_energy/properties/aperture.py +333 -0
  111. honeybee_energy/properties/door.py +342 -0
  112. honeybee_energy/properties/extension.py +244 -0
  113. honeybee_energy/properties/face.py +274 -0
  114. honeybee_energy/properties/model.py +2640 -0
  115. honeybee_energy/properties/room.py +1747 -0
  116. honeybee_energy/properties/shade.py +314 -0
  117. honeybee_energy/properties/shademesh.py +262 -0
  118. honeybee_energy/reader.py +48 -0
  119. honeybee_energy/result/__init__.py +1 -0
  120. honeybee_energy/result/colorobj.py +648 -0
  121. honeybee_energy/result/emissions.py +290 -0
  122. honeybee_energy/result/err.py +101 -0
  123. honeybee_energy/result/eui.py +100 -0
  124. honeybee_energy/result/generation.py +160 -0
  125. honeybee_energy/result/loadbalance.py +890 -0
  126. honeybee_energy/result/match.py +202 -0
  127. honeybee_energy/result/osw.py +90 -0
  128. honeybee_energy/result/rdd.py +59 -0
  129. honeybee_energy/result/zsz.py +190 -0
  130. honeybee_energy/run.py +1577 -0
  131. honeybee_energy/schedule/__init__.py +1 -0
  132. honeybee_energy/schedule/day.py +626 -0
  133. honeybee_energy/schedule/dictutil.py +59 -0
  134. honeybee_energy/schedule/fixedinterval.py +1012 -0
  135. honeybee_energy/schedule/rule.py +619 -0
  136. honeybee_energy/schedule/ruleset.py +1867 -0
  137. honeybee_energy/schedule/typelimit.py +310 -0
  138. honeybee_energy/shw.py +315 -0
  139. honeybee_energy/simulation/__init__.py +1 -0
  140. honeybee_energy/simulation/control.py +214 -0
  141. honeybee_energy/simulation/daylightsaving.py +185 -0
  142. honeybee_energy/simulation/dictutil.py +51 -0
  143. honeybee_energy/simulation/output.py +646 -0
  144. honeybee_energy/simulation/parameter.py +606 -0
  145. honeybee_energy/simulation/runperiod.py +443 -0
  146. honeybee_energy/simulation/shadowcalculation.py +295 -0
  147. honeybee_energy/simulation/sizing.py +546 -0
  148. honeybee_energy/ventcool/__init__.py +5 -0
  149. honeybee_energy/ventcool/_crack_data.py +91 -0
  150. honeybee_energy/ventcool/afn.py +289 -0
  151. honeybee_energy/ventcool/control.py +269 -0
  152. honeybee_energy/ventcool/crack.py +126 -0
  153. honeybee_energy/ventcool/fan.py +493 -0
  154. honeybee_energy/ventcool/opening.py +365 -0
  155. honeybee_energy/ventcool/simulation.py +314 -0
  156. honeybee_energy/writer.py +1078 -0
  157. honeybee_energy-1.116.106.dist-info/METADATA +113 -0
  158. honeybee_energy-1.116.106.dist-info/RECORD +162 -0
  159. honeybee_energy-1.116.106.dist-info/WHEEL +5 -0
  160. honeybee_energy-1.116.106.dist-info/entry_points.txt +2 -0
  161. honeybee_energy-1.116.106.dist-info/licenses/LICENSE +661 -0
  162. honeybee_energy-1.116.106.dist-info/top_level.txt +1 -0
@@ -0,0 +1,854 @@
1
+ # coding=utf-8
2
+ """Glazing materials representing panes of glass within window constructions.
3
+
4
+ They can exist anywhere within a window construction as long as they are not adjacent
5
+ to other glazing materials.
6
+ The one exception to this is the EnergyWindowMaterialSimpleGlazSys, which is meant to
7
+ represent an entire window assembly (including glazing, gaps, and frame), and
8
+ therefore must be the only material in its parent construction.
9
+ """
10
+ from __future__ import division
11
+ import math
12
+
13
+ from ._base import _EnergyMaterialWindowBase
14
+ from ..properties.extension import (
15
+ EnergyWindowMaterialGlazingsProperties,
16
+ EnergyWindowMaterialSimpleGlazSysProperties,
17
+ )
18
+ from ..reader import parse_idf_string
19
+ from ..writer import generate_idf_string
20
+
21
+ from honeybee._lockable import lockable
22
+ from honeybee.typing import float_in_range, float_positive
23
+ from honeybee.altnumber import autocalculate
24
+
25
+
26
+ @lockable
27
+ class _EnergyWindowMaterialGlazingBase(_EnergyMaterialWindowBase):
28
+ """Base for all glazing layers."""
29
+ __slots__ = ()
30
+
31
+ @property
32
+ def is_glazing_material(self):
33
+ """Boolean to note whether the material is a glazing layer."""
34
+ return True
35
+
36
+
37
+ @lockable
38
+ class EnergyWindowMaterialGlazing(_EnergyWindowMaterialGlazingBase):
39
+ """A single glass pane corresponding to a layer in a window construction.
40
+
41
+ Args:
42
+ identifier: Text string for a unique Material ID. Must be < 100 characters
43
+ and not contain any EnergyPlus special characters. This will be used to
44
+ identify the object across a model and in the exported IDF.
45
+ thickness: Number for the thickness of the glass layer [m].
46
+ Default: 0.003 meters (3 mm).
47
+ solar_transmittance: Number between 0 and 1 for the transmittance of solar
48
+ radiation through the glass at normal incidence.
49
+ Default: 0.85 for clear glass.
50
+ solar_reflectance: Number between 0 and 1 for the reflectance of solar
51
+ radiation off of the front side of the glass at normal incidence,
52
+ averaged over the solar spectrum. Default: 0.075.
53
+ visible_transmittance: Number between 0 and 1 for the transmittance of
54
+ visible light through the glass at normal incidence.
55
+ Default: 0.9 for clear glass.
56
+ visible_reflectance: Number between 0 and 1 for the reflectance of
57
+ visible light off of the front side of the glass at normal incidence.
58
+ Default: 0.075.
59
+ infrared_transmittance: Long-wave transmittance of the glass at normal
60
+ incidence. Default: 0.
61
+ emissivity: Number between 0 and 1 for the infrared hemispherical
62
+ emissivity of the front side of the glass. Default: 0.84, which
63
+ is typical of clear glass.
64
+ emissivity_back: Number between 0 and 1 for the infrared hemispherical
65
+ emissivity of the back side of the glass. Default: 0.84, which
66
+ is typical of clear glass.
67
+ conductivity: Number for the thermal conductivity of the glass [W/m-K].
68
+ Default: 0.9.
69
+
70
+ Properties:
71
+ * identifier
72
+ * display_name
73
+ * thickness
74
+ * solar_transmittance
75
+ * solar_reflectance
76
+ * solar_reflectance_back
77
+ * visible_transmittance
78
+ * visible_reflectance
79
+ * visible_reflectance_back
80
+ * infrared_transmittance
81
+ * emissivity
82
+ * emissivity_back
83
+ * conductivity
84
+ * dirt_correction
85
+ * solar_diffusing
86
+ * resistivity
87
+ * u_value
88
+ * r_value
89
+ * solar_absorptance
90
+ * visible_absorptance
91
+ * solar_transmissivity
92
+ * visible_transmissivity
93
+ * user_data
94
+ * properties
95
+ """
96
+ __slots__ = ('_thickness', '_solar_transmittance', '_solar_reflectance',
97
+ '_solar_reflectance_back', '_visible_transmittance',
98
+ '_visible_reflectance', '_visible_reflectance_back',
99
+ '_infrared_transmittance', '_emissivity', '_emissivity_back',
100
+ '_conductivity', '_dirt_correction', '_dirt_correction',
101
+ '_solar_diffusing')
102
+
103
+ def __init__(self, identifier, thickness=0.003, solar_transmittance=0.85,
104
+ solar_reflectance=0.075, visible_transmittance=0.9,
105
+ visible_reflectance=0.075, infrared_transmittance=0,
106
+ emissivity=0.84, emissivity_back=0.84, conductivity=0.9):
107
+ """Initialize energy window material glazing."""
108
+ _EnergyWindowMaterialGlazingBase.__init__(self, identifier)
109
+
110
+ # default values for checking transmittance + reflectance < 1
111
+ self._solar_reflectance = 0
112
+ self._solar_reflectance_back = None
113
+ self._visible_reflectance = 0
114
+ self._visible_reflectance_back = None
115
+
116
+ # assign the specified properties from __init__
117
+ self.thickness = thickness
118
+ self.solar_transmittance = solar_transmittance
119
+ self.solar_reflectance = solar_reflectance
120
+ self.visible_transmittance = visible_transmittance
121
+ self.visible_reflectance = visible_reflectance
122
+ self.infrared_transmittance = infrared_transmittance
123
+ self.emissivity = emissivity
124
+ self.emissivity_back = emissivity_back
125
+ self.conductivity = conductivity
126
+ self.dirt_correction = 1.0
127
+ self.solar_diffusing = False
128
+ self._properties = EnergyWindowMaterialGlazingsProperties(self)
129
+
130
+ @property
131
+ def thickness(self):
132
+ """Get or set the thickness of the glass material layer [m]."""
133
+ return self._thickness
134
+
135
+ @thickness.setter
136
+ def thickness(self, thick):
137
+ self._thickness = float_positive(thick, 'glazing material thickness')
138
+ assert self._thickness != 0, 'Material thickness must be greater than zero.'
139
+
140
+ @property
141
+ def solar_transmittance(self):
142
+ """Get or set the solar transmittance of the glass at normal incidence."""
143
+ return self._solar_transmittance
144
+
145
+ @solar_transmittance.setter
146
+ def solar_transmittance(self, s_tr):
147
+ s_tr = float_in_range(s_tr, 0.0, 1.0, 'glazing material solar transmittance')
148
+ assert s_tr + self._solar_reflectance <= 1, 'Sum of window transmittance and ' \
149
+ 'reflectance ({}) is greater than 1.'.format(s_tr + self._solar_reflectance)
150
+ if self._solar_reflectance_back is not None:
151
+ assert s_tr + self._solar_reflectance_back <= 1, 'Sum of window ' \
152
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
153
+ s_tr + self._solar_reflectance_back)
154
+ self._solar_transmittance = s_tr
155
+
156
+ @property
157
+ def solar_reflectance(self):
158
+ """Get or set the front solar reflectance of the glass at normal incidence."""
159
+ return self._solar_reflectance
160
+
161
+ @solar_reflectance.setter
162
+ def solar_reflectance(self, s_ref):
163
+ s_ref = float_in_range(s_ref, 0.0, 1.0, 'glazing material solar reflectance')
164
+ assert s_ref + self._solar_transmittance <= 1, 'Sum of window transmittance ' \
165
+ 'and reflectance ({}) is greater than 1.'.format(
166
+ s_ref + self._solar_transmittance)
167
+ self._solar_reflectance = s_ref
168
+
169
+ @property
170
+ def solar_reflectance_back(self):
171
+ """Get or set the back solar reflectance of the glass at normal incidence."""
172
+ return self._solar_reflectance_back if self._solar_reflectance_back is not None \
173
+ else self._solar_reflectance
174
+
175
+ @solar_reflectance_back.setter
176
+ def solar_reflectance_back(self, s_ref):
177
+ if s_ref is not None:
178
+ s_ref = float_in_range(s_ref, 0.0, 1.0, 'glazing material solar reflectance')
179
+ assert s_ref + self._solar_transmittance <= 1, 'Sum of window ' \
180
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
181
+ s_ref + self._solar_transmittance)
182
+ self._solar_reflectance_back = s_ref
183
+
184
+ @property
185
+ def visible_transmittance(self):
186
+ """Get or set the visible transmittance of the glass at normal incidence."""
187
+ return self._visible_transmittance
188
+
189
+ @visible_transmittance.setter
190
+ def visible_transmittance(self, v_tr):
191
+ v_tr = float_in_range(v_tr, 0.0, 1.0, 'glazing material visible transmittance')
192
+ assert v_tr + self._visible_reflectance <= 1, 'Sum of window transmittance ' \
193
+ 'and reflectance ({}) is greater than 1.'.format(
194
+ v_tr + self._visible_reflectance)
195
+ if self._visible_reflectance_back is not None:
196
+ assert v_tr + self._visible_reflectance_back <= 1, 'Sum of window ' \
197
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
198
+ v_tr + self._visible_reflectance_back)
199
+ self._visible_transmittance = v_tr
200
+
201
+ @property
202
+ def visible_reflectance(self):
203
+ """Get or set the front visible reflectance of the glass at normal incidence."""
204
+ return self._visible_reflectance
205
+
206
+ @visible_reflectance.setter
207
+ def visible_reflectance(self, v_ref):
208
+ v_ref = float_in_range(v_ref, 0.0, 1.0, 'glazing material visible reflectance')
209
+ assert v_ref + self._visible_transmittance <= 1, 'Sum of window transmittance ' \
210
+ 'and reflectance ({}) is greater than 1.'.format(
211
+ v_ref + self._visible_transmittance)
212
+ self._visible_reflectance = v_ref
213
+
214
+ @property
215
+ def visible_reflectance_back(self):
216
+ """Get or set the back visible reflectance of the glass at normal incidence."""
217
+ return self._visible_reflectance_back if self._visible_reflectance_back \
218
+ is not None else self._visible_reflectance
219
+
220
+ @visible_reflectance_back.setter
221
+ def visible_reflectance_back(self, v_ref):
222
+ if v_ref is not None:
223
+ v_ref = float_in_range(v_ref, 0.0, 1.0,
224
+ 'glazing material visible reflectance')
225
+ assert v_ref + self._visible_transmittance <= 1, 'Sum of window ' \
226
+ 'transmittance and reflectance ({}) is greater than 1.'.format(
227
+ v_ref + self._visible_transmittance)
228
+ self._visible_reflectance_back = v_ref
229
+
230
+ @property
231
+ def infrared_transmittance(self):
232
+ """Get or set the infrared transmittance of the glass at normal incidence."""
233
+ return self._infrared_transmittance
234
+
235
+ @infrared_transmittance.setter
236
+ def infrared_transmittance(self, ir_tr):
237
+ self._infrared_transmittance = float_in_range(
238
+ ir_tr, 0.0, 1.0, 'glazing material infrared transmittance')
239
+
240
+ @property
241
+ def emissivity(self):
242
+ """Get or set the hemispherical emissivity of the front side of the glass."""
243
+ return self._emissivity
244
+
245
+ @emissivity.setter
246
+ def emissivity(self, ir_e):
247
+ ir_e = float_in_range(ir_e, 0.0, 1.0, 'glazing material emissivity')
248
+ self._emissivity = ir_e
249
+
250
+ @property
251
+ def emissivity_back(self):
252
+ """Get or set the hemispherical emissivity of the back side of the glass."""
253
+ return self._emissivity_back if self._emissivity_back is not None \
254
+ else self._emissivity
255
+
256
+ @emissivity_back.setter
257
+ def emissivity_back(self, ir_e):
258
+ if ir_e is not None:
259
+ ir_e = float_in_range(ir_e, 0.0, 1.0, 'glazing material emissivity')
260
+ self._emissivity_back = ir_e
261
+
262
+ @property
263
+ def conductivity(self):
264
+ """Get or set the conductivity of the glazing layer [W/m-K]."""
265
+ return self._conductivity
266
+
267
+ @conductivity.setter
268
+ def conductivity(self, cond):
269
+ self._conductivity = float_positive(cond, 'glazing material conductivity')
270
+
271
+ @property
272
+ def dirt_correction(self):
273
+ """Get or set the hemispherical emissivity of the back side of the glass."""
274
+ return self._dirt_correction
275
+
276
+ @dirt_correction.setter
277
+ def dirt_correction(self, dirt):
278
+ self._dirt_correction = float_in_range(
279
+ dirt, 0.0, 1.0, 'glazing material dirt correction')
280
+
281
+ @property
282
+ def solar_diffusing(self):
283
+ """Get or set the solar diffusing property of the glass."""
284
+ return self._solar_diffusing
285
+
286
+ @solar_diffusing.setter
287
+ def solar_diffusing(self, s_diff):
288
+ self._solar_diffusing = bool(s_diff)
289
+
290
+ @property
291
+ def resistivity(self):
292
+ """Get or set the resistivity of the glazing layer [m-K/W]."""
293
+ return 1 / self._conductivity
294
+
295
+ @resistivity.setter
296
+ def resistivity(self, resis):
297
+ self._conductivity = 1 / float_positive(resis, 'glazing material resistivity')
298
+
299
+ @property
300
+ def u_value(self):
301
+ """Get or set the U-value of the material layer [W/m2-K] (excluding air films).
302
+
303
+ Note that, when setting the R-value, the thickness of the material will
304
+ remain fixed and only the conductivity will be adjusted.
305
+ """
306
+ return self.conductivity / self.thickness
307
+
308
+ @u_value.setter
309
+ def u_value(self, u_val):
310
+ self.r_value = 1 / float_positive(u_val, 'glazing material u-value')
311
+
312
+ @property
313
+ def r_value(self):
314
+ """Get or set the R-value of the material [m2-K/W] (excluding air films).
315
+
316
+ Note that, when setting the R-value, the thickness of the material will
317
+ remain fixed and only the conductivity will be adjusted.
318
+ """
319
+ return self.thickness / self.conductivity
320
+
321
+ @r_value.setter
322
+ def r_value(self, r_val):
323
+ self._conductivity = self.thickness / \
324
+ float_positive(r_val, 'glazing material r-value')
325
+
326
+ @property
327
+ def solar_absorptance(self):
328
+ """Get the solar absorptance of the glass at normal incidence."""
329
+ return 1 - self.solar_transmittance - self.solar_reflectance
330
+
331
+ @property
332
+ def visible_absorptance(self):
333
+ """Get the visible absorptance of the glass at normal incidence."""
334
+ return 1 - self.visible_transmittance - self.visible_reflectance
335
+
336
+ @property
337
+ def solar_transmissivity(self):
338
+ """Get the solar transmissivity of the glass at normal incidence."""
339
+ return self._transmissivity_from_transmittance(self._solar_transmittance)
340
+
341
+ @property
342
+ def visible_transmissivity(self):
343
+ """Get the visible transmissivity of the glass at normal incidence."""
344
+ return self._transmissivity_from_transmittance(self._visible_transmittance)
345
+
346
+ @classmethod
347
+ def from_idf(cls, idf_string):
348
+ """Create EnergyWindowMaterialGlazing from an EnergyPlus text string.
349
+
350
+ Args:
351
+ idf_string: A text string fully describing an EnergyPlus material.
352
+ """
353
+ ep_s = parse_idf_string(idf_string, 'WindowMaterial:Glazing,')
354
+ idf_defaults = {10: 0, 11: 0.84, 12: 0.84, 13: 0.9, 14: 1.0, 15: 'No'}
355
+ for i, ep_str in enumerate(ep_s): # fill in any default values
356
+ if ep_str == '' and i in idf_defaults:
357
+ ep_s[i] = idf_defaults[i]
358
+
359
+ assert ep_s[1] == 'SpectralAverage', \
360
+ 'Expected SpectralAverage glazing type. Got {}.'.format(ep_s[1])
361
+ new_mat = cls(ep_s[0], ep_s[3], ep_s[4], ep_s[5], ep_s[7], ep_s[8],
362
+ ep_s[10], ep_s[11], ep_s[12], ep_s[13])
363
+ new_mat.solar_reflectance_back = ep_s[6]
364
+ new_mat.visible_reflectance_back = ep_s[9]
365
+ new_mat.dirt_correction = ep_s[14] if len(ep_s) > 14 else 1.0
366
+ if len(ep_s) > 15:
367
+ new_mat.solar_diffusing = False if ep_s[15] == 'No' else True
368
+ return new_mat
369
+
370
+ @classmethod
371
+ def from_dict(cls, data):
372
+ """Create a EnergyWindowMaterialGlazing from a dictionary.
373
+
374
+ Args:
375
+ data: A python dictionary in the following format
376
+
377
+ .. code-block:: python
378
+
379
+ {
380
+ "type": 'EnergyWindowMaterialGlazing',
381
+ "identifier": 'Lowe_Glazing_00030_045_090',
382
+ "display_name": 'Low-e Glazing',
383
+ "thickness": 0.003,
384
+ "solar_transmittance": 0.45,
385
+ "solar_reflectance": 0.36,
386
+ "visible_transmittance": 0.714,
387
+ "visible_reflectance": 0.207,
388
+ "infrared_transmittance": 0,
389
+ "emissivity": 0.84,
390
+ "emissivity_back": 0.0466,
391
+ "conductivity": 0.9
392
+ }
393
+ """
394
+ assert data['type'] == 'EnergyWindowMaterialGlazing', \
395
+ 'Expected EnergyWindowMaterialGlazing. Got {}.'.format(data['type'])
396
+
397
+ thick = data['thickness'] if 'thickness' in data and data['thickness'] \
398
+ is not None else 0.003
399
+ t_sol = data['solar_transmittance'] if 'solar_transmittance' in data and \
400
+ data['solar_transmittance'] is not None else 0.85
401
+ r_sol = data['solar_reflectance'] if 'solar_reflectance' in data and \
402
+ data['solar_reflectance'] is not None else 0.075
403
+ r_sol_b = data['solar_reflectance_back'] if 'solar_reflectance_back' \
404
+ in data and data['solar_reflectance_back'] != autocalculate.to_dict() \
405
+ else None
406
+ t_vis = data['visible_transmittance'] if 'visible_transmittance' in data and \
407
+ data['visible_transmittance'] is not None else 0.9
408
+ r_vis = data['visible_reflectance'] if 'visible_reflectance' in data and \
409
+ data['visible_reflectance'] is not None else 0.075
410
+ r_vis_b = data['visible_reflectance_back'] if 'visible_reflectance_back' \
411
+ in data and data['visible_reflectance_back'] != autocalculate.to_dict() \
412
+ else None
413
+ t_inf = data['infrared_transmittance'] if 'infrared_transmittance' in data and \
414
+ data['infrared_transmittance'] is not None else 0.0
415
+ emis = data['emissivity'] if 'emissivity' in data and \
416
+ data['emissivity'] is not None else 0.84
417
+ emis_b = data['emissivity_back'] if 'emissivity_back' in data and \
418
+ data['emissivity_back'] is not None else 0.84
419
+ cond = data['conductivity'] if 'conductivity' in data and \
420
+ data['conductivity'] is not None else 0.9
421
+ dirt = data['dirt_correction'] if 'dirt_correction' in data and \
422
+ data['dirt_correction'] is not None else 1.0
423
+ sol_diff = data['solar_diffusing'] if 'solar_diffusing' in data and \
424
+ data['solar_diffusing'] is not None else False
425
+
426
+ new_mat = cls(data['identifier'], thick, t_sol, r_sol, t_vis, r_vis,
427
+ t_inf, emis, emis_b, cond)
428
+ new_mat.solar_reflectance_back = r_sol_b
429
+ new_mat.visible_reflectance_back = r_vis_b
430
+ new_mat.dirt_correction = dirt
431
+ new_mat.solar_diffusing = sol_diff
432
+ if 'display_name' in data and data['display_name'] is not None:
433
+ new_mat.display_name = data['display_name']
434
+ if 'user_data' in data and data['user_data'] is not None:
435
+ new_mat.user_data = data['user_data']
436
+ if 'properties' in data and data['properties'] is not None:
437
+ new_mat._properties._load_extension_attr_from_dict(data['properties'])
438
+ return new_mat
439
+
440
+ def to_idf(self):
441
+ """Get an EnergyPlus string representation of the material.
442
+
443
+ .. code-block:: shell
444
+
445
+ WindowMaterial:Glazing,
446
+ CLEAR 3MM, !- Name
447
+ SpectralAverage, !- Optical Data Type
448
+ , !- Window Glass Spectral Data Set Name
449
+ 0.003, !- Thickness {m}
450
+ 0.837, !- Solar Transmittance at Normal Incidence
451
+ 0.075, !- Front Side Solar Reflectance at Normal Incidence
452
+ 0.075, !- Back Side Solar Reflectance at Normal Incidence
453
+ 0.898, !- Visible Transmittance at Normal Incidence
454
+ 0.081, !- Front Side Visible Reflectance at Normal Incidence
455
+ 0.081, !- Back Side Visible Reflectance at Normal Incidence
456
+ 0.0, !- Infrared Transmittance at Normal Incidence
457
+ 0.84, !- Front Side Infrared Hemispherical Emissivity
458
+ 0.84, !- Back Side Infrared Hemispherical Emissivity
459
+ 0.9, !- Conductivity {W/m-K}
460
+ 0.54, !- Dirt Correction Factor
461
+ 0.09; !- Solar Diffusing
462
+ """
463
+ solar_diffusing = 'Yes' if self.solar_diffusing is True else 'No'
464
+ values = (self.identifier, 'SpectralAverage', '',
465
+ self.thickness, self.solar_transmittance,
466
+ self.solar_reflectance, self.solar_reflectance_back,
467
+ self.visible_transmittance, self.visible_reflectance,
468
+ self.visible_reflectance_back, self.infrared_transmittance,
469
+ self.emissivity, self.emissivity_back, self.conductivity,
470
+ self.dirt_correction, solar_diffusing)
471
+ comments = ('name', 'optical data type', 'spectral data set name',
472
+ 'thickness {m}', 'solar transmittance', 'solar reflectance front',
473
+ 'solar reflectance back', 'visible transmittance',
474
+ 'visible reflectance front', 'visible reflectance back',
475
+ 'infrared_transmittance', 'emissivity front', 'emissivity back',
476
+ 'conductivity {W/m-K}', 'dirt correction factor',
477
+ 'solar diffusing')
478
+ return generate_idf_string('WindowMaterial:Glazing', values, comments)
479
+
480
+ def to_dict(self):
481
+ """Energy Window Material Glazing dictionary representation."""
482
+ base = {
483
+ 'type': 'EnergyWindowMaterialGlazing',
484
+ 'identifier': self.identifier,
485
+ 'thickness': self.thickness,
486
+ 'solar_transmittance': self.solar_transmittance,
487
+ 'solar_reflectance': self.solar_reflectance,
488
+ 'solar_reflectance_back': self.solar_reflectance_back,
489
+ 'visible_transmittance': self.visible_transmittance,
490
+ 'visible_reflectance': self.visible_reflectance,
491
+ 'visible_reflectance_back': self.visible_reflectance_back,
492
+ 'infrared_transmittance': self.infrared_transmittance,
493
+ 'emissivity': self.emissivity,
494
+ 'emissivity_back': self.emissivity_back,
495
+ 'conductivity': self.conductivity,
496
+ 'dirt_correction': self.dirt_correction,
497
+ 'solar_diffusing': self.solar_diffusing
498
+ }
499
+ if self._display_name is not None:
500
+ base['display_name'] = self.display_name
501
+ if self._user_data is not None:
502
+ base['user_data'] = self.user_data
503
+ prop_dict = self._properties.to_dict()
504
+ if prop_dict is not None:
505
+ base['properties'] = prop_dict
506
+ return base
507
+
508
+ @staticmethod
509
+ def _transmissivity_from_transmittance(transmittance):
510
+ """Get transmissivity from a transmittance value"""
511
+ try:
512
+ return (math.sqrt(0.8402528435 + 0.0072522239 * (transmittance ** 2)) -
513
+ 0.9166530661) / 0.0036261119 / transmittance
514
+ except ZeroDivisionError:
515
+ return 0
516
+
517
+ def __key(self):
518
+ """A tuple based on the object properties, useful for hashing."""
519
+ return (self.identifier, self.thickness, self.solar_transmittance,
520
+ self.solar_reflectance, self.solar_reflectance_back,
521
+ self.visible_transmittance, self.visible_reflectance,
522
+ self.visible_reflectance_back, self.infrared_transmittance,
523
+ self.emissivity, self.emissivity_back, self.conductivity,
524
+ self.dirt_correction, self.solar_diffusing)
525
+
526
+ def __hash__(self):
527
+ return hash(self.__key())
528
+
529
+ def __eq__(self, other):
530
+ return isinstance(other, EnergyWindowMaterialGlazing) and \
531
+ self.__key() == other.__key()
532
+
533
+ def __ne__(self, other):
534
+ return not self.__eq__(other)
535
+
536
+ def __repr__(self):
537
+ return self.to_idf()
538
+
539
+ def __copy__(self):
540
+ new_material = EnergyWindowMaterialGlazing(
541
+ self.identifier, self.thickness, self.solar_transmittance,
542
+ self.solar_reflectance, self.visible_transmittance, self.visible_reflectance,
543
+ self.infrared_transmittance, self.emissivity, self._emissivity_back,
544
+ self.conductivity)
545
+ new_material._solar_reflectance_back = self._solar_reflectance_back
546
+ new_material._visible_reflectance_back = self._visible_reflectance_back
547
+ new_material._dirt_correction = self._dirt_correction
548
+ new_material._solar_diffusing = self._solar_diffusing
549
+ new_material._display_name = self._display_name
550
+ new_material._user_data = None if self._user_data is None \
551
+ else self._user_data.copy()
552
+ new_material._properties._duplicate_extension_attr(self._properties)
553
+ return new_material
554
+
555
+
556
+ @lockable
557
+ class EnergyWindowMaterialSimpleGlazSys(_EnergyWindowMaterialGlazingBase):
558
+ """A material to describe an entire glazing system, including glass, gaps, and frame.
559
+
560
+ Args:
561
+ identifier: Text string for a unique Material ID. Must be < 100 characters
562
+ and not contain any EnergyPlus special characters. This will be used to
563
+ identify the object across a model and in the exported IDF.
564
+ u_factor: A number for the U-factor of the glazing system [W/m2-K]
565
+ including standard air gap resistances on either side of the system.
566
+ shgc: A number between 0 and 1 for the solar heat gain coefficient
567
+ of the glazing system. This includes both directly transmitted solar
568
+ heat as well as solar heat that is absorbed by the glazing system and
569
+ conducts towards the interior.
570
+ vt: A number between 0 and 1 for the visible transmittance of the
571
+ glazing system. Default: 0.6.
572
+
573
+ Properties:
574
+ * identifier
575
+ * display_name
576
+ * u_factor
577
+ * shgc
578
+ * vt
579
+ * r_factor
580
+ * u_value
581
+ * r_value
582
+ * solar_transmittance
583
+ * solar_reflectance
584
+ * solar_reflectance_back
585
+ * solar_absorptance
586
+ * visible_transmittance
587
+ * visible_reflectance
588
+ * visible_reflectance_back
589
+ * visible_absorptance
590
+ * thickness
591
+ * user_data
592
+ * properties
593
+ """
594
+ __slots__ = ('_u_factor', '_shgc', '_vt')
595
+
596
+ def __init__(self, identifier, u_factor, shgc, vt=0.6):
597
+ """Initialize energy window material simple glazing system."""
598
+ _EnergyWindowMaterialGlazingBase.__init__(self, identifier)
599
+ self.u_factor = u_factor
600
+ self.shgc = shgc
601
+ self.vt = vt
602
+ self._properties = EnergyWindowMaterialSimpleGlazSysProperties(self)
603
+
604
+ @property
605
+ def u_factor(self):
606
+ """Get or set the glazing system U-factor (including air film resistance)."""
607
+ return self._u_factor
608
+
609
+ @u_factor.setter
610
+ def u_factor(self, u_fac):
611
+ # NOTE: u-values above 5.8 are not realistic but 12 is the absolute hard limit
612
+ self._u_factor = float_in_range(u_fac, 0.0, 12, 'glazing material u-factor')
613
+
614
+ @property
615
+ def r_factor(self):
616
+ """Get or set the glazing system R-factor (including air film resistance)."""
617
+ return 1 / self._u_factor
618
+
619
+ @r_factor.setter
620
+ def r_factor(self, r_fac):
621
+ self._u_factor = 1 / float_positive(r_fac, 'glazing material r-factor')
622
+
623
+ @property
624
+ def shgc(self):
625
+ """Get or set the glazing system solar heat gain coefficient (SHGC)."""
626
+ return self._shgc
627
+
628
+ @shgc.setter
629
+ def shgc(self, sc):
630
+ self._shgc = float_in_range(sc, 0.0, 1.0, 'glazing material shgc')
631
+
632
+ @property
633
+ def vt(self):
634
+ """Get or set the visible transmittance."""
635
+ return self._vt
636
+
637
+ @vt.setter
638
+ def vt(self, vt):
639
+ self._vt = float_in_range(vt, 0.0, 1.0, 'glazing material visible transmittance')
640
+
641
+ @property
642
+ def u_value(self):
643
+ """U-value of the material layer [W/m2-K] (excluding air film resistance).
644
+
645
+ This is the U-value of glazing system material layer as understood by EnergyPlus.
646
+ """
647
+ return 1 / self.r_value
648
+
649
+ @property
650
+ def r_value(self):
651
+ """R-value of the material layer [m2-K/W] (excluding air film resistance).
652
+
653
+ This is the R-value of glazing system as understood by EnergyPlus.
654
+ """
655
+ out_r = 1 / ((0.025342 * self._u_factor) + 29.163853)
656
+ in_r = 1 / ((0.359073 * math.log(self._u_factor)) + 6.949915) \
657
+ if self._u_factor < 5.85 else \
658
+ 1 / ((1.788041 * self._u_factor) - 2.886625)
659
+ return (1 / self.u_factor) - out_r - in_r
660
+
661
+ @property
662
+ def solar_transmittance(self):
663
+ """Get the solar transmittance of the glazing system at normal incidence."""
664
+ if self.u_factor > 3.4:
665
+ term_1 = (0.939998 * (self.shgc ** 2)) + (0.20332 * self.shgc) \
666
+ if self.shgc < 0.7206 else (1.30415 * self.shgc) - 0.30515
667
+ if self.u_factor < 4.5:
668
+ term_2 = (0.085775 * (self.shgc ** 2)) + (0.963954 * self.shgc) - 0.084958 \
669
+ if self.shgc > 0.15 else (0.4104 * self.shgc)
670
+ if self.u_factor >= 4.5:
671
+ return term_1
672
+ elif self.u_factor <= 3.4:
673
+ return term_2
674
+ else:
675
+ weight = (self.u_factor - 3.4) / 1.1
676
+ return (term_1 * weight) + (term_2 * (1 - weight))
677
+
678
+ @property
679
+ def solar_reflectance(self):
680
+ """Get the solar reflectance of the glazing system at normal incidence."""
681
+ # get values needed to compute the reflectance
682
+ t_sol, r_val = self.solar_transmittance, self.r_value
683
+ # determine the resistance of inside and outside air films
684
+ s_t = self.shgc - t_sol
685
+ if self.u_factor > 3.4:
686
+ term_1_is = 1 / ((29.436546 * (s_t ** 3)) - (21.943415 * (s_t ** 2)) +
687
+ (9.945872 * s_t) + 7.426151)
688
+ term_1_os = 1 / ((2.225824 * s_t) + 20.57708)
689
+ if self.u_factor < 4.5:
690
+ term_2_is = 1 / ((199.8208128 * (s_t ** 3)) - (90.639733 * (s_t ** 2)) +
691
+ (19.737055 * s_t) + 6.766575)
692
+ term_2_os = 1 / ((5.763355 * s_t) + 20.541528)
693
+ if self.u_factor >= 4.5:
694
+ r_is, r_os = term_1_is, term_1_os
695
+ elif self.u_factor <= 3.4:
696
+ r_is, r_os = term_2_is, term_2_os
697
+ else:
698
+ weight = (self.u_factor - 3.4) / 1.1
699
+ r_is = (term_1_is * weight) + (term_2_is * (1 - weight))
700
+ r_os = (term_1_os * weight) + (term_2_os * (1 - weight))
701
+ # compute the inward flowing fraction of solar heat and the reflectance
702
+ f_in = (r_os + (0.5 * r_val)) / (r_os + r_val + r_is)
703
+ return 1 - t_sol - ((self.shgc - t_sol) / f_in)
704
+
705
+ @property
706
+ def solar_reflectance_back(self):
707
+ """Get the solar reflectance of the glazing system at normal incidence."""
708
+ return self.solar_reflectance
709
+
710
+ @property
711
+ def solar_absorptance(self):
712
+ """Get the solar absorptance of the glazing system at normal incidence.
713
+
714
+ This is the solar absorptance as understood by EnergyPlus.
715
+ """
716
+ return 1 - self.solar_transmittance - self.solar_reflectance
717
+
718
+ @property
719
+ def visible_transmittance(self):
720
+ """Get the visible transmittance of the glazing system at normal incidence."""
721
+ return self.vt
722
+
723
+ @property
724
+ def visible_reflectance(self):
725
+ """Get the visible reflectance of the glazing system at normal incidence.
726
+
727
+ This is the visible reflectance as understood by EnergyPlus.
728
+ """
729
+ return (-0.0622 * (self.vt ** 3)) + (0.4277 * self.vt ** 2) - \
730
+ (0.4169 * self.vt) + 0.2399
731
+
732
+ @property
733
+ def visible_reflectance_back(self):
734
+ """Get the visible reflectance of the glazing system at normal incidence."""
735
+ return self.visible_reflectance
736
+
737
+ @property
738
+ def visible_absorptance(self):
739
+ """Get the visible absorptance of the glazing system at normal incidence.
740
+
741
+ This is the visible absorptance as understood by EnergyPlus.
742
+ """
743
+ return 1 - self.vt - self.visible_reflectance
744
+
745
+ @property
746
+ def thickness(self):
747
+ """Get the thickess of the glazing system as interpreted by EnergyPlus [m]."""
748
+ u_val = self.u_value
749
+ return 0.002 if u_val > 7 else (0.05914 - (0.00714 * u_val))
750
+
751
+ @classmethod
752
+ def from_idf(cls, idf_string):
753
+ """Create EnergyWindowMaterialSimpleGlazSys from an EnergyPlus text string.
754
+
755
+ Args:
756
+ idf_string: A text string fully describing an EnergyPlus material.
757
+ """
758
+ ep_strs = parse_idf_string(idf_string, 'WindowMaterial:SimpleGlazingSystem,')
759
+ if len(ep_strs) == 4 and ep_strs[3] == '':
760
+ ep_strs.pop(3)
761
+ glz_mat = cls(*ep_strs)
762
+ glz_mat.vt = glz_mat.solar_transmittance
763
+ return glz_mat
764
+ return cls(*ep_strs)
765
+
766
+ @classmethod
767
+ def from_dict(cls, data):
768
+ """Create a EnergyWindowMaterialSimpleGlazSys from a dictionary.
769
+
770
+ Args:
771
+ data: A python dictionary in the following format
772
+
773
+ .. code-block:: python
774
+
775
+ {
776
+ "type": 'EnergyWindowMaterialSimpleGlazSys',
777
+ "identifier": 'Double_Lowe_Glazing_200_040_060',
778
+ "display_name": 'Double Low-e Glazing System',
779
+ "u_factor": 2.0,
780
+ "shgc": 0.4,
781
+ "vt": 0.6
782
+ }
783
+ """
784
+ assert data['type'] == 'EnergyWindowMaterialSimpleGlazSys', \
785
+ 'Expected EnergyWindowMaterialSimpleGlazSys. Got {}.'.format(data['type'])
786
+ vt = 0.6 if 'vt' not in data else data['vt']
787
+ new_obj = cls(data['identifier'], data['u_factor'], data['shgc'], vt)
788
+ if 'display_name' in data and data['display_name'] is not None:
789
+ new_obj.display_name = data['display_name']
790
+ if 'user_data' in data and data['user_data'] is not None:
791
+ new_obj.user_data = data['user_data']
792
+ if 'properties' in data and data['properties'] is not None:
793
+ new_obj._properties._load_extension_attr_from_dict(data['properties'])
794
+ return new_obj
795
+
796
+ def to_idf(self):
797
+ """Get an EnergyPlus string representation of the material.
798
+
799
+ .. code-block:: shell
800
+
801
+ WindowMaterial:SimpleGlazingSystem,
802
+ SimpleWindow:DOUBLE PANE WINDOW , !- Name
803
+ 2.716 , !- U-Factor
804
+ 0.763 , !- Solar Heat Gain Coefficient
805
+ 0.812 ; !- Visible Transmittance
806
+ """
807
+ values = (self.identifier, self.u_factor, self.shgc, self.vt)
808
+ comments = ('name', 'u-factor {W/m2-K}', 'shgc', 'vt')
809
+ return generate_idf_string(
810
+ 'WindowMaterial:SimpleGlazingSystem', values, comments)
811
+
812
+ def to_dict(self):
813
+ """Energy Window Material Simple Glazing System dictionary representation."""
814
+ base = {
815
+ 'type': 'EnergyWindowMaterialSimpleGlazSys',
816
+ 'identifier': self.identifier,
817
+ 'u_factor': self.u_factor,
818
+ 'shgc': self.shgc,
819
+ 'vt': self.vt
820
+ }
821
+ if self._display_name is not None:
822
+ base['display_name'] = self.display_name
823
+ if self._user_data is not None:
824
+ base['user_data'] = self.user_data
825
+ prop_dict = self._properties.to_dict()
826
+ if prop_dict is not None:
827
+ base['properties'] = prop_dict
828
+ return base
829
+
830
+ def __key(self):
831
+ """A tuple based on the object properties, useful for hashing."""
832
+ return (self.identifier, self.u_factor, self.shgc, self.vt)
833
+
834
+ def __hash__(self):
835
+ return hash(self.__key())
836
+
837
+ def __eq__(self, other):
838
+ return isinstance(other, EnergyWindowMaterialSimpleGlazSys) and \
839
+ self.__key() == other.__key()
840
+
841
+ def __ne__(self, other):
842
+ return not self.__eq__(other)
843
+
844
+ def __repr__(self):
845
+ return self.to_idf()
846
+
847
+ def __copy__(self):
848
+ new_material = EnergyWindowMaterialSimpleGlazSys(
849
+ self.identifier, self.u_factor, self.shgc, self.vt)
850
+ new_material._display_name = self._display_name
851
+ new_material._user_data = None if self._user_data is None \
852
+ else self._user_data.copy()
853
+ new_material._properties._duplicate_extension_attr(self._properties)
854
+ return new_material