1#ifndef FPMAS_ENVIRONMENT_H
2#define FPMAS_ENVIRONMENT_H
10#include "../serializer.h"
27#define FPMAS_MOBILITY_RANGE(RANGE)\
28 const decltype(RANGE)& mobilityRange() const override {return RANGE;}
44#define FPMAS_PERCEPTION_RANGE(RANGE)\
45 const decltype(RANGE)& perceptionRange() const override {return RANGE;}
47namespace fpmas {
namespace model {
49 using api::model::DistributedId;
60 static const bool EXCLUDE_LOCATION =
false;
65 static const bool INCLUDE_LOCATION =
true;
70 template<
typename CellType>
99 dist_move_algo(model, *this, model.getGroup(CELL_GROUP_ID), end_condition) {
122 return dist_move_algo;
126 template<
typename CellType>
129 job_list.push_back(this->agentExecutionJob());
131 for(
auto job : dist_move_algo.jobs())
132 job_list.push_back(job);
145 std::vector<DistributedId> current_layer_ids;
156 : _agent(agent), layer_id(layer_id) {
158 current_layer_ids.resize(edges.size());
160 for(std::size_t i = 0; i < edges.size(); i++)
161 current_layer_ids[i] = edges[i]->getTargetNode()->getId();
174 current_layer_ids.begin(),
175 current_layer_ids.end(),
177 ) != current_layer_ids.end();
190 current_layer_ids.push_back(other_agent->
node()->
getId());
191 _agent->
model()->
link(_agent, other_agent, layer_id);
214 template<
typename CellInterface,
typename CellType,
typename TypeIdBase = CellType>
230 std::vector<CellType*> successors_buffer;
231 std::vector<api::model::AgentEdge*> raw_successors_buffer;
232 const std::vector<CellType*>& bufferedSuccessors();
380 template<
typename CellInterface,
typename CellType,
typename TypeIdBase>
382 return this->successors_buffer;
385 template<
typename CellInterface,
typename CellType,
typename TypeIdBase>
387 bool init_successors;
390 auto current_successors
391 = this->node()->getOutgoingEdges(SpatialModelLayers::CELL_SUCCESSOR);
395 if(current_successors.size() == 0 ||
396 current_successors.size() != raw_successors_buffer.size()) {
397 init_successors =
false;
399 auto it = current_successors.begin();
400 auto raw_it = raw_successors_buffer.begin();
401 while(it != current_successors.end() && (*it) == *raw_it) {
405 if(it == current_successors.end()) {
406 init_successors =
true;
408 init_successors =
false;
412 if(!init_successors) {
413 raw_successors_buffer = current_successors;
414 successors_buffer.resize(raw_successors_buffer.size());
415 for(std::size_t i = 0; i < raw_successors_buffer.size(); i++)
416 successors_buffer[i] =
static_cast<CellType*
>(
417 raw_successors_buffer[i]->getTargetNode()->data().get()
421 std::set<DistributedId> new_location_layer;
423 : this->node()->getIncomingEdges(SpatialModelLayers::NEW_LOCATION))
424 new_location_layer.insert(agent_edge->getSourceNode()->getId());
430 for(
auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::MOVE)) {
431 if(new_location_layer.count(agent_edge->getSourceNode()->getId())==0)
432 this->no_move_flags.insert(agent_edge->getSourceNode()->getId());
434 for(
auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::PERCEIVE)) {
435 if(new_location_layer.count(agent_edge->getSourceNode()->getId())==0)
436 this->no_move_flags.insert(agent_edge->getSourceNode()->getId());
441 for(
auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::LOCATION)) {
442 this->no_move_flags.insert(agent_edge->getSourceNode()->getId());
446 template<
typename CellInterface,
typename CellType,
typename TypeIdBase>
462 for(
auto cell : this->bufferedSuccessors()) {
463 if(!move_layer.contains(cell)) {
468 if(spatial_agent->mobilityRange().contains(
475 move_layer.link(cell);
485 for(
auto cell : this->bufferedSuccessors())
489 SpatialModelLayers::NEW_MOVE
494 template<
typename CellInterface,
typename CellType,
typename TypeIdBase>
496 std::vector<api::model::Cell*> neighbors;
497 for(
auto edge : this->node()->getOutgoingEdges(SpatialModelLayers::CELL_SUCCESSOR)) {
501 neighbors.push_back(
static_cast<api::model::Cell*
>(edge->getTargetNode()->data().get()));
510 template<
typename CellInterface,
typename CellType,
typename TypeIdBase>
515 FPMAS_LOGD(this->model()->graph().getMpiCommunicator().getRank(),
"[CELL]",
516 "%s Setting this Cell as %s location.",
521 new_location_edge, SpatialModelLayers::LOCATION
524 this->model()->link(agent,
this, SpatialModelLayers::LOCATION);
525 this->model()->unlink(new_location_edge);
529 template<
typename CellInterface,
typename CellType,
typename TypeIdBase>
531 FPMAS_LOGD(this->model()->graph().getMpiCommunicator().getRank(),
"[CELL]",
532 "%s Updating ranges...",
535 for(
auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::NEW_LOCATION)) {
536 AgentPtr& agent = agent_edge->getSourceNode()->data();
537 updateLocation(agent, agent_edge);
538 growMobilityField(agent);
539 growPerceptionField(agent);
545 move_flags.insert(agent->node()->getId());
546 perception_flags.insert(agent->node()->getId());
550 template<
typename CellInterface,
typename CellType,
typename TypeIdBase>
552 for(
auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::MOVE)) {
553 auto agent = agent_edge->getSourceNode();
557 no_move_flags.count(agent->getId()) == 0 &&
559 move_flags.count(agent->getId()) == 0) {
560 growMobilityField(agent->data());
561 move_flags.insert(agent->getId());
566 template<
typename CellInterface,
typename CellType,
typename TypeIdBase>
568 for(
auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::PERCEIVE)) {
569 auto agent = agent_edge->getSourceNode();
573 no_move_flags.count(agent->getId()) == 0 &&
575 perception_flags.count(agent->getId()) == 0) {
576 growPerceptionField(agent->data());
577 perception_flags.insert(agent->getId());
582 template<
typename CellInterface,
typename CellType,
typename TypeIdBase>
584 FPMAS_LOGD(this->model()->graph().getMpiCommunicator().getRank(),
"[CELL]",
585 "%s Updating perceptions...",
589 perception_flags.clear();
590 std::vector<api::model::AgentEdge*> perceived_agent_edges =
591 this->node()->getIncomingEdges(SpatialModelLayers::LOCATION);
592 for(
auto agent_edge : this->node()->getIncomingEdges(SpatialModelLayers::PERCEIVE)) {
593 auto agent = agent_edge->getSourceNode();
594 for(
auto perceived_agent_edge : perceived_agent_edges) {
595 auto perceived_agent = perceived_agent_edge->getSourceNode();
600 this->no_move_flags.count(agent->getId()) == 0 ||
601 this->no_move_flags.count(perceived_agent->getId()) == 0
603 if(perceived_agent->getId() != agent->getId())
604 this->model()->graph().link(
605 agent, perceived_agent,
606 SpatialModelLayers::PERCEPTION
610 no_move_flags.clear();
613 template<
typename CellInterface,
typename CellType,
typename TypeIdBase>
624 for(
auto cell : this->bufferedSuccessors()) {
625 if(!perceive_layer.contains(cell)) {
627 if(spatial_agent->perceptionRange().contains(
631 perceive_layer.link(cell);
636 for(
auto cell : this->bufferedSuccessors())
640 SpatialModelLayers::NEW_PERCEIVE
656 template<
typename CellType,
typename TypeIdBase = CellType>
669 template<
typename>
class SyncMode,
674 public Model<SyncMode> {
677 EndCondition dist_move_algo_end_condition;
685 void add(CellType* cell)
override;
686 std::vector<CellType*>
cells()
override;
693 template<
template<
typename>
class SyncMode,
typename CellType,
typename EndCondition>
695 cell_group.add(cell);
698 template<
template<
typename>
class SyncMode,
typename CellType,
typename EndCondition>
700 std::vector<CellType*> cells;
701 for(
auto agent : cell_group.localAgents())
702 cells.push_back(
static_cast<CellType*
>(agent));
706 template<
template<
typename>
class SyncMode,
typename CellType,
typename EndCondition>
711 template<
template<
typename>
class SyncMode,
typename CellType,
typename EndCondition>
715 id, behavior, *
this, dist_move_algo_end_condition);
716 this->insert(
id, group);
744 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived = AgentType>
747 SpatialAgentInterface,
749 SpatialAgentBase<SpatialAgentInterface, AgentType, CellType, Derived>
751 friend nlohmann::adl_serializer<
786 mutable CellType* location_cell_buffer =
nullptr;
815 using SpatialAgentInterface::moveTo;
828 return this->
template outNeighbors<CellType>(SpatialModelLayers::MOVE);
840 template<
typename NeighborType = api::model::Agent>
842 return this->
template outNeighbors<NeighborType>(SpatialModelLayers::PERCEPTION);
866 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
869 this->model()->link(
this, cell, SpatialModelLayers::NEW_LOCATION);
872 auto location = this->node()->getOutgoingEdges(SpatialModelLayers::LOCATION);
873 if(location.size() > 0)
874 this->model()->unlink(location[0]);
878 this->node()->getOutgoingEdges(SpatialModelLayers::MOVE)) {
879 this->model()->unlink(cell_edge);
884 : this->node()->getOutgoingEdges(SpatialModelLayers::PERCEIVE))
885 this->model()->unlink(cell_edge);
889 : this->node()->getOutgoingEdges(fpmas::api::model::PERCEPTION))
890 this->model()->unlink(perception);
900 if(this->mobilityRange().contains(cell, cell))
901 this->model()->link(
this, cell, SpatialModelLayers::MOVE);
902 if(this->perceptionRange().contains(cell, cell))
903 this->model()->link(
this, cell, SpatialModelLayers::PERCEIVE);
906 this->location_id = cell->node()->getId();
907 this->location_cell_buffer = cell;
910 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
912 if(location_cell_buffer !=
nullptr) {
913 return location_cell_buffer;
915 auto edges = this->node()->getOutgoingEdges(SpatialModelLayers::LOCATION);
917 location_cell_buffer =
static_cast<CellType*
>(
918 edges[0]->getTargetNode()->data().get()
921 location_cell_buffer =
nullptr;
924 return location_cell_buffer;
927 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
932 auto location = this->locationCell();
934 for(
auto cell_edge : this->node()->getOutgoingEdges(SpatialModelLayers::NEW_MOVE)) {
935 auto* agent = cell_edge->getTargetNode()->data().get();
938 && this->mobilityRange().contains(location,
static_cast<CellType*
>(agent)))
939 move_layer.
link(agent);
940 this->model()->unlink(cell_edge);
944 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
948 auto location = this->locationCell();
950 for(
auto cell_edge : this->node()->getOutgoingEdges(SpatialModelLayers::NEW_PERCEIVE)) {
951 auto* agent = cell_edge->getTargetNode()->data().get();
954 && this->perceptionRange().contains(location,
static_cast<CellType*
>(agent)))
955 perceive_layer.
link(agent);
956 this->model()->unlink(cell_edge);
960 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
963 auto mobility_field = this->
template outNeighbors<CellType>(SpatialModelLayers::MOVE);
964 auto it = mobility_field.begin();
965 while(!found && it != mobility_field.end()) {
966 if((*it)->node()->getId() == cell_id) {
988 template<
typename AgentType,
typename CellType = api::model::Cell,
typename Derived = AgentType>
999 this->updateLocation(cell);
1008 template<
typename CellType>
1020 std::size_t
radius(CellType*)
const override {
1031 template<
typename CellType>
1036 bool contains(CellType* location, CellType* cell)
const override {
1037 return location->node()->getId() == cell->node()->getId();
1043 std::size_t
radius(CellType*)
const override {
1052 template<
typename AgentType>
1062 return new AgentType;
1080 template<
typename CellType,
typename MappingCellType>
1113 template<
typename CellType,
typename MappingCellType>
1120 build_agents(model, groups, [&factory] () {
return factory.
build();}, agent_mapping);
1123 template<
typename CellType,
typename MappingCellType>
1133 std::vector<api::model::SpatialAgent<CellType>*> agents;
1134 for(
auto cell : model.
cells()) {
1135 for(std::size_t i = 0; i < agent_mapping.
countAt(cell); i++) {
1136 auto agent = factory();
1137 agents.push_back(agent);
1138 temp_group.
add(agent);
1141 agent->initLocation(cell);
1158 template<
typename CellType,
typename MappingCellType = api::model::Cell>
1170 this->
build_agents(model, groups, factory, agent_mapping);
1182 this->
build_agents(model, groups, factory, agent_mapping);
1191 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
1192 struct adl_serializer<
fpmas::api::utils::PtrWrapper<fpmas::model::SpatialAgentBase<SpatialAgentInterface, AgentType, CellType, Derived>>> {
1215 const_cast<Derived*
>(
static_cast<const Derived*
>(ptr.
get())));
1216 j[1] = ptr->location_id;
1244 return derived_ptr.
get();
1249namespace fpmas {
namespace io {
namespace json {
1261 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
1284 const_cast<Derived*
>(
static_cast<const Derived*
>(agent.
get()))
1305 return derived_ptr.
get();
1311namespace fpmas {
namespace io {
namespace datapack {
1330 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
1343 const_cast<Derived*
>(
static_cast<const Derived*
>(ptr.
get())));
1357 const_cast<Derived*
>(
static_cast<const Derived*
>(ptr.
get())));
1359 pack.
put(ptr->locationId());
1386 return derived_ptr.
get();
1410 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
1423 const_cast<Derived*
>(
1424 static_cast<const Derived*
>(ptr.
get())
1445 const_cast<Derived*
>(
static_cast<const Derived*
>(agent.
get()))
1466 return derived_ptr.
get();
Definition: distributed_edge.h:91
virtual LocationState state() const =0
virtual void switchLayer(DistributedEdge< T > *edge, LayerId layer_id)=0
Definition: distributed_id.h:89
virtual LocationState state() const =0
virtual IdType getId() const =0
virtual const std::vector< EdgeType * > getOutgoingEdges() const =0
virtual void add(Agent *agent)=0
virtual Model * model()=0
virtual AgentNode * node()=0
Definition: spatial_model.h:90
Definition: spatial_model.h:425
Definition: spatial_model.h:376
virtual void removeGroup(AgentGroup &group)=0
virtual api::runtime::Runtime & runtime()=0
virtual AgentEdge * link(Agent *src_agent, Agent *tgt_agent, api::graph::LayerId layer)=0
virtual AgentGroup & buildGroup(GroupId id)=0
Definition: spatial_model.h:455
virtual DistributedMoveAlgorithm< CellType > & distributedMoveAlgorithm()=0
Definition: exceptions.h:32
Definition: spatial_model.h:121
Definition: spatial_model.h:675
Definition: spatial_model.h:597
virtual SpatialAgent< CellType > * build()=0
Definition: spatial_model.h:646
virtual std::size_t countAt(CellType *cell)=0
Definition: spatial_model.h:234
virtual CellType * locationCell() const =0
Definition: spatial_model.h:479
virtual std::vector< CellType * > cells()=0
virtual MoveAgentGroup< CellType > & buildMoveGroup(GroupId id, const Behavior &behavior)=0
virtual void execute(const scheduler::Job &job)=0
Definition: ptr_wrapper.h:21
T * get()
Definition: ptr_wrapper.h:58
Definition: datapack.h:275
std::size_t size() const
Definition: datapack.h:341
void put(const T &item)
Definition: datapack.h:421
T get() const
Definition: datapack.h:433
Definition: spatial_model.h:215
void init() override
Definition: spatial_model.h:386
CellBase & operator=(const CellBase &)=default
std::set< DistributedId > move_flags
Definition: spatial_model.h:257
void handleNewLocation() override
Definition: spatial_model.h:530
void updatePerceptions(api::model::AgentGroup &group) override
Definition: spatial_model.h:583
CellBase(CellBase &&)=default
void handleMove() override
Definition: spatial_model.h:551
CellBase< CellInterface, CellType, TypeIdBase > & operator=(CellBase< CellInterface, CellType, TypeIdBase > &&)
Definition: spatial_model.h:331
CellBase(const CellBase &)=default
std::vector< api::model::Cell * > successors() override
Definition: spatial_model.h:495
std::set< DistributedId > perception_flags
Definition: spatial_model.h:265
void handlePerceive() override
Definition: spatial_model.h:567
std::set< DistributedId > no_move_flags
Definition: spatial_model.h:249
Definition: spatial_model.h:1053
AgentType * build() override
Definition: spatial_model.h:1061
Definition: dist_move_algo.h:145
Definition: dist_move_algo.h:99
Definition: spatial_model.h:73
MoveAgentGroup(api::model::GroupId group_id, const api::model::Behavior &behavior, api::model::SpatialModel< CellType > &model, api::model::EndCondition< CellType > &end_condition)
Definition: spatial_model.h:92
api::model::DistributedMoveAlgorithm< CellType > & distributedMoveAlgorithm() override
Definition: spatial_model.h:121
api::scheduler::JobList jobs() const override
Definition: spatial_model.h:127
Definition: spatial_model.h:750
Neighbors< CellType > mobilityField() const
Definition: spatial_model.h:827
CellType * locationCell() const override
Definition: spatial_model.h:911
void handleNewMove() override
Definition: spatial_model.h:928
void handleNewPerceive() override
Definition: spatial_model.h:945
DistributedId locationId() const override
Definition: spatial_model.h:856
void moveTo(DistributedId id) override
Definition: spatial_model.h:961
void initLocation(CellType *cell) override
Definition: spatial_model.h:849
SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > JsonBase
Definition: spatial_model.h:783
Neighbors< NeighborType > perceptions() const
Definition: spatial_model.h:841
void updateLocation(CellType *cell)
Definition: spatial_model.h:867
Definition: spatial_model.h:1081
void build_agents(api::model::SpatialModel< CellType > &model, api::model::GroupList groups, api::model::SpatialAgentFactory< CellType > &factory, api::model::SpatialAgentMapping< MappingCellType > &agent_mapping)
Definition: spatial_model.h:1114
static const api::model::GroupId TEMP_GROUP_ID
Definition: spatial_model.h:1087
void build_agents(api::model::SpatialModel< CellType > &model, api::model::GroupList groups, std::function< api::model::SpatialAgent< CellType > *()> factory, api::model::SpatialAgentMapping< MappingCellType > &agent_mapping)
Definition: spatial_model.h:1124
Definition: spatial_model.h:1159
void build(api::model::SpatialModel< CellType > &model, api::model::GroupList groups, std::function< api::model::SpatialAgent< CellType > *()> factory, api::model::SpatialAgentMapping< MappingCellType > &agent_mapping) override
Definition: spatial_model.h:1176
void build(api::model::SpatialModel< CellType > &model, api::model::GroupList groups, api::model::SpatialAgentFactory< CellType > &factory, api::model::SpatialAgentMapping< MappingCellType > &agent_mapping) override
Definition: spatial_model.h:1164
Definition: spatial_model.h:990
void moveTo(CellType *cell) override
Definition: spatial_model.h:998
Definition: spatial_model.h:674
fpmas::api::model::AgentGroup & cellGroup() override
Definition: spatial_model.h:707
void add(CellType *cell) override
Definition: spatial_model.h:694
MoveAgentGroup< CellType > & buildMoveGroup(api::model::GroupId id, const api::model::Behavior &behavior) override
Definition: spatial_model.h:712
std::vector< CellType * > cells() override
Definition: spatial_model.h:699
api::model::AgentGroup * group() override
Definition: model.h:831
AgentGroupBase(GroupId group_id, api::model::AgentGraph &agent_graph)
Definition: model.cpp:142
const api::model::Behavior & behavior() override
Definition: model.h:400
Definition: spatial_model.h:141
CurrentOutLayer(api::model::Agent *agent, fpmas::graph::LayerId layer_id)
Definition: spatial_model.h:155
bool contains(fpmas::api::model::Agent *agent)
Definition: spatial_model.h:172
void link(fpmas::api::model::Agent *other_agent)
Definition: spatial_model.h:189
api::model::AgentGraph & graph() override
Definition: model.h:487
#define FPMAS_C_STR(arg)
Definition: macros.h:24
@ LOCAL
Definition: location_state.h:21
int LayerId
Definition: edge.h:13
int GroupId
Definition: model.h:78
SpatialModelLayers
Definition: spatial_model.h:17
std::vector< std::reference_wrapper< AgentGroup > > GroupList
Definition: model.h:833
std::vector< std::reference_wrapper< const Job > > JobList
Definition: scheduler.h:215
nlohmann::basic_json< std::map, std::vector, std::string, bool, std::int64_t, std::uint64_t, double, std::allocator, light_serializer > light_json
Definition: json.h:14
CellBase< api::model::Cell, CellType, TypeIdBase > Cell
Definition: spatial_model.h:657
static Ptr from_datapack(const LightObjectPack &o)
Definition: spatial_model.h:1461
static void to_datapack(LightObjectPack &o, const Ptr &agent)
Definition: spatial_model.h:1441
static std::size_t size(const LightObjectPack &p, const Ptr &ptr)
Definition: spatial_model.h:1421
PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1415
Definition: datapack.h:1382
static void to_datapack(LightObjectPack &pack, const T &item)
Definition: datapack.h:1409
static T from_datapack(const LightObjectPack &pack)
Definition: datapack.h:1422
static Ptr from_datapack(const ObjectPack &pack)
Definition: spatial_model.h:1379
PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1335
static std::size_t size(const ObjectPack &p, const Ptr &ptr)
Definition: spatial_model.h:1341
static void to_datapack(ObjectPack &pack, const Ptr &ptr)
Definition: spatial_model.h:1354
Definition: datapack.h:55
static void to_json(light_json &j, const Ptr &agent)
Definition: spatial_model.h:1280
static Ptr from_json(const light_json &j)
Definition: spatial_model.h:1300
PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1266
static void from_json(const light_json &j, T &data)
Definition: json.h:123
static void to_json(light_json &j, const T &data)
Definition: json.h:107
Definition: spatial_model.h:1032
std::size_t radius(CellType *) const override
Definition: spatial_model.h:1043
bool contains(CellType *location, CellType *cell) const override
Definition: spatial_model.h:1036
Definition: spatial_model.h:1009
bool contains(CellType *, CellType *) const override
Definition: spatial_model.h:1013
std::size_t radius(CellType *) const override
Definition: spatial_model.h:1020
static void to_json(nlohmann::json &j, const Ptr &ptr)
Definition: spatial_model.h:1212
static Ptr from_json(const nlohmann::json &j)
Definition: spatial_model.h:1237
fpmas::api::utils::PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1196