BioDynaMo  v1.03.58-27764645
agent.cc
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------
2 //
3 // Copyright (C) 2021 CERN & University of Surrey for the benefit of the
4 // BioDynaMo collaboration. All Rights Reserved.
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 //
9 // See the LICENSE file distributed with this work for details.
10 // See the NOTICE file distributed with this work for additional information
11 // regarding copyright ownership.
12 //
13 // -----------------------------------------------------------------------------
14 
15 #include "core/agent/agent.h"
16 
17 #include <algorithm>
18 #include <cassert>
19 #include <limits>
20 #include <memory>
21 #include <set>
22 #include <sstream>
23 #include <string>
24 #include <type_traits>
25 #include <unordered_map>
26 #include <vector>
27 
29 #include "core/behavior/behavior.h"
32 #include "core/resource_manager.h"
33 #include "core/simulation.h"
34 #include "core/util/log.h"
35 #include "core/util/macros.h"
36 #include "core/util/root.h"
37 #include "core/util/type.h"
38 
39 namespace bdm {
40 
43 }
44 
45 Agent::Agent(TRootIOCtor* io_ctor) {}
46 
47 Agent::Agent(const Agent& other)
48  : uid_(other.uid_),
49  box_idx_(other.box_idx_),
50  run_behavior_loop_idx_(other.run_behavior_loop_idx_),
51  propagate_staticness_neighborhood_(
52  other.propagate_staticness_neighborhood_),
53  is_static_next_ts_(other.is_static_next_ts_) {
54  for (auto* behavior : other.behaviors_) {
55  behaviors_.push_back(behavior->NewCopy());
56  }
57 }
58 
60  for (auto* el : behaviors_) {
61  delete el;
62  }
63 }
64 
65 void Agent::Initialize(const NewAgentEvent& event) {
66  box_idx_ = event.existing_agent->GetBoxIdx();
67  // copy behaviors_ to me
68  InitializeBehaviors(event);
69 }
70 
71 void Agent::Update(const NewAgentEvent& event) {
72  // Run displacement if a new agent has been created with an event.
74  UpdateBehaviors(event);
75 }
76 
77 void Agent::PropagateStaticness(bool beginning) {
79  return;
80  }
81 
82  if (!Simulation::GetActive()->GetParam()->detect_static_agents) {
83  is_static_next_ts_ = false;
84  return;
85  }
86 
87  auto* env = Simulation::GetActive()->GetEnvironment();
88  // TODO(all) generalize to axis-aligned bounding box
89  if (!beginning && GetDiameter() > env->GetLargestAgentSize()) {
90  // If the agent is bigger than all other agents,
91  // the uniform grid implementation is not able to inform
92  // all necessary neighbors.
93  // Therefore, we delay the propagation of the staticness info
94  // to the beginning of the next iteration.
95  return;
96  }
97 
99  is_static_next_ts_ = false;
100  auto set_staticness = L2F([this](Agent* neighbor, real_t squared_distance) {
101  // TODO(all) generalize to axis-aligned bounding box
102  real_t distance = this->GetDiameter() + neighbor->GetDiameter();
103  if (squared_distance < distance * distance) {
104  neighbor->SetStaticnessNextTimestep(false);
105  }
106  });
107  env->ForEachNeighbor(set_staticness, *this,
108  env->GetLargestAgentSizeSquared());
109 }
110 
112  auto* param = Simulation::GetActive()->GetParam();
114  is_static_next_ts_ = param->detect_static_agents;
115 }
116 
118 
121 }
122 
123 const AgentUid& Agent::GetUid() const { return uid_; }
124 
125 uint32_t Agent::GetBoxIdx() const { return box_idx_; }
126 
127 void Agent::SetBoxIdx(uint32_t idx) { box_idx_ = idx; }
128 
129 // ---------------------------------------------------------------------------
130 // Behaviors
131 
132 void Agent::AddBehavior(Behavior* behavior) { behaviors_.push_back(behavior); }
133 
134 void Agent::RemoveBehavior(const Behavior* behavior) {
135  for (unsigned int i = 0; i < behaviors_.size(); i++) {
136  if (behaviors_[i] == behavior) {
137  delete behavior;
138  behaviors_.erase(behaviors_.begin() + i);
139  // if behavior was before or at the current run_behavior_loop_idx_,
140  // correct it by subtracting one.
142  }
143  }
144 }
145 
149  auto* behavior = behaviors_[run_behavior_loop_idx_];
150  behavior->Run(this);
151  }
152 }
153 
155  return behaviors_;
156 }
157 // ---------------------------------------------------------------------------
158 
161 }
162 
164  const auto& existing_agent_behaviors = event.existing_agent->behaviors_;
165  event.new_behaviors.clear();
166  uint64_t cnt = 0;
167  for (auto* behavior : existing_agent_behaviors) {
168  if (behavior->WillBeCopied(event.GetUid())) {
169  event.new_behaviors.clear();
170  // collect new behaviors from other new agents
171  for (auto* nagent : event.new_agents) {
172  event.new_behaviors.push_back(nagent->behaviors_[cnt]);
173  }
174  event.existing_behavior = behavior;
175  auto* new_behavior = behavior->New();
176  new_behavior->Initialize(event);
177  behaviors_.push_back(new_behavior);
178  cnt++;
179  }
180  }
181 }
182 
184  // call event handler for behaviors
185  uint64_t cnt = 0;
186  for (auto* behavior : behaviors_) {
187  bool copied = behavior->WillBeCopied(event.GetUid());
188  if (!behavior->WillBeRemoved(event.GetUid())) {
189  event.new_behaviors.clear();
190  if (copied) {
191  for (auto* new_agent : event.new_agents) {
192  auto* new_behavior = new_agent->behaviors_[cnt];
193  event.new_behaviors.push_back(new_behavior);
194  }
195  }
196  behavior->Update(event);
197  }
198  cnt += copied ? 1 : 0;
199  }
200 
201  // remove behaviors from current
202  for (auto it = behaviors_.begin(); it != behaviors_.end();) {
203  auto* behavior = *it;
204  if (behavior->WillBeRemoved(event.GetUid())) {
205  delete *it;
206  it = behaviors_.erase(it);
207  } else {
208  ++it;
209  }
210  }
211 }
212 
213 } // namespace bdm
in_place_exec_ctxt.h
bdm::NewAgentEvent
Definition: new_agent_event.h:61
bdm::Agent::SetStaticnessNextTimestep
void SetStaticnessNextTimestep(bool value) const
Definition: agent.h:176
bdm::Agent::InitializeBehaviors
void InitializeBehaviors(const NewAgentEvent &event)
Definition: agent.cc:163
bdm::Agent::RunBehaviors
void RunBehaviors()
Execute all behaviorsq.
Definition: agent.cc:146
bdm::Agent::UpdateBehaviors
void UpdateBehaviors(const NewAgentEvent &event)
Function to invoke the Update method of the behavior or remove it from current. Forwards the call to ...
Definition: agent.cc:183
bdm
Definition: agent.cc:39
bdm::Agent::RemoveFromSimulation
virtual void RemoveFromSimulation()
Definition: agent.cc:159
bdm::Behavior
Definition: behavior.h:29
bdm::Agent::is_static_
bool is_static_
If an agent is static, we should not compute the mechanical forces.
Definition: agent.h:297
macros.h
bdm::Agent::Initialize
virtual void Initialize(const NewAgentEvent &event)
Definition: agent.cc:65
bdm::real_t
double real_t
Definition: real_t.h:21
bdm::Agent::GetAllBehaviors
const InlineVector< Behavior *, 2 > & GetAllBehaviors() const
Return all behaviors.
Definition: agent.cc:154
bdm::Agent::GetUid
const AgentUid & GetUid() const
Definition: agent.cc:123
bdm::AgentUidGenerator::GenerateUid
AgentUid GenerateUid()
Definition: agent_uid_generator.h:44
bdm::Agent::GetDiameter
virtual real_t GetDiameter() const =0
type.h
bdm::Agent::SetPropagateStaticness
void SetPropagateStaticness(bool value=true)
Definition: agent.h:184
bdm::Agent::is_static_next_ts_
bool is_static_next_ts_
Flag to determine of an agent is static in the next timestep.
Definition: agent.h:302
bdm::L2F
LambdaFunctor< decltype(&TLambda::operator())> L2F(const TLambda &l)
Definition: functor.h:110
bdm::Agent
Contains code required by all agents.
Definition: agent.h:79
bdm::Agent::run_behavior_loop_idx_
uint16_t run_behavior_loop_idx_
Definition: agent.h:294
bdm::Agent::SetBoxIdx
void SetBoxIdx(uint32_t idx)
Definition: agent.cc:127
new_agent_event.h
root.h
bdm::Agent::RunDiscretization
virtual void RunDiscretization()
Definition: agent.cc:117
bdm::NewAgentEvent::new_agents
InlineVector< Agent *, 3 > new_agents
Definition: new_agent_event.h:73
agent.h
bdm::Simulation::GetAgentUidGenerator
AgentUidGenerator * GetAgentUidGenerator()
Definition: simulation.cc:273
log.h
bdm::Agent::AddBehavior
void AddBehavior(Behavior *behavior)
Add a behavior to this agent.
Definition: agent.cc:132
bdm::Agent::GetBoxIdx
uint32_t GetBoxIdx() const
Definition: agent.cc:125
bdm::AgentUid
Definition: agent_uid.h:25
bdm::Agent::propagate_staticness_neighborhood_
bool propagate_staticness_neighborhood_
Definition: agent.h:300
bdm::Agent::Agent
Agent()
Definition: agent.cc:41
bdm::Simulation::GetExecutionContext
ExecutionContext * GetExecutionContext()
Returns a thread local execution context.
Definition: simulation.cc:288
bdm::Simulation::GetEnvironment
Environment * GetEnvironment()
Definition: simulation.cc:277
bdm::Agent::~Agent
virtual ~Agent()
Definition: agent.cc:59
bdm::Agent::behaviors_
InlineVector< Behavior *, 2 > behaviors_
collection of behaviors which define the internal behavior
Definition: agent.h:275
bdm::NewAgentEvent::GetUid
virtual NewAgentEventUid GetUid() const =0
bdm::Agent::Update
virtual void Update(const NewAgentEvent &event)
Definition: agent.cc:71
behavior.h
bdm::Agent::UpdateStaticness
void UpdateStaticness()
Definition: agent.cc:111
environment.h
bdm::Agent::AssignNewUid
void AssignNewUid()
Definition: agent.cc:119
simulation.h
bdm::Agent::RemoveBehavior
void RemoveBehavior(const Behavior *behavior)
Definition: agent.cc:134
bdm::Simulation::GetParam
const Param * GetParam() const
Returns the simulation parameters.
Definition: simulation.cc:271
bdm::Agent::PropagateStaticness
void PropagateStaticness(bool beginning=false)
Definition: agent.cc:77
bdm::InlineVector
Definition: inline_vector.h:49
resource_manager.h
bdm::Simulation::GetActive
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
Definition: simulation.cc:67
bdm::Agent::box_idx_
uint32_t box_idx_
Grid box index.
Definition: agent.h:273
bdm::Agent::uid_
AgentUid uid_
unique id
Definition: agent.h:271
bdm::ExecutionContext::RemoveAgent
virtual void RemoveAgent(const AgentUid &uid)=0