2020import argparse
2121
2222import numpy as np
23+ import matplotlib .pyplot as plt
2324
2425import memilio .simulation as mio
2526import memilio .simulation .secir as secir
2627
2728
28- def parameter_study ( ):
29+ def run_mobility_example ( plot_results = True ):
2930 mio .set_log_level (mio .LogLevel .Warning )
3031
3132 t0 = 0
@@ -52,7 +53,7 @@ def parameter_study():
5253 model .parameters .CriticalPerSevere [secir .AgeGroup (0 )] = 0.25
5354 model .parameters .DeathsPerCritical [secir .AgeGroup (0 )] = 0.3
5455
55- # two regions with different populations and with some migration between them
56+ # two regions with different populations and with some mobility between them
5657 graph = secir .MigrationGraph ()
5758 model .populations [secir .AgeGroup (0 ), secir .InfectionState .Exposed ] = 100
5859 model .populations [secir .AgeGroup (
@@ -88,25 +89,80 @@ def parameter_study():
8889 2000 )
8990 model .apply_constraints ()
9091 graph .add_node (id = 1 , model = model , t0 = t0 )
91- migration_coefficients = 0.1 * np .ones (8 )
92- migration_params = mio .MigrationParameters (migration_coefficients )
92+ mobility_coefficients = 0.1 * np .ones (model . populations . numel () )
93+ mobility_params = mio .MigrationParameters (mobility_coefficients )
9394 # one coefficient per (age group x compartment)
94- graph .add_edge (0 , 1 , migration_params )
95+ graph .add_edge (0 , 1 , mobility_params )
9596 # directed graph -> add both directions so coefficients can be different
96- graph .add_edge (1 , 0 , migration_params )
97+ graph .add_edge (1 , 0 , mobility_params )
9798
9899 # run simulation
99100 sim = secir .MigrationSimulation (graph , t0 , dt = 0.5 )
100101 sim .advance (tmax )
101102
102103 # process results
103- region0_result = sim .graph .get_node (0 ).property .result
104- region1_result = sim .graph .get_node (1 ).property .result
104+ region0_result = secir .interpolate_simulation_result (
105+ sim .graph .get_node (0 ).property .result )
106+ region1_result = secir .interpolate_simulation_result (
107+ sim .graph .get_node (1 ).property .result )
108+
109+ if (plot_results ):
110+ results = [region0_result .as_ndarray (), region1_result .as_ndarray ()]
111+ t = results [0 ][0 , :]
112+ tick_range = (np .arange (int ((len (t ) - 1 ) / 10 ) + 1 ) * 10 )
113+ tick_range [- 1 ] -= 1
114+
115+ fig , ax = plt .subplots (figsize = (10 , 6 ))
116+ for idx , result_region in enumerate (results ):
117+ region_label = f'Region { idx } '
118+ ax .plot (t , result_region [1 , :],
119+ label = f'{ region_label } - #Susceptible' )
120+ ax .plot (t , result_region [2 , :], label = f'{ region_label } - #Exposed' )
121+ ax .plot (t , result_region [3 , :] + result_region [4 , :],
122+ label = f'{ region_label } - #InfectedNoSymptoms' )
123+ ax .plot (t , result_region [5 , :] + result_region [6 , :],
124+ label = f'{ region_label } - #InfectedSymptoms' )
125+ ax .plot (t , result_region [7 , :],
126+ label = f'{ region_label } - #Hospitalzed' )
127+ ax .plot (t , result_region [8 , :],
128+ label = f'{ region_label } - #InfectedCritical' )
129+ ax .plot (t , result_region [9 , :],
130+ label = f'{ region_label } - #Recovered' )
131+ ax .plot (t , result_region [10 , :], label = f'{ region_label } - #Dead' )
132+
133+ ax .set_title (
134+ "SECIR simulation results for both regions (entire population)" )
135+ ax .set_xticks (tick_range )
136+ ax .legend (loc = 'upper right' , bbox_to_anchor = (1 , 0.6 ))
137+ plt .yscale ('log' )
138+ fig .tight_layout
139+ fig .savefig ('Mobility_Secir_by_compartments.pdf' )
140+
141+ fig , ax = plt .subplots (5 , 2 , figsize = (12 , 15 ))
142+ compartments = [
143+ 'Susceptible' , 'Exposed' , 'InfectedNoSymptoms' ,
144+ 'InfectedNoSymptomsConfirmed' , 'InfectedSymptoms' ,
145+ 'InfectedSymptomsConfirmed' , 'InfectedSevere' , 'InfectedCritical' ,
146+ 'Recovered' , 'Dead' ]
147+ num_compartments = len (compartments )
148+
149+ for i , title in zip (range (num_compartments ), compartments ):
150+ ax [int (np .floor (i / 2 )), int (i % 2 )].plot (t ,
151+ results [0 ][i + 1 , :], label = "Region 0" )
152+ ax [int (np .floor (i / 2 )), int (i % 2 )].plot (t ,
153+ results [1 ][i + 1 , :], label = "Region 1" )
154+ ax [int (np .floor (i / 2 )), int (i % 2 )].set_title (title , fontsize = 10 )
155+ ax [int (np .floor (i / 2 )), int (i % 2 )].legend ()
156+ ax [int (np .floor (i / 2 )), int (i % 2 )].set_xticks (tick_range )
157+
158+ plt .subplots_adjust (hspace = 0.5 , bottom = 0.1 , top = 0.9 )
159+ fig .suptitle ('Simulation results for each region in each compartment' )
160+ fig .savefig ('Region_results_compartments.pdf' )
105161
106162
107163if __name__ == "__main__" :
108164 arg_parser = argparse .ArgumentParser (
109165 'migration' ,
110166 description = 'Example demonstrating the setup and simulation of a geographically resolved SECIR model with travel.' )
111167 args = arg_parser .parse_args ()
112- parameter_study ()
168+ run_mobility_example ()
0 commit comments