1 #ifndef UTOPIA_CORE_AGENTMANAGER_HH
2 #define UTOPIA_CORE_AGENTMANAGER_HH
30 template<
class AgentTraits,
class Model>
70 using VoidRuleFunc = std::function<void(
const std::shared_ptr<Agent>&)>;
82 const std::shared_ptr<spdlog::logger>
_log;
88 const std::shared_ptr<RNG>
_rng;
133 _log->info(
"AgentManager is all set up.");
159 _log->info(
"AgentManager is all set up.");
164 const auto&
log ()
const {
174 const std::shared_ptr<RNG>&
rng ()
const {
179 const std::shared_ptr<Space>&
space ()
const {
200 void move_to(
const std::shared_ptr<Agent>& agent,
214 void move_by(
const std::shared_ptr<Agent>& agent,
259 const Config& custom_cfg = {})
263 if (custom_cfg.size()) {
264 throw std::runtime_error(
"custom_cfg was passed but "
265 "AgentTraits specified use of default constructor!");
275 if (custom_cfg.size()) {
283 if constexpr (std::is_constructible<
AgentState,
285 const std::shared_ptr<RNG>&
311 const auto it = std::find(
_agents.cbegin(),
_agents.cend(), agent);
314 throw std::invalid_argument(
"The given agent is not handled by "
318 _log->trace(
"Removing agent with ID {:d} ...", agent->id());
331 template<
typename UnaryPredicate>
352 "The update_agents method only makes sense to call when agents "
353 "are set to be updated synchronously, which is not the case! "
354 "Either adapt the AgentTraits to that update mode or remove the "
355 "call to the update_agents method.");
358 for (
const auto& agent :
_agents){
375 return select_entities<mode>(*
this, std::forward<Args>(args)...);
401 const std::shared_ptr<Agent>& b)
const
403 return this->_space->displacement(a->position(), b->position());
409 template<
class NormType=std::
size_t>
411 const std::shared_ptr<Agent>& b,
412 const NormType p = 2)
const
414 return this->_space->distance(a->position(), b->position(), p);
435 const double radius)
const
438 for (
const auto& a :
agents()) {
439 if (
distance(a, agent) <= radius and a != agent) {
455 std::uniform_real_distribution<double> dist(0., 1.);
456 return ( this->_space->extent
457 %
SpaceVec().imbue([
this,&dist](){
return dist(*this->_rng);}));
469 if (custom_cfg.size() > 0) {
470 _log->debug(
"Using custom config for agent manager setup ...");
474 _log->debug(
"Using '{}' model's configuration for agent manager "
477 if (not model.
get_cfg()[
"agent_manager"]) {
478 throw std::invalid_argument(
"Missing config entry "
479 "'agent_manager' in model configuration! Either specify "
480 "that key or pass a custom configuration node to the "
481 "AgentManager constructor.");
492 std::string initial_pos_mode =
"random";
495 if (
_cfg[
"initial_position"]) {
496 initial_pos_mode = get_as<std::string>(
"initial_position",
_cfg);
500 if (initial_pos_mode ==
"random") {
504 throw std::invalid_argument(
"AgentManager got an invalid "
505 "configuration entry for 'initial_position': '"
506 + initial_pos_mode +
"'. Valid options are: 'random'");
521 if (not
_cfg[
"initial_num_agents"]) {
522 throw std::invalid_argument(
"AgentManager is missing the "
523 "configuration entry 'initial_num_agents' that specifies the "
524 "number of agents to set up!");
526 const auto num_agents = get_as<IndexType>(
"initial_num_agents",
_cfg);
536 _log->info(
"Populated agent container with {:d} agents.",
563 static_assert(std::is_default_constructible<AgentState>(),
564 "AgentTraits were configured to use the default constructor "
565 "to create agent states, but the AgentState is not "
566 "default-constructible! Either implement such a constructor, "
567 "unset the flag in the AgentTraits, or pass an explicit "
568 "initial agent state to the AgentManager.");
570 _log->info(
"Setting up agents using default constructor ...");
577 else if constexpr (std::is_constructible<
AgentState,
579 const std::shared_ptr<RNG>&
582 _log->info(
"Setting up agents using config constructor (with RNG) "
586 if (not
_cfg[
"agent_params"]) {
587 throw std::invalid_argument(
"AgentManager is missing the "
588 "configuration entry 'agent_params' to set up the agents' "
591 const auto agent_params =
_cfg[
"agent_params"];
593 if (not
_cfg[
"initial_num_agents"]){
594 throw std::invalid_argument(
"AgentManager is missing the "
595 "configuration entry 'initial_num_agents' to set up the "
599 const auto initial_num_agents =
600 get_as<IndexType>(
"initial_num_agents",
_cfg);
603 for (
IndexType i=0; i<initial_num_agents; i++) {
610 _log->info(
"Populated agent container with {:d} agents.",
616 static_assert(std::is_constructible<
AgentState,
618 "AgentManager::AgentState needs to be constructible using "
619 "const DataIO::Config& as only argument. Either implement "
620 "such a constructor, pass an explicit initial agent state to "
621 "the AgentManager, or set the AgentTraits such that a default "
622 "constructor is to be used.");
624 _log->info(
"Setting up agents using config constructor ...");
627 if (not
_cfg[
"agent_params"]) {
628 throw std::invalid_argument(
"AgentManager is missing the "
629 "configuration entry 'agent_params' to set up the agents' "
652 agent.set_pos(this->_space->map_into_space(pos));
658 if (not this->_space->contains(pos)) {
660 "Could not move agent!");
684 return this->_space->map_into_space(pos);
691 if (not
_space->contains(pos)) {
693 "Given position is out of space!");
An agent is a slightly specialized state container.
Definition: agent.hh:47
The agent manager manages the agents living in a model.
Definition: agent_manager.hh:31
void move_by(const std::shared_ptr< Agent > &agent, const SpaceVec &move_vec) const
Move an agent relative to its current position.
Definition: agent_manager.hh:214
AgentContainer< Agent > select_agents(const Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition: agent_manager.hh:388
void update_agents()
Update the agents.
Definition: agent_manager.hh:349
std::function< SpaceVec(const SpaceVec &)> PosFunc
The type of the function that prepares the position of a new agent.
Definition: agent_manager.hh:58
void setup_agents()
Set up agents container via config or default constructor.
Definition: agent_manager.hh:559
MoveFunc _move_to_func
Function that will be used for moving agents, called by move_* methods.
Definition: agent_manager.hh:97
IndexType id_counter() const
Return the ID counter.
Definition: agent_manager.hh:194
typename AgentTraits::State AgentState
The type of the agent state.
Definition: agent_manager.hh:46
const AgentContainer< Agent > & entities() const
Return const reference to the entities managed by this manager: agents.
Definition: agent_manager.hh:189
SpaceVec random_pos() const
Returns a valid (uniformly) random position in space.
Definition: agent_manager.hh:451
AgentContainer< Agent > neighbors_of(const std::shared_ptr< Agent > &agent, const double radius) const
Returns a container of all agents within a certain radius.
Definition: agent_manager.hh:434
const DataIO::Config & cfg() const
Return the configuration used for building this AgentManager.
Definition: agent_manager.hh:169
void erase_agent_if(UnaryPredicate &&condition)
Remove agents if the given condition is met.
Definition: agent_manager.hh:332
const std::shared_ptr< RNG > _rng
The model's random number generator.
Definition: agent_manager.hh:88
void remove_agent(const std::shared_ptr< Agent > &agent)
Removes the given agent from the agent manager.
Definition: agent_manager.hh:309
SpaceVec displacement(const std::shared_ptr< Agent > &a, const std::shared_ptr< Agent > &b) const
Returns the (shortest) displacement vector between two agents.
Definition: agent_manager.hh:400
AgentContainer< Agent > select_agents(Args &&... args)
Select agents using the Utopia::select_entities interface.
Definition: agent_manager.hh:374
double distance(const std::shared_ptr< Agent > &a, const std::shared_ptr< Agent > &b, const NormType p=2) const
Returns the (shortest) distance between two agents.
Definition: agent_manager.hh:410
AgentManager(const Model &model, const DataIO::Config &custom_cfg={})
Construct an agent manager.
Definition: agent_manager.hh:120
IndexType _id_counter
Counts the number of agents created with this manager, used for new IDs.
Definition: agent_manager.hh:79
SpaceVecType< dim > SpaceVec
The type of the vectors that represent physical quantities.
Definition: agent_manager.hh:52
const std::shared_ptr< RNG > & rng() const
Return a reference to the shared random number generator.
Definition: agent_manager.hh:174
const std::shared_ptr< Agent > & add_agent(const SpaceVec &pos, const Config &custom_cfg={})
add_agent overload for auto-constructed agent states
Definition: agent_manager.hh:258
std::function< void(const std::shared_ptr< Agent > &)> VoidRuleFunc
The type of a void rule function acting on agents of this agent manager.
Definition: agent_manager.hh:70
AgentContainer< Agent > _agents
Storage container for agents.
Definition: agent_manager.hh:94
PosFunc _prepare_pos
Function that will be used to prepare positions for adding an agent.
Definition: agent_manager.hh:100
const auto & log() const
Definition: agent_manager.hh:164
PosFunc setup_prepare_pos_func() const
Definition: agent_manager.hh:679
AgentManager(const Model &model, const AgentState initial_state, const DataIO::Config &custom_cfg={})
Construct an agent manager, using the same initial state for all agents.
Definition: agent_manager.hh:145
typename Model::RNG RNG
The random number generator type.
Definition: agent_manager.hh:73
void setup_agents(const AgentState &initial_state)
Set up the manager's agent container with initial states.
Definition: agent_manager.hh:519
const std::shared_ptr< Space > & space() const
Return pointer to the space, for convenience.
Definition: agent_manager.hh:179
const std::shared_ptr< Agent > & add_agent(const AgentState &state, const SpaceVec &pos)
Create an agent and associate it with this AgentManager.
Definition: agent_manager.hh:236
void move_to(const std::shared_ptr< Agent > &agent, const SpaceVec &pos) const
Move an agent to a new position in the space.
Definition: agent_manager.hh:200
const std::shared_ptr< spdlog::logger > _log
The logger (same as the model this manager resides in)
Definition: agent_manager.hh:82
static constexpr DimType dim
The dimensionality of the space.
Definition: agent_manager.hh:49
void move_to(Agent &agent, const SpaceVec &pos) const
Move an agent to a new position in the space.
Definition: agent_manager.hh:207
const AgentContainer< Agent > & agents() const
Return const reference to the managed agents.
Definition: agent_manager.hh:184
const DataIO::Config _cfg
Agent manager configuration node.
Definition: agent_manager.hh:85
void move_by(Agent &agent, const SpaceVec &move_vec) const
Move an agent relative to its current position.
Definition: agent_manager.hh:221
const std::shared_ptr< Space > _space
The physical space the agents are to reside in.
Definition: agent_manager.hh:91
const std::shared_ptr< Agent > & add_agent(const Config &custom_cfg={})
add_agent overload for auto constructed states and random position
Definition: agent_manager.hh:303
MoveFunc setup_move_to_func() const
Depending on periodicity, return the function to move agents in space.
Definition: agent_manager.hh:647
std::function< AgentState(const std::shared_ptr< Agent > &)> RuleFunc
The type of a rule function acting on agents of this agent manager.
Definition: agent_manager.hh:64
std::function< void(Agent &, const SpaceVec &)> MoveFunc
The type of the move function type.
Definition: agent_manager.hh:55
SpaceVec initial_agent_pos()
Setup helper used to determine a single agent's initial position.
Definition: agent_manager.hh:490
Config setup_cfg(const Model &model, const Config &custom_cfg)
Set up the agent manager configuration member.
Definition: agent_manager.hh:466
Utopia::Agent< AgentTraits, Space > Agent
The type of the managed agents.
Definition: agent_manager.hh:40
typename Model::Space Space
The type of the space.
Definition: agent_manager.hh:37
Base class interface for Models using the CRT Pattern.
Definition: model.hh:112
std::shared_ptr< spdlog::logger > get_logger() const
Return a pointer to the logger of this model.
Definition: model.hh:485
typename ModelTypes::Space Space
Data type of the space this model resides in.
Definition: model.hh:131
std::string get_name() const
Return the name of this model instance.
Definition: model.hh:417
Config get_cfg() const
Return the config node of this model.
Definition: model.hh:412
std::shared_ptr< RNG > get_rng() const
Return a pointer to the shared RNG.
Definition: model.hh:480
typename ModelTypes::RNG RNG
Data type of the shared RNG.
Definition: model.hh:128
const std::shared_ptr< Space > & get_space() const
Return the space this model resides in.
Definition: model.hh:388
An exception class for invalid positions in Utopia::Space.
Definition: exceptions.hh:113
YAML::Node Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition: types.hh:71
SelectionMode
Possible selection modes; availability depends on choice of manager.
Definition: select.hh:72
Container select_entities(const Manager &mngr, const DataIO::Config &sel_cfg)
Select entities according to parameters specified in a configuration.
Definition: select.hh:200
@ condition
Select if a condition is fulfilled.
@ sync
Synchronous update.
DataIO::Config Config
Type of a variadic dictionary-like data structure used throughout Utopia.
Definition: types.hh:80
EntityContainer< AgentType > AgentContainer
Type of the variably sized container for agents.
Definition: types.hh:30
arma::Col< double >::fixed< dim > SpaceVecType
Type for vector-like data that is associated with a physical space.
Definition: types.hh:61
unsigned short DimType
Type for dimensions, i.e. very small unsigned integers.
Definition: types.hh:34
std::size_t IndexType
Type for indices, i.e. values used for container indexing, agent IDs, ...
Definition: types.hh:40
static constexpr bool use_default_state_constructor
Whether to use the default constructor for constructing a entity state.
Definition: entity.hh:57
static constexpr Update mode
Whether the entitys should be synchronously updated.
Definition: entity.hh:54
StateType State
Type of the entitys' state container.
Definition: entity.hh:51
static constexpr std::size_t dim
The dimensionality of the space.
Definition: space.hh:30