Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions cpp/memilio/compartments/flow_simulation.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,9 @@ class FlowSimulation : public details::FlowSimulationBase<FP, M, OdeIntegrator<F
// To incorporate external changes to the last values of pop_result (e.g. by applying mobility), we only
// calculate the change in population starting from the last available time point in m_result, instead
// of starting at t0. To do that, the following difference of flows is used.
model.get_derivatives(flows - Base::get_flows().get_value(pop_result.get_num_time_points() - 1),
m_pop); // note: overwrites values in pop
auto& flow_delta = Base::get_flow_delta();
flow_delta = flows - Base::get_flows().get_value(pop_result.get_num_time_points() - 1);
model.get_derivatives(flow_delta, m_pop); // note: overwrites values in pop
// add the "initial" value of the ODEs (using last available time point in pop_result)
// If no changes were made to the last value in m_result outside of FlowSimulation, the following
// line computes the same as `model.get_derivatives(flows, x); x += model.get_initial_values();`.
Expand Down
11 changes: 10 additions & 1 deletion cpp/memilio/compartments/flow_simulation_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class FlowSimulationBase : public SimulationBase<FP, M, Integrands...>
FlowSimulationBase(Model const& model, std::unique_ptr<Core>&& integrator_core, FP t0, FP dt)
: Base(model, std::move(integrator_core), t0, dt)
, m_flow_result(t0, model.get_initial_flows())
, m_flow_delta(model.get_initial_flows().size())
{
}

Expand Down Expand Up @@ -94,16 +95,24 @@ class FlowSimulationBase : public SimulationBase<FP, M, Integrands...>
auto& result = this->get_result();
// take the last time point as base result (instead of the initial results), so that we use external changes
const size_t last_tp = result.get_num_time_points() - 1;
result.reserve(flows.get_num_time_points());
// calculate new time points
for (Eigen::Index i = result.get_num_time_points(); i < flows.get_num_time_points(); i++) {
result.add_time_point(flows.get_time(i));
model.get_derivatives(flows.get_value(i) - flows.get_value(last_tp), result.get_value(i));
m_flow_delta = flows.get_value(i) - flows.get_value(last_tp);
model.get_derivatives(m_flow_delta, result.get_value(i));
result.get_value(i) += result.get_value(last_tp);
}
}

Eigen::VectorX<FP>& get_flow_delta()
{
return m_flow_delta;
}

private:
mio::TimeSeries<FP> m_flow_result; ///< Flow result of the simulation.
Eigen::VectorX<FP> m_flow_delta; ///< Pre-allocated temporary for flow changes relative to the current base point.
};

/// @brief Specialization of FlowSimulationBase that takes a SystemIntegrator instead of it's Integrands.
Expand Down
Loading