|
| 1 | +/* |
| 2 | +* Copyright (C) 2020-2026 MEmilio |
| 3 | +* |
| 4 | +* Authors: Henrik Zunker |
| 5 | +* |
| 6 | +* Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de> |
| 7 | +* |
| 8 | +* Licensed under the Apache License, Version 2.0 (the "License"); |
| 9 | +* you may not use this file except in compliance with the License. |
| 10 | +* You may obtain a copy of the License at |
| 11 | +* |
| 12 | +* http://www.apache.org/licenses/LICENSE-2.0 |
| 13 | +* |
| 14 | +* Unless required by applicable law or agreed to in writing, software |
| 15 | +* distributed under the License is distributed on an "AS IS" BASIS, |
| 16 | +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 17 | +* See the License for the specific language governing permissions and |
| 18 | +* limitations under the License. |
| 19 | +*/ |
| 20 | + |
| 21 | +/** |
| 22 | + * Benchmark comparing the overhead of the model-specific osecirvvs::Simulation::advance() |
| 23 | + * (which uses substeps and calls apply_vaccination / apply_variant / dynamic NPI checks) |
| 24 | + * versus the generic mio::Simulation::advance() (a single integrator call for the entire range). |
| 25 | + */ |
| 26 | + |
| 27 | +#include "ode_secirvvs/model.h" |
| 28 | +#include "memilio/compartments/simulation.h" |
| 29 | +#include "memilio/utils/logging.h" |
| 30 | +#include "benchmark/benchmark.h" |
| 31 | + |
| 32 | +using FP = double; |
| 33 | +using Model = mio::osecirvvs::Model<FP>; |
| 34 | + |
| 35 | +static Model make_model(bool with_npis = false) |
| 36 | +{ |
| 37 | + constexpr int tmax = 10; |
| 38 | + Model model(1); |
| 39 | + model.populations[{mio::AgeGroup(0), mio::osecirvvs::InfectionState::InfectedSymptomsNaive}] = 100.0; |
| 40 | + model.populations.set_difference_from_total({mio::AgeGroup(0), mio::osecirvvs::InfectionState::SusceptibleNaive}, |
| 41 | + 10000.0); |
| 42 | + model.parameters.get<mio::osecirvvs::DailyPartialVaccinations<FP>>().resize(mio::SimulationDay(size_t(tmax + 1))); |
| 43 | + model.parameters.get<mio::osecirvvs::DailyFullVaccinations<FP>>().resize(mio::SimulationDay(size_t(tmax + 1))); |
| 44 | + if (with_npis) { |
| 45 | + auto& npis = model.parameters.get<mio::osecirvvs::DynamicNPIsInfectedSymptoms<FP>>(); |
| 46 | + npis.set_threshold(0.01 * 100'000, {mio::DampingSampling<FP>{1.0, |
| 47 | + mio::DampingLevel(0), |
| 48 | + mio::DampingType(0), |
| 49 | + mio::SimulationTime<FP>(0), |
| 50 | + {0}, |
| 51 | + Eigen::VectorXd::Ones(1)}}); |
| 52 | + npis.set_duration(mio::SimulationTime<FP>(14.0)); |
| 53 | + npis.set_base_value(100'000); |
| 54 | + } |
| 55 | + return model; |
| 56 | +} |
| 57 | + |
| 58 | +// Generic advance: single integrator call for the full [t0, tmax] range. |
| 59 | +static void BM_generic(benchmark::State& state) |
| 60 | +{ |
| 61 | + mio::set_log_level(mio::LogLevel::off); |
| 62 | + auto model = make_model(); |
| 63 | + for (auto _ : state) { |
| 64 | + mio::simulate<FP, Model>(0., 10., 0.1, model); |
| 65 | + } |
| 66 | +} |
| 67 | + |
| 68 | +// Model-specific advance without dynamic NPIs: 1-day loop with apply_vaccination + apply_variant, |
| 69 | +// dynamic NPI threshold check is skipped (thresholds empty). |
| 70 | +static void BM_secirvvs_no_npis(benchmark::State& state) |
| 71 | +{ |
| 72 | + mio::set_log_level(mio::LogLevel::off); |
| 73 | + auto model = make_model(/*with_npis=*/false); |
| 74 | + for (auto _ : state) { |
| 75 | + mio::osecirvvs::simulate<FP>(0., 10., 0.1, model); |
| 76 | + } |
| 77 | +} |
| 78 | + |
| 79 | +// Model-specific advance with dynamic NPIs: same as above plus get_infections_relative + |
| 80 | +// threshold comparison on every day step. |
| 81 | +static void BM_secirvvs_with_npis(benchmark::State& state) |
| 82 | +{ |
| 83 | + mio::set_log_level(mio::LogLevel::off); |
| 84 | + auto model = make_model(/*with_npis=*/true); |
| 85 | + for (auto _ : state) { |
| 86 | + mio::osecirvvs::simulate<FP>(0., 10., 0.1, model); |
| 87 | + } |
| 88 | +} |
| 89 | + |
| 90 | +BENCHMARK(BM_generic)->Name("SECIRVVS generic advance"); |
| 91 | +BENCHMARK(BM_secirvvs_no_npis)->Name("SECIRVVS model-specific advance (no dynamic NPIs)"); |
| 92 | +BENCHMARK(BM_secirvvs_with_npis)->Name("SECIRVVS model-specific advance (with dynamic NPIs)"); |
| 93 | +BENCHMARK_MAIN(); |
0 commit comments