CenterForTheBuiltEnvironment / pythermalcomfort
1 9
import warnings
2

3 9
warnings.simplefilter("always")
4

5

6 9
def check_standard_compliance(standard, **kwargs):
7 9
    params = dict()
8 9
    params["standard"] = standard
9 9
    for key, value in kwargs.items():
10 9
        params[key] = value
11

12 9
    if params["standard"] == "utci":
13 9
        for key, value in params.items():
14 9
            if key == "v":
15 9
                if value > 17:
16 0
                    warnings.warn(
17
                        "UTCI wind speed applicability limits between 0.5 and 17 m/s",
18
                        UserWarning,
19
                    )
20 9
                elif value < 0.5:
21 0
                    warnings.warn(
22
                        "UTCI wind speed applicability limits between 0.5 and 17 m/s",
23
                        UserWarning,
24
                    )
25

26 9
    elif params["standard"] == "ashrae":  # based on table 7.3.4 ashrae 55 2017
27 9
        for key, value in params.items():
28 9
            if key in ["tdb", "tr"]:
29 9
                if key == "tdb":
30 9
                    parameter = "dry-bulb"
31
                else:
32 9
                    parameter = "mean radiant"
33 9
                if value > 40 or value < 10:
34 9
                    warnings.warn(
35
                        f"ASHRAE {parameter} temperature applicability limits between 10 and 40 °C",
36
                        UserWarning,
37
                    )
38 9
            if key in ["v", "vr"]:
39 9
                if value > 2 or value < 0:
40 9
                    warnings.warn(
41
                        "ASHRAE air velocity applicability limits between 0 and 2 m/s",
42
                        UserWarning,
43
                    )
44 9
            if key == "met":
45 9
                if value > 2 or value < 1:
46 9
                    warnings.warn(
47
                        "ASHRAE met applicability limits between 1.0 and 2.0 met",
48
                        UserWarning,
49
                    )
50 9
            if key == "clo":
51 9
                if value > 1.5 or value < 0:
52 9
                    warnings.warn(
53
                        "ASHRAE clo applicability limits between 0.0 and 1.5 clo",
54
                        UserWarning,
55
                    )
56 9
            if key == "v_limited":
57 9
                if value > 0.2:
58 9
                    raise ValueError(
59
                        "This equation is only applicable for air speed lower than 0.2 m/s"
60
                    )
61

62 9
    elif params["standard"] == "iso":  # based on ISO 7730:2005 page 3
63 9
        for key, value in params.items():
64 9
            if key == "tdb":
65 9
                if value > 30 or value < 10:
66 0
                    warnings.warn(
67
                        "ISO air temperature applicability limits between 10 and 30 °C",
68
                        UserWarning,
69
                    )
70 9
            if key == "tr":
71 9
                if value > 40 or value < 10:
72 0
                    warnings.warn(
73
                        "ISO mean radiant temperature applicability limits between 10 and 40 °C",
74
                        UserWarning,
75
                    )
76 9
            if key in ["v", "vr"]:
77 9
                if value > 1 or value < 0:
78 0
                    warnings.warn(
79
                        "ISO air velocity applicability limits between 0 and 1 m/s",
80
                        UserWarning,
81
                    )
82 9
            if key == "met":
83 9
                if value > 4 or value < 0.8:
84 0
                    warnings.warn(
85
                        "ISO met applicability limits between 0.8 and 4.0 met",
86
                        UserWarning,
87
                    )
88 9
            if key == "clo":
89 9
                if value > 2 or value < 0:
90 0
                    warnings.warn(
91
                        "ISO clo applicability limits between 0.0 and 2 clo",
92
                        UserWarning,
93
                    )
94

95

96 9
def secant(f, a, b, n):
97
    """Approximate solution of f(x)=0 on interval [a,b] by the secant method.
98

99
    Parameters
100
    ----------
101
    f : function
102
        The function for which we are trying to approximate a solution f(x)=0.
103
    a,b : numbers
104
        The interval in which to search for a solution. The function returns
105
        None if f(a)*f(b) >= 0 since a solution is not guaranteed.
106
    n : (positive) integer
107
        The number of iterations to implement.
108

109
    Returns
110
    -------
111
    m_N : number
112
        The x intercept of the secant line on the the Nth interval
113
            m_n = a_n - f(a_n)*(b_n - a_n)/(f(b_n) - f(a_n))
114
        The initial interval [a_0,b_0] is given by [a,b]. If f(m_n) == 0
115
        for some intercept m_n then the function returns this solution.
116
        If all signs of values f(a_n), f(b_n) and f(m_n) are the same at any
117
        iterations, the secant method fails and return None.
118

119
    Examples
120
    --------
121
    >>> f = lambda x: x**2 - x - 1
122
    >>> secant(f,1,2,5)
123
    1.6180257510729614
124
    """
125 9
    if f(a) * f(b) >= 0:
126 0
        print("Secant method fails.")
127 0
        return None
128 0
    a_n = a
129 0
    b_n = b
130 9
    for n in range(1, n + 1):
131 0
        m_n = a_n - f(a_n) * (b_n - a_n) / (f(b_n) - f(a_n))
132 0
        f_m_n = f(m_n)
133 9
        if f(a_n) * f_m_n < 0:
134 0
            a_n = a_n
135 0
            b_n = m_n
136 9
        elif f(b_n) * f_m_n < 0:
137 0
            a_n = m_n
138 0
            b_n = b_n
139 9
        elif f_m_n == 0:
140
            # print("Found exact solution.")
141 0
            return m_n
142
        else:
143
            # print("Secant method fails.")
144 0
            return None
145 0
    return a_n - f(a_n) * (b_n - a_n) / (f(b_n) - f(a_n))
146

147

148 9
def bisection(f, a, b, max_iterations, error=0.01):
149
    """Approximate solution of f(x)=0 on interval [a,b] by the bisection method.
150

151
    Parameters
152
    ----------
153
    f : function
154
        The function for which we are trying to approximate a solution f(x)=0.
155
    a,b : numbers
156
        The interval in which to search for a solution. The function returns
157
        None if f(a)*f(b) >= 0 since a solution is not guaranteed.
158
    max_iterations : (positive) integer
159
        The number of iterations to implement.
160
    error: (positive) float
161
        The max error that is accepted
162

163
    Returns
164
    -------
165
    x_N : number
166
        The midpoint of the Nth interval computed by the bisection method. The
167
        initial interval [a_0,b_0] is given by [a,b]. If f(m_n) == 0 for some
168
        midpoint m_n = (a_n + b_n)/2, then the function returns this solution.
169
        If all signs of values f(a_n), f(b_n) and f(m_n) are the same at any
170
        iteration, the bisection method fails and return None.
171

172
    Examples
173
    --------
174
    >>> f = lambda x: x**2 - x - 1
175
    >>> bisection(f,1,2,25)
176
    1.618033990263939
177
    >>> f = lambda x: (2*x - 1)*(x - 3)
178
    >>> bisection(f,0,1,10)
179
    0.5
180
    """
181
    # check that the two values have opposite signs
182 9
    if f(a) * f(b) >= 0:
183 0
        return None
184 0
    a_n = a
185 0
    b_n = b
186 0
    n = 0
187 9
    while error < abs(f(a_n) - f(b_n)):
188 0
        m_n = (a_n + b_n) / 2
189 0
        f_m_n = f(m_n)
190

191 0
        n += 1
192 9
        if n > max_iterations:
193 0
            return None
194

195 9
        if error > abs(f(a_n) - f(b_n)):
196 0
            return (a_n + b_n) / 2
197 9
        elif f(a_n) * f_m_n < 0:
198 0
            a_n = a_n
199 0
            b_n = m_n
200 9
        elif f(b_n) * f_m_n < 0:
201 0
            a_n = m_n
202 0
            b_n = b_n
203 9
        elif f_m_n == 0:
204
            # print("Found exact solution.")
205 0
            return m_n
206
        else:
207
            # print("Bisection method fails.")
208 0
            return None
209 0
    return (a_n + b_n) / 2
210

211

212
#: This dictionary contains the met values of typical tasks.
213 9
met_typical_tasks = {
214
    "Sleeping": 0.7,
215
    "Reclining": 0.8,
216
    "Seated, quiet": 1.0,
217
    "Reading, seated": 1.0,
218
    "Writing": 1.0,
219
    "Typing": 1.1,
220
    "Standing, relaxed": 1.2,
221
    "Filing, seated": 1.2,
222
    "Flying aircraft, routine": 1.2,
223
    "Filing, standing": 1.4,
224
    "Driving a car": 1.5,
225
    "Walking about": 1.7,
226
    "Cooking": 1.8,
227
    "Table sawing": 1.8,
228
    "Walking 2mph (3.2kmh)": 2.0,
229
    "Lifting/packing": 2.1,
230
    "Seated, heavy limb movement": 2.2,
231
    "Light machine work": 2.2,
232
    "Flying aircraft, combat": 2.4,
233
    "Walking 3mph (4.8kmh)": 2.6,
234
    "House cleaning": 2.7,
235
    "Driving, heavy vehicle": 3.2,
236
    "Dancing": 3.4,
237
    "Calisthenics": 3.5,
238
    "Walking 4mph (6.4kmh)": 3.8,
239
    "Tennis": 3.8,
240
    "Heavy machine work": 4.0,
241
    "Handling 100lb (45 kg) bags": 4.0,
242
    "Pick and shovel work": 4.4,
243
    "Basketball": 6.3,
244
    "Wrestling": 7.8,
245
}
246

247
#: This dictionary contains the total clothing insulation of typical typical ensembles.
248 9
clo_typical_ensembles = {
249
    "Walking shorts, short-sleeve shirt": 0.36,
250
    "Typical summer indoor clothing": 0.5,
251
    "Knee-length skirt, short-sleeve shirt, sandals, underwear": 0.54,
252
    "Trousers, short-sleeve shirt, socks, shoes, underwear": 0.57,
253
    "Trousers, long-sleeve shirt": 0.61,
254
    "Knee-length skirt, long-sleeve shirt, full slip": 0.67,
255
    "Sweat pants, long-sleeve sweatshirt": 0.74,
256
    "Jacket, Trousers, long-sleeve shirt": 0.96,
257
    "Typical winter indoor clothing": 1.0,
258
}
259

260
#: This dictionary contains the clo values of individual clothing elements. To calculate the total clothing insulation you need to add these values together.
261 9
clo_individual_garments = {
262
    "Metal chair": 0.00,
263
    "Bra": 0.01,
264
    "Wooden stool": 0.01,
265
    "Ankle socks": 0.02,
266
    "Shoes or sandals": 0.02,
267
    "Slippers": 0.03,
268
    "Panty hose": 0.02,
269
    "Calf length socks": 0.03,
270
    "Women's underwear": 0.03,
271
    "Men's underwear": 0.04,
272
    "Knee socks (thick)": 0.06,
273
    "Short shorts": 0.06,
274
    "Walking shorts": 0.08,
275
    "T-shirt": 0.08,
276
    "Standard office chair": 0.10,
277
    "Executive chair": 0.15,
278
    "Boots": 0.1,
279
    "Sleeveless scoop-neck blouse": 0.12,
280
    "Half slip": 0.14,
281
    "Long underwear bottoms": 0.15,
282
    "Full slip": 0.16,
283
    "Short-sleeve knit shirt": 0.17,
284
    "Sleeveless vest (thin)": 0.1,
285
    "Sleeveless vest (thick)": 0.17,
286
    "Sleeveless short gown (thin)": 0.18,
287
    "Short-sleeve dress shirt": 0.19,
288
    "Sleeveless long gown (thin)": 0.2,
289
    "Long underwear top": 0.2,
290
    "Thick skirt": 0.23,
291
    "Long-sleeve dress shirt": 0.25,
292
    "Long-sleeve flannel shirt": 0.34,
293
    "Long-sleeve sweat shirt": 0.34,
294
    "Short-sleeve hospital gown": 0.31,
295
    "Short-sleeve short robe (thin)": 0.34,
296
    "Short-sleeve pajamas": 0.42,
297
    "Long-sleeve long gown": 0.46,
298
    "Long-sleeve short wrap robe (thick)": 0.48,
299
    "Long-sleeve pajamas (thick)": 0.57,
300
    "Long-sleeve long wrap robe (thick)": 0.69,
301
    "Thin trousers": 0.15,
302
    "Thick trousers": 0.24,
303
    "Sweatpants": 0.28,
304
    "Overalls": 0.30,
305
    "Coveralls": 0.49,
306
    "Thin skirt": 0.14,
307
    "Long-sleeve shirt dress (thin)": 0.33,
308
    "Long-sleeve shirt dress (thick)": 0.47,
309
    "Short-sleeve shirt dress": 0.29,
310
    "Sleeveless, scoop-neck shirt (thin)": 0.23,
311
    "Sleeveless, scoop-neck shirt (thick)": 0.27,
312
    "Long sleeve shirt (thin)": 0.25,
313
    "Long sleeve shirt (thick)": 0.36,
314
    "Single-breasted coat (thin)": 0.36,
315
    "Single-breasted coat (thick)": 0.44,
316
    "Double-breasted coat (thin)": 0.42,
317
    "Double-breasted coat (thick)": 0.48,
318
}

Read our documentation on viewing source code .

Loading