12#ifndef RESPOND_SIMULATION_HPP_
13#define RESPOND_SIMULATION_HPP_
15#include <respond/constants.hpp>
16#include <respond/history.hpp>
17#include <respond/logging.hpp>
18#include <respond/model.hpp>
38 : _owner(&owner), _idx(idx) {}
47 operator Model &() {
return _owner->GetModelRefOrThrow(_idx); }
51 return *
this =
static_cast<const Model &
>(
52 other._owner->GetModelRefOrThrow(other._idx));
57 _owner->GetModelRefOrThrow(_idx);
58 _owner->_models[_idx] = model.
clone();
66 LogError(_owner->_log_name,
67 "Cannot assign null model pointer to simulation "
69 throw std::invalid_argument(
70 "Error attempting to assign null model pointer.");
72 _owner->GetModelRefOrThrow(_idx);
73 _owner->_models[_idx] = model->clone();
95 :
Simulation(log_name, RESPOND_DEFAULT_LOG_FILE) {}
100 Simulation(
const std::string &log_name,
const std::string &log_filepath)
101 : _log_name(log_name) {
102 CreateFileLogger(log_name, log_filepath);
113 _log_name = other._log_name;
114 for (
const auto &m : other._models) {
115 _models.push_back(m->clone());
117 _duration = other._duration;
118 _parameter_change_times = other._parameter_change_times;
119 _stratify_entering_cohort = other._stratify_entering_cohort;
120 _build_summary_stats = other._build_summary_stats;
121 _save_state_history = other._save_state_history;
122 _timesteps_to_report = other._timesteps_to_report;
123 _pivot_long = other._pivot_long;
130 if (
this != &other) {
131 _log_name = other._log_name;
133 for (
const auto &m : other._models) {
134 _models.push_back(m->clone());
136 _duration = other._duration;
137 _parameter_change_times = other._parameter_change_times;
138 _stratify_entering_cohort = other._stratify_entering_cohort;
139 _build_summary_stats = other._build_summary_stats;
140 _save_state_history = other._save_state_history;
141 _timesteps_to_report = other._timesteps_to_report;
142 _pivot_long = other._pivot_long;
150 : _log_name(std::move(other._log_name)), _duration(other._duration),
151 _parameter_change_times(std::move(other._parameter_change_times)),
152 _stratify_entering_cohort(other._stratify_entering_cohort),
153 _build_summary_stats(other._build_summary_stats),
154 _save_state_history(other._save_state_history),
155 _timesteps_to_report(std::move(other._timesteps_to_report)),
156 _pivot_long(other._pivot_long) {
157 for (
const auto &m : other._models) {
158 _models.push_back(m->clone());
160 other._models.clear();
167 if (
this != &other) {
168 _log_name = std::move(other._log_name);
169 _duration = other._duration;
170 _parameter_change_times = std::move(other._parameter_change_times);
171 _stratify_entering_cohort = other._stratify_entering_cohort;
172 _build_summary_stats = other._build_summary_stats;
173 _save_state_history = other._save_state_history;
174 _timesteps_to_report = std::move(other._timesteps_to_report);
175 _pivot_long = other._pivot_long;
177 for (
const auto &m : other._models) {
178 _models.push_back(m->clone());
180 other._models.clear();
198 return _models.back()->clone();
207 void AddModel(
const std::unique_ptr<Model> &model) {
208 _models.push_back(model->clone());
213 void Run(
int duration = -1) {
215 _duration = duration;
217 LogInfo(_log_name,
"Running simulation for duration of " +
218 std::to_string(_duration) +
" timesteps.");
219 for (
const auto &model : _models) {
220 model->SetFinalTimestep(_duration);
221 model->RunTimesteps();
234 std::vector<std::unique_ptr<Model>> _models_copy;
235 for (
const auto &model : _models) {
236 _models_copy.push_back(model->clone());
248 GetModelRefOrThrow(idx);
257 return GetModelRefOrThrow(idx);
268 std::map<size_t, std::string> ret;
269 for (
size_t i = 0; i < _models.size(); ++i) {
270 ret[i] = _models[i]->GetName();
281 if (_models.empty()) {
282 LogError(_log_name,
"No models available in GetModel.");
283 throw std::out_of_range(
"Error attempting to GetModel: no models.");
285 if (idx < -1 || idx >=
static_cast<int>(_models.size())) {
287 "Index out of range in GetModel: " + std::to_string(idx));
288 throw std::out_of_range(
"Error attempting to GetModel by index.");
292 return _models.back()->clone();
294 return _models[idx]->clone();
300 std::vector<std::string> ret;
301 for (
auto &m : _models) {
302 ret.push_back(m->GetName());
312 if (idx >= _models.size()) {
313 LogError(_log_name,
"Index out of range in GetModelHistory: " +
314 std::to_string(idx));
315 throw std::out_of_range(
316 "Error attempting to GetModelHistory by index.");
318 return _models[idx]->GetHistories();
325 if (idx >= _models.size()) {
326 LogError(_log_name,
"Index out of range in GetModelHistoryNames: " +
327 std::to_string(idx));
328 throw std::out_of_range(
329 "Error attempting to GetModelHistoryNames by index.");
331 std::vector<std::string> ret;
332 for (
const auto &kv : _models[idx]->GetHistories()) {
333 ret.push_back(kv.first);
338 void SetDuration(
int duration) { _duration = duration; }
341 Model &GetModelRefOrThrow(
size_t idx) {
342 if (idx >= _models.size()) {
343 LogError(_log_name,
"Index out of range in model access: " +
344 std::to_string(idx));
345 throw std::out_of_range(
"Error attempting to access model by "
348 return *_models[idx];
351 const Model &GetModelRefOrThrow(
size_t idx)
const {
352 if (idx >= _models.size()) {
353 LogError(_log_name,
"Index out of range in model access: " +
354 std::to_string(idx));
355 throw std::out_of_range(
"Error attempting to access model by "
358 return *_models[idx];
361 std::string _log_name;
362 std::vector<std::unique_ptr<Model>> _models;
365 std::vector<int> _parameter_change_times;
366 bool _stratify_entering_cohort;
368 bool _build_summary_stats;
369 bool _save_state_history;
370 std::vector<int> _timesteps_to_report;
Abstract base class representing a state transition model. Models manage a state vector,...
Definition: model.hpp:30
virtual std::unique_ptr< Model > clone() const =0
Creates a deep copy of this model.
static std::unique_ptr< Model > Create(const std::string &name, const std::string &log_name=RESPOND_DEFAULT_LOG, const std::string &log_filepath=RESPOND_DEFAULT_LOG_FILE)
Factory method to create a Model instance.
Proxy for mutable model slot access with clone-based assignment.
Definition: simulation.hpp:35
Model * operator->()
Access the underlying model pointer for member access.
Definition: simulation.hpp:41
Model & operator*()
Dereference to the underlying model.
Definition: simulation.hpp:44
ModelSlotProxy & operator=(const ModelSlotProxy &other)
Replace this slot by cloning from another proxy's model.
Definition: simulation.hpp:50
ModelSlotProxy & operator=(const Model &model)
Replace this slot by cloning from a model reference.
Definition: simulation.hpp:56
ModelSlotProxy & operator=(const std::unique_ptr< Model > &model)
Replace this slot by cloning from a model unique_ptr.
Definition: simulation.hpp:64
Manages and executes multiple models in a coordinated simulation. A Simulation aggregates Model insta...
Definition: simulation.hpp:32
std::vector< std::string > GetModelNames() const
Retrieves the names of all models in the simulation.
Definition: simulation.hpp:299
Simulation(Simulation &&other) noexcept
Move constructor for transferring simulation ownership.
Definition: simulation.hpp:149
std::vector< std::unique_ptr< Model > > GetModels() const
Retrieves all models in the simulation.
Definition: simulation.hpp:233
~Simulation()=default
Virtual destructor for polymorphic cleanup.
std::map< size_t, std::string > GetModelIndexNameMap() const
Provide a mapping of model indices to their names for all models in the simulation.
Definition: simulation.hpp:267
void Run(int duration=-1)
Executes one step of the simulation for all models. Calls RunTransitions() on each registered model i...
Definition: simulation.hpp:213
Simulation(const std::string &log_name)
Constructs a Simulation with a specified logger.
Definition: simulation.hpp:94
void ClearModels()
Removes all models from the simulation.
Definition: simulation.hpp:202
const std::map< std::string, History > & GetModelHistory(size_t idx) const
Retrieves the complete state histories for the model at the index.
Definition: simulation.hpp:311
Simulation(const Simulation &other)
Copy constructor creating an independent deep copy of the simulation. All models are cloned; modifica...
Definition: simulation.hpp:112
std::unique_ptr< Model > GetModel(int idx) const
Retrieves a specific model by index in the simulation.
Definition: simulation.hpp:280
std::unique_ptr< Model > CreateNewModel(const std::string &model_name)
Creates a new model instance and adds it to the simulation.
Definition: simulation.hpp:196
Simulation()
Default constructor for a Simulation instance. Initializes the simulation with the default logger.
Definition: simulation.hpp:90
Simulation & operator=(const Simulation &other)
Copy assignment operator for deep copying simulation state.
Definition: simulation.hpp:129
const Model & operator[](size_t idx) const
Const index-based model access.
Definition: simulation.hpp:256
Simulation(const std::string &log_name, const std::string &log_filepath)
Constructs a Simulation with a specified logger and log file.
Definition: simulation.hpp:100
Simulation & operator=(Simulation &&other) noexcept
Move assignment operator for transferring simulation ownership.
Definition: simulation.hpp:166
void AddModel(const std::unique_ptr< Model > &model)
Adds a model to the simulation. The model is cloned and managed by the simulation.
Definition: simulation.hpp:207
const std::vector< std::string > GetModelHistoryNames(size_t idx) const
Retrieves history names for the model at the specified index.
Definition: simulation.hpp:324
ModelSlotProxy operator[](size_t idx)
Mutable index-based model access.
Definition: simulation.hpp:247