BioDynaMo  v1.05.119-a4ff3934
environment.h
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 #ifndef CORE_ENVIRONMENT_ENVIRONMENT_H_
16 #define CORE_ENVIRONMENT_ENVIRONMENT_H_
17 
18 #include <omp.h>
19 #include <cassert>
20 #include <mutex>
21 #include <vector>
22 #include "core/agent/agent.h"
24 #include "core/functor.h"
25 #include "core/load_balance_info.h"
26 #include "core/resource_manager.h"
27 
28 namespace bdm {
29 
30 class Environment {
31  private:
32  // Flag that indicates if the environment is up to date with the simulation.
33  // E.g. load balancing can result in an environment that does no longer
34  // describe the actual state of the simulation.
35  bool out_of_sync_ = true;
36 
37  public:
38  virtual ~Environment() = default;
39 
44  void MarkAsOutOfSync() { out_of_sync_ = true; }
45 
48  void Update() {
49  assert(!omp_in_parallel() && "Update called in parallel region.");
50  if (out_of_sync_) {
52  out_of_sync_ = false;
53  }
54  }
55 
57  void ForcedUpdate() {
59  Update();
60  }
61 
66  const Agent& query, real_t squared_radius) = 0;
67 
72  virtual void ForEachNeighbor(Functor<void, Agent*>& lambda,
73  const Agent& query, void* criteria) = 0;
74 
83  const Real3& query_position,
84  real_t squared_radius,
85  const Agent* query_agent = nullptr) = 0;
86 
87  virtual void Clear() = 0;
88 
89  virtual std::array<int32_t, 6> GetDimensions() const = 0;
90 
91  virtual std::array<int32_t, 2> GetDimensionThresholds() const = 0;
92 
97  };
98 
99  virtual LoadBalanceInfo* GetLoadBalanceInfo() = 0;
100 
104  public:
109  public:
110  virtual ~NeighborMutex() = default;
111  virtual void lock(){}; // NOLINT
112  virtual void unlock(){}; // NOLINT
113  };
114 
115  virtual ~NeighborMutexBuilder() = default;
116  virtual NeighborMutex* GetMutex(uint64_t box_idx) = 0;
117  };
118 
121  virtual NeighborMutexBuilder* GetNeighborMutexBuilder() = 0;
122 
123  bool HasGrown() const { return has_grown_; }
124 
125  protected:
126  bool has_grown_ = false;
130 
133  virtual void UpdateImplementation() = 0;
134 
136  : public Functor<void, Agent*, AgentHandle> {
137  using Type = std::vector<std::array<real_t, 8>>;
138 
140  Type& ymax, Type& zmin, Type& zmax,
141  Type& largest)
142  : xmin_(xmin),
143  xmax_(xmax),
144  ymin_(ymin),
145  ymax_(ymax),
146  zmin_(zmin),
147  zmax_(zmax),
148  largest_(largest) {}
149 
150  void operator()(Agent* agent, AgentHandle) override {
151  auto tid = omp_get_thread_num();
152  const auto& position = agent->GetPosition();
153  // x
154  if (position[0] < xmin_[tid][0]) {
155  xmin_[tid][0] = position[0];
156  }
157  if (position[0] > xmax_[tid][0]) {
158  xmax_[tid][0] = position[0];
159  }
160  // y
161  if (position[1] < ymin_[tid][0]) {
162  ymin_[tid][0] = position[1];
163  }
164  if (position[1] > ymax_[tid][0]) {
165  ymax_[tid][0] = position[1];
166  }
167  // z
168  if (position[2] < zmin_[tid][0]) {
169  zmin_[tid][0] = position[2];
170  }
171  if (position[2] > zmax_[tid][0]) {
172  zmax_[tid][0] = position[2];
173  }
174  // largest object
175  auto diameter = agent->GetDiameter();
176  if (diameter > largest_[tid][0]) {
177  largest_[tid][0] = diameter;
178  }
179  }
180 
187 
189  };
190 
194  std::array<real_t, 6>* ret_grid_dimensions) {
196 
197  const auto max_threads = omp_get_max_threads();
198  // allocate version for each thread - avoid false sharing by padding them
199  // assumes 64 byte cache lines (8 * sizeof(real_t))
200  std::vector<std::array<real_t, 8>> xmin(max_threads, {{Math::kInfinity}});
201  std::vector<std::array<real_t, 8>> xmax(max_threads, {{-Math::kInfinity}});
202 
203  std::vector<std::array<real_t, 8>> ymin(max_threads, {{Math::kInfinity}});
204  std::vector<std::array<real_t, 8>> ymax(max_threads, {{-Math::kInfinity}});
205 
206  std::vector<std::array<real_t, 8>> zmin(max_threads, {{Math::kInfinity}});
207  std::vector<std::array<real_t, 8>> zmax(max_threads, {{-Math::kInfinity}});
208 
209  std::vector<std::array<real_t, 8>> largest(max_threads, {{0}});
210 
211  SimDimensionAndLargestAgentFunctor functor(xmin, xmax, ymin, ymax, zmin,
212  zmax, largest);
213  rm->ForEachAgentParallel(1000, functor);
214 
215  // reduce partial results into global one
216  real_t& gxmin = (*ret_grid_dimensions)[0];
217  real_t& gxmax = (*ret_grid_dimensions)[1];
218  real_t& gymin = (*ret_grid_dimensions)[2];
219  real_t& gymax = (*ret_grid_dimensions)[3];
220  real_t& gzmin = (*ret_grid_dimensions)[4];
221  real_t& gzmax = (*ret_grid_dimensions)[5];
222  for (int tid = 0; tid < max_threads; tid++) {
223  // x
224  if (xmin[tid][0] < gxmin) {
225  gxmin = xmin[tid][0];
226  }
227  if (xmax[tid][0] > gxmax) {
228  gxmax = xmax[tid][0];
229  }
230  // y
231  if (ymin[tid][0] < gymin) {
232  gymin = ymin[tid][0];
233  }
234  if (ymax[tid][0] > gymax) {
235  gymax = ymax[tid][0];
236  }
237  // z
238  if (zmin[tid][0] < gzmin) {
239  gzmin = zmin[tid][0];
240  }
241  if (zmax[tid][0] > gzmax) {
242  gzmax = zmax[tid][0];
243  }
244  // largest object
245  if (largest[tid][0] > largest_object_size_) {
246  largest_object_size_ = largest[tid][0];
247  }
248  }
249 
251  }
252 };
253 
254 } // namespace bdm
255 
256 #endif // CORE_ENVIRONMENT_ENVIRONMENT_H_
bdm::Environment::GetDimensions
virtual std::array< int32_t, 6 > GetDimensions() const =0
bdm::Environment::out_of_sync_
bool out_of_sync_
Definition: environment.h:35
bdm::Environment::NeighborMutexBuilder
Definition: environment.h:103
bdm::Environment::largest_object_size_squared_
real_t largest_object_size_squared_
Definition: environment.h:129
bdm::Environment::NeighborMutexBuilder::~NeighborMutexBuilder
virtual ~NeighborMutexBuilder()=default
bdm::Environment::Clear
virtual void Clear()=0
bdm
Definition: agent.cc:39
bdm::Environment::NeighborMutexBuilder::NeighborMutex::unlock
virtual void unlock()
Definition: environment.h:112
bdm::Environment::CalcSimDimensionsAndLargestAgent
void CalcSimDimensionsAndLargestAgent(std::array< real_t, 6 > *ret_grid_dimensions)
Definition: environment.h:193
bdm::real_t
double real_t
Definition: real_t.h:21
bdm::Environment::GetNeighborMutexBuilder
virtual NeighborMutexBuilder * GetNeighborMutexBuilder()=0
bdm::Environment::NeighborMutexBuilder::NeighborMutex
Definition: environment.h:108
bdm::Environment::HasGrown
bool HasGrown() const
Definition: environment.h:123
bdm::Agent::GetDiameter
virtual real_t GetDiameter() const =0
bdm::LoadBalanceInfo
Definition: load_balance_info.h:24
bdm::Environment::GetLoadBalanceInfo
virtual LoadBalanceInfo * GetLoadBalanceInfo()=0
load_balance_info.h
bdm::Environment::SimDimensionAndLargestAgentFunctor::xmax_
Type & xmax_
Definition: environment.h:182
bdm::Environment::has_grown_
bool has_grown_
Definition: environment.h:126
bdm::Environment::SimDimensionAndLargestAgentFunctor::ymax_
Type & ymax_
Definition: environment.h:184
bdm::Environment::ForcedUpdate
void ForcedUpdate()
Updates the environment. Prefer Update() for implementations.
Definition: environment.h:57
bdm::Agent
Contains code required by all agents.
Definition: agent.h:79
bdm::Environment::SimDimensionAndLargestAgentFunctor::operator()
void operator()(Agent *agent, AgentHandle) override
Definition: environment.h:150
bdm::Environment::~Environment
virtual ~Environment()=default
bdm::Functor< void, Agent *, real_t >
bdm::Environment::SimDimensionAndLargestAgentFunctor::ymin_
Type & ymin_
Definition: environment.h:183
bdm::Environment::Update
void Update()
Definition: environment.h:48
bdm::Math::kInfinity
static constexpr real_t kInfinity
Helpful constant to identify 'infinity'.
Definition: math.h:35
bdm::Environment::ForEachNeighbor
virtual void ForEachNeighbor(Functor< void, Agent *, real_t > &lambda, const Agent &query, real_t squared_radius)=0
bdm::Simulation::GetResourceManager
ResourceManager * GetResourceManager()
Returns the ResourceManager instance.
Definition: simulation.cc:244
bdm::Environment::UpdateImplementation
virtual void UpdateImplementation()=0
bdm::Environment::SimDimensionAndLargestAgentFunctor::zmax_
Type & zmax_
Definition: environment.h:186
bdm::Environment::SimDimensionAndLargestAgentFunctor
Definition: environment.h:135
math_array.h
bdm::Environment::GetDimensionThresholds
virtual std::array< int32_t, 2 > GetDimensionThresholds() const =0
agent.h
bdm::Environment::MarkAsOutOfSync
void MarkAsOutOfSync()
Definition: environment.h:44
bdm::Environment::NeighborMutexBuilder::NeighborMutex::~NeighborMutex
virtual ~NeighborMutex()=default
bdm::Environment::NeighborMutexBuilder::NeighborMutex::lock
virtual void lock()
Definition: environment.h:111
bdm::Environment::NeighborMutexBuilder::GetMutex
virtual NeighborMutex * GetMutex(uint64_t box_idx)=0
bdm::Environment::SimDimensionAndLargestAgentFunctor::SimDimensionAndLargestAgentFunctor
SimDimensionAndLargestAgentFunctor(Type &xmin, Type &xmax, Type &ymin, Type &ymax, Type &zmin, Type &zmax, Type &largest)
Definition: environment.h:139
bdm::Environment::GetLargestAgentSize
real_t GetLargestAgentSize() const
Return the size of the largest agent.
Definition: environment.h:94
bdm::Environment::SimDimensionAndLargestAgentFunctor::largest_
Type & largest_
Definition: environment.h:188
bdm::MathArray
Definition: math_array.h:36
bdm::Environment::SimDimensionAndLargestAgentFunctor::zmin_
Type & zmin_
Definition: environment.h:185
bdm::Environment::GetLargestAgentSizeSquared
real_t GetLargestAgentSizeSquared() const
Definition: environment.h:95
bdm::Environment
Definition: environment.h:30
bdm::Agent::GetPosition
virtual const Real3 & GetPosition() const =0
resource_manager.h
bdm::Simulation::GetActive
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
Definition: simulation.cc:68
bdm::Environment::SimDimensionAndLargestAgentFunctor::xmin_
Type & xmin_
Definition: environment.h:181
functor.h
bdm::Environment::SimDimensionAndLargestAgentFunctor::Type
std::vector< std::array< real_t, 8 > > Type
Definition: environment.h:137
bdm::Environment::largest_object_size_
real_t largest_object_size_
The size of the largest object in the simulation.
Definition: environment.h:128
bdm::AgentHandle
Definition: agent_handle.h:29