CAiMIRA models
This module implements the core CAiMIRA models.
The CAiMIRA model is a flexible, object-oriented numerical model. It is designed
to allow the user to swap-out and extend its various components. One of the
major abstractions of the model is the distinction between virus concentration
(ConcentrationModel
) and virus exposure (ExposureModel
).
The concentration component is a recursive (on model time) model and therefore in order to optimise its execution certain layers of caching are implemented. This caching mandates that the models in this module, once instantiated, are immutable and deterministic (i.e. running the same model twice will result in the same answer).
In order to apply stochastic / non-deterministic analyses therefore you must
introduce the randomness before constructing the models themselves; the
caimira.monte_carlo
module is a good example of doing this - that module uses
the models defined here to allow you to construct a ConcentrationModel containing
parameters which are expressed as probability distributions. Under the hood the
caimira.monte_carlo.ConcentrationModel
implementation simply samples all of those
probability distributions to produce many instances of the deterministic model.
The models in this module have been designed for flexibility above performance, particularly in the single-model case. By using the natural expressiveness of Python we benefit from a powerful, readable and extendable implementation. A useful feature of the implementation is that we are able to benefit from numpy vectorisation in the case of wanting to run multiple-parameterisations of the model at the same time. In order to benefit from this feature you must construct the models with an array of parameter values. The values must be either scalar, length 1 arrays, or length N arrays, where N is the number of parameterisations to run; N must be the same for all parameters of a single model.
Activity Class
class Activity(inhalation_rate: float | numpy.ndarray, exhalation_rate: float | numpy.ndarray)
Bases: object
exhalation_rate : float | ndarray
Exhalation rate in m^3/h
inhalation_rate : float | ndarray
Inhalation rate in m^3/h
types : ClassVar[Dict[str, Activity]] = {'Heavy exercise': Activity(inhalation_rate=3.3, exhalation_rate=3.3), 'Light activity': Activity(inhalation_rate=1.25, exhalation_rate=1.25), 'Moderate activity': Activity(inhalation_rate=1.78, exhalation_rate=1.78), 'Seated': Activity(inhalation_rate=0.51, exhalation_rate=0.51), 'Standing': Activity(inhalation_rate=0.57, exhalation_rate=0.57)}
Pre-populated examples of Activities.
AirChange Class
class AirChange(active: models.models.Interval, air_exch: float | numpy.ndarray)
Bases: Ventilation
active : Interval
The interval in which the ventilation is operating.
air_exch : float | ndarray
air_exchange(room: Room, time: float) → float | ndarray
Returns the rate at which air is being exchanged in the given room at a given time (in hours).
Note that whilst the time is known inside this function, it may not be used to vary the result unless the specific time used is declared as part of a state change in the interval (e.g. when air_exchange == 0).
CO2ConcentrationModel Class
class CO2ConcentrationModel(data_registry: DataRegistry, room: Room, ventilation: _VentilationBase, CO2_emitters: SimplePopulation)
Bases: _ConcentrationModelBase
Class used for the computation of the CO2 concentration.
property CO2_atmosphere_concentration : float
CO2_emitters : SimplePopulation
Population in the room emitting CO2
property CO2_fraction_exhaled : float
min_background_concentration() → float | ndarray
Background CO2 concentration in the atmosphere (in ppm)
normalization_factor() → float | ndarray
Normalization factor (in the same unit as the concentration). This factor is applied to the normalized concentration only at the very end.
property population : SimplePopulation
Population in the room (the emitters of what we compute the concentration of)
removal_rate(time: float) → float | ndarray
Remove rate of the species considered, in h^-1
CO2DataModel Class
class CO2DataModel(data_registry: DataRegistry, room: Room, occupancy: IntPiecewiseConstant, ventilation_transition_times: Tuple[float, ...], times: Sequence[float], CO2_concentrations: Sequence[float])
Bases: object
The CO2DataModel class models CO2 data based on room volume and capacity, ventilation transition times, and people presence. It uses optimization techniques to fit the model’s parameters and estimate the exhalation rate and ventilation values that best match the measured CO2 concentrations.
CO2_concentration_model(exhalation_rate: float, ventilation_values: Tuple[float, ...]) → CO2ConcentrationModel
CO2_concentrations : Sequence[float]
CO2_concentrations_from_params(CO2_concentration_model: CO2ConcentrationModel) → List[float | ndarray]
CO2_fit_params() → Dict
data_registry : DataRegistry
occupancy : IntPiecewiseConstant
room : Room
times : Sequence[float]
ventilation_transition_times : Tuple[float, ...]
Cases Class
class Cases(geographic_population: int = 0, geographic_cases: int = 0, ascertainment_bias: int = 0)
Bases: object
The geographical data to calculate the probability of having at least 1 new infection in a probabilistic exposure.
ascertainment_bias : int = 0
Number of new cases confidence level
geographic_cases : int = 0
Geographic location new cases
geographic_population : int = 0
Geographic location population
probability_meet_infected_person(virus: Virus, n_infected: int, event_population: int) → float | ndarray
Probability to meet n_infected persons in an event. From https://doi.org/10.1038/s41562-020-01000-9.
probability_random_individual(virus: Virus) → float | ndarray
Probability that a randomly selected individual in a focal population is infected.
ConcentrationModel Class
class ConcentrationModel(data_registry: DataRegistry, room: Room, ventilation: _VentilationBase, infected: InfectedPopulation, evaporation_factor: float)
Bases: _ConcentrationModelBase
Class used for the computation of the long-range virus concentration.
evaporation_factor : float
infected : InfectedPopulation
Infected population in the room, emitting virions
infectious_virus_removal_rate(time: float) → float | ndarray
normalization_factor() → float | ndarray
Normalization factor (in the same unit as the concentration). This factor is applied to the normalized concentration only at the very end.
property population : InfectedPopulation
Population in the room (the emitters of what we compute the concentration of)
removal_rate(time: float) → float | ndarray
Remove rate of the species considered, in h^-1
property virus : Virus
CustomVentilation Class
class CustomVentilation(ventilation_value: models.models.PiecewiseConstant)
Bases: _VentilationBase
air_exchange(room: Room, time: float) → float | ndarray
Returns the rate at which air is being exchanged in the given room at a given time (in hours).
Note that whilst the time is known inside this function, it may not be used to vary the result unless the specific time used is declared as part of a state change in the interval (e.g. when air_exchange == 0).
transition_times(room: Room) → Set[float]
ventilation_value : PiecewiseConstant
EmittingPopulation Class
class EmittingPopulation(number: int | models.models.IntPiecewiseConstant, presence: models.models.Interval | None, activity: models.models.Activity, mask: models.models.Mask, host_immunity: float, data_registry: caimira.calculator.store.data_registry.DataRegistry, virus: models.models.Virus, known_individual_emission_rate: float)
Bases: _PopulationWithVirus
aerosols()
Total volume of aerosols expired per volume of exhaled air (mL/cm^3). Here arbitrarily set to 1 as the full emission rate is known.
emission_rate_per_aerosol_per_person_when_present() → float | ndarray
The emission rate of infectious respiratory particles (IRP) in the expired air per mL of respiratory fluid, if the infected population is present, in (virions.cm^3)/(mL.h). This method returns only the diameter-independent variables within the emission rate. It should not be a function of time.
known_individual_emission_rate : float
The emission rate of a single individual, in virions / h.
Expiration Class
class Expiration(diameter: float | ndarray, cn: float = 1.0)
Bases: _ExpirationBase
Model for the expiration. For a given diameter of aerosol, provides the aerosol volume, weighted by the mask outward efficiency when applicable.
aerosols(mask: Mask)
Total volume of aerosols expired per volume of exhaled air considering the outward mask efficiency. Result is in mL.cm^-3.
cn : float = 1.0
diameter : float | ndarray
diameter of the aerosol in microns
property particle : Particle
The Particle object representing the aerosol
ExposureModel Class
class ExposureModel(data_registry: DataRegistry, concentration_model: ConcentrationModel, short_range: Tuple[ShortRangeModel, ...], exposed: Population, geographical_data: Cases, exposed_to_short_range: int = 0)
Bases: object
Represents the exposure to a concentration of infectious respiratory particles (IRP) in the air.
concentration(time: float) → float | ndarray
Virus exposure concentration, as a function of time.
It considers the long-range concentration with the contribution of the short-range concentration.
concentration_model : ConcentrationModel
The virus concentration model which this exposure model should consider.
data_registry : DataRegistry
deposited_exposure() → float | ndarray
The number of virus per m^3 deposited on the respiratory tract.
deposited_exposure_between_bounds(time1: float, time2: float) → float | ndarray
The number of virus per m^3 deposited on the respiratory tract between any two times.
Considers a contribution between the short-range and long-range exposures: It calculates the deposited exposure given a short-range interaction (if any). Then, the deposited exposure given the long-range interactions is added to the initial deposited exposure.
expected_new_cases() → float | ndarray
The expected_new_cases may provide one or two different outputs: : 1. Long-range exposure: take the infection_probability and multiply by the occupants exposed to long-range. 2. Short- and long-range exposure: take the infection_probability of long-range multiplied by the occupants exposed to long-range only, plus the infection_probability of short- and long-range multiplied by the occupants exposed to short-range only.
Currently disabled when dynamic occupancy is defined for the exposed population.
exposed : Population
The population of non-infected people to be used in the model.
exposed_to_short_range : int = 0
Total people with short-range interactions
geographical_data : Cases
Geographical data
infection_probability() → float | ndarray
long_range_deposited_exposure_between_bounds(time1: float, time2: float) → float | ndarray
long_range_fraction_deposited() → float | ndarray
The fraction of particles actually deposited in the respiratory tract (over the total number of particles). It depends on the particle diameter.
population_state_change_times() → List[float]
All time dependent population entities on this model must provide information about the times at which their state changes.
property repeats : int
reproduction_number() → float | ndarray
The reproduction number can be thought of as the expected number of cases directly generated by one infected case in a population.
Currently disabled when dynamic occupancy is defined for both the infected and exposed population.
short_range : Tuple[ShortRangeModel, ...]
The list of short-range models which this exposure model should consider.
total_probability_rule() → float | ndarray
HEPAFilter Class
class HEPAFilter(active: models.models.Interval, q_air_mech: float | numpy.ndarray)
Bases: Ventilation
active : Interval
The interval in which the HEPA filter is operating.
air_exchange(room: Room, time: float) → float | ndarray
Returns the rate at which air is being exchanged in the given room at a given time (in hours).
Note that whilst the time is known inside this function, it may not be used to vary the result unless the specific time used is declared as part of a state change in the interval (e.g. when air_exchange == 0).
q_air_mech : float | ndarray
HVACMechanical Class
class HVACMechanical(active: models.models.Interval, q_air_mech: float | numpy.ndarray)
Bases: Ventilation
active : Interval
The interval in which the mechanical ventilation (HVAC) is operating.
air_exchange(room: Room, time: float) → float | ndarray
Returns the rate at which air is being exchanged in the given room at a given time (in hours).
Note that whilst the time is known inside this function, it may not be used to vary the result unless the specific time used is declared as part of a state change in the interval (e.g. when air_exchange == 0).
q_air_mech : float | ndarray
HingedWindow Class
class HingedWindow(active: Interval, outside_temp: PiecewiseConstant, window_height: float | ndarray, opening_length: float | ndarray, number_of_windows: int = 1, min_deltaT: float = 0.1, window_width: float | ndarray = 0.0)
Bases: WindowOpening
Top-hung or bottom-hung hinged window (with the hinge parallel to horizontal plane).
property discharge_coefficient : float | ndarray
Simple model to compute discharge coefficient for top or bottom hung hinged windows, in the absence of empirical test results from manufacturers. From an excel spreadsheet calculator (Richard Daniels, Crawford Wright, Benjamin Jones - 2018) from the UK government - see Section 8.3 of BB101 and Section 11.3 of ESFA Output Specification Annex 2F on Ventilation opening areas.
window_width : float | ndarray = 0.0
Window width (m).
InfectedPopulation Class
class InfectedPopulation(number: int | models.models.IntPiecewiseConstant, presence: models.models.Interval | None, activity: models.models.Activity, mask: models.models.Mask, host_immunity: float, data_registry: caimira.calculator.store.data_registry.DataRegistry, virus: models.models.Virus, expiration: models.models._ExpirationBase)
Bases: _PopulationWithVirus
aerosols()
Total volume of aerosols expired per volume of exhaled air (mL/cm^3).
emission_rate_per_aerosol_per_person_when_present() → float | ndarray
The emission rate of infectious respiratory particles (IRP) in the expired air per mL of respiratory fluid, if the infected population is present, in (virions.cm^3)/(mL.h). This method returns only the diameter-independent variables within the emission rate. It should not be a function of time.
expiration : _ExpirationBase
The type of expiration that is being emitted whilst doing the activity.
fraction_of_infectious_virus() → float | ndarray
The fraction of infectious virus.
property particle : Particle
The Particle object representing the aerosol - here the default one
IntPiecewiseConstant Class
class IntPiecewiseConstant(transition_times: Tuple[float, ...], values: Tuple[int, ...])
Bases: PiecewiseConstant
value(time) → float | ndarray
values : Tuple[int, ...]
values of the function between transitions
Interval Class
class Interval
Bases: object
Represents a collection of times in which a “thing” happens.
The “thing” may be when an action is taken, such as opening a window, or entering a room.
Note that all intervals are open at the start, and closed at the end. So a simple start, stop interval follows:
start < t <= end
boundaries() → Tuple[Tuple[Time_t, Time_t], ...] | Tuple
transition_times() → Set[float]
triggered(time: float) → bool
Whether the given time falls inside this interval.
Mask Class
class Mask(η_inhale: float | numpy.ndarray, η_exhale: NoneType | float | numpy.ndarray = None, factor_exhale: float = 1.0)
Bases: object
exhale_efficiency(diameter: float | ndarray) → float | ndarray
Overall exhale efficiency, including the effect of the leaks. See CERN-OPEN-2021-004 (doi: 10.17181/CERN.1GDQ.5Y75), and Ref. therein (Asadi 2020). Obtained from measurements of filtration efficiency and of the leakage through the sides. Diameter is in microns.
factor_exhale : float = 1.0
Global factor applied to filtration efficiency of masks when exhaling.
inhale_efficiency() → float | ndarray
Overall inhale efficiency, including the effect of the leaks.
types : ClassVar[Dict[str, Mask]] = {'Cloth': Mask(η_inhale=0.225, η_exhale=0.35, factor_exhale=1.0), 'FFP2': Mask(η_inhale=0.865, η_exhale=None, factor_exhale=1.0), 'No mask': Mask(η_inhale=0, η_exhale=0, factor_exhale=1.0), 'Type I': Mask(η_inhale=0.5, η_exhale=None, factor_exhale=1.0)}
Pre-populated examples of Masks.
η_exhale : None | float | ndarray = None
Filtration efficiency of masks when exhaling.
η_inhale : float | ndarray
Filtration efficiency of masks when inhaling.
MultipleExpiration Class
class MultipleExpiration(expirations: Tuple[_ExpirationBase, ...], weights: Tuple[float, ...])
Bases: _ExpirationBase
Represents an expiration of aerosols. Group together different modes of expiration, that represent each the main expiration mode for a certain fraction of time (given by the weights). This class can only be used with single diameters defined in each expiration (it cannot be used with diameter distributions).
aerosols(mask: Mask)
Total volume of aerosols expired per volume of exhaled air considering the outward mask efficiency (mL/cm^3).
expirations : Tuple[_ExpirationBase, ...]
weights : Tuple[float, ...]
MultipleVentilation Class
class MultipleVentilation(ventilations: Tuple[_VentilationBase, ...])
Bases: _VentilationBase
Represents a mechanism by which air can be exchanged (replaced/filtered) in a time dependent manner.
Group together different sources of ventilations.
air_exchange(room: Room, time: float) → float | ndarray
Returns the rate at which air is being exchanged in the given room at a given time (in hours).
transition_times(room: Room) → Set[float]
ventilations : Tuple[_VentilationBase, ...]
Particle Class
class Particle(diameter: None | float | ndarray = None)
Bases: object
Represents an aerosol particle.
diameter : None | float | ndarray = None
diameter of the aerosol in microns
fraction_deposited(evaporation_factor: float = 0.3) → float | ndarray
The fraction of particles actually deposited in the respiratory tract (over the total number of particles). It depends on the particle diameter. From W. C. Hinds, New York, Wiley, 1999 (pp. 233 – 259). evaporation_factor represents the factor applied to the diameter, due to instantaneous evaporation of the particle in the air.
settling_velocity(evaporation_factor: float = 0.3) → float | ndarray
Settling velocity (i.e. speed of deposition on the floor due to gravity), for aerosols, in m/s. Diameter-dependent expression from https://doi.org/10.1101/2021.10.14.21264988 When an aerosol-diameter is not given, returns the default value of 1.88e-4 m/s (corresponds to diameter of 2.5 microns, i.e. geometric average of the breathing expiration distribution, taking evaporation into account, see https://doi.org/10.1101/2021.10.14.21264988) evaporation_factor represents the factor applied to the diameter, due to instantaneous evaporation of the particle in the air.
PeriodicInterval Class
class PeriodicInterval(period: float, duration: float, start: float = 0.0)
Bases: Interval
boundaries() → Tuple[Tuple[Time_t, Time_t], ...] | Tuple
duration : float
How long does the interval occur for (minutes).
A value greater than period
signifies the event is permanently
occurring, a value of 0 signifies that the event never happens.
period : float
How often does the interval occur (minutes).
start : float = 0.0
Time at which the first person (infected or exposed) arrives at the enclosed space.
PiecewiseConstant Class
class PiecewiseConstant(transition_times: Tuple[float, ...], values: Tuple[float | numpy.ndarray, ...])
Bases: object
interval() → Interval
refine(refine_factor=10) → PiecewiseConstant
transition_times : Tuple[float, ...]
transition times at which the function changes value (hours).
value(time) → float | ndarray
values : Tuple[float | ndarray, ...]
values of the function between transitions
Population Class
class Population(number: int | IntPiecewiseConstant, presence: Interval | None, activity: Activity, mask: Mask, host_immunity: float)
Bases: SimplePopulation
Represents a group of people all with exactly the same behaviour and situation, considering the usage of mask and a certain host immunity.
host_immunity : float
mask : Mask
The kind of mask being worn by the people.
Room Class
class Room(volume: float | numpy.ndarray, inside_temp: models.models.PiecewiseConstant = PiecewiseConstant(transition_times=(0, 24), values=(293,)), humidity: float | numpy.ndarray = 0.5, capacity: int | None = None)
Bases: object
capacity : int | None = None
The maximum occupation of the room - design limit
humidity : float | ndarray = 0.5
The humidity in the room (from 0 to 1 - e.g. 0.5 is 50% humidity)
inside_temp : PiecewiseConstant = PiecewiseConstant(transition_times=(0, 24), values=(293,))
The temperature inside the room (Kelvin).
volume : float | ndarray
The total volume of the room
SARSCoV2 Class
class SARSCoV2(viral_load_in_sputum: float | numpy.ndarray, infectious_dose: float | numpy.ndarray, viable_to_RNA_ratio: float | numpy.ndarray, transmissibility_factor: float, infectiousness_days: int = 14)
Bases: Virus
halflife(humidity: float | ndarray, inside_temp: float | ndarray) → float | ndarray
Half-life changes with humidity level. Here is implemented a simple piecewise constant model (for more details see A. Henriques et al, CERN-OPEN-2021-004, DOI: 10.17181/CERN.1GDQ.5Y75)
infectiousness_days : int = 14
Number of days the infector is contagious
ShortRangeModel Class
class ShortRangeModel(data_registry: DataRegistry, expiration: _ExpirationBase, activity: Activity, presence: SpecificInterval, distance: float | ndarray)
Bases: object
Based on the two-stage (jet/puff) expiratory jet model by Jia et al (2022) - https://doi.org/10.1016/j.buildenv.2022.109166
activity : Activity
Activity type
data_registry : DataRegistry
dilution_factor() → float | ndarray
The dilution factor for the respective expiratory activity type.
distance : float | ndarray
Interpersonal distances
expiration : _ExpirationBase
Expiration type
extract_between_bounds(time1: float, time2: float) → None | Tuple[float, float]
Extract the bounds of the interval resulting from the intersection of [time1, time2] and the presence interval. If [time1, time2] has nothing common to the presence interval, we return (0, 0). Raise an error if time1 and time2 are not in ascending order.
jet_origin_concentration(infected: InfectedPopulation) → float | ndarray
The initial jet concentration at the source origin (mouth/nose). Returns the full result with the diameter dependent and independent variables, in virions/m^3.
normalization_factor(infected: InfectedPopulation) → float | ndarray
The normalization factor applied to the short-range results. It refers to the emission rate per aerosol without accounting for the exhalation rate (viral load and f_inf). Result in (virions.cm^3)/(mL.m^3).
presence : SpecificInterval
Short-range expiration and respective presence
short_range_concentration(concentration_model: ConcentrationModel, time: float) → float | ndarray
Virus short-range exposure concentration, as a function of time. Factor of normalization applied back here. Results in virions/m^3.
SimplePopulation Class
class SimplePopulation(number: int | IntPiecewiseConstant, presence: Interval | None, activity: Activity)
Bases: object
Represents a group of people all with exactly the same behaviour and situation.
activity : Activity
The physical activity being carried out by the people.
number : int | IntPiecewiseConstant
How many in the population.
people_present(time: float)
person_present(time: float)
presence : Interval | None
The times in which the people are in the room.
presence_interval()
SlidingWindow Class
class SlidingWindow(active: ~models.models.Interval, outside_temp: ~models.models.PiecewiseConstant, window_height: float | ~numpy.ndarray, opening_length: float | ~numpy.ndarray, number_of_windows: int = 1, min_deltaT: float = 0.1, data_registry: ~caimira.calculator.store.data_registry.DataRegistry = )
Bases: WindowOpening
Sliding window, or side-hung window (with the hinge perpendicular to the horizontal plane).
data_registry : DataRegistry =
property discharge_coefficient : float | ndarray
Average measured value of discharge coefficient for sliding or side-hung windows.
SpecificInterval Class
class SpecificInterval(present_times: Tuple[Tuple[Time_t, Time_t], ...] | Tuple)
Bases: Interval
boundaries() → Tuple[Tuple[Time_t, Time_t], ...] | Tuple
present_times : Tuple[Tuple[Time_t, Time_t], ...] | Tuple
A sequence of times (start, stop), in hours, that the infected person is present. The flattened list of times must be strictly monotonically increasing.
Ventilation Class
class Ventilation(active: models.models.Interval)
Bases: _VentilationBase
active : Interval
The interval in which the ventilation is active.
transition_times(room: Room) → Set[float]
Virus Class
class Virus(viral_load_in_sputum: float | numpy.ndarray, infectious_dose: float | numpy.ndarray, viable_to_RNA_ratio: float | numpy.ndarray, transmissibility_factor: float, infectiousness_days: int)
Bases: object
decay_constant(humidity: float | ndarray, inside_temp: float | ndarray) → float | ndarray
halflife(humidity: float | ndarray, inside_temp: float | ndarray) → float | ndarray
infectious_dose : float | ndarray
Dose to initiate infection, in RNA copies
infectiousness_days : int
Number of days the infector is contagious
transmissibility_factor : float
Reported increase of transmissibility of a VOC
types : ClassVar[Dict[str, Virus]] = {'SARS_CoV_2': SARSCoV2(viral_load_in_sputum=1000000000.0, infectious_dose=50.0, viable_to_RNA_ratio=0.5, transmissibility_factor=1.0, infectiousness_days=14), 'SARS_CoV_2_ALPHA': SARSCoV2(viral_load_in_sputum=1000000000.0, infectious_dose=50.0, viable_to_RNA_ratio=0.5, transmissibility_factor=0.78, infectiousness_days=14), 'SARS_CoV_2_BETA': SARSCoV2(viral_load_in_sputum=1000000000.0, infectious_dose=50.0, viable_to_RNA_ratio=0.5, transmissibility_factor=0.8, infectiousness_days=14), 'SARS_CoV_2_DELTA': SARSCoV2(viral_load_in_sputum=1000000000.0, infectious_dose=50.0, viable_to_RNA_ratio=0.5, transmissibility_factor=0.51, infectiousness_days=14), 'SARS_CoV_2_GAMMA': SARSCoV2(viral_load_in_sputum=1000000000.0, infectious_dose=50.0, viable_to_RNA_ratio=0.5, transmissibility_factor=0.72, infectiousness_days=14), 'SARS_CoV_2_OMICRON': SARSCoV2(viral_load_in_sputum=1000000000.0, infectious_dose=50.0, viable_to_RNA_ratio=0.5, transmissibility_factor=0.2, infectiousness_days=14)}
Pre-populated examples of Viruses.
viable_to_RNA_ratio : float | ndarray
viable-to-RNA virus ratio as a function of the viral load
viral_load_in_sputum : float | ndarray
RNA copies / mL
WindowOpening Class
class WindowOpening(active: models.models.Interval, outside_temp: models.models.PiecewiseConstant, window_height: float | numpy.ndarray, opening_length: float | numpy.ndarray, number_of_windows: int = 1, min_deltaT: float = 0.1)
Bases: Ventilation
active : Interval
The interval in which the window is open.
air_exchange(room: Room, time: float) → float | ndarray
Returns the rate at which air is being exchanged in the given room at a given time (in hours).
Note that whilst the time is known inside this function, it may not be used to vary the result unless the specific time used is declared as part of a state change in the interval (e.g. when air_exchange == 0).
property discharge_coefficient : float | ndarray
Discharge coefficient (or cd_b): what portion effective area is used to exchange air (0 <= discharge_coefficient <= 1). To be implemented in subclasses.
min_deltaT : float = 0.1
Minimum difference between inside and outside temperature (K).
number_of_windows : int = 1
The number of windows of the given dimensions.
opening_length : float | ndarray
The length of the opening-gap when the window is open (m).
outside_temp : PiecewiseConstant
The temperature outside of the window (Kelvin).
transition_times(room: Room) → Set[float]
window_height : float | ndarray
The height of the window (m).