19 namespace neuroscience {
23 tension_ = param->neurite_default_tension;
26 density_ = param->neurite_default_density;
35 Base::Initialize(event);
48 diameter = e.diameter_left;
49 direction = e.direction_left;
52 diameter = e.diameter_right;
53 direction = e.direction_right;
71 auto* ne = bdm_static_cast<NeuriteElement*>(event.
new_agents[0]);
80 auto new_agent1 =
event.new_agents[0];
81 auto new_agent2 =
event.new_agents[1];
90 auto* proximal = bdm_static_cast<NeuriteElement*>(new_agent1);
94 mother_->UpdateRelative(*
this, *proximal);
98 proximal->UpdateDependentPhysicalVariables();
100 proximal->UpdateLocalCoordinateAxis();
103 auto* proximal = bdm_static_cast<NeuriteElement*>(new_agent1);
104 auto* branch = bdm_static_cast<NeuriteElement*>(new_agent2);
108 proximal->SetDaughterRight(branch->GetAgentPtr<
NeuriteElement>());
112 mother_->UpdateRelative(*
this, *proximal);
116 proximal->UpdateDependentPhysicalVariables();
118 proximal->UpdateLocalCoordinateAxis();
124 aptrs->push_back(GetAgentPtr<>());
135 return {
"mass_location_",
"diameter_",
"actual_length_",
"spring_axis_"};
215 }
else if (mother_agentma) {
216 mother_->RemoveDaughter(Base::GetAgentPtr<NeuriteElement>());
218 }
else if (mother_neurite && mother_neurite->GetDaughterRight() ==
nullptr) {
226 mother_->RemoveDaughter(Base::GetAgentPtr<NeuriteElement>());
229 mother_->UpdateDependentPhysicalVariables();
251 return bdm_static_cast<NeuriteElement*>(event.
new_agents[1]);
260 auto rand_noise = random->template UniformArray<3>(-0.1, 0.1);
263 growth_direction.Normalize();
264 return Branch(diameter, growth_direction);
270 auto rand_noise = random->template UniformArray<3>(-0.1, 0.1);
273 return Branch(branch_diameter, growth_direction);
284 const Real3& direction_1,
const Real3& direction_2) {
288 Fatal(
"NeuriteElements",
289 "Bifurcation only allowed on a terminal neurite element");
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};
301 const Real3& direction_2) {
302 Log::Fatal(
"NeuriteElement::Bifurcate",
"Not Implemented");
303 std::array<NeuriteElement*, 2> dummy;
308 const Real3& direction_1,
const Real3& direction_2) {
314 return Bifurcate(l, d, d, direction_1, direction_2);
329 spring_axis_, angle_between_branches * 0.5, perp_plane);
331 spring_axis_, -angle_between_branches * 0.5, perp_plane);
333 return Bifurcate(l, d, d, direction_1, direction_2);
350 Fatal(
"NeuriteElement",
"Given object is not a daughter!");
355 if (
mother_ == &old_relative) {
358 auto new_neurite_agent_ptr =
359 bdm_static_cast<const NeuriteElement*>(&new_relative)
372 Fatal(
"NeuriteElement",
"Given object is not the mother!");
398 }
else if (mother_agentma !=
nullptr) {
403 }
else if (actual_length_ < param->neurite_min_length &&
404 mother_neurite !=
nullptr &&
405 mother_neurite->GetRestingLength() <
407 mother_neurite->GetDaughterRight() ==
nullptr &&
411 mother_neurite->RemoveFromSimulation();
430 auto relative_ml =
mother_->OriginOf(Base::GetUid());
445 if (tension == 0.0) {
486 bdm_static_cast<const NeuriteElement*>(neighbor)->GetMother() ||
490 }
else if (
auto* neighbor_soma =
dynamic_cast<const NeuronSoma*
>(neighbor)) {
503 force_from_neighbor = force_from_neighbor *
h_over_m;
507 if (force_from_neighbor[0] != 0 || force_from_neighbor[1] != 0 ||
508 force_from_neighbor[2] != 0) {
512 if (std::abs(force_from_neighbor[3]) <
520 real_t part_for_point_mass = 1.0 - force_from_neighbor[3];
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];
535 Real3 force_on_my_mothers_point_mass{0, 0, 0};
547 force_on_my_point_mass +=
551 force_on_my_point_mass +=
555 Real3 force_from_neighbors = {0, 0, 0};
562 uint64_t non_zero_neighbor_force = 0;
567 force,
this, force_from_neighbors, force_on_my_mothers_point_mass,
570 ctxt->
ForEachNeighbor(calculate_neighbor_forces, *
this, squared_radius);
572 if (non_zero_neighbor_force > 1) {
581 force_on_my_point_mass *= h_over_m;
584 force_on_my_point_mass += force_from_neighbors;
589 if (
mother_->IsNeuriteElement()) {
590 bdm_static_cast<NeuriteElement*>(
mother_.Get())
591 ->SetStaticnessNextTimestep(
false);
593 bdm_static_cast<NeuronSoma*>(
mother_.Get())
594 ->SetStaticnessNextTimestep(
false);
600 if (force_on_my_point_mass ==
Real3{0, 0, 0}) {
604 real_t force_norm = force_on_my_point_mass.
Norm();
612 auto& displacement = force_on_my_point_mass;
613 real_t& displacement_norm = force_norm;
616 if (displacement_norm > core_param->simulation_max_displacement) {
617 displacement = displacement * (core_param->simulation_max_displacement /
626 if (displacement ==
Real3{0, 0, 0}) {
657 if (norm_of_z < 1E-10) {
672 Base::SetPropagateStaticness();
682 const Real3& position)
const {
688 const Real3& position)
const {
692 auto x = position * axis_0;
693 auto y = position * axis_1;
694 auto z = position * axis_2;
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])};
706 const Real3& position)
const {
707 return {position[0], position[2] * std::cos(position[1]),
708 position[2] * std::sin(position[1])};
712 const std::array<real_t, 2>& position)
const {
717 Real3 polar_position{position[0], position[1], r};
723 const Real3& position)
const {
780 if (
auto* mother_neurite =
782 if (mother_neurite->GetDaughterRight() ==
nullptr) {
783 length += mother_neurite->LengthToProximalBranchingPoint();
795 auto relative_ml =
mother_->OriginOf(Base::GetUid());
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;
824 str <<
"volume_: " << n.
volume_ << std::endl;
825 str <<
"diameter_: " << n.
diameter_ << std::endl;
826 str <<
"is_axon_: " << n.
is_axon_ << std::endl;
829 str <<
"tension_: " << n.
tension_ << std::endl;
838 if (mother_agentma) {
840 }
else if (mother_neurite) {
845 str <<
"mother_ " << mother << std::endl;
867 return bdm_static_cast<NeuriteElement*>(event.
new_agents[0]);
874 if (mother_neurite ==
nullptr ||
875 mother_neurite->GetDaughterRight() !=
nullptr) {
879 auto* proximal_ne = mother_neurite;
884 SetMother(mother_neurite->GetMother()->GetNeuronOrNeuriteAgentPtr());
900 proximal_ne->RemoveFromSimulation();
906 Fatal(
"NeuriteElement",
907 "Can't extend a side neurite since daughter_right is not a nullptr!");
912 return bdm_static_cast<NeuriteElement*>(event.new_agents[0]);
921 real_t new_length = param->neurite_default_actual_length;
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);
927 z_coord * soma->
kZAxis[0],
929 z_coord * soma->
kZAxis[1],
931 z_coord * soma->
kZAxis[2]};
934 auto new_begin_location = soma->
GetPosition() + (axis_direction * radius);
935 auto new_spring_axis = axis_direction * new_length;
937 auto new_mass_location = new_begin_location + new_spring_axis;
957 const Real3& direction) {
964 auto dir_1 = direction;
969 dir_1 = direction + proj;
1002 auto new_position = other_ml - (other_sa * distal_portion);
1018 const Real3& direction) {
1023 auto dir = direction;
1026 real_t angle_with_side_branch =
1028 if (angle_with_side_branch < 0.78 ||
1029 angle_with_side_branch > 2.35) {
1033 dir = direction_normalized + p;
1036 auto new_spring_axis = direction_normalized * length;