1#ifndef UTOPIA_CORE_MODEL_HH
2#define UTOPIA_CORE_MODEL_HH
13#include "../data_io/hdffile.hh"
14#include "../data_io/hdfgroup.hh"
15#include "../data_io/cfg_utils.hh"
16#include "../data_io/monitor.hh"
17#include "../data_io/data_manager/data_manager.hh"
18#include "../data_io/data_manager/factory.hh"
110template<
class Derived,
typename ModelTypes>
161 const std::shared_ptr<RNG>
_rng;
164 const std::shared_ptr<spdlog::logger>
_log;
202 template<
class Parent>
204 auto log = spdlog::stdout_color_mt(
209 if (
_cfg[
"log_level"]) {
212 log->debug(
"Setting log level to '{}' ...",
lvl);
213 log->set_level(spdlog::level::from_str(
lvl));
220 log->info(
"Model logger initialized.");
227 auto space = std::make_shared<Space>(
_cfg[
"space"]);
229 "Using {}periodic space with extent {}.",
230 space->periodic ?
"" :
"non-",
Utils::str(space->extent)
236 "No model-level space configured; using default space."
238 return std::make_shared<Space>();
271 const std::string& name,
275 const DataIO::Default::DefaultDecidermap< Derived >&
276 w_deciders = DataIO::Default::default_deciders< Derived >,
277 const DataIO::Default::DefaultTriggermap< Derived >&
278 w_triggers = DataIO::Default::default_triggers< Derived >
316 _log->info(
"Model base constructor for '{}' finished.",
_name);
322 _log->info(
" write_mode: {:>7s}",
"basic");
328 _hdfgrp->add_attribute(
"write_mode",
"basic");
334 _log->info(
" write_mode: {:>7s}",
"manual");
335 _hdfgrp->add_attribute(
"write_mode",
"manual");
338 _log->info(
" write_mode: {:>7s}",
"off");
339 _hdfgrp->add_attribute(
"write_mode",
"off");
342 static_assert(
sizeof...(WriterArgs) > 0,
343 "No arguments to construct write_tasks given!");
345 _log->info(
" write_mode: {:>7s}",
"managed");
348 _hdfgrp->add_attribute(
"write_mode",
"managed");
351 if (
not _cfg[
"data_manager"]) {
352 throw KeyError(
"data_manager",
_cfg,
353 "Cannot set up DataManager!");
358 throw KeyError(
"tasks",
dm_cfg,
359 "Cannot set up DataManager tasks!");
362 throw KeyError(
"deciders",
dm_cfg,
363 "Cannot set up DataManager deciders!");
366 throw KeyError(
"triggers",
dm_cfg,
367 "Cannot set up DataManager triggers!");
370 _log->info(
"Invoking DataManager task factory ...");
376 _log->info(
"DataManager set up with {} task(s), {} decider(s), "
404 if (
_time_max == std::numeric_limits<Time>::max()) {
405 this->_log->warn(
"Accessing the `time_max` of (sub-)model {} with "
461 if (
_time_max == std::numeric_limits<hsize_t>::max()) {
462 return std::numeric_limits<hsize_t>::max();
469 return std::numeric_limits<hsize_t>::max();
496 return _monitor.get_monitor_manager();
540 _monitor.get_monitor_manager()->check_timer();
547 _monitor.get_monitor_manager()->emit_if_enabled();
571 _log->debug(
"Finished iteration: {:7d}",
_time);
583 throw std::runtime_error(fmt::format(
"Cannot perform run on "
584 "(sub-)model {} with unlimited `time_max`. You need to provide "
585 "`num_steps` to the model's configuration in order to use the "
586 "`run` method. See the nested models guide for further "
598 _log->info(
"Running from current time {} to {} ...",
608 _log->warn(
"The stop condition for this run is fulfilled. "
609 "Not iterating further ...");
612 _log->warn(
"Was told to stop. Not iterating further ...");
615 _log->info(
"Invoking epilog ...");
622 _log->info(
"Run finished. Current time: {}",
_time);
634 impl().perform_step();
643 if (
_monitor.get_monitor_manager()->emit_enabled()) {
661 _log->trace(
"Calling write_data ...");
671 _log->info(
"Writing initial state ...");
698 this->_log->debug(
"Prolog finished.");
706 this->_log->debug(
"Epilog finished.");
713 return static_cast<Derived&
>(*this);
718 return static_cast<const Derived&
>(*this);
751 std::shared_ptr<DataSet>
753 const std::shared_ptr<DataGroup>&
hdfgrp,
758 _log->debug(
"Creating dataset '{}' in group '{}' ...",
759 name,
hdfgrp->get_path());
769 const auto dset =
hdfgrp->open_dataset(name, capacity,
771 _log->debug(
"Successfully created dataset '{}'.", name);
777 dset->add_attribute(
"dim_name__0",
"time");
778 dset->add_attribute(
"coords_mode__time",
"start_and_step");
779 dset->add_attribute(
"coords__time",
782 _log->debug(
"Added time dimension labels and coordinates to "
783 "dataset '{}'.", name);
814 std::shared_ptr<DataSet>
847 template<
class CellManager>
848 std::shared_ptr<DataSet>
864 dset->add_attribute(
"content",
"grid");
869 dset->add_attribute(
"grid_shape", cm.
grid()->shape());
870 dset->add_attribute(
"space_extent", cm.
grid()->space()->extent);
871 dset->add_attribute(
"periodic_space", cm.
grid()->space()->periodic);
876 dset->add_attribute(
"coordinate_mode",
"offset");
877 dset->add_attribute(
"offset_mode",
"even");
878 dset->add_attribute(
"pointy_top",
true);
883 dset->add_attribute(
"index_order",
"F");
885 _log->debug(
"Added attributes to dataset '{}' to mark it as storing "
893 dset->add_attribute(
"dim_name__1",
"ids");
896 dset->add_attribute(
"coords_mode__ids",
"range");
897 dset->add_attribute(
"coords__ids",
898 std::vector<std::size_t>{cm.
cells().size()});
900 _log->debug(
"Added cell ID dimension labels and coordinates to "
901 "dataset '{}'.", name);
937 template<
class AgentManager>
938 std::shared_ptr<DataSet>
942 const std::vector<hsize_t>
chunksize = {})
948 {
am.agents().size()},
954 dset->add_attribute(
"space_extent",
am.space()->extent);
955 _log->debug(
"Added attribute to dataset '{}' to store space extent",
964 dset->add_attribute(
"dim_name__1",
"ids");
967 dset->add_attribute(
"coords_mode__ids",
"trivial");
969 _log->debug(
"Added agent index dimension labels and coordinates "
970 "to dataset '{}'.", name);
991 _log->debug(
"Attaching signal handlers for SIGINT and SIGTERM ...");
996 _log->debug(
"Attaching signal handler for stop conditions, triggered "
997 "by SIGUSR1 ({:d}) ...",
SIGUSR1);
1000 _log->debug(
"Signal handlers attached.");
1015template<
typename RNG=DefaultRNG>
1046 const std::shared_ptr<spdlog::logger>
_log;
1088 _log->info(
"Initialized PseudoParent from config file");
1093 _log->debug(
"emit_interval: {}s",
1130 _log->info(
"Initialized PseudoParent from parameters");
1132 _log->debug(
"output_path: {} (mode: {})",
1219 spdlog::level::from_str(
1222 spdlog::level::from_str(
1225 spdlog::level::from_str(
1236 _cfg[
"log_levels"]))
The agent manager manages the agents living in a model.
Definition agent_manager.hh:31
Manages a physical space, its grid discretization, and cells on that grid.
Definition cell_manager.hh:41
const std::shared_ptr< GridType > & grid() const
Return const reference to the grid.
Definition cell_manager.hh:214
const CellContainer< Cell > & cells() const
Return const reference to the managed CA cells.
Definition cell_manager.hh:219
Manage different tasks of writing out data from a source in a uniform yet flexible way....
Definition data_manager.hh:131
TriggerMap & get_triggers()
Get the container of trigger objects.
Definition data_manager.hh:493
DeciderMap & get_deciders()
Get the container of decider objects.
Definition data_manager.hh:471
TaskMap & get_tasks()
Get the container of task objects.
Definition data_manager.hh:482
Class representing a HDFDataset, wich reads and writes data and attributes.
Definition hdfdataset.hh:53
Class representing a HDF5 file.
Definition hdffile.hh:62
Class represting a HDFGroup, an object analogous to a folder for HDFFiles.
Definition hdfgroup.hh:41
The Monitor monitors entries that are emitted if a given time has passed.
Definition monitor.hh:323
The MonitorManager manages the monitor entries and MonitorTimer.
Definition monitor.hh:159
An exception for when the program should end due to handling of a signal.
Definition exceptions.hh:51
Base class interface for Models using the CRT Pattern.
Definition model.hh:112
void __prolog()
The default prolog of a model.
Definition model.hh:695
DataManager get_datamanager() const
return the datamanager
Definition model.hh:442
std::shared_ptr< DataSet > create_cm_dset(const std::string name, const CellManager &cm, const std::size_t compression_level=1, const std::vector< hsize_t > chunksize={})
Create a dataset storing data from a CellManager.
Definition model.hh:849
auto setup_logger(const Parent &parent_model) const
Constructs this models logger instance from the parent.
Definition model.hh:203
auto setup_space() const
Constructs the Space from configuration or uses the default Space.
Definition model.hh:225
typename ModelTypes::MonitorManager MonitorManager
Data type for the monitor manager.
Definition model.hh:140
typename ModelTypes::Level Level
Data type for the hierarchical level.
Definition model.hh:143
const std::shared_ptr< DataGroup > _hdfgrp
The HDF group this model instance should write its data to.
Definition model.hh:176
void __write_initial_state()
Write the initial state.
Definition model.hh:666
DataManager _datamanager
Manager object for handling data output; see DataManager.
Definition model.hh:194
std::shared_ptr< DataGroup > get_hdfgrp() const
Return a pointer to the HDF group this model stores data in.
Definition model.hh:427
std::shared_ptr< spdlog::logger > get_logger() const
Return a pointer to the logger of this model.
Definition model.hh:485
std::shared_ptr< MonitorManager > get_monitor_manager() const
Get the monitor manager of the root model.
Definition model.hh:495
Monitor _monitor
The monitor.
Definition model.hh:188
void run()
Run the model from the current time to the maximum time.
Definition model.hh:581
void iterate()
Iterate one (time) step of this model.
Definition model.hh:527
void __attach_sig_handlers() const
Attaches signal handlers: SIGINT, SIGTERM, SIGUSR1.
Definition model.hh:990
Monitor get_monitor() const
Return the monitor of this model.
Definition model.hh:490
const Time _write_start
First time at which write_data is called.
Definition model.hh:182
Time get_time_max() const
Return the maximum time possible for this model.
Definition model.hh:403
const Derived & impl() const
const cast to the derived interface
Definition model.hh:717
typename ModelTypes::DataSet DataSet
Data type that is used for storing data.
Definition model.hh:125
const Config _cfg
Config node belonging to this model instance.
Definition model.hh:158
const Time _write_every
How often to call write_data from iterate.
Definition model.hh:185
std::shared_ptr< DataSet > create_dset(const std::string name, const std::vector< hsize_t > add_write_shape, const std::size_t compression_level=1, const std::vector< hsize_t > chunksize={})
Create a new dataset within the model's base data group.
Definition model.hh:815
Time _time
Model-internal current time stamp.
Definition model.hh:170
typename ModelTypes::Space Space
Data type of the space this model resides in.
Definition model.hh:131
const std::string _name
Name of the model instance.
Definition model.hh:149
std::string get_full_name() const
Return the full name of this model within the model hierarchy.
Definition model.hh:422
std::string get_name() const
Return the name of this model instance.
Definition model.hh:417
Time get_time() const
Return the current time of this model.
Definition model.hh:393
Derived & impl()
cast to the derived class
Definition model.hh:712
void __monitor()
Monitor information in the terminal.
Definition model.hh:642
const Time _time_max
Model-internal maximum time stamp.
Definition model.hh:173
void __perform_step()
Perform the computation of a step.
Definition model.hh:633
Model(const std::string &name, const ParentModel &parent_model, const Config &custom_cfg={}, std::tuple< WriterArgs... > w_args={}, const DataIO::Default::DefaultDecidermap< Derived > &w_deciders=DataIO::Default::default_deciders< Derived >, const DataIO::Default::DefaultTriggermap< Derived > &w_triggers=DataIO::Default::default_triggers< Derived >)
Constructs a Model instance.
Definition model.hh:270
void __write_data()
Write data; calls the implementation's write_data method.
Definition model.hh:660
hsize_t get_remaining_num_writes() const
Return the number of remaining write_data calls this model will make.
Definition model.hh:452
virtual void epilog()
A function that is called after the last iteration of a model.
Definition model.hh:516
Config get_cfg() const
Return the config node of this model.
Definition model.hh:412
Time get_write_start() const
Return the parameter that controls when write_data is called first.
Definition model.hh:432
Level get_level() const
Return the hierarchical level within the model hierarchy.
Definition model.hh:500
const Level _level
The level within the model hierarchy.
Definition model.hh:155
typename ModelTypes::DataGroup DataGroup
Data type that is used for storing datasets.
Definition model.hh:122
virtual void prolog()
A function that is called before starting model iteration.
Definition model.hh:509
void __epilog()
The default epilog of a model.
Definition model.hh:705
typename ModelTypes::Time Time
Data type for the model time.
Definition model.hh:134
typename ModelTypes::Config Config
Data type that holds the configuration.
Definition model.hh:116
typename ModelTypes::Monitor Monitor
Data type for the monitor.
Definition model.hh:137
std::shared_ptr< DataSet > create_am_dset(const std::string name, const AgentManager &am, const std::size_t compression_level=1, const std::vector< hsize_t > chunksize={})
Create a dataset storing data from a AgentManager.
Definition model.hh:939
typename ModelTypes::RNG RNG
Data type of the shared RNG.
Definition model.hh:128
Time get_write_every() const
Return the parameter that controls how often write_data is called.
Definition model.hh:437
const std::string _full_name
The full name within the model hierarchy.
Definition model.hh:152
std::shared_ptr< RNG > get_rng() const
Return a pointer to the shared RNG.
Definition model.hh:480
const std::shared_ptr< spdlog::logger > _log
The (model) logger.
Definition model.hh:164
void increment_time(const Time dt=1)
Increment time.
Definition model.hh:687
static constexpr WriteMode _write_mode
Which data-writing mode the base model should use.
Definition model.hh:179
const std::shared_ptr< RNG > _rng
The RNG shared between models.
Definition model.hh:161
std::shared_ptr< DataSet > create_dset(const std::string name, const std::shared_ptr< DataGroup > &hdfgrp, std::vector< hsize_t > add_write_shape, const std::size_t compression_level=1, const std::vector< hsize_t > chunksize={})
Create a new dataset within the given group.
Definition model.hh:752
const std::shared_ptr< Space > & get_space() const
Return the space this model resides in.
Definition model.hh:388
std::shared_ptr< Space > _space
The space this model resides in.
Definition model.hh:167
static void init(const DataIO::Config &cfg)
Initialize parallel features based on configuration setting.
Definition parallel.hh:113
A class to use at the top level of the model hierarchy as a mock parent.
Definition model.hh:1017
std::shared_ptr< MonitorManager > get_monitor_manager() const
Return the monitor manager of this model.
Definition model.hh:1196
Utopia::DataIO::Config Config
Definition model.hh:1019
Monitor _monitor
The monitor instance of this root model.
Definition model.hh:1052
void set_log_level() const
Set the log level for the pseudo parent from the base_cfg.
Definition model.hh:1233
std::size_t Level
Definition model.hh:1028
std::shared_ptr< HDFFile > get_hdffile() const
Return a pointer to the HDF data file.
Definition model.hh:1158
const Config _cfg
The config node.
Definition model.hh:1034
Level get_level() const
Return the hierarchical level within the model hierarchy.
Definition model.hh:1143
const std::shared_ptr< RNG > _rng
Pointer to a RNG that can be shared between models.
Definition model.hh:1040
const Monitor & get_monitor() const
Return the monitor of this model.
Definition model.hh:1201
const std::shared_ptr< spdlog::logger > _log
Pointer to the logger of this (pseudo) model.
Definition model.hh:1046
std::shared_ptr< HDFGroup > get_hdfgrp() const
Return a pointer to the HDF group, which is the base group of the file.
Definition model.hh:1163
Time get_time_max() const
The maximum time value as it can be found in the config.
Definition model.hh:1191
const std::shared_ptr< MonitorManager > _monitor_mgr
The monitor manager.
Definition model.hh:1049
Time get_write_start() const
Return the parameter that controls when write_data is called first.
Definition model.hh:1168
PseudoParent(const std::string cfg_path, const std::string output_path, const int seed=42, const std::string output_file_mode="w", const double emit_interval=5.)
Constructor that allows granular control over config parameters.
Definition model.hh:1106
PseudoParent(const std::string cfg_path)
Constructor that only requires path to a config file.
Definition model.hh:1063
std::size_t Time
Definition model.hh:1027
Time get_write_every() const
Return the parameter that controls how often write_data is called.
Definition model.hh:1173
const Level _level
The hierarchical level.
Definition model.hh:1031
void setup_loggers() const
Set up the global loggers with levels specified in the config file.
Definition model.hh:1217
std::shared_ptr< RNG > get_rng() const
Return a pointer to the RNG.
Definition model.hh:1178
std::string get_full_name() const
Return the full name of the PseudoParent: an empty string.
Definition model.hh:1148
const std::shared_ptr< HDFFile > _hdffile
Pointer to the HDF5 file where data is written to.
Definition model.hh:1037
Config get_cfg() const
Return the config node of the Pseudo model, i.e. the root node.
Definition model.hh:1153
std::shared_ptr< spdlog::logger > get_logger() const
Return a pointer to the logger of this model.
Definition model.hh:1183
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition types.hh:71
ReturnType get_as(const std::string &key, const DataIO::Config &node)
This function is a wrapper around the yaml-cpp YAML::Node::as function.
Definition cfg_utils.hh:158
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition select.hh:213
std::shared_ptr< spdlog::logger > init_logger(const std::string name, const spdlog::level::level_enum level, const bool throw_on_exist=true)
Initialize a logger with a certain name and log level.
Definition logging.hh:31
void setup_loggers(const spdlog::level::level_enum level_core=spdlog::level::warn, const spdlog::level::level_enum level_data_io=spdlog::level::warn, const spdlog::level::level_enum level_data_mngr=spdlog::level::warn, const std::string &log_pattern="")
Set up and register the global loggers and set the global log pattern.
Definition logging.hh:66
WriteMode
How to write data in the models.
Definition model.hh:30
constexpr WriteMode DefaultWriteMode
Alias for the default write mode.
Definition model.hh:64
Space< 2 > DefaultSpace
The default Space object to be used throughout Utopia.
Definition space.hh:220
@ off
The write_data method is never called.
@ manual
Fully manual: write_data method is always called.
@ managed
Use the DataManager to handle output.
@ basic
Basic writing features: write_start, write_every.
@ off
Immediately apply the rule sequentially.
std::string str(T &&t)
Turn any object for which operator<< exists into a string. Mostly useful for logging data via spdlog ...
Definition ostream.hh:164
std::atomic< bool > stop_now
The flag indicating whether to stop whatever is being done right now.
Definition signal.hh:15
std::mt19937 DefaultRNG
Type of default random number generator.
Definition types.hh:17
std::atomic< int > received_signum
The received signal value.
Definition signal.hh:18
void attach_signal_handler(int signum, Handler &&handler)
Attaches a signal handler for the given signal via sigaction.
Definition signal.hh:35
Definition parallel.hh:235
Wrapper struct for defining model class data types.
Definition model.hh:92
ConfigType Config
Definition model.hh:96
TimeType Time
Definition model.hh:99
static constexpr WriteMode write_mode
Definition model.hh:94
std::size_t Level
Definition model.hh:102
RNGType RNG
Definition model.hh:93
MonitorManagerType MonitorManager
Definition model.hh:101
DataSetType DataSet
Definition model.hh:98
MonitorType Monitor
Definition model.hh:100
SpaceType Space
Definition model.hh:95
DataGroupType DataGroup
Definition model.hh:97