BioDynaMo  v1.03.58-27764645
neurite_element.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 
16 #include <string>
17 
18 namespace bdm {
19 namespace neuroscience {
20 
22  auto* param = Simulation::GetActive()->GetParam()->Get<Param>();
23  tension_ = param->neurite_default_tension;
24  SetDiameter(param->neurite_default_diameter);
25  SetActualLength(param->neurite_default_actual_length);
26  density_ = param->neurite_default_density;
27  spring_constant_ = param->neurite_default_spring_constant;
28  adherence_ = param->neurite_default_adherence;
31  UpdateVolume();
32 }
33 
35  Base::Initialize(event);
36 
37  if (event.GetUid() == NewNeuriteExtensionEvent::kUid) {
38  const auto& e = static_cast<const NewNeuriteExtensionEvent&>(event);
39  auto* soma = bdm_static_cast<NeuronSoma*>(event.existing_agent);
40  InitializeNewNeuriteExtension(soma, e.diameter, e.phi, e.theta);
41  } else if (event.GetUid() == NeuriteBifurcationEvent::kUid) {
42  const auto& e = static_cast<const NeuriteBifurcationEvent&>(event);
43  auto* ne = bdm_static_cast<NeuriteElement*>(event.existing_agent);
44  real_t diameter;
45  Real3 direction;
46  if (event.new_agents.size() == 0) {
47  // left branch
48  diameter = e.diameter_left;
49  direction = e.direction_left;
50  } else {
51  // right branch
52  diameter = e.diameter_right;
53  direction = e.direction_right;
54  }
55  InitializeNeuriteBifurcation(ne, e.length, diameter, direction);
56  } else if (event.GetUid() == SideNeuriteExtensionEvent::kUid) {
57  const auto& e = static_cast<const SideNeuriteExtensionEvent&>(event);
58  auto* ne = bdm_static_cast<NeuriteElement*>(event.existing_agent);
59  InitializeSideExtensionOrBranching(ne, e.length, e.diameter, e.direction);
60  } else if (event.GetUid() == SplitNeuriteElementEvent::kUid) {
61  const auto& e = static_cast<const SplitNeuriteElementEvent&>(event);
62  auto* ne = bdm_static_cast<NeuriteElement*>(event.existing_agent);
63  InitializeSplitOrBranching(ne, e.distal_portion);
64  } else if (event.GetUid() == NeuriteBranchingEvent::kUid) {
65  const auto& e = static_cast<const NeuriteBranchingEvent&>(event);
66  if (event.new_agents.size() == 0) {
67  auto* ne = bdm_static_cast<NeuriteElement*>(event.existing_agent);
68  InitializeSplitOrBranching(ne, e.distal_portion);
69  } else {
70  // new proximal neurite element
71  auto* ne = bdm_static_cast<NeuriteElement*>(event.new_agents[0]);
72  InitializeSideExtensionOrBranching(ne, e.length, e.diameter, e.direction);
73  }
74  }
75 }
76 
78  Base::Update(event);
79 
80  auto new_agent1 = event.new_agents[0];
81  auto new_agent2 = event.new_agents[1];
82 
83  if (event.GetUid() == NeuriteBifurcationEvent::kUid) {
84  SetDaughterLeft(new_agent1->GetAgentPtr<NeuriteElement>());
85  SetDaughterRight(new_agent2->GetAgentPtr<NeuriteElement>());
86  } else if (event.GetUid() == SideNeuriteExtensionEvent::kUid) {
87  SetDaughterRight(new_agent2->GetAgentPtr<NeuriteElement>());
88  } else if (event.GetUid() == SplitNeuriteElementEvent::kUid) {
89  const auto& e = static_cast<const SplitNeuriteElementEvent&>(event);
90  auto* proximal = bdm_static_cast<NeuriteElement*>(new_agent1);
91  resting_length_ *= e.distal_portion;
92 
93  // family relations
94  mother_->UpdateRelative(*this, *proximal);
95  mother_ = proximal->GetAgentPtr<NeuronOrNeurite>();
96 
98  proximal->UpdateDependentPhysicalVariables();
99  // UpdateLocalCoordinateAxis has to come after UpdateDepend...
100  proximal->UpdateLocalCoordinateAxis();
101  } else if (event.GetUid() == NeuriteBranchingEvent::kUid) {
102  const auto& e = static_cast<const NeuriteBranchingEvent&>(event);
103  auto* proximal = bdm_static_cast<NeuriteElement*>(new_agent1);
104  auto* branch = bdm_static_cast<NeuriteElement*>(new_agent2);
105 
106  // TODO(lukas) some code duplication with SplitNeuriteElementEvent and
107  // SideNeuriteExtensionEvent event handler
108  proximal->SetDaughterRight(branch->GetAgentPtr<NeuriteElement>());
109 
110  // elongation
111  resting_length_ *= e.distal_portion;
112  mother_->UpdateRelative(*this, *proximal);
113  mother_ = proximal->GetAgentPtr<NeuronOrNeurite>();
114 
116  proximal->UpdateDependentPhysicalVariables();
117  // UpdateLocalCoordinateAxis has to come after UpdateDepend...
118  proximal->UpdateLocalCoordinateAxis();
119  }
120 }
121 
123  aptrs->reserve(4);
124  aptrs->push_back(GetAgentPtr<>());
125  aptrs->push_back(mother_);
126  if (daughter_left_) {
127  aptrs->push_back(daughter_left_);
128  }
129  if (daughter_right_) {
130  aptrs->push_back(daughter_right_);
131  }
132 }
133 
134 std::set<std::string> NeuriteElement::GetRequiredVisDataMembers() const {
135  return {"mass_location_", "diameter_", "actual_length_", "spring_axis_"};
136 }
137 
139  if (diameter > diameter_) {
141  }
142  diameter_ = diameter;
143  UpdateVolume();
144 }
145 
147  if (density > density_) {
149  }
150  density_ = density;
151 }
152 
153 void NeuriteElement::SetPosition(const Real3& position) {
154  position_ = position;
155  SetMassLocation(position + spring_axis_ * 0.5);
156 }
157 
161 }
162 
163 void NeuriteElement::SetMassLocation(const Real3& mass_location) {
164  mass_location_ = mass_location;
166 }
167 
169  if (adherence < adherence_) {
171  }
172  adherence_ = adherence;
173 }
174 
175 Real3 NeuriteElement::OriginOf(const AgentUid& daughter_uid) const {
176  return mass_location_;
177 }
178 
180  if (IsAxon()) {
182  } else {
184  }
185 };
186 
188  // check if is a terminal branch
189  if (daughter_left_ != nullptr) {
190  return;
191  }
192  // scaling for integration step
193  auto* core_param = Simulation::GetActive()->GetParam();
194  speed *= core_param->simulation_time_step;
195 
196  auto* mother_agentma = dynamic_cast<NeuronSoma*>(mother_.Get());
197  auto* mother_neurite = dynamic_cast<NeuriteElement*>(mother_.Get());
198 
199  if (actual_length_ > speed + 0.1) {
200  // if actual_length_ > length : retraction keeping the same tension
201  // (putting a limit on how short a branch can be is absolutely necessary
202  // otherwise the tension might explode)
203 
204  real_t new_actual_length = actual_length_ - speed;
205  real_t factor = new_actual_length / actual_length_;
206  SetActualLength(new_actual_length);
207  // cf removeproximalCylinder()
210  SetSpringAxis(spring_axis_ * factor);
211 
212  SetMassLocation(mother_->OriginOf(Base::GetUid()) + spring_axis_);
213  UpdatePosition();
214  UpdateVolume(); // and update concentration of internal stuff.
215  } else if (mother_agentma) {
216  mother_->RemoveDaughter(Base::GetAgentPtr<NeuriteElement>());
217  this->RemoveFromSimulation();
218  } else if (mother_neurite && mother_neurite->GetDaughterRight() == nullptr) {
219  // if actual_length_ < length and mother is a neurite element with no
220  // other daughter : merge with mother
221  RemoveProximalNeuriteElement(); // also updates volume_...
222  RetractTerminalEnd(speed / core_param->simulation_time_step);
223  } else {
224  // if mother is neurite element with other daughter or is not a neurite
225  // segment: disappear.
226  mother_->RemoveDaughter(Base::GetAgentPtr<NeuriteElement>());
227  this->RemoveFromSimulation();
228 
229  mother_->UpdateDependentPhysicalVariables();
230  }
231 }
232 
233 void NeuriteElement::ElongateTerminalEnd(real_t speed, const Real3& direction) {
234  real_t temp = direction * spring_axis_;
235  if (temp > 0) {
236  MovePointMass(speed, direction);
237  }
238 }
239 
241  return daughter_left_ != nullptr && daughter_right_ == nullptr;
242 }
243 
245  const Real3& direction, real_t length) {
246  // create a new neurite element for side branch
247  // we first split this neurite element into two pieces
248  // then append a "daughter right" between the two
249  NeuriteBranchingEvent event(0.5, length, new_branch_diameter, direction);
250  CreateNewAgents(event, {this, this});
251  return bdm_static_cast<NeuriteElement*>(event.new_agents[1]);
252 }
253 
255  return Branch(diameter_, direction);
256 }
257 
259  auto* random = Simulation::GetActive()->GetRandom();
260  auto rand_noise = random->template UniformArray<3>(-0.1, 0.1);
261  auto growth_direction = Math::Perp3(
262  GetUnitaryAxisDirectionVector() + rand_noise, random->Uniform(0, 1));
263  growth_direction.Normalize();
264  return Branch(diameter, growth_direction);
265 }
266 
268  auto* random = Simulation::GetActive()->GetRandom();
269  real_t branch_diameter = diameter_;
270  auto rand_noise = random->template UniformArray<3>(-0.1, 0.1);
271  auto growth_direction = Math::Perp3(
272  GetUnitaryAxisDirectionVector() + rand_noise, random->Uniform(0, 1));
273  return Branch(branch_diameter, growth_direction);
274 }
275 
277  auto* param = Simulation::GetActive()->GetParam()->Get<Param>();
278  return (daughter_left_ == nullptr &&
279  actual_length_ > param->neurite_minimial_bifurcation_length);
280 }
281 
282 std::array<NeuriteElement*, 2> NeuriteElement::Bifurcate(
283  real_t length, real_t diameter_1, real_t diameter_2,
284  const Real3& direction_1, const Real3& direction_2) {
285  // 1) physical bifurcation
286  // check it is a terminal branch
287  if (daughter_left_ != nullptr) {
288  Fatal("NeuriteElements",
289  "Bifurcation only allowed on a terminal neurite element");
290  }
291  NeuriteBifurcationEvent event(length, diameter_1, diameter_2, direction_1,
292  direction_2);
293  CreateNewAgents(event, {this, this});
294  auto* new_branch_l = bdm_static_cast<NeuriteElement*>(event.new_agents[0]);
295  auto* new_branch_r = bdm_static_cast<NeuriteElement*>(event.new_agents[1]);
296  return {new_branch_l, new_branch_r};
297 }
298 
299 std::array<NeuriteElement*, 2> NeuriteElement::Bifurcate(
300  real_t diameter_1, real_t diameter_2, const Real3& direction_1,
301  const Real3& direction_2) {
302  Log::Fatal("NeuriteElement::Bifurcate", "Not Implemented");
303  std::array<NeuriteElement*, 2> dummy;
304  return dummy;
305 }
306 
307 std::array<NeuriteElement*, 2> NeuriteElement::Bifurcate(
308  const Real3& direction_1, const Real3& direction_2) {
309  // initial default length :
310  auto* param = Simulation::GetActive()->GetParam()->Get<Param>();
312  // diameters :
313  real_t d = diameter_;
314  return Bifurcate(l, d, d, direction_1, direction_2);
315 }
316 
317 std::array<NeuriteElement*, 2> NeuriteElement::Bifurcate() {
318  // initial default length :
319  auto* param = Simulation::GetActive()->GetParam()->Get<Param>();
321  // diameters :
322  real_t d = diameter_;
323  // direction : (60 degrees between branches)
324  auto* random = Simulation::GetActive()->GetRandom();
325  real_t random_val = random->Uniform(0, 1);
326  auto perp_plane = Math::Perp3(spring_axis_, random_val);
327  real_t angle_between_branches = Math::kPi / 3.0;
328  auto direction_1 = Math::RotAroundAxis(
329  spring_axis_, angle_between_branches * 0.5, perp_plane);
330  auto direction_2 = Math::RotAroundAxis(
331  spring_axis_, -angle_between_branches * 0.5, perp_plane);
332 
333  return Bifurcate(l, d, d, direction_1, direction_2);
334 }
335 
337  const AgentPointer<NeuriteElement>& daughter) {
338  // If there is another daughter than the one we want to remove,
339  // we have to be sure that it will be the daughterLeft->
340  if (daughter == daughter_right_) {
341  daughter_right_ = nullptr;
342  return;
343  }
344 
345  if (daughter == daughter_left_) {
347  daughter_right_ = nullptr;
348  return;
349  }
350  Fatal("NeuriteElement", "Given object is not a daughter!");
351 }
352 
354  const NeuronOrNeurite& new_relative) {
355  if (mother_ == &old_relative) {
356  mother_ = new_relative.GetNeuronOrNeuriteAgentPtr();
357  } else {
358  auto new_neurite_agent_ptr =
359  bdm_static_cast<const NeuriteElement*>(&new_relative)
360  ->GetAgentPtr<NeuriteElement>();
361  if (daughter_left_ == &old_relative) {
362  daughter_left_ = new_neurite_agent_ptr;
363  } else if (daughter_right_ == &old_relative) {
364  daughter_right_ = new_neurite_agent_ptr;
365  }
366  }
367 }
368 
370  const NeuronOrNeurite& mother) {
371  if (mother_ != &mother) {
372  Fatal("NeuriteElement", "Given object is not the mother!");
373  return {0, 0, 0};
374  }
375 
376  // The inner tension is added to the external force that was computed
377  // earlier.
378  // (The reason for dividing by the actualLength is to normalize the
379  // direction : T = T * axis/ (axis length)
380  real_t factor = tension_ / actual_length_;
381  if (factor < 0) {
382  factor = 0;
383  }
385 }
386 
388  if (daughter_left_ != nullptr) {
389  return;
390  }
391 
392  auto* param = Simulation::GetActive()->GetParam()->Get<Param>();
393  auto* mother_agentma = dynamic_cast<NeuronSoma*>(mother_.Get());
394  auto* mother_neurite = dynamic_cast<NeuriteElement*>(mother_.Get());
395  if (actual_length_ > param->neurite_max_length) {
396  if (daughter_left_ == nullptr) { // if terminal branch :
397  SplitNeuriteElement(0.1);
398  } else if (mother_agentma != nullptr) { // if initial branch :
399  SplitNeuriteElement(0.9);
400  } else {
401  SplitNeuriteElement(0.5);
402  }
403  } else if (actual_length_ < param->neurite_min_length &&
404  mother_neurite != nullptr &&
405  mother_neurite->GetRestingLength() <
406  param->neurite_max_length - resting_length_ - 1 &&
407  mother_neurite->GetDaughterRight() == nullptr &&
408  daughter_left_ != nullptr) {
409  // if the previous branch is removed, we first remove its associated
410  // NeuriteElement
411  mother_neurite->RemoveFromSimulation();
412  // then we remove it
414  // TODO(neurites) LB: what about ourselves??
415  }
416 }
417 
418 void NeuriteElement::MovePointMass(real_t speed, const Real3& direction) {
419  // check if is a terminal branch
420  if (daughter_left_ != nullptr) {
421  return;
422  }
423 
424  // scaling for integration step
425  auto* core_param = Simulation::GetActive()->GetParam();
426  real_t length = speed * core_param->simulation_time_step;
427  auto displacement = direction.GetNormalizedArray() * length;
428  auto new_mass_location = displacement + mass_location_;
429  // here I have to define the actual length ..........
430  auto relative_ml = mother_->OriginOf(Base::GetUid()); // change to auto&&
431  SetSpringAxis(new_mass_location - relative_ml);
432  SetMassLocation(new_mass_location);
433  UpdatePosition();
435  // process of elongation : setting tension to 0 increases the resting length
437 
438  // some physics and computation obligations....
439  UpdateVolume(); // and update concentration of internal stuff.
441 }
442 
444  SetTension(tension);
445  if (tension == 0.0) {
447  } else {
448  // T = k*(A-R)/R --> R = k*A/(T+K)
451  }
452 }
453 
455  // scaling for integration step
456  auto* core_param = Simulation::GetActive()->GetParam();
457  real_t delta = speed * core_param->simulation_time_step;
458  volume_ += delta;
459 
460  if (volume_ <
461  5.2359877E-7) { // minimum volume_, corresponds to minimal diameter_
462  volume_ = 5.2359877E-7;
463  }
464  UpdateDiameter();
465 }
466 
468  // scaling for integration step
469  auto* core_param = Simulation::GetActive()->GetParam();
470  real_t delta = speed * core_param->simulation_time_step;
471  diameter_ += delta;
472  UpdateVolume();
473 }
474 
476  Agent* neighbor, real_t squared_distance) {
477  // if neighbor is a NeuriteElement
478  // use shape to determine if neighbor is a NeuriteElement
479  // this is much faster than using a dynamic_cast
480  if (neighbor->GetShape() == Shape::kCylinder) {
481  // if it is a direct relative, or sister branch, we don't take it into
482  // account
483  if (ne->GetDaughterLeft() == neighbor ||
484  ne->GetDaughterRight() == neighbor ||
485  ne->GetMother() ==
486  bdm_static_cast<const NeuriteElement*>(neighbor)->GetMother() ||
487  (ne->GetMother() == neighbor)) {
488  return;
489  }
490  } else if (auto* neighbor_soma = dynamic_cast<const NeuronSoma*>(neighbor)) {
491  // if neighbor is NeuronSoma
492  // if it is a direct relative, we don't take it into account
493  if (ne->GetMother() == neighbor_soma) {
494  return;
495  }
496  }
497 
498  Real4 force_from_neighbor = force->Calculate(ne, neighbor);
499 
500  // hack: if the neighbour is a neurite, we need to reduce the force from
501  // that neighbour in order to avoid kink behaviour
502  if (neighbor->GetShape() == Shape::kCylinder) {
503  force_from_neighbor = force_from_neighbor * h_over_m;
504  has_neurite_neighbor = true;
505  }
506 
507  if (force_from_neighbor[0] != 0 || force_from_neighbor[1] != 0 ||
508  force_from_neighbor[2] != 0) {
510  }
511 
512  if (std::abs(force_from_neighbor[3]) <
513  1E-10) { // TODO(neurites) hard coded value
514  // (if all the force is transmitted to the (distal end) point mass)
515  force_from_neighbors[0] += force_from_neighbor[0];
516  force_from_neighbors[1] += force_from_neighbor[1];
517  force_from_neighbors[2] += force_from_neighbor[2];
518  } else {
519  // (if there is a part transmitted to the proximal end)
520  real_t part_for_point_mass = 1.0 - force_from_neighbor[3];
521  force_from_neighbors[0] += force_from_neighbor[0] * part_for_point_mass;
522  force_from_neighbors[1] += force_from_neighbor[1] * part_for_point_mass;
523  force_from_neighbors[2] += force_from_neighbor[2] * part_for_point_mass;
525  force_from_neighbor[0] * force_from_neighbor[3];
527  force_from_neighbor[1] * force_from_neighbor[3];
529  force_from_neighbor[2] * force_from_neighbor[3];
530  }
531 }
532 
534  real_t squared_radius, real_t dt) {
535  Real3 force_on_my_mothers_point_mass{0, 0, 0};
536 
537  // 1) Spring force
538  // Only the spring of this cylinder. The daughters spring also act on this
539  // mass, but they are treated in point (2)
540  real_t factor = -tension_ / actual_length_; // the minus sign is important
541  // because the spring axis goes
542  // in the opposite direction
543  Real3 force_on_my_point_mass = spring_axis_ * factor;
544 
545  // 2) InteractionForce transmitted by daugthers (if they exist)
546  if (daughter_left_ != nullptr) {
547  force_on_my_point_mass +=
548  daughter_left_->ForceTransmittedFromDaugtherToMother(*this);
549  }
550  if (daughter_right_ != nullptr) {
551  force_on_my_point_mass +=
552  daughter_right_->ForceTransmittedFromDaugtherToMother(*this);
553  }
554 
555  Real3 force_from_neighbors = {0, 0, 0};
556 
557  auto* core_param = Simulation::GetActive()->GetParam();
558  // this value will be used to reduce force for neurite/neurite interactions
559  real_t h_over_m = 0.01;
560 
561  // 3) Object avoidance force
562  uint64_t non_zero_neighbor_force = 0;
563  // (We check for every neighbor object if they touch us, i.e. push us away)
564  if (!IsStatic()) {
565  has_neurite_neighbor_ = false;
566  MechanicalForcesFunctor calculate_neighbor_forces(
567  force, this, force_from_neighbors, force_on_my_mothers_point_mass,
568  h_over_m, has_neurite_neighbor_, non_zero_neighbor_force);
569  auto* ctxt = Simulation::GetActive()->GetExecutionContext();
570  ctxt->ForEachNeighbor(calculate_neighbor_forces, *this, squared_radius);
571 
572  if (non_zero_neighbor_force > 1) {
574  }
575  }
576 
577  // hack: if the neighbour is a neurite, and as we reduced the force from
578  // that neighbour, we also need to reduce my internal force (from internal
579  // tension and daughters)
580  if (has_neurite_neighbor_) {
581  force_on_my_point_mass *= h_over_m;
582  }
583 
584  force_on_my_point_mass += force_from_neighbors;
585 
586  // 5) define the force that will be transmitted to the mother
587  force_to_transmit_to_proximal_mass_ = force_on_my_mothers_point_mass;
588  if (!IsStatic() && force_to_transmit_to_proximal_mass_ != Real3{0, 0, 0}) {
589  if (mother_->IsNeuriteElement()) {
590  bdm_static_cast<NeuriteElement*>(mother_.Get())
591  ->SetStaticnessNextTimestep(false);
592  } else {
593  bdm_static_cast<NeuronSoma*>(mother_.Get())
594  ->SetStaticnessNextTimestep(false);
595  }
596  }
597  // 6.1) Define movement scale
598 
599  // 6.2) If is F not strong enough -> no movements
600  if (force_on_my_point_mass == Real3{0, 0, 0}) {
601  return {0, 0, 0};
602  }
603 
604  real_t force_norm = force_on_my_point_mass.Norm();
605  if (force_norm < adherence_) {
606  return {0, 0, 0};
607  }
608 
609  // So, what follows is only executed if we do actually move :
610 
611  // 6.3) Since there's going be a move, we calculate it
612  auto& displacement = force_on_my_point_mass;
613  real_t& displacement_norm = force_norm;
614 
615  // 6.4) There is an upper bound for the movement.
616  if (displacement_norm > core_param->simulation_max_displacement) {
617  displacement = displacement * (core_param->simulation_max_displacement /
618  displacement_norm);
619  }
620 
621  return displacement;
622 }
623 
624 void NeuriteElement::ApplyDisplacement(const Real3& displacement) {
625  // FIXME comparing real_ts
626  if (displacement == Real3{0, 0, 0}) {
627  return;
628  }
629 
630  // move of our mass
631  SetMassLocation(GetMassLocation() + displacement);
632  // Recompute length, tension and re-center the computation node, and
633  // redefine axis
636 
637  // FIXME this whole block might be superfluous - ApplyDisplacement is called
638  // For the relatives: recompute the lenght, tension etc. (why for mother?
639  // have to think about that)
640  if (daughter_left_ != nullptr) {
641  daughter_left_->UpdateDependentPhysicalVariables();
642  daughter_left_->UpdateLocalCoordinateAxis();
643  }
644  if (daughter_right_ != nullptr) {
645  daughter_right_->UpdateDependentPhysicalVariables();
646  daughter_right_->UpdateLocalCoordinateAxis();
647  }
648 }
649 
651  // x (new) = something new
652  // z (new) = x (new) cross y(old)
653  // y (new) = z(new) cross x(new)
656  real_t norm_of_z = z_axis_.Norm();
657  if (norm_of_z < 1E-10) { // TODO(neurites) use parameter
658  // If new x_axis_ and old y_axis_ are aligned, we cannot use this scheme;
659  // we start by re-defining new perp vectors. Ok, we loose the previous
660  // info, but this should almost never happen....
661  auto* random = Simulation::GetActive()->GetRandom();
662  z_axis_ = Math::Perp3(x_axis_, random->Uniform(0, 1));
663  } else {
664  z_axis_ = z_axis_ * (1 / norm_of_z);
665  }
667 }
668 
670  real_t diameter = std::sqrt(4 / Math::kPi * volume_ / actual_length_);
671  if (diameter > diameter_) {
672  Base::SetPropagateStaticness();
673  }
674  diameter_ = diameter;
675 }
676 
679 }
680 
682  const Real3& position) const {
683  auto pos = position - ProximalEnd();
684  return {pos * x_axis_, pos * y_axis_, pos * z_axis_};
685 }
686 
688  const Real3& position) const {
689  Real3 axis_0{x_axis_[0], y_axis_[0], z_axis_[0]};
690  Real3 axis_1{x_axis_[1], y_axis_[1], z_axis_[1]};
691  Real3 axis_2{x_axis_[2], y_axis_[2], z_axis_[2]};
692  auto x = position * axis_0;
693  auto y = position * axis_1;
694  auto z = position * axis_2;
695  Real3 glob{x, y, z};
696  return glob + ProximalEnd();
697 }
698 
700  const Real3& position) const {
701  return {position[0], std::atan2(position[2], position[1]),
702  std::sqrt(position[1] * position[1] + position[2] * position[2])};
703 }
704 
706  const Real3& position) const {
707  return {position[0], position[2] * std::cos(position[1]),
708  position[2] * std::sin(position[1])};
709 }
710 
712  const std::array<real_t, 2>& position) const {
713  // the position is in cylindrical coord (h,theta,r)
714  // with r being implicit (half the diameter_)
715  // We thus have h (along x_axis_) and theta (the angle from the y_axis_).
716  real_t r = 0.5 * diameter_;
717  Real3 polar_position{position[0], position[1], r};
718  auto local = TransformCoordinatesPolarToLocal(polar_position);
719  return TransformCoordinatesLocalToGlobal(local);
720 }
721 
723  const Real3& position) const {
724  auto local = TransformCoordinatesGlobalToLocal(position);
725  return TransformCoordinatesLocalToPolar(local);
726 }
727 
729  return daughter_left_;
730 }
731 
733  const AgentPointer<NeuriteElement>& daughter) {
734  daughter_left_ = daughter;
735 }
736 
738  return daughter_right_;
739 }
740 
742  const AgentPointer<NeuriteElement>& daughter) {
743  daughter_right_ = daughter;
744 }
745 
747  if (actual_length > actual_length_) {
749  }
750  actual_length_ = actual_length;
751 }
752 
754  resting_length_ = resting_length;
755 }
756 
759  spring_axis_ = axis;
760 }
761 
763  spring_constant_ = spring_constant;
764 }
765 
767  if (tension > tension_) {
769  }
770  tension_ = tension;
771 }
772 
774  real_t factor = 1.0 / actual_length_;
775  return spring_axis_ * factor;
776 }
777 
779  real_t length = actual_length_;
780  if (auto* mother_neurite =
781  dynamic_cast<const NeuriteElement*>(mother_.Get())) {
782  if (mother_neurite->GetDaughterRight() == nullptr) {
783  length += mother_neurite->LengthToProximalBranchingPoint();
784  }
785  }
786  return length;
787 }
788 
790  // local coordinate x_axis_ is equal to cylinder axis
791  return x_axis_;
792 }
793 
795  auto relative_ml = mother_->OriginOf(Base::GetUid());
796  SetSpringAxis(mass_location_ - relative_ml);
798  UpdatePosition();
799  if (std::abs(actual_length_ - resting_length_) > 1e-13) {
802  } else {
803  // avoid floating point rounding effects that increase the tension
804  SetTension(0.0);
805  }
806  UpdateVolume();
807 }
808 
809 std::ostream& operator<<(std::ostream& str, const NeuriteElement& n) {
810  auto pos = n.GetPosition();
811  str << "MassLocation: " << n.mass_location_[0] << ", "
812  << n.mass_location_[1] << ", " << n.mass_location_[2] << ", "
813  << std::endl;
814  str << "Position: " << pos[0] << ", " << pos[1] << ", " << pos[2]
815  << ", " << std::endl;
816  str << "x_axis_: " << n.x_axis_[0] << ", " << n.x_axis_[1] << ", "
817  << n.x_axis_[2] << ", " << std::endl;
818  str << "y_axis_: " << n.y_axis_[0] << ", " << n.y_axis_[1] << ", "
819  << n.y_axis_[2] << ", " << std::endl;
820  str << "z_axis_: " << n.z_axis_[0] << ", " << n.z_axis_[1] << ", "
821  << n.z_axis_[2] << ", " << std::endl;
822  str << "spring_axis_: " << n.spring_axis_[0] << ", " << n.spring_axis_[1]
823  << ", " << n.spring_axis_[2] << ", " << std::endl;
824  str << "volume_: " << n.volume_ << std::endl;
825  str << "diameter_: " << n.diameter_ << std::endl;
826  str << "is_axon_: " << n.is_axon_ << std::endl;
827  str << "branch_order_: " << n.branch_order_ << std::endl;
828  str << "actual_length_: " << n.actual_length_ << std::endl;
829  str << "tension_: " << n.tension_ << std::endl;
830  str << "spring_constant_: " << n.spring_constant_ << std::endl;
831  str << "resting_length_: " << n.resting_length_ << std::endl;
832  str << "resting_length_: " << n.resting_length_ << std::endl;
833  str << "d left : " << n.daughter_left_ << std::endl;
834  str << "d right : " << n.daughter_right_ << std::endl;
835  auto* mother_agentma = dynamic_cast<const NeuronSoma*>(n.mother_.Get());
836  auto* mother_neurite = dynamic_cast<const NeuriteElement*>(n.mother_.Get());
837  std::string mother;
838  if (mother_agentma) {
839  mother = "neuron";
840  } else if (mother_neurite) {
841  mother = "neurite";
842  } else {
843  mother = "nullptr";
844  }
845  str << "mother_ " << mother << std::endl;
846  return str;
847 }
848 
850  // TODO(neurites) adherence
851  adherence_ = rhs.GetAdherence();
852  // density_
853  SetDiameter(rhs.GetDiameter()); // also updates voluume
854  x_axis_ = rhs.GetXAxis();
855  y_axis_ = rhs.GetYAxis();
856  z_axis_ = rhs.GetZAxis();
857 
861  // TODO(neurites) what about actual length, tension and resting_length_ ??
862 }
863 
865  SplitNeuriteElementEvent event(distal_portion);
866  CreateNewAgents(event, {this});
867  return bdm_static_cast<NeuriteElement*>(event.new_agents[0]);
868 }
869 
871  // The mother is removed if (a) it is a neurite element and (b) it has no
872  // other daughter than
873  auto* mother_neurite = dynamic_cast<NeuriteElement*>(mother_.Get());
874  if (mother_neurite == nullptr ||
875  mother_neurite->GetDaughterRight() != nullptr) {
876  return;
877  }
878  // The guy we gonna remove
879  auto* proximal_ne = mother_neurite;
880 
881  // Re-organisation of the PhysicalObject tree structure: by-passing
882  // proximalCylinder
883  proximal_ne->GetMother()->UpdateRelative(*mother_, *this);
884  SetMother(mother_neurite->GetMother()->GetNeuronOrNeuriteAgentPtr());
885 
886  // Keeping the same tension :
887  // (we don't use updateDependentPhysicalVariables(), because we have tension
888  // and want to
889  // compute restingLength, and not the opposite...)
890  // T = k*(A-R)/R --> R = k*A/(T+K)
891  spring_axis_ = mass_location_ - mother_->OriginOf(Base::GetUid());
895  // .... and volume_
896  UpdateVolume();
897  // and local coord
899 
900  proximal_ne->RemoveFromSimulation();
901 }
902 
904  real_t length, real_t diameter, const Real3& direction) {
905  if (daughter_right_ != nullptr) {
906  Fatal("NeuriteElement",
907  "Can't extend a side neurite since daughter_right is not a nullptr!");
908  }
909 
910  SideNeuriteExtensionEvent event{length, diameter, direction};
911  CreateNewAgents(event, {this});
912  return bdm_static_cast<NeuriteElement*>(event.new_agents[0]);
913 }
914 
916  real_t diameter, real_t phi,
917  real_t theta) {
918  auto* param = Simulation::GetActive()->GetParam()->Get<Param>();
919 
920  real_t radius = 0.5 * soma->GetDiameter();
921  real_t new_length = param->neurite_default_actual_length;
922  // position in bdm.cells coord
923  real_t x_coord = std::sin(theta) * std::cos(phi);
924  real_t y_coord = std::sin(theta) * std::sin(phi);
925  real_t z_coord = std::cos(theta);
926  Real3 axis_direction{x_coord * soma->kXAxis[0] + y_coord * soma->kYAxis[0] +
927  z_coord * soma->kZAxis[0],
928  x_coord * soma->kXAxis[1] + y_coord * soma->kYAxis[1] +
929  z_coord * soma->kZAxis[1],
930  x_coord * soma->kXAxis[2] + y_coord * soma->kYAxis[2] +
931  z_coord * soma->kZAxis[2]};
932 
933  // positions & axis in cartesian coord
934  auto new_begin_location = soma->GetPosition() + (axis_direction * radius);
935  auto new_spring_axis = axis_direction * new_length;
936 
937  auto new_mass_location = new_begin_location + new_spring_axis;
938 
939  // set attributes of new neurite segment
940  SetDiameter(diameter);
941  UpdateVolume();
942  SetSpringAxis(new_spring_axis);
943 
944  SetMassLocation(new_mass_location);
945  UpdatePosition();
946  SetActualLength(new_length);
947  SetRestingLengthForDesiredTension(param->neurite_default_tension);
949 
950  // family relations
952 }
953 
955  real_t length,
956  real_t diameter,
957  const Real3& direction) {
958  auto* param = Simulation::GetActive()->GetParam()->Get<Param>();
959 
960  Copy(*mother);
962 
963  // check that the directions are not pointing backwards
964  auto dir_1 = direction; // todo avoid cpy
965  const auto& mother_spring_axis = mother->GetSpringAxis();
966  if (Math::AngleRadian(mother_spring_axis, direction) > Math::kPi / 2.0) {
967  auto proj = Math::ProjectionOnto(direction, mother_spring_axis);
968  proj = proj * -1;
969  dir_1 = direction + proj;
970  }
971 
972  // mass location and spring axis
973  const auto& mother_ml = mother->GetMassLocation();
974  dir_1.Normalize();
975  SetSpringAxis(dir_1 * length);
976  SetMassLocation(mother_ml + spring_axis_);
977  UpdatePosition();
978  UpdateLocalCoordinateAxis(); // (important so that x_axis_ is correct)
979 
980  // physics of tension :
981  SetActualLength(length);
982  SetRestingLengthForDesiredTension(param->neurite_default_tension);
983 
984  // set local coordinate axis in the new branches
985  // TODO(neurites) again?? alreay done a few lines up
987 
988  // 2) creating the first daughter branch
989  SetDiameter(diameter);
990  branch_order_ = mother->GetBranchOrder() + 1;
991 
993 }
994 
996  real_t distal_portion) {
997  const auto& other_ml = other->GetMassLocation();
998  const auto& other_sa = other->GetSpringAxis();
999  const auto& other_rl = other->GetRestingLength();
1000 
1001  // TODO(neurites) reformulate to mass_location_
1002  auto new_position = other_ml - (other_sa * distal_portion);
1003 
1004  SetPosition(new_position);
1005  Copy(*other);
1006  UpdatePosition();
1007 
1008  // family relations
1009  SetMother(other->GetMother()->GetNeuronOrNeuriteAgentPtr());
1011 
1012  // physics
1013  resting_length_ = ((1 - distal_portion) * other_rl);
1014 }
1015 
1017  NeuriteElement* mother, real_t length, real_t diameter,
1018  const Real3& direction) {
1019  auto* param = Simulation::GetActive()->GetParam()->Get<Param>();
1020 
1021  Copy(*mother);
1022 
1023  auto dir = direction;
1024  auto direction_normalized = direction.GetNormalizedArray();
1025  const auto& mother_spring_axis = mother->GetSpringAxis();
1026  real_t angle_with_side_branch =
1027  Math::AngleRadian(mother_spring_axis, direction);
1028  if (angle_with_side_branch < 0.78 ||
1029  angle_with_side_branch > 2.35) { // 45-135 degrees
1030  auto p = Math::CrossProduct(mother_spring_axis, direction);
1031  p = Math::CrossProduct(p, mother_spring_axis);
1032  p.Normalize();
1033  dir = direction_normalized + p;
1034  }
1035  // location of mass and computation center
1036  auto new_spring_axis = direction_normalized * length;
1037  const auto& mother_ml = mother->GetMassLocation();
1038 
1039  SetSpringAxis(new_spring_axis);
1040  SetMassLocation(mother_ml + new_spring_axis);
1041  UpdatePosition();
1042  // physics
1043  SetActualLength(length);
1044  SetRestingLengthForDesiredTension(param->neurite_default_tension);
1045  SetDiameter(param->neurite_default_diameter);
1047  // family relations
1049 
1050  branch_order_ = mother->GetBranchOrder() + 1;
1051 
1052  SetDiameter(diameter);
1053 
1054  // correct physical values (has to be after family relations
1056 }
1057 
1058 } // namespace neuroscience
1059 } // namespace bdm
bdm::NewAgentEvent
Definition: new_agent_event.h:61
bdm::Agent::SetStaticnessNextTimestep
void SetStaticnessNextTimestep(bool value) const
Definition: agent.h:176
bdm::neuroscience::NeuriteElement::GetSpringAxis
const Real3 & GetSpringAxis() const
Definition: neurite_element.h:405
bdm::neuroscience::NeuriteElement::MechanicalForcesFunctor::has_neurite_neighbor
bool & has_neurite_neighbor
Definition: neurite_element.h:260
bdm::InteractionForce::Calculate
virtual Real4 Calculate(const Agent *lhs, const Agent *rhs) const
Definition: interaction_force.cc:33
bdm::neuroscience::NeuriteElement::TransformCoordinatesPolarToLocal
Real3 TransformCoordinatesPolarToLocal(const Real3 &position) const
Definition: neurite_element.cc:705
bdm::neuroscience::NeuriteElement::mother_
AgentPointer< NeuronOrNeurite > mother_
Definition: neurite_element.h:486
bdm::neuroscience::NeuriteElement::SetMother
void SetMother(const AgentPointer< NeuronOrNeurite > &mother)
Definition: neurite_element.h:375
bdm::neuroscience::NeuriteElement::ApplyDisplacement
void ApplyDisplacement(const Real3 &displacement) override
Definition: neurite_element.cc:624
bdm::neuroscience::NeuriteElement::Update
void Update(const NewAgentEvent &event) override
Definition: neurite_element.cc:77
bdm::neuroscience::NeuriteElement::MechanicalForcesFunctor::force_from_neighbors
Real3 & force_from_neighbors
Definition: neurite_element.h:257
bdm::neuroscience::NewNeuriteExtensionEvent
Contains the parameters to extend a new neurite from a neuron soma.
Definition: new_neurite_extension_event.h:27
bdm::neuroscience::NeuriteElement::UpdateDiameter
void UpdateDiameter()
Recomputes diameter after volume has changed.
Definition: neurite_element.cc:669
bdm::neuroscience::NeuriteElement::InitializeSideExtensionOrBranching
void InitializeSideExtensionOrBranching(NeuriteElement *mother, real_t length, real_t diameter, const Real3 &direction)
Definition: neurite_element.cc:1016
bdm::neuroscience::NeuriteElement::ProximalEnd
Real3 ProximalEnd() const
Definition: neurite_element.h:429
bdm::neuroscience::NeuriteElement::TransformCoordinatesGlobalToPolar
Real3 TransformCoordinatesGlobalToPolar(const Real3 &position) const
G -> L : G -> L, then L -> P.
Definition: neurite_element.cc:722
bdm::neuroscience::NeuriteElement::RemoveDaughter
void RemoveDaughter(const AgentPointer< NeuriteElement > &daughter) override
Definition: neurite_element.cc:336
bdm::neuroscience::SplitNeuriteElementEvent::kUid
static const NewAgentEventUid kUid
Definition: split_neurite_element_event.h:29
bdm::neuroscience::NeuriteElement::GetXAxis
const Real3 & GetXAxis() const
Definition: neurite_element.h:97
bdm
Definition: agent.cc:39
bdm::Agent::RemoveFromSimulation
virtual void RemoveFromSimulation()
Definition: agent.cc:159
bdm::neuroscience::NeuriteElement::GetRestingLength
real_t GetRestingLength() const
Definition: neurite_element.h:401
bdm::neuroscience::NeuriteElement::Initialize
void Initialize(const NewAgentEvent &event) override
Definition: neurite_element.cc:34
bdm::neuroscience::NeuriteElement::SetDensity
void SetDensity(real_t density)
Definition: neurite_element.cc:146
bdm::InteractionForce
Definition: interaction_force.h:26
bdm::Agent::CreateNewAgents
void CreateNewAgents(const NewAgentEvent &event, const std::initializer_list< Agent * > &prototypes)
Definition: agent.h:121
bdm::AgentPointer
Definition: agent_pointer.h:58
bdm::neuroscience::NeuriteElement::SetRestingLengthForDesiredTension
void SetRestingLengthForDesiredTension(real_t tension)
Definition: neurite_element.cc:443
bdm::neuroscience::NeuriteElement::diameter_
real_t diameter_
NB: Use setter and don't assign values directly.
Definition: neurite_element.h:470
bdm::neuroscience::NeuriteElement::GetIdentifierSWC
virtual StructureIdentifierSWC GetIdentifierSWC() const override
Definition: neurite_element.cc:179
bdm::neuroscience::NeuriteElement::RetractTerminalEnd
void RetractTerminalEnd(real_t speed)
Definition: neurite_element.cc:187
bdm::neuroscience::NeuriteElement::BranchPermitted
bool BranchPermitted() const
Definition: neurite_element.cc:240
bdm::ExecutionContext::ForEachNeighbor
virtual void ForEachNeighbor(Functor< void, Agent * > &lambda, const Agent &query, void *criteria)=0
bdm::neuroscience::NeuriteElement::UpdatePosition
void UpdatePosition()
Definition: neurite_element.cc:158
bdm::neuroscience::NeuronOrNeurite::GetNeuronOrNeuriteAgentPtr
AgentPointer< NeuronOrNeurite > GetNeuronOrNeuriteAgentPtr() const
Definition: neuron_or_neurite.cc:24
bdm::neuroscience::NeuriteElement::MechanicalForcesFunctor::ne
NeuriteElement * ne
Definition: neurite_element.h:256
bdm::neuroscience::NeuriteElement::UpdateRelative
void UpdateRelative(const NeuronOrNeurite &old_relative, const NeuronOrNeurite &new_relative) override
Definition: neurite_element.cc:353
bdm::neuroscience::NeuriteElement::Branch
NeuriteElement * Branch()
Create a branch for this neurite element.
Definition: neurite_element.cc:267
bdm::neuroscience::NeuriteElement::SetSpringConstant
void SetSpringConstant(real_t spring_constant)
Definition: neurite_element.cc:762
bdm::Math::Perp3
static Real3 Perp3(const Real3 &a, real_t random)
Definition: math.h:68
bdm::real_t
double real_t
Definition: real_t.h:21
bdm::neuroscience::NeuriteElement::CalculateDisplacement
Real3 CalculateDisplacement(const InteractionForce *force, real_t squared_radius, real_t dt) override
Definition: neurite_element.cc:533
bdm::neuroscience::NeuriteElement::MechanicalForcesFunctor
Definition: neurite_element.h:254
bdm::neuroscience::NeuriteElement::GetAxis
const Real3 & GetAxis() const
Returns the axis direction of a neurite element.
Definition: neurite_element.cc:789
bdm::neuroscience::kApicalDendrite
@ kApicalDendrite
Definition: neuron_or_neurite.h:37
bdm::neuroscience::NeuriteBranchingEvent::kUid
static const NewAgentEventUid kUid
Definition: neurite_branching_event.h:32
bdm::neuroscience::NeuriteElement::y_axis_
Real3 y_axis_
Second axis of the local coordinate system.
Definition: neurite_element.h:478
bdm::neuroscience::NeuriteElement::adherence_
real_t adherence_
NB: Use setter and don't assign values directly.
Definition: neurite_element.h:474
bdm::Simulation::GetRandom
Random * GetRandom()
Returns a thread local random number generator.
Definition: simulation.cc:284
bdm::neuroscience::NeuriteBifurcationEvent
Contains the parameters to bifurcate a growth cone.
Definition: neurite_bifurcation_event.h:32
bdm::neuroscience::NeuriteElement::RunDiscretization
void RunDiscretization() override
Definition: neurite_element.cc:387
bdm::neuroscience::NeuriteElement::SetRestingLength
void SetRestingLength(real_t resting_length)
Definition: neurite_element.cc:753
bdm::neuroscience::NeuriteElement::ChangeDiameter
void ChangeDiameter(real_t speed)
Definition: neurite_element.cc:467
neurite_element.h
bdm::neuroscience::NeuronSoma
Definition: neuron_soma.h:30
bdm::Agent::GetShape
virtual Shape GetShape() const =0
bdm::neuroscience::NeuriteElement::spring_axis_
Real3 spring_axis_
Definition: neurite_element.h:505
bdm::Cell::kYAxis
static const Real3 kYAxis
Second axis of the local coordinate system.
Definition: cell.h:47
bdm::neuroscience::NeuriteElement::ExtendSideNeuriteElement
NeuriteElement * ExtendSideNeuriteElement(real_t length, real_t diameter, const Real3 &direction)
Extend a side neurite element and assign it to daughter right.
Definition: neurite_element.cc:903
bdm::neuroscience::NeuriteElement::IsAxon
bool IsAxon() const
Definition: neurite_element.h:367
bdm::neuroscience::SplitNeuriteElementEvent
Contains the parameters to split a neurite element into two segments.
Definition: split_neurite_element_event.h:28
bdm::neuroscience::NeuriteElement::OriginOf
Real3 OriginOf(const AgentUid &daughter_uid) const override
Definition: neurite_element.cc:175
bdm::Cell::GetPosition
const Real3 & GetPosition() const override
Definition: cell.h:188
bdm::Agent::SetPropagateStaticness
void SetPropagateStaticness(bool value=true)
Definition: agent.h:184
bdm::neuroscience::NeuriteElement::TransformCoordinatesGlobalToLocal
Real3 TransformCoordinatesGlobalToLocal(const Real3 &position) const
Definition: neurite_element.cc:681
bdm::Random::Uniform
real_t Uniform(real_t max=1.0)
Definition: random.cc:62
bdm::NewAgentEvent::existing_agent
Agent * existing_agent
Definition: new_agent_event.h:69
bdm::neuroscience::NeuriteElement::SetTension
void SetTension(real_t tension)
Definition: neurite_element.cc:766
bdm::neuroscience::NeuriteElement::NeuriteElement
NeuriteElement()
Definition: neurite_element.cc:21
bdm::neuroscience::NeuriteElement::Bifurcate
std::array< NeuriteElement *, 2 > Bifurcate()
Growth cone bifurcation.
Definition: neurite_element.cc:317
bdm::neuroscience::NeuriteElement::TransformCoordinatesLocalToGlobal
Real3 TransformCoordinatesLocalToGlobal(const Real3 &position) const
Definition: neurite_element.cc:687
bdm::neuroscience::NeuriteElement::TransformCoordinatesPolarToGlobal
Real3 TransformCoordinatesPolarToGlobal(const std::array< real_t, 2 > &position) const
P -> G : P -> L, then L -> G.
Definition: neurite_element.cc:711
bdm::Agent
Contains code required by all agents.
Definition: agent.h:79
bdm::neuroscience::NeuriteElement::MechanicalForcesFunctor::operator()
void operator()(Agent *neighbor, real_t squared_distance) override
Definition: neurite_element.cc:475
bdm::neuroscience::NeuriteElement::spring_constant_
real_t spring_constant_
Definition: neurite_element.h:517
bdm::Param::Get
const TParamGroup * Get() const
Definition: param.h:59
bdm::neuroscience::NeuriteElement::resting_length_
real_t resting_length_
Definition: neurite_element.h:521
bdm::neuroscience::NeuriteElement::UpdateDependentPhysicalVariables
void UpdateDependentPhysicalVariables() override
Definition: neurite_element.cc:794
bdm::neuroscience::NeuriteElement::z_axis_
Real3 z_axis_
Third axis of the local coordinate system.
Definition: neurite_element.h:480
bdm::neuroscience::NeuriteElement::GetPosition
const Real3 & GetPosition() const override
Definition: neurite_element.h:82
bdm::neuroscience::NeuriteElement::force_to_transmit_to_proximal_mass_
Real3 force_to_transmit_to_proximal_mass_
The part of the inter-object force transmitted to the mother (parent node)
Definition: neurite_element.h:500
bdm::neuroscience::Param
Definition: param.h:32
bdm::Math::AngleRadian
static real_t AngleRadian(const Real3 &a, const Real3 &b)
Definition: math.h:108
bdm::neuroscience::NeuriteElement::GetRequiredVisDataMembers
std::set< std::string > GetRequiredVisDataMembers() const override
Definition: neurite_element.cc:134
bdm::neuroscience::NeuriteElement::SetAdherence
void SetAdherence(real_t adherence)
Definition: neurite_element.cc:168
bdm::neuroscience::NeuriteElement::GetAdherence
real_t GetAdherence() const
Definition: neurite_element.h:93
bdm::neuroscience::NeuriteElement::SplitNeuriteElement
NeuriteElement * SplitNeuriteElement(real_t distal_portion=0.5)
Split this neurite element into two segments.
Definition: neurite_element.cc:864
bdm::neuroscience::NeuronOrNeurite
Definition: neuron_or_neurite.h:42
bdm::Math::CrossProduct
static MathArray< real_t, N > CrossProduct(const MathArray< real_t, N > &a, const MathArray< real_t, N > &b)
Definition: math.h:54
bdm::neuroscience::NeuriteElement::GetDaughterRight
const AgentPointer< NeuriteElement > & GetDaughterRight() const
Definition: neurite_element.cc:737
bdm::MathArray::Norm
T Norm() const
Definition: math_array.h:352
bdm::neuroscience::NeuriteElement::MechanicalForcesFunctor::non_zero_neighbor_force
uint64_t & non_zero_neighbor_force
Definition: neurite_element.h:261
bdm::neuroscience::NeuriteElement::GetBranchOrder
int GetBranchOrder() const
Definition: neurite_element.h:392
bdm::neuroscience::NeuriteElement::mass_location_
Real3 mass_location_
Definition: neurite_element.h:463
bdm::Param::simulation_time_step
real_t simulation_time_step
Definition: param.h:185
bdm::neuroscience::NeuriteElement::ChangeVolume
void ChangeVolume(real_t speed)
Definition: neurite_element.cc:454
bdm::neuroscience::NeuriteElement::GetZAxis
const Real3 & GetZAxis() const
Definition: neurite_element.h:99
bdm::neuroscience::NeuriteBranchingEvent
This event splits the current neurite element into two elements and adds a new side branch as daughte...
Definition: neurite_branching_event.h:31
bdm::neuroscience::NeuriteElement::CriticalRegion
void CriticalRegion(std::vector< AgentPointer<>> *aptrs) override
Definition: neurite_element.cc:122
bdm::neuroscience::NeuriteElement::position_
Real3 position_
position_ is the middle point of cylinder
Definition: neurite_element.h:466
bdm::neuroscience::NeuriteElement::GetMassLocation
const Real3 & GetMassLocation() const
return end of neurite element position
Definition: neurite_element.h:89
bdm::neuroscience::NeuriteElement::SetDaughterRight
void SetDaughterRight(const AgentPointer< NeuriteElement > &daughter)
Definition: neurite_element.cc:741
bdm::neuroscience::NeuriteElement::InitializeSplitOrBranching
void InitializeSplitOrBranching(NeuriteElement *other, real_t distal_portion)
Definition: neurite_element.cc:995
bdm::neuroscience::NeuriteElement::daughter_left_
AgentPointer< NeuriteElement > daughter_left_
Definition: neurite_element.h:490
bdm::neuroscience::StructureIdentifierSWC
StructureIdentifierSWC
Definition: neuron_or_neurite.h:32
bdm::neuroscience::NeuriteElement::UpdateVolume
void UpdateVolume()
Recomputes volume, after diameter has been changed.
Definition: neurite_element.cc:677
bdm::neuroscience::SideNeuriteExtensionEvent
Contains the parameters to add a side neurite element.
Definition: side_neurite_extension_event.h:27
bdm::neuroscience::NeuriteElement::tension_
real_t tension_
Definition: neurite_element.h:513
bdm::NewAgentEvent::new_agents
InlineVector< Agent *, 3 > new_agents
Definition: new_agent_event.h:73
bdm::neuroscience::NeuriteElement::MechanicalForcesFunctor::force
const InteractionForce * force
Definition: neurite_element.h:255
bdm::neuroscience::NeuriteElement::ElongateTerminalEnd
void ElongateTerminalEnd(real_t speed, const Real3 &direction)
Definition: neurite_element.cc:233
bdm::neuroscience::NeuriteElement::MechanicalForcesFunctor::h_over_m
real_t & h_over_m
Definition: neurite_element.h:259
bdm::neuroscience::NeuriteElement::SetDaughterLeft
void SetDaughterLeft(const AgentPointer< NeuriteElement > &daughter)
Definition: neurite_element.cc:732
bdm::Log::Fatal
static void Fatal(const std::string &location, const Args &... parts)
Prints fatal error message.
Definition: log.h:115
bdm::neuroscience::NeuriteElement::SetActualLength
void SetActualLength(real_t actual_length)
Should not be used, since the actual length depends on the geometry.
Definition: neurite_element.cc:746
bdm::neuroscience::NeuriteElement::GetMother
AgentPointer< NeuronOrNeurite > & GetMother()
Definition: neurite_element.h:371
bdm::neuroscience::NeuriteElement::LengthToProximalBranchingPoint
real_t LengthToProximalBranchingPoint() const
Definition: neurite_element.cc:778
bdm::neuroscience::NeuriteElement::GetSpringConstant
real_t GetSpringConstant() const
Definition: neurite_element.h:409
bdm::neuroscience::NeuriteElement::daughter_right_
AgentPointer< NeuriteElement > daughter_right_
Definition: neurite_element.h:493
bdm::neuroscience::NeuriteElement::GetDiameter
real_t GetDiameter() const override
Definition: neurite_element.h:103
bdm::neuroscience::NeuriteElement::SetDiameter
void SetDiameter(real_t diameter) override
Definition: neurite_element.cc:138
bdm::neuroscience::NeuriteElement::density_
real_t density_
NB: Use setter and don't assign values directly.
Definition: neurite_element.h:472
bdm::Cell::GetDiameter
real_t GetDiameter() const override
Definition: cell.h:182
bdm::neuroscience::NeuriteElement::x_axis_
Real3 x_axis_
First axis of the local coordinate system equal to cylinder axis.
Definition: neurite_element.h:476
bdm::Agent::GetAgentPtr
AgentPointer< TAgent > GetAgentPtr() const
Return agent pointer.
Definition: agent.h:208
bdm::neuroscience::NeuriteElement::volume_
real_t volume_
Definition: neurite_element.h:468
bdm::AgentUid
Definition: agent_uid.h:25
bdm::neuroscience::NeuriteBifurcationEvent::kUid
static const NewAgentEventUid kUid
Definition: neurite_bifurcation_event.h:33
bdm::Math::RotAroundAxis
static Real3 RotAroundAxis(const Real3 &vector, real_t theta, const Real3 &axis)
Definition: math.h:92
bdm::neuroscience::NeuriteElement::InitializeNeuriteBifurcation
void InitializeNeuriteBifurcation(NeuriteElement *mother, real_t length, real_t diameter, const Real3 &direction)
TODO.
Definition: neurite_element.cc:954
bdm::neuroscience::NeuriteElement::UpdateLocalCoordinateAxis
void UpdateLocalCoordinateAxis()
Definition: neurite_element.cc:650
bdm::Simulation::GetExecutionContext
ExecutionContext * GetExecutionContext()
Returns a thread local execution context.
Definition: simulation.cc:288
bdm::neuroscience::NeuriteElement::SetPosition
void SetPosition(const Real3 &position) override
Definition: neurite_element.cc:153
bdm::neuroscience::NeuriteElement::TransformCoordinatesLocalToPolar
Real3 TransformCoordinatesLocalToPolar(const Real3 &position) const
Definition: neurite_element.cc:699
bdm::neuroscience::NeuriteElement::BifurcationPermitted
bool BifurcationPermitted() const
Definition: neurite_element.cc:276
bdm::neuroscience::NeuriteElement::ForceTransmittedFromDaugtherToMother
Real3 ForceTransmittedFromDaugtherToMother(const NeuronOrNeurite &mother)
Definition: neurite_element.cc:369
bdm::NewAgentEvent::GetUid
virtual NewAgentEventUid GetUid() const =0
bdm::neuroscience::NeuriteElement::InitializeNewNeuriteExtension
void InitializeNewNeuriteExtension(NeuronSoma *soma, real_t diameter, real_t phi, real_t theta)
TODO.
Definition: neurite_element.cc:915
bdm::Cell::kXAxis
static const Real3 kXAxis
First axis of the local coordinate system.
Definition: cell.h:45
bdm::neuroscience::NeuriteElement::SetMassLocation
void SetMassLocation(const Real3 &mass_location)
Definition: neurite_element.cc:163
bdm::Math::kPi
static constexpr real_t kPi
value of pi
Definition: math.h:33
bdm::neuroscience::NeuriteElement::branch_order_
int branch_order_
Definition: neurite_element.h:497
bdm::neuroscience::kAxon
@ kAxon
Definition: neuron_or_neurite.h:35
bdm::Simulation::GetParam
const Param * GetParam() const
Returns the simulation parameters.
Definition: simulation.cc:271
bdm::neuroscience::NeuriteElement::GetYAxis
const Real3 & GetYAxis() const
Definition: neurite_element.h:98
bdm::neuroscience::NeuriteElement::MovePointMass
void MovePointMass(real_t speed, const Real3 &direction)
Definition: neurite_element.cc:418
bdm::neuroscience::NeuriteElement::actual_length_
real_t actual_length_
Definition: neurite_element.h:509
bdm::neuroscience::NeuriteElement::RemoveProximalNeuriteElement
void RemoveProximalNeuriteElement()
Definition: neurite_element.cc:870
bdm::MathArray< real_t, 3 >
bdm::Math::ProjectionOnto
static Real3 ProjectionOnto(const Real3 &a, const Real3 &b)
Definition: math.h:116
bdm::kCylinder
@ kCylinder
Definition: shape.h:20
bdm::Simulation::GetActive
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
Definition: simulation.cc:67
bdm::neuroscience::NeuriteElement::MechanicalForcesFunctor::force_on_my_mothers_point_mass
Real3 & force_on_my_mothers_point_mass
Definition: neurite_element.h:258
bdm::neuroscience::Param::neurite_default_actual_length
real_t neurite_default_actual_length
Definition: param.h:41
bdm::neuroscience::NeuriteElement::operator<<
friend std::ostream & operator<<(std::ostream &str, const NeuriteElement &n)
Definition: neurite_element.cc:809
bdm::neuroscience::NeuriteElement::is_axon_
bool is_axon_
Definition: neurite_element.h:482
bdm::neuroscience::NeuriteElement::Copy
void Copy(const NeuriteElement &rhs)
Definition: neurite_element.cc:849
bdm::neuroscience::NewNeuriteExtensionEvent::kUid
static const NewAgentEventUid kUid
Definition: new_neurite_extension_event.h:28
bdm::neuroscience::NeuriteElement::SetSpringAxis
void SetSpringAxis(const Real3 &axis)
Definition: neurite_element.cc:757
bdm::Agent::IsStatic
bool IsStatic() const
Definition: agent.h:204
bdm::Cell::kZAxis
static const Real3 kZAxis
Third axis of the local coordinate system.
Definition: cell.h:49
bdm::neuroscience::NeuriteElement::GetUnitaryAxisDirectionVector
Real3 GetUnitaryAxisDirectionVector() const
Definition: neurite_element.cc:773
bdm::MathArray::Normalize
void Normalize()
Normalize the array in-place.
Definition: math_array.h:364
bdm::MathArray::GetNormalizedArray
MathArray GetNormalizedArray() const
Get a nomalized copy of the MathArray.
Definition: math_array.h:386
bdm::neuroscience::SideNeuriteExtensionEvent::kUid
static const NewAgentEventUid kUid
Definition: side_neurite_extension_event.h:28
bdm::neuroscience::NeuriteElement::has_neurite_neighbor_
bool has_neurite_neighbor_
Helper variable needed in CalculateDisplacement.
Definition: neurite_element.h:524
bdm::neuroscience::NeuriteElement::GetDaughterLeft
const AgentPointer< NeuriteElement > & GetDaughterLeft() const
Definition: neurite_element.cc:728
bdm::neuroscience::NeuriteElement
Definition: neurite_element.h:56