void DeltaNotchTrackingModifier<DIM>::UpdateCellData(AbstractCellPopulation<DIM,DIM>& rCellPopulation) { // Make sure the cell population is updated rCellPopulation.Update(); // First recover each cell's Notch and Delta concentrations from the ODEs and store in CellData for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = rCellPopulation.Begin(); cell_iter != rCellPopulation.End(); ++cell_iter) { DeltaNotchCellCycleModel* p_model = static_cast<DeltaNotchCellCycleModel*>(cell_iter->GetCellCycleModel()); double this_delta = p_model->GetDelta(); double this_notch = p_model->GetNotch(); // Note that the state variables must be in the same order as listed in DeltaNotchOdeSystem cell_iter->GetCellData()->SetItem("notch", this_notch); cell_iter->GetCellData()->SetItem("delta", this_delta); } // Next iterate over the population to compute and store each cell's neighbouring Delta concentration in CellData for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = rCellPopulation.Begin(); cell_iter != rCellPopulation.End(); ++cell_iter) { // Get the set of neighbouring location indices std::set<unsigned> neighbour_indices = rCellPopulation.GetNeighbouringLocationIndices(*cell_iter); // Compute this cell's average neighbouring Delta concentration and store in CellData if (!neighbour_indices.empty()) { double mean_delta = 0.0; for (std::set<unsigned>::iterator iter = neighbour_indices.begin(); iter != neighbour_indices.end(); ++iter) { CellPtr p_cell = rCellPopulation.GetCellUsingLocationIndex(*iter); double this_delta = p_cell->GetCellData()->GetItem("delta"); mean_delta += this_delta/neighbour_indices.size(); } cell_iter->GetCellData()->SetItem("mean delta", mean_delta); } else { // If this cell has no neighbours, such as an isolated cell in a CaBasedCellPopulation, store 0.0 for the cell data cell_iter->GetCellData()->SetItem("mean delta", 0.0); } } }
void VolumeTrackingModifier<DIM>::UpdateCellData(AbstractCellPopulation<DIM,DIM>& rCellPopulation) { // Make sure the cell population is updated rCellPopulation.Update(); /** * This hack is needed because in the case of a MeshBasedCellPopulation in which * multiple cell divisions have occurred over one time step, the Voronoi tessellation * (while existing) is out-of-date. Thus, if we did not regenerate the Voronoi * tessellation here, an assertion may trip as we try to access a Voronoi element * whose index exceeds the number of elements in the out-of-date tessellation. * * \todo work out how to properly fix this (#1986) */ if (bool(dynamic_cast<MeshBasedCellPopulation<DIM>*>(&rCellPopulation))) { static_cast<MeshBasedCellPopulation<DIM>*>(&(rCellPopulation))->CreateVoronoiTessellation(); } // Iterate over cell population for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = rCellPopulation.Begin(); cell_iter != rCellPopulation.End(); ++cell_iter) { // Get the volume of this cell double cell_volume = rCellPopulation.GetVolumeOfCell(*cell_iter); // Store the cell's volume in CellData cell_iter->GetCellData()->SetItem("volume", cell_volume); } }
void GonadArmPositionTrackerModifier<DIM>::UpdateAtEndOfTimeStep(AbstractCellPopulation<DIM,DIM>& rCellPopulation) { if((SimulationTime::Instance()->GetTime())-(int)SimulationTime::Instance()->GetTime()==(1/250)) for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = rCellPopulation.Begin(); cell_iter != rCellPopulation.End(); ++cell_iter) { double id = cell_iter->GetCellId(); double position = cell_iter->GetCellData()->GetItem("DistanceAwayFromDTC"); double prolif = cell_iter->GetCellData()->GetItem("Proliferating"); fprintf(OutputPositionFile,"%e\t",SimulationTime::Instance()->GetTime()); fprintf(OutputPositionFile,"%f\t",id); fprintf(OutputPositionFile,"%e\t",position); fprintf(OutputPositionFile,"%e\t",prolif); fprintf(OutputPositionFile,"\n"); } if(SimulationTime::Instance()->IsFinished()){ //Close output file fclose(OutputPositionFile); } }
void CryptProjectionForce::UpdateNode3dLocationMap(AbstractCellPopulation<2>& rCellPopulation) { mNode3dLocationMap.clear(); c_vector<double, 2> node_location_2d; c_vector<double, 3> node_location_3d; // Only consider nodes corresponding to real cells for (AbstractCellPopulation<2>::Iterator cell_iter = rCellPopulation.Begin(); cell_iter != rCellPopulation.End(); ++cell_iter) { // Get node index unsigned node_index = rCellPopulation.GetLocationIndexUsingCell(*cell_iter); // Get 3D location node_location_2d = rCellPopulation.GetLocationOfCellCentre(*cell_iter); node_location_3d[0] = node_location_2d[0]; node_location_3d[1] = node_location_2d[1]; node_location_3d[2] = CalculateCryptSurfaceHeightAtPoint(node_location_2d); // Add to map mNode3dLocationMap[node_index] = node_location_3d; } }
/* * Next, we define the {{{UpdateCellData()}}} method itself. This is a helper * method that computes the height (y coordinate) of each cell in the population * and stores this in the {{{CellData}}} property. */ void UpdateCellData(AbstractCellPopulation<2,2>& rCellPopulation) { /* * We begin by calling {{{Update()}}} on the cell population, which ensures that * it is in a coherent state. */ rCellPopulation.Update(); /* * Next, we iterate over the cell population... */ for (AbstractCellPopulation<2>::Iterator cell_iter = rCellPopulation.Begin(); cell_iter != rCellPopulation.End(); ++cell_iter) { /* * ...find its height... */ double cell_height = rCellPopulation.GetLocationOfCellCentre(*cell_iter)[1]; /* * ...and store this in the {{{CellData}}} item "height". */ cell_iter->GetCellData()->SetItem("height", cell_height); } }
void CryptProjectionForce::AddForceContribution(AbstractCellPopulation<2>& rCellPopulation) { // First work out the 3D location of each cell UpdateNode3dLocationMap(rCellPopulation); // Throw an exception message if not using a MeshBasedCellPopulation if (dynamic_cast<MeshBasedCellPopulation<2>*>(&rCellPopulation) == NULL) { EXCEPTION("CryptProjectionForce is to be used with a subclass of MeshBasedCellPopulation only"); } MeshBasedCellPopulation<2>* p_static_cast_cell_population = static_cast<MeshBasedCellPopulation<2>*>(&rCellPopulation); for (MeshBasedCellPopulation<2>::SpringIterator spring_iterator = p_static_cast_cell_population->SpringsBegin(); spring_iterator != p_static_cast_cell_population->SpringsEnd(); ++spring_iterator) { unsigned nodeA_global_index = spring_iterator.GetNodeA()->GetIndex(); unsigned nodeB_global_index = spring_iterator.GetNodeB()->GetIndex(); c_vector<double, 2> force = CalculateForceBetweenNodes(nodeA_global_index, nodeB_global_index, rCellPopulation); c_vector<double, 2> negative_force = -1.0 * force; spring_iterator.GetNodeB()->AddAppliedForceContribution(negative_force); spring_iterator.GetNodeA()->AddAppliedForceContribution(force); } if (mIncludeWntChemotaxis) { assert(WntConcentration<2>::Instance()->IsWntSetUp()); for (AbstractCellPopulation<2>::Iterator cell_iter = rCellPopulation.Begin(); cell_iter != rCellPopulation.End(); ++cell_iter) { if (cell_iter->GetCellProliferativeType()->IsType<StemCellProliferativeType>()) { c_vector<double, 2> wnt_chemotactic_force = mWntChemotaxisStrength*WntConcentration<2>::Instance()->GetWntGradient(*cell_iter); unsigned index = rCellPopulation.GetLocationIndexUsingCell(*cell_iter); rCellPopulation.GetNode(index)->AddAppliedForceContribution(wnt_chemotactic_force); } } } }
/* The second public method overrides {{{AddForceContribution()}}}. * This method takes in one argument, a reference to the cell population itself. */ void AddForceContribution(AbstractCellPopulation<2>& rCellPopulation) { /* Inside the method, we loop over cells, and add a vector to * each node associated with cells with the {{{MotileCellProperty}}}, which is proportional (with constant {{{mStrength}}}) to the negative of the position. Causing * cells to move inwards towards the origin. Note that this will currently only work with subclasses of {{{AbstractCentreBasedCellPopulation}}}s as * we associate cells with nodes in the force calculation. However, this could easily be modified to make it work for {{{VertexBasedCellPopulation}}}s. */ for (AbstractCellPopulation<2>::Iterator cell_iter = rCellPopulation.Begin(); cell_iter != rCellPopulation.End(); ++cell_iter) { if (cell_iter->HasCellProperty<MotileCellProperty>()) { unsigned node_index = rCellPopulation.GetLocationIndexUsingCell(*cell_iter); c_vector<double, 2> location = rCellPopulation.GetLocationOfCellCentre(*cell_iter); c_vector<double, 2> force = -1.0 * mStrength * location; rCellPopulation.GetNode(node_index)->AddAppliedForceContribution(force); } } }
void BuskeCompressionForce<DIM>::AddForceContribution(AbstractCellPopulation<DIM>& rCellPopulation) { // This force class is defined for NodeBasedCellPopulations only assert(dynamic_cast<NodeBasedCellPopulation<DIM>*>(&rCellPopulation) != NULL); NodeBasedCellPopulation<DIM>* p_static_cast_cell_population = static_cast<NodeBasedCellPopulation<DIM>*>(&rCellPopulation); c_vector<double, DIM> unit_vector; // Loop over cells in the population for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = rCellPopulation.Begin(); cell_iter != rCellPopulation.End(); ++cell_iter) { // Get the node index corresponding to this cell unsigned node_index = rCellPopulation.GetLocationIndexUsingCell(*cell_iter); Node<DIM>* p_node_i = rCellPopulation.GetNode(node_index); // Get the location of this node c_vector<double, DIM> node_i_location = p_node_i->rGetLocation(); // Get the radius of this cell double radius_of_cell_i = p_node_i->GetRadius(); double delta_V_c = 0.0; c_vector<double, DIM> dVAdd_vector = zero_vector<double>(DIM); // Get the set of node indices corresponding to this cell's neighbours std::set<unsigned> neighbouring_node_indices = p_static_cast_cell_population->GetNeighbouringNodeIndices(node_index); // Loop over this set for (std::set<unsigned>::iterator iter = neighbouring_node_indices.begin(); iter != neighbouring_node_indices.end(); ++iter) { Node<DIM>* p_node_j = rCellPopulation.GetNode(*iter); // Get the location of this node c_vector<double, DIM> node_j_location = p_node_j->rGetLocation(); // Get the unit vector parallel to the line joining the two nodes (assuming no periodicities etc.) unit_vector = node_j_location - node_i_location; // Calculate the distance between the two nodes double dij = norm_2(unit_vector); unit_vector /= dij; // Get the radius of the cell corresponding to this node double radius_of_cell_j = p_node_j->GetRadius(); // If the cells are close enough to exert a force on each other... if (dij < radius_of_cell_i + radius_of_cell_j) { // ...then compute the adhesion force and add it to the vector of forces... double xij = 0.5*(radius_of_cell_i*radius_of_cell_i - radius_of_cell_j*radius_of_cell_j + dij*dij)/dij; double dxijdd = 1.0 - xij/dij; double dVAdd = M_PI*dxijdd*(5.0*pow(radius_of_cell_i,2.0) + 3.0*pow(xij,2.0) - 8.0*radius_of_cell_i*xij)/3.0; dVAdd_vector += dVAdd*unit_vector; // ...and add the contribution to the compression force acting on cell i delta_V_c += M_PI*pow(radius_of_cell_i - xij,2.0)*(2*radius_of_cell_i - xij)/3.0; } } double V_A = 4.0/3.0*M_PI*pow(radius_of_cell_i,3.0) - delta_V_c; /** * Target volume of the cell * \todo Doesn't say in the Buske paper how they calculate this, so * we need to look at this to be sure it's what we want (#1764) */ double V_T = 5.0; // Note: the sign in force_magnitude is different from the one in equation (A3) in the Buske paper c_vector<double, DIM> applied_force = -mCompressionEnergyParameter/V_T*(V_T - V_A)*dVAdd_vector; p_node_i->AddAppliedForceContribution(applied_force); } }