Utopia  2
Framework for studying models of complex & adaptive systems.
Environment.hh
Go to the documentation of this file.
1 #ifndef UTOPIA_MODELS_ENVIRONMENT_HH
2 #define UTOPIA_MODELS_ENVIRONMENT_HH
3 
4 // standard library includes
5 #include <random>
6 #include <unordered_map>
7 
8 // third-party library includes
9 
10 // Utopia-related includes
11 #include <utopia/core/model.hh>
12 #include <utopia/core/apply.hh>
13 #include <utopia/core/types.hh>
15 
16 // FuncBundle classes
17 #include "func_bundle.hh"
18 
19 // Collections of environment functions
22 
23 
24 namespace Utopia {
25 namespace Models {
26 namespace Environment {
27 
36 using namespace ParameterFunctionCollection;
37 using namespace StateFunctionCollection;
38 
39 // ++ Type definitions ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
40 
42 
45 struct BaseEnvParam {
46  virtual ~BaseEnvParam() = default;
47 
49  virtual double get_env(const std::string&) const = 0;
50 
52  virtual void set_env(const std::string&, const double&) = 0;
53 };
54 
56 
60 {
62 
63  ~DummyEnvParam() = default;
64 
66  double get_env(const std::string&) const override {
67  throw std::invalid_argument("Accessing getter of the dummy type of "
68  "EnvParam!");
69  }
70 
72  void set_env(const std::string&, const double&) override {
73  throw std::invalid_argument("Accessing setter of the dummy type of "
74  "EnvParam!");
75  }
76 };
77 
79 
84 
87 
88  virtual ~BaseEnvCellState() = default;
89 
91  virtual double get_env(const std::string&) const = 0;
92 
94  virtual void set_env(const std::string&, const double&) = 0;
95 };
96 
98 
102 {
104 
105  ~DummyEnvCellState() = default;
106 
108  double get_env(const std::string&) const override {
109  throw std::invalid_argument("Accessing getter of the dummy type of "
110  "EnvCellState!");
111  }
112 
114  void set_env(const std::string&, const double&) override {
115  throw std::invalid_argument("Accessing setter of the dummy type of "
116  "EnvCellState!");
117  }
118 };
119 
120 
123 
124 
125 // ++ Model definition ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
126 
128 
135 template<typename EnvParam=DummyEnvParam,
137  bool standalone=false>
139  public Model<Environment<EnvParam, EnvCellState, standalone>, ModelTypes>
140 {
141 public:
144 
147 
149  using DataGroup = typename Base::DataGroup;
150 
152  using DataSet = typename Base::DataSet;
153 
156 
159 
162 
164  using Time = typename Base::Time;
165 
167  using EnvParamFunc = typename std::function<double()>;
168 
171 
174 
178 
181 
182 private:
186  DataIO::Config cfg() const {
187  return {};
188  }
189  };
190 
191  // -- Members -------------------------------------------------------------
192  // Base members: _time, _name, _cfg, _hdfgrp, _rng, _monitor, _space
193 
196 
199 
201 
202  std::vector<EnvParamFuncBundle> _env_param_funcs;
203 
205 
206  std::vector<EnvStateFuncBundle> _init_env_state_funcs;
207 
209 
210  std::vector<EnvStateFuncBundle> _env_state_funcs;
211 
212  // .. Datasets ............................................................
214  std::unordered_map<std::string, std::shared_ptr<DataSet>> _dsets_state;
215 
217  std::unordered_map<std::string, std::shared_ptr<DataSet>> _dsets_param;
218 
219 
220 public:
221  // -- Model Setup ---------------------------------------------------------
223 
232  template<class ParentModel, class CellManager>
234  const std::string& name,
235  ParentModel& parent_model,
236  CellManager&& associate_cm,
237  const DataIO::Config& custom_cfg = {}
238  )
239  :
240  // Initialize first via base model
241  Base(name, parent_model, custom_cfg),
242 
243  // Set up the internal CellManager
244  _cm(*this, associate_cm.cfg()),
245  // NOTE If called from the standalone constructor, the .cfg() call
246  // always returns an empty configuration which leads to this
247  // internal CellManager being set up from _cfg["cell_manager"]
248 
249  //set up the environment params
250  _params(this->_cfg),
251 
252  // Set up environment function bundle containers empty
253  _env_param_funcs{},
254  _init_env_state_funcs{},
255  _env_state_funcs{},
256 
257  // Map of datasets; empty until states are set to be tracked
258  _dsets_state{},
259  _dsets_param{}
260  {
261  // Associate the CellManager's cells with each other
262  if constexpr (not std::is_same<CellManager, DummyCellManager>()) {
263  for (std::size_t i=0; i < _cm.cells().size(); i++) {
264  associate_cm.cells()[i]->custom_links().env = _cm.cells()[i];
265  }
266 
267  this->_log->info(
268  "Associated '{}' cells with those of the parent model '{}'.",
269  this->_name, parent_model.get_name()
270  );
271  }
272  else if constexpr (not standalone) {
273  // Only allow coupled models without coupled cellmanagers when
274  // a EnvCellState is the dummy type
275  static_assert(std::is_same<EnvCellState, DummyEnvCellState>(),
276  "The cm for association of environment cells cannot "
277  "be the DummyCellManager! \n"
278  "Setup the model with type DummyEnvCellState for "
279  "standalone model or pass a cell manager for "
280  "associated model.");
281 
282  this->_log->info("Setting up '{}' as coupled model without "
283  "associated cell manager.", this->_name);
284  }
285  else {
286  this->_log->info("Setting up '{}' as standalone model ...",
287  this->_name);
288  }
289 
290  // Check inheritance of EnvCellState; needed for position cache
291  static_assert(std::is_base_of<BaseEnvCellState, EnvCellState>::value,
292  "The model's EnvCellState must derive from "
293  "Utopia::Models::Environment::BaseEnvCellState!");
294 
295  // Check inheritance of EnvParam; needed for getters and setters
296  static_assert(std::is_base_of<BaseEnvParam, EnvParam>::value,
297  "The model's EnvParam must derive from "
298  "Utopia::Models::Environment::BaseEnvParam!");
299 
300  // Store positions
301  apply_rule<Update::sync>(
302  [this](const auto& cell){
303  auto& state = cell->state;
304  state.position = this->_cm.barycenter_of(cell);
305  return state;
306  },
307  this->_cm.cells()
308  );
309  this->_log->debug("Cell barycenters cached.");
310 
311 
312  // Now set up the actual environment parameter functions
313  if (this->_cfg["env_param_funcs"]) {
314  setup_env_param_funcs(this->_cfg["env_param_funcs"]);
315  }
316 
317  // Apply the env_param_funcs for initialization
318  this->_log->debug("Applying {} initial environment param function{} ...",
319  _env_param_funcs.size(),
320  _env_param_funcs.size() != 1 ? "s" : "");
321  for (auto& epfb : _env_param_funcs) {
322  if (epfb.invoke_at_initialization) {
323  apply_env_param_func(epfb, true);
324  }
325  }
326 
327  // Now set up the actual environment state functions
328  if (this->_cfg["init_env_state_funcs"]) {
329  setup_env_state_funcs<true>(this->_cfg["init_env_state_funcs"]);
330  }
331  if (this->_cfg["env_state_funcs"]) {
332  setup_env_state_funcs<false>(this->_cfg["env_state_funcs"]);
333  }
334 
335  // Apply the env_state_funcs for initialization
336  this->_log->info("Applying {} initial environment state function{} ...",
337  _init_env_state_funcs.size(),
338  _init_env_state_funcs.size() != 1 ? "s" : "");
339  for (auto& esfb : _init_env_state_funcs) {
340  apply_env_state_func(esfb);
341  }
342 
343  this->_log->info("{} set up.", this->_name);
344  }
345 
347 
355  template <typename ParentModel>
356  Environment (const std::string name, ParentModel& parent)
357  :
358  // Use existing constructor, passing a _DummyCellManager instance that
359  // ensures that no configuration is carried over.
360  Environment(name, parent, DummyCellManager())
361  { }
362 
363 
364  // -- Public Interface ----------------------------------------------------
365  // .. Simulation Control ..................................................
366 
368  void perform_step () {
369  for (auto& epfb : _env_param_funcs) {
370  apply_env_param_func(epfb);
371  }
372  for (auto& esfb : _env_state_funcs) {
373  apply_env_state_func(esfb);
374  }
375  }
376 
377 
379  void monitor () {
380  }
381 
382 
384 
390  void write_data () {
391  // write parameters
392  for (auto& [key, dset] : _dsets_param) {
393  dset->write(_params.get_env(key));
394  }
395 
396  // write states
397  for (auto& param_dset_pair : _dsets_state) {
398  const auto key = std::get<0>(param_dset_pair);
399  auto& dset = std::get<1>(param_dset_pair);
400 
401  dset->write(_cm.cells().begin(), _cm.cells().end(),
402  [key](const auto& cell) {
403  return cell->state.get_env(key);
404  }
405  );
406  }
407  }
408 
409 
410  // Getters and setters ....................................................
412  double get_parameter(const std::string& param_name) const {
413  return this->_params.get_env(param_name);
414  }
415 
417  void set_parameter(const std::string& param_name, double value) {
418  this->_params.set_env(param_name, value);
419  }
420 
422  const auto& cm() const {
423  return this->_cm;
424  }
425 
426  // .. Environment Function Bundle Handling ................................
428 
431  template<class EPFB>
432  void add_env_param_func(EPFB&& epfb) {
433  _env_param_funcs.push_back(epfb);
434  this->_log->debug("Added environment param function '{}'.", epfb.name);
435  }
436 
438 
442  void add_env_param_func(const std::string& name, const EnvParamFunc& epf,
443  const std::string& param_name,
444  std::tuple<bool, bool, std::set<Time>> times_tuple)
445  {
446  add_env_param_func(
447  EnvParamFuncBundle(name, epf, param_name, times_tuple)
448  );
449  }
450 
452 
456  void add_env_param_func_from_cfg(const std::string& name,
457  const EnvParamFunc& epf, const std::string& param_name,
458  const Config& cfg = {})
459  {
460  auto invoke_times_tuple = extract_times_and_initialization<Time>(cfg);
461  add_env_param_func(name, epf, param_name, invoke_times_tuple);
462  }
463 
465 
468  template<bool add_to_initial=false, class ESFB>
469  void add_env_state_func(ESFB&& esfb) {
470  if constexpr (add_to_initial) {
471  _init_env_state_funcs.push_back(esfb);
472  }
473  else {
474  _env_state_funcs.push_back(esfb);
475  }
476  this->_log->debug("Added {}environment function '{}'.",
477  add_to_initial ? "initial " : "", esfb.name);
478  }
479 
481 
487  template<bool add_to_initial=false>
488  void add_env_state_func(const std::string& name,
489  const EnvStateFunc& esf, const Update& update = Update::sync,
490  std::pair<bool, std::set<Time>> times_pair = {true, {}},
491  Config select_cfg = {})
492  {
493  // resolve select option
494  bool fix_selection;
495  EnvCellContainer cell_selection = {};
496  if (not select_cfg.IsNull()) {
497  std::string generate = get_as<std::string>("generate", select_cfg);
498  if (generate == "once") {
499  fix_selection = true;
500  }
501  else if (generate == "always") {
502  fix_selection = false;
503  }
504  else {
505  throw std::invalid_argument("Key 'generate' in 'select' "
506  "feature of environment state function '"
507  + name + "' must be 'once' to fix selection or "
508  "'always' to generate it on the fly, but was '"
509  + generate + "'!");
510  }
511 
512  if (fix_selection) {
513  this->_log->debug("Generating a selection of cells and fixing "
514  "it for the rule '{}'.", name);
515  cell_selection = _cm.select_cells(select_cfg);
516  }
517  }
518  else {
519  fix_selection = false;
520  }
521 
522  add_env_state_func<add_to_initial>(
523  EnvStateFuncBundle(name, esf, update, add_to_initial, times_pair,
524  {fix_selection, cell_selection, select_cfg})
525  );
526  }
527 
529 
535  template<bool add_to_initial=false>
537  const std::string& name,
538  const EnvStateFunc& esf,
539  const Update& update = Update::sync,
540  const Config& cfg = {})
541  {
542  auto times_pair = extract_times<Time>(cfg);
543  Config select_cfg = {};
544  if (cfg.IsMap()) {
545  select_cfg = get_as<Config>("select", cfg, {});
546  }
547 
548  add_env_state_func<add_to_initial>(name, esf, update, times_pair,
549  select_cfg);
550  }
551 
553  void track_parameter(const std::string& key) {
554  if (_dsets_param.find(key) != _dsets_param.end()) {
555  throw std::invalid_argument("Parameter '" + key + "' is already "
556  "being tracked!");
557  }
558  _dsets_param.insert({key, this->create_dset(key, {})});
559  }
560 
562 
564  void track_parameters(const std::vector<std::string>& keys) {
565  for (const auto& key : keys) {
566  track_parameter(key);
567  }
568  }
569 
571  void track_state(const std::string& key) {
572  if (_dsets_state.find(key) != _dsets_state.end()) {
573  throw std::invalid_argument("State '" + key + "' is already "
574  "being tracked!");
575  }
576  _dsets_state.insert({key, this->create_cm_dset(key, _cm)});
577  }
578 
580 
582  void track_states(const std::vector<std::string>& keys) {
583  for (const auto& key : keys) {
584  track_state(key);
585  }
586  }
587 
588 private:
590  void setup_env_param_funcs(const Config& cfg) {
591  this->_log->info("Setting up environment param function sequence "
592  "from {} configuration entr{} ...",
593  cfg.size(), cfg.size() != 1 ? "ies" : "y");
594 
595  // For zombie or empty configurations, return empty container
596  if (not cfg or not cfg.size()) {
597  return;
598  }
599  // Otherwise, require a sequence
600  if (not cfg.IsSequence()) {
601  throw std::invalid_argument("The config for initializing the "
602  "environment functions must be a sequence!");
603  }
604 
605  // Iterate over the sequence of mappings
606  for (const auto& epfs : cfg) {
607  // epfs.IsMap() == true
608  // The top `epfs` keys are now the names of the desired environment
609  // functions. Iterate over those ...
610  for (const auto& epf_pair : epfs) {
611  // epf_pair is a pair of (key node, value node)
612  // Find out the name of the rule function
613  const auto epf_name = epf_pair.first.as<std::string>();
614 
615  this->_log->trace(" Function name: {}", epf_name);
616 
617  // Now iterate over the (param name, param cfg) pairs
618  for (const auto& kv_pair : epf_pair.second) {
619  // Get the parameter name and configuration
620  const auto param_name = kv_pair.first.as<std::string>();
621  const auto& epf_cfg = kv_pair.second;
622 
623  // Distinguish by name of rule function
624  if (epf_name == "increment") {
625  auto epf = epf_increment(*this, param_name, epf_cfg);
626  add_env_param_func_from_cfg(
627  epf_name+"."+param_name, epf, param_name, epf_cfg
628  );
629  }
630  else if (epf_name == "random") {
631  auto epf = epf_random(*this, param_name, epf_cfg);
632  add_env_param_func_from_cfg(
633  epf_name+"."+param_name, epf, param_name, epf_cfg
634  );
635  }
636  else if (epf_name == "rectangular") {
637  auto epf = epf_rectangular(*this, epf_cfg);
638  add_env_param_func_from_cfg(
639  epf_name+"."+param_name, epf, param_name, epf_cfg
640  );
641  }
642  else if (epf_name == "set") {
643  auto epf = epf_set(*this, epf_cfg);
644  add_env_param_func_from_cfg(
645  epf_name+"."+param_name, epf, param_name, epf_cfg
646  );
647  }
648  else if (epf_name == "sinusoidal") {
649  auto epf = epf_sinusoidal(*this, epf_cfg);
650  add_env_param_func_from_cfg(
651  epf_name+"."+param_name, epf, param_name, epf_cfg
652  );
653  }
654  // .. can add more rule functions here (alphabetic order).
655  // Add also in invalid_argument message below ..
656  else if (epf_name != "void") {
657  throw std::invalid_argument("No environment parameter "
658  "function '" + epf_name + "' available to "
659  "construct! Choose from: increment, random, "
660  "rectangular, set, sinusoidal.");
661  }
662 
663  this->_log->debug("Added '{}' environment parameter "
664  "function for parameter '{}'.", epf_name, param_name);
665  }
666  }
667  }
668  };
669 
671  template<bool add_to_initial=false>
672  void setup_env_state_funcs(const Config& cfg) {
673  this->_log->info("Setting up {}environment state function sequence "
674  "from {} configuration entr{} ...",
675  add_to_initial ? "initial " : "",
676  cfg.size(), cfg.size() != 1 ? "ies" : "y");
677 
678  // For zombie or empty configurations, return empty container
679  if (not cfg or not cfg.size()) {
680  return;
681  }
682  // Otherwise, require a sequence
683  if (not cfg.IsSequence()) {
684  throw std::invalid_argument("The config for initializing the "
685  "environment state functions must be a sequence!");
686  }
687 
688  // Iterate over the sequence of mappings
689  for (const auto& esfs : cfg) {
690  // esfs.IsMap() == true
691  // The top `esfs` keys are now the names of the desired environment
692  // functions. Iterate over those ...
693  for (const auto& esf_pair : esfs) {
694  // esf_pair is a pair of (key node, value node)
695  // Find out the name of the rule function
696  const auto esf_name = esf_pair.first.as<std::string>();
697 
698  this->_log->trace(" Function name: {}", esf_name);
699 
700  // Now iterate over the (param name, param cfg) pairs
701  for (const auto& kv_pair : esf_pair.second) {
702  // Get the parameter name and configuration
703  const auto param_name = kv_pair.first.as<std::string>();
704  const auto& esf_cfg = kv_pair.second;
705 
706  // Distinguish by name of rule function
707  if (esf_name == "noise") {
708  auto esf_update_pair = esf_noise(*this, param_name,
709  esf_cfg);
710  add_env_state_func_from_cfg<add_to_initial>(
711  "noise."+param_name, esf_update_pair.first,
712  esf_update_pair.second, esf_cfg
713  );
714  }
715  else if (esf_name == "slope") {
716  auto esf_update_pair = esf_slope(*this, param_name,
717  esf_cfg,
718  _cm.space()->extent);
719  add_env_state_func_from_cfg<add_to_initial>(
720  "slope."+param_name, esf_update_pair.first,
721  esf_update_pair.second, esf_cfg
722  );
723  }
724  else if (esf_name == "steps") {
725  auto esf_update_pair = esf_steps(*this, param_name,
726  esf_cfg);
727  add_env_state_func_from_cfg<add_to_initial>(
728  "steps."+param_name, esf_update_pair.first,
729  esf_update_pair.second, esf_cfg
730  );
731  }
732  else if (esf_name == "uniform") {
733  auto esf_update_pair = esf_uniform(*this, param_name,
734  esf_cfg);
735  add_env_state_func_from_cfg<add_to_initial>(
736  "uniform."+param_name, esf_update_pair.first,
737  esf_update_pair.second, esf_cfg
738  );
739  }
740  // .. can add more rule functions here ..
741  else if (esf_name != "void") {
742  throw std::invalid_argument("No environment state "
743  "function '" + esf_name + "' available to "
744  "construct! Choose from: noise, slope, steps, "
745  "uniform.");
746  }
747 
748  this->_log->trace("Added '{}' environment state"
749  "function for parameter '{}'.", esf_name, param_name);
750  }
751  }
752  }
753  };
754 
755 
757 
758  template<class EPFB>
759  void apply_env_param_func(EPFB&& epfb, bool initialization = false) {
760  // Check whether to invoke
761  if (initialization) {
762  if (not epfb.invoke_at_initialization) {
763  this->_log->trace("Not invoking environment function '{}' at "
764  "initialization.", epfb.name);
765  return;
766  }
767  }
768  else if (not epfb.invoke_always) {
769  // Compare to first element of the times set
770  // NOTE This approach has a low and constant complexity as no tree
771  // traversal in the set takes place. This, however, relies on
772  // the ordering of the set and that the first element is
773  // never smaller than (current time + 1), which would lead to
774  // clogging of the erasure ...
775  if ( epfb.times.size()
776  and *epfb.times.begin() == (this->_time + 1))
777  {
778  // Invoke at this time; pop element corresponding to this time
779  epfb.times.erase(epfb.times.begin());
780  }
781  else {
782  this->_log->trace("Not invoking environment function '{}' in "
783  "this iteration.", epfb.name);
784  return;
785  }
786  }
787 
788  this->_log->debug("Applying environment parameter function '{}' ...",
789  epfb.name);
790  this->_params.set_env(epfb.param_name, epfb.func());
791  }
792 
794 
795  template<class ESFB>
796  void apply_env_state_func(ESFB&& esfb) {
797  // Check whether to invoke
798  if (not esfb.invoke_always) {
799  // Compare to first element of the times set
800  // NOTE This approach has a low and constant complexity as no tree
801  // traversal in the set takes place. This, however, relies on
802  // the ordering of the set and that the first element is
803  // never smaller than (current time + 1), which would lead to
804  // clogging of the erasure ...
805  if ( esfb.times.size()
806  and *esfb.times.begin() == (this->_time + 1))
807  {
808  // Invoke at this time; pop element corresponding to this time
809  esfb.times.erase(esfb.times.begin());
810  }
811  else {
812  this->_log->trace("Not invoking environment function '{}' in "
813  "this iteration.", esfb.name);
814  return;
815  }
816  }
817 
818  this->_log->debug("Applying environment state function '{}' ...",
819  esfb.name);
820 
821  // get EnvCellContainer over which to apply the function
822  EnvCellContainer cell_selection = {};
823  if (esfb.fix_selection) {
824  cell_selection = esfb.cell_selection;
825  }
826  else if (not esfb.select_cfg.IsNull()) {
827  this->_log->debug("Generating a new selection of cells for "
828  "environment state function '{}' ...", esfb.name);
829  cell_selection = _cm.select_cells(esfb.select_cfg);
830  }
831  else {
832  cell_selection = _cm.cells();
833  }
834 
835  this->_log->debug("Applying to {} cells ...",
836  (cell_selection.size() == _cm.cells().size() ?
837  "all" : std::to_string(cell_selection.size())));
838 
839  // Need to distinguish by update mode
840  if (esfb.update == Update::sync) {
841  apply_rule<Update::sync>(esfb.func, cell_selection);
842  }
843  else if (esfb.update == Update::async) {
844  apply_rule<Update::async>(esfb.func, cell_selection, *this->_rng);
845  }
846  else {
847  // Throw in case the Update enum gets extended and an unexpected
848  // value is passed ...
849  throw std::invalid_argument("Unsupported `update` argument!");
850  }
851  }
852 
853  // .. Helper functions ....................................................
854 };
855 
856 // End group Environment
861 } // namespace Environment
862 } // namespace Models
863 } // namespace Utopia
864 
865 #endif // UTOPIA_MODELS_ENVIRONMENT_HH
const CellContainer< Cell > & cells() const
Return const reference to the managed CA cells.
Definition: cell_manager.hh:219
typename std::function< CellState(const std::shared_ptr< Cell > &)> RuleFunc
The type of a rule function acting on cells of this cell manager.
Definition: cell_manager.hh:84
CellContainer< Cell > select_cells(Args &&... args) const
Select cells using the Utopia::select_entities interface.
Definition: cell_manager.hh:342
SpaceVec barycenter_of(const Cell &cell) const
Returns the barycenter of the given cell.
Definition: cell_manager.hh:249
const std::shared_ptr< Space > & space() const
Return pointer to the space, for convenience.
Definition: cell_manager.hh:209
Base class interface for Models using the CRT Pattern.
Definition: model.hh:112
typename ModelTypes::DataSet DataSet
Data type that is used for storing data.
Definition: model.hh:125
typename ModelTypes::DataGroup DataGroup
Data type that is used for storing datasets.
Definition: model.hh:122
typename ModelTypes::Time Time
Data type for the model time.
Definition: model.hh:134
The Environment model provides a non-uniform, dynamic parameter background.
Definition: Environment.hh:140
std::vector< EnvParamFuncBundle > _env_param_funcs
Container of functions that are invoked every time step.
Definition: Environment.hh:202
CellManager _cm
The cell manager.
Definition: Environment.hh:195
std::vector< EnvStateFuncBundle > _init_env_state_funcs
Container of rule functions that are invoked once at initialisation.
Definition: Environment.hh:206
void add_env_state_func(ESFB &&esfb)
Add a rule function at the end of the sequence of state functions.
Definition: Environment.hh:469
typename Base::Time Time
The type of the model time.
Definition: Environment.hh:164
std::unordered_map< std::string, std::shared_ptr< DataSet > > _dsets_state
Dynamically generated map of datasets of cell states.
Definition: Environment.hh:214
typename Base::DataSet DataSet
Data type for a dataset.
Definition: Environment.hh:152
void setup_env_state_funcs(const Config &cfg)
Construct the rule funcs sequence from cfg.
Definition: Environment.hh:672
void setup_env_param_funcs(const Config &cfg)
Construct the rule funcs sequencefor EnvParam from cfg.
Definition: Environment.hh:590
typename Base::DataGroup DataGroup
Data type of the group to write model data to, holding datasets.
Definition: Environment.hh:149
DataIO::Config Config
Configuration node type alias.
Definition: Environment.hh:180
void monitor()
Monitor model information.
Definition: Environment.hh:379
void set_parameter(const std::string &param_name, double value)
Change the current value of the parameter with param_name.
Definition: Environment.hh:417
CellContainer< typename CellManager::Cell > EnvCellContainer
The type of the EnvCellContainer.
Definition: Environment.hh:161
EnvParam _params
The environment parameters.
Definition: Environment.hh:198
void apply_env_state_func(ESFB &&esfb)
Apply a given environment state function.
Definition: Environment.hh:796
const auto & cm() const
Return a const reference to the cell manager.
Definition: Environment.hh:422
std::vector< EnvStateFuncBundle > _env_state_funcs
Container of rule functions that are invoked every time step.
Definition: Environment.hh:210
void add_env_state_func_from_cfg(const std::string &name, const EnvStateFunc &esf, const Update &update=Update::sync, const Config &cfg={})
Add a rule function at the end of the sequence of environment functions.
Definition: Environment.hh:536
void add_env_param_func(EPFB &&epfb)
Add a rule function at the end of the sequence of parameter functions.
Definition: Environment.hh:432
void add_env_state_func(const std::string &name, const EnvStateFunc &esf, const Update &update=Update::sync, std::pair< bool, std::set< Time >> times_pair={true, {}}, Config select_cfg={})
Add a rule function at the end of the sequence of environment functions.
Definition: Environment.hh:488
typename std::function< double()> EnvParamFunc
The type of the environment parameter functions.
Definition: Environment.hh:167
void perform_step()
Iterate a single step.
Definition: Environment.hh:368
void track_parameters(const std::vector< std::string > &keys)
Track multiple parameters.
Definition: Environment.hh:564
void add_env_param_func(const std::string &name, const EnvParamFunc &epf, const std::string &param_name, std::tuple< bool, bool, std::set< Time >> times_tuple)
Add a param function at the end of the sequence of env functions.
Definition: Environment.hh:442
typename CellManager::RuleFunc EnvStateFunc
The type of the environment state functions; basically a rule function.
Definition: Environment.hh:173
double get_parameter(const std::string &param_name) const
Return the current value of the parameter with param_name.
Definition: Environment.hh:412
Environment(const std::string &name, ParentModel &parent_model, CellManager &&associate_cm, const DataIO::Config &custom_cfg={})
Construct the Environment model associated to a CellManager.
Definition: Environment.hh:233
void apply_env_param_func(EPFB &&epfb, bool initialization=false)
Apply a given environment parameter function.
Definition: Environment.hh:759
Environment(const std::string name, ParentModel &parent)
Construct Environment without associated CellManager.
Definition: Environment.hh:356
void write_data()
Write data.
Definition: Environment.hh:390
void track_state(const std::string &key)
Mark a state as being tracked, i.e. store its data in write_data.
Definition: Environment.hh:571
std::unordered_map< std::string, std::shared_ptr< DataSet > > _dsets_param
Dynamically generated map of datasets of parameters.
Definition: Environment.hh:217
void track_states(const std::vector< std::string > &keys)
Track multiple states.
Definition: Environment.hh:582
void track_parameter(const std::string &key)
Mark a parameter as being tracked, i.e. store its data in write_data.
Definition: Environment.hh:553
void add_env_param_func_from_cfg(const std::string &name, const EnvParamFunc &epf, const std::string &param_name, const Config &cfg={})
Add a param function at the end of the sequence of env functions.
Definition: Environment.hh:456
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition: types.hh:71
std::string to_string(const Config &node)
Given a config node, returns a string representation of it.
Definition: cfg_utils.hh:110
EnvParamFunc epf_sinusoidal(const EnvModel &model, const Config &cfg)
Creates a rule function for sinusoidal parameter values.
Definition: env_param_func_collection.hh:270
std::pair< EnvStateFunc, Update > esf_uniform(const EnvModel &, const std::string &param_name, const Config &cfg)
Creates a rule function for spatially uniform parameter values.
Definition: env_state_func_collection.hh:260
EnvParamFunc epf_random(const EnvModel &model, const std::string &param_name, const Config &cfg)
Creates a rule function for random parameter values.
Definition: env_param_func_collection.hh:106
EnvParamFunc epf_increment(const EnvModel &model, const std::string param_name, const Config &cfg)
Creates a rule function for incrementing parameter values.
Definition: env_param_func_collection.hh:73
std::pair< EnvStateFunc, Update > esf_steps(const EnvModel &, const std::string &param_name, const Config &cfg)
Creates a rule function for spatial steps in the parameter values.
Definition: env_state_func_collection.hh:201
EnvParamFunc epf_rectangular(const EnvModel &model, const Config &cfg)
Creates a rule function for rectangular function like parameter values.
Definition: env_param_func_collection.hh:181
std::pair< EnvStateFunc, Update > esf_slope(const EnvModel &, const std::string &param_name, const Config &cfg, const Extent &extent)
Creates a rule function for spatially linearly parameter values.
Definition: env_state_func_collection.hh:151
EnvParamFunc epf_set(const EnvModel &, const Config &cfg)
Creates a rule function for setting a parameter value.
Definition: env_param_func_collection.hh:236
std::pair< EnvStateFunc, Update > esf_noise(const EnvModel &model, const std::string &param_name, const Config &cfg)
Creates a rule function for noisy parameter values.
Definition: env_state_func_collection.hh:77
Update
Update modes when applying rules.
Definition: state.hh:20
@ async
Asynchronous update.
@ sync
Synchronous update.
DataIO::Config Config
Configuration node type alias.
Definition: env_param_func_collection.hh:13
Definition: agent.hh:11
arma::Col< double >::fixed< dim > SpaceVecType
Type for vector-like data that is associated with a physical space.
Definition: types.hh:61
EntityContainer< CellType > CellContainer
Type of the variably sized container for cells.
Definition: types.hh:26
A non-abstract EnvCellState, derived from the base class.
Definition: Environment.cc:50
A non-abstract EnvParam, derived from the base class.
Definition: Environment.cc:11
double get_env(const std::string &key) const override
Getter.
Definition: Environment.cc:23
void set_env(const std::string &key, const double &value) override
Setter.
Definition: Environment.cc:32
The entity traits struct gathers types to be used for specializing an entity.
Definition: entity.hh:49
Wrapper struct for defining model class data types.
Definition: model.hh:92
Base type for environment cell states.
Definition: Environment.hh:82
virtual void set_env(const std::string &, const double &)=0
Set an environment variable.
virtual double get_env(const std::string &) const =0
Get an environment variable.
SpaceVec position
Cached barycenter of the cell.
Definition: Environment.hh:86
SpaceVecType< 2 > SpaceVec
Definition: Environment.hh:83
Base type for environment parameter.
Definition: Environment.hh:45
virtual double get_env(const std::string &) const =0
Get an environment variable.
virtual void set_env(const std::string &, const double &)=0
Set an environment variable.
Dummy type for environment cell states.
Definition: Environment.hh:102
double get_env(const std::string &) const override
Getter.
Definition: Environment.hh:108
void set_env(const std::string &, const double &) override
Setter.
Definition: Environment.hh:114
DummyEnvCellState(const DataIO::Config &)
Definition: Environment.hh:103
Dummy type for environment parameter.
Definition: Environment.hh:60
double get_env(const std::string &) const override
Getter.
Definition: Environment.hh:66
DummyEnvParam(const DataIO::Config &)
Definition: Environment.hh:61
void set_env(const std::string &, const double &) override
Setter.
Definition: Environment.hh:72
A dummy CellManager type that is used in standalone mode.
Definition: Environment.hh:184
DataIO::Config cfg() const
Always returns an empty node.
Definition: Environment.hh:186
A bundle wrapping a (iterative) function with metadata.
Definition: func_bundle.hh:42
A bundle wrapping a (rule-)function with metadata.
Definition: func_bundle.hh:71