BioDynaMo  v1.05.159-3be850bb
mechanical_forces_op.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_OPERATION_MECHANICAL_FORCES_OP_H_
16 #define CORE_OPERATION_MECHANICAL_FORCES_OP_H_
17 
18 #include <array>
19 #include <cmath>
20 #include <limits>
21 #include <vector>
22 
23 #include "core/agent/agent.h"
25 #include "core/interaction_force.h"
29 #include "core/param/param.h"
30 #include "core/scheduler.h"
31 #include "core/simulation.h"
32 #include "core/util/math.h"
33 #include "core/util/thread_info.h"
34 
35 namespace bdm {
36 
40 
41  public:
43  auto* tinfo = ThreadInfo::GetInstance();
44  last_iteration_.resize(tinfo->GetMaxThreads(),
45  std::numeric_limits<uint64_t>::max());
46  last_time_run_.resize(tinfo->GetMaxThreads(), 0);
47  delta_time_.resize(tinfo->GetMaxThreads(), 0);
48  }
49 
53  delta_time_(other.delta_time_),
55  if (other.force_) {
56  force_ = other.force_->NewCopy();
57  }
58  }
59 
60  ~MechanicalForcesOp() override {
61  if (force_) {
62  delete force_;
63  }
64  }
65 
67  if (force == force_) {
68  return;
69  }
70  if (force_) {
71  delete force_;
72  }
73  force_ = force;
74  }
75 
76  void operator()(Agent* agent) override {
77  auto* sim = Simulation::GetActive();
78  auto* scheduler = sim->GetScheduler();
79  auto* param = sim->GetParam();
80 
81  // Update search radius and delta_time_ at beginning of each iteration, and
82  // avoid updating them within an iteration
83  auto current_iteration = scheduler->GetSimulatedSteps();
84  auto tid = omp_get_thread_num();
85  if (last_iteration_[tid] != current_iteration) {
86  last_iteration_[tid] = current_iteration;
87 
88  auto* grid = sim->GetEnvironment();
89  auto search_radius = grid->GetLargestAgentSize();
90  squared_radius_ = search_radius * search_radius;
91  auto current_time = (current_iteration + 1) * param->simulation_time_step;
92  delta_time_[tid] = current_time - last_time_run_[tid];
93  last_time_run_[tid] = current_time;
94  }
95 
96  const auto& displacement =
98  agent->ApplyDisplacement(displacement);
99  if (param->bound_space) {
100  ApplyBoundingBox(agent, param->bound_space, param->min_bound,
101  param->max_bound);
102  }
103  }
104 
105  private:
108  std::vector<real_t> last_time_run_;
109  std::vector<real_t> delta_time_;
110  std::vector<uint64_t> last_iteration_;
111 };
112 
113 } // namespace bdm
114 
115 #endif // CORE_OPERATION_MECHANICAL_FORCES_OP_H_
Contains code required by all agents.
Definition: agent.h:79
virtual void ApplyDisplacement(const Real3 &displacement)=0
virtual Real3 CalculateDisplacement(const InteractionForce *force, real_t squared_radius, real_t dt)=0
virtual InteractionForce * NewCopy() const
Defines the 3D physical interactions between physical objects.
void operator()(Agent *agent) override
std::vector< real_t > delta_time_
MechanicalForcesOp(const MechanicalForcesOp &other)
std::vector< uint64_t > last_iteration_
std::vector< real_t > last_time_run_
void SetInteractionForce(InteractionForce *force)
BDM_OP_HEADER(MechanicalForcesOp)
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
Definition: simulation.cc:68
static ThreadInfo * GetInstance()
Definition: thread_info.cc:21
Definition: agent.cc:39
double real_t
Definition: real_t.h:21
void ApplyBoundingBox(Agent *agent, Param::BoundSpaceMode mode, real_t lb, real_t rb)
Interface for implementing an operation.
Definition: operation.h:76