36 #include "PottsBasedCellPopulation.hpp" 37 #include "RandomNumberGenerator.hpp" 38 #include "AbstractPottsUpdateRule.hpp" 39 #include "NodesOnlyMesh.hpp" 40 #include "CellPopulationElementWriter.hpp" 41 #include "CellIdWriter.hpp" 44 #include "VtkMeshWriter.hpp" 46 template<
unsigned DIM>
50 std::vector<unsigned> validated_element = std::vector<unsigned>(this->GetNumElements(), 0);
53 cell_iter != this->End();
56 unsigned elem_index = this->GetLocationIndexUsingCell(*cell_iter);
57 validated_element[elem_index]++;
60 for (
unsigned i=0; i<validated_element.size(); i++)
62 if (validated_element[i] == 0)
67 if (validated_element[i] > 1)
69 EXCEPTION(
"At time " <<
SimulationTime::Instance()->GetTime() <<
", Element " << i <<
" appears to have " << validated_element[i] <<
" cells associated with it");
74 template<
unsigned DIM>
76 std::vector<CellPtr>& rCells,
79 const std::vector<unsigned> locationIndices)
81 mpElementTessellation(nullptr),
82 mpMutableMesh(nullptr),
84 mNumSweepsPerTimestep(1)
94 template<
unsigned DIM>
105 template<
unsigned DIM>
118 template<
unsigned DIM>
124 template<
unsigned DIM>
130 template<
unsigned DIM>
133 std::vector<Node<DIM>*> temp_nodes;
137 cell_iter != this->
End();
142 temp_nodes.push_back(
new Node<DIM>(index, location));
148 template<
unsigned DIM>
154 template<
unsigned DIM>
160 template<
unsigned DIM>
166 template<
unsigned DIM>
172 template<
unsigned DIM>
176 return mpPottsMesh->GetNeighbouringElementIndices(elem_index);
179 template<
unsigned DIM>
185 template<
unsigned DIM>
191 template<
unsigned DIM>
198 unsigned new_element_index =
mpPottsMesh->DivideElement(p_element,
true);
201 this->
mCells.push_back(pNewCell);
204 CellPtr p_created_cell = this->
mCells.back();
206 return p_created_cell;
209 template<
unsigned DIM>
212 unsigned num_removed = 0;
214 for (std::list<CellPtr>::iterator cell_iter = this->
mCells.begin();
215 cell_iter != this->
mCells.end();
218 if ((*cell_iter)->IsDead())
227 cell_iter = this->
mCells.erase(cell_iter);
238 template<
unsigned DIM>
269 node_index = p_gen->
randMod(num_nodes);
274 node_index = i%num_nodes;
283 std::set<unsigned> neighbouring_node_indices =
mpPottsMesh->GetMooreNeighbouringNodeIndices(node_index);
284 unsigned neighbour_location_index;
286 if (!neighbouring_node_indices.empty())
288 unsigned num_neighbours = neighbouring_node_indices.size();
289 unsigned chosen_neighbour = p_gen->
randMod(num_neighbours);
291 std::set<unsigned>::iterator neighbour_iter = neighbouring_node_indices.begin();
292 for (
unsigned j=0; j<chosen_neighbour; j++)
297 neighbour_location_index = *neighbour_iter;
300 std::set<unsigned> neighbour_containing_elements =
GetNode(neighbour_location_index)->rGetContainingElementIndices();
302 if ((!containing_elements.empty() && neighbour_containing_elements.empty())
303 || (containing_elements.empty() && !neighbour_containing_elements.empty())
304 || (!containing_elements.empty() && !neighbour_containing_elements.empty() && *containing_elements.begin() != *neighbour_containing_elements.begin()))
306 double delta_H = 0.0;
319 double random_number = p_gen->
ranf();
322 if (delta_H <= 0 || random_number < p)
327 for (std::set<unsigned>::iterator iter = containing_elements.begin();
328 iter != containing_elements.end();
337 for (std::set<unsigned>::iterator iter = neighbour_containing_elements.begin();
338 iter != neighbour_containing_elements.end();
341 GetElement(*iter)->AddNode(this->mrMesh.GetNode(node_index));
349 template<
unsigned DIM>
355 template<
unsigned DIM>
360 template<
unsigned DIM>
365 if (!this->
template HasWriter<CellPopulationElementWriter>())
367 this->
template AddPopulationWriter<CellPopulationElementWriter>();
371 this->
template AddCellWriter<CellIdWriter>();
376 template<
unsigned DIM>
384 template<
unsigned DIM>
387 pPopulationWriter->Visit(
this);
390 template<
unsigned DIM>
393 pPopulationCountWriter->Visit(
this);
396 template<
unsigned DIM>
399 pCellWriter->VisitCell(pCell,
this);
402 template<
unsigned DIM>
409 double cell_volume =
mpPottsMesh->GetVolumeOfElement(elem_index);
414 template<
unsigned DIM>
423 template<
unsigned DIM>
430 template<
unsigned DIM>
448 template<
unsigned DIM>
455 template<
unsigned DIM>
461 std::vector<Node<DIM>*> nodes;
464 const c_vector<double, DIM>& r_location = this->
mrMesh.
GetNode(node_index)->rGetLocation();
465 nodes.push_back(
new Node<DIM>(node_index, r_location));
471 template<
unsigned DIM>
478 template<
unsigned DIM>
481 *rParamsFile <<
"\t\t<Temperature>" <<
mTemperature <<
"</Temperature>\n";
482 *rParamsFile <<
"\t\t<NumSweepsPerTimestep>" <<
mNumSweepsPerTimestep <<
"</NumSweepsPerTimestep>\n";
488 template<
unsigned DIM>
494 template<
unsigned DIM>
500 template<
unsigned DIM>
506 template<
unsigned DIM>
512 template<
unsigned DIM>
517 std::stringstream time;
518 time << num_timesteps;
530 std::vector<double> vtk_cell_data(num_nodes);
538 unsigned node_index = iter->GetIndex();
539 std::set<unsigned> element_indices = iter->rGetContainingElementIndices();
542 if (element_indices.empty())
545 vtk_cell_data[node_index] = -1.0;
550 assert(element_indices.size() == 1);
551 unsigned elem_index = *(element_indices.begin());
555 vtk_cell_data[node_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell,
this);
559 mesh_writer.AddPointData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data);
563 unsigned num_cell_data_items = this->
Begin()->GetCellData()->GetNumItems();
564 std::vector<std::string> cell_data_names = this->
Begin()->GetCellData()->GetKeys();
566 std::vector<std::vector<double> > cell_data;
567 for (
unsigned var=0; var<num_cell_data_items; var++)
569 std::vector<double> cell_data_var(num_nodes);
570 cell_data.push_back(cell_data_var);
578 unsigned node_index = iter->GetIndex();
579 std::set<unsigned> element_indices = iter->rGetContainingElementIndices();
582 if (element_indices.empty())
584 for (
unsigned var=0; var<num_cell_data_items; var++)
586 cell_data[var][node_index] = -1.0;
592 assert(element_indices.size() == 1);
593 unsigned elem_index = *(element_indices.begin());
596 for (
unsigned var=0; var<num_cell_data_items; var++)
598 cell_data[var][node_index] = p_cell->GetCellData()->GetItem(cell_data_names[var]);
602 for (
unsigned var=0; var<cell_data.size(); var++)
604 mesh_writer.AddPointData(cell_data_names[var], cell_data[var]);
614 mesh_writer.WriteFilesUsingMesh(temp_mesh);
618 *(this->
mpVtkMetaFile) <<
"\" group=\"\" part=\"0\" file=\"results_";
625 std::vector<Node<2>*> outline_nodes;
626 std::vector<VertexElement<2,2>*> outline_elements;
628 unsigned outline_node_index = 0;
629 unsigned outline_element_index = 0;
635 unsigned node_index = iter->GetIndex();
636 std::set<unsigned> element_indices = iter->rGetContainingElementIndices();
638 std::set<unsigned> target_neighbouring_node_indices = this->
rGetMesh().GetVonNeumannNeighbouringNodeIndices(node_index);
640 for (std::set<unsigned>::iterator neighbour_iter = target_neighbouring_node_indices.begin();
641 neighbour_iter != target_neighbouring_node_indices.end();
644 std::set<unsigned> neighbouring_element_indices = this->
rGetMesh().GetNode(*neighbour_iter)->rGetContainingElementIndices();
647 if (element_indices != neighbouring_element_indices)
649 std::vector<Node<2>*> element_nodes;
651 const c_vector<double, 2>& r_node_location = this->
mrMesh.
GetNode(node_index)->rGetLocation();
652 const c_vector<double, 2>& r_neighbour_node_location = this->
mrMesh.
GetNode(*neighbour_iter)->rGetLocation();
654 c_vector<double, 2> unit_tangent = r_neighbour_node_location - r_node_location;
656 if (norm_2(unit_tangent) > 1.0)
658 c_vector<double, 2> mid_point = 0.5*(r_node_location + r_neighbour_node_location);
659 if (unit_tangent(0) == 0)
661 if (r_node_location(1) < r_neighbour_node_location(1))
663 mid_point(1) = r_node_location(1) - 0.5;
667 mid_point(1) = r_node_location(1) + 0.5;
672 assert(unit_tangent(1) == 0);
674 if (r_node_location(0) < r_neighbour_node_location(0))
676 mid_point(0) = r_node_location(0) - 0.5;
680 mid_point(0) = r_node_location(0) + 0.5;
683 assert(norm_2(unit_tangent) > 0);
684 unit_tangent = unit_tangent/norm_2(unit_tangent);
686 c_vector<double, DIM> unit_normal;
687 unit_normal(0) = -unit_tangent(1);
688 unit_normal(1) = unit_tangent(0);
690 std::vector<Node<2>*> element_nodes;
693 Node<2>* p_node_1 =
new Node<2>(outline_node_index, mid_point - 0.5*unit_normal);
694 outline_nodes.push_back(p_node_1);
695 element_nodes.push_back(outline_nodes[outline_node_index]);
696 outline_node_index++;
699 outline_nodes.push_back(p_node_2);
700 element_nodes.push_back(outline_nodes[outline_node_index]);
701 outline_node_index++;
703 Node<2>* p_node_3 =
new Node<2>(outline_node_index, mid_point + 0.5*unit_normal);
704 outline_nodes.push_back(p_node_3);
705 element_nodes.push_back(outline_nodes[outline_node_index]);
706 outline_node_index++;
709 outline_elements.push_back(p_element);
710 outline_element_index++;
715 c_vector<double, 2> mid_point = 0.5*(r_node_location + r_neighbour_node_location);
717 assert(norm_2(unit_tangent) > 0);
718 unit_tangent = unit_tangent/norm_2(unit_tangent);
720 c_vector<double, 2> unit_normal;
721 unit_normal(0) = -unit_tangent(1);
722 unit_normal(1) = unit_tangent(0);
724 std::vector<Node<2>*> element_nodes;
727 Node<2>* p_node_1 =
new Node<2>(outline_node_index, mid_point - 0.5*unit_normal);
728 outline_nodes.push_back(p_node_1);
729 element_nodes.push_back(outline_nodes[outline_node_index]);
730 outline_node_index++;
733 outline_nodes.push_back(p_node_2);
734 element_nodes.push_back(outline_nodes[outline_node_index]);
735 outline_node_index++;
737 Node<2>* p_node_3 =
new Node<2>(outline_node_index, mid_point + 0.5*unit_normal);
738 outline_nodes.push_back(p_node_3);
739 element_nodes.push_back(outline_nodes[outline_node_index]);
740 outline_node_index++;
743 outline_elements.push_back(p_element);
744 outline_element_index++;
758 template<
unsigned DIM>
760 unsigned pdeNodeIndex,
761 std::string& rVariableName,
762 bool dirichletBoundaryConditionApplies,
763 double dirichletBoundaryValue)
766 double value = p_cell->GetCellData()->GetItem(rVariableName);
unsigned randMod(unsigned base)
virtual CellPtr GetCellUsingLocationIndex(unsigned index)
PottsMesh< DIM > * mpPottsMesh
unsigned GetLocationIndexUsingCell(CellPtr pCell)
Node< DIM > * GetNode(unsigned index)
std::vector< boost::shared_ptr< AbstractCellWriter< ELEMENT_DIM, ELEMENT_DIM > > > mCellWriters
void WriteFilesUsingMesh(VertexMesh< ELEMENT_DIM, SPACE_DIM > &rMesh)
PottsMesh< DIM > & rGetMesh()
Node< SPACE_DIM > * GetNode(unsigned index) const
MutableMesh< DIM, DIM > * mpMutableMesh
#define EXCEPTION(message)
VertexMesh< DIM, DIM > * GetElementTessellation()
static SimulationTime * Instance()
std::set< unsigned > GetNeighbouringLocationIndices(CellPtr pCell)
PottsElement< DIM > * GetElementCorrespondingToCell(CellPtr pCell)
unsigned GetNumElements()
std::set< unsigned > & rGetContainingElementIndices()
virtual unsigned GetNumNodes() const
unsigned GetTimeStepsElapsed() const
unsigned RemoveDeadCells()
virtual void OutputCellPopulationParameters(out_stream &rParamsFile)
virtual void AcceptPopulationCountWriter(boost::shared_ptr< AbstractCellPopulationCountWriter< DIM, DIM > > pPopulationCountWriter)
virtual void WriteResultsToFiles(const std::string &rDirectory)
virtual double GetCellDataItemAtPdeNode(unsigned pdeNodeIndex, std::string &rVariableName, bool dirichletBoundaryConditionApplies=false, double dirichletBoundaryValue=0.0)
bool mOutputResultsForChasteVisualizer
void Shuffle(std::vector< boost::shared_ptr< T > > &rValues)
void CreateElementTessellation()
c_vector< double, DIM > GetLocationOfCellCentre(CellPtr pCell)
virtual void AcceptCellWriter(boost::shared_ptr< AbstractCellWriter< DIM, DIM > > pCellWriter, CellPtr pCell)
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
void SetCellUsingLocationIndex(unsigned index, CellPtr pCell)
std::vector< boost::shared_ptr< AbstractUpdateRule< DIM > > > mUpdateRuleCollection
void OutputCellPopulationParameters(out_stream &rParamsFile)
void SetTemperature(double temperature)
virtual void WriteVtkResultsToFile(const std::string &rDirectory)
virtual void AcceptPopulationWriter(boost::shared_ptr< AbstractCellPopulationWriter< DIM, DIM > > pPopulationWriter)
void Update(bool hasHadBirthsOrDeaths=true)
void WriteVtkUsingMesh(VertexMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, std::string stamp="")
virtual void AddUpdateRule(boost::shared_ptr< AbstractUpdateRule< DIM > > pUpdateRule)
static RandomNumberGenerator * Instance()
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
std::list< CellPtr > mCells
void ConstructNodesWithoutMesh(const std::vector< Node< SPACE_DIM > * > &rNodes, double maxInteractionDistance)
double GetVolumeOfCell(CellPtr pCell)
unsigned mNumSweepsPerTimestep
virtual void WriteResultsToFiles(const std::string &rDirectory)
virtual double GetWidth(const unsigned &rDimension) const
CellPtr AddCell(CellPtr pNewCell, CellPtr pParentCell=CellPtr())
virtual TetrahedralMesh< DIM, DIM > * GetTetrahedralMeshForPdeModifier()
MutableMesh< DIM, DIM > * GetMutableMesh()
void UpdateCellLocations(double dt)
unsigned GetNumContainingElements() const
bool mIterateRandomlyOverUpdateRuleCollection
unsigned GetIndex() const
PottsElement< DIM > * GetElement(unsigned elementIndex)
double GetWidth(const unsigned &rDimension)
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
unsigned GetNumSweepsPerTimestep()
AbstractMesh< ELEMENT_DIM, ELEMENT_DIM > & mrMesh
bool mUpdateNodesInRandomOrder
virtual ~PottsBasedCellPopulation()
void SetNumSweepsPerTimestep(unsigned numSweepsPerTimestep)
VertexMesh< DIM, DIM > * mpElementTessellation
PottsBasedCellPopulation(PottsMesh< DIM > &rMesh, std::vector< CellPtr > &rCells, bool deleteMesh=false, bool validate=true, const std::vector< unsigned > locationIndices=std::vector< unsigned >())
bool IsCellAssociatedWithADeletedLocation(CellPtr pCell)