fairyfly-therm 0.3.1__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.
- fairyfly_therm/__init__.py +8 -0
- fairyfly_therm/__main__.py +4 -0
- fairyfly_therm/cli/__init__.py +47 -0
- fairyfly_therm/cli/setconfig.py +75 -0
- fairyfly_therm/condition/__init__.py +1 -0
- fairyfly_therm/condition/_base.py +167 -0
- fairyfly_therm/condition/comprehensive.py +412 -0
- fairyfly_therm/config.json +6 -0
- fairyfly_therm/config.py +315 -0
- fairyfly_therm/lib/__init__.py +1 -0
- fairyfly_therm/lib/_loadconditions.py +87 -0
- fairyfly_therm/lib/_loadgases.py +98 -0
- fairyfly_therm/lib/_loadmaterials.py +98 -0
- fairyfly_therm/lib/conditions.py +24 -0
- fairyfly_therm/lib/gases.py +36 -0
- fairyfly_therm/lib/materials.py +38 -0
- fairyfly_therm/material/__init__.py +1 -0
- fairyfly_therm/material/_base.py +182 -0
- fairyfly_therm/material/cavity.py +377 -0
- fairyfly_therm/material/gas.py +925 -0
- fairyfly_therm/material/solid.py +399 -0
- fairyfly_therm/material/xmlutil.py +45 -0
- fairyfly_therm-0.3.1.dist-info/METADATA +86 -0
- fairyfly_therm-0.3.1.dist-info/RECORD +28 -0
- fairyfly_therm-0.3.1.dist-info/WHEEL +5 -0
- fairyfly_therm-0.3.1.dist-info/entry_points.txt +2 -0
- fairyfly_therm-0.3.1.dist-info/licenses/LICENSE +661 -0
- fairyfly_therm-0.3.1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,399 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""Solid THERM material."""
|
|
3
|
+
from __future__ import division
|
|
4
|
+
import xml.etree.ElementTree as ET
|
|
5
|
+
|
|
6
|
+
from fairyfly._lockable import lockable
|
|
7
|
+
from fairyfly.typing import float_in_range, float_positive, uuid_from_therm_id
|
|
8
|
+
|
|
9
|
+
from ._base import _ThermMaterialBase
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@lockable
|
|
13
|
+
class SolidMaterial(_ThermMaterialBase):
|
|
14
|
+
"""Typical conductive material.
|
|
15
|
+
|
|
16
|
+
Args:
|
|
17
|
+
conductivity: Number for the thermal conductivity of the material [W/m-K].
|
|
18
|
+
emissivity: Number between 0 and 1 for the infrared hemispherical
|
|
19
|
+
emissivity of the front side of the material. (Default: 0.9).
|
|
20
|
+
emissivity_back: Number between 0 and 1 for the infrared hemispherical
|
|
21
|
+
emissivity of the back side of the material. If None, this will
|
|
22
|
+
default to the same value specified for emissivity. (Default: None)
|
|
23
|
+
density: Optional number for the density of the material [kg/m3]. (Default: None).
|
|
24
|
+
porosity: Optional number between zero and one for the porosity of
|
|
25
|
+
the material. (Default: None).
|
|
26
|
+
specific_heat: Optional number for the specific heat of the material [J/kg-K].
|
|
27
|
+
If None, it is not included in the export. (Default: None).
|
|
28
|
+
vapor_diffusion_resistance: Optional number for the water vapor diffusion
|
|
29
|
+
resistance factor [Dimensionless]. (Default: None).
|
|
30
|
+
identifier: Text string for a unique object ID. Must be a UUID in the
|
|
31
|
+
format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. If None, a UUID will
|
|
32
|
+
automatically be generated. (Default: None).
|
|
33
|
+
|
|
34
|
+
Properties:
|
|
35
|
+
* identifier
|
|
36
|
+
* display_name
|
|
37
|
+
* conductivity
|
|
38
|
+
* emissivity
|
|
39
|
+
* emissivity_back
|
|
40
|
+
* density
|
|
41
|
+
* porosity
|
|
42
|
+
* specific_heat
|
|
43
|
+
* vapor_diffusion_resistance
|
|
44
|
+
* resistivity
|
|
45
|
+
* color
|
|
46
|
+
* protected
|
|
47
|
+
* user_data
|
|
48
|
+
"""
|
|
49
|
+
__slots__ = ('_conductivity', '_emissivity', '_emissivity_back',
|
|
50
|
+
'_density', '_porosity', '_specific_heat',
|
|
51
|
+
'_vapor_diffusion_resistance')
|
|
52
|
+
|
|
53
|
+
def __init__(
|
|
54
|
+
self, conductivity, emissivity=0.9, emissivity_back=None,
|
|
55
|
+
density=None, porosity=None, specific_heat=None,
|
|
56
|
+
vapor_diffusion_resistance=None, identifier=None
|
|
57
|
+
):
|
|
58
|
+
"""Initialize therm material."""
|
|
59
|
+
_ThermMaterialBase.__init__(self, identifier)
|
|
60
|
+
self.conductivity = conductivity
|
|
61
|
+
self.emissivity = emissivity
|
|
62
|
+
self.emissivity_back = emissivity_back
|
|
63
|
+
self.density = density
|
|
64
|
+
self.porosity = porosity
|
|
65
|
+
self.specific_heat = specific_heat
|
|
66
|
+
self.vapor_diffusion_resistance = vapor_diffusion_resistance
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def conductivity(self):
|
|
70
|
+
"""Get or set the conductivity of the material layer [W/m-K]."""
|
|
71
|
+
return self._conductivity
|
|
72
|
+
|
|
73
|
+
@conductivity.setter
|
|
74
|
+
def conductivity(self, cond):
|
|
75
|
+
self._conductivity = float_positive(cond, 'material conductivity')
|
|
76
|
+
assert self._conductivity != 0, 'Conductivity cannot be equal to zero.'
|
|
77
|
+
|
|
78
|
+
@property
|
|
79
|
+
def emissivity(self):
|
|
80
|
+
"""Get or set the hemispherical emissivity of the front side of the material."""
|
|
81
|
+
return self._emissivity
|
|
82
|
+
|
|
83
|
+
@emissivity.setter
|
|
84
|
+
def emissivity(self, ir_e):
|
|
85
|
+
ir_e = float_in_range(ir_e, 0.0, 1.0, 'material emissivity')
|
|
86
|
+
self._emissivity = ir_e
|
|
87
|
+
|
|
88
|
+
@property
|
|
89
|
+
def emissivity_back(self):
|
|
90
|
+
"""Get or set the hemispherical emissivity of the back side of the material."""
|
|
91
|
+
return self._emissivity_back if self._emissivity_back is not None \
|
|
92
|
+
else self._emissivity
|
|
93
|
+
|
|
94
|
+
@emissivity_back.setter
|
|
95
|
+
def emissivity_back(self, ir_e):
|
|
96
|
+
if ir_e is not None:
|
|
97
|
+
ir_e = float_in_range(ir_e, 0.0, 1.0, 'material emissivity')
|
|
98
|
+
self._emissivity_back = ir_e
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def density(self):
|
|
102
|
+
"""Get or set the density of the material layer [kg/m3]."""
|
|
103
|
+
return self._density
|
|
104
|
+
|
|
105
|
+
@density.setter
|
|
106
|
+
def density(self, value):
|
|
107
|
+
if value is not None:
|
|
108
|
+
value = float_positive(value, 'material density')
|
|
109
|
+
self._density = value
|
|
110
|
+
|
|
111
|
+
@property
|
|
112
|
+
def porosity(self):
|
|
113
|
+
"""Get or set a number between zero and one for the porosity."""
|
|
114
|
+
return self._porosity
|
|
115
|
+
|
|
116
|
+
@porosity.setter
|
|
117
|
+
def porosity(self, value):
|
|
118
|
+
if value is not None:
|
|
119
|
+
value = float_in_range(value, 0.0, 1.0, 'material porosity')
|
|
120
|
+
self._porosity = value
|
|
121
|
+
|
|
122
|
+
@property
|
|
123
|
+
def specific_heat(self):
|
|
124
|
+
"""Get or set the specific heat of the material layer [J/kg-K]."""
|
|
125
|
+
return self._specific_heat
|
|
126
|
+
|
|
127
|
+
@specific_heat.setter
|
|
128
|
+
def specific_heat(self, value):
|
|
129
|
+
if value is not None:
|
|
130
|
+
value = float_positive(value, 'material specific heat')
|
|
131
|
+
self._specific_heat = value
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
def vapor_diffusion_resistance(self):
|
|
135
|
+
"""Get or set the vapor diffusion resistance of the material."""
|
|
136
|
+
return self._vapor_diffusion_resistance
|
|
137
|
+
|
|
138
|
+
@vapor_diffusion_resistance.setter
|
|
139
|
+
def vapor_diffusion_resistance(self, value):
|
|
140
|
+
if value is not None:
|
|
141
|
+
value = float_positive(value, 'vapor diffusion resistance')
|
|
142
|
+
self._vapor_diffusion_resistance = value
|
|
143
|
+
|
|
144
|
+
@property
|
|
145
|
+
def resistivity(self):
|
|
146
|
+
"""Get or set the resistivity of the material layer [m-K/W]."""
|
|
147
|
+
return 1 / self._conductivity
|
|
148
|
+
|
|
149
|
+
@resistivity.setter
|
|
150
|
+
def resistivity(self, resis):
|
|
151
|
+
self._conductivity = 1 / float_positive(resis, 'material resistivity')
|
|
152
|
+
|
|
153
|
+
@classmethod
|
|
154
|
+
def from_therm_xml(cls, xml_element):
|
|
155
|
+
"""Create a SolidMaterial from an XML element of a THERM Material.
|
|
156
|
+
|
|
157
|
+
Args:
|
|
158
|
+
xml_element: An XML element of a THERM material.
|
|
159
|
+
"""
|
|
160
|
+
# create the base material from the UUID and conductivity
|
|
161
|
+
xml_uuid = xml_element.find('UUID')
|
|
162
|
+
identifier = xml_uuid.text
|
|
163
|
+
if len(identifier) == 31:
|
|
164
|
+
identifier = uuid_from_therm_id(identifier)
|
|
165
|
+
xml_solid = xml_element.find('Solid')
|
|
166
|
+
xml_hyt = xml_solid.find('HygroThermal')
|
|
167
|
+
xml_cond = xml_hyt.find('ThermalConductivityDry')
|
|
168
|
+
conductivity = xml_cond.text
|
|
169
|
+
mat = SolidMaterial(conductivity, identifier=identifier)
|
|
170
|
+
# assign the other hygrothermal attributes if specified
|
|
171
|
+
xml_dens = xml_hyt.find('BulkDensity')
|
|
172
|
+
if xml_dens is not None:
|
|
173
|
+
mat.density = xml_dens.text
|
|
174
|
+
xml_por = xml_hyt.find('Porosity')
|
|
175
|
+
if xml_por is not None:
|
|
176
|
+
mat.porosity = xml_por.text
|
|
177
|
+
xml_shc = xml_hyt.find('SpecificHeatCapacityDry')
|
|
178
|
+
if xml_shc is not None:
|
|
179
|
+
mat.specific_heat = xml_shc.text
|
|
180
|
+
xml_vdr = xml_hyt.find('WaterVaporDiffusionResistanceFactor')
|
|
181
|
+
if xml_vdr is not None:
|
|
182
|
+
mat.vapor_diffusion_resistance = xml_vdr.text
|
|
183
|
+
# assign the optical properties if specified
|
|
184
|
+
xml_optical = xml_solid.find('Optical')
|
|
185
|
+
if xml_optical is not None:
|
|
186
|
+
xml_int = xml_optical.find('Integrated')
|
|
187
|
+
if xml_int is not None:
|
|
188
|
+
xml_inf = xml_int.find('Infrared')
|
|
189
|
+
if xml_inf is not None:
|
|
190
|
+
xml_emiss = xml_inf.find('Emissivity-Front')
|
|
191
|
+
if xml_emiss is not None:
|
|
192
|
+
mat.emissivity = xml_emiss.text
|
|
193
|
+
xml_emiss_b = xml_inf.find('Emissivity-Back')
|
|
194
|
+
if xml_emiss_b is not None:
|
|
195
|
+
mat.emissivity_back = xml_emiss_b.text
|
|
196
|
+
# assign the name and color if they are specified
|
|
197
|
+
xml_name = xml_element.find('Name')
|
|
198
|
+
if xml_name is not None:
|
|
199
|
+
mat.display_name = xml_name.text
|
|
200
|
+
xml_col = xml_element.find('Color')
|
|
201
|
+
if xml_col is not None:
|
|
202
|
+
mat.color = xml_col.text
|
|
203
|
+
xml_protect = xml_element.find('Protected')
|
|
204
|
+
if xml_protect is not None:
|
|
205
|
+
mat.protected = True if xml_protect.text == 'true' else False
|
|
206
|
+
return mat
|
|
207
|
+
|
|
208
|
+
@classmethod
|
|
209
|
+
def from_therm_xml_str(cls, xml_str):
|
|
210
|
+
"""Create a SolidMaterial from an XML text string of a THERM Material.
|
|
211
|
+
|
|
212
|
+
Args:
|
|
213
|
+
xml_str: An XML text string of a THERM material.
|
|
214
|
+
"""
|
|
215
|
+
root = ET.fromstring(xml_str)
|
|
216
|
+
return cls.from_therm_xml(root)
|
|
217
|
+
|
|
218
|
+
@classmethod
|
|
219
|
+
def from_dict(cls, data):
|
|
220
|
+
"""Create a SolidMaterial from a dictionary.
|
|
221
|
+
|
|
222
|
+
Args:
|
|
223
|
+
data: A python dictionary in the following format
|
|
224
|
+
|
|
225
|
+
.. code-block:: python
|
|
226
|
+
|
|
227
|
+
{
|
|
228
|
+
"type": 'SolidMaterial',
|
|
229
|
+
"identifier": 'f26f3597-e3ee-43fe-a0b3-ec673f993d86',
|
|
230
|
+
"display_name": 'Concrete',
|
|
231
|
+
"conductivity": 2.31,
|
|
232
|
+
"emissivity": 0.9,
|
|
233
|
+
"emissivity_back": 0.9,
|
|
234
|
+
"density": 2322,
|
|
235
|
+
"porosity": 0.24,
|
|
236
|
+
"specific_heat": 832,
|
|
237
|
+
"vapor_diffusion_resistance": 19
|
|
238
|
+
}
|
|
239
|
+
"""
|
|
240
|
+
assert data['type'] == 'SolidMaterial', \
|
|
241
|
+
'Expected SolidMaterial. Got {}.'.format(data['type'])
|
|
242
|
+
|
|
243
|
+
emiss = data['emissivity'] if 'emissivity' in data and \
|
|
244
|
+
data['emissivity'] is not None else 0.9
|
|
245
|
+
emiss_b = data['emissivity_back'] if 'emissivity_back' in data else None
|
|
246
|
+
dens = data['density'] if 'density' in data else None
|
|
247
|
+
poro = data['porosity'] if 'porosity' in data else None
|
|
248
|
+
s_heat = data['specific_heat'] if 'specific_heat' in data else None
|
|
249
|
+
vdr = data['vapor_diffusion_resistance'] \
|
|
250
|
+
if 'vapor_diffusion_resistance' in data else None
|
|
251
|
+
|
|
252
|
+
new_mat = cls(
|
|
253
|
+
data['conductivity'], emiss, emiss_b, dens, poro, s_heat, vdr,
|
|
254
|
+
data['identifier'])
|
|
255
|
+
if 'display_name' in data and data['display_name'] is not None:
|
|
256
|
+
new_mat.display_name = data['display_name']
|
|
257
|
+
if 'color' in data and data['color'] is not None:
|
|
258
|
+
new_mat.color = data['color']
|
|
259
|
+
if 'protected' in data and data['protected'] is not None:
|
|
260
|
+
new_mat.protected = data['protected']
|
|
261
|
+
if 'user_data' in data and data['user_data'] is not None:
|
|
262
|
+
new_mat.user_data = data['user_data']
|
|
263
|
+
return new_mat
|
|
264
|
+
|
|
265
|
+
def to_therm_xml(self, materials_element=None):
|
|
266
|
+
"""Get an THERM XML element of the material.
|
|
267
|
+
|
|
268
|
+
Args:
|
|
269
|
+
materials_element: An optional XML Element for the Materials to
|
|
270
|
+
which the generated objects will be added. If None, a new XML
|
|
271
|
+
Element will be generated.
|
|
272
|
+
|
|
273
|
+
.. code-block:: xml
|
|
274
|
+
|
|
275
|
+
<Material>
|
|
276
|
+
<UUID>1543f77f-e4aa-47d4-b7bf-2365d7bc0b9d</UUID>
|
|
277
|
+
<Name>Polyurethane Foam</Name>
|
|
278
|
+
<Protected>false</Protected>
|
|
279
|
+
<Color>0xFFFFC1</Color>
|
|
280
|
+
<Solid>
|
|
281
|
+
<HygroThermal>
|
|
282
|
+
<ThermalConductivityDry>0.05</ThermalConductivityDry>
|
|
283
|
+
</HygroThermal>
|
|
284
|
+
<Optical>
|
|
285
|
+
<Integrated>
|
|
286
|
+
<Infrared>
|
|
287
|
+
<Emissivity-Front>0.9</Emissivity-Front>
|
|
288
|
+
<Emissivity-Back>0.9</Emissivity-Back>
|
|
289
|
+
</Infrared>
|
|
290
|
+
</Integrated>
|
|
291
|
+
</Optical>
|
|
292
|
+
</Solid>
|
|
293
|
+
</Material>
|
|
294
|
+
"""
|
|
295
|
+
# create a new Materials element if one is not specified
|
|
296
|
+
if materials_element is not None:
|
|
297
|
+
xml_mat = ET.SubElement(materials_element, 'Material')
|
|
298
|
+
else:
|
|
299
|
+
xml_mat = ET.Element('Material')
|
|
300
|
+
# add all of the required basic attributes
|
|
301
|
+
xml_id = ET.SubElement(xml_mat, 'UUID')
|
|
302
|
+
xml_id.text = self.identifier
|
|
303
|
+
xml_name = ET.SubElement(xml_mat, 'Name')
|
|
304
|
+
xml_name.text = self.display_name
|
|
305
|
+
xml_protect = ET.SubElement(xml_mat, 'Protected')
|
|
306
|
+
xml_protect.text = 'true' if self.protected else 'false'
|
|
307
|
+
xml_color = ET.SubElement(xml_mat, 'Color')
|
|
308
|
+
xml_color.text = self.color.to_hex().replace('#', '0x')
|
|
309
|
+
xml_solid = ET.SubElement(xml_mat, 'Solid')
|
|
310
|
+
# add all of the required hygrothermal and optical attributes
|
|
311
|
+
xml_hyt = ET.SubElement(xml_solid, 'HygroThermal')
|
|
312
|
+
xml_cond = ET.SubElement(xml_hyt, 'ThermalConductivityDry')
|
|
313
|
+
xml_cond.text = str(self.conductivity)
|
|
314
|
+
xml_optical = ET.SubElement(xml_solid, 'Optical')
|
|
315
|
+
xml_int = ET.SubElement(xml_optical, 'Integrated')
|
|
316
|
+
xml_inf = ET.SubElement(xml_int, 'Infrared')
|
|
317
|
+
xml_emiss = ET.SubElement(xml_inf, 'Emissivity-Front')
|
|
318
|
+
xml_emiss.text = str(self.emissivity)
|
|
319
|
+
xml_emiss_b = ET.SubElement(xml_inf, 'Emissivity-Back')
|
|
320
|
+
xml_emiss_b.text = str(self.emissivity_back)
|
|
321
|
+
# add any of the optional hygrothermal attributes
|
|
322
|
+
if self.density is not None:
|
|
323
|
+
xml_dens = ET.SubElement(xml_hyt, 'BulkDensity')
|
|
324
|
+
xml_dens.text = str(self.density)
|
|
325
|
+
if self.porosity is not None:
|
|
326
|
+
xml_por = ET.SubElement(xml_hyt, 'Porosity')
|
|
327
|
+
xml_por.text = str(self.porosity)
|
|
328
|
+
if self.specific_heat is not None:
|
|
329
|
+
xml_shc = ET.SubElement(xml_hyt, 'SpecificHeatCapacityDry')
|
|
330
|
+
xml_shc.text = str(self.specific_heat)
|
|
331
|
+
if self.vapor_diffusion_resistance is not None:
|
|
332
|
+
xml_vdr = ET.SubElement(xml_hyt, 'WaterVaporDiffusionResistanceFactor')
|
|
333
|
+
xml_vdr.text = str(self.vapor_diffusion_resistance)
|
|
334
|
+
return xml_mat
|
|
335
|
+
|
|
336
|
+
def to_therm_xml_str(self):
|
|
337
|
+
"""Get an THERM XML string of the material."""
|
|
338
|
+
xml_root = self.to_therm_xml()
|
|
339
|
+
try: # try to indent the XML to make it read-able
|
|
340
|
+
ET.indent(xml_root)
|
|
341
|
+
return ET.tostring(xml_root, encoding='unicode')
|
|
342
|
+
except AttributeError: # we are in Python 2 and no indent is available
|
|
343
|
+
return ET.tostring(xml_root)
|
|
344
|
+
|
|
345
|
+
def to_dict(self):
|
|
346
|
+
"""SolidMaterial dictionary representation."""
|
|
347
|
+
base = {
|
|
348
|
+
'type': 'SolidMaterial',
|
|
349
|
+
'identifier': self.identifier,
|
|
350
|
+
'conductivity': self.conductivity,
|
|
351
|
+
'emissivity': self.emissivity
|
|
352
|
+
}
|
|
353
|
+
if self._emissivity_back is not None:
|
|
354
|
+
base['emissivity_back'] = self._emissivity_back
|
|
355
|
+
if self._density is not None:
|
|
356
|
+
base['density'] = self._density
|
|
357
|
+
if self._porosity is not None:
|
|
358
|
+
base['porosity'] = self.porosity
|
|
359
|
+
if self._specific_heat is not None:
|
|
360
|
+
base['specific_heat'] = self.specific_heat
|
|
361
|
+
if self._vapor_diffusion_resistance is not None:
|
|
362
|
+
base['vapor_diffusion_resistance'] = self.vapor_diffusion_resistance
|
|
363
|
+
if self._display_name is not None:
|
|
364
|
+
base['display_name'] = self.display_name
|
|
365
|
+
base['protected'] = self._protected
|
|
366
|
+
base['color'] = self.color.to_hex()
|
|
367
|
+
if self._user_data is not None:
|
|
368
|
+
base['user_data'] = self.user_data
|
|
369
|
+
return base
|
|
370
|
+
|
|
371
|
+
def __key(self):
|
|
372
|
+
"""A tuple based on the object properties, useful for hashing."""
|
|
373
|
+
return (self.identifier, self.conductivity, self.emissivity,
|
|
374
|
+
self.emissivity_back, self.density, self.porosity,
|
|
375
|
+
self.specific_heat, self.vapor_diffusion_resistance)
|
|
376
|
+
|
|
377
|
+
def __hash__(self):
|
|
378
|
+
return hash(self.__key())
|
|
379
|
+
|
|
380
|
+
def __eq__(self, other):
|
|
381
|
+
return isinstance(other, SolidMaterial) and self.__key() == other.__key()
|
|
382
|
+
|
|
383
|
+
def __ne__(self, other):
|
|
384
|
+
return not self.__eq__(other)
|
|
385
|
+
|
|
386
|
+
def __copy__(self):
|
|
387
|
+
new_material = self.__class__(
|
|
388
|
+
self.conductivity, self._emissivity, self._emissivity_back,
|
|
389
|
+
self._density, self._porosity, self._specific_heat,
|
|
390
|
+
self._vapor_diffusion_resistance, self.identifier)
|
|
391
|
+
new_material._display_name = self._display_name
|
|
392
|
+
new_material._color = self._color
|
|
393
|
+
new_material._protected = self._protected
|
|
394
|
+
new_material._user_data = None if self._user_data is None \
|
|
395
|
+
else self._user_data.copy()
|
|
396
|
+
return new_material
|
|
397
|
+
|
|
398
|
+
def __repr__(self):
|
|
399
|
+
return 'Solid THERM Material: {}'.format(self.display_name)
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""Utilities to convert THERM XML files to Material objects."""
|
|
3
|
+
from __future__ import division
|
|
4
|
+
import xml.etree.ElementTree as ET
|
|
5
|
+
|
|
6
|
+
from .solid import SolidMaterial
|
|
7
|
+
from .cavity import CavityMaterial
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def extract_all_materials_from_xml_file(xml_file, gases=None):
|
|
11
|
+
"""Extract all Material objects from a THERM XML file.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
xml_file: A path to an XML file containing objects Material objects.
|
|
15
|
+
gases: A dictionary with gas names as keys and Gas object instances
|
|
16
|
+
as values. These will be used to reassign the gas that fills
|
|
17
|
+
cavity materials. If None, only solid materials are extracted.
|
|
18
|
+
|
|
19
|
+
Returns:
|
|
20
|
+
A tuple with two elements
|
|
21
|
+
|
|
22
|
+
- solid_materials: A list of all SolidMaterial objects in the XML
|
|
23
|
+
file as fairyfly_therm SolidMaterial objects.
|
|
24
|
+
|
|
25
|
+
- cavity_materials: A list of all CavityMaterial objects in the XML
|
|
26
|
+
file as fairyfly_therm CavityMaterial objects.
|
|
27
|
+
"""
|
|
28
|
+
# read the file and get the root
|
|
29
|
+
tree = ET.parse(xml_file)
|
|
30
|
+
root = tree.getroot()
|
|
31
|
+
# extract all of the objects
|
|
32
|
+
solid_materials, cavity_materials = [], []
|
|
33
|
+
for mat_obj in root:
|
|
34
|
+
if mat_obj.find('Solid') is not None:
|
|
35
|
+
solid_materials.append(SolidMaterial.from_therm_xml(mat_obj))
|
|
36
|
+
try:
|
|
37
|
+
solid_materials.append(SolidMaterial.from_therm_xml(mat_obj))
|
|
38
|
+
except Exception: # not a valid solid material
|
|
39
|
+
pass
|
|
40
|
+
elif mat_obj.find('Cavity') is not None and gases is not None:
|
|
41
|
+
try:
|
|
42
|
+
cavity_materials.append(CavityMaterial.from_therm_xml(mat_obj, gases))
|
|
43
|
+
except Exception: # not a valid cavity material
|
|
44
|
+
pass
|
|
45
|
+
return solid_materials, cavity_materials
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fairyfly-therm
|
|
3
|
+
Version: 0.3.1
|
|
4
|
+
Summary: Fairyfly extension for translating HBJSON files to INP files for eQuest
|
|
5
|
+
Home-page: https://github.com/ladybug-tools/fairyfly-therm
|
|
6
|
+
Author: Ladybug Tools
|
|
7
|
+
Author-email: info@ladybug.tools
|
|
8
|
+
License: AGPL-3.0
|
|
9
|
+
Classifier: Programming Language :: Python :: 2.7
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
17
|
+
Classifier: Programming Language :: Python :: Implementation :: IronPython
|
|
18
|
+
Classifier: Operating System :: OS Independent
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: fairyfly-core==0.2.2
|
|
22
|
+
Dynamic: author
|
|
23
|
+
Dynamic: author-email
|
|
24
|
+
Dynamic: classifier
|
|
25
|
+
Dynamic: description
|
|
26
|
+
Dynamic: description-content-type
|
|
27
|
+
Dynamic: home-page
|
|
28
|
+
Dynamic: license
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
Dynamic: requires-dist
|
|
31
|
+
Dynamic: summary
|
|
32
|
+
|
|
33
|
+

|
|
34
|
+
<img src="https://raw.githubusercontent.com/ladybug-tools/artwork/refs/heads/master/icons_components/fairyfly/png/therm.png" alt="THERM" width="200" height="200">
|
|
35
|
+
|
|
36
|
+
[](https://github.com/ladybug-tools/fairyfly-therm/actions)
|
|
37
|
+
[](https://www.python.org/downloads/release/python-3100/)
|
|
38
|
+
[](https://www.python.org/downloads/release/python-370/)
|
|
39
|
+
[](https://www.python.org/downloads/release/python-270/)
|
|
40
|
+
[](https://github.com/IronLanguages/ironpython2/releases/tag/ipy-2.7.8/)
|
|
41
|
+
|
|
42
|
+
# fairyfly-therm
|
|
43
|
+
|
|
44
|
+
Fairyfly extension for energy modeling with LBNL THERM.
|
|
45
|
+
|
|
46
|
+
[THERM](https://windows.lbl.gov/software-tools#therm-heading) is a widely used and accepted freeware for modeling two-dimensional heat-transfer in building components such as windows, walls, foundations, etc.
|
|
47
|
+
|
|
48
|
+
## Installation
|
|
49
|
+
|
|
50
|
+
`pip install -U fairyfly-therm`
|
|
51
|
+
|
|
52
|
+
## QuickStart
|
|
53
|
+
|
|
54
|
+
```console
|
|
55
|
+
import fairyfly_therm
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## [API Documentation](http://ladybug-tools.github.io/fairyfly-therm/docs)
|
|
59
|
+
|
|
60
|
+
## Local Development
|
|
61
|
+
|
|
62
|
+
1. Clone this repo locally
|
|
63
|
+
```console
|
|
64
|
+
git clone git@github.com:ladybug-tools/fairyfly-therm
|
|
65
|
+
|
|
66
|
+
# or
|
|
67
|
+
|
|
68
|
+
git clone https://github.com/ladybug-tools/fairyfly-therm
|
|
69
|
+
```
|
|
70
|
+
2. Install dependencies:
|
|
71
|
+
```
|
|
72
|
+
cd fairyfly-therm
|
|
73
|
+
pip install -r dev-requirements.txt
|
|
74
|
+
pip install -r requirements.txt
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
3. Run Tests:
|
|
78
|
+
```console
|
|
79
|
+
python -m pytest tests/
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
4. Generate Documentation:
|
|
83
|
+
```console
|
|
84
|
+
sphinx-apidoc -f -e -d 4 -o ./docs ./fairyfly_therm
|
|
85
|
+
sphinx-build -b html ./docs ./docs/_build/docs
|
|
86
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
fairyfly_therm/__init__.py,sha256=IS7j-6gnB1EZ4__lbHKo3QxfjHizqPb87U0XbXV7QUI,290
|
|
2
|
+
fairyfly_therm/__main__.py,sha256=fobjjrmQikcHgVp8c2JotRTcQYwfQMrUbV-o9g6kgz4,77
|
|
3
|
+
fairyfly_therm/config.json,sha256=s13eKhjxbTw5vYlVN5rGuBEqKQaKvGbRQFx22sNuLAY,168
|
|
4
|
+
fairyfly_therm/config.py,sha256=znMJ7zAEbniGWU_1wuDYsRY8bM5KqVvpAbpoWVd1qtc,11540
|
|
5
|
+
fairyfly_therm/cli/__init__.py,sha256=NSHUkMKzBUlGcta1bhSiojKPdTjeAHIT6Ocn-7_gT8o,1437
|
|
6
|
+
fairyfly_therm/cli/setconfig.py,sha256=uvhon_-e6ocQKMA07F7Hg63Gwg7v1bvA2Nditu16T8g,2462
|
|
7
|
+
fairyfly_therm/condition/__init__.py,sha256=33Shb0umuvvBmKdr8UHG45z2B1EDg1_eFZLvFZJVP_U,33
|
|
8
|
+
fairyfly_therm/condition/_base.py,sha256=myWjdykScrq1VsOIBnKF0FptzJc4cSJl4iR0VaT7n48,5507
|
|
9
|
+
fairyfly_therm/condition/comprehensive.py,sha256=QMnI1A0vvFPEX8DGzi5pxxWs8HZgg9Rugbncb3C5f84,16947
|
|
10
|
+
fairyfly_therm/lib/__init__.py,sha256=W0-7G1VPDOOTi6HI1VTZGFrtqm424RkWiRH-u7lrtzo,43
|
|
11
|
+
fairyfly_therm/lib/_loadconditions.py,sha256=H9HATHZ0Pk2rmCFB5uU7685yWrCoQ21YlkcMkRAAYeg,3259
|
|
12
|
+
fairyfly_therm/lib/_loadgases.py,sha256=uyiweNk6EumWWl50wdR7pkd8Ui10KUAwU5QCtzir5ZM,3518
|
|
13
|
+
fairyfly_therm/lib/_loadmaterials.py,sha256=gokdSHwHS1mnVh5YuoqOQ3CvPC8iPVLHRddFeSyolEw,3846
|
|
14
|
+
fairyfly_therm/lib/conditions.py,sha256=n2DuyxtJl_T9-ju6GzdIOLbF3r2QrtVHuRGIL1EdjoQ,809
|
|
15
|
+
fairyfly_therm/lib/gases.py,sha256=j7s2wzSrgC6YlJx6U3EcV66No3D98bCWh0719xECYO4,993
|
|
16
|
+
fairyfly_therm/lib/materials.py,sha256=SDdNr-slmw3uAj99oaqGAguV60XodCDRjZSsOZAoOAY,1363
|
|
17
|
+
fairyfly_therm/material/__init__.py,sha256=qPr1xhKfofQo5HJ6yD1127J39eO1ci1mJIe9X3VgPk0,32
|
|
18
|
+
fairyfly_therm/material/_base.py,sha256=8p6mTSzzgwnUgQx3y_hXzfgQsf19h3w8h7qag4s-UY8,5937
|
|
19
|
+
fairyfly_therm/material/cavity.py,sha256=Yp3crAFvd5bP31zdNP1ikGaYM0rCr7sAhNr0Ba81-8E,14625
|
|
20
|
+
fairyfly_therm/material/gas.py,sha256=nV3h839ZOmJfUYb5uMg5MGm4-sQQGkHwoSm1p4hb7oo,37050
|
|
21
|
+
fairyfly_therm/material/solid.py,sha256=s-uC2Ok2extCM8u6NhydC-ALoBl38iTTGOMFtIWim80,16056
|
|
22
|
+
fairyfly_therm/material/xmlutil.py,sha256=mTAYIq5wvZmwlxOz2meSkAIO5TYSQAYz1CNO7datbVk,1776
|
|
23
|
+
fairyfly_therm-0.3.1.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
|
|
24
|
+
fairyfly_therm-0.3.1.dist-info/METADATA,sha256=piH88aEaTHGhIrDj0LvFWyQ6MJ2GXmWoK9iIcQIzZhY,3026
|
|
25
|
+
fairyfly_therm-0.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
26
|
+
fairyfly_therm-0.3.1.dist-info/entry_points.txt,sha256=DMC3oL1yMvUCIXs6wVN6UioSZVWMH2QXm_Vk4iXe7Sg,60
|
|
27
|
+
fairyfly_therm-0.3.1.dist-info/top_level.txt,sha256=XBeq4SaQHPgh0KaC7FvobpLAOs3-pphzpi4DiM1WLSA,15
|
|
28
|
+
fairyfly_therm-0.3.1.dist-info/RECORD,,
|