diff --git a/caimira/models.py b/caimira/models.py index e8de7667..db62293f 100644 --- a/caimira/models.py +++ b/caimira/models.py @@ -1132,23 +1132,21 @@ class _ConcentrationModelBase: return self.min_background_concentration()/self.normalization_factor() next_state_change_time = self._next_state_change(time) - RR = self.removal_rate(next_state_change_time) - # If RR is 0, conc_limit does not play a role but its computation - # would raise an error -> we set it to zero. - try: - conc_limit = self._normed_concentration_limit(next_state_change_time) - except ZeroDivisionError: - conc_limit = 0. t_last_state_change = self.last_state_change(time) conc_at_last_state_change = self._normed_concentration_cached(t_last_state_change) - delta_time = time - t_last_state_change + fac = np.exp(-RR * delta_time) - return conc_limit * (1 - fac) + conc_at_last_state_change * fac + if isinstance(RR, float) and RR == 0: + curr_conc_state = delta_time * self.population.people_present(time) / self.room.volume + else: + curr_conc_state = self._normed_concentration_limit(next_state_change_time) * (1 - fac) + return curr_conc_state + conc_at_last_state_change * fac + def concentration(self, time: float) -> _VectorisedFloat: """ Total concentration as a function of time. The normalization @@ -1260,9 +1258,7 @@ class CO2ConcentrationModel(_ConcentrationModelBase): return self.CO2_emitters def removal_rate(self, time: float) -> _VectorisedFloat: - # Setting minimum air exchange rate to 1e-6 to avoid divisions by - # zero when computing the CO2 concentration. - return np.maximum(1e-6,self.ventilation.air_exchange(self.room, time)) + return self.ventilation.air_exchange(self.room, time) def min_background_concentration(self) -> _VectorisedFloat: """ diff --git a/caimira/tests/models/test_concentration_model.py b/caimira/tests/models/test_concentration_model.py index f8f42106..27703a2f 100644 --- a/caimira/tests/models/test_concentration_model.py +++ b/caimira/tests/models/test_concentration_model.py @@ -252,8 +252,11 @@ def test_normed_integrated_concentration_vectorisation( "known_min_background_concentration", "expected_concentration"], [ - [0., 240., 240.], - [0., np.array([240., 240.]), np.array([240., 240.])] + [0., 240., 240. + 0.5/75], + [0.0001, 240.0, 240. + 0.5/75], + [1e-6, 240.0, 240 + 0.5/75], + [0., np.array([240., 240.]), np.array([240. + 0.5/75, 240. + 0.5/75])], + [np.array([0.0001, 1e-6]), np.array([240., 240.]), np.array([240. + 0.5/75, 240. + 0.5/75])], ] ) def test_zero_ventilation_rate( @@ -272,4 +275,5 @@ def test_zero_ventilation_rate( known_min_background_concentration = known_min_background_concentration) normed_concentration = known_conc_model.concentration(1) - npt.assert_almost_equal(normed_concentration, expected_concentration) + assert normed_concentration == pytest.approx(expected_concentration, abs=1e-6) + \ No newline at end of file