diff --git a/caimira/apps/templates/common_text.md.j2 b/caimira/apps/templates/common_text.md.j2 index b35e0858..79648ed6 100644 --- a/caimira/apps/templates/common_text.md.j2 +++ b/caimira/apps/templates/common_text.md.j2 @@ -34,7 +34,7 @@ We wish to thank CERN’s HSE Unit, Beams Department, Experimental Physics Depar

The risk assessment tool simulates the airborne spread SARS-CoV-2 virus in a finite volume, assuming homogenous mixing for the long-range component and a two-stage jet model for short-range, and estimates the risk of COVID-19 airborne transmission therein. - The results DO NOT include short-range airborne exposure (where the physical distance is a significant factor) nor the other known modes of SARS-CoV-2 transmission. + The results DO NOT include other known modes of SARS-CoV-2 transmission, such as contact or fomite. Hence, the output from this model is only valid when the other recommended public health & safety instructions are observed, such as adequate physical distancing, good hand hygiene and other barrier measures.

diff --git a/caimira/docs/full_diameter_dependence.rst b/caimira/docs/full_diameter_dependence.rst index 09461003..d4a3b628 100644 --- a/caimira/docs/full_diameter_dependence.rst +++ b/caimira/docs/full_diameter_dependence.rst @@ -139,12 +139,28 @@ Very similar to what we did with the **emission rate**, we need to calculate the During a given exposure time, multiple short-range interactions can be defined in the model. In addition, for each individual interaction, the expiration type may be different. -To calculate the short-range component, we first need to calculate what is the **concentration at the jet origin**, that depends on the diameter :math:`D`. -The initial concentration of virions at the mouth/nose, :math:`C_{0, \mathrm{SR}}(D)` is calculated as follows: +To calculate the short-range component, we first need to calculate what is the **dilution factor**, that depends on the distance :math:`x` as a random variable, from a log normal distribution in :meth:`caimira.monte_carlo.data.short_range_distances`. +This factor is calculated in a two-stage expiratory jet model, with its transition point defined as follows: + +:math:`\mathrm{xstar}=𝛽_{\mathrm{x1}} (Q_{0} \cdot u_{0})^\frac{1}{4} \cdot (\mathrm{tstar} + t_{0})^\frac{1}{2} - x_{0}`, + +where the :math:`Q_{0}` is the expired flow rate during the expiration period, in :math:`m^{3} s^{-1}`, :math:`u_{0}` is the expired jet speed (in :math:`m s^{-1}`) given by :math:`u_{0}=\frac{Q_{0}}{A_{m}}`, :math:`A_{m}` being the area of the mouth assuming a perfect circle (average `mouth_diameter` of `0.02m`). +The time of the transition point :math:`\mathrm{tstar}` is defined as `2s` and corresponds to the end of the exhalation period, i.e. when the jet is interrupted. The distance of the virtual origin of the puff-like stage is defined by :math:`x_{0}=\frac{\textrm{mouth_diameter}}{2𝛽_{\mathrm{r1}}}` (in m), and the corresponding time is given by :math:`t_{0} = \frac{\sqrt{\pi}D^3}{8𝛽_{\mathrm{r1}}^2𝛽_{\mathrm{x1}}^2Q_{0}}` (in s). +Having the distance for the transition point, we can calculate the dilution factor at the transition point, defined as follows: + +:math:`\mathrm{Sxstar}=2𝛽_{\mathrm{r1}}\frac{(xstar + x_{0})}{\textrm{mouth_diameter}}`. + +The remaining dilution factors, either in the jet- or puff-like stages are calculated as follows: + +:math:`\mathrm{factors}(x)=\begin{cases}\hfil 2𝛽_{\mathrm{r1}}\frac{(x + x_{0})}{\textrm{mouth_diameter}} & \textrm{if } x < \mathrm{xstar},\\\hfil \mathrm{Sxstar} \cdot \biggl(1 + \frac{𝛽_{\mathrm{r2}}(x - xstar)}{𝛽_{\mathrm{r1}}(xstar + x_{0})}\biggl)^3 & \textrm{if } x > \mathrm{xstar}.\end{cases}` + +The penetration coefficients in the jet-like stage :math:`𝛽_{\mathrm{r1}}`, :math:`𝛽_{\mathrm{r2}}` and :math:`𝛽_{\mathrm{x1}}` are defined by the following empirical values `0.18`, `0.2`, and `2.4` respectively. The dilution factor for each distance :math:`x` is then stored in the :math:`\mathrm{factors}` array that is returned by the method. + +Having the dilution factors, the **initial concentration of virions at the mouth/nose**, :math:`C_{0, \mathrm{SR}}(D)`, is calculated as follows: :math:`C_{0, \mathrm{SR}}(D) = N_p(D) \cdot V_p(D) \cdot \mathrm{vl_{in}} \cdot 10^{-6}`, given by :meth:`caimira.models.Expiration.jet_origin_concentration`. It computes the same quantity as :meth:`caimira.models.Expiration.aerosols`, except for the mask inclusion. As previously mentioned, it is normalized by the **viral load**, which is a diameter-independent property. -Note, the :math:`10^{-6}` factor corresponds to the conversion from :math:`\mathrm{μm}^{3} \cdot \mathrm{cm}^{-3}` to :math:`\mathrm{mL} \cdot m^{3}`. +Note, the :math:`10^{-6}` factor corresponds to the conversion from :math:`\mathrm{μm}^{3} \cdot \mathrm{cm}^{-3}` to :math:`\mathrm{mL} \cdot m^{-3}`. Note that similarly to the `long-range` approach, the MC integral over the diameters is not calculated at this stage. @@ -155,7 +171,7 @@ The former operation is given in method :meth:`caimira.models.ShortRangeModel._l one solution would be to recompute the values a second time using :math:`D_{\mathrm{max}} = 100\mathrm{μm}`; or perform a approximation using linear interpolation, which is possible and more effective in terms of performance. We decided to adopt the interpolation solution. The set of points with a known value are given by the default expiration particle diameters for long-range, i.e. from 0 to 30 :math:`\mathrm{μm}`. -The set of points we want the interpolated values are given by the short-range expiration particle diameters, i.e. from 0 to 100:math:`\mathrm{μm}`. +The set of points we want the interpolated values are given by the short-range expiration particle diameters, i.e. from 0 to 100 :math:`\mathrm{μm}`. To summarize, in the code, :math:`C_{\mathrm{SR}}(t, D)` is computed as follows: diff --git a/caimira/models.py b/caimira/models.py index 4a96be97..1efde56d 100644 --- a/caimira/models.py +++ b/caimira/models.py @@ -1155,39 +1155,39 @@ class ShortRangeModel: The dilution factor for the respective expiratory activity type. ''' # Average mouth diameter - D = 0.02 + mouth_diameter = 0.02 # Convert Breathing rate from m3/h to m3/s BR = np.array(self.activity.exhalation_rate/3600.) # Area of the mouth assuming a perfect circle - Am = np.pi*(D**2)/4 + Am = np.pi*(mouth_diameter**2)/4 # Initial velocity from the division of the Breathing rate with the area u0 = np.array(BR/Am) tstar = 2.0 - Cr1 = 0.18 - Cr2 = 0.2 - Cx1 = 2.4 + 𝛽r1 = 0.18 + 𝛽r2 = 0.2 + 𝛽x1 = 2.4 # The expired flow rate during the expiration period, m^3/s - Q0 = u0 * np.pi/4*D**2 + Q0 = u0 * np.pi/4*mouth_diameter**2 # Parameters in the jet-like stage - x01 = D/2/Cr1 + x0 = mouth_diameter/2/𝛽r1 # Time of virtual origin - t01 = (x01/Cx1)**2 * (Q0*u0)**(-0.5) + t0 = (x0/𝛽x1)**2 * (Q0*u0)**(-0.5) # The transition point, m - xstar = np.array(Cx1*(Q0*u0)**0.25*(tstar + t01)**0.5 - x01) + xstar = np.array(𝛽x1*(Q0*u0)**0.25*(tstar + t0)**0.5 - x0) # Dilution factor at the transition point xstar - Sxstar = np.array(2*Cr1*(xstar+x01)/D) + Sxstar = np.array(2*𝛽r1*(xstar+x0)/mouth_diameter) distances = np.array(self.distance) factors = np.empty(distances.shape, dtype=np.float64) - factors[distances < xstar] = 2*Cr1*(distances[distances < xstar] - + x01)/D + factors[distances < xstar] = 2*𝛽r1*(distances[distances < xstar] + + x0)/mouth_diameter factors[distances >= xstar] = Sxstar[distances >= xstar]*(1 + - Cr2*(distances[distances >= xstar] - - xstar[distances >= xstar])/Cr1/(xstar[distances >= xstar] - + x01))**3 + 𝛽r2*(distances[distances >= xstar] - + xstar[distances >= xstar])/𝛽r1/(xstar[distances >= xstar] + + x0))**3 return factors def _long_range_normed_concentration(self, concentration_model: ConcentrationModel, time: float) -> _VectorisedFloat: