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;
686 std::vector<CellType*>
cells()
override;
694 template<
template<
typename>
class SyncMode,
typename CellType,
typename EndCondition>
696 cell_group.add(cell);
699 template<
template<
typename>
class SyncMode,
typename CellType,
typename EndCondition>
701 std::vector<CellType*> cells;
702 for(
auto agent : cell_group.localAgents())
703 cells.push_back(
static_cast<CellType*
>(agent));
707 template<
template<
typename>
class SyncMode,
typename CellType,
typename EndCondition>
712 template<
template<
typename>
class SyncMode,
typename CellType,
typename EndCondition>
717 template<
template<
typename>
class SyncMode,
typename CellType,
typename EndCondition>
721 id, behavior, *
this, dist_move_algo_end_condition);
722 this->insert(
id, group);
750 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived = AgentType>
753 SpatialAgentInterface,
755 SpatialAgentBase<SpatialAgentInterface, AgentType, CellType, Derived>
757 friend nlohmann::adl_serializer<
792 mutable CellType* location_cell_buffer =
nullptr;
821 using SpatialAgentInterface::moveTo;
834 return this->
template outNeighbors<CellType>(SpatialModelLayers::MOVE);
846 template<
typename NeighborType = api::model::Agent>
848 return this->
template outNeighbors<NeighborType>(SpatialModelLayers::PERCEPTION);
872 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
875 this->model()->link(
this, cell, SpatialModelLayers::NEW_LOCATION);
878 auto location = this->node()->getOutgoingEdges(SpatialModelLayers::LOCATION);
879 if(location.size() > 0)
880 this->model()->unlink(location[0]);
884 this->node()->getOutgoingEdges(SpatialModelLayers::MOVE)) {
885 this->model()->unlink(cell_edge);
890 : this->node()->getOutgoingEdges(SpatialModelLayers::PERCEIVE))
891 this->model()->unlink(cell_edge);
895 : this->node()->getOutgoingEdges(fpmas::api::model::PERCEPTION))
896 this->model()->unlink(perception);
906 if(this->mobilityRange().contains(cell, cell))
907 this->model()->link(
this, cell, SpatialModelLayers::MOVE);
908 if(this->perceptionRange().contains(cell, cell))
909 this->model()->link(
this, cell, SpatialModelLayers::PERCEIVE);
912 this->location_id = cell->node()->getId();
913 this->location_cell_buffer = cell;
916 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
918 if(location_cell_buffer !=
nullptr) {
919 return location_cell_buffer;
921 auto edges = this->node()->getOutgoingEdges(SpatialModelLayers::LOCATION);
923 location_cell_buffer =
static_cast<CellType*
>(
924 edges[0]->getTargetNode()->data().get()
927 location_cell_buffer =
nullptr;
930 return location_cell_buffer;
933 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
938 auto location = this->locationCell();
940 for(
auto cell_edge : this->node()->getOutgoingEdges(SpatialModelLayers::NEW_MOVE)) {
941 auto* agent = cell_edge->getTargetNode()->data().get();
944 && this->mobilityRange().contains(location,
static_cast<CellType*
>(agent)))
945 move_layer.
link(agent);
946 this->model()->unlink(cell_edge);
950 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
954 auto location = this->locationCell();
956 for(
auto cell_edge : this->node()->getOutgoingEdges(SpatialModelLayers::NEW_PERCEIVE)) {
957 auto* agent = cell_edge->getTargetNode()->data().get();
960 && this->perceptionRange().contains(location,
static_cast<CellType*
>(agent)))
961 perceive_layer.
link(agent);
962 this->model()->unlink(cell_edge);
966 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
969 auto mobility_field = this->
template outNeighbors<CellType>(SpatialModelLayers::MOVE);
970 auto it = mobility_field.begin();
971 while(!found && it != mobility_field.end()) {
972 if((*it)->node()->getId() == cell_id) {
994 template<
typename AgentType,
typename CellType = api::model::Cell,
typename Derived = AgentType>
1005 this->updateLocation(cell);
1014 template<
typename CellType>
1026 std::size_t
radius(CellType*)
const override {
1037 template<
typename CellType>
1042 bool contains(CellType* location, CellType* cell)
const override {
1043 return location->node()->getId() == cell->node()->getId();
1049 std::size_t
radius(CellType*)
const override {
1058 template<
typename AgentType>
1068 return new AgentType;
1086 template<
typename CellType,
typename MappingCellType>
1119 template<
typename CellType,
typename MappingCellType>
1126 build_agents(model, groups, [&factory] () {
return factory.
build();}, agent_mapping);
1129 template<
typename CellType,
typename MappingCellType>
1139 std::vector<api::model::SpatialAgent<CellType>*> agents;
1140 for(
auto cell : model.
cells()) {
1141 for(std::size_t i = 0; i < agent_mapping.
countAt(cell); i++) {
1142 auto agent = factory();
1143 agents.push_back(agent);
1144 temp_group.
add(agent);
1147 agent->initLocation(cell);
1164 template<
typename CellType,
typename MappingCellType = api::model::Cell>
1176 this->
build_agents(model, groups, factory, agent_mapping);
1188 this->
build_agents(model, groups, factory, agent_mapping);
1197 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
1198 struct adl_serializer<
fpmas::api::utils::PtrWrapper<fpmas::model::SpatialAgentBase<SpatialAgentInterface, AgentType, CellType, Derived>>> {
1221 const_cast<Derived*
>(
static_cast<const Derived*
>(ptr.
get())));
1222 j[1] = ptr->location_id;
1250 return derived_ptr.
get();
1255namespace fpmas {
namespace io {
namespace json {
1267 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
1290 const_cast<Derived*
>(
static_cast<const Derived*
>(agent.
get()))
1311 return derived_ptr.
get();
1317namespace fpmas {
namespace io {
namespace datapack {
1336 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
1349 const_cast<Derived*
>(
static_cast<const Derived*
>(ptr.
get())));
1363 const_cast<Derived*
>(
static_cast<const Derived*
>(ptr.
get())));
1365 pack.
put(ptr->locationId());
1392 return derived_ptr.
get();
1416 template<
typename SpatialAgentInterface,
typename AgentType,
typename CellType,
typename Derived>
1429 const_cast<Derived*
>(
1430 static_cast<const Derived*
>(ptr.
get())
1451 const_cast<Derived*
>(
static_cast<const Derived*
>(agent.
get()))
1472 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:685
Definition: spatial_model.h:607
virtual SpatialAgent< CellType > * build()=0
Definition: spatial_model.h:656
virtual std::size_t countAt(CellType *cell)=0
Definition: spatial_model.h:234
virtual CellType * locationCell() const =0
api::model::Cell CellType
Definition: spatial_model.h:484
virtual MoveAgentGroup< CellType > & buildMoveGroup(GroupId id, const Behavior &behavior)=0
virtual std::vector< CellType * > cells()=0
virtual void execute(const scheduler::Job &job)=0
Definition: ptr_wrapper.h:21
T * get()
Definition: ptr_wrapper.h:58
Definition: datapack.h:301
std::size_t size() const
Definition: datapack.h:367
void put(const T &item)
Definition: datapack.h:447
T get() const
Definition: datapack.h:459
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:1059
AgentType * build() override
Definition: spatial_model.h:1067
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:756
Neighbors< CellType > mobilityField() const
Definition: spatial_model.h:833
CellType * locationCell() const override
Definition: spatial_model.h:917
void handleNewMove() override
Definition: spatial_model.h:934
void handleNewPerceive() override
Definition: spatial_model.h:951
DistributedId locationId() const override
Definition: spatial_model.h:862
void moveTo(DistributedId id) override
Definition: spatial_model.h:967
void initLocation(CellType *cell) override
Definition: spatial_model.h:855
SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > JsonBase
Definition: spatial_model.h:789
Neighbors< NeighborType > perceptions() const
Definition: spatial_model.h:847
void updateLocation(CellType *cell)
Definition: spatial_model.h:873
Definition: spatial_model.h:1087
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:1120
static const api::model::GroupId TEMP_GROUP_ID
Definition: spatial_model.h:1093
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:1130
Definition: spatial_model.h:1165
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:1182
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:1170
Definition: spatial_model.h:996
void moveTo(CellType *cell) override
Definition: spatial_model.h:1004
Definition: spatial_model.h:674
fpmas::api::model::AgentGroup & cellGroup() override
Definition: spatial_model.h:708
void add(CellType *cell) override
Definition: spatial_model.h:695
MoveAgentGroup< CellType > & buildMoveGroup(api::model::GroupId id, const api::model::Behavior &behavior) override
Definition: spatial_model.h:718
std::vector< CellType * > cells() override
Definition: spatial_model.h:700
api::model::AgentGroup * group() override
Definition: model.h:851
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:1467
static void to_datapack(LightObjectPack &o, const Ptr &agent)
Definition: spatial_model.h:1447
static std::size_t size(const LightObjectPack &p, const Ptr &ptr)
Definition: spatial_model.h:1427
PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1421
Definition: datapack.h:1411
static void to_datapack(LightObjectPack &pack, const T &item)
Definition: datapack.h:1438
static T from_datapack(const LightObjectPack &pack)
Definition: datapack.h:1451
static Ptr from_datapack(const ObjectPack &pack)
Definition: spatial_model.h:1385
PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1341
static std::size_t size(const ObjectPack &p, const Ptr &ptr)
Definition: spatial_model.h:1347
static void to_datapack(ObjectPack &pack, const Ptr &ptr)
Definition: spatial_model.h:1360
Definition: datapack.h:55
static void to_json(light_json &j, const Ptr &agent)
Definition: spatial_model.h:1286
static Ptr from_json(const light_json &j)
Definition: spatial_model.h:1306
PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1272
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:1038
std::size_t radius(CellType *) const override
Definition: spatial_model.h:1049
bool contains(CellType *location, CellType *cell) const override
Definition: spatial_model.h:1042
Definition: spatial_model.h:1015
bool contains(CellType *, CellType *) const override
Definition: spatial_model.h:1019
std::size_t radius(CellType *) const override
Definition: spatial_model.h:1026
static void to_json(nlohmann::json &j, const Ptr &ptr)
Definition: spatial_model.h:1218
static Ptr from_json(const nlohmann::json &j)
Definition: spatial_model.h:1243
fpmas::api::utils::PtrWrapper< fpmas::model::SpatialAgentBase< SpatialAgentInterface, AgentType, CellType, Derived > > Ptr
Definition: spatial_model.h:1202