From eaf858e1b8870aa042d5c2128cd8cfd1a627a263 Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 13 May 2026 14:24:38 +0200 Subject: [PATCH 1/2] renewal at t >= t_end and not when t > t_end --- cpp/benchmarks/flow_simulation_ode_secirvvs.h | 15 ++++++++++----- .../mobility/metapopulation_mobility_instant.h | 5 +++-- cpp/models/ode_secir/model.h | 9 +++++---- cpp/models/ode_secirts/model.h | 9 +++++---- cpp/models/ode_secirvvs/model.h | 9 +++++---- cpp/tests/test_dynamic_npis.cpp | 16 ++++++++-------- 6 files changed, 36 insertions(+), 27 deletions(-) diff --git a/cpp/benchmarks/flow_simulation_ode_secirvvs.h b/cpp/benchmarks/flow_simulation_ode_secirvvs.h index 82a262cdf7..3df9d65c93 100644 --- a/cpp/benchmarks/flow_simulation_ode_secirvvs.h +++ b/cpp/benchmarks/flow_simulation_ode_secirvvs.h @@ -570,12 +570,17 @@ class Simulation : public Base auto inf_rel = get_infections_relative(*this, t, this->get_result().get_last_value()) * dyn_npis.get_base_value(); auto exceeded_threshold = dyn_npis.get_max_exceeded_threshold(inf_rel); + const bool npi_expired = + floating_point_greater_equal(t, ScalarType(m_dynamic_npi.second), 1e-10); if (exceeded_threshold != dyn_npis.get_thresholds().end() && - (exceeded_threshold->first > m_dynamic_npi.first || - t > ScalarType(m_dynamic_npi.second))) { // old npi was weaker or is expired - - if (t + delay_npi_implementation < direc_end) { - auto t_start = SimulationTime(t + delay_npi_implementation); + (exceeded_threshold->first > m_dynamic_npi.first || npi_expired)) { + // old npi was weaker or is expired + + const bool is_expiry_renewal = + npi_expired && !(exceeded_threshold->first > m_dynamic_npi.first); + ScalarType effective_delay = is_expiry_renewal ? ScalarType(0) : delay_npi_implementation; + if (t + effective_delay < direc_end) { + auto t_start = SimulationTime(t + effective_delay); // set the end to the minimum of start+delay and the end of the directive auto t_end = SimulationTime( std::min(direc_end, ScalarType(t_start + dyn_npis.get_duration()))); diff --git a/cpp/memilio/mobility/metapopulation_mobility_instant.h b/cpp/memilio/mobility/metapopulation_mobility_instant.h index dadef6739e..1343369af2 100644 --- a/cpp/memilio/mobility/metapopulation_mobility_instant.h +++ b/cpp/memilio/mobility/metapopulation_mobility_instant.h @@ -551,9 +551,10 @@ void mio::MobilityEdge::apply_mobility(FP t, FP dt, SimulationNode& auto inf_rel = get_infections_relative(node_from, t, node_from.get_last_state()) * dyn_npis.get_base_value(); auto exceeded_threshold = dyn_npis.get_max_exceeded_threshold(inf_rel); + const bool npi_expired = floating_point_greater_equal(t, FP(m_dynamic_npi.second), 1e-10); if (exceeded_threshold != dyn_npis.get_thresholds().end() && - (exceeded_threshold->first > m_dynamic_npi.first || - t > FP(m_dynamic_npi.second))) { //old NPI was weaker or is expired + (exceeded_threshold->first > m_dynamic_npi.first || npi_expired)) { + //old NPI was weaker or is expired auto t_end = SimulationTime(t + dyn_npis.get_duration().get()); m_dynamic_npi = std::make_pair(exceeded_threshold->first, t_end); implement_dynamic_npis(m_parameters.get_coefficients(), exceeded_threshold->second, diff --git a/cpp/models/ode_secir/model.h b/cpp/models/ode_secir/model.h index 154b6d0337..664d26f09c 100644 --- a/cpp/models/ode_secir/model.h +++ b/cpp/models/ode_secir/model.h @@ -315,15 +315,16 @@ class Simulation : public BaseT auto inf_rel = get_infections_relative(*this, t, this->get_result().get_last_value()) * dyn_npis.get_base_value(); auto exceeded_threshold = dyn_npis.get_max_exceeded_threshold(inf_rel); + const bool npi_expired = floating_point_greater_equal(t, FP(m_dynamic_npi.second), 1e-10); if (exceeded_threshold != dyn_npis.get_thresholds().end() && - (exceeded_threshold->first > m_dynamic_npi.first || - t > FP(m_dynamic_npi.second))) { // old npi was weaker or is expired + (exceeded_threshold->first > m_dynamic_npi.first || npi_expired)) { + // old npi was weaker or is expired // Keep-alive: if the NPI expired but the threshold is still exceeded at the // same level, renew immediately without delay to avoid a gap. // Apply implementation delay only if stronger NPI needed. bool is_expiry_renewal = - (t > FP(m_dynamic_npi.second)) && !(exceeded_threshold->first > m_dynamic_npi.first); + npi_expired && !(exceeded_threshold->first > m_dynamic_npi.first); FP effective_delay = is_expiry_renewal ? FP(0) : delay_npi_implementation; if (t + effective_delay < direc_end) { auto t_start = SimulationTime(t + effective_delay); @@ -341,7 +342,7 @@ class Simulation : public BaseT auto t_start_damping = (!is_expiry_renewal && FP(t_start) > FP(0)) ? SimulationTime(FP(t_start) + FP(1)) : t_start; - auto t_end_damping = (FP(t_start) > FP(0)) ? SimulationTime(FP(t_end) + FP(1)) : t_end; + auto t_end_damping = SimulationTime(FP(t_end) + FP(1)); implement_dynamic_npis(contact_patterns.get_cont_freq_mat(), exceeded_threshold->second, t_start_damping, t_end_damping, [](auto& g) { return make_contact_damping_matrix(g); diff --git a/cpp/models/ode_secirts/model.h b/cpp/models/ode_secirts/model.h index 9e05e543c9..78119b3c17 100644 --- a/cpp/models/ode_secirts/model.h +++ b/cpp/models/ode_secirts/model.h @@ -785,15 +785,16 @@ class Simulation : public BaseT auto inf_rel = get_infections_relative(*this, t, this->get_result().get_last_value()) * dyn_npis.get_base_value(); auto exceeded_threshold = dyn_npis.get_max_exceeded_threshold(inf_rel); + const bool npi_expired = floating_point_greater_equal(t, FP(m_dynamic_npi.second), 1e-10); if (exceeded_threshold != dyn_npis.get_thresholds().end() && - (exceeded_threshold->first > m_dynamic_npi.first || - t > FP(m_dynamic_npi.second))) { //old npi was weaker or is expired + (exceeded_threshold->first > m_dynamic_npi.first || npi_expired)) { + //old npi was weaker or is expired // Keep-alive: if the NPI expired but the threshold is still exceeded at the // same level, renew immediately without delay to avoid a gap. // Apply implementation delay only if stronger NPI needed. bool is_expiry_renewal = - (t > FP(m_dynamic_npi.second)) && !(exceeded_threshold->first > m_dynamic_npi.first); + npi_expired && !(exceeded_threshold->first > m_dynamic_npi.first); FP effective_delay = is_expiry_renewal ? FP(0) : delay_npi_implementation; if (t + effective_delay < direc_end) { auto t_start = SimulationTime(t + effective_delay); @@ -813,7 +814,7 @@ class Simulation : public BaseT auto t_start_damping = (!is_expiry_renewal && FP(t_start) > FP(0)) ? SimulationTime(FP(t_start) + FP(1)) : t_start; - auto t_end_damping = (FP(t_start) > FP(0)) ? SimulationTime(FP(t_end) + FP(1)) : t_end; + auto t_end_damping = SimulationTime(FP(t_end) + FP(1)); implement_dynamic_npis(contact_patterns.get_cont_freq_mat(), exceeded_threshold->second, t_start_damping, t_end_damping, [](auto& g) { return make_contact_damping_matrix(g); diff --git a/cpp/models/ode_secirvvs/model.h b/cpp/models/ode_secirvvs/model.h index 785756c0c3..9ed73d0abb 100644 --- a/cpp/models/ode_secirvvs/model.h +++ b/cpp/models/ode_secirvvs/model.h @@ -710,15 +710,16 @@ class Simulation : public BaseT auto inf_rel = get_infections_relative(*this, t, this->get_result().get_last_value()) * dyn_npis.get_base_value(); auto exceeded_threshold = dyn_npis.get_max_exceeded_threshold(inf_rel); + const bool npi_expired = floating_point_greater_equal(t, FP(m_dynamic_npi.second), 1e-10); if (exceeded_threshold != dyn_npis.get_thresholds().end() && - (exceeded_threshold->first > m_dynamic_npi.first || - t > FP(m_dynamic_npi.second))) { //old npi was weaker or is expired + (exceeded_threshold->first > m_dynamic_npi.first || npi_expired)) { + //old npi was weaker or is expired // Keep-alive: if the NPI expired but the threshold is still exceeded at the // same level, renew immediately without delay to avoid a gap. // Apply implementation delay only if stronger NPI needed. bool is_expiry_renewal = - (t > FP(m_dynamic_npi.second)) && !(exceeded_threshold->first > m_dynamic_npi.first); + npi_expired && !(exceeded_threshold->first > m_dynamic_npi.first); FP effective_delay = is_expiry_renewal ? FP(0) : delay_npi_implementation; if (t + effective_delay < direc_end) { auto t_start = SimulationTime(t + effective_delay); @@ -738,7 +739,7 @@ class Simulation : public BaseT auto t_start_damping = (!is_expiry_renewal && FP(t_start) > FP(0)) ? SimulationTime(FP(t_start) + FP(1)) : t_start; - auto t_end_damping = (FP(t_start) > FP(0)) ? SimulationTime(FP(t_end) + FP(1)) : t_end; + auto t_end_damping = SimulationTime(FP(t_end) + FP(1)); implement_dynamic_npis(contact_patterns.get_cont_freq_mat(), exceeded_threshold->second, t_start_damping, t_end_damping, [](auto& g) { return make_contact_damping_matrix(g); diff --git a/cpp/tests/test_dynamic_npis.cpp b/cpp/tests/test_dynamic_npis.cpp index 54baa7a091..aeeffeebd0 100644 --- a/cpp/tests/test_dynamic_npis.cpp +++ b/cpp/tests/test_dynamic_npis.cpp @@ -682,8 +682,8 @@ TEST(DynamicNPIs, secir_expiry_keep_alive) // // Timeline (delay=2, duration=5, t0=1): // 1st NPI: t_start=3, t_start_damping=4, t_end=8, t_end_damping=9 - // At t=9 (expiry): keep-alive acts, t_start=9, t_start_damping=9 (no +1!), - // t_end=14, t_end_damping=15 -> list collapses to [(t=4,0.5),(t=15,0.0)] + // At t=8 (expiry): keep-alive acts, t_start=8, t_start_damping=8 (no +1!), + // t_end=13, t_end_damping=14 -> list collapses to [(t=4,0.5),(t=14,0.0)] mio::osecir::Model model(1); model.populations[{mio::AgeGroup(0), mio::osecir::InfectionState::InfectedSymptoms}] = 10; model.populations.set_difference_from_total({mio::AgeGroup(0), mio::osecir::InfectionState::Susceptible}, 100); @@ -703,22 +703,22 @@ TEST(DynamicNPIs, secir_expiry_keep_alive) npis.set_implementation_delay(mio::SimulationTime(2.0)); model.parameters.get>() = npis; - // Stop at t=14 so the 2nd keep-alive (which would act at t=15) does not trigger. + // Stop at t=12 so the 2nd keep-alive (which would act at t=13) does not trigger. mio::osecir::Simulation> sim(model, 1.0); - sim.advance(14.0); + sim.advance(12.0); auto const& cm_dyn = sim.get_model().parameters.get>().get_cont_freq_mat(); - // Damping list after keep-alive collapses to [(t=4, 0.5), (t=15, 0.0)]: + // Damping list after keep-alive collapses to [(t=4, 0.5), (t=14, 0.0)]: EXPECT_DOUBLE_EQ(cm_dyn.get_matrix_at(mio::SimulationTime(4.0))(0, 0), 0.5); // 1st NPI active EXPECT_DOUBLE_EQ(cm_dyn.get_matrix_at(mio::SimulationTime(8.0))(0, 0), 0.5); // still active // no dip at t=9 as keep-alive overwrote the restore entry, contact stays at 0.5. // (Without this fix the restore would restore to 1.0 at t=9.) EXPECT_DOUBLE_EQ(cm_dyn.get_matrix_at(mio::SimulationTime(9.0))(0, 0), 0.5); EXPECT_DOUBLE_EQ(cm_dyn.get_matrix_at(mio::SimulationTime(10.0))(0, 0), 0.5); // still constant - EXPECT_DOUBLE_EQ(cm_dyn.get_matrix_at(mio::SimulationTime(14.0))(0, 0), 0.5); // still active - // Restore window [14, 15]: complete at t=15. - EXPECT_DOUBLE_EQ(cm_dyn.get_matrix_at(mio::SimulationTime(15.0))(0, 0), 1.0); + EXPECT_DOUBLE_EQ(cm_dyn.get_matrix_at(mio::SimulationTime(13.0))(0, 0), 0.5); // still active + // Restore window [13, 14]: complete at t=14. + EXPECT_DOUBLE_EQ(cm_dyn.get_matrix_at(mio::SimulationTime(14.0))(0, 0), 1.0); } TEST(DynamicNPIs, secirvvs_threshold_safe) From 5af3dae0cadb48e3bebe196fd2020f6bb4f4899a Mon Sep 17 00:00:00 2001 From: HenrZu <69154294+HenrZu@users.noreply.github.com> Date: Wed, 13 May 2026 14:47:40 +0200 Subject: [PATCH 2/2] update h5 secirvvs test file --- cpp/tests/data/results_osecirvvs.h5 | Bin 33312 -> 33312 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/cpp/tests/data/results_osecirvvs.h5 b/cpp/tests/data/results_osecirvvs.h5 index 34707a720b3b2f38e5bb4570703f897d1835ec07..432ace94dc24dbcdb46f417281b616825dc49f78 100644 GIT binary patch delta 14932 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ℜK^bTSlqUqnIQY}DvLh))0 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 delta 14931 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