jsthermalcomfort

0.1.5

Overview

docs docs
build build
tests test
page deployment page deployment
snyk security synk
license license
npm version npm

Package to calculate thermophysiological, thermal comfort, thermal stress indices, in JavaScript.

Please cite us if you use this package: Tartarini, F., Schiavon, S., 2020. pythermalcomfort: A Python package for thermal comfort research. SoftwareX 12, 100578. https://doi.org/10.1016/j.softx.2020.100578

Official Documentation Website

https://federicotartarini.github.io/jsthermalcomfort/

Installation

npm install jsthermalcomfort

If you want to use jsthermalcomfort package without installing it on your local machine, you can import with:

https://cdn.jsdelivr.net/gh/FedericoTartarini/jsthermalcomfort/lib/esm/

Example:

import { models, utilities, pschymetrics } from "https://cdn.jsdelivr.net/gh/FedericoTartarini/jsthermalcomfort/lib/esm/index.js"

You can also import it in the website directly, and caution that you need to mark the script as module:

<script type="module">
  import { models, utilities, pschymetrics } from "https://cdn.jsdelivr.net/gh/FedericoTartarini/jsthermalcomfort/lib/esm/index.js"
</script>

Examples and Tutorials

We developed a few examples files on how to use some of the functions.

Here is a list of examples running in the browser:

Functions Documentation

Comfort Models
Heat Index

Calculates the Heat Index (HI). It combines air temperature and relative humidity to determine an apparent temperature. The HI equation [12] is derived by multiple regression analysis in temperature and relative humidity from the first version of Steadman’s (1979) apparent temperature (AT) [13].

heat_index(tdb: number, rh: number, options: Object?): number
Parameters
tdb (number) Dry bulb air temperature, default in [°C] in [°F] if units = 'IP'.
rh (number) Relative humidity, [%].
options (Object? = {round:true,units:"SI"}) (Optional) Other parameters.
Name Description
options.round boolean (default true) If True rounds output value, if False it does not round it.
options.units ("SI" | "IP") (default "SI") Select the SI (International System of Units) or the IP (Imperial Units) system.
Returns
number: Heat Index, default in [°C] in [°F] if units = 'IP'.
Example
const hi = heat_index(25, 50); // returns 25.9
Predicted Heat Strain (PHS) Index

Calculates the Predicted Heat Strain (PHS) index based in compliace with the ISO 7933:2004 Standard [8]. The ISO 7933 provides a method for the analytical evaluation and interpretation of the thermal stress experienced by a subject in a hot environment. It describes a method for predicting the sweat rate and the internal core temperature that the human body will develop in response to the working conditions.

The PHS model can be used to predict the: heat by respiratory convection, heat flow by respiratory evaporation, steady state mean skin temperature, instantaneous value of skin temperature, heat accumulation associated with the metabolic rate, maximum evaporative heat flow at the skin surface, predicted sweat rate, predicted evaporative heat flow, and rectal temperature.

phs(tdb: number, tr: number, v: number, rh: number, met: number, clo: number, posture: (1 | 2 | 3), wme: number, kwargs: PhsKwargs?): PhsReturnType
Parameters
tdb (number) dry bulb air temperature, default in [°C]
tr (number) mean radiant temperature, default in [°C]
v (number) air speed, default in [m/s]
rh (number) relative humidity, [%]
met (number) metabolic rate, [W/(m2)]
clo (number) clothing insulation, [clo]
posture ((1 | 2 | 3)) a numeric value presenting posture of person [sitting=1, standing=2, crouching=3]
wme (number = 0) external work, [W/(m2)] default 0
kwargs (PhsKwargs? = {}) additional arguments
Returns
PhsReturnType: object with results of phs
Related types
PhsKwargs

Type: Object

Properties
i_mst (number?) : static moisture permeability index, [dimensionless]
a_p (number?) : fraction of the body surface covered by the reflective clothing, [dimensionless]
drink ((0 | 1)?) : 1 if workers can drink freely, 0 otherwise
weight (number?) : body weight, [kg]
height (number?) : height, [m]
walk_sp (number?) : walking speed, [m/s]
theta (number?) : angle between walking direction and wind direction [degrees]
acclimatized (number?) : 100 if acclimatized subject, 0 otherwise
duration (number?) : duration of the work sequence, [minutes]
f_r (number?) : emissivity of the reflective clothing, [dimensionless]
t_sk (number?) : mean skin temperature when worker starts working, [°C]
t_cr (number?) : mean core temperature when worker starts working, [°C]
t_re (number?) : mean rectal temperature when worker starts working, [°C]
t_cr_eq (number?) : mean core temperature as a function of met when worker starts working, [°C]
sweat_rate (number?) : sweat rate
round (boolean?) : round the result of the PHS model
PhsReturnType

Type: Object

Properties
t_re (number) : rectal temperature, [°C]
t_sk (number) : skin temperature, [°C]
t_cr (number) : core temperature, [°C]
t_cr_eq (number) : core temperature as a function of the metabolic rate, [°C]
t_sk_t_cr_wg (number) : fraction of the body mass at the skin temperature
d_lim_loss_50 (number) : maximum allowable exposure time for water loss, mean subject, [minutes]
d_lim_loss_95 (number) : maximum allowable exposure time for water loss, 95% of the working population, [minutes]
d_lim_t_re (number) : maximum allowable exposure time for heat storage, [minutes]
water_loss_watt (number) : maximum water loss in watts, [W]
water_loss (number) : maximum water loss, [g]
Example
import { phs } from "jsthermalcomfort";
const results = phs(40, 40, 33.85, 0.3, 150, 0.5, 2);
console.log(results); // {t_re: 37.5, d_lim_loss_50: 440, d_lim_loss_95: 298, d_lim_t_re: 480, water_loss: 6166.0}
Humidex

Calculates the humidex (short for "humidity index"). It has been developed by the Canadian Meteorological service. It was introduced in 1965 and then it was revised by Masterson and Richardson (1979) [14]. It aims to describe how hot, humid weather is felt by the average person. The Humidex differs from the heat index in being related to the dew point rather than relative humidity [15].

humidex(tdb: number, rh: number, options: object?): HumidexResult
Parameters
tdb (number) dry bulb air temperature, [°C]
rh (number) relative humidity, [%]
options (object? = {round:true}) configuration options for the function.
Name Description
options.round boolean (default true) If true, rounds output value. If false, it does not.
Returns
HumidexResult: the result given the provided temperature and relative humidity.
Related types
HumidexResult

Type: object

Properties
humidex (number) : the humdidex given the provided dry bulb air temperature and relative humidity.
discomfort (string) : a human description of how the weather would be felt by the average person.
Example
const result = humidex(25, 50);
console.log(result); // -> { humidex: 28.2, discomfort: "Little or no discomfort" }
Normal Effective Temperature (NET)

Calculates the Normal Effective Temperature (NET). Missenard (1933) devised a formula for calculating effective temperature. The index establishes a link between the same condition of the organism's thermoregulatory capability (warm and cold perception) and the surrounding environment's temperature and humidity. The index is calculated as a function of three meteorological factors: air temperature, relative humidity of air, and wind speed. This index allows to calculate the effective temperature felt by a person. Missenard original equation was then used to calculate the Normal Effective Temperature (NET), by considering normal atmospheric pressure and a normal human body temperature (37°C). The NET is still in use in Germany, where medical check-ups for subjects working in the heat are decided on by prevailing levels of ET, depending on metabolic rates. The NET is also constantly monitored by the Hong Kong Observatory [16]. In central Europe the following thresholds are in use: <1°C = very cold; 1–9 = cold; 9–17 = cool; 17–21 = fresh; 21–23 = comfortable; 23–27 = warm; >27°C = hot [1].

net(tdb: number, rh: number, v: number, options: object?): number
Parameters
tdb (number) dry bulb air temperature, [°C]
rh (number) relative humidity, [%]
v (number) wind speed [m/s] at 1.2 m above the ground
options (object? = {round:true}) configuration options for the function.
Name Description
options.round boolean (default true) If true, rounds output value. If false, it does not.
Returns
number: Normal Effective Temperature, [°C]
Example
const result = net(37, 100, 0.1);
console.log(result); // -> 37
Wet Bulb Globe Temperature Index (WBGT)

Calculates the Wet Bulb Globe Temperature (WBGT) index calculated in compliance with the ISO 7243 [11]. The WBGT is a heat stress index that measures the thermal environment to which a person is exposed. In most situations, this index is simple to calculate. It should be used as a screening tool to determine whether heat stress is present. The PHS model allows a more accurate estimation of stress. PHS can be calculated using the function jsthermalcomfort.models.phs.

The WBGT determines the impact of heat on a person throughout the course of a working day (up to 8 h). It does not apply to very brief heat exposures. It pertains to the evaluation of male and female people who are fit for work in both indoor and outdoor occupational environments, as well as other sorts of surroundings [11].

The WBGT is defined as a function of only twb and tg if the person is not exposed to direct radiant heat from the sun. When a person is exposed to direct radiant heat, tdb must also be specified.

wbgt(twb: number, tg: number, options: object?): number
Parameters
twb (number) natural (no forced air flow) wet bulb temperature, [°C]
tg (number) globe temperature, [°C]
options (object?) configuration options for the function.
Name Description
options.round boolean (default true) If true rounds output value. If false it does not round it.
options.tdb number (default undefined) Dry bulb air temperature, [°C]. This value is needed as input if the person is exposed to direct solar radiation.
options.with_solar_load boolean (default false) If the globe sensor is exposed to direct solar radiation. If this is set to true without also setting options.tdb then an error will be thrown.
Returns
number: Wet Bulb Globe Temperature Index, [°C]
Example
const result = wbgt(25, 32);
console.log(result); // -> 27.1
const result = wbgt(25, 32, { tdb: 20, with_solar_radiation: true });
console.log(result); // -> 25.9
Discomfort Index (DI)

Calculates the Discomfort Index (DI). The index is essentially an effective temperature based on air temperature and humidity. The discomfort index is usuallly divided in 6 dicomfort categories and it only applies to warm environments. [24]

  • class 1 - DI < 21 °C - No discomfort
  • class 2 - 21 <= DI < 24 °C - Less than 50% feels discomfort
  • class 3 - 24 <= DI < 27 °C - More than 50% feels discomfort
  • class 4 - 27 <= DI < 29 °C - Most of the population feels discomfort
  • class 5 - 29 <= DI < 32 °C - Everyone feels severe stress
  • class 6 - DI >= 32 °C - State of medical emergency
discomfort_index(tdb: number, rh: number): DiscomfortIndexReturnType
Parameters
tdb (number) air temperature [C]
rh (number) relative humidity [%]
Returns
DiscomfortIndexReturnType: object with results of DI
Related types
DiscomfortIndexReturnType

Type: Object

Properties
di (number) : – Discomfort Index(DI)
discomfort_condition (string) : Classification of the thermal comfort conditions according to the discomfort index
Related
discomfort_index_array for a version that supports arrays
Example
const DI = discomfort_index(25, 50); // returns { di: 22.1, discomfort_condition: 'Less than 50% feels discomfort' }
Discomfort Index (DI) (array version)

Calculates the Discomfort Index (DI). The index is essentially an effective temperature based on air temperature and humidity. The discomfort index is usuallly divided in 6 dicomfort categories and it only applies to warm environments. [24]

  • class 1 - DI < 21 °C - No discomfort
  • class 2 - 21 <= DI < 24 °C - Less than 50% feels discomfort
  • class 3 - 24 <= DI < 27 °C - More than 50% feels discomfort
  • class 4 - 27 <= DI < 29 °C - Most of the population feels discomfort
  • class 5 - 29 <= DI < 32 °C - Everyone feels severe stress
  • class 6 - DI >= 32 °C - State of medical emergency
discomfort_index_array(tdb: Array<number>, rh: Array<number>): DiscomfortIndexArrayReturnType
Parameters
tdb (Array<number>) air temperature [C]
rh (Array<number>) relative humidity [%]
Returns
DiscomfortIndexArrayReturnType: object with results of DI
Related types
DiscomfortIndexArrayReturnType

Type: Object

Properties
di (Array<number>) : – Discomfort Index(DI) Array
discomfort_condition (Array<string>) : Classification of the thermal comfort conditions in array
Related
discomfort_index for a version that supports scalar arguments
Gagge et al. two-node model

Two-node model of human temperature regulation Gagge et al. (1986).

[10] This model can be used to calculate a variety of indices, including:

  • Gagge’s version of Fanger’s Predicted Mean Vote (PMV). This function uses the Fanger’s PMV equations but it replaces the heat loss and gain terms with those calculated by the two node model developed by Gagge et al. (1986) [10].
  • PMV SET and the predicted thermal sensation based on SET [10]. This function is similar in all aspects to the pythermalcomfort.models.pmv_gagge(). However, it uses the pythermalcomfort.models.set() equation to calculate the dry heat loss by convection.
  • Thermal discomfort (DISC) as the relative thermoregulatory strain necessary to restore a state of comfort and thermal equilibrium by sweating [10]. DISC is described numerically as: comfortable and pleasant (0), slightly uncomfortable but acceptable (1), uncomfortable and unpleasant (2), very uncomfortable (3), limited tolerance (4), and intolerable (S). The range of each category is ± 0.5 numerically. In the cold, the classical negative category descriptions used for Fanger’s PMV apply [10].
  • Heat gains and losses via convection, radiation and conduction.
  • The Standard Effective Temperature (SET)
  • The New Effective Temperature (ET)
  • The Predicted Thermal Sensation (TSENS)
  • The Predicted Percent Dissatisfied Due to Draft (PD)
  • Predicted Percent Satisfied With the Level of Air Movement” (PS)
two_nodes(tdb: number, tr: number, v: number, rh: number, met: number, clo: number, wme: number, body_surface_area: number, p_atmospheric: number, body_position: ("standing" | "sitting"), max_skin_blood_flow: number, kwargs: TwoNodesKwargs?): TwoNodesReturnType
Parameters
tdb (number) Dry bulb air temperature, default in [°C] in [°F] if units = 'IP'.
tr (number) Mean radiant temperature, default in [°C]
v (number) Air speed, default in [m/s]
rh (number) Relative humidity, [%].
met (number) Metabolic rate, [W/(m2)]
clo (number) Clothing insulation, [clo]
wme (number = 0) External work, [W/(m2)] default 0
body_surface_area (number = 1.8258) Body surface area, default value 1.8258 [m2] in [ft2] if units = ‘IP’
p_atmospheric (number = 101325) Atmospheric pressure, default value 101325 [Pa] in [atm] if units = ‘IP’
body_position (("standing" | "sitting") = "standing") Select either “sitting” or “standing”
max_skin_blood_flow (number = 90) Maximum blood flow from the core to the skin, [kg/h/m2] default 90
kwargs (TwoNodesKwargs? = {})
Returns
TwoNodesReturnType: object with results of two_nodes
Related types
TwoNodesKwargs

Type: Object

Properties
round (boolean?) : round the result of two nodes model
calculate_ce (boolean?) : select if SET is used to calculate Cooling Effect
max_sweating (number?) : maximum rate at which regulatory sweat is generated, [kg/h/m2]
w_max (number?) : – maximum skin wettedness (w) adimensional. Ranges from 0 and 1
TwoNodesReturnType

Type: Object

Properties
e_skin (number) : – Total rate of evaporative heat loss from skin, [W/m2]. Equal to e_rsw + e_diff
e_rsw (number) : – Rate of evaporative heat loss from sweat evaporation, [W/m2]
e_max (number) : – Maximum rate of evaporative heat loss from skin, [W/m2]
q_sensible (number) : – Sensible heat loss from skin, [W/m2]
q_skin (number) : – Total rate of heat loss from skin, [W/m2]. Equal to q_sensible + e_skin
q_res (number) : – Total rate of heat loss through respiration, [W/m2]
t_core (number) : – Core temperature, [°C]
t_skin (number) : – Skin temperature, [°C]
m_bl (number) : – Skin blood flow, [kg/h/m2]
m_rsw (number) : – Rate at which regulatory sweat is generated, [kg/h/m2]
w (number) : – Skin wettedness, adimensional. Ranges from 0 and 1.
w_max (number) : – Skin wettedness (w) practical upper limit, adimensional. Ranges from 0 and 1.
set (number) : – Standard Effective Temperature (SET)
et (number) : – New Effective Temperature (ET)
pmv_gagge (number) : – PMV Gagge
pmv_set (number) : – PMV SET
disc (number) : – Thermal discomfort
t_sens (number) : – Predicted Thermal Sensation
Related
two_nodes_array for a version that supports arrays
Example
const results = two_nodes(25, 25, 0.3, 50, 1.2, 0.5);
console.log(results); // {
e_skin: 16.2,
e_rsw: 7,
e_max: 159.9,
q_sensible: 47.6,
q_skin: 63.8,
q_res: 5.2,
t_core: 36.9,
t_skin: 33.7,
m_bl: 12.9,
m_rsw: 10.3,
w: 0.1,
w_max: 0.6,
set: 23.6,
et: 25,
pmv_gagge: 0.1,
pmv_set: -0,
disc: 0.1,
t_sens: 0.1
}
Gagge et al. two-node model (array version)

Two nodes model of human temperature regulation Gagge et al. when the input parameters are arrays.

[10] This model can be used to calculate a variety of indices, including:

  • Gagge’s version of Fanger’s Predicted Mean Vote (PMV). This function uses the Fanger’s PMV equations but it replaces the heat loss and gain terms with those calculated by the two node model developed by Gagge et al. (1986) [10].
  • PMV SET and the predicted thermal sensation based on SET [10]. This function is similar in all aspects to the pythermalcomfort.models.pmv_gagge(). However, it uses the pythermalcomfort.models.set() equation to calculate the dry heat loss by convection.
  • Thermal discomfort (DISC) as the relative thermoregulatory strain necessary to restore a state of comfort and thermal equilibrium by sweating [10]. DISC is described numerically as: comfortable and pleasant (0), slightly uncomfortable but acceptable (1), uncomfortable and unpleasant (2), very uncomfortable (3), limited tolerance (4), and intolerable (S). The range of each category is ± 0.5 numerically. In the cold, the classical negative category descriptions used for Fanger’s PMV apply [10].
  • Heat gains and losses via convection, radiation and conduction.
  • The Standard Effective Temperature (SET)
  • The New Effective Temperature (ET)
  • The Predicted Thermal Sensation (TSENS)
  • The Predicted Percent Dissatisfied Due to Draft (PD)
  • Predicted Percent Satisfied With the Level of Air Movement” (PS)
two_nodes_array(tdbArray: Array<number>, trArray: Array<number>, vArray: Array<number>, rhArray: Array<number>, metArray: Array<number>, cloArray: Array<number>, wmeArray: Array<number>, bodySurfaceArray: Array<number>, pAtmArray: Array<number>, bodyPositionArray: ("standing" | "sitting"), maxSkinBloodFlowArray: Array<number>, kwargs: TwoNodesKwargs?): TwoNodesArrayReturnType
Parameters
tdbArray (Array<number>) Dry bulb air temperature, default in [°C] in [°F] if units = 'IP'.
trArray (Array<number>) Mean radiant temperature, default in [°C]
vArray (Array<number>) Air speed, default in [m/s]
rhArray (Array<number>) Relative humidity, [%].
metArray (Array<number>) Metabolic rate, [W/(m2)]
cloArray (Array<number>) Clothing insulation, [clo]
wmeArray (Array<number>) External work, [W/(m2)] default 0
bodySurfaceArray (Array<number>) Body surface area, default value 1.8258 [m2] in [ft2] if units = ‘IP’
pAtmArray (Array<number>) Atmospheric pressure, default value 101325 [Pa] in [atm] if units = ‘IP’
bodyPositionArray (("standing" | "sitting")) Select either “sitting” or “standing”
maxSkinBloodFlowArray (Array<number>) Maximum blood flow from the core to the skin, [kg/h/m2] default 90
kwargs (TwoNodesKwargs? = {})
Returns
TwoNodesArrayReturnType: object with results of two_nodes_array
Related types
TwoNodesArrayReturnType

Type: Object

Properties
e_skin (Array<number>) : – Array of total rate of evaporative heat loss from skin, [W/m2]. Equal to e_rsw + e_diff
e_rsw (Array<number>) : – Array of rate of evaporative heat loss from sweat evaporation, [W/m2]
e_max (Array<number>) : – Array of maximum rate of evaporative heat loss from skin, [W/m2]
q_sensible (Array<number>) : – Array of sensible heat loss from skin, [W/m2]
q_skin (Array<number>) : – Array of total rate of heat loss from skin, [W/m2]. Equal to q_sensible + e_skin
q_res (Array<number>) : – Array of total rate of heat loss through respiration, [W/m2]
t_core (Array<number>) : – Array of core temperature, [°C]
t_skin (Array<number>) : – Array of skin temperature, [°C]
m_bl (Array<number>) : – Array of skin blood flow, [kg/h/m2]
m_rsw (Array<number>) : – Array of rate at which regulatory sweat is generated, [kg/h/m2]
w (Array<number>) : – Array of skin wettedness, adimensional. Ranges from 0 and 1.
w_max (Array<number>) : – Array of skin wettedness (w) practical upper limit, adimensional. Ranges from 0 and 1.
set (Array<number>) : – Array of standard Effective Temperature (SET)
et (Array<number>) : – Array of new Effective Temperature (ET)
pmv_gagge (Array<number>) : – Array of PMV Gagge
pmv_set (Array<number>) : – Array of PMV SET
disc (Array<number>) : – Array of Thermal discomfort
t_sens (Array<number>) : – Array of Predicted Thermal Sensation
Related
two_nodes for a version that supports scalar arguments
Example
const results = two_nodes_array([25,30], [25,35], [0.3,0.5], [50,60], [1.2,1.5], [0.5, 0.3], [0,0], [1.8258,1.8258], [101325,101325], ["standing","standing"], [90,90])
console.log(results); // {
e_skin: [ 16.2, 60.4 ],
e_rsw: [ 7, 51.9 ],
e_max: [ 159.9, 193.8 ],
q_sensible: [ 47.6, 21.1 ],
q_skin: [ 63.8, 81.5 ],
q_res: [ 5.2, 5 ],
t_core: [ 36.9, 37 ],
t_skin: [ 33.7, 35.1 ],
m_bl: [ 12.9, 31.6 ],
m_rsw: [ 10.3, 76.3 ],
w: [ 0.1, 0.3 ],
w_max: [ 0.6, 0.6 ],
set: [ 23.6, 29.3 ],
et: [ 25, 32.5 ],
pmv_gagge: [ 0.1, 1.6 ],
pmv_set: [ -0, 1.1 ],
disc: [ 0.1, 1.9 ],
t_sens: [ 0.1, 1.4 ]
}
Standard Effective Temperature (SET)

Calculates the Standard Effective Temperature (SET). The SET is the temperature of a hypothetical isothermal environment at 50% (rh), <0.1 m/s (20 fpm) average air speed (v), and tr = tdb, in which the total heat loss from the skin of an imaginary occupant wearing clothing, standardized for the activity concerned is the same as that from a person in the actual environment with actual clothing and activity level [10].

set_tmp(tdb: number, tr: number, v: number, rh: number, met: number, clo: number, wme: number, body_surface_area: number?, p_atm: number?, body_position: ("standing" | "sitting"), units: ("SI" | "IP"), limit_inputs: boolean, kwargs: SetTmpKwargs?): number
Parameters
tdb (number) Dry bulb air temperature, default in [°C] in [°F] if units = 'IP'.
tr (number) Mean radiant temperature, default in [°C]
v (number) Air speed, default in [m/s]
rh (number) Relative humidity, [%].
met (number) Metabolic rate, [W/(m2)]
clo (number) Clothing insulation, [clo]
wme (number = 0) External work, [W/(m2)] default 0
body_surface_area (number?) Body surface area, default value 1.8258 [m2] in [ft2] if units = ‘IP’
p_atm (number?) Atmospheric pressure, default value 101325 [Pa] in [atm] if units = ‘IP’
body_position (("standing" | "sitting") = "standing") Select either “sitting” or “standing”
units (("SI" | "IP") = "SI") Select the SI (International System of Units) or the IP (Imperial Units) system.
limit_inputs (boolean = true) By default, if the inputs are outsude the following limits the function returns nan. If False returns values regardless of the input values.
kwargs (SetTmpKwargs? = {})
Returns
number: SET – Standard effective temperature in array, [°C]
Related types
SetTmpKwargs

Type: Object

Properties
round (boolean?) : round the result of the SET
calculate_ce (boolean?) : select if SET is used to calculate Cooling Effect
Related
set_tmp_array for a version that supports arrays
Example
const set = set_tmp(25, 25, 0.1, 50, 1.2, 0.5); // returns 24.3
Standard Effective Temperature (SET) (array version)

Calculates the SET when the input parameters are arrays. The SET is the temperature of a hypothetical isothermal environment at 50% (rh), <0.1 m/s (20 fpm) average air speed (v), and tr = tdb, in which the total heat loss from the skin of an imaginary occupant wearing clothing, standardized for the activity concerned is the same as that from a person in the actual environment with actual clothing and activity level [10].

set_tmp_array(tdbArray: Array<number>, trArray: Array<number>, vArray: Array<number>, rhArray: Array<number>, metArray: Array<number>, cloArray: Array<number>, wmeArray: Array<number>?, bodySurfaceArray: Array<number>?, pAtmArray: Array<number>?, bodyPositionArray: ("standing" | "sitting"), units: ("SI" | "IP"), limit_inputs: boolean, kwargs: SetTmpKwargs?): Array<number>
Parameters
tdbArray (Array<number>) Dry bulb air temperature, default in [°C] in [°F] if units = 'IP'.
trArray (Array<number>) Mean radiant temperature, default in [°C]
vArray (Array<number>) Air speed, default in [m/s]
rhArray (Array<number>) Relative humidity, [%].
metArray (Array<number>) Metabolic rate, [W/(m2)]
cloArray (Array<number>) Clothing insulation, [clo]
wmeArray (Array<number>?) External work, [W/(m2)] default 0
bodySurfaceArray (Array<number>?) Body surface area, default value 1.8258 [m2] in [ft2] if units = ‘IP’
pAtmArray (Array<number>?) Atmospheric pressure, default value 101325 [Pa] in [atm] if units = ‘IP’
bodyPositionArray (("standing" | "sitting")) Select either “sitting” or “standing”
units (("SI" | "IP") = "SI") Select the SI (International System of Units) or the IP (Imperial Units) system.
limit_inputs (boolean = true) By default, if the inputs are outsude the following limits the function returns nan. If False returns values regardless of the input values.
kwargs (SetTmpKwargs? = {})
Returns
Array<number>: SET Array – Standard effective temperature in array, [°C]
Related
set_tmp for a version that supports scalar arguments
Example
const set = set_tmp_array([25, 25], [25, 25], [0.1, 0.1], [50, 50], [1.2, 1.2], [0.5, 0.5]); // returns [24.3, 24.3]
Wind chill index

Calculates the Wind Chill Index (WCI) in accordance with the ASHRAE 2017 Handbook Fundamentals - Chapter 9 [18].

The wind chill index (WCI) is an empirical index based on cooling measurements taken on a cylindrical flask partially filled with water in Antarctica (Siple and Passel 1945). For a surface temperature of 33°C, the index describes the rate of heat loss from the cylinder via radiation and convection as a function of ambient temperature and wind velocity.

This formulation has been met with some valid criticism. WCI is unlikely to be an accurate measure of heat loss from exposed flesh, which differs from plastic in terms of curvature, roughness, and radiation exchange qualities, and is always below 33°C in a cold environment. Furthermore, the equation’s values peak at 90 km/h and then decline as velocity increases. Nonetheless, this score reliably represents the combined effects of temperature and wind on subjective discomfort for velocities below 80 km/h [18].

wc(tdb: number, v: number, kwargs: object?): {wci: number}
Parameters
tdb (number) dry bulb air temperature,[°C]
v (number) wind speed 10m above ground level, [m/s]
kwargs (object? = {round:true}) (Optional) Other parameters.
Name Description
kwargs.round boolean (default true) If True rounds output value, if False it does not round it.
Returns
{wci: number}: wind chill index, [W/m2]
Adaptive EN

Determines the adaptive thermal comfort based on EN 16798-1 2019 [3]

Note: You can use this function to calculate if your conditions are within the EN adaptive thermal comfort region. Calculations with comply with the EN 16798-1 2019 [3].

adaptive_en(tdb: number, tr: number, t_running_mean: number, v: number, units: ("IP" | "SI"), limit_inputs: boolean): AdaptiveEnResult
Parameters
tdb (number) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (number) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
t_running_mean (number) running mean temperature, default in [°C] in [°C] in [°F] if units = 'IP' The running mean temperature can be calculated using the function running_mean_outdoor_temperature
v (number) air speed, default in [m/s] in [fps] if units = 'IP'

Note: Indoor operative temperature correction is applicable for buildings equipped with fans or personal systems providing building occupants with personal control over air speed at occupant level. For operative temperatures above 25°C the comfort zone upper limit can be increased by 1.2 °C (0.6 < v < 0.9 m/s), 1.8 °C (0.9 < v < 1.2 m/s), 2.2 °C (v > 1.2 m/s)

units (("IP" | "SI") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
limit_inputs (boolean = true) By default, if the inputs are outsude the standard applicability limits the function returns nan. If False returns pmv and ppd values even if input values are outside the applicability limits of the model.
Returns
AdaptiveEnResult: result set
Related types
AdaptiveEnResult

Type: object

Properties
tmp_cmf (number) : Comfort temperature at that specific running mean temperature, default in [°C] or in [°F]
acceptability_cat_i (boolean) : If the indoor conditions comply with comfort category I
acceptability_cat_ii (boolean) : If the indoor conditions comply with comfort category II
acceptability_cat_iii (boolean) : If the indoor conditions comply with comfort category III
tmp_cmf_cat_i_up (number) : Upper acceptable comfort temperature for category I, default in [°C] or in [°F]
tmp_cmf_cat_ii_up (number) : Upper acceptable comfort temperature for category II, default in [°C] or in [°F]
tmp_cmf_cat_iii_up (number) : Upper acceptable comfort temperature for category III, default in [°C] or in [°F]
tmp_cmf_cat_i_low (number) : Lower acceptable comfort temperature for category I, default in [°C] or in [°F]
tmp_cmf_cat_ii_low (number) : Lower acceptable comfort temperature for category II, default in [°C] or in [°F]
tmp_cmf_cat_iii_low (number) : Lower acceptable comfort temperature for category III, default in [°C] or in [°F]
Related
adaptive_en_array for a version that supports array arguments
Example
const results = adaptive_en(25, 25, 20, 0.1);
console.log(results); // {tmp_cmf: 25.4, acceptability_cat_i: true, acceptability_cat_ii: true, ... }
console.log(results.acceptability_cat_i); // true
// The conditions you entered are considered to comply with Category I
// for users who wants to use the IP system
const results = adaptive_en(77, 77, 68, 0.3, 'IP');
console.log(results); // {tmp_cmf: 77.7, acceptability_cat_i: true, acceptability_cat_ii: true, ... }
const results = adaptive_en(25, 25, 9, 0.1);
console.log(results); // {tmp_cmf: NaN, acceptability_cat_i: true, acceptability_cat_ii: true, ... }
// The adaptive thermal comfort model can only be used
// if the running mean temperature is between 10 °C and 30 °C
Adaptive EN (array version)

Determines the adaptive thermal comfort based on EN 16798-1 2019 [3]

Note: You can use this function to calculate if your conditions are within the EN adaptive thermal comfort region. Calculations with comply with the EN 16798-1 2019 [3].

adaptive_en_array(tdb: Array<number>, tr: Array<number>, t_running_mean: Array<number>, v: Array<number>, units: ("IP" | "SI"), limit_inputs: boolean): AdaptiveEnArrayResult
Parameters
tdb (Array<number>) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (Array<number>) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
t_running_mean (Array<number>) running mean temperature, default in [°C] in [°C] in [°F] if units = 'IP' The running mean temperature can be calculated using the function running_mean_outdoor_temperature
v (Array<number>) air speed, default in [m/s] in [fps] if units = 'IP'

Note: Indoor operative temperature correction is applicable for buildings equipped with fans or personal systems providing building occupants with personal control over air speed at occupant level. For operative temperatures above 25°C the comfort zone upper limit can be increased by 1.2 °C (0.6 < v < 0.9 m/s), 1.8 °C (0.9 < v < 1.2 m/s), 2.2 °C (v> 1.2 m/s)

units (("IP" | "SI") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
limit_inputs (boolean = true) By default, if the inputs are outsude the standard applicability limits the function returns nan. If False returns pmv and ppd values even if input values are outside the applicability limits of the model.
Returns
AdaptiveEnArrayResult: result set
Related types
AdaptiveEnArrayResult

Type: object

Properties
tmp_cmf (Array<number>) : Comfort temperature at that specific running mean temperature, default in [°C] or in [°F]
acceptability_cat_i (Array<boolean>) : If the indoor conditions comply with comfort category I
acceptability_cat_ii (Array<boolean>) : If the indoor conditions comply with comfort category II
acceptability_cat_iii (Array<boolean>) : If the indoor conditions comply with comfort category III
tmp_cmf_cat_i_up (Array<number>) : Upper acceptable comfort temperature for category I, default in [°C] or in [°F]
tmp_cmf_cat_ii_up (Array<number>) : Upper acceptable comfort temperature for category II, default in [°C] or in [°F]
tmp_cmf_cat_iii_up (Array<number>) : Upper acceptable comfort temperature for category III, default in [°C] or in [°F]
tmp_cmf_cat_i_low (Array<number>) : Lower acceptable comfort temperature for category I, default in [°C] or in [°F]
tmp_cmf_cat_ii_low (Array<number>) : Lower acceptable comfort temperature for category II, default in [°C] or in [°F]
tmp_cmf_cat_iii_low (Array<number>) : Lower acceptable comfort temperature for category III, default in [°C] or in [°F]
Related
adaptive_en for a version that supports scalar arguments
Example
const results = adaptive_en([25,25], [25,25], [20,9], [0.1,0.1]);
console.log(results); // {tmp_cmf: [25.4, NaN], acceptability_cat_i: [true, true], acceptability_cat_ii: [true, true], ... }
console.log(results.acceptability_cat_i); // [true, true]
// The conditions you entered are considered to comply with Category I
// The adaptive thermal comfort model can only be used
// if the running mean temperature is between 10 °C and 30 °C
Apparent Temperature (AT)

Calculates the Apparent Temperature (AT). The AT is defined as the temperature at the reference humidity level producing the same amount of discomfort as that experienced under the current ambient temperature, humidity, and solar radiation [17]. In other words, the AT is an adjustment to the dry bulb temperature based on the relative humidity value. Absolute humidity with a dew point of 14°C is chosen as a reference.

[16]. It includes the chilling effect of the wind at lower temperatures.

Two formulas for AT are in use by the Australian Bureau of Meteorology: one includes solar radiation and the other one does not ({@link http://www.bom.gov.au/info/thermal_stress/}, 29 Sep 2021). Please specify q if you want to estimate AT with solar load.

at(tdb: number, rh: number, v: number, q: (number | undefined)?, kwargs: object?): number
Parameters
tdb (number) dry bulb air temperature, [°C]
rh (number) relative humidity, [%]
v (number) wind speed 10m above ground level, [m/s]
q ((number | undefined)?) Net radiation absorbed per unit area of body surface [W/m2]
kwargs (object? = {round:true}) other parameters
Name Description
kwargs.round boolean (default true) if True rounds output value, if False it does not round it
Returns
number: apparent temperature, [°C]
Example
const result = at(25, 30, 0.1);
console.log(result); // 24.1
Predicted Mean Vote (PMV) and Predicted Percentage of Dissatisfied (PPD)

Returns Predicted Mean Vote ( PMV ) and Predicted Percentage of Dissatisfied ( PPD ) calculated in accordance with main thermal comfort Standards. The PMV is an index that predicts the mean value of the thermal sensation votes (self-reported perceptions) of a large group of people on a sensation scale expressed from –3 to +3 corresponding to the categories: cold, cool, slightly cool, neutral, slightly warm, warm, and hot. [1]

While the PMV equation is the same for both the ISO and ASHRAE standards, in the ASHRAE 55 PMV equation, the SET is used to calculate the cooling effect first, this is then subtracted from both the air and mean radiant temperatures, and the differences are used as input to the PMV model, while the airspeed is set to 0.1m/s. Please read more in the Note below.

Notes:

You can use this function to calculate the PMV and PPD in accordance with either the ASHRAE 55 2020 Standard [1] or the ISO 7730 Standard [2].

This is a version that supports scalar arguments.

pmv_ppd(tdb: number, tr: number, vr: number, rh: number, met: number, clo: number, wme: number, standard: ("ISO" | "ASHRAE"), kwargs: Pmv_ppdKwargs): Pmv_ppdReturns
Parameters
tdb (number) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (number) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
vr (number) relative air speed, default in [m/s] in [fps] if units = 'IP'

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function v_relative which is in .utilities.js.

rh (number) relative humidity, [%]
met (number) metabolic rate
clo (number) clothing insulation

Note: The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met) The dynamic clothing insulation, clo, can be calculated using the function clo_dynamic which is in .utilities.js.

wme (number = 0) external work
standard (("ISO" | "ASHRAE") = "ISO") comfort standard used for calculation

· If "ISO", then the ISO Equation is used

· If "ASHRAE", then the ASHRAE Equation is used

Note: While the PMV equation is the same for both the ISO and ASHRAE standards, the ASHRAE Standard Use of the PMV model is limited to air speeds below 0.10m/s (20 fpm). When air speeds exceed 0.10 m/s (20 fpm), the comfort zone boundaries are adjusted based on the SET model. This change was introduced by the Addendum_C to Standard 55-2020

kwargs (Pmv_ppdKwargs = {}) additional arguments
Returns
Pmv_ppdReturns: Result of pmv and ppd
Related types
Pmv_ppdKwargs

Type: Object

Properties
units (("SI" | "IP")) : select the SI (International System of Units) or the IP (Imperial Units) system.
limit_inputs (boolean) : Default is True. By default, if the inputs are outside the standard applicability limits the function returns NaN. If false, returns pmv and ppd values even if input values are outside the applicability limits of the model.

The ASHRAE 55 2020 limits are 10 < tdb [°C] < 40, 10 < tr [°C] < 40, 0 < vr [m/s] < 2, 1 < met [met] < 4, and 0 < clo [clo] < 1.5. The ISO 7730 2005 limits are 10 < tdb [°C] < 30, 10 < tr [°C] < 40, 0 < vr [m/s] < 1, 0.8 < met [met] < 4, 0 < clo [clo] < 2, and -2 < PMV < 2.

airspeed_control (boolean) : This only applies if standard = "ASHRAE".

Default is True. By default, it is assumed that the occupant has control over the airspeed. In this case, the ASHRAE 55 Standard does not impose any airspeed limits. On the other hand, if the occupant has no control over the airspeed, the ASHRAE 55 imposes an upper limit for v which varies as a function of the operative temperature, for more information please consult the Standard.

Pmv_ppdReturns

Type: Object

Properties
pmv (number) : Predicted Mean Vote
ppd (number) : Predicted Percentage of Dissatisfied occupants, [%]
Related
pmv_ppd_array for a version that supports arrays.
Example
const tdb = 25;
const tr = 25;
const rh = 50;
const v = 0.1;
const met = 1.4;
const clo = 0.5;
// Calculate relative air speed
const v_r = v_relative(v, met);
// Calculate dynamic clothing
const clo_d = clo_dynamic(clo, met);
const results = pmv_ppd(tdb, tr, v_r, rh, met, clo_d);
console.log(results); // Output: { pmv: 0.06, ppd: 5.1 }
console.log(results.pmv); // Output: -0.06
Predicted Mean Vote (PMV) and Predicted Percentage of Dissatisfied (PPD) (array version)

Returns Predicted Mean Vote ( PMV ) and Predicted Percentage of Dissatisfied ( PPD ) calculated in accordance with main thermal comfort Standards. The PMV is an index that predicts the mean value of the thermal sensation votes (self-reported perceptions) of a large group of people on a sensation scale expressed from –3 to +3 corresponding to the categories: cold, cool, slightly cool, neutral, slightly warm, warm, and hot. [1]

While the PMV equation is the same for both the ISO and ASHRAE standards, in the ASHRAE 55 PMV equation, the SET is used to calculate the cooling effect first, this is then subtracted from both the air and mean radiant temperatures, and the differences are used as input to the PMV model, while the airspeed is set to 0.1m/s. Please read more in the Note below.

Notes:

You can use this function to calculate the PMV and PPD in accordance with either the ASHRAE 55 2020 Standard [1] or the ISO 7730 Standard [2].

This is a version that supports arrays.

pmv_ppd_array(tdb: Array<number>, tr: Array<number>, vr: Array<number>, rh: Array<number>, met: Array<number>, clo: Array<number>, wme: Array<number>, standard: ("ISO" | "ASHRAE"), kwargs: Pmv_ppdKwargs): Pmv_ppd_arrayReturns
Parameters
tdb (Array<number>) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (Array<number>) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
vr (Array<number>) relative air speed, default in [m/s] in [fps] if units = 'IP'

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function v_relative_array which is in .utilities.js.

rh (Array<number>) relative humidity, [%]
met (Array<number>) metabolic rate, [met]
clo (Array<number>) clothing insulation, [clo]

Note: The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met) The dynamic clothing insulation, clo, can be calculated using the function clo_dynamic_array which is in .utilities.js.

wme (Array<number>) external work, default is array of 0
standard (("ISO" | "ASHRAE") = "ISO") comfort standard used for calculation

· If "ISO", then the ISO Equation is used

· If "ASHRAE", then the ASHRAE Equation is used

Note: While the PMV equation is the same for both the ISO and ASHRAE standards, the ASHRAE Standard Use of the PMV model is limited to air speeds below 0.10m/s (20 fpm). When air speeds exceed 0.10 m/s (20 fpm), the comfort zone boundaries are adjusted based on the SET model. This change was introduced by the Addendum_C to Standard 55-2020

kwargs (Pmv_ppdKwargs = {}) additional arguments
Returns
Pmv_ppd_arrayReturns: Result of pmv and ppd
Related types
Pmv_ppd_arrayReturns

Type: Object

Properties
pmv (Array<number>) : Predicted Mean Vote
ppd (Array<number>) : Predicted Percentage of Dissatisfied occupants, [%]
Related
pmv_ppd for a version that supports scalar arguments.
Example
const tdb = [22, 25];
const tr = [25, 25];
const rh = [50, 50];
const v = [0.1, 0.1];
const met = [1.4, 1.4];
const clo = [0.5, 0.5];
// Calculate relative air speed
const v_r = v_relative_array(v, met);
// Calculate dynamic clothing
const clo_d = clo_dynamic_array(clo, met);
const arrayResults = pmv_ppd_array(tdb, tr, v_r, rh, met, clo_d);
console.log(arrayResults); // Output: { pmv: [-0.47, 0.06], ppd: [9.6, 5.1] }
console.log(results.pmv); // Output: [-0.47, 0.06]
Adaptive ASHRAE

Determines the adaptive thermal comfort based on ASHRAE 55. The adaptive model relates indoor design temperatures or acceptable temperature ranges to outdoor meteorological or climatological parameters. The adaptive model can only be used in occupant-controlled naturally conditioned spaces that meet all the following criteria:

  • There is no mechianical cooling or heating system in operation
  • Occupants have a metabolic rate between 1.0 and 1.5 met
  • Occupants are free to adapt their clothing within a range as wide as 0.5 and 1.0 clo
  • The prevailing mean (runnin mean) outdoor temperature is between 10 and 33.5 °C
adaptive_ashrae(tdb: number, tr: number, t_running_mean: number, v: number, units: ("SI" | "IP"), limit_inputs: boolean): AdaptiveAshraeResult
Parameters
tdb (number) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (number) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
t_running_mean (number) running mean temperature, default in [°C] in [°C] in [°F] if units = 'IP' The running mean temperature can be calculated using the function running_mean_outdoor_temperature
v (number) air speed, default in [m/s] in [fps] if units = 'IP'
units (("SI" | "IP") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
limit_inputs (boolean = true) By default, if the inputs are outsude the standard applicability limits the function returns nan. If False returns pmv and ppd values even if input values are outside the applicability limits of the model.
Returns
AdaptiveAshraeResult: set containing results for the model

The ASHRAE 55 2020 limits are 10 < tdb [°C] < 40, 10 < tr [°C] < 40, 0 < vr [m/s] < 2, 10 < t running mean [°C] < 33.5

You can use this function to calculate if your conditions are within the adaptive thermal comfort region. Calculations with comply with the ASHRAE 55 2020 Standard [1].

Related types
AdaptiveAshraeResult

Type: object

Properties
tmp_cmf (number) : Comfort temperature a that specific running mean temperature, default in [°C] or in [°F]
tmp_cmf_80_low (number) : Lower acceptable comfort temperature for 80% occupants, default in [°C] or in [°F]
tmp_cmf_80_up (number) : Upper acceptable comfort temperature for 80% occupants, default in [°C] or in [°F]
tmp_cmf_90_low (number) : Lower acceptable comfort temperature for 90% occupants, default in [°C] or in [°F]
tmp_cmf_90_up (number) : Upper acceptable comfort temperature for 90% occupants, default in [°C] or in [°F]
acceptability_80 (boolean) : Acceptability for 80% occupants
acceptability_90 (boolean) : Acceptability for 90% occupants
Related
adaptive_ashrae_array for a version that supports array arguments
Example
import { adaptive_ashrae } from "jsthermalcomfort/models";
const results = adaptive_ashrae(25, 25, 20, 0.1);
console.log(results);
// {tmp_cmf: 24.0, tmp_cmf_80_low: 20.5, tmp_cmf_80_up: 27.5,
//   tmp_cmf_90_low: 21.5, tmp_cmf_90_up: 26.5, acceptability_80: true,
//   acceptability_90: true}
console.log(results.acceptability_80);
// true
import { adaptive_ashrae } from "jsthermalcomfort/models";
// For users who want to use the IP system
const results = adaptive_ashrae(77, 77, 68, 0.3, 'IP');
console.log(results);
// {tmp_cmf: 75.2, tmp_cmf_80_low: 68.9, tmp_cmf_80_up: 81.5,
//  tmp_cmf_90_low: 70.7, tmp_cmf_90_up: 79.7, acceptability_80: true,
//  acceptability_90: true}
import { adaptive_ashrae } from "jsthermalcomfort/models";
const results = adaptive_ashrae(25, 25, 9, 0.1);
console.log(results);
// {tmp_cmf: NaN, tmp_cmf_80_low: NaN, ...}
// The adaptive thermal comfort model can only be used
// if the running mean temperature is higher than 10°C
Adaptive ASHRAE (array version)

Determines the adaptive thermal comfort based on ASHRAE 55. The adaptive model relates indoor design temperatures or acceptable temperature ranges to outdoor meteorological or climatological parameters. The adaptive model can only be used in occupant-controlled naturally conditioned spaces that meet all the following criteria:

  • There is no mechianical cooling or heating system in operation
  • Occupants have a metabolic rate between 1.0 and 1.5 met
  • Occupants are free to adapt their clothing within a range as wide as 0.5 and 1.0 clo
  • The prevailing mean (runnin mean) outdoor temperature is between 10 and 33.5 °C
adaptive_ashrae_array(tdb: Array<number>, tr: Array<number>, t_running_mean: Array<number>, v: Array<number>, units: ("SI" | "IP"), limit_inputs: boolean): AdaptiveAshraeArrayResult
Parameters
tdb (Array<number>) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (Array<number>) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
t_running_mean (Array<number>) running mean temperature, default in [°C] in [°C] in [°F] if units = 'IP' The running mean temperature can be calculated using the function running_mean_outdoor_temperature
v (Array<number>) air speed, default in [m/s] in [fps] if units = 'IP'
units (("SI" | "IP") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
limit_inputs (boolean = true) By default, if the inputs are outsude the standard applicability limits the function returns nan. If False returns pmv and ppd values even if input values are outside the applicability limits of the model.
Returns
AdaptiveAshraeArrayResult: set containing results for the model

The ASHRAE 55 2020 limits are 10 < tdb [°C] < 40, 10 < tr [°C] < 40, 0 < vr [m/s] < 2, 10 < t running mean [°C] < 33.5

You can use this function to calculate if your conditions are within the adaptive thermal comfort region. Calculations with comply with the ASHRAE 55 2020 Standard [1].

Related types
AdaptiveAshraeArrayResult

Type: object

Properties
tmp_cmf (Array<number>) : Comfort temperature a that specific running mean temperature, default in [°C] or in [°F]
tmp_cmf_80_low (Array<number>) : Lower acceptable comfort temperature for 80% occupants, default in [°C] or in [°F]
tmp_cmf_80_up (Array<number>) : Upper acceptable comfort temperature for 80% occupants, default in [°C] or in [°F]
tmp_cmf_90_low (Array<number>) : Lower acceptable comfort temperature for 90% occupants, default in [°C] or in [°F]
tmp_cmf_90_up (Array<number>) : Upper acceptable comfort temperature for 90% occupants, default in [°C] or in [°F]
acceptability_80 (Array<boolean>) : Acceptability for 80% occupants
acceptability_90 (Array<boolean>) : Acceptability for 90% occupants
Related
adaptive_ashrae for a version that supports scalar arguments
Example
import { adaptive_ashrae_array } from "jsthermalcomfort/models";
const results = adaptive_ashrae_array([25], [25], [20], [0.1]);
console.log(results);
// {tmp_cmf: [24.0], tmp_cmf_80_low: [20.5], tmp_cmf_80_up: [27.5],
//   tmp_cmf_90_low: [21.5], tmp_cmf_90_up: [26.5], acceptability_80: [true],
//   acceptability_90: [true]}
console.log(results.acceptability_80);
// [true]
import { adaptive_ashrae_array } from "jsthermalcomfort/models";
// For users who want to use the IP system
const results = adaptive_ashrae_array([77], [77], [68], [0.3], 'IP');
console.log(results);
// {tmp_cmf: [75.2], tmp_cmf_80_low: [68.9], tmp_cmf_80_up: [81.5],
//  tmp_cmf_90_low: [70.7], tmp_cmf_90_up: [79.7], acceptability_80: [true],
//  acceptability_90: [true]}
import { adaptive_ashrae_array } from "jsthermalcomfort/models";
const results = adaptive_ashrae_array([25], [25], [9], [0.1]);
console.log(results);
// {tmp_cmf: [NaN], tmp_cmf_80_low: [NaN], ...}
// The adaptive thermal comfort model can only be used
// if the running mean temperature is higher than 10°C
Solar gain on people

Calculates the solar gain to the human body using the Effective Radiant Field ( ERF) [1]. The ERF is a measure of the net energy flux to or from the human body. ERF is expressed in W over human body surface area [w/m2].

In addition, it calculates the delta mean radiant temperature. Which is the amount by which the mean radiant temperature of the space should be increased if no solar radiation is present.

More information on the calculation procedure can be found in Appendix C of [1].

solar_gain(sol_altitude: number, sharp: number, sol_radiation_dir: number, sol_transmittance: number, f_svv: number, f_bes: number, asw: number, posture: ("standing" | "supine" | "seated"), floor_reflectance: number): SolarGainReturnType
Parameters
sol_altitude (number) Solar altitude, degrees from horizontal [deg]. Ranges between 0 and 90.
sharp (number) Solar horizontal angle relative to the front of the person (SHARP) [deg]. Ranges between 0 and 180 and is symmetrical on either side. Zero (0) degrees represents direct-beam radiation from the front, 90 degrees represents direct-beam radiation from the side, and 180 degrees rep- resent direct-beam radiation from the back. SHARP is the angle between the sun and the person only. Orientation relative to compass or to room is not included in SHARP.
sol_radiation_dir (number) Direct-beam solar radiation, [W/m2]. Ranges between 200 and 1000. See Table C2-3 of ASHRAE 55 2020 [1] .
sol_transmittance (number) Total solar transmittance, ranges from 0 to 1. The total solar transmittance of window systems, including glazing unit, blinds, and other façade treatments, shall be determined using one of the following methods:
  • i) Provided by manufacturer or from the National Fenestration Rating Council approved Lawrence Berkeley National Lab International Glazing Database.
  • ii) Glazing unit plus venetian blinds or other complex or unique shades shall be calculated using National Fenestration Rating Council approved software or Lawrence Berkeley National Lab Complex Glazing Database.
f_svv (number) Fraction of sky-vault view fraction exposed to body, ranges from 0 to 1. It can be calculated using the function f_svv in utilities.
f_bes (number) Fraction of the possible body surface exposed to sun, ranges from 0 to 1. See Table C2-2 and equation C-7 ASHRAE 55 2020 [1] .
asw (number = 0.7) The average short-wave absorptivity of the occupant. It will range widely, depending on the color of the occupant’s skin as well as the color and amount of clothing covering the body.

A value of 0.7 shall be used unless more specific information about the clothing or skin color of the occupants is available. Note: Short-wave absorptivity typically ranges from 0.57 to 0.84, depending on skin and clothing color. More information is available in Blum (1945).

posture (("standing" | "supine" | "seated") = "seated") Default 'seated' list of available options 'standing', 'supine' or 'seated'
floor_reflectance (number = 0.7) Floor refectance. It is assumed to be constant and equal to 0.6.
Returns
SolarGainReturnType:
Related types
SolarGainReturnType

Type: object

Properties
erf (number) : Solar gain to the human body using the Effective Radiant Field [W/m2]
delta_mrt (number) : Delta mean radiant temperature. The amount by which the mean radiant temperature of the space should be increased if no solar radiation is present.
Example
import {solar_gain} from "jsthermalcomfort/models";
const results = solar_gain(0, 120, 800, 0.5, 0.7, "seated");
console.log(results); // {erf: 42.9, delta_mrt: 10.3}
Cooling Effect (CE)

Returns the value of the Cooling Effect ( CE ) calculated in compliance with the ASHRAE 55 2020 Standard [1]. The CE of the elevated air speed is the value that, when subtracted equally from both the average air temperature and the mean radiant temperature, the same SET under still air as in the first SET calculation under elevated air speed. The cooling effect is calculated only for air speed higher than 0.1 m/s.

cooling_effect(tdb: number, tr: number, vr: number, rh: number, met: number, clo: number, wme: number, units: ("SI" | "IP")): number
Parameters
tdb (number) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (number) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
vr (number) relative air speed, default in [m/s] in [fps] if units = 'IP'

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function v_relative which is in .utilities.js.

rh (number) relative humidity, [%]
met (number) metabolic rate, [met]
clo (number) clothing insulation, [clo]

Note: The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met) The dynamic clothing insulation, clo, can be calculated using the function clo_dynamic which is in .utilities.js.

wme (number = 0) external work
units (("SI" | "IP") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
Returns
number: ce - Cooling Effect, default in [°C] in [°F] if units = 'IP'
Example
const CE = cooling_effect(25, 25, 0.3, 50, 1.2, 0.5);
console.log(CE); // Output: 1.64

// For users who want to use the IP system
const CE_IP = cooling_effect(77, 77, 1.64, 50, 1, 0.6, "IP");
console.log(CE_IP); // Output: 3.74
Adaptive Thermal Heat Balance (athb)

Return the PMV value calculated with the Adaptive Thermal Heat Balance Framework [27]. The adaptive thermal heat balance (ATHB) framework introduced a method to account for the three adaptive principals, namely physiological, behavioral, and psychological adaptation, individually within existing heat balance models. The objective is a predictive model of thermal sensation applicable during the design stage or in international standards without knowing characteristics of future occupants.

This is a version that supports scalar arguments.

athb(tdb: number, tr: number, vr: number, rh: number, met: number, t_running_mean: number): number
Parameters
tdb (number) dry bulb air temperature, in [°C]
tr (number) mean radiant temperature, in [°C]
vr (number) relative air speed, in [m/s]

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function jsthermalcomfort.utilities.v_relative.

rh (number) relative humidity, [%]
met (number) metabolic rate, [met]
t_running_mean (number) running mean temperature, in [°C]

The running mean temperature can be calculated using the function jsthermalcomfort.utilities.running_mean_outdoor_temperature.

Returns
number: athb_pmv - Predicted Mean Vote calculated with the Adaptive Thermal Heat Balance framework
Related
athb_array for a version that supports arrays.
Example
const tdb = 25;
const tr = 25;
const vr = 0.1;
const rh = 50;
const met = 1.1;
const t_running_mean = 20;

const athb_result = athb(tdb, tr, vr, rh, met, t_running_mean);
console.log(athb_result); // Output: 0.2
Adaptive Thermal Heat Balance (athb) (array version)

Return the PMV value calculated with the Adaptive Thermal Heat Balance Framework [27]. The adaptive thermal heat balance (ATHB) framework introduced a method to account for the three adaptive principals, namely physiological, behavioral, and psychological adaptation, individually within existing heat balance models. The objective is a predictive model of thermal sensation applicable during the design stage or in international standards without knowing characteristics of future occupants.

This is a version that supports arrays.

athb_array(tdb: Array<number>, tr: Array<number>, vr: Array<number>, rh: Array<number>, met: Array<number>, t_running_mean: Array<number>): Array<number>
Parameters
tdb (Array<number>) dry bulb air temperature, in [°C]
tr (Array<number>) mean radiant temperature, in [°C]
vr (Array<number>) relative air speed, in [m/s]

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function jsthermalcomfort.utilities.v_relative.

rh (Array<number>) relative humidity, [%]
met (Array<number>) metabolic rate, [met]
t_running_mean (Array<number>) running mean temperature, in [°C]

The running mean temperature can be calculated using the function jsthermalcomfort.utilities.running_mean_outdoor_temperature.

Returns
Array<number>: athb_pmv - Predicted Mean Vote calculated with the Adaptive Thermal Heat Balance framework
Related
athb for a version that supports scalar arguments.
Example
const tdb = [25, 27];
const tr = [25, 25];
const vr = [0.1, 0.1];
const rh = [50, 50];
const met = [1.1, 1.1];
const t_running_mean = [20, 20];

const athb_array_result = athb_array(tdb, tr, vr, rh, met, t_running_mean);
console.log(athb_array_result); // Output: [0.2, 0.209]
Predicted Mean Vote (PMV)

Returns Predicted Mean Vote ( PMV ) calculated in accordance with main thermal comfort Standards.

The PMV is an index that predicts the mean value of the thermal sensation votes (self-reported perceptions) of a large group of people on a sensation scale expressed from –3 to +3 corresponding to the categories: cold, cool, slightly cool, neutral, slightly warm, warm, and hot. [1]

While the PMV equation is the same for both the ISO and ASHRAE standards, in the ASHRAE 55 PMV equation, the SET is used to calculate the cooling effect first, this is then subtracted from both the air and mean radiant temperatures, and the differences are used as input to the PMV model, while the airspeed is set to 0.1m/s. Please read more in the Note below.

Notes:

You can use this function to calculate the PMV [1] [2]

This is a version that supports scalar arguments.

pmv(tdb: number, tr: number, vr: number, rh: number, met: number, clo: number, wme: number, standard: ("ISO" | "ASHRAE"), kwargs: PmvKwargs): number
Parameters
tdb (number) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (number) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
vr (number) relative air speed, default in [m/s] in [fps] if units = 'IP'

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function 'v_relative' in utilities.

rh (number) relative humidity, [%]
met (number) metabolic rate

Note: The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met) The dynamic clothing insulation, clo, can be calculated using the function 'clo_dynamic' in utilities.

clo (number) clothing insulation
wme (number = 0) external work
standard (("ISO" | "ASHRAE") = "ISO") comfort standard used for calculation

· If "ISO", then the ISO Equation is used

· If "ASHRAE", then the ASHRAE Equation is used

Note: While the PMV equation is the same for both the ISO and ASHRAE standards, the ASHRAE Standard Use of the PMV model is limited to air speeds below 0.10m/s (20 fpm). When air speeds exceed 0.10 m/s (20 fpm), the comfort zone boundaries are adjusted based on the SET model. This change was introduced by the Addendum_C to Standard 55-2020

kwargs (PmvKwargs = {}) additional arguments
Returns
number: pmv - Predicted Mean Vote
Related types
PmvKwargs

Type: Object

Properties
units (("SI" | "IP")) : select the SI (International System of Units) or the IP (Imperial Units) system.
limit_inputs (boolean) : Default is True. By default, if the inputs are outside the standard applicability limits the function returns NaN. If false, returns pmv and ppd values even if input values are outside the applicability limits of the model.

The ASHRAE 55 2020 limits are 10 < tdb [°C] < 40, 10 < tr [°C] < 40, 0 < vr [m/s] < 2, 1 < met [met] < 4, and 0 < clo [clo] < 1.5. The ISO 7730 2005 limits are 10 < tdb [°C] < 30, 10 < tr [°C] < 40, 0 < vr [m/s] < 1, 0.8 < met [met] < 4, 0 < clo [clo] < 2, and -2 < PMV < 2.

airspeed_control (boolean) : This only applies if standard = "ASHRAE".

Default is True. By default, it is assumed that the occupant has control over the airspeed. In this case, the ASHRAE 55 Standard does not impose any airspeed limits. On the other hand, if the occupant has no control over the airspeed, the ASHRAE 55 imposes an upper limit for v which varies as a function of the operative temperature, for more information please consult the Standard.

Related
pmv_array for a version that supports arrays.
Example
const tdb = 25;
const tr = 25;
const rh = 50;
const v = 0.1;
const met = 1.4;
const clo = 0.5;

// calculate relative air speed
const v_r = v_relative(v, met);
// calculate dynamic clothing
const clo_d = clo_dynamic(clo, met);

const results = pmv(tdb, tr, v_r, rh, met, clo_d);
console.log(results); // 0.06
Predicted Mean Vote (PMV) (array version)

Returns Predicted Mean Vote ( PMV ) calculated in accordance with main thermal comfort Standards.

The PMV is an index that predicts the mean value of the thermal sensation votes (self-reported perceptions) of a large group of people on a sensation scale expressed from –3 to +3 corresponding to the categories: cold, cool, slightly cool, neutral, slightly warm, warm, and hot. [1]

While the PMV equation is the same for both the ISO and ASHRAE standards, in the ASHRAE 55 PMV equation, the SET is used to calculate the cooling effect first, this is then subtracted from both the air and mean radiant temperatures, and the differences are used as input to the PMV model, while the airspeed is set to 0.1m/s. Please read more in the Note below.

Notes:

You can use this function to calculate the PMV [1] [2]

This is a version that supports arrays.

pmv_array(tdb: Array<number>, tr: Array<number>, vr: Array<number>, rh: Array<number>, met: Array<number>, clo: Array<number>, wme: Array<number>, standard: ("ISO" | "ASHRAE"), kwargs: PmvKwargs): Array<number>
Parameters
tdb (Array<number>) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (Array<number>) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
vr (Array<number>) relative air speed, default in [m/s] in [fps] if units = 'IP'

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function 'v_relative_array' in utilities.

rh (Array<number>) relative humidity, [%]
met (Array<number>) metabolic rate, [met]
clo (Array<number>) clothing insulation, [clo]

Note: The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met) The dynamic clothing insulation, clo, can be calculated using the function 'clo_dynamic_array' in utilities.

wme (Array<number>) external work, default is array of 0
standard (("ISO" | "ASHRAE") = "ISO") comfort standard used for calculation

· If "ISO", then the ISO Equation is used

· If "ASHRAE", then the ASHRAE Equation is used

Note: While the PMV equation is the same for both the ISO and ASHRAE standards, the ASHRAE Standard Use of the PMV model is limited to air speeds below 0.10m/s (20 fpm). When air speeds exceed 0.10 m/s (20 fpm), the comfort zone boundaries are adjusted based on the SET model. This change was introduced by the Addendum_C to Standard 55-2020

kwargs (PmvKwargs = {}) additional arguments
Returns
Array<number>: pmv - Predicted Mean Vote
Related
pmv for a version that supports scalar arguments.
Example
const tdb = [22, 25];
const tr = [25, 25];
const rh = [50, 50];
const v = [0.1, 0.1];
const met = [1.4, 1.4];
const clo = [0.5, 0.5];

// calculate relative air speed
const v_r = v_relative_array(v, met);
// calculate dynamic clothing
const clo_d = clo_dynamic_array(clo, met);

const results = pmv_array(tdb, tr, v_r, rh, met, clo_d);
console.log(results); // [-0.47, 0.06]
Adaptive Predicted Mean Vote (aPMV)

Returns Adaptive Predicted Mean Vote (aPMV) [25]. This index was developed by Yao, R. et al. (2009). The model takes into account factors such as culture, climate, social, psychological and behavioral adaptations, which have an impact on the senses used to detect thermal comfort. This model uses an adaptive coefficient (λ) representing the adaptive factors that affect the sense of thermal comfort.

This is a version that supports scalar arguments.

a_pmv(tdb: number, tr: number, vr: number, rh: number, met: number, clo: number, a_coefficient: number, wme: number, kwargs: A_pmvKwargs): number
Parameters
tdb (number) Dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (number) Mean radiant temperature, default in [°C] in [°F] if units = 'IP'
vr (number) Relative air speed, default in [m/s] in [fps] if units = 'IP'

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function v_relative in utilities.js.

rh (number) Relative humidity, [%]
met (number) Metabolic rate, [met]
clo (number) Clothing insulation, [clo]

Note: The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met) The dynamic clothing insulation, clo, can be calculated using the function clo_dynamic in utilities.js.

a_coefficient (number) Adaptive coefficient
wme (number = 0) External work
kwargs (A_pmvKwargs = {}) additional arguments
Returns
number: pmv - Predicted Mean Vote
Related types
A_pmvKwargs

Type: Object

Properties
units (("SI" | "IP")) : select the SI (International System of Units) or the IP (Imperial Units) system.
limit_inputs (boolean) : Default is True. By default, if the inputs are outside the standard applicability limits the function returns NaN. If false, returns pmv and ppd values even if input values are outside the applicability limits of the model.

The ISO 7730 2005 limits are 10 < tdb [°C] < 30, 10 < tr [°C] < 40, 0 < vr [m/s] < 1, 0.8 < met [met] < 4, 0 < clo [clo] < 2, and -2 < PMV < 2.

Related
a_pmv_array for a version that supports arrays.
Example
const tdb = 24,
const tr = 30,
const vr = 0.22,
const rh = 50,
const met = 1.4,
const clo = 0.5,
const a_coefficient = 0.293,
const wme = undefined,

const result = a_pmv(tdb, tr, vr, rh, met, clo, a_coefficient, wme);
console.log(result) //output 0.48
Adaptive Predicted Mean Vote (aPMV) (array version)

Returns Adaptive Predicted Mean Vote (aPMV) [25]. This index was developed by Yao, R. et al. (2009). The model takes into account factors such as culture, climate, social, psychological and behavioral adaptations, which have an impact on the senses used to detect thermal comfort. This model uses an adaptive coefficient (λ) representing the adaptive factors that affect the sense of thermal comfort.

This is a version that supports arrays.

a_pmv_array(tdb: Array<number>, tr: Array<number>, vr: Array<number>, rh: Array<number>, met: Array<number>, clo: Array<number>, a_coefficient: Array<number>, wme: Array<number>, kwargs: A_pmvKwargs): Array<number>
Parameters
tdb (Array<number>) Dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (Array<number>) Mean radiant temperature, default in [°C] in [°F] if units = 'IP'
vr (Array<number>) Relative air speed, default in [m/s] in [fps] if units = 'IP'

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function v_relative_array in utilities.js.

rh (Array<number>) Relative humidity, [%]
met (Array<number>) Metabolic rate, [met]
clo (Array<number>) Clothing insulation, [clo]

Note: The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met) The dynamic clothing insulation, clo, can be calculated using the function clo_dynamic_array in utilities.js.

a_coefficient (Array<number>) Adaptive coefficient
wme (Array<number>) External work, default is array of 0
kwargs (A_pmvKwargs = {}) additional arguments
Returns
Array<number>: pmv - Predicted Mean Vote
Related
a_pmv for a version that supports scalar arguments.
Example
const tdb = [24, 30],
const tr = [30, 30],
const vr = [0.22, 0.22],
const rh = [50, 50],
const met = [1.4, 1.4],
const clo = [0.5, 0.5],
const a_coefficient = [0.293, 0.293],
const wme = undefined,

const result = a_pmv_array(tdb, tr, vr, rh, met, clo, a_coefficient, wme);
console.log(result) //output [0.48, 1.09]
Ankle draft

Calculates the percentage of thermally dissatisfied people with the ankle draft (0.1 m) above floor level [23]. This equation is only applicable for vr < 0.2 m/s (40 fps).

ankle_draft(tdb: number, tr: number, vr: number, rh: number, met: number, clo: number, v_ankle: number, units: ("IP" | "SI")): AnkleDraftRet
Parameters
tdb (number) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'

Note: The air temperature is the average value over two heights: 0.6 m (24 in.) and 1.1 m (43 in.) for seated occupants and 1.1 m (43 in.) and 1.7 m (67 in.) for standing occupants.

tr (number) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
vr (number) relative air speed, default in [m/s] in [fps] if units = 'IP'

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function v_relative in utilities.js.

rh (number) relative humidity, [%]
met (number) metabolic rate, [met]
clo (number) clothing insulation, [clo]

Note: The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met) The dynamic clothing insulation, clo, can be calculated using the function clo_dynamic in utilities.js.

v_ankle (number) air speed at the 0.1 m (4 in.) above the floor, default in [m/s] in [fps] if units = 'IP'
units (("IP" | "SI") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
Returns
AnkleDraftRet: Returns {"PPD_ad": ppd_val, "Acceptability": acceptability}
Related types
AnkleDraftRet

Type: Object

Properties
PPD_ad (number) : redicted Percentage of Dissatisfied occupants with ankle draft, [%]
Acceptability (boolean) : The ASHRAE 55 2020 standard defines that the value of air speed at the ankle level is acceptable if PPD_ad is lower or equal than 20%
Example
results = ankle_draft(25, 25, 0.2, 50, 1.2, 0.5, 0.3, "SI")
console.log(results) // expected result is {PPD_ad: 18.5, Acceptability: true}
Adjusted Predicted Mean Votes with Expectancy Factor (ePMV)

Returns Adjusted Predicted Mean Votes with Expectancy Factor (ePMV). This index was developed by Fanger, P. O. et al. (2002). In non-air-conditioned buildings in warm climates, occupants may sense the warmth as being less severe than the PMV predicts. The main reason is low expectations, but a metabolic rate that is estimated too high can also contribute to explaining the difference. An extension of the PMV model that includes an expectancy factor is introduced for use in non-air-conditioned buildings in warm climates [26].

This is a version that supports scalar arguments.

e_pmv(tdb: number, tr: number, vr: number, rh: number, met: number, clo: number, e_coefficient: number, wme: number, kwargs: E_pmvKwargs?): number
Parameters
tdb (number) Dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (number) Mean radiant temperature, default in [°C] in [°F] if units = 'IP'
vr (number) Relative air speed, default in [m/s] in [fps] if units = 'IP'

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function v_relative in utilities.js.

rh (number) Relative humidity, [%]
met (number) Metabolic rate, [met]
clo (number) Clothing insulation, [clo]

Note: The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met) The dynamic clothing insulation, clo, can be calculated using the function clo_dynamic in utilities.js.

e_coefficient (number) expectancy factor
wme (number = 0) External work
kwargs (E_pmvKwargs? = {}) additional arguments
Returns
number: pmv - Predicted Mean Vote
Related types
E_pmvKwargs

Type: Object

Properties
units (("SI" | "IP")) : select the SI (International System of Units) or the IP (Imperial Units) system.
limit_inputs (boolean) : Default is True. By default, if the inputs are outside the standard applicability limits the function returns NaN. If false, returns pmv and ppd values even if input values are outside the applicability limits of the model.

The ISO 7730 2005 limits are 10 < tdb [°C] < 30, 10 < tr [°C] < 40, 0 < vr [m/s] < 1, 0.8 < met [met] < 4, 0 < clo [clo] < 2, and -2 < PMV < 2.

Related
e_pmv_array for a version that supports arrays.
Example
const tdb = 28;
const tr = 28;
const v = 0.1;
const met = 1.4;
const clo = 0.5;
// Calculate relative air speed
const v_r = v_relative(v, met);
// Calculate dynamic clothing
const clo_d = clo_dynamic(clo, met);
const e_coefficient = 0.6;

const result = e_pmv(tdb, tr, v_r, rh, met, clo_d, e_coefficient);
console.log(result) // output 0.51
Adjusted Predicted Mean Votes with Expectancy Factor (ePMV) (array version)

Returns Adjusted Predicted Mean Votes with Expectancy Factor (ePMV). This index was developed by Fanger, P. O. et al. (2002). In non-air-conditioned buildings in warm climates, occupants may sense the warmth as being less severe than the PMV predicts. The main reason is low expectations, but a metabolic rate that is estimated too high can also contribute to explaining the difference. An extension of the PMV model that includes an expectancy factor is introduced for use in non-air-conditioned buildings in warm climates [26].

This is a version that supports arrays.

e_pmv_array(tdb: Array<number>, tr: Array<number>, vr: Array<number>, rh: Array<number>, met: Array<number>, clo: Array<number>, e_coefficient: Array<number>, wme: Array<number>, kwargs: E_pmvKwargs?): Array<number>
Parameters
tdb (Array<number>) Dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (Array<number>) Mean radiant temperature, default in [°C] in [°F] if units = 'IP'
vr (Array<number>) Relative air speed, default in [m/s] in [fps] if units = 'IP'

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function v_relative_array in utilities.js.

rh (Array<number>) Relative humidity, [%]
met (Array<number>) Metabolic rate, [met]
clo (Array<number>) Clothing insulation, [clo]

Note: The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met) The dynamic clothing insulation, clo, can be calculated using the function clo_dynamic_array in utilities.js.

e_coefficient (Array<number>) expectancy factor
wme (Array<number>) External work, default is array of 0
kwargs (E_pmvKwargs? = {}) additional arguments
Returns
Array<number>: pmv - Predicted Mean Vote
Related
a_pmv for a version that supports scalar arguments.
Example
const tdb = [24, 30];
const tr = [30, 30];
const v = [0.22, 0.22];
const met = [1.4, 1.4];
const clo = [0.5, 0.5];
// Calculate relative air speed
const v_r = v_relative_array(v, met);
// Calculate dynamic clothing
const clo_d = clo_dynamic_array(clo, met);
const e_coefficient = [0.6, 0.6];

const result = e_pmv_array(tdb, tr, v_r, rh, met, clo_d, e_coefficient);
console.log(result) // output [0.29, 0.91]
Vertical air temperature gradient

Calculates the percentage of thermally dissatisfied people with a vertical temperature gradient between feet and head [1] . This equation is only applicable for vr < 0.2 m/s (40 fps).

vertical_tmp_grad_ppd(tdb: number, tr: number, vr: number, rh: number, met: number, clo: number, vertical_tmp_grad: number, units: ("SI" | "IP")): VerTmpGradReturnType
Parameters
tdb (number) dry bulb air temperature, default in [°C] in [°F] if "units" = 'IP'.

Note: The air temperature is the average value over two heights: 0.6 m (24 in.) and 1.1 m (43 in.) for seated occupants and 1.1 m (43 in.) and 1.7 m (67 in.) for standing occupants.

tr (number) mean radiant temperature, default in [°C] in [°F] if "units" = 'IP'.
vr (number) relative air speed, default in [m/s] in [fps] if "units" = "IP"

Note: vr is the relative air speed caused by body movement and not the air speed measured by the air speed sensor. The relative air speed is the sum of the average air speed measured by the sensor plus the activity-generated air speed (Vag). Where Vag is the activity-generated air speed caused by motion of individual body parts. vr can be calculated using the function pythermalcomfort.utilities.v_relative().

rh (number) relative humidity, [%].
met (number) metabolic rate, [met]
clo (number) clothing insulation, [clo]

Note: The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met) The dynamic clothing insulation, clo, can be calculated using the function pythermalcomfort.utilities.clo_dynamic().

vertical_tmp_grad (number) vertical temperature gradient between the feet and the head, default in [°C/m] in [°F/ft] if units = ‘IP’
units (("SI" | "IP") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
Returns
VerTmpGradReturnType: Object with results of the PPD with vertical temprature gradient.
Related types
VerTmpGradReturnType

Type: Object

Properties
PPD_vg (number) : Predicted Percentage of Dissatisfied occupants with vertical temperature gradient, [%]
Acceptability (boolean) : The ASHRAE 55 2020 standard defines that the value of air speed at the ankle level is acceptable if PPD_ad is lower or equal than 5 %
Example
const result = vertical_tmp_grad_ppd(25, 25, 0.1, 50, 1.2, 0.5, 7); // returns {'PPD_vg': 12.6, 'Acceptability': false}
Use Fans During Heatwaves

It helps you to estimate if the conditions you have selected would cause heat strain. This occurs when either the following variables reaches its maximum value:

  • m_rsw Rate at which regulatory sweat is generated, [mL/h/m2].
  • w : Skin wettedness, adimensional. Ranges from 0 and 1.
  • m_bl : Skin blood flow [kg/h/m2].
use_fans_heatwaves(tdb: number, tr: number, v: number, rh: number, met: number, clo: number, wme: number, body_surface_area: number?, p_atm: number?, body_position: ("standing" | "sitting"), units: ("SI" | "IP"), max_skin_blood_flow: number, kwargs: HeatwaveKwargs?): HeatwaveReturnType
Parameters
tdb (number) dry bulb air temperature, default in [°C] in [°F] if units = ‘IP’
tr (number) mean radiant temperature, default in [°C] in [°F] if units = ‘IP’
v (number) air speed, default in [m/s] in [fps] if units = ‘IP’
rh (number) relative humidity, [%]
met (number) metabolic rate, [met]
clo (number) clothing insulation, [clo]
wme (number = 0) external work, [met] default 0
body_surface_area (number?) body surface area, default value 1.8258 [m2] in [ft2] if units = ‘IP’

The body surface area can be calculated using the function pythermalcomfort.utilities.body_surface_area().

p_atm (number?) atmospheric pressure, default value 101325 [Pa] in [atm] if units = ‘IP’
body_position (("standing" | "sitting") = "standing") select either “sitting” or “standing”
units (("SI" | "IP") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
max_skin_blood_flow (number = 80) maximum blood flow from the core to the skin
kwargs (HeatwaveKwargs? = {})
Returns
HeatwaveReturnType: object with results of use fans during heatwave
Related types
HeatwaveKwargs

Type: Object

Properties
max_sweating (number?) : max sweating, [mL/h/m2] default 500
round (boolean?) : if True rounds output value, if False it does not round it, default True
limit_inputs (boolean?) : – By default, if the inputs are outsude the following limits the function returns nan. If False returns values regardless of the input values, default True

The applicability limits are 20 < tdb [°C] < 50, 20 < tr [°C] < 50, 0.1 < v [m/s] < 4.5, 0.7 < met [met] < 2, and 0 < clo [clo] < 1.

HeatwaveReturnType

Type: Object

Properties
e_skin (number) : – Total rate of evaporative heat loss from skin, [W/m2]. Equal to e_rsw + e_diff
e_rsw (number) : – Rate of evaporative heat loss from sweat evaporation, [W/m2]
e_diff (number) : – Rate of evaporative heat loss from moisture diffused through the skin [W/m2]
e_max (number) : – Maximum rate of evaporative heat loss from skin, [W/m2]
q_sensible (number) : – Sensible heat loss from skin, [W/m2]
q_skin (number) : – Total rate of heat loss from skin, [W/m2]. Equal to q_sensible + e_skin
q_res (number) : – Total rate of heat loss through respiration, [W/m2]
t_core (number) : – Core temperature, [°C]
t_skin (number) : – Skin temperature, [°C]
m_bl (number) : – Skin blood flow, [kg/h/m2]
m_rsw (number) : – Rate at which regulatory sweat is generated, [kg/h/m2]
w (number) : – Skin wettedness, adimensional. Ranges from 0 and 1
w_max (number) : – Skin wettedness (w) practical upper limit, adimensional. Ranges from 0 and 1
heat_strain ((boolean | undefined)) : – True if the model predict that the person may be experiencing heat strain, undefined if the result of two nodes model is not a number
heat_strain_blood_flow ((boolean | undefined)) : – True if heat strain is caused by skin blood flow (m_bl) reaching its maximum value, undefined if the result of two nodes model is not a number
heat_strain_w ((boolean | undefined)) : – True if heat strain is caused by skin wettedness (w) reaching its maximum value, undefined if the result of two nodes model is not a number
heat_strain_sweating ((boolean | undefined)) : – True if heat strain is caused by regulatory sweating (m_rsw) reaching its maximum value, undefined if the result of two nodes model is not a number
Example
const results = use_fans_heatwaves(25, 25, 0.1, 50, 1.2, 0.5);
console.log(results); // 
{
e_skin: 18.1,
e_rsw: 10.0,
e_max: 145.0,
q_sensible: 45.7, 
q_skin: 63.8, 
q_res: 5.2, 
t_core: 36.9, 
t_skin: 33.8, 
m_bl: 13.6, 
m_rsw: 14.6, 
w: 0.1, 
w_max: 0.7, 
heat_strain_blood_flow: 0.0, 
heat_strain_w: 0.0, 
heat_strain_sweating: 0.0, 
heat_strain: 0.0
}
Clothing prediction

Representative clothing insulation Icl as a function of outdoor air temperature at 06:00 a.m [4].

Note: The ASHRAE 55 2020 states that it is acceptable to determine the clothing insulation Icl using this equation in mechanically conditioned buildings [1].

clo_tout(tout: number, units: ("IP" | "SI")): number
Parameters
tout (number) outdoor air temperature at 06:00 a.m., default in [°C] in [°F] if units = 'IP'
units (("IP" | "SI") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
Returns
number: Representative clothing insulation Icl, [clo]
Related
clo_tout_array for a version that supports arrays
Clothing prediction (array version)

Representative clothing insulation Icl as a function of outdoor air temperature at 06:00 a.m [4].

Note: The ASHRAE 55 2020 states that it is acceptable to determine the clothing insulation Icl using this equation in mechanically conditioned buildings [1].

clo_tout_array(tout: Array<number>, units: ("IP" | "SI")): Array<number>
Parameters
tout (Array<number>) outdoor air temperatures at 06:00 a.m., default in [°C] in [°F] if units = 'IP'
units (("IP" | "SI") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
Returns
Array<number>: Representative clothing insulation Icl, [clo]
Related
clo_tout for a version that supports scalar arguments
Universal Thermal Climate Index (UTCI)

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]

  • Note: 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(tdb: number, tr: number, v: number, rh: number, units: ("SI" | "IP"), return_stress_category: boolean, limit_inputs: boolean)
Parameters
tdb (number) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (number) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
v (number) wind speed 10m above ground level, default in [m/s] in [fps] if units = 'IP'
rh (number) relative humidity, [%]
units (("SI" | "IP") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
return_stress_category (boolean = false) default False if True returns the UTCI categorized in terms of thermal stress.
limit_inputs (boolean = true) 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.
Related
utci_array for a version that supports arrays
Example
console.log(utci(25, 25, 1.0, 50)) // will print 24.6
console.log(utci(77, 77, 3.28, 50, 'ip')) // will print 76.4
console.log(utci(25, 25, 1.0, 50, 'si', true))
// will print {utci: 24.6, stress_category: "no thermal stress"}
Universal Thermal Climate Index (array version)

Determines the Universal Thermal Climate Index (UTCI) (Supports array type). 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]

  • Note: 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_array(tdb: Array<number>, tr: Array<number>, v: Array<number>, rh: Array<number>, units: ("SI" | "IP"), return_stress_category: boolean, limit_inputs: boolean)
Parameters
tdb (Array<number>) dry bulb air temperature, default in [°C] in [°F] if units = 'IP'
tr (Array<number>) mean radiant temperature, default in [°C] in [°F] if units = 'IP'
v (Array<number>) wind speed 10m above ground level, default in [m/s] in [fps] if units = 'IP'
rh (Array<number>) relative humidity, [%]
units (("SI" | "IP") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
return_stress_category (boolean = false) default False, if True returns the UTCI categorized in terms of thermal stress.
limit_inputs (boolean = true) 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.
Related
utci for scalar arguments.
Example
console.log(utci_array([25, 25], [27, 25], [1, 1], [50, 50])) // will print [25.2, 24.6]
console.log(utci_array([25, 25], [27, 25], [1, 1], [50, 50], "si", true))
// will print {
//     utci: [25.2, 24.6],
//    stress_category: ["no thermal stress", "no thermal stress"],
//  }
Physiological Equivalent Temperature (PET)

The steady physiological equivalent temperature (PET) is calculated using the Munich Energy-balance Model for Individuals (MEMI), which simulates the human body's thermal circumstances in a medically realistic manner. PET is defined as the air temperature at which, in a typical indoor setting the heat budget of the human body is balanced with the same core and skin temperature as under the complex outdoor conditions to be assessed [20].

The following assumptions are made for the indoor reference climate: tdb = tr, v = 0.1 m/s, water vapour pressure = 12 hPa, clo = 0.9 clo, and met = 1.37 met + basic metabolism.

PET allows a layperson to compare the total effects of complex thermal circumstances outside with his or her own personal experience indoors in this way. This function solves the heat balances without accounting for heat storage in the human body.

The PET was originally proposed by Hoppe [20]. In 2018, Walther and Goestchel [21] proposed a correction of the original model, purging the errors in the PET calculation routine, and implementing a state-of-the-art vapour diffusion model. Walther and Goestchel (2018) model is therefore used to calculate the PET.

pet_steady(tdb: number, tr: number, v: number, rh: number, met: number, clo: number, p_atm: number, position: (1 | 2 | 3), age: number, sex: (1 | 2), weight: number, height: number, wme: number): number
Parameters
tdb (number) dry bulb air temperature, [°C]
tr (number) mean radiant temperature, [°C]
v (number) air speed, [m/s]
rh (number) relative humidity, [%]
met (number) metabolic rate, [met]
clo (number) clothing insulation, [clo]
p_atm (number = 1013.25) atmospheric pressure, default value 1013.25 [hPa]
position ((1 | 2 | 3) = 1) position of the individual (1=sitting, 2=standing, 3=standing, forced convection)
age (number = 23) age in years
sex ((1 | 2) = 1) male (1) or female (2).
weight (number = 75) body mass, [kg]
height (number = 1.8) height, [m]
wme (number = 0) external work, [W/(m2)]
Returns
number: Steady-state PET under the given ambient conditions
Example
const result = pet_steady(20, 20, 50, 0.15, 1.37, 0.5);
console.log(result); // 18.85
JOS3

JOS-3 model simulates human thermal physiology including skin temperature, core temperature, sweating rate, etc. for the whole body and 17 local body parts.

This model was developed at Shin-ichi Tanabe Laboratory, Waseda University and was derived from 65 Multi-Node model (https://doi.org/10.1016/S0378-7788(02)00014-2) and JOS-2 model (https://doi.org/10.1016/j.buildenv.2013.04.013).

To use this model, create an instance of the JOS3 class with optional body parameters such as body height, weight, age, sex, etc.

Environmental conditions such as air temperature, mean radiant temperature, air velocity, etc. can be set using the setter methods. (ex. X.tdb, X.tr X.v) If you want to set the different conditions in each body part, set them as a 17 lengths of list, dictionary, or numpy array format.

List or numpy array format input must be 17 lengths and means the order of "head", "neck", "chest", "back", "pelvis", "left_shoulder", "left_arm", "left_hand", "right_shoulder", "right_arm", "right_hand", "left_thigh", "left_leg", "left_foot", "right_thigh", "right_leg" and "right_foot".

The model output includes local and mean skin temperature, local core temperature, local and mean skin wettedness, and heat loss from the skin etc. The model output can be accessed using "dict_results()" method and be converted to a csv file using "to_csv" method. Each output parameter also can be accessed using getter methods. (ex. X.t_skin, X.t_skin_mean, X.t_core)

If you use this package, please cite us as follows and mention the version of pythermalcomfort used: Y. Takahashi, A. Nomoto, S. Yoda, R. Hisayama, M. Ogata, Y. Ozeki, S. Tanabe, Thermoregulation Model JOS-3 with New Open Source Code, Energy & Buildings (2020), doi: https://doi.org/10.1016/j.enbuild.2020.110575

Note: To maintain consistency in variable names for jsthermalcomfort and pythermalcomfort, some variable names differ from those used in the original paper.

Parameters
height (number? = JOS3Defaults.height) body height, in [m].
weight (number? = JOS3Defaults.weight) body weight, in [kg].
fat (number? = JOS3Defaults.body_fat) fat percentage, in [%].
age (number? = JOS3Defaults.age) age, in [years].
sex (("male" | "female")? = JOS3Defaults.sex) sex.
ci (number? = JOS3Defaults.cardiac_index) Cardiac index, in [L/min/m2].
bmr_equation (("harris-benedict" | "harris-benedict_origin" | "japanese" | "ganpule")? = JOS3Defaults.bmr_equation) The equation used to calculate basal metabolic rate (BMR).
bsa_equation (("dubois" | "fujimoto" | "kruazumi" | "takahira")? = JOS3Defaults.bsa_equation) The equation used to calculate body surface area (bsa).
ex_output (([] | "all")? = []) This is used when you want to display results other than the default output parameters (ex.skin temperature); by default, JOS outputs only the most necessary parameters in order to reduce the computational load.
Psychrometrics
p_sat(tdb)

Calculates vapour pressure of water at different temperatures

p_sat(tdb: number): number
Parameters
tdb (number) air temperature, [°C]
Returns
number: vapour pressure of water, [Pa]
p_sat_torr(tdb)

Estimates the saturation vapour pressure in [torr].

p_sat_torr(tdb: number): number
Parameters
tdb (number) dry bulb air temperature [C]
Returns
number: saturation vapour pressure [torr]
Related
p_sat_torr_array for a version that supports arrays
p_sat_torr_array(tdb)

Estimates the saturation vapour pressure in [torr].

p_sat_torr_array(tdb: Array<number>): Array<number>
Parameters
tdb (Array<number>) dry bulb air temperature [C]
Returns
Array<number>: saturation vapour pressure [torr]
Related
p_sat_torr for a version that supports scalar arguments
t_o(tdb, tr, v, standard)

Calculates operative temperature in accordance with ISO 7726:1998 [5].

t_o(tdb: number, tr: number, v: number, standard: ("ISO" | "ASHRAE")): number
Parameters
tdb (number) air temperature [C]
tr (number) mean radiant temperature [C]
v (number) air speed [m/s]
standard (("ISO" | "ASHRAE") = "ISO") the standard to use
Returns
number: operative temperature [C]
Related
t_o_array for a version that supports arrays
t_o_array(tdb, tr, v, standard)

Calculates operative temperature in accordance with ISO 7726:1998 [5].

t_o_array(tdb: Array<number>, tr: Array<number>, v: Array<number>, standard: ("ISO" | "ASHRAE")): Array<number>
Parameters
tdb (Array<number>) air temperature [C]
tr (Array<number>) mean radiant temperature [C]
v (Array<number>) air speed [m/s]
standard (("ISO" | "ASHRAE") = "ISO") the standard to use
Returns
Array<number>: operative temperature [C]
Related
t_o for a version that supports scalar arguments
enthalpy(tdb, hr)

Calculates air enthalpy

enthalpy(tdb: number, hr: number): number
Parameters
tdb (number) air temperature [C]
hr (number) humidity ratio [kg water/kg dry air]
Returns
number: enthalpy [J/kg dry air]
t_wb(tdb, rh)

Calculates the wet-bulb temperature using the Stull equation [6].

t_wb(tdb: number, rh: number): number
Parameters
tdb (number) air temperature, [°C]
rh (number) relative humidity, [%]
Returns
number: wet-bulb temperature, [°C]
t_mrt(tg, tdb, v, d, emissivity, standard)

Converts globe temperature reading into mean radiant temperature in accordance with either the Mixed Convection developed by Teitelbaum E. et al. (2022) or the ISO 7726:1998 Standard [5].

t_mrt(tg: number, tdb: number, v: number, d: number, emissivity: number, standard: ("Mixed Convection" | "ISO")): number
Parameters
tg (number) globe temperature, [°C]
tdb (number) air temperature, [°C]
v (number) air speed, [m/s]
d (number = 0.15) diameter of the globe, [m] default 0.15 m
emissivity (number = 0.95) emissivity of the globe temperature sensor, default 0.95
standard (("Mixed Convection" | "ISO") = "Mixed Convection") either choose between the Mixed Convection and ISO formulations. The Mixed Convection formulation has been proposed by Teitelbaum E. et al. (2022) to better determine the free and forced convection coefficient used in the calculation of the mean radiant temperature. They also showed that mean radiant temperature measured with ping-pong ball-sized globe thermometers is not reliable due to a stochastic convective bias [22] . The Mixed Convection model has only been validated for globe sensors with a diameter between 0.04 and 0.15 m.
Returns
number:
Related
t_mrt_array for a version that supports arrays
t_mrt_array(tg, tdb, v, d, emissivity, standard)

Converts globe temperature reading into mean radiant temperature in accordance with either the Mixed Convection developed by Teitelbaum E. et al. (2022) or the ISO 7726:1998 Standard [5].

t_mrt_array(tg: Array<number>, tdb: Array<number>, v: Array<number>, d: Array<number>, emissivity: Array<number>, standard: ("Mixed Convection" | "ISO")): Array<number>
Parameters
tg (Array<number>) globe temperature, [°C]
tdb (Array<number>) air temperature, [°C]
v (Array<number>) air speed, [m/s]
d (Array<number>) diameter of the globe, [m] default 0.15 m
emissivity (Array<number>) emissivity of the globe temperature sensor, default 0.95
standard (("Mixed Convection" | "ISO") = "Mixed Convection") either choose between the Mixed Convection and ISO formulations. Refer to the t_mrt function for more information
Returns
Array<number>:
Related
t_mrt for scalar arguments. Accepts array arguments.
psy_ta_rh(tdb, rh, p_atm)

Calculates psychrometric values of air based on dry bulb air temperature and relative humidity.

psy_ta_rh(tdb: number, rh: number, p_atm: number): PsyTaRhReturnType
Parameters
tdb (number) air temperature, [°C]
rh (number) relative humidity, [%]
p_atm (number = 101325) atmospheric pressure, [Pa]
Returns
PsyTaRhReturnType: object with calculated psychrometrics values
Related types
PsyTaRhReturnType

Type: object

Properties
p_vap (number) : partial pressure of water vapor in moist air, [Pa]
hr (number) : humidity ratio, [kg water/kg dry air]
t_wb (number) : wet bulb temperature, [°C]
t_dp (number) : dew point temperature, [°C]
h (number) : enthalpy [J/kg dry air]
Example
import { psy_ta_rh } from "jsthermalcomfort";
const results = psy_ta_rh(21, 56);
console.log(results); // { p_sat: 2487.7, p_vap: 1393.112, hr: -2.2041754048718936, t_wb: 15.4, t_dp: 11.9, h: -5575107.96 }
Utilities
Body Surface Area

Returns the body surface area in square meters

body_surface_area(weight: number, height: number, formula: ("dubois" | "takahira" | "fujimoto" | "kurazumi")): number
Parameters
weight (number) body weight, [kg]
height (number) height, [m]
formula (("dubois" | "takahira" | "fujimoto" | "kurazumi") = "dubois") formula used to calculate the body surface area. default="dubois"
Returns
number: body surface area, [m2]
Relative air speed

Estimates the relative air speed which combines the average air speed of the space plus the relative air speed caused by the body movement. Vag is assumed to be 0 for metabolic rates equal and lower than 1 met and otherwise equal to Vag = 0.3 (M - 1) (m/s)

v_relative(v: number, met: number): number
Parameters
v (number) air spped measured by the sensor, [m/s]
met (number) metabolic rate, [met]
Returns
number: relative air speed, [m/s]
Related
v_relative_array for a version that supports array arguments
Relative air speed (array version)

Estimates the relative air speed which combines the average air speed of the space plus the relative air speed caused by the body movement. Vag is assumed to be 0 for metabolic rates equal and lower than 1 met and otherwise equal to Vag = 0.3 (M - 1) (m/s)

v_relative_array(v: Array<number>, met: Array<number>): Array<number>
Parameters
v (Array<number>) air spped measured by the sensor, [m/s]
met (Array<number>) metabolic rate, [met]
Returns
Array<number>: relative air speed, [m/s]
Related
v_relative for a version that supports scalar arguments
Dynamic clothing

Estimates the dynamic clothing insulation of a moving occupant. The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met)

clo_dynamic(clo: number, met: number, standard: ("ASHRAE" | "ISO")): number
Parameters
clo (number) clothing insulation, [clo]
met (number) metabolic rate, [met]
standard (("ASHRAE" | "ISO") = "ASHRAE") If "ASHRAE", uses Equation provided in Section 5.2.2.2 of ASHRAE 55 2020
Returns
number: dunamic clothing insulation, [clo]
Related
clo_dynamic_array for a version that supports array arguments
Dynamic clothing (array version)

Estimates the dynamic clothing insulation of a moving occupant. The activity as well as the air speed modify the insulation characteristics of the clothing and the adjacent air layer. Consequently, the ISO 7730 states that the clothing insulation shall be corrected [2]. The ASHRAE 55 Standard corrects for the effect of the body movement for met equal or higher than 1.2 met using the equation clo = Icl × (0.6 + 0.4/met)

clo_dynamic_array(clo: Array<number>, met: Array<number>, standard: ("ASHRAE" | "ISO")): Array<number>
Parameters
clo (Array<number>) clothing insulation, [clo]
met (Array<number>) metabolic rate, [met]
standard (("ASHRAE" | "ISO") = "ASHRAE") If "ASHRAE", uses Equation provided in Section 5.2.2.2 of ASHRAE 55 2020
Returns
Array<number>: dunamic clothing insulation, [clo]
Related
clo_dynamic for a version that supports scalar arguments
Units converter

Converts IP values to SI units

units_converter(kwargs: T, from_units: ("IP" | "SI")): T
Parameters
kwargs (T) [t, v] units to convert
from_units (("IP" | "SI") = "IP") specify system to convert from
Returns
T: converted values in SI units
Related
units_converter_array for a version that supports array parameters
Units converter (array version)

Converts IP values to SI units

units_converter_array(kwargs: T, from_units: ("IP" | "SI")): T
Parameters
kwargs (T) [t, v] units to convert
from_units (("IP" | "SI") = "IP") specify system to convert from
Returns
T: converted values in SI units
Related
units_converter for a version that supports scalar parameters
Running mean outdoor temperature

Estimates the running mean temperature also known as prevailing mean outdoor temperature

running_mean_outdoor_temperature(temp_array: Array<number>, alpha: number, units: ("IP" | "SI")): number
Parameters
temp_array (Array<number>) array containing the mean daily temperature in descending order (i.e. from newest/yestedayr to oldest) :math: [t_{day-1}, t_{day-2}, ... , t_{day-n}] , Where :math: t_{day-1} is yesterday's daily mean temperature. The EN 16798-1 2019 [3] states that n should be equal to 7
alpha (number = 0.8) constant between 0 and 1. The EN 16798-1 2019 [3] recommends a value of 0.8, while the ASHRAE 55 2020 recommends to choose values between 0.9 and 0.6, corresponding to a slow- and fast- response running mean, respectively. Adaptive comfort theory suggest that a slow-response running mean (alpha = 0.9) could be more appropriate for climates in which synoptic-scale (day-to-day) temperature dynamics are relatively minor, sich as the humid tropics.
units (("IP" | "SI") = "SI") select the SI (International System of Units) or the IP (Imperial Units) system.
Returns
number: running mean outdoor temperature
Sky-vault view fraction

Calculates the sky-vault view fraction

f_svv(w: number, h: number, d: number): number
Parameters
w (number) width of the window, [m]
h (number) height of the window, [m]
d (number) distance between the occupant and the window, [m]
Returns
number: sky-vault view faction ranges between 0 and 1
Reference values clo and met
Met typical tasks, [met]

Met values of typical tasks.

Type: Object

Properties
Sleeping (number) : 0.7
Reclining (number) : 0.8
Seated_Cquiet (number) : 1.0
Reading_seated (number) : 1.0
Writing (number) : 1.0
Reading_seatedTyping (number) : 1.1
Standing_relaxed (number) : 1.2
Filing_seated (number) : 1.2
Flying_aircraft_routine (number) : 1.2
Filing_standing (number) : 1.4
Driving_a_car (number) : 1.5
Walking_about (number) : 1.7
Cooking (number) : 1.8
Table_sawing (number) : 1.8
Walking_2mph_3_2kmh (number) : 2.0
Lifting_packing (number) : 2.1
Seated_heavy_limb_movement (number) : 2.2
Light_machine_work (number) : 2.2
Flying_aircraft_combat (number) : 2.4
Walking_3mph_4_8kmh (number) : 2.6
House_cleaning (number) : 2.7
Driving_heavy_vehicle (number) : 3.2
Dancing (number) : 3.4
Calisthenics (number) : 3.5
Walking_4mph_6_4kmh (number) : 3.8
Tennis (number) : 3.8
Heavy_machine_work (number) : 4.0
Handling_100lb_45_kg_bags (number) : 4.0
Pick_and_shovel_work (number) : 4.4
Basketball (number) : 6.3
Wrestling (number) : 7.8
Example
import { met_typical_tasks } from "jsthermalcomfort/utilities"; //The path to utilities
console.log(met_typical_tasks['Seated_Cquiet']);
// output 1.0
Typical ensembles insulation, [clo]

Total Clothing insulation of typical ensembles

clo_typical_ensembles(ensembles: ("Walking shorts, short-sleeve shirt" | "Typical summer indoor clothing" | "Knee-length skirt, short-sleeve shirt, sandals, underwear" | "Trousers, long-sleeve shirt" | "Knee-length skirt, long-sleeve shirt, full slip" | "Sweat pants, long-sleeve sweatshirt" | "Jacket, Trousers, long-sleeve shirt" | "Typical winter indoor clothing")): number
Parameters
ensembles (("Walking shorts, short-sleeve shirt" | "Typical summer indoor clothing" | "Knee-length skirt, short-sleeve shirt, sandals, underwear" | "Trousers, long-sleeve shirt" | "Knee-length skirt, long-sleeve shirt, full slip" | "Sweat pants, long-sleeve sweatshirt" | "Jacket, Trousers, long-sleeve shirt" | "Typical winter indoor clothing")) Typical ensembles. One of:
  • "Walking shorts, short-sleeve shirt"
  • "Typical summer indoor clothing"
  • "Knee-length skirt, short-sleeve shirt, sandals, underwear"
  • "Trousers, short-sleeve shirt, socks, shoes, underwear"
  • "Trousers, long-sleeve shirt"
  • "Knee-length skirt, long-sleeve shirt, full slip"
  • "Sweat pants, long-sleeve sweatshirt"
  • "Jacket, Trousers, long-sleeve shirt"
  • "Typical winter indoor clothing"
Returns
number: Clothing insulation of the given ensembles
Example
const result = clo_typical_ensembles("Trousers, long-sleeve shirt"); // returns 0.61
Insulation of individual garments, [clo]

Clo values of individual clothing elements. To calculate the total clothing insulation you need to add these values together.

Type: Object

Properties
Metal_chair (number) : 0.0
Bra (number) : 0.01
Wooden_stool (number) : 0.01
Ankle_socks (number) : 0.02
Shoes_or_sandals (number) : 0.02
Slippers (number) : 0.03
Panty_hose (number) : 0.02
Calf_length_socks (number) : 0.03
Women_underwear (number) : 0.03
Men_underwear (number) : 0.04
Knee_socks_thick (number) : 0.06
Short_shorts (number) : 0.06
Walking_shorts (number) : : 0.08,
T_shirt (number) : 0.08
Standard_office_chair (number) : 0.1
Executive_chair (number) : 0.15
Boots (number) : 0.1
Sleeveless_scoop_neck_blouse (number) : 0.12
Half_slip (number) : 0.14
Long_underwear_bottoms (number) : 0.15
Full_slip (number) : 0.16
Short_sleeve_knit_shirt (number) : 0.17
Sleeveless_vest_thin (number) : 0.1
Sleeveless_vest_thick (number) : 0.17
Sleeveless_short_gown_thin (number) : 0.18
Short_sleeve_dress_shirt (number) : 0.19
Sleeveless_long_gown_thin (number) : 0.2
Long_underwear_top (number) : 0.2
Thick_skirt (number) : 0.23
Long_sleeve_dress_shirt (number) : 0.25
Long_sleeve_flannel_shirt (number) : 0.34
Long_sleeve_sweat_shirt (number) : 0.34
Short_sleeve_hospital_gown (number) : 0.31
Short_sleeve_short_robe_thin (number) : 0.34
Short_sleeve_pajamas (number) : 0.42
Long_sleeve_long_gown (number) : 0.46
Long_sleeve_short_wrap_robe_thick (number) : 0.48
Long_sleeve_pajamas_thick (number) : 0.57
Long_sleeve_long_wrap_robe_thick (number) : 0.69
Thin_trousers (number) : 0.15
Thick_trousers (number) : 0.24
Sweatpants (number) : 0.28
Overalls (number) : 0.3
Coveralls (number) : 0.49
Thin_skirt (number) : 0.14
Long_sleeve_shirt_dress_thin (number) : 0.33
Long_sleeve_shirt_dress_thick (number) : 0.47
Short_sleeve_shirt_dress (number) : 0.29
Sleeveless_scoop_neck_shirt_thin (number) : 0.23
Sleeveless_scoop_neck_shirt_thick (number) : 0.27
Long_sleeve_shirt_thin (number) : 0.25
Long_sleeve_shirt_thick (number) : 0.36
Single_breasted_coat_thin (number) : 0.36
Single_breasted_coat_thick (number) : 0.44
Double_breasted_coat_thin (number) : 0.42
Double_breasted_coat_thick (number) : 0.48
Example
import { clo_individual_garments } from "jsthermalcomfort/utilities"; //The path to utilities
console.log(clo_individual_garments['Metal_chair']);
// output 0.0

Contributing

Contributions are welcome, and they are greatly appreciated! Every little bit helps, and credit will always be given.

Bug reports

When reporting a bug please include:

  • Your operating system name and version.
  • Any details about your local setup that might be helpful in troubleshooting.
  • Detailed steps to reproduce the bug.

Documentation improvements

If you find any issue in our online documentation please open an issue.

jsthermalcomfort could always use more documentation, whether as part of the official jsthermalcomfort docs, in JSDocs, or even on the web in blog posts, articles, and such.

Feature requests and feedback

The best way to send feedback is to file an issue at https://github.com/FedericoTartarini/jsthermalcomfort/issues

If you are proposing a feature:

  • Explain in detail how it would work.
  • Keep the scope as narrow as possible, to make it easier to implement.
  • Remember that this is a volunteer-driven project, and that code contributions are welcome :)

Local development

To set up jsthermalcomfort for local development:

  1. Fork jsthermalcomfort (look for the “Fork” button).

  2. Clone your fork locally. Fetch and pull all the updates from the master branch before you do anything:

    git clone git@github.com:FedericoTartarini/jsthermalcomfort.git

    We use git submodules to pull validation data for the tests, to ensure tests are successful please run:

    git submodule update --init --recursive
  3. Create a branch for local development. The naming rule for new branch are, as follows:

    • If this update is for a new feature Feature/feature_name_here
    • If this update is for bug fix Fix/bug_name_here
    • If this update is for documentation Documentation/doc_name_here

    You can create a branch locally using the following command. Make sure you only push updates to this new branch only:

    git checkout -b name-of-your-bugfix-or-feature

    Now you can make your changes locally.

  4. When you’re done making changes run all tests using Jest:

    • Install dependencies
    npm install
    npm run test
    • Run prettier to format your code:
    npm run format
    • Commit your changes:
    git add .
    git commit -m "Your detailed description of your changes."
    • Update the docs:
    npm run docs
    • Commit your documentation changes:
    git add .
    git commit -m "Your detailed description of your changes."
    • Push your branch to GitHub:
    git push origin name-of-your-bugfix-or-feature
  5. Submit a pull request after you have done all your modifications and tested your work. The pull request should include a detailed description of your work:

    • What this pull request is about
    • Have you tested your work
    • Will this work affect other component in the product

Pull Request Guidelines

If you need some code review or feedback while you’re developing the code just make the pull request.

For merging, you should:

  • Include passing tests (run npm run test).
  • Update documentation when there’s new API, functionality etc.

Documentation

We are using JSDoc and documentation.js to automatically build the documentation.

All the files needed to generate the documentation can be found in the docs_theme repository. After updating the Markdown files, please run the command:

npm run docs

Please ignore the docs folder, this folder contains all the files generated by the above command.

How to add a new model to jsthermalcomfort

  1. Add a file under src/models/ with the name of the function/model and document it.

  2. Add any related functions that are used by your function either in src/utilities/utilities.js or src/psychrometrics/. See existing code as example.

    • In order to add a new function/API to the library you should mark that function as @public, add it to its corresponding category, for example for models you should do @memberof models, and lastly you should give it a proper name for the documentation with @docname, for example: @docname Clothing prediction. It is important to note that you should also add the @public tag to any types the function exposes/uses.
  3. Test your function by writing a test in tests/models/<name_of_model>.test.js.

  4. To run a subset of tests you can do the following:

    npm run test -- '<path_to_test_file>' -t '<test_pattern/name>'

If you are using VSCode you can use the Jest Runner extension to easily run subset of tests.

How to publish a new version of jsthermalcomfort

To create a new release do the following:

  1. Update the package.json version to the new version (we use the semantic release system for versioning)
  2. Run npm run build to update the lib directory (output with types of the library that gets published to NPM)
  3. Commit the updates
  4. In GitHub go to Releases -> click Draft a new release
  5. Click Choose a tag and type the new version, for example v0.1.1
  6. Write the title and description and click Publish release
  7. This will trigger a GitHub action that will publish the new version to NPM

References

[1] ANSI, & ASHRAE. (2020). Thermal Environmental Conditions for Human Occupancy. Atlanta.

[2] ISO. (2005). ISO 7730 - Ergonomics of the thermal environment — Analytical determination and interpretation of thermal comfort using calculation of the PMV and PPD indices and local thermal comfort criteria.

[3] EN, & BSI. (2019). Energy performance of buildings - Ventilation for buildings. BSI Standards Limited 2019.

[4] Schiavon, S., & Lee, K. H. (2013). Dynamic predictive clothing insulation models based on outdoor air and indoor operative temperatures. Building and Environment, 59, 250–260. doi.org/10.1016/j.buildenv.2012.08.024

[5] ISO. (1998). ISO 7726 - Ergonomics of the thermal environment instruments for measuring physical quantities.

[6] Stull, R., 2011. Wet-Bulb Temperature from Relative Humidity and Air Temperature. J. Appl. Meteorol. Climatol. 50, 2267–2269. doi.org/10.1175/JAMC-D-11-0143.1

[7] Zare, S., Hasheminejad, N., Shirvan, H.E., Hemmatjo, R., Sarebanzadeh, K., Ahmadi, S., 2018. Comparing Universal Thermal Climate Index (UTCI) with selected thermal indices/environmental parameters during 12 months of the year. Weather Clim. Extrem. 19, 49–57. https://doi.org/10.1016/j.wace.2018.01.004

[8] ISO, 2004. ISO 7933 - Ergonomics of the thermal environment — Analytical determination and interpretation of heat stress using calculation of the predicted heat strain.

[9] Błażejczyk, K., Jendritzky, G., Bröde, P., Fiala, D., Havenith, G., Epstein, Y., Psikuta, A. and Kampmann, B., 2013. An introduction to the universal thermal climate index (UTCI). Geographia Polonica, 86(1), pp.5-10.

[10] Gagge, A.P., Fobelets, A.P., and Berglund, L.G., 1986. A standard predictive Index of human reponse to thermal enviroment. Am. Soc. Heating, Refrig. Air-Conditioning Eng. 709–731.

[11] ISO, 2017. ISO 7243 - Ergonomics of the thermal environment — Assessment of heat stress using the WBGT (wet bulb globe temperature) index.

[12] Rothfusz LP (1990) The heat index equation. NWS Southern Region Technical Attachment, SR/SSD 90–23, Fort Worth, Texas

[13] Steadman RG (1979) The assessment of sultriness. Part I: A temperature-humidity index based on human physiology and clothing science. J Appl Meteorol 18:861–873

[14] Masterton JM, Richardson FA. Humidex, a method of quantifying human discomfort due to excessive heat and humidity. Downsview, Ontario: CLI 1-79, Environment Canada, Atmospheric Environment Service, 1979

[15] Havenith, G., Fiala, D., 2016. Thermal indices and thermophysiological modeling for heat stress. Compr. Physiol. 6, 255–302. DOI: doi.org/10.1002/cphy.c140051

[16] Blazejczyk, K., Epstein, Y., Jendritzky, G., Staiger, H., Tinz, B., 2012. Comparison of UTCI to selected thermal indices. Int. J. Biometeorol. 56, 515–535. DOI: doi.org/10.1007/s00484-011-0453-2

[17] Steadman RG (1984) A universal scale of apparent temperature. J Appl Meteorol Climatol 23:1674–1687

[18] ASHRAE, 2017. 2017 ASHRAE Handbook Fundamentals. Atlanta.

[20] Höppe P. The physiological equivalent temperature - a universal index for the biometeorological assessment of the thermal environment. Int J Biometeorol. 1999 Oct;43(2):71-5. doi: 10.1007/s004840050118. PMID: 10552310.

[21] Walther, E. and Goestchel, Q., 2018. The PET comfort index: Questioning the model. Building and Environment, 137, pp.1-10. DOI: doi.org/10.1016/j.buildenv.2018.03.054

[22] Teitelbaum, E., Alsaad, H., Aviv, D., Kim, A., Voelker, C., Meggers, F., & Pantelic, J. (2022). Addressing a systematic error correcting for free and mixed convection when measuring mean radiant temperature with globe thermometers. Scientific Reports, 12(1), 1–18. DOI: doi.org/10.1038/s41598-022-10172-5

[23] Liu, S., Schiavon, S., Kabanshi, A., Nazaroff, W.W., 2017. Predicted percentage dissatisfied with ankle draft. Indoor Air 27, 852–862. DOI: doi.org/10.1111/ina.12364

[24] Polydoros, Anastasios & Cartalis, Constantinos. (2015). Use of Earth Observation based indices for the monitoring of built-up area features and dynamics in support of urban energy studies. Energy and Buildings. 98. 92-99. 10.1016/j.enbuild.2014.09.060.

[25] Yao, Runming & Li, Baizhan & Liu, Jing. (2009). A theoretical adaptive model of thermal comfort – Adaptive Predicted Mean Vote (aPMV). Building and Environment. 44. 2089-2096. 10.1016/j.buildenv.2009.02.014.

[26] Fanger, P. & Toftum, Jorn. (2002). Extension of the PMV model to non-air-conditioned buildings in warm climates. Energy and Buildings. 34. 533-536. 10.1016/S0378-7788(02)00003-8.

[27] Schweiker, M., 2022. Combining adaptive and heat balance models for thermal sensation prediction: A new approach towards a theory and data‐driven adaptive thermal heat balance model. Indoor Air 32, 1–19. DOI: doi.org/10.1111/ina.13018