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.
- honeybee_energy/__init__.py +24 -0
- honeybee_energy/__main__.py +4 -0
- honeybee_energy/_extend_honeybee.py +145 -0
- honeybee_energy/altnumber.py +21 -0
- honeybee_energy/baseline/__init__.py +2 -0
- honeybee_energy/baseline/create.py +608 -0
- honeybee_energy/baseline/data/__init__.py +1 -0
- honeybee_energy/baseline/data/constructions.csv +64 -0
- honeybee_energy/baseline/data/fen_ratios.csv +15 -0
- honeybee_energy/baseline/data/lpd_building.csv +21 -0
- honeybee_energy/baseline/data/pci_2016.csv +22 -0
- honeybee_energy/baseline/data/pci_2019.csv +22 -0
- honeybee_energy/baseline/data/pci_2022.csv +22 -0
- honeybee_energy/baseline/data/shw.csv +21 -0
- honeybee_energy/baseline/pci.py +512 -0
- honeybee_energy/baseline/result.py +371 -0
- honeybee_energy/boundarycondition.py +128 -0
- honeybee_energy/cli/__init__.py +69 -0
- honeybee_energy/cli/baseline.py +475 -0
- honeybee_energy/cli/edit.py +327 -0
- honeybee_energy/cli/lib.py +1154 -0
- honeybee_energy/cli/result.py +810 -0
- honeybee_energy/cli/setconfig.py +124 -0
- honeybee_energy/cli/settings.py +569 -0
- honeybee_energy/cli/simulate.py +380 -0
- honeybee_energy/cli/translate.py +1714 -0
- honeybee_energy/cli/validate.py +224 -0
- honeybee_energy/config.json +11 -0
- honeybee_energy/config.py +842 -0
- honeybee_energy/construction/__init__.py +1 -0
- honeybee_energy/construction/_base.py +374 -0
- honeybee_energy/construction/air.py +325 -0
- honeybee_energy/construction/dictutil.py +89 -0
- honeybee_energy/construction/dynamic.py +607 -0
- honeybee_energy/construction/opaque.py +460 -0
- honeybee_energy/construction/shade.py +319 -0
- honeybee_energy/construction/window.py +1096 -0
- honeybee_energy/construction/windowshade.py +847 -0
- honeybee_energy/constructionset.py +1655 -0
- honeybee_energy/dictutil.py +56 -0
- honeybee_energy/generator/__init__.py +5 -0
- honeybee_energy/generator/loadcenter.py +204 -0
- honeybee_energy/generator/pv.py +535 -0
- honeybee_energy/hvac/__init__.py +21 -0
- honeybee_energy/hvac/_base.py +124 -0
- honeybee_energy/hvac/_template.py +270 -0
- honeybee_energy/hvac/allair/__init__.py +22 -0
- honeybee_energy/hvac/allair/_base.py +349 -0
- honeybee_energy/hvac/allair/furnace.py +168 -0
- honeybee_energy/hvac/allair/psz.py +131 -0
- honeybee_energy/hvac/allair/ptac.py +163 -0
- honeybee_energy/hvac/allair/pvav.py +109 -0
- honeybee_energy/hvac/allair/vav.py +128 -0
- honeybee_energy/hvac/detailed.py +337 -0
- honeybee_energy/hvac/doas/__init__.py +28 -0
- honeybee_energy/hvac/doas/_base.py +345 -0
- honeybee_energy/hvac/doas/fcu.py +127 -0
- honeybee_energy/hvac/doas/radiant.py +329 -0
- honeybee_energy/hvac/doas/vrf.py +81 -0
- honeybee_energy/hvac/doas/wshp.py +91 -0
- honeybee_energy/hvac/heatcool/__init__.py +23 -0
- honeybee_energy/hvac/heatcool/_base.py +177 -0
- honeybee_energy/hvac/heatcool/baseboard.py +61 -0
- honeybee_energy/hvac/heatcool/evapcool.py +72 -0
- honeybee_energy/hvac/heatcool/fcu.py +92 -0
- honeybee_energy/hvac/heatcool/gasunit.py +53 -0
- honeybee_energy/hvac/heatcool/radiant.py +269 -0
- honeybee_energy/hvac/heatcool/residential.py +77 -0
- honeybee_energy/hvac/heatcool/vrf.py +54 -0
- honeybee_energy/hvac/heatcool/windowac.py +70 -0
- honeybee_energy/hvac/heatcool/wshp.py +62 -0
- honeybee_energy/hvac/idealair.py +699 -0
- honeybee_energy/internalmass.py +310 -0
- honeybee_energy/lib/__init__.py +1 -0
- honeybee_energy/lib/_loadconstructions.py +194 -0
- honeybee_energy/lib/_loadconstructionsets.py +117 -0
- honeybee_energy/lib/_loadmaterials.py +83 -0
- honeybee_energy/lib/_loadprogramtypes.py +125 -0
- honeybee_energy/lib/_loadschedules.py +87 -0
- honeybee_energy/lib/_loadtypelimits.py +64 -0
- honeybee_energy/lib/constructions.py +207 -0
- honeybee_energy/lib/constructionsets.py +95 -0
- honeybee_energy/lib/materials.py +67 -0
- honeybee_energy/lib/programtypes.py +125 -0
- honeybee_energy/lib/schedules.py +61 -0
- honeybee_energy/lib/scheduletypelimits.py +31 -0
- honeybee_energy/load/__init__.py +1 -0
- honeybee_energy/load/_base.py +190 -0
- honeybee_energy/load/daylight.py +397 -0
- honeybee_energy/load/dictutil.py +47 -0
- honeybee_energy/load/equipment.py +771 -0
- honeybee_energy/load/hotwater.py +543 -0
- honeybee_energy/load/infiltration.py +460 -0
- honeybee_energy/load/lighting.py +480 -0
- honeybee_energy/load/people.py +497 -0
- honeybee_energy/load/process.py +472 -0
- honeybee_energy/load/setpoint.py +816 -0
- honeybee_energy/load/ventilation.py +550 -0
- honeybee_energy/material/__init__.py +1 -0
- honeybee_energy/material/_base.py +166 -0
- honeybee_energy/material/dictutil.py +59 -0
- honeybee_energy/material/frame.py +367 -0
- honeybee_energy/material/gas.py +1087 -0
- honeybee_energy/material/glazing.py +854 -0
- honeybee_energy/material/opaque.py +1351 -0
- honeybee_energy/material/shade.py +1360 -0
- honeybee_energy/measure.py +472 -0
- honeybee_energy/programtype.py +723 -0
- honeybee_energy/properties/__init__.py +1 -0
- honeybee_energy/properties/aperture.py +333 -0
- honeybee_energy/properties/door.py +342 -0
- honeybee_energy/properties/extension.py +244 -0
- honeybee_energy/properties/face.py +274 -0
- honeybee_energy/properties/model.py +2640 -0
- honeybee_energy/properties/room.py +1747 -0
- honeybee_energy/properties/shade.py +314 -0
- honeybee_energy/properties/shademesh.py +262 -0
- honeybee_energy/reader.py +48 -0
- honeybee_energy/result/__init__.py +1 -0
- honeybee_energy/result/colorobj.py +648 -0
- honeybee_energy/result/emissions.py +290 -0
- honeybee_energy/result/err.py +101 -0
- honeybee_energy/result/eui.py +100 -0
- honeybee_energy/result/generation.py +160 -0
- honeybee_energy/result/loadbalance.py +890 -0
- honeybee_energy/result/match.py +202 -0
- honeybee_energy/result/osw.py +90 -0
- honeybee_energy/result/rdd.py +59 -0
- honeybee_energy/result/zsz.py +190 -0
- honeybee_energy/run.py +1577 -0
- honeybee_energy/schedule/__init__.py +1 -0
- honeybee_energy/schedule/day.py +626 -0
- honeybee_energy/schedule/dictutil.py +59 -0
- honeybee_energy/schedule/fixedinterval.py +1012 -0
- honeybee_energy/schedule/rule.py +619 -0
- honeybee_energy/schedule/ruleset.py +1867 -0
- honeybee_energy/schedule/typelimit.py +310 -0
- honeybee_energy/shw.py +315 -0
- honeybee_energy/simulation/__init__.py +1 -0
- honeybee_energy/simulation/control.py +214 -0
- honeybee_energy/simulation/daylightsaving.py +185 -0
- honeybee_energy/simulation/dictutil.py +51 -0
- honeybee_energy/simulation/output.py +646 -0
- honeybee_energy/simulation/parameter.py +606 -0
- honeybee_energy/simulation/runperiod.py +443 -0
- honeybee_energy/simulation/shadowcalculation.py +295 -0
- honeybee_energy/simulation/sizing.py +546 -0
- honeybee_energy/ventcool/__init__.py +5 -0
- honeybee_energy/ventcool/_crack_data.py +91 -0
- honeybee_energy/ventcool/afn.py +289 -0
- honeybee_energy/ventcool/control.py +269 -0
- honeybee_energy/ventcool/crack.py +126 -0
- honeybee_energy/ventcool/fan.py +493 -0
- honeybee_energy/ventcool/opening.py +365 -0
- honeybee_energy/ventcool/simulation.py +314 -0
- honeybee_energy/writer.py +1078 -0
- honeybee_energy-1.116.106.dist-info/METADATA +113 -0
- honeybee_energy-1.116.106.dist-info/RECORD +162 -0
- honeybee_energy-1.116.106.dist-info/WHEEL +5 -0
- honeybee_energy-1.116.106.dist-info/entry_points.txt +2 -0
- honeybee_energy-1.116.106.dist-info/licenses/LICENSE +661 -0
- honeybee_energy-1.116.106.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""honeybee-energy constructions."""
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""Base Construction."""
|
|
3
|
+
from __future__ import division
|
|
4
|
+
|
|
5
|
+
from ..material.gas import EnergyWindowMaterialGas
|
|
6
|
+
from ..writer import generate_idf_string
|
|
7
|
+
|
|
8
|
+
from honeybee._lockable import lockable
|
|
9
|
+
from honeybee.typing import valid_ep_string
|
|
10
|
+
|
|
11
|
+
import math
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@lockable
|
|
15
|
+
class _ConstructionBase(object):
|
|
16
|
+
"""Energy construction.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
identifier: Text string for a unique Construction ID. Must be < 100 characters
|
|
20
|
+
and not contain any EnergyPlus special characters. This will be used to
|
|
21
|
+
identify the object across a model and in the exported IDF.
|
|
22
|
+
materials: List of materials in the construction (from outside to inside).
|
|
23
|
+
|
|
24
|
+
Properties:
|
|
25
|
+
* identifier
|
|
26
|
+
* display_name
|
|
27
|
+
* materials
|
|
28
|
+
* layers
|
|
29
|
+
* unique_materials
|
|
30
|
+
* r_value
|
|
31
|
+
* u_value
|
|
32
|
+
* u_factor
|
|
33
|
+
* r_factor
|
|
34
|
+
* is_symmetric
|
|
35
|
+
* has_frame
|
|
36
|
+
* has_shade
|
|
37
|
+
* is_dynamic
|
|
38
|
+
* user_data
|
|
39
|
+
"""
|
|
40
|
+
# generic air material used to compute indoor film coefficients.
|
|
41
|
+
_air = EnergyWindowMaterialGas('generic air', gas_type='Air')
|
|
42
|
+
|
|
43
|
+
__slots__ = ('_identifier', '_display_name', '_materials', '_locked',
|
|
44
|
+
'_properties', '_user_data')
|
|
45
|
+
|
|
46
|
+
def __init__(self, identifier, materials):
|
|
47
|
+
"""Initialize energy construction."""
|
|
48
|
+
self._locked = False # unlocked by default
|
|
49
|
+
self.identifier = identifier
|
|
50
|
+
self._display_name = None
|
|
51
|
+
self.materials = materials
|
|
52
|
+
self._user_data = None
|
|
53
|
+
self._properties = None
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def identifier(self):
|
|
57
|
+
"""Get or set the text string for unique construction identifier."""
|
|
58
|
+
return self._identifier
|
|
59
|
+
|
|
60
|
+
@identifier.setter
|
|
61
|
+
def identifier(self, identifier):
|
|
62
|
+
self._identifier = valid_ep_string(identifier, 'construction identifier')
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def display_name(self):
|
|
66
|
+
"""Get or set a string for the object name without any character restrictions.
|
|
67
|
+
|
|
68
|
+
If not set, this will be equal to the identifier.
|
|
69
|
+
"""
|
|
70
|
+
if self._display_name is None:
|
|
71
|
+
return self._identifier
|
|
72
|
+
return self._display_name
|
|
73
|
+
|
|
74
|
+
@display_name.setter
|
|
75
|
+
def display_name(self, value):
|
|
76
|
+
if value is not None:
|
|
77
|
+
try:
|
|
78
|
+
value = str(value)
|
|
79
|
+
except UnicodeEncodeError: # Python 2 machine lacking the character set
|
|
80
|
+
pass # keep it as unicode
|
|
81
|
+
self._display_name = value
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def materials(self):
|
|
85
|
+
"""Get or set the list of materials in the construction (outside to inside)."""
|
|
86
|
+
return self._materials
|
|
87
|
+
|
|
88
|
+
@materials.setter
|
|
89
|
+
def materials(self, mats):
|
|
90
|
+
self._materials = mats
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def layers(self):
|
|
94
|
+
"""A list of material identifiers in the construction (outside to inside)."""
|
|
95
|
+
return [mat.identifier for mat in self._materials]
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def unique_materials(self):
|
|
99
|
+
"""A set of only unique material objects in the construction.
|
|
100
|
+
|
|
101
|
+
This is useful when constructions reuse material layers.
|
|
102
|
+
"""
|
|
103
|
+
return list(set(self._materials))
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def inside_emissivity(self):
|
|
107
|
+
""""The emissivity of the inside face of the construction."""
|
|
108
|
+
return self.materials[-1].thermal_absorptance
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def outside_emissivity(self):
|
|
112
|
+
""""The emissivity of the outside face of the construction."""
|
|
113
|
+
return self.materials[0].thermal_absorptance
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def r_value(self):
|
|
117
|
+
"""R-value of the construction [m2-K/W] (excluding air films)."""
|
|
118
|
+
return sum(tuple(mat.r_value for mat in self.materials))
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def u_value(self):
|
|
122
|
+
"""U-value of the construction [W/m2-K] (excluding air films)."""
|
|
123
|
+
return 1 / self.r_value
|
|
124
|
+
|
|
125
|
+
@property
|
|
126
|
+
def r_factor(self):
|
|
127
|
+
"""Construction R-factor [m2-K/W] (including standard resistances for air films).
|
|
128
|
+
|
|
129
|
+
Formulas for film coefficients come from EN673 / ISO10292.
|
|
130
|
+
"""
|
|
131
|
+
_ext_r = 1 / self.out_h_simple() # exterior heat transfer coefficient in m2-K/W
|
|
132
|
+
_int_r = 1 / self.in_h_simple() # interior film
|
|
133
|
+
return self.r_value + _ext_r + _int_r
|
|
134
|
+
|
|
135
|
+
@property
|
|
136
|
+
def u_factor(self):
|
|
137
|
+
"""Construction U-factor [W/m2-K] (including standard resistances for air films).
|
|
138
|
+
|
|
139
|
+
Formulas for film coefficients come from EN673 / ISO10292.
|
|
140
|
+
"""
|
|
141
|
+
return 1 / self.r_factor
|
|
142
|
+
|
|
143
|
+
@property
|
|
144
|
+
def is_symmetric(self):
|
|
145
|
+
"""Get a boolean to note whether the construction layers are symmetric.
|
|
146
|
+
|
|
147
|
+
Symmetric means that the materials in reversed order are equal to those
|
|
148
|
+
in the current order (eg. 'Gypsum', 'Air Gap', 'Gypsum'). This is particularly
|
|
149
|
+
helpful for interior constructions, which need to have matching materials
|
|
150
|
+
in reversed order between adjacent Faces.
|
|
151
|
+
"""
|
|
152
|
+
half_mat = int(len(self._materials) / 2)
|
|
153
|
+
for i in range(half_mat):
|
|
154
|
+
if self._materials[i] != self._materials[-(i + 1)]:
|
|
155
|
+
return False
|
|
156
|
+
return True
|
|
157
|
+
|
|
158
|
+
@property
|
|
159
|
+
def has_shade(self):
|
|
160
|
+
"""Get a boolean noting whether dynamic shade materials are in the construction.
|
|
161
|
+
"""
|
|
162
|
+
# This is False for all construction types except WindowConstructionShade.
|
|
163
|
+
return False
|
|
164
|
+
|
|
165
|
+
@property
|
|
166
|
+
def has_frame(self):
|
|
167
|
+
"""Get a boolean noting whether the construction has a frame assigned to it."""
|
|
168
|
+
return False
|
|
169
|
+
|
|
170
|
+
@property
|
|
171
|
+
def is_dynamic(self):
|
|
172
|
+
"""Get a boolean noting whether the construction is dynamic.
|
|
173
|
+
|
|
174
|
+
This will always be False for this class.
|
|
175
|
+
"""
|
|
176
|
+
return False
|
|
177
|
+
|
|
178
|
+
@property
|
|
179
|
+
def user_data(self):
|
|
180
|
+
"""Get or set an optional dictionary for additional meta data for this object.
|
|
181
|
+
|
|
182
|
+
This will be None until it has been set. All keys and values of this
|
|
183
|
+
dictionary should be of a standard Python type to ensure correct
|
|
184
|
+
serialization of the object to/from JSON (eg. str, float, int, list, dict)
|
|
185
|
+
"""
|
|
186
|
+
if self._user_data is not None:
|
|
187
|
+
return self._user_data
|
|
188
|
+
|
|
189
|
+
@user_data.setter
|
|
190
|
+
def user_data(self, value):
|
|
191
|
+
if value is not None:
|
|
192
|
+
assert isinstance(value, dict), 'Expected dictionary for honeybee_energy' \
|
|
193
|
+
'object user_data. Got {}.'.format(type(value))
|
|
194
|
+
self._user_data = value
|
|
195
|
+
|
|
196
|
+
@property
|
|
197
|
+
def properties(self):
|
|
198
|
+
"""Get properties for extensions."""
|
|
199
|
+
return self._properties
|
|
200
|
+
|
|
201
|
+
def duplicate(self):
|
|
202
|
+
"""Get a copy of this construction."""
|
|
203
|
+
return self.__copy__()
|
|
204
|
+
|
|
205
|
+
def out_h_simple(self):
|
|
206
|
+
"""Get the simple outdoor heat transfer coefficient according to ISO 10292.
|
|
207
|
+
|
|
208
|
+
This is used for all opaque R-factor calculations.
|
|
209
|
+
"""
|
|
210
|
+
return 23
|
|
211
|
+
|
|
212
|
+
def in_h_simple(self):
|
|
213
|
+
"""Get the simple indoor heat transfer coefficient according to ISO 10292.
|
|
214
|
+
|
|
215
|
+
This is used for all opaque R-factor calculations.
|
|
216
|
+
"""
|
|
217
|
+
return (3.6 + (4.4 * self.inside_emissivity / 0.84))
|
|
218
|
+
|
|
219
|
+
def out_h(self, wind_speed=6.7, t_kelvin=273.15):
|
|
220
|
+
"""Get the detailed outdoor heat transfer coefficient according to ISO 15099.
|
|
221
|
+
|
|
222
|
+
This is used for window U-factor calculations and all of the
|
|
223
|
+
temperature_profile calculations.
|
|
224
|
+
|
|
225
|
+
Args:
|
|
226
|
+
wind_speed: The average outdoor wind speed [m/s]. This affects the
|
|
227
|
+
convective heat transfer coefficient. Default is 6.7 m/s.
|
|
228
|
+
t_kelvin: The average between the outdoor temperature and the
|
|
229
|
+
exterior surface temperature. This can affect the radiative heat
|
|
230
|
+
transfer. Default is 273.15K (0C).
|
|
231
|
+
"""
|
|
232
|
+
_conv_h = 4 + (4 * wind_speed)
|
|
233
|
+
_rad_h = 4 * 5.6697e-8 * self.outside_emissivity * (t_kelvin ** 3)
|
|
234
|
+
return _conv_h + _rad_h
|
|
235
|
+
|
|
236
|
+
def in_h(self, t_kelvin=293.15, delta_t=15, height=1.0, angle=90, pressure=101325):
|
|
237
|
+
"""Get the detailed indoor heat transfer coefficient according to ISO 15099.
|
|
238
|
+
|
|
239
|
+
This is used for window U-factor calculations and all of the
|
|
240
|
+
temperature_profile calculations.
|
|
241
|
+
|
|
242
|
+
Args:
|
|
243
|
+
t_kelvin: The average between the indoor temperature and the
|
|
244
|
+
interior surface temperature. Default is 293.15K (20C).
|
|
245
|
+
delta_t: The temperature difference between the indoor temperature and the
|
|
246
|
+
interior surface temperature [C]. Default is 15C.
|
|
247
|
+
height: An optional height for the surface in meters. Default is 1.0 m,
|
|
248
|
+
which is consistent with NFRC standards.
|
|
249
|
+
angle: An angle in degrees between 0 and 180.
|
|
250
|
+
0 = A horizontal surface with downward heat flow through the layer.
|
|
251
|
+
90 = A vertical surface
|
|
252
|
+
180 = A horizontal surface with upward heat flow through the layer.
|
|
253
|
+
pressure: The average pressure in Pa.
|
|
254
|
+
Default is 101325 Pa for standard pressure at sea level.
|
|
255
|
+
"""
|
|
256
|
+
_ray_numerator = (self._air.density_at_temperature(t_kelvin, pressure) ** 2) * \
|
|
257
|
+
(height ** 3) * 9.81 * self._air.specific_heat_at_temperature(t_kelvin) \
|
|
258
|
+
* delta_t
|
|
259
|
+
_ray_denominator = t_kelvin * self._air.viscosity_at_temperature(t_kelvin) * \
|
|
260
|
+
self._air.conductivity_at_temperature(t_kelvin)
|
|
261
|
+
_rayleigh_h = abs(_ray_numerator / _ray_denominator)
|
|
262
|
+
if angle < 15:
|
|
263
|
+
nusselt = 0.13 * (_rayleigh_h ** (1 / 3))
|
|
264
|
+
elif angle <= 90:
|
|
265
|
+
_sin_a = math.sin(math.radians(angle))
|
|
266
|
+
_rayleigh_c = 2.5e5 * ((math.exp(0.72 * angle) / _sin_a) ** (1 / 5))
|
|
267
|
+
if _rayleigh_h < _rayleigh_c:
|
|
268
|
+
nusselt = 0.56 * ((_rayleigh_h * _sin_a) ** (1 / 4))
|
|
269
|
+
else:
|
|
270
|
+
nu_1 = 0.56 * ((_rayleigh_c * _sin_a) ** (1 / 4))
|
|
271
|
+
nu_2 = 0.13 * ((_rayleigh_h ** (1 / 3)) - (_rayleigh_c ** (1 / 3)))
|
|
272
|
+
nusselt = nu_1 + nu_2
|
|
273
|
+
elif angle <= 179:
|
|
274
|
+
_sin_a = math.sin(math.radians(angle))
|
|
275
|
+
nusselt = 0.56 * ((_rayleigh_h * _sin_a) ** (1 / 4))
|
|
276
|
+
else:
|
|
277
|
+
nusselt = 0.58 * (_rayleigh_h ** (1 / 5))
|
|
278
|
+
a_cond = self._air.conductivity_at_temperature(t_kelvin)
|
|
279
|
+
try:
|
|
280
|
+
_conv_h = nusselt * (a_cond / height)
|
|
281
|
+
except ZeroDivisionError: # completely horizontal face
|
|
282
|
+
_conv_h = nusselt * a_cond
|
|
283
|
+
_rad_h = 4 * 5.6697e-8 * self.inside_emissivity * (t_kelvin ** 3)
|
|
284
|
+
return _conv_h + _rad_h
|
|
285
|
+
|
|
286
|
+
def lock(self):
|
|
287
|
+
"""The lock() method will also lock the materials."""
|
|
288
|
+
self._locked = True
|
|
289
|
+
for mat in self.materials:
|
|
290
|
+
mat.lock()
|
|
291
|
+
|
|
292
|
+
def unlock(self):
|
|
293
|
+
"""The unlock() method will also unlock the materials."""
|
|
294
|
+
self._locked = False
|
|
295
|
+
for mat in self.materials:
|
|
296
|
+
mat.unlock()
|
|
297
|
+
|
|
298
|
+
def _temperature_profile_from_r_values(
|
|
299
|
+
self, r_values, outside_temperature=-18, inside_temperature=21,
|
|
300
|
+
heat_generation=None):
|
|
301
|
+
"""Get a list of temperatures at each material boundary between R-values."""
|
|
302
|
+
r_factor = sum(r_values)
|
|
303
|
+
delta_t = inside_temperature - outside_temperature
|
|
304
|
+
temperatures = [outside_temperature]
|
|
305
|
+
for i, r_val in enumerate(r_values):
|
|
306
|
+
temperatures.append(temperatures[i] + (delta_t * (r_val / r_factor)))
|
|
307
|
+
# account for heat_generation in material layers if specified
|
|
308
|
+
if isinstance(heat_generation, float): # single heat incident on the exterior
|
|
309
|
+
r_prev, r_follow = r_values[0], r_values[1:]
|
|
310
|
+
q_prev = heat_generation * (1 - (r_prev / r_factor))
|
|
311
|
+
q_follow = heat_generation * (1 - (sum(r_follow) / r_factor))
|
|
312
|
+
temperatures[1] += q_prev * r_prev # heat going to exterior
|
|
313
|
+
# add the heat transferred to the interior
|
|
314
|
+
for j in range(len(r_follow)):
|
|
315
|
+
temperatures[2 + j] += q_follow * sum(r_follow[j + 1:])
|
|
316
|
+
elif isinstance(heat_generation, list): # a list of heat generated inside layers
|
|
317
|
+
for i, heat_g in enumerate(heat_generation):
|
|
318
|
+
if heat_g == 0:
|
|
319
|
+
continue
|
|
320
|
+
r_prev, r_follow = r_values[:i], r_values[i + 1:]
|
|
321
|
+
q_prev = heat_g * (1 - (sum(r_prev) / r_factor))
|
|
322
|
+
q_follow = heat_g * (1 - (sum(r_follow) / r_factor))
|
|
323
|
+
# add the heat transferred to the interior
|
|
324
|
+
for j in range(len(r_follow)):
|
|
325
|
+
temperatures[i + 1 + j] += q_follow * sum(r_follow[j:])
|
|
326
|
+
# add the heat transferred to the exterior
|
|
327
|
+
for k in range(len(r_prev), 0, -1):
|
|
328
|
+
temperatures[k] += q_prev * sum(r_prev[:k])
|
|
329
|
+
return temperatures
|
|
330
|
+
|
|
331
|
+
@staticmethod
|
|
332
|
+
def _generate_idf_string(constr_type, identifier, materials):
|
|
333
|
+
"""Get an EnergyPlus string representation from values and comments."""
|
|
334
|
+
values = (identifier,) + tuple(mat.identifier for mat in materials)
|
|
335
|
+
comments = ('name',) + tuple('layer %s' % (i + 1) for i in range(len(materials)))
|
|
336
|
+
return generate_idf_string('Construction', values, comments)
|
|
337
|
+
|
|
338
|
+
def __copy__(self):
|
|
339
|
+
new_con = self.__class__(
|
|
340
|
+
self.identifier, [mat.duplicate() for mat in self.materials])
|
|
341
|
+
new_con._display_name = self._display_name
|
|
342
|
+
new_con._user_data = None if self._user_data is None else self._user_data.copy()
|
|
343
|
+
new_con._properties._duplicate_extension_attr(self._properties)
|
|
344
|
+
return new_con
|
|
345
|
+
|
|
346
|
+
def __len__(self):
|
|
347
|
+
return len(self._materials)
|
|
348
|
+
|
|
349
|
+
def __getitem__(self, key):
|
|
350
|
+
return self._materials[key]
|
|
351
|
+
|
|
352
|
+
def __iter__(self):
|
|
353
|
+
return iter(self._materials)
|
|
354
|
+
|
|
355
|
+
def __key(self):
|
|
356
|
+
"""A tuple based on the object properties, useful for hashing."""
|
|
357
|
+
return (self.identifier,) + tuple(hash(mat) for mat in self.materials)
|
|
358
|
+
|
|
359
|
+
def __hash__(self):
|
|
360
|
+
return hash(self.__key())
|
|
361
|
+
|
|
362
|
+
def __eq__(self, other):
|
|
363
|
+
return isinstance(other, _ConstructionBase) and self.__key() == other.__key()
|
|
364
|
+
|
|
365
|
+
def __ne__(self, other):
|
|
366
|
+
return not self.__eq__(other)
|
|
367
|
+
|
|
368
|
+
def ToString(self):
|
|
369
|
+
"""Overwrite .NET ToString."""
|
|
370
|
+
return self.__repr__()
|
|
371
|
+
|
|
372
|
+
def __repr__(self):
|
|
373
|
+
return 'Construction: {}, [{} materials]'.format(
|
|
374
|
+
self.display_name, len(self.materials))
|