36 #include <boost/scoped_array.hpp> 38 #include "CaBasedCellPopulation.hpp" 39 #include "MutableMesh.hpp" 40 #include "AbstractCaUpdateRule.hpp" 41 #include "AbstractCaSwitchingUpdateRule.hpp" 42 #include "RandomNumberGenerator.hpp" 43 #include "CellLocationIndexWriter.hpp" 44 #include "ExclusionCaBasedDivisionRule.hpp" 45 #include "NodesOnlyMesh.hpp" 46 #include "ApoptoticCellProperty.hpp" 49 #include "VtkMeshWriter.hpp" 52 template<
unsigned DIM>
59 template<
unsigned DIM>
61 std::vector<CellPtr>& rCells,
62 const std::vector<unsigned> locationIndices,
63 unsigned latticeCarryingCapacity,
67 mLatticeCarryingCapacity(latticeCarryingCapacity)
75 if (locationIndices.empty())
77 EXCEPTION(
"No location indices being passed. Specify where cells lie before creating the cell population.");
83 std::list<CellPtr>::iterator it = this->
mCells.begin();
84 for (
unsigned i=0; it != this->
mCells.end(); ++it, ++i)
86 assert(i < locationIndices.size());
89 EXCEPTION(
"One of the lattice sites has more cells than the carrying capacity. Check the initial cell locations.");
96 EXCEPTION(
"There is no validation for CaBasedCellPopulation.");
100 template<
unsigned DIM>
106 template<
unsigned DIM>
115 template<
unsigned DIM>
121 template<
unsigned DIM>
128 template<
unsigned DIM>
134 template<
unsigned DIM>
140 template<
unsigned DIM>
143 std::vector<Node<DIM>*> temp_nodes;
146 unsigned cell_index = 0;
148 cell_iter != this->
End();
158 template<
unsigned DIM>
164 template<
unsigned DIM>
170 template<
unsigned DIM>
176 std::set<unsigned> neighbour_indices;
177 for (std::set<unsigned>::iterator iter = candidates.begin();
178 iter != candidates.end();
183 neighbour_indices.insert(*iter);
187 return neighbour_indices;
190 template<
unsigned DIM>
196 template<
unsigned DIM>
202 template<
unsigned DIM>
207 EXCEPTION(
"No available spaces at location index " << index <<
".");
214 template<
unsigned DIM>
224 template<
unsigned DIM>
230 template<
unsigned DIM>
233 unsigned daughter_node_index =
mpCaBasedDivisionRule->CalculateDaughterNodeIndex(pNewCell,pParentCell,*
this);
236 this->
mCells.push_back(pNewCell);
239 CellPtr p_created_cell = this->
mCells.back();
242 return p_created_cell;
245 template<
unsigned DIM>
247 unsigned targetNodeIndex,
253 template<
unsigned DIM>
256 unsigned num_removed = 0;
258 for (std::list<CellPtr>::iterator cell_iter = this->
mCells.begin();
259 cell_iter != this->
mCells.end();
262 if ((*cell_iter)->IsDead())
271 cell_iter = this->
mCells.erase(cell_iter);
282 template<
unsigned DIM>
293 for (std::list<CellPtr>::iterator cell_iter = this->
mCells.begin();
294 cell_iter != this->
mCells.end();
302 std::vector<double> neighbouring_node_propensities;
303 std::vector<unsigned> neighbouring_node_indices_vector;
305 if (!neighbouring_node_indices.empty())
307 unsigned num_neighbours = neighbouring_node_indices.size();
308 double probability_of_not_moving = 1.0;
310 for (std::set<unsigned>::iterator iter = neighbouring_node_indices.begin();
311 iter != neighbouring_node_indices.end();
314 double probability_of_moving = 0.0;
316 neighbouring_node_indices_vector.push_back(*iter);
326 double p = (boost::static_pointer_cast<
AbstractCaUpdateRule<DIM> >(*iter_rule))->EvaluateProbability(node_index, *iter, *
this, dt, 1, *cell_iter);
327 probability_of_moving += p;
328 if (probability_of_moving < 0)
330 EXCEPTION(
"The probability of cellular movement is smaller than zero. In order to prevent it from happening you should change your time step and parameters");
333 if (probability_of_moving > 1)
335 EXCEPTION(
"The probability of the cellular movement is bigger than one. In order to prevent it from happening you should change your time step and parameters");
339 probability_of_not_moving -= probability_of_moving;
340 neighbouring_node_propensities.push_back(probability_of_moving);
344 neighbouring_node_propensities.push_back(0.0);
347 if (probability_of_not_moving < 0)
349 EXCEPTION(
"The probability of the cell not moving is smaller than zero. In order to prevent it from happening you should change your time step and parameters");
354 double random_number = p_gen->
ranf();
356 double total_probability = 0.0;
357 for (
unsigned counter=0; counter<num_neighbours; counter++)
359 total_probability += neighbouring_node_propensities[counter];
360 if (total_probability >= random_number)
363 unsigned chosen_neighbour_location_index = neighbouring_node_indices_vector[counter];
398 for (
unsigned i=0; i<num_nodes; i++)
404 node_index = p_gen->
randMod(num_nodes);
409 node_index = i%num_nodes;
415 unsigned neighbour_location_index;
417 if (!neighbouring_node_indices.empty())
419 unsigned num_neighbours = neighbouring_node_indices.size();
420 unsigned chosen_neighbour = p_gen->
randMod(num_neighbours);
422 std::set<unsigned>::iterator neighbour_iter = neighbouring_node_indices.begin();
423 for (
unsigned j=0; j<chosen_neighbour; j++)
427 neighbour_location_index = *neighbour_iter;
429 bool is_cell_on_node_index =
mAvailableSpaces[node_index] == 0 ?
true :
false;
430 bool is_cell_on_neighbour_location_index =
mAvailableSpaces[neighbour_location_index] == 0 ?
true :
false;
432 if (is_cell_on_node_index || is_cell_on_neighbour_location_index)
434 double probability_of_switch = 0.0;
442 double p = (boost::static_pointer_cast<
AbstractCaSwitchingUpdateRule<DIM> >(*iter_rule))->EvaluateSwitchingProbability(node_index, neighbour_location_index, *
this, dt, 1);
443 probability_of_switch += p;
446 assert(probability_of_switch >= 0);
447 assert(probability_of_switch <= 1);
450 double random_number = p_gen->
ranf();
452 if (random_number < probability_of_switch)
454 if (is_cell_on_node_index && is_cell_on_neighbour_location_index)
468 else if (is_cell_on_node_index && !is_cell_on_neighbour_location_index)
475 else if (!is_cell_on_node_index && is_cell_on_neighbour_location_index)
493 template<
unsigned DIM>
499 template<
unsigned DIM>
504 template<
unsigned DIM>
507 pPopulationWriter->Visit(
this);
510 template<
unsigned DIM>
513 pPopulationCountWriter->Visit(
this);
516 template<
unsigned DIM>
519 pCellWriter->VisitCell(pCell,
this);
522 template<
unsigned DIM>
527 if (!this->
template HasWriter<CellLocationIndexWriter>())
529 this->
template AddCellWriter<CellLocationIndexWriter>();
536 template<
unsigned DIM>
539 double cell_volume = 1.0;
543 template<
unsigned DIM>
550 template<
unsigned DIM>
567 template<
unsigned DIM>
577 template<
unsigned DIM>
580 std::vector<boost::shared_ptr<AbstractUpdateRule<DIM> > > update_rules;
594 template<
unsigned DIM>
600 template<
unsigned DIM>
606 template<
unsigned DIM>
610 *rParamsFile <<
"\t\t<CaBasedDivisionRule>\n";
612 *rParamsFile <<
"\t\t</CaBasedDivisionRule>\n";
618 template<
unsigned DIM>
624 std::stringstream time;
625 time << num_timesteps;
631 unsigned num_cell_data_items = 0u;
632 std::vector<std::string> cell_data_names;
635 num_cell_data_items = this->
Begin()->GetCellData()->GetNumItems();
636 cell_data_names = this->
Begin()->GetCellData()->GetKeys();
638 std::vector<std::vector<double> > cell_data;
639 for (
unsigned var=0; var<num_cell_data_items; var++)
641 std::vector<double> cell_data_var(num_cells);
642 cell_data.push_back(cell_data_var);
650 boost::scoped_array<unsigned> number_of_cells_at_site(
new unsigned[num_sites]);
651 for (
unsigned i=0; i<num_sites; i++)
653 number_of_cells_at_site[i] = 0;
657 std::vector<Node<DIM>*> nodes;
658 unsigned node_index = 0;
660 cell_iter != this->
End();
665 number_of_cells_at_site[location_index]++;
669 c_vector<double, DIM> coords;
670 coords = this->
mrMesh.
GetNode(location_index)->rGetLocation();
675 c_vector<double, DIM> offset;
680 offset[0] = 0.2*sin(angle);
681 offset[1] = 0.2*cos(angle);
686 for (
unsigned i=0; i<DIM; i++)
688 offset[i] = p_gen->
ranf();
692 for (
unsigned i=0; i<DIM; i++)
694 coords[i] += offset[i];
698 nodes.push_back(
new Node<DIM>(node_index, coords,
false));
709 std::vector<double> vtk_cell_data(num_cells, -1.0);
712 unsigned cell_index = 0;
714 cell_iter != this->
End();
718 vtk_cell_data[cell_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(*cell_iter,
this);
722 mesh_writer.AddPointData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data);
726 unsigned cell_index = 0;
728 cell_iter != this->
End();
731 for (
unsigned var=0; var<num_cell_data_items; var++)
733 cell_data[var][cell_index] = cell_iter->GetCellData()->GetItem(cell_data_names[var]);
737 for (
unsigned var=0; var<num_cell_data_items; var++)
739 mesh_writer.AddPointData(cell_data_names[var], cell_data[var]);
752 for (
unsigned idx=1; idx<DIM; idx++)
760 spacing = std::pow(volume /
double(this->
mrMesh.
GetNumNodes()), 1.0/
double(DIM));
768 mesh_writer.WriteFilesUsingMesh(temp_mesh);
772 *(this->
mpVtkMetaFile) <<
"\" group=\"\" part=\"0\" file=\"results_";
777 for (
unsigned i=0; i<nodes.size(); i++)
784 template<
unsigned DIM>
786 unsigned pdeNodeIndex,
787 std::string& rVariableName,
788 bool dirichletBoundaryConditionApplies,
789 double dirichletBoundaryValue)
791 unsigned counter = 0;
793 while (counter != pdeNodeIndex)
799 double value = cell_iter->GetCellData()->GetItem(rVariableName);
804 template<
unsigned DIM>
811 for (
unsigned i=0; i<pdeNodeIndex; i++)
815 bool is_cell_apoptotic = cell_iter->template HasCellProperty<ApoptoticCellProperty>();
817 return !is_cell_apoptotic;
bool IsCellAssociatedWithADeletedLocation(CellPtr pCell)
boost::shared_ptr< AbstractCaBasedDivisionRule< DIM > > GetCaBasedDivisionRule()
std::vector< unsigned > mAvailableSpaces
unsigned randMod(unsigned base)
std::vector< unsigned > & rGetAvailableSpaces()
void AddCellUsingLocationIndex(unsigned index, CellPtr pCell)
virtual double EvaluateDivisionPropensity(unsigned currentNodeIndex, unsigned targetNodeIndex, CellPtr pCell)
virtual CellPtr GetCellUsingLocationIndex(unsigned index)
PottsMesh< DIM > & rGetMesh()
unsigned GetLocationIndexUsingCell(CellPtr pCell)
void OutputCellPopulationParameters(out_stream &rParamsFile)
virtual bool IsPdeNodeAssociatedWithNonApoptoticCell(unsigned pdeNodeIndex)
std::vector< boost::shared_ptr< AbstractCellWriter< ELEMENT_DIM, ELEMENT_DIM > > > mCellWriters
virtual void RemoveCellUsingLocationIndex(unsigned index, CellPtr pCell)
Node< DIM > * GetNode(unsigned index)
Node< SPACE_DIM > * GetNode(unsigned index) const
#define EXCEPTION(message)
virtual void AcceptPopulationCountWriter(boost::shared_ptr< AbstractCellPopulationCountWriter< DIM, DIM > > pPopulationCountWriter)
static SimulationTime * Instance()
virtual bool IsSiteAvailable(unsigned index, CellPtr pCell)
boost::shared_ptr< AbstractCaBasedDivisionRule< DIM > > mpCaBasedDivisionRule
virtual unsigned GetNumNodes() const
unsigned GetTimeStepsElapsed() const
unsigned mLatticeCarryingCapacity
unsigned GetNumRealCells()
std::set< unsigned > GetMooreNeighbouringNodeIndices(unsigned nodeIndex)
virtual void OutputCellPopulationParameters(out_stream &rParamsFile)
void RemoveCellUsingLocationIndex(unsigned index, CellPtr pCell)
virtual void WriteVtkResultsToFile(const std::string &rDirectory)
virtual ~CaBasedCellPopulation()
CaBasedCellPopulation(PottsMesh< DIM > &rMesh, std::vector< CellPtr > &rCells, const std::vector< unsigned > locationIndices, unsigned latticeCarryingCapacity=1u, bool deleteMesh=false, bool validate=false)
virtual void RemoveAllUpdateRules()
void MoveCellInLocationMap(CellPtr pCell, unsigned old_index, unsigned new_index)
bool mOutputResultsForChasteVisualizer
void Shuffle(std::vector< boost::shared_ptr< T > > &rValues)
bool IsRoomToDivide(CellPtr pCell)
virtual TetrahedralMesh< DIM, DIM > * GetTetrahedralMeshForPdeModifier()
void SetCaBasedDivisionRule(boost::shared_ptr< AbstractCaBasedDivisionRule< DIM > > pCaBasedDivisionRule)
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
std::set< unsigned > GetNeighbouringLocationIndices(CellPtr pCell)
void UpdateCellLocations(double dt)
std::vector< boost::shared_ptr< AbstractUpdateRule< DIM > > > mUpdateRuleCollection
void Update(bool hasHadBirthsOrDeaths=true)
static RandomNumberGenerator * Instance()
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
std::list< CellPtr > mCells
virtual double GetCellDataItemAtPdeNode(unsigned pdeNodeIndex, std::string &rVariableName, bool dirichletBoundaryConditionApplies=false, double dirichletBoundaryValue=0.0)
void RemoveAllUpdateRules()
void ConstructNodesWithoutMesh(const std::vector< Node< SPACE_DIM > * > &rNodes, double maxInteractionDistance)
std::vector< boost::shared_ptr< AbstractUpdateRule< DIM > > > mSwitchingUpdateRuleCollection
virtual double GetWidth(const unsigned &rDimension) const
Node< DIM > * GetNodeCorrespondingToCell(CellPtr pCell)
c_vector< double, DIM > GetLocationOfCellCentre(CellPtr pCell)
bool mIterateRandomlyOverUpdateRuleCollection
double GetWidth(const unsigned &rDimension)
unsigned RemoveDeadCells()
virtual void AcceptPopulationWriter(boost::shared_ptr< AbstractCellPopulationWriter< DIM, DIM > > pPopulationWriter)
double GetVolumeOfCell(CellPtr pCell)
virtual void AddCellUsingLocationIndex(unsigned index, CellPtr pCell)
CellPtr AddCell(CellPtr pNewCell, CellPtr pParentCell=CellPtr())
AbstractMesh< ELEMENT_DIM, ELEMENT_DIM > & mrMesh
bool mUpdateNodesInRandomOrder
virtual void AddUpdateRule(boost::shared_ptr< AbstractUpdateRule< DIM > > pUpdateRule)
virtual void AcceptCellWriter(boost::shared_ptr< AbstractCellWriter< DIM, DIM > > pCellWriter, CellPtr pCell)
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
virtual const std::vector< boost::shared_ptr< AbstractUpdateRule< DIM > > > GetUpdateRuleCollection() const