Introducing diameter as a vectorised parameter of Expiration. Providing equivalent diameters for each expiration type (gives the same emission rate as before)
This commit is contained in:
parent
686c709cc9
commit
83e2185763
2 changed files with 29 additions and 16 deletions
|
|
@ -560,8 +560,11 @@ class Expiration(_ExpirationBase):
|
|||
# speaking, singing, or shouting).
|
||||
BLO_factors: typing.Tuple[float, float, float]
|
||||
|
||||
#: diameter of the aerosol in microns
|
||||
diameter: _VectorisedFloat
|
||||
|
||||
@cached()
|
||||
def aerosols(self, mask: Mask):
|
||||
def aerosols_(self, mask: Mask):
|
||||
""" Result is in mL.cm^-3 """
|
||||
def volume(d):
|
||||
return (np.pi * d**3) / 6.
|
||||
|
|
@ -590,6 +593,15 @@ class Expiration(_ExpirationBase):
|
|||
# final result converted from microns^3/cm3 to mL/cm^3
|
||||
return scipy.integrate.quad(integrand, 0.1, 30.)[0]*1e-12
|
||||
|
||||
@cached()
|
||||
def aerosols(self, mask: Mask):
|
||||
""" Result is in mL.cm^-3 """
|
||||
def volume(d):
|
||||
return (np.pi * d**3) / 6.
|
||||
|
||||
return (volume(self.diameter) *
|
||||
(1 - mask.exhale_efficiency(self.diameter))) * 1e-12
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class MultipleExpiration(_ExpirationBase):
|
||||
|
|
@ -616,10 +628,11 @@ class MultipleExpiration(_ExpirationBase):
|
|||
|
||||
|
||||
_ExpirationBase.types = {
|
||||
'Breathing': Expiration((1., 0., 0.)),
|
||||
'Talking': Expiration((1., 1., 1.)),
|
||||
'Shouting': Expiration((1., 5., 5.)),
|
||||
'Singing': Expiration((1., 5., 5.)),
|
||||
'Breathing': Expiration((1., 0., 0.), 1.3844),
|
||||
'Talking': Expiration((1., 1., 1.), 5.8925),
|
||||
'Shouting': Expiration((1., 5., 5.), 10.0411),
|
||||
'Singing': Expiration((1., 5., 5.), 10.0411),
|
||||
'Superspreading event': Expiration((np.inf, 0., 0.), 10.0411),
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -748,7 +761,7 @@ class ConcentrationModel:
|
|||
|
||||
def infectious_virus_removal_rate(self, time: float) -> _VectorisedFloat:
|
||||
# Particle deposition on the floor (value from CERN-OPEN-2021-04)
|
||||
vg = 1.88e-4
|
||||
vg = 1.88e-4 # value corresponding to a diameter of 2.5 microns
|
||||
# Height of the emission source to the floor - i.e. mouth/nose (m)
|
||||
h = 1.5
|
||||
# Deposition rate (h^-1)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ from cara import models
|
|||
|
||||
def test_multiple_wrong_weight_size():
|
||||
weights = (1., 2., 3.)
|
||||
e_base = models.Expiration((1., 0., 0.))
|
||||
e_base = models.Expiration((1., 0., 0.), 2.5)
|
||||
with pytest.raises(
|
||||
ValueError,
|
||||
match=re.escape("expirations and weigths should contain the"
|
||||
|
|
@ -20,9 +20,9 @@ def test_multiple_wrong_weight_size():
|
|||
|
||||
def test_multiple():
|
||||
weights = (1., 1.)
|
||||
e1 = models.Expiration((1., 0., 0.))
|
||||
e2 = models.Expiration((4., 5., 5.))
|
||||
e_expected = models.Expiration((2.5, 2.5, 2.5))
|
||||
e1 = models.Expiration((1., 0., 0.), 2.5)
|
||||
e2 = models.Expiration((4., 5., 5.), 2.5)
|
||||
e_expected = models.Expiration((2.5, 2.5, 2.5), 2.5)
|
||||
e = models.MultipleExpiration([e1, e2], weights)
|
||||
mask = models.Mask.types['Type I']
|
||||
npt.assert_almost_equal(e_expected.aerosols(mask), e.aerosols(mask))
|
||||
|
|
@ -30,14 +30,14 @@ def test_multiple():
|
|||
|
||||
# expected values obtained from another code
|
||||
@pytest.mark.parametrize(
|
||||
"BLO_weights, expected_aerosols",
|
||||
"expiration_type, expected_aerosols",
|
||||
[
|
||||
[(1.,0.,0.), 1.38924e-12],
|
||||
[(1.,1.,1.), 1.07129e-10],
|
||||
[(1.,5.,5.), 5.30088e-10],
|
||||
['Breathing', 1.38924e-12],
|
||||
['Talking', 1.07129e-10],
|
||||
['Shouting', 5.30088e-10],
|
||||
],
|
||||
)
|
||||
def test_expiration_aerosols(BLO_weights, expected_aerosols):
|
||||
def test_expiration_aerosols(expiration_type, expected_aerosols):
|
||||
mask = models.Mask.types['No mask']
|
||||
e = models.Expiration(BLO_weights)
|
||||
e = models._ExpirationBase.types[expiration_type]
|
||||
npt.assert_allclose(e.aerosols(mask), expected_aerosols, rtol=1e-4)
|
||||
|
|
|
|||
Loading…
Reference in a new issue