BioDynaMo
v1.05.120-25dc9790
|
Go to the documentation of this file.
15 #ifndef CORE_ENVIRONMENT_UNIFORM_GRID_ENVIRONMENT_H_
16 #define CORE_ENVIRONMENT_UNIFORM_GRID_ENVIRONMENT_H_
30 #include <parallel/algorithm>
35 #include <morton/morton.h>
54 struct InitializeGPUData;
63 friend struct ::bdm::detail::InitializeGPUData;
94 bool IsEmpty(uint64_t grid_timestamp)
const {
98 uint16_t
Size(uint64_t grid_timestamp)
const {
111 std::lock_guard<Spinlock> lock_guard(
lock_);
112 if (
length_ == std::numeric_limits<uint16_t>::max()) {
114 "UniformGridEnvironment::Box::AddObject",
115 "Box overflow. You have added too many agents to a single Box.");
123 (*successors)[ah] =
start_;
167 uint64_t grid_timestamp)
250 int32_t inf = std::numeric_limits<int32_t>::max();
265 assert(idx <= std::numeric_limits<uint32_t>::max());
266 agent->
SetBoxIdx(
static_cast<uint32_t
>(idx));
291 const Real3& pos2)
const {
292 const real_t dx = pos2[0] - pos1[0];
293 const real_t dy = pos2[1] - pos1[1];
294 const real_t dz = pos2[2] - pos1[2];
295 return (dx * dx + dy * dy + dz * dz);
300 const Real3& pos2)
const {
301 const real_t dx = pos2[0] - pos1[0];
302 const real_t dx2 = dx * dx;
303 if (dx2 > squared_radius) {
307 const real_t dy = pos2[1] - pos1[1];
308 const real_t dy2_plus_dx2 = dy * dy + dx2;
309 if (dy2_plus_dx2 > squared_radius) {
313 const real_t dz = pos2[2] - pos1[2];
314 const real_t distance = dz * dz + dy2_plus_dx2;
315 return distance < squared_radius;
332 assert(floor(position[0]) <= std::numeric_limits<int32_t>::max());
333 assert(floor(position[1]) <= std::numeric_limits<int32_t>::max());
334 assert(floor(position[2]) <= std::numeric_limits<int32_t>::max());
335 std::array<uint64_t, 3> box_coord;
363 if (point[0] >= xmin && point[0] <= xmax && point[1] >= ymin &&
364 point[1] <= ymax && point[2] >= zmin && point[2] <= zmax) {
388 std::array<uint64_t, 3> box_coord;
407 const Agent& query,
real_t squared_radius)
override {
422 const Real3& query_position,
real_t squared_radius,
423 const Agent* query_agent =
nullptr)
override {
426 "UniformGridEnvironment::ForEachNeighbor",
427 "The requested search radius (", std::sqrt(squared_radius),
")",
428 " of the neighborhood search exceeds the "
430 box_length_,
"). The resulting neighborhood would be incomplete.");
432 const auto& position = query_position;
434 uint32_t idx{std::numeric_limits<uint32_t>::max()};
435 if (query_agent !=
nullptr) {
436 idx = query_agent->GetBoxIdx();
442 idx == std::numeric_limits<uint32_t>::max()) {
444 "UniformGridEnvironment::ForEachNeighbor",
445 "You provided a query_position that is outside of the environment. ",
446 "Neighbor search is not supported in this case. \n",
447 "query_position: ", query_position,
462 if (idx == std::numeric_limits<uint32_t>::max()) {
465 assert(idx_tmp <= std::numeric_limits<uint32_t>::max());
466 idx =
static_cast<uint32_t
>(idx_tmp);
475 const unsigned batch_size = 64;
477 Agent* agents[batch_size] __attribute__((aligned(64)));
478 real_t x[batch_size] __attribute__((aligned(64)));
479 real_t y[batch_size] __attribute__((aligned(64)));
480 real_t z[batch_size] __attribute__((aligned(64)));
481 real_t squared_distance[batch_size] __attribute__((aligned(64)));
483 auto process_batch = [&]() {
485 for (uint64_t i = 0; i < size; ++i) {
486 const real_t dx = x[i] - position[0];
487 const real_t dy = y[i] - position[1];
488 const real_t dz = z[i] - position[2];
490 squared_distance[i] = dx * dx + dy * dy + dz * dz;
493 for (uint64_t i = 0; i < size; ++i) {
494 if (squared_distance[i] < squared_radius) {
495 lambda(agents[i], squared_distance[i]);
505 auto* agent = rm->GetAgent(ah);
506 if (agent != query_agent) {
507 agents[size] = agent;
508 const auto& pos = agent->GetPosition();
513 if (size == batch_size) {
533 void* criteria)
override;
562 while (mutex.test_and_set(std::memory_order_acquire)) {
571 mutex.clear(std::memory_order_release);
590 std::atomic_flag
mutex_ = ATOMIC_FLAG_INIT;
598 mutexes_.resize(grid->GetNumBoxes());
625 uint64_t start, uint64_t end,
696 std::make_unique<GridNeighborMutexBuilder>();
711 "Your agents are getting near the edge of "
712 "the simulation space. Be aware of boundary conditions that "
713 "may come into play!");
743 size_t box_idx)
const {
808 size_t box_idx)
const {
886 size_t box_idx)
const {
924 assert(index <
boxes_.size());
935 assert(index <
boxes_.size());
946 size_t GetBoxIndex(
const std::array<uint64_t, 3>& box_coord)
const {
949 assert(box_idx <
boxes_.size());
956 #endif // CORE_ENVIRONMENT_UNIFORM_GRID_ENVIRONMENT_H_
void push_back(const T &value)
Defines the 3D physical interactions between physical objects.
std::vector with parallel resize
Contains code required by all agents.
static void Warning(const std::string &location, const Args &... parts)
Prints warning message.
void SetBoxIdx(uint32_t idx)
static void Info(const std::string &location, const Args &... parts)
Prints information message.
ResourceManager * GetResourceManager()
Returns the ResourceManager instance.
static void Fatal(const std::string &location, const Args &... parts)
Prints fatal error message.
Environment * GetEnvironment()
Defines the 3D physical interactions between physical objects.
virtual const Real3 & GetPosition() const =0
static Simulation * GetActive()
This function returns the currently active Simulation simulation.