15 #ifndef CORE_AGENT_CELL_H_
16 #define CORE_AGENT_CELL_H_
23 #include <type_traits>
69 Base::Initialize(event);
74 auto* daughter =
this;
80 real_t radius = mother_cell->GetDiameter() *
real_t(0.5);
83 real_t x_coord = std::cos(cdevent.theta) * std::sin(cdevent.phi);
84 real_t y_coord = std::sin(cdevent.theta) * std::sin(cdevent.phi);
85 real_t z_coord = std::cos(cdevent.phi);
86 Real3 coords = {x_coord, y_coord, z_coord};
87 real_t total_length_of_displacement = radius /
real_t(4.0);
89 const auto& x_axis = mother_cell->kXAxis;
90 const auto& y_axis = mother_cell->kYAxis;
91 const auto& z_axis = mother_cell->kZAxis;
93 Real3 axis_of_division =
96 total_length_of_displacement;
102 real_t d_2 = total_length_of_displacement / (cdevent.volume_ratio + 1);
103 real_t d_1 = total_length_of_displacement - d_2;
105 real_t mother_volume = mother_cell->GetVolume();
106 real_t new_volume = mother_volume / (cdevent.volume_ratio + 1);
107 daughter->SetVolume(mother_volume - new_volume);
110 auto mother_pos = mother_cell->GetPosition();
111 auto new_position = mother_pos + (axis_of_division * d_2);
112 daughter->SetPosition(new_position);
116 mother_pos -= axis_of_division * d_1;
118 mother_cell->SetPosition(mother_pos);
119 mother_cell->SetVolume(new_volume);
121 daughter->SetAdherence(mother_cell->GetAdherence());
122 daughter->SetDensity(mother_cell->GetDensity());
148 real_t phi = std::acos(2 * random->Uniform(0, 1) - 1);
149 return Divide(volume_ratio, phi, theta);
168 return Divide(volume_ratio, polarcoord[1], polarcoord[2]);
177 return bdm_static_cast<Cell*>(event.
new_agents[0]);
247 Base::SetPropagateStaticness();
278 bool physical_translation =
false;
282 Real3 movement_at_next_step{0, 0, 0};
287 movement_at_next_step += tf * h;
291 Real3 translation_force_on_point_mass{0, 0, 0};
305 uint64_t non_zero_neighbor_forces = 0;
308 auto calculate_neighbor_forces =
310 auto neighbor_force = force->
Calculate(
this, neighbor);
311 if (neighbor_force[0] != 0 || neighbor_force[1] != 0 ||
312 neighbor_force[2] != 0) {
313 non_zero_neighbor_forces++;
314 translation_force_on_point_mass[0] += neighbor_force[0];
315 translation_force_on_point_mass[1] += neighbor_force[1];
316 translation_force_on_point_mass[2] += neighbor_force[2];
319 ctxt->ForEachNeighbor(calculate_neighbor_forces, *
this, squared_radius);
321 if (non_zero_neighbor_forces > 1) {
328 real_t norm_of_force = std::sqrt(translation_force_on_point_mass *
329 translation_force_on_point_mass);
336 assert(
GetMass() != 0 &&
"The mass of a cell was found to be zero!");
339 if (physical_translation) {
341 movement_at_next_step += translation_force_on_point_mass * mh;
347 if (norm_of_force * mh > param->simulation_max_displacement) {
348 movement_at_next_step.Normalize();
352 return movement_at_next_step;
Contains code required by all agents.
void SetPropagateStaticness(bool value=true)
void SetStaticnessNextTimestep(bool value) const
void CreateNewAgents(const NewAgentEvent &event, const std::initializer_list< Agent * > &prototypes)
void SetPosition(const Real3 &position) override
static const Real3 kZAxis
Third axis of the local coordinate system.
void SetAdherence(real_t adherence)
real_t diameter_
NB: Use setter and don't assign values directly.
Shape GetShape() const override
virtual Cell * Divide(real_t volume_ratio, real_t phi, real_t theta)
Divide this cell.
BDM_AGENT_HEADER(Cell, Agent, 1)
Real3 TransformCoordinatesGlobalToPolar(const Real3 &coord) const
static const Real3 kXAxis
First axis of the local coordinate system.
void SetDiameter(real_t diameter) override
void SetTractorForce(const Real3 &tractor_force)
void UpdatePosition(const Real3 &delta)
real_t adherence_
NB: Use setter and don't assign values directly.
virtual Cell * Divide(const Real3 &axis)
Divide this cell.
void MovePointMass(const Real3 &normalized_dir, real_t speed)
void SetDensity(real_t density)
void SetMass(real_t mass)
static const Real3 kYAxis
Second axis of the local coordinate system.
Cell(const Real3 &position)
real_t GetDensity() const
Real3 position_
NB: Use setter and don't assign values directly.
virtual Cell * Divide(real_t volume_ratio)
Divide this cell.
const Real3 & GetPosition() const override
real_t GetDiameter() const override
real_t density_
NB: Use setter and don't assign values directly.
real_t GetAdherence() const
void SetVolume(real_t volume)
virtual Cell * Divide()
Divide this cell.
Real3 CalculateDisplacement(const InteractionForce *force, real_t squared_radius, real_t dt) override
void ApplyDisplacement(const Real3 &displacement) override
void ChangeVolume(real_t speed)
const Real3 & GetTractorForce() const
virtual Cell * Divide(real_t volume_ratio, const Real3 &axis)
Divide this cell.
void Initialize(const NewAgentEvent &event) override
This method is used to initialise the values of daughter 2 for a cell division event.
virtual Real4 Calculate(const Agent *lhs, const Agent *rhs) const
MathArray EntryWiseProduct(const MathArray &rhs) const
Random * GetRandom()
Returns a thread local random number generator.
ExecutionContext * GetExecutionContext()
Returns a thread local execution context.
static Simulation * GetActive()
This function returns the currently active Simulation simulation.
const Param * GetParam() const
Returns the simulation parameters.
LambdaFunctor< decltype(&TLambda::operator())> L2F(const TLambda &l)
Contains the parameters to perform a cell division.
static const NewAgentEventUid kUid
static constexpr real_t kPi
value of pi
InlineVector< Agent *, 3 > new_agents
virtual NewAgentEventUid GetUid() const =0
real_t simulation_time_step
real_t simulation_max_displacement