BioDynaMo  v1.05.119-a4ff3934
kd_tree_environment.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 <algorithm>
16 
18 
19 #include <nanoflann.hpp>
20 
21 namespace bdm {
22 
23 using nanoflann::KDTreeSingleIndexAdaptor;
24 using nanoflann::KDTreeSingleIndexAdaptorParams;
25 using nanoflann::L2_Simple_Adaptor;
26 
27 typedef KDTreeSingleIndexAdaptor<L2_Simple_Adaptor<real_t, NanoFlannAdapter>,
28  NanoFlannAdapter, 3, uint64_t>
30 
32  bdm_kd_tree_t* index_ = nullptr;
33 };
34 
36  auto* param = Simulation::GetActive()->GetParam();
38  impl_ = std::unique_ptr<KDTreeEnvironment::NanoflannImpl>(
40  impl_->index_ = new bdm_kd_tree_t(
41  3, *nf_adapter_, KDTreeSingleIndexAdaptorParams(param->nanoflann_depth));
42 }
43 
45  delete impl_->index_;
46  delete nf_adapter_;
47 }
48 
51 
52  // Update the flattened indices map
54  if (nf_adapter_->rm_->GetNumAgents() != 0) {
55  Clear();
56  auto inf = Math::kInfinity;
57  std::array<real_t, 6> tmp_dim = {{inf, -inf, inf, -inf, inf, -inf}};
59  RoundOffGridDimensions(tmp_dim);
61  impl_->index_->buildIndex();
62  } else {
63  // There are no sim objects in this simulation
64  auto* param = Simulation::GetActive()->GetParam();
65 
66  bool uninitialized = impl_->index_->m_size == 0;
67  if (uninitialized && param->bound_space) {
68  // Simulation has never had any simulation objects
69  // Initialize grid dimensions with `Param::min_bound_` and
70  // `Param::max_bound_`
71  // This is required for the DiffusionGrid
72  int min = param->min_bound;
73  int max = param->max_bound;
74  grid_dimensions_ = {min, max, min, max, min, max};
75  threshold_dimensions_ = {min, max};
76  has_grown_ = true;
77  } else if (!uninitialized) {
78  // all simulation objects have been removed in the last iteration
79  // grid state remains the same, but we have to set has_grown_ to false
80  // otherwise the DiffusionGrid will attempt to resize
81  has_grown_ = false;
82  } else {
83  Log::Fatal(
84  "KDtreeEnvironment",
85  "You tried to initialize an empty simulation without bound space. "
86  "Therefore we cannot determine the size of the simulation space. "
87  "Please add simulation objects, or set Param::bound_space_, "
88  "Param::min_bound_, and Param::max_bound_.");
89  }
90  }
91 }
92 
94  const Agent& query,
95  real_t squared_radius) {
96  ForEachNeighbor(lambda, query.GetPosition(), squared_radius, &query);
97 }
98 
100  const Real3& query_position,
101  real_t squared_radius,
102  const Agent* query_agent) {
103  std::vector<std::pair<uint64_t, real_t>> neighbors;
104 
105  nanoflann::SearchParams params;
106  params.sorted = false;
107 
108  // calculate neighbors
109  impl_->index_->radiusSearch(&query_position[0], squared_radius, neighbors,
110  params);
111 
113  for (auto& n : neighbors) {
114  Agent* nb_so =
115  rm->GetAgent(nf_adapter_->flat_idx_map_.GetAgentHandle(n.first));
116  if (nb_so != query_agent) {
117  lambda(nb_so, n.second);
118  }
119  }
120 }
121 
123  const Agent& query, void* criteria) {
124  Log::Fatal("KDTreeEnvironment::ForEachNeighbor",
125  "You tried to call a specific ForEachNeighbor in an "
126  "environment that does not yet support it.");
127 }
128 
129 std::array<int32_t, 6> KDTreeEnvironment::GetDimensions() const {
130  return grid_dimensions_;
131 }
132 
133 std::array<int32_t, 2> KDTreeEnvironment::GetDimensionThresholds() const {
134  return threshold_dimensions_;
135 }
136 
138  Log::Fatal("KDTreeEnvironment::GetLoadBalanceInfo",
139  "You tried to call GetLoadBalanceInfo in an environment that does "
140  "not support it.");
141  return nullptr;
142 }
143 
146  return nullptr;
147 };
148 
150  int32_t inf = std::numeric_limits<int32_t>::max();
151  grid_dimensions_ = {inf, -inf, inf, -inf, inf, -inf};
152  threshold_dimensions_ = {inf, -inf};
153 }
154 
156  const std::array<real_t, 6>& grid_dimensions) {
157  grid_dimensions_[0] = floor(grid_dimensions[0]);
158  grid_dimensions_[2] = floor(grid_dimensions[2]);
159  grid_dimensions_[4] = floor(grid_dimensions[4]);
160  grid_dimensions_[1] = ceil(grid_dimensions[1]);
161  grid_dimensions_[3] = ceil(grid_dimensions[3]);
162  grid_dimensions_[5] = ceil(grid_dimensions[5]);
163 }
164 
166  // Determine if the grid dimensions have changed (changed in the sense that
167  // the grid has grown outwards)
168  auto min_gd =
169  *std::min_element(grid_dimensions_.begin(), grid_dimensions_.end());
170  auto max_gd =
171  *std::max_element(grid_dimensions_.begin(), grid_dimensions_.end());
172  if (min_gd < threshold_dimensions_[0]) {
173  threshold_dimensions_[0] = min_gd;
174  has_grown_ = true;
175  }
176  if (max_gd > threshold_dimensions_[1]) {
177  threshold_dimensions_[1] = max_gd;
178  has_grown_ = true;
179  }
180 }
181 
182 } // namespace bdm
bdm::AgentFlatIdxMap::Update
void Update()
Definition: agent_flat_idx_map.h:49
bdm::KDTreeEnvironment::grid_dimensions_
std::array< int32_t, 6 > grid_dimensions_
Definition: kd_tree_environment.h:106
kd_tree_environment.h
bdm::Environment::NeighborMutexBuilder
Definition: environment.h:103
bdm::AgentFlatIdxMap::GetAgentHandle
AgentHandle GetAgentHandle(uint64_t idx) const
Definition: agent_flat_idx_map.h:63
bdm::ResourceManager::GetNumAgents
size_t GetNumAgents(int numa_node=-1) const
Definition: resource_manager.h:256
bdm::KDTreeEnvironment::GetLoadBalanceInfo
LoadBalanceInfo * GetLoadBalanceInfo() override
Definition: kd_tree_environment.cc:137
bdm::KDTreeEnvironment::UpdateImplementation
void UpdateImplementation() override
Definition: kd_tree_environment.cc:49
bdm
Definition: agent.cc:39
bdm::bdm_kd_tree_t
KDTreeSingleIndexAdaptor< L2_Simple_Adaptor< real_t, NanoFlannAdapter >, NanoFlannAdapter, 3, uint64_t > bdm_kd_tree_t
Definition: kd_tree_environment.cc:29
bdm::KDTreeEnvironment::threshold_dimensions_
std::array< int32_t, 2 > threshold_dimensions_
Definition: kd_tree_environment.h:109
bdm::NanoFlannAdapter::flat_idx_map_
AgentFlatIdxMap flat_idx_map_
Definition: kd_tree_environment.h:66
bdm::Environment::CalcSimDimensionsAndLargestAgent
void CalcSimDimensionsAndLargestAgent(std::array< real_t, 6 > *ret_grid_dimensions)
Definition: environment.h:193
bdm::KDTreeEnvironment::GetDimensionThresholds
std::array< int32_t, 2 > GetDimensionThresholds() const override
Definition: kd_tree_environment.cc:133
bdm::KDTreeEnvironment::NanoflannImpl::index_
bdm_kd_tree_t * index_
Definition: kd_tree_environment.cc:32
bdm::real_t
double real_t
Definition: real_t.h:21
bdm::LoadBalanceInfo
Definition: load_balance_info.h:24
bdm::Environment::has_grown_
bool has_grown_
Definition: environment.h:126
bdm::Agent
Contains code required by all agents.
Definition: agent.h:79
bdm::Functor< void, Agent *, real_t >
bdm::KDTreeEnvironment::GetDimensions
std::array< int32_t, 6 > GetDimensions() const override
Definition: kd_tree_environment.cc:129
bdm::Math::kInfinity
static constexpr real_t kInfinity
Helpful constant to identify 'infinity'.
Definition: math.h:35
bdm::KDTreeEnvironment::NanoflannImpl
Definition: kd_tree_environment.cc:31
bdm::Simulation::GetResourceManager
ResourceManager * GetResourceManager()
Returns the ResourceManager instance.
Definition: simulation.cc:244
bdm::KDTreeEnvironment::impl_
std::unique_ptr< NanoflannImpl > impl_
Definition: kd_tree_environment.h:103
bdm::KDTreeEnvironment::GetNeighborMutexBuilder
NeighborMutexBuilder * GetNeighborMutexBuilder() override
Definition: kd_tree_environment.cc:145
bdm::Log::Fatal
static void Fatal(const std::string &location, const Args &... parts)
Prints fatal error message.
Definition: log.h:115
bdm::NanoFlannAdapter::rm_
ResourceManager * rm_
Definition: kd_tree_environment.h:67
bdm::KDTreeEnvironment::ForEachNeighbor
void ForEachNeighbor(Functor< void, Agent *, real_t > &lambda, const Agent &query, real_t squared_radius) override
Definition: kd_tree_environment.cc:93
bdm::KDTreeEnvironment::CheckGridGrowth
void CheckGridGrowth()
Definition: kd_tree_environment.cc:165
bdm::Simulation::GetParam
const Param * GetParam() const
Returns the simulation parameters.
Definition: simulation.cc:254
bdm::KDTreeEnvironment::KDTreeEnvironment
KDTreeEnvironment()
Definition: kd_tree_environment.cc:35
bdm::KDTreeEnvironment::~KDTreeEnvironment
~KDTreeEnvironment() override
Definition: kd_tree_environment.cc:44
bdm::MathArray< real_t, 3 >
bdm::Agent::GetPosition
virtual const Real3 & GetPosition() const =0
bdm::NanoFlannAdapter
Definition: kd_tree_environment.h:25
bdm::Simulation::GetActive
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
Definition: simulation.cc:68
bdm::KDTreeEnvironment::RoundOffGridDimensions
void RoundOffGridDimensions(const std::array< real_t, 6 > &grid_dimensions)
Definition: kd_tree_environment.cc:155
bdm::KDTreeEnvironment::nf_adapter_
NanoFlannAdapter * nf_adapter_
Definition: kd_tree_environment.h:110
bdm::KDTreeEnvironment::Clear
void Clear() override
Definition: kd_tree_environment.cc:149