@@ -83,35 +83,30 @@ class Simulation
8383 update_current_rates_and_waiting_times ();
8484 size_t next_event = determine_next_event (); // index of the next event
8585 FP current_time = m_result.get_last_time ();
86- // set current time to add next time point in the future
87- FP last_result_time = current_time;
86+ // set next result time; system state is saved every dt time step
87+ FP next_result_time = current_time + m_dt ;
8888 // iterate over time
8989 while (current_time + m_waiting_times[next_event] < tmax) {
90- // If the next event happens further in the future than the next stored time point, add a new one.
91- if (current_time + m_waiting_times[next_event] >= last_result_time) {
92- auto num_dt = std::ceil ((current_time + m_waiting_times[next_event] - last_result_time) / m_dt);
93- last_result_time = std::min (tmax, last_result_time + num_dt * m_dt);
94- m_result.add_time_point (last_result_time);
95- // copy from the previous last value
96- m_result.get_last_value () = m_result[m_result.get_num_time_points () - 2 ];
97- }
9890 // update time
9991 current_time += m_waiting_times[next_event];
92+ // Save results until the next event time point
93+ // do not save current time, as it does not yet include the next event
94+ while (next_result_time < current_time) {
95+ m_result.add_time_point (next_result_time);
96+ m_result.get_last_value () = m_model->populations .get_compartments ();
97+ next_result_time += m_dt;
98+ }
10099 // decide event type by index and perform it
101100 if (next_event < adoption_rates ().size ()) {
102101 // perform adoption event
103102 const auto & rate = adoption_rates ()[next_event];
104- m_result.get_last_value ()[m_model->populations .get_flat_index ({rate.region , rate.from })] -= 1 ;
105103 m_model->populations [{rate.region , rate.from }] -= 1.0 ;
106- m_result.get_last_value ()[m_model->populations .get_flat_index ({rate.region , rate.to })] += 1 ;
107104 m_model->populations [{rate.region , rate.to }] += 1.0 ;
108105 }
109106 else {
110107 // perform transition event
111108 const auto & rate = transition_rates ()[next_event - adoption_rates ().size ()];
112- m_result.get_last_value ()[m_model->populations .get_flat_index ({rate.from , rate.status })] -= 1 ;
113109 m_model->populations [{rate.from , rate.status }] -= 1.0 ;
114- m_result.get_last_value ()[m_model->populations .get_flat_index ({rate.to , rate.status })] += 1 ;
115110 m_model->populations [{rate.to , rate.status }] += 1.0 ;
116111 }
117112 // update internal times
@@ -124,10 +119,13 @@ class Simulation
124119 update_current_rates_and_waiting_times ();
125120 next_event = determine_next_event ();
126121 }
127- // copy last result, if no event occurs between last_result_time and tmax
128- if (last_result_time < tmax) {
129- m_result.add_time_point (tmax);
130- m_result.get_last_value () = m_result[m_result.get_num_time_points () - 2 ];
122+ // copy last result, if no event occurs between last result time point and tmax
123+ if (m_result.get_last_time () < tmax) {
124+ while (next_result_time <= tmax) {
125+ m_result.add_time_point (next_result_time);
126+ m_result.get_last_value () = m_model->populations .get_compartments ();
127+ next_result_time += m_dt;
128+ }
131129 // update internal times
132130 for (size_t i = 0 ; i < m_internal_time.size (); i++) {
133131 m_internal_time[i] += m_current_rates[i] * (tmax - current_time);
@@ -184,7 +182,7 @@ class Simulation
184182 inline void update_current_rates_and_waiting_times ()
185183 {
186184 size_t i = 0 ; // shared index for iterating both rates
187- const auto last_values = m_result. get_last_value ();
185+ const auto last_values = m_model-> populations . get_compartments ();
188186 for (const auto & rate : adoption_rates ()) {
189187 m_current_rates[i] = m_model->evaluate (rate, last_values);
190188 m_waiting_times[i] = (m_current_rates[i] > 0 )
0 commit comments