Source code for pythermalcomfort.models.utci

import numpy as np
from numba import vectorize, float64

from pythermalcomfort.shared_functions import valid_range
from pythermalcomfort.utilities import (
    units_converter,
    mapping,
)


[docs]def utci(tdb, tr, v, rh, units="SI", return_stress_category=False, limit_inputs=True): """Determines the Universal Thermal Climate Index (UTCI). The UTCI is the equivalent temperature for the environment derived from a reference environment. It is defined as the air temperature of the reference environment which produces the same strain index value in comparison with the reference individual's response to the real environment. It is regarded as one of the most comprehensive indices for calculating heat stress in outdoor spaces. The parameters that are taken into account for calculating UTCI involve dry bulb temperature, mean radiation temperature, the pressure of water vapor or relative humidity, and wind speed (at the elevation of 10 m above the ground). [7]_ Parameters ---------- tdb : float, int, or array-like dry bulb air temperature, default in [°C] in [°F] if `units` = 'IP' tr : float, int, or array-like mean radiant temperature, default in [°C] in [°F] if `units` = 'IP' v : float, int, or array-like wind speed 10m above ground level, default in [m/s] in [fps] if `units` = 'IP' rh : float, int, or array-like relative humidity, [%] units : {'SI', 'IP'} select the SI (International System of Units) or the IP (Imperial Units) system. return_stress_category : boolean default False if True returns the UTCI categorized in terms of thermal stress. limit_inputs : boolean default True By default, if the inputs are outsude the standard applicability limits the function returns nan. If False returns UTCI values even if input values are outside the applicability limits of the model. The valid input ranges are -50 < tdb [°C] < 50, tdb - 70 < tr [°C] < tdb + 30, and for 0.5 < v [m/s] < 17.0. Returns ------- utci : float, int, or array-like Universal Thermal Climate Index, [°C] or in [°F] stress_category : str or array-like UTCI categorized in terms of thermal stress [9]_. Notes ----- You can use this function to calculate the Universal Thermal Climate Index (`UTCI`) The applicability wind speed value must be between 0.5 and 17 m/s. .. _UTCI: https://www.utci.org/ Examples -------- .. code-block:: python >>> from pythermalcomfort.models import utci >>> utci(tdb=25, tr=25, v=1.0, rh=50) 24.6 >>> # for users who wants to use the IP system >>> utci(tdb=77, tr=77, v=3.28, rh=50, units='ip') 76.4 >>> # for users who wants to get stress category >>> utci(tdb=25, tr=25, v=1.0, rh=50, return_stress_category=True) {"utci": 24.6, "stress_category": "no thermal stress"} Raises ------ ValueError Raised if the input are outside the Standard's applicability limits """ tdb = np.array(tdb) tr = np.array(tr) v = np.array(v) rh = np.array(rh) if units.lower() == "ip": tdb, tr, v = units_converter(tdb=tdb, tr=tr, v=v) def exponential(t_db): g = [ -2836.5744, -6028.076559, 19.54263612, -0.02737830188, 0.000016261698, (7.0229056 * np.power(10.0, -10)), (-1.8680009 * np.power(10.0, -13)), ] tk = t_db + 273.15 # air temp in K es = 2.7150305 * np.log1p(tk) for count, i in enumerate(g): es = es + (i * np.power(tk, count - 2)) es = np.exp(es) * 0.01 # convert Pa to hPa return es eh_pa = exponential(tdb) * (rh / 100.0) delta_t_tr = tr - tdb pa = eh_pa / 10.0 # convert vapour pressure to kPa utci_approx = _utci_optimized(tdb, v, delta_t_tr, pa) # Checks that inputs are within the bounds accepted by the model if not return nan if limit_inputs: tdb_valid = valid_range(tdb, (-50.0, 50.0)) diff_valid = valid_range(tr - tdb, (-30.0, 70.0)) v_valid = valid_range(v, (0.5, 17.0)) all_valid = ~(np.isnan(tdb_valid) | np.isnan(diff_valid) | np.isnan(v_valid)) utci_approx = np.where(all_valid, utci_approx, np.nan) if units.lower() == "ip": utci_approx = units_converter(tmp=utci_approx, from_units="si")[0] if return_stress_category: stress_categories = { -40.0: "extreme cold stress", -27.0: "very strong cold stress", -13.0: "strong cold stress", 0.0: "moderate cold stress", 9.0: "slight cold stress", 26.0: "no thermal stress", 32.0: "moderate heat stress", 38.0: "strong heat stress", 46.0: "very strong heat stress", 1000.0: "extreme heat stress", } return { "utci": np.round(utci_approx, 1), "stress_category": mapping(utci_approx, stress_categories), } else: return np.round(utci_approx, 1)
@vectorize( [ float64( float64, float64, float64, float64, ) ], ) def _utci_optimized(tdb, v, delta_t_tr, pa): return ( tdb + 0.607562052 + (-0.0227712343) * tdb + (8.06470249 * (10 ** (-4))) * tdb * tdb + (-1.54271372 * (10 ** (-4))) * tdb * tdb * tdb + (-3.24651735 * (10 ** (-6))) * tdb * tdb * tdb * tdb + (7.32602852 * (10 ** (-8))) * tdb * tdb * tdb * tdb * tdb + (1.35959073 * (10 ** (-9))) * tdb * tdb * tdb * tdb * tdb * tdb + (-2.25836520) * v + 0.0880326035 * tdb * v + 0.00216844454 * tdb * tdb * v + (-1.53347087 * (10 ** (-5))) * tdb * tdb * tdb * v + (-5.72983704 * (10 ** (-7))) * tdb * tdb * tdb * tdb * v + (-2.55090145 * (10 ** (-9))) * tdb * tdb * tdb * tdb * tdb * v + (-0.751269505) * v * v + (-0.00408350271) * tdb * v * v + (-5.21670675 * (10 ** (-5))) * tdb * tdb * v * v + (1.94544667 * (10 ** (-6))) * tdb * tdb * tdb * v * v + (1.14099531 * (10 ** (-8))) * tdb * tdb * tdb * tdb * v * v + 0.158137256 * v * v * v + (-6.57263143 * (10 ** (-5))) * tdb * v * v * v + (2.22697524 * (10 ** (-7))) * tdb * tdb * v * v * v + (-4.16117031 * (10 ** (-8))) * tdb * tdb * tdb * v * v * v + (-0.0127762753) * v * v * v * v + (9.66891875 * (10 ** (-6))) * tdb * v * v * v * v + (2.52785852 * (10 ** (-9))) * tdb * tdb * v * v * v * v + (4.56306672 * (10 ** (-4))) * v * v * v * v * v + (-1.74202546 * (10 ** (-7))) * tdb * v * v * v * v * v + (-5.91491269 * (10 ** (-6))) * v * v * v * v * v * v + 0.398374029 * delta_t_tr + (1.83945314 * (10 ** (-4))) * tdb * delta_t_tr + (-1.73754510 * (10 ** (-4))) * tdb * tdb * delta_t_tr + (-7.60781159 * (10 ** (-7))) * tdb * tdb * tdb * delta_t_tr + (3.77830287 * (10 ** (-8))) * tdb * tdb * tdb * tdb * delta_t_tr + (5.43079673 * (10 ** (-10))) * tdb * tdb * tdb * tdb * tdb * delta_t_tr + (-0.0200518269) * v * delta_t_tr + (8.92859837 * (10 ** (-4))) * tdb * v * delta_t_tr + (3.45433048 * (10 ** (-6))) * tdb * tdb * v * delta_t_tr + (-3.77925774 * (10 ** (-7))) * tdb * tdb * tdb * v * delta_t_tr + (-1.69699377 * (10 ** (-9))) * tdb * tdb * tdb * tdb * v * delta_t_tr + (1.69992415 * (10 ** (-4))) * v * v * delta_t_tr + (-4.99204314 * (10 ** (-5))) * tdb * v * v * delta_t_tr + (2.47417178 * (10 ** (-7))) * tdb * tdb * v * v * delta_t_tr + (1.07596466 * (10 ** (-8))) * tdb * tdb * tdb * v * v * delta_t_tr + (8.49242932 * (10 ** (-5))) * v * v * v * delta_t_tr + (1.35191328 * (10 ** (-6))) * tdb * v * v * v * delta_t_tr + (-6.21531254 * (10 ** (-9))) * tdb * tdb * v * v * v * delta_t_tr + (-4.99410301 * (10 ** (-6))) * v * v * v * v * delta_t_tr + (-1.89489258 * (10 ** (-8))) * tdb * v * v * v * v * delta_t_tr + (8.15300114 * (10 ** (-8))) * v * v * v * v * v * delta_t_tr + (7.55043090 * (10 ** (-4))) * delta_t_tr * delta_t_tr + (-5.65095215 * (10 ** (-5))) * tdb * delta_t_tr * delta_t_tr + (-4.52166564 * (10 ** (-7))) * tdb * tdb * delta_t_tr * delta_t_tr + (2.46688878 * (10 ** (-8))) * tdb * tdb * tdb * delta_t_tr * delta_t_tr + (2.42674348 * (10 ** (-10))) * tdb * tdb * tdb * tdb * delta_t_tr * delta_t_tr + (1.54547250 * (10 ** (-4))) * v * delta_t_tr * delta_t_tr + (5.24110970 * (10 ** (-6))) * tdb * v * delta_t_tr * delta_t_tr + (-8.75874982 * (10 ** (-8))) * tdb * tdb * v * delta_t_tr * delta_t_tr + (-1.50743064 * (10 ** (-9))) * tdb * tdb * tdb * v * delta_t_tr * delta_t_tr + (-1.56236307 * (10 ** (-5))) * v * v * delta_t_tr * delta_t_tr + (-1.33895614 * (10 ** (-7))) * tdb * v * v * delta_t_tr * delta_t_tr + (2.49709824 * (10 ** (-9))) * tdb * tdb * v * v * delta_t_tr * delta_t_tr + (6.51711721 * (10 ** (-7))) * v * v * v * delta_t_tr * delta_t_tr + (1.94960053 * (10 ** (-9))) * tdb * v * v * v * delta_t_tr * delta_t_tr + (-1.00361113 * (10 ** (-8))) * v * v * v * v * delta_t_tr * delta_t_tr + (-1.21206673 * (10 ** (-5))) * delta_t_tr * delta_t_tr * delta_t_tr + (-2.18203660 * (10 ** (-7))) * tdb * delta_t_tr * delta_t_tr * delta_t_tr + (7.51269482 * (10 ** (-9))) * tdb * tdb * delta_t_tr * delta_t_tr * delta_t_tr + (9.79063848 * (10 ** (-11))) * tdb * tdb * tdb * delta_t_tr * delta_t_tr * delta_t_tr + (1.25006734 * (10 ** (-6))) * v * delta_t_tr * delta_t_tr * delta_t_tr + (-1.81584736 * (10 ** (-9))) * tdb * v * delta_t_tr * delta_t_tr * delta_t_tr + (-3.52197671 * (10 ** (-10))) * tdb * tdb * v * delta_t_tr * delta_t_tr * delta_t_tr + (-3.36514630 * (10 ** (-8))) * v * v * delta_t_tr * delta_t_tr * delta_t_tr + (1.35908359 * (10 ** (-10))) * tdb * v * v * delta_t_tr * delta_t_tr * delta_t_tr + (4.17032620 * (10 ** (-10))) * v * v * v * delta_t_tr * delta_t_tr * delta_t_tr + (-1.30369025 * (10 ** (-9))) * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr + (4.13908461 * (10 ** (-10))) * tdb * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr + (9.22652254 * (10 ** (-12))) * tdb * tdb * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr + (-5.08220384 * (10 ** (-9))) * v * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr + (-2.24730961 * (10 ** (-11))) * tdb * v * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr + (1.17139133 * (10 ** (-10))) * v * v * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr + (6.62154879 * (10 ** (-10))) * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr + (4.03863260 * (10 ** (-13))) * tdb * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr + (1.95087203 * (10 ** (-12))) * v * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr + (-4.73602469 * (10 ** (-12))) * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr + 5.12733497 * pa + (-0.312788561) * tdb * pa + (-0.0196701861) * tdb * tdb * pa + (9.99690870 * (10 ** (-4))) * tdb * tdb * tdb * pa + (9.51738512 * (10 ** (-6))) * tdb * tdb * tdb * tdb * pa + (-4.66426341 * (10 ** (-7))) * tdb * tdb * tdb * tdb * tdb * pa + 0.548050612 * v * pa + (-0.00330552823) * tdb * v * pa + (-0.00164119440) * tdb * tdb * v * pa + (-5.16670694 * (10 ** (-6))) * tdb * tdb * tdb * v * pa + (9.52692432 * (10 ** (-7))) * tdb * tdb * tdb * tdb * v * pa + (-0.0429223622) * v * v * pa + 0.00500845667 * tdb * v * v * pa + (1.00601257 * (10 ** (-6))) * tdb * tdb * v * v * pa + (-1.81748644 * (10 ** (-6))) * tdb * tdb * tdb * v * v * pa + (-1.25813502 * (10 ** (-3))) * v * v * v * pa + (-1.79330391 * (10 ** (-4))) * tdb * v * v * v * pa + (2.34994441 * (10 ** (-6))) * tdb * tdb * v * v * v * pa + (1.29735808 * (10 ** (-4))) * v * v * v * v * pa + (1.29064870 * (10 ** (-6))) * tdb * v * v * v * v * pa + (-2.28558686 * (10 ** (-6))) * v * v * v * v * v * pa + (-0.0369476348) * delta_t_tr * pa + 0.00162325322 * tdb * delta_t_tr * pa + (-3.14279680 * (10 ** (-5))) * tdb * tdb * delta_t_tr * pa + (2.59835559 * (10 ** (-6))) * tdb * tdb * tdb * delta_t_tr * pa + (-4.77136523 * (10 ** (-8))) * tdb * tdb * tdb * tdb * delta_t_tr * pa + (8.64203390 * (10 ** (-3))) * v * delta_t_tr * pa + (-6.87405181 * (10 ** (-4))) * tdb * v * delta_t_tr * pa + (-9.13863872 * (10 ** (-6))) * tdb * tdb * v * delta_t_tr * pa + (5.15916806 * (10 ** (-7))) * tdb * tdb * tdb * v * delta_t_tr * pa + (-3.59217476 * (10 ** (-5))) * v * v * delta_t_tr * pa + (3.28696511 * (10 ** (-5))) * tdb * v * v * delta_t_tr * pa + (-7.10542454 * (10 ** (-7))) * tdb * tdb * v * v * delta_t_tr * pa + (-1.24382300 * (10 ** (-5))) * v * v * v * delta_t_tr * pa + (-7.38584400 * (10 ** (-9))) * tdb * v * v * v * delta_t_tr * pa + (2.20609296 * (10 ** (-7))) * v * v * v * v * delta_t_tr * pa + (-7.32469180 * (10 ** (-4))) * delta_t_tr * delta_t_tr * pa + (-1.87381964 * (10 ** (-5))) * tdb * delta_t_tr * delta_t_tr * pa + (4.80925239 * (10 ** (-6))) * tdb * tdb * delta_t_tr * delta_t_tr * pa + (-8.75492040 * (10 ** (-8))) * tdb * tdb * tdb * delta_t_tr * delta_t_tr * pa + (2.77862930 * (10 ** (-5))) * v * delta_t_tr * delta_t_tr * pa + (-5.06004592 * (10 ** (-6))) * tdb * v * delta_t_tr * delta_t_tr * pa + (1.14325367 * (10 ** (-7))) * tdb * tdb * v * delta_t_tr * delta_t_tr * pa + (2.53016723 * (10 ** (-6))) * v * v * delta_t_tr * delta_t_tr * pa + (-1.72857035 * (10 ** (-8))) * tdb * v * v * delta_t_tr * delta_t_tr * pa + (-3.95079398 * (10 ** (-8))) * v * v * v * delta_t_tr * delta_t_tr * pa + (-3.59413173 * (10 ** (-7))) * delta_t_tr * delta_t_tr * delta_t_tr * pa + (7.04388046 * (10 ** (-7))) * tdb * delta_t_tr * delta_t_tr * delta_t_tr * pa + (-1.89309167 * (10 ** (-8))) * tdb * tdb * delta_t_tr * delta_t_tr * delta_t_tr * pa + (-4.79768731 * (10 ** (-7))) * v * delta_t_tr * delta_t_tr * delta_t_tr * pa + (7.96079978 * (10 ** (-9))) * tdb * v * delta_t_tr * delta_t_tr * delta_t_tr * pa + (1.62897058 * (10 ** (-9))) * v * v * delta_t_tr * delta_t_tr * delta_t_tr * pa + (3.94367674 * (10 ** (-8))) * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr * pa + (-1.18566247 * (10 ** (-9))) * tdb * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr * pa + (3.34678041 * (10 ** (-10))) * v * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr * pa + (-1.15606447 * (10 ** (-10))) * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr * pa + (-2.80626406) * pa * pa + 0.548712484 * tdb * pa * pa + (-0.00399428410) * tdb * tdb * pa * pa + (-9.54009191 * (10 ** (-4))) * tdb * tdb * tdb * pa * pa + (1.93090978 * (10 ** (-5))) * tdb * tdb * tdb * tdb * pa * pa + (-0.308806365) * v * pa * pa + 0.0116952364 * tdb * v * pa * pa + (4.95271903 * (10 ** (-4))) * tdb * tdb * v * pa * pa + (-1.90710882 * (10 ** (-5))) * tdb * tdb * tdb * v * pa * pa + 0.00210787756 * v * v * pa * pa + (-6.98445738 * (10 ** (-4))) * tdb * v * v * pa * pa + (2.30109073 * (10 ** (-5))) * tdb * tdb * v * v * pa * pa + (4.17856590 * (10 ** (-4))) * v * v * v * pa * pa + (-1.27043871 * (10 ** (-5))) * tdb * v * v * v * pa * pa + (-3.04620472 * (10 ** (-6))) * v * v * v * v * pa * pa + 0.0514507424 * delta_t_tr * pa * pa + (-0.00432510997) * tdb * delta_t_tr * pa * pa + (8.99281156 * (10 ** (-5))) * tdb * tdb * delta_t_tr * pa * pa + (-7.14663943 * (10 ** (-7))) * tdb * tdb * tdb * delta_t_tr * pa * pa + (-2.66016305 * (10 ** (-4))) * v * delta_t_tr * pa * pa + (2.63789586 * (10 ** (-4))) * tdb * v * delta_t_tr * pa * pa + (-7.01199003 * (10 ** (-6))) * tdb * tdb * v * delta_t_tr * pa * pa + (-1.06823306 * (10 ** (-4))) * v * v * delta_t_tr * pa * pa + (3.61341136 * (10 ** (-6))) * tdb * v * v * delta_t_tr * pa * pa + (2.29748967 * (10 ** (-7))) * v * v * v * delta_t_tr * pa * pa + (3.04788893 * (10 ** (-4))) * delta_t_tr * delta_t_tr * pa * pa + (-6.42070836 * (10 ** (-5))) * tdb * delta_t_tr * delta_t_tr * pa * pa + (1.16257971 * (10 ** (-6))) * tdb * tdb * delta_t_tr * delta_t_tr * pa * pa + (7.68023384 * (10 ** (-6))) * v * delta_t_tr * delta_t_tr * pa * pa + (-5.47446896 * (10 ** (-7))) * tdb * v * delta_t_tr * delta_t_tr * pa * pa + (-3.59937910 * (10 ** (-8))) * v * v * delta_t_tr * delta_t_tr * pa * pa + (-4.36497725 * (10 ** (-6))) * delta_t_tr * delta_t_tr * delta_t_tr * pa * pa + (1.68737969 * (10 ** (-7))) * tdb * delta_t_tr * delta_t_tr * delta_t_tr * pa * pa + (2.67489271 * (10 ** (-8))) * v * delta_t_tr * delta_t_tr * delta_t_tr * pa * pa + (3.23926897 * (10 ** (-9))) * delta_t_tr * delta_t_tr * delta_t_tr * delta_t_tr * pa * pa + (-0.0353874123) * pa * pa * pa + (-0.221201190) * tdb * pa * pa * pa + 0.0155126038 * tdb * tdb * pa * pa * pa + (-2.63917279 * (10 ** (-4))) * tdb * tdb * tdb * pa * pa * pa + 0.0453433455 * v * pa * pa * pa + (-0.00432943862) * tdb * v * pa * pa * pa + (1.45389826 * (10 ** (-4))) * tdb * tdb * v * pa * pa * pa + (2.17508610 * (10 ** (-4))) * v * v * pa * pa * pa + (-6.66724702 * (10 ** (-5))) * tdb * v * v * pa * pa * pa + (3.33217140 * (10 ** (-5))) * v * v * v * pa * pa * pa + (-0.00226921615) * delta_t_tr * pa * pa * pa + (3.80261982 * (10 ** (-4))) * tdb * delta_t_tr * pa * pa * pa + (-5.45314314 * (10 ** (-9))) * tdb * tdb * delta_t_tr * pa * pa * pa + (-7.96355448 * (10 ** (-4))) * v * delta_t_tr * pa * pa * pa + (2.53458034 * (10 ** (-5))) * tdb * v * delta_t_tr * pa * pa * pa + (-6.31223658 * (10 ** (-6))) * v * v * delta_t_tr * pa * pa * pa + (3.02122035 * (10 ** (-4))) * delta_t_tr * delta_t_tr * pa * pa * pa + (-4.77403547 * (10 ** (-6))) * tdb * delta_t_tr * delta_t_tr * pa * pa * pa + (1.73825715 * (10 ** (-6))) * v * delta_t_tr * delta_t_tr * pa * pa * pa + (-4.09087898 * (10 ** (-7))) * delta_t_tr * delta_t_tr * delta_t_tr * pa * pa * pa + 0.614155345 * pa * pa * pa * pa + (-0.0616755931) * tdb * pa * pa * pa * pa + 0.00133374846 * tdb * tdb * pa * pa * pa * pa + 0.00355375387 * v * pa * pa * pa * pa + (-5.13027851 * (10 ** (-4))) * tdb * v * pa * pa * pa * pa + (1.02449757 * (10 ** (-4))) * v * v * pa * pa * pa * pa + (-0.00148526421) * delta_t_tr * pa * pa * pa * pa + (-4.11469183 * (10 ** (-5))) * tdb * delta_t_tr * pa * pa * pa * pa + (-6.80434415 * (10 ** (-6))) * v * delta_t_tr * pa * pa * pa * pa + (-9.77675906 * (10 ** (-6))) * delta_t_tr * delta_t_tr * pa * pa * pa * pa + 0.0882773108 * pa * pa * pa * pa * pa + (-0.00301859306) * tdb * pa * pa * pa * pa * pa + 0.00104452989 * v * pa * pa * pa * pa * pa + (2.47090539 * (10 ** (-4))) * delta_t_tr * pa * pa * pa * pa * pa + 0.00148348065 * pa * pa * pa * pa * pa * pa )