BioDynaMo  v1.05.119-a4ff3934
model_initializer.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_MODEL_INITIALIZER_H_
16 #define CORE_MODEL_INITIALIZER_H_
17 
18 #include <Math/DistFunc.h>
19 #include <omp.h>
20 #include <ctime>
21 #include <string>
22 #include <vector>
23 
26 #include "core/resource_manager.h"
27 #include "core/simulation.h"
28 #include "core/util/random.h"
29 
30 class EulerGrid;
31 class EulerDepletionGrid;
32 
33 namespace bdm {
34 
52  template <typename Function>
53  static void Grid3D(size_t agents_per_dim, real_t space,
54  Function agent_builder) {
55 #pragma omp parallel
56  {
57  auto* sim = Simulation::GetActive();
58  auto* ctxt = sim->GetExecutionContext();
59 
60 #pragma omp for
61  for (size_t x = 0; x < agents_per_dim; x++) {
62  auto x_pos = x * space;
63  for (size_t y = 0; y < agents_per_dim; y++) {
64  auto y_pos = y * space;
65  for (size_t z = 0; z < agents_per_dim; z++) {
66  auto* new_agent = agent_builder({x_pos, y_pos, z * space});
67  ctxt->AddAgent(new_agent);
68  }
69  }
70  }
71  }
72  }
73 
91  template <typename Function>
92  static void Grid3D(const std::array<size_t, 3>& agents_per_dim, real_t space,
93  Function agent_builder) {
94 #pragma omp parallel
95  {
96  auto* sim = Simulation::GetActive();
97  auto* ctxt = sim->GetExecutionContext();
98 
99 #pragma omp for
100  for (size_t x = 0; x < agents_per_dim[0]; x++) {
101  auto x_pos = x * space;
102  for (size_t y = 0; y < agents_per_dim[1]; y++) {
103  auto y_pos = y * space;
104  for (size_t z = 0; z < agents_per_dim[2]; z++) {
105  auto* new_agent = agent_builder({x_pos, y_pos, z * space});
106  ctxt->AddAgent(new_agent);
107  }
108  }
109  }
110  }
111  }
112 
121  template <typename Function>
122  static void CreateAgents(const std::vector<Real3>& positions,
123  Function agent_builder) {
124 #pragma omp parallel
125  {
126  auto* sim = Simulation::GetActive();
127  auto* ctxt = sim->GetExecutionContext();
128 
129 #pragma omp for
130  for (size_t i = 0; i < positions.size(); i++) {
131  auto* new_agent =
132  agent_builder({positions[i][0], positions[i][1], positions[i][2]});
133  ctxt->AddAgent(new_agent);
134  }
135  }
136  }
137 
150  template <typename Function>
151  static void CreateAgentsRandom(real_t min, real_t max, uint64_t num_agents,
152  Function agent_builder,
153  DistributionRng<real_t>* rng = nullptr) {
154 #pragma omp parallel
155  {
156  auto* sim = Simulation::GetActive();
157  auto* ctxt = sim->GetExecutionContext();
158  auto* random = sim->GetRandom();
159 
160 #pragma omp for
161  for (uint64_t i = 0; i < num_agents; i++) {
162  if (rng != nullptr) {
163  Real3 pos;
164  bool in_range = false;
165  do {
166  pos = rng->Sample3();
167  in_range = (pos[0] >= min) && (pos[0] <= max) && (pos[1] >= min) &&
168  (pos[1] <= max) && (pos[2] >= min) && (pos[2] <= max);
169  } while (!in_range);
170  auto* new_agent = agent_builder(pos);
171  ctxt->AddAgent(new_agent);
172  } else {
173  auto* new_agent = agent_builder(random->UniformArray<3>(min, max));
174  ctxt->AddAgent(new_agent);
175  }
176  }
177  }
178  }
179 
213  template <typename Function>
215  real_t (*f)(const real_t*, const real_t*),
216  const FixedSizeVector<real_t, 10>& fn_params, real_t xmin, real_t xmax,
217  real_t deltax, real_t ymin, real_t ymax, real_t deltay,
218  Function agent_builder) {
219 #pragma omp parallel
220  {
221  auto* sim = Simulation::GetActive();
222  auto* ctxt = sim->GetExecutionContext();
223 
224  auto xiterations =
225  static_cast<uint64_t>(std::floor((xmax - xmin) / deltax));
226  auto yiterations =
227  static_cast<uint64_t>(std::floor((ymax - ymin) / deltay));
228 
229 #pragma omp for
230  for (uint64_t xit = 0; xit < xiterations; ++xit) {
231  real_t x = xmin + xit * deltax;
232  for (uint64_t yit = 0; yit < yiterations; ++yit) {
233  real_t y = ymin + yit * deltay;
234  Real3 pos = {x, y};
235  pos[2] = f(pos.data(), fn_params.data());
236  ctxt->AddAgent(agent_builder(pos));
237  }
238  }
239  }
240  }
241 
273  template <typename Function>
275  real_t (*f)(const real_t*, const real_t*),
276  const FixedSizeVector<real_t, 10>& fn_params, real_t xmin, real_t xmax,
277  real_t ymin, real_t ymax, uint64_t num_agents, Function agent_builder) {
278 #pragma omp parallel
279  {
280  auto* sim = Simulation::GetActive();
281  auto* ctxt = sim->GetExecutionContext();
282  auto* random = sim->GetRandom();
283 
284 #pragma omp for
285  for (uint64_t i = 0; i < num_agents; ++i) {
286  Real3 pos = {random->Uniform(xmin, xmax), random->Uniform(ymin, ymax)};
287  pos[2] = f(pos.data(), fn_params.data());
288  ctxt->AddAgent(agent_builder(pos));
289  }
290  }
291  }
292 
304  template <typename Function>
305  static void CreateAgentsOnSphereRndm(const Real3& center, real_t radius,
306  uint64_t num_agents,
307  Function agent_builder) {
308 #pragma omp parallel
309  {
310  auto* sim = Simulation::GetActive();
311  auto* ctxt = sim->GetExecutionContext();
312  auto* random = sim->GetRandom();
313 
314 #pragma omp for
315  for (uint64_t i = 0; i < num_agents; i++) {
316  auto pos = random->Sphere(radius) + center;
317  auto* new_agent = agent_builder(pos);
318  ctxt->AddAgent(new_agent);
319  }
320  }
321  }
322 
334  template <typename Function>
335  static void CreateAgentsInSphereRndm(const Real3& center, real_t radius,
336  uint64_t num_agents,
337  Function agent_builder) {
338  // We use a probability density function (PDF) to model the probability of
339  // an agent to occur at a distance `r>=0` of the center. As the surface of
340  // a sphere scales as `r^2`, the PDF does as well. Thus
341  // `p(r)=a*r^2*\Theta(R-r)`, where `\Theta` is a heavyside function and R is
342  // largest allowed radius (interpretation: no agents outside the sphere). We
343  // can fix `a` by requiring `\int_0^\inf p(r') dr' = 1` and obtain
344  // `a=3/R^3`.
345  auto radial_pdf_sphere = [](const double* x, const double* params) {
346  double R{params[0]};
347  double r{x[0]};
348  if (r > 0.0 && r <= R) {
349  return 3.0 * std::pow(r, 2.0) / std::pow(R, 3.0);
350  } else {
351  return 0.0;
352  }
353  };
354 
355  // Get a random number generator to sample from our PDF.
356  auto* random = Simulation::GetActive()->GetRandom();
357  auto rng =
358  random->GetUserDefinedDistRng1D(radial_pdf_sphere, {radius}, 0, radius);
359 
360  // Create a random radius for each of the agents. Note: this is done
361  // serially because we GetUserDefinedDistRng1D does not work in parallel
362  // regions at the moment.
363  std::vector<real_t> random_radius;
364  random_radius.resize(num_agents);
365  for (size_t i = 0; i < num_agents; i++) {
366  random_radius[i] = rng.Sample();
367  }
368 #pragma omp parallel shared(random_radius)
369  {
370  auto* ctxt_tl = Simulation::GetActive()->GetExecutionContext();
371 #pragma omp for schedule(static)
372  for (uint64_t i = 0; i < num_agents; i++) {
373  auto pos = random->Sphere(random_radius[i]) + center;
374  auto* new_agent = agent_builder(pos);
375  ctxt_tl->AddAgent(new_agent);
376  }
377  }
378  }
379 
392  static void DefineSubstance(
393  int substance_id, const std::string& substance_name,
394  real_t diffusion_coeff, real_t decay_constant, int resolution = 10,
395  const std::vector<real_t>& binding_coefficients = {},
396  const std::vector<int>& binding_substances = {});
397 
398  template <typename F>
399  static void InitializeSubstance(int substance_id, F function) {
400  auto* sim = Simulation::GetActive();
401  auto* rm = sim->GetResourceManager();
402  auto diffusion_grid = rm->GetDiffusionGrid(substance_id);
403  diffusion_grid->AddInitializer(function);
404  }
405 
411  static void AddBoundaryConditions(int substance_id,
412  BoundaryConditionType bc_type,
413  std::unique_ptr<BoundaryCondition> bc) {
414  auto* sim = Simulation::GetActive();
415  const auto* rm = sim->GetResourceManager();
416  auto diffusion_grid = rm->GetDiffusionGrid(substance_id);
417  diffusion_grid->SetBoundaryConditionType(bc_type);
418  diffusion_grid->SetBoundaryCondition(std::move(bc));
419  }
420 };
421 
422 } // namespace bdm
423 
424 #endif // CORE_MODEL_INITIALIZER_H_
bdm::ModelInitializer::CreateAgentsOnSurfaceRndm
static void CreateAgentsOnSurfaceRndm(real_t(*f)(const real_t *, const real_t *), const FixedSizeVector< real_t, 10 > &fn_params, real_t xmin, real_t xmax, real_t ymin, real_t ymax, uint64_t num_agents, Function agent_builder)
Definition: model_initializer.h:274
bdm::FixedSizeVector< real_t, 10 >
bdm::ModelInitializer::Grid3D
static void Grid3D(const std::array< size_t, 3 > &agents_per_dim, real_t space, Function agent_builder)
Definition: model_initializer.h:92
bdm
Definition: agent.cc:39
bdm::real_t
double real_t
Definition: real_t.h:21
bdm::Simulation::GetRandom
Random * GetRandom()
Returns a thread local random number generator.
Definition: simulation.cc:267
bdm::MathArray::data
const T * data() const
Definition: math_array.h:62
bdm::BoundaryConditionType
BoundaryConditionType
Available boundary conditions.
Definition: diffusion_grid.h:35
random.h
bdm::ModelInitializer
Definition: model_initializer.h:35
diffusion_grid.h
bdm::ModelInitializer::CreateAgentsOnSphereRndm
static void CreateAgentsOnSphereRndm(const Real3 &center, real_t radius, uint64_t num_agents, Function agent_builder)
Definition: model_initializer.h:305
bdm::ModelInitializer::AddBoundaryConditions
static void AddBoundaryConditions(int substance_id, BoundaryConditionType bc_type, std::unique_ptr< BoundaryCondition > bc)
Definition: model_initializer.h:411
bdm::FixedSizeVector::data
const T * data() const
Definition: fixed_size_vector.h:79
math_array.h
bdm::Random::GetUserDefinedDistRng1D
UserDefinedDistRng1D GetUserDefinedDistRng1D(double(*f)(const double *, const double *), const FixedSizeVector< real_t, 10 > &params, real_t min, real_t max, const char *option=nullptr)
Definition: random.cc:249
bdm::ModelInitializer::CreateAgentsRandom
static void CreateAgentsRandom(real_t min, real_t max, uint64_t num_agents, Function agent_builder, DistributionRng< real_t > *rng=nullptr)
Definition: model_initializer.h:151
bdm::ModelInitializer::CreateAgentsOnSurface
static void CreateAgentsOnSurface(real_t(*f)(const real_t *, const real_t *), const FixedSizeVector< real_t, 10 > &fn_params, real_t xmin, real_t xmax, real_t deltax, real_t ymin, real_t ymax, real_t deltay, Function agent_builder)
Definition: model_initializer.h:214
bdm::ModelInitializer::CreateAgentsInSphereRndm
static void CreateAgentsInSphereRndm(const Real3 &center, real_t radius, uint64_t num_agents, Function agent_builder)
Definition: model_initializer.h:335
bdm::DistributionRng< real_t >
bdm::Simulation::GetExecutionContext
ExecutionContext * GetExecutionContext()
Returns a thread local execution context.
Definition: simulation.cc:271
bdm::DistributionRng::Sample
TSample Sample()
Draws a sample from the distribution.
Definition: random.cc:133
bdm::ModelInitializer::Grid3D
static void Grid3D(size_t agents_per_dim, real_t space, Function agent_builder)
Definition: model_initializer.h:53
simulation.h
bdm::ModelInitializer::DefineSubstance
static void DefineSubstance(int substance_id, const std::string &substance_name, real_t diffusion_coeff, real_t decay_constant, int resolution=10, const std::vector< real_t > &binding_coefficients={}, const std::vector< int > &binding_substances={})
Definition: model_initializer.cc:23
bdm::ModelInitializer::CreateAgents
static void CreateAgents(const std::vector< Real3 > &positions, Function agent_builder)
Definition: model_initializer.h:122
bdm::MathArray< real_t, 3 >
bdm::ModelInitializer::InitializeSubstance
static void InitializeSubstance(int substance_id, F function)
Definition: model_initializer.h:399
resource_manager.h
bdm::Simulation::GetActive
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
Definition: simulation.cc:68