Merge branch 'ventilation-calc' into 'master'
Ventilation calc See merge request cara/cara!32
This commit is contained in:
commit
4551e51b98
2 changed files with 53 additions and 32 deletions
|
|
@ -83,8 +83,32 @@ class FormData:
|
|||
return model_from_form(self, tmp_raw_form_data)
|
||||
|
||||
def ventilation(self) -> models.Ventilation:
|
||||
# TODO
|
||||
pass
|
||||
# Initializes a ventilation instance as a window if 'natural' is selected, or as a HEPA-filter otherwise
|
||||
if self.ventilation_type == 'natural':
|
||||
if self.windows_open == '10 min / 2h':
|
||||
period, duration = 120, 10
|
||||
else:
|
||||
period, duration = 120, 120
|
||||
# I multiply the opening width by the number of windows to simulate the correct window area
|
||||
if self.event_type == 'single_event':
|
||||
month_number = int(self.single_event_date.split('/')[1])
|
||||
month = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'][month_number - 1]
|
||||
else:
|
||||
month = self.recurrent_event_month[:3]
|
||||
|
||||
inside_temp = models.PiecewiseConstant((0, 24), (293,))
|
||||
outside_temp = models.GenevaTemperatures[month]
|
||||
|
||||
ventilation = models.WindowOpening(active=models.PeriodicInterval(period=period, duration=duration),
|
||||
inside_temp=inside_temp, outside_temp=outside_temp, cd_b=0.6,
|
||||
window_height=self.window_height,
|
||||
opening_length=self.opening_distance * self.windows_number)
|
||||
else:
|
||||
q_air_mech = self.air_changes * self.room_volume + self.air_supply
|
||||
ventilation = models.HEPAFilter(active=models.PeriodicInterval(period=120, duration=120),
|
||||
q_air_mech=q_air_mech)
|
||||
|
||||
return ventilation
|
||||
|
||||
def present_interval(self) -> models.Interval:
|
||||
coffee_period = (self.activity_finish - self.activity_start) // self.coffee_breaks
|
||||
|
|
@ -143,36 +167,18 @@ def model_from_form(form: FormData, tmp_raw_form_data) -> models.Model:
|
|||
d['lunch_finish'] = '13:00'
|
||||
|
||||
# Initializes room with volume either given directly or as product of area and height
|
||||
if d['volume_type'] == 'room_volume':
|
||||
volume = int(d['room_volume'])
|
||||
if form.volume_type == 'room_volume':
|
||||
volume = form.room_volume
|
||||
else:
|
||||
volume = int(float(d['floor_area']) * form.ceiling_height)
|
||||
volume = form.floor_area * form.ceiling_height
|
||||
room = models.Room(volume=volume)
|
||||
|
||||
# Initializes a ventilation instance as a window if 'natural' is selected, or as a HEPA-filter otherwise
|
||||
if d['ventilation_type'] == 'natural':
|
||||
if d['windows_open'] == 'always':
|
||||
period, duration = 120, 120
|
||||
else:
|
||||
period, duration = 15, 120
|
||||
# I multiply the opening width by the number of windows to simulate the correct window area
|
||||
ventilation = models.WindowOpening(active=models.PeriodicInterval(period=period, duration=duration),
|
||||
inside_temp=models.PiecewiseConstant((0, 24), (293, )),
|
||||
# TODO: This should be based on the month etc.
|
||||
outside_temp=models.PiecewiseConstant((0, 24), (283, )),
|
||||
cd_b=0.6,
|
||||
window_height=float(d['window_height']),
|
||||
opening_length=float(d['opening_distance']) * int(d['windows_number']))
|
||||
else:
|
||||
q_air_mech = float(d['air_changes']) if d['air_type'] == 'air_changes' else float(d['air_supply'])
|
||||
ventilation = models.HEPAFilter(active=models.PeriodicInterval(period=120, duration=120),
|
||||
q_air_mech=q_air_mech)
|
||||
|
||||
# Initializes the virus as SARS_Cov_2
|
||||
virus = models.Virus.types['SARS_CoV_2']
|
||||
|
||||
# Initializes a mask of type 1 if mask wearing is "continuous", otherwise instantiates the mask attribute as
|
||||
# the "No mask"-mask
|
||||
# TODO: figure out the possible values of mask_wearing in the form
|
||||
mask = models.Mask.types['Type I' if d['mask_wearing'] == "Continuous" else 'No mask']
|
||||
|
||||
# A dictionary containing the mapping of activities listed in the UI to the activity level and expiration level
|
||||
|
|
@ -183,19 +189,19 @@ def model_from_form(form: FormData, tmp_raw_form_data) -> models.Model:
|
|||
'Training': (('Light exercise', 'Talking'), ('Seated', 'Whispering')),
|
||||
'Workshop': (('Light exercise', 'Talking'), ('Light exercise', 'Talking'))}
|
||||
|
||||
(infected_activity, infected_expiration), (exposed_activity, exposed_expiration) = activity_dict[d['activity_type']]
|
||||
(infected_activity, infected_expiration), (exposed_activity, exposed_expiration) = activity_dict[form.activity_type.capitalize()]
|
||||
# Converts these strings to Activity and Expiration instances
|
||||
infected_activity, exposed_activity = models.Activity.types[infected_activity], models.Activity.types[exposed_activity]
|
||||
infected_expiration, exposed_expiration = models.Expiration.types[infected_expiration], models.Expiration.types[exposed_expiration]
|
||||
|
||||
infected_occupants = int(d['infected_people'])
|
||||
infected_occupants = form.infected_people
|
||||
# Defines the number of exposed occupants as the total number of occupants minus the number of infected occupants
|
||||
exposed_occupants = int(d['total_people']) - infected_occupants
|
||||
exposed_occupants = form.total_people - infected_occupants
|
||||
|
||||
# Initializes and returns a model with the attributes defined above
|
||||
return models.Model(
|
||||
room=room,
|
||||
ventilation=ventilation,
|
||||
ventilation=form.ventilation(),
|
||||
infected=models.InfectedPerson(
|
||||
virus=virus,
|
||||
presence=form.present_interval(),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import pytest
|
||||
|
||||
from cara.apps.calculator import model_generator
|
||||
|
||||
from cara import models
|
||||
import numpy as np
|
||||
|
||||
@pytest.fixture
|
||||
def baseline_form_data():
|
||||
|
|
@ -20,9 +21,23 @@ def test_model_from_dict(baseline_form_data):
|
|||
|
||||
|
||||
def test_ventilation(baseline_form):
|
||||
ventilation = baseline_form.ventilation()
|
||||
# TODO:
|
||||
# assert ventilation == cara.models.Ventilation()
|
||||
room = models.Room(75)
|
||||
window = models.WindowOpening(
|
||||
active=models.PeriodicInterval(period=120, duration=10),
|
||||
inside_temp=models.PiecewiseConstant((0, 24), (293,)),
|
||||
outside_temp=models.GenevaTemperatures['Dec'],
|
||||
cd_b=0.6, window_height=1.6, opening_length=0.6,
|
||||
)
|
||||
baseline_form.ventilation_type = 'natural'
|
||||
baseline_form.windows_open = '10 min / 2h'
|
||||
baseline_form.event_type = 'recurrent_event'
|
||||
baseline_form.recurrent_event_month = 'December'
|
||||
baseline_form.window_height = 1.6
|
||||
baseline_form.opening_distance = 0.6
|
||||
|
||||
ts = np.linspace(8, 16, 100)
|
||||
np.testing.assert_allclose([window.air_exchange(room, t) for t in ts],
|
||||
[baseline_form.ventilation().air_exchange(room, t) for t in ts])
|
||||
|
||||
|
||||
def test_present_intervals(baseline_form):
|
||||
|
|
|
|||
Loading…
Reference in a new issue