36 #include "VertexBasedCellPopulation.hpp" 37 #include "Warnings.hpp" 38 #include "ShortAxisVertexBasedDivisionRule.hpp" 39 #include "StepSizeException.hpp" 40 #include "WildTypeCellMutationState.hpp" 41 #include "Cylindrical2dVertexMesh.hpp" 43 #include "T2SwapCellKiller.hpp" 44 #include "ApoptoticCellProperty.hpp" 45 #include "CellPopulationElementWriter.hpp" 46 #include "VertexT1SwapLocationsWriter.hpp" 47 #include "VertexT2SwapLocationsWriter.hpp" 48 #include "VertexT3SwapLocationsWriter.hpp" 49 #include "AbstractCellBasedSimulation.hpp" 51 template<
unsigned DIM>
53 std::vector<CellPtr>& rCells,
56 const std::vector<unsigned> locationIndices)
58 mDeleteMesh(deleteMesh),
59 mOutputCellRearrangementLocations(true),
60 mRestrictVertexMovement(true)
66 std::list<CellPtr>::iterator it = this->
mCells.begin();
67 for (
unsigned i=0; it != this->
mCells.end(); ++it, ++i)
69 unsigned index = locationIndices.empty() ? i : locationIndices[i];
80 template<
unsigned DIM>
90 template<
unsigned DIM>
99 template<
unsigned DIM>
103 double average_damping_constant = 0.0;
105 std::set<unsigned> containing_elements =
GetNode(nodeIndex)->rGetContainingElementIndices();
107 unsigned num_containing_elements = containing_elements.size();
108 if (num_containing_elements == 0)
110 EXCEPTION(
"At time " <<
SimulationTime::Instance()->GetTime() <<
", Node " << nodeIndex <<
" is not contained in any elements, so GetDampingConstant() returns zero");
113 double temp = 1.0/((
double) num_containing_elements);
114 for (std::set<unsigned>::iterator iter = containing_elements.begin();
115 iter != containing_elements.end();
121 if (cell_is_wild_type)
131 return average_damping_constant;
134 template<
unsigned DIM>
140 template<
unsigned DIM>
146 template<
unsigned DIM>
152 template<
unsigned DIM>
155 return this->
mrMesh.GetNumNodes();
158 template<
unsigned DIM>
164 template<
unsigned DIM>
167 return this->
mrMesh.GetNode(index);
170 template<
unsigned DIM>
177 template<
unsigned DIM>
183 template<
unsigned DIM>
189 template<
unsigned DIM>
195 template<
unsigned DIM>
201 template<
unsigned DIM>
214 this->
mCells.push_back(pNewCell);
217 CellPtr p_created_cell = this->
mCells.back();
221 return p_created_cell;
224 template<
unsigned DIM>
227 unsigned num_removed = 0;
229 for (std::list<CellPtr>::iterator it = this->
mCells.begin();
244 WARN_ONCE_ONLY(
"A Cell is removed without performing a T2 swap. This could leave a void in the mesh.");
249 it = this->
mCells.erase(it);
259 template<
unsigned DIM>
262 double length = norm_2(rDisplacement);
270 std::ostringstream message;
271 message <<
"Vertices are moving more than half the CellRearrangementThreshold. This could cause elements to become inverted ";
272 message <<
"so the motion has been restricted. Use a smaller timestep to avoid these warnings.";
281 template<
unsigned DIM>
287 template<
unsigned DIM>
293 if (!element_map.IsIdentityMap())
302 for (std::list<CellPtr>::iterator cell_iter = this->
mCells.begin();
303 cell_iter != this->
mCells.end();
307 unsigned old_elem_index = old_map[(*cell_iter).get()];
308 assert(!element_map.IsDeleted(old_elem_index));
310 unsigned new_elem_index = element_map.GetNewIndex(old_elem_index);
318 element_map.ResetToIdentity();
321 template<
unsigned DIM>
325 std::vector<unsigned> validated_element = std::vector<unsigned>(this->
GetNumElements(), 0);
327 cell_iter != this->
End();
331 validated_element[elem_index]++;
334 for (
unsigned i=0; i<validated_element.size(); i++)
336 if (validated_element[i] == 0)
341 if (validated_element[i] > 1)
344 EXCEPTION(
"At time " <<
SimulationTime::Instance()->GetTime() <<
", Element " << i <<
" appears to have " << validated_element[i] <<
" cells associated with it");
349 template<
unsigned DIM>
352 pPopulationWriter->Visit(
this);
355 template<
unsigned DIM>
358 pPopulationCountWriter->Visit(
this);
361 template<
unsigned DIM>
364 pCellWriter->VisitCell(pCell,
this);
367 template<
unsigned DIM>
379 template<
unsigned DIM>
391 template<
unsigned DIM>
406 std::vector<double> vtk_cell_data(num_cells);
414 unsigned elem_index = elem_iter->GetIndex();
421 vtk_cell_data[elem_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell,
this);
424 mesh_writer.
AddCellData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data);
428 unsigned num_cell_data_items = this->
Begin()->GetCellData()->GetNumItems();
429 std::vector<std::string> cell_data_names = this->
Begin()->GetCellData()->GetKeys();
431 std::vector<std::vector<double> > cell_data;
432 for (
unsigned var=0; var<num_cell_data_items; var++)
434 std::vector<double> cell_data_var(num_cells);
435 cell_data.push_back(cell_data_var);
444 unsigned elem_index = elem_iter->GetIndex();
450 for (
unsigned var=0; var<num_cell_data_items; var++)
452 cell_data[var][elem_index] = p_cell->GetCellData()->GetItem(cell_data_names[var]);
455 for (
unsigned var=0; var<num_cell_data_items; var++)
457 mesh_writer.
AddCellData(cell_data_names[var], cell_data[var]);
461 std::stringstream time;
462 time << num_timesteps;
468 *(this->
mpVtkMetaFile) <<
"\" group=\"\" part=\"0\" file=\"results_";
474 template<
unsigned DIM>
479 if (!this->
template HasWriter<CellPopulationElementWriter>())
481 this->
template AddPopulationWriter<CellPopulationElementWriter>();
487 if (!this->
template HasWriter<VertexT1SwapLocationsWriter>())
489 this->
template AddPopulationWriter<VertexT1SwapLocationsWriter>();
491 if (!this->
template HasWriter<VertexT2SwapLocationsWriter>())
493 this->
template AddPopulationWriter<VertexT2SwapLocationsWriter>();
495 if (!this->
template HasWriter<VertexT3SwapLocationsWriter>())
497 this->
template AddPopulationWriter<VertexT3SwapLocationsWriter>();
504 template<
unsigned DIM>
510 template<
unsigned DIM>
516 template<
unsigned DIM>
525 *rParamsFile <<
"\t\t<VertexBasedDivisionRule>\n";
527 *rParamsFile <<
"\t\t</VertexBasedDivisionRule>\n";
533 template<
unsigned DIM>
537 double width = this->
mrMesh.GetWidth(rDimension);
542 template<
unsigned DIM>
548 template<
unsigned DIM>
554 template<
unsigned DIM>
560 template<
unsigned DIM>
566 template<
unsigned DIM>
572 template<
unsigned DIM>
578 template<
unsigned DIM>
584 template<
unsigned DIM>
591 template<
unsigned DIM>
601 std::string mesh_file_name =
"mesh";
604 std::stringstream pid;
606 OutputFileHandler output_file_handler(
"2D_temporary_tetrahedral_mesh_" + pid.str());
610 unsigned num_tetrahedral_nodes = num_vertex_nodes + num_vertex_elements;
613 out_stream p_node_file = output_file_handler.OpenOutputFile(mesh_file_name+
".node");
614 (*p_node_file) << std::scientific;
615 (*p_node_file) << std::setprecision(20);
616 (*p_node_file) << num_tetrahedral_nodes <<
"\t2\t0\t1" << std::endl;
619 for (
unsigned node_index=0; node_index<num_vertex_nodes; node_index++)
624 unsigned index = p_node->
GetIndex();
625 const c_vector<double, DIM>& r_location = p_node->
rGetLocation();
628 (*p_node_file) << index <<
"\t" << r_location[0] <<
"\t" << r_location[1] <<
"\t" << is_boundary_node << std::endl;
632 unsigned num_tetrahedral_elements = 0;
633 for (
unsigned vertex_elem_index=0; vertex_elem_index<num_vertex_elements; vertex_elem_index++)
635 unsigned index = num_vertex_nodes + vertex_elem_index;
640 unsigned is_boundary_node = 0;
641 (*p_node_file) << index <<
"\t" << location[0] <<
"\t" << location[1] <<
"\t" << is_boundary_node << std::endl;
646 p_node_file->close();
649 out_stream p_elem_file = output_file_handler.OpenOutputFile(mesh_file_name+
".ele");
650 (*p_elem_file) << std::scientific;
651 (*p_elem_file) << num_tetrahedral_elements <<
"\t3\t0" << std::endl;
653 std::set<std::pair<unsigned, unsigned> > tetrahedral_edges;
655 unsigned tetrahedral_elem_index = 0;
656 for (
unsigned vertex_elem_index=0; vertex_elem_index<num_vertex_elements; vertex_elem_index++)
661 unsigned num_nodes_in_vertex_element = p_vertex_element->
GetNumNodes();
662 for (
unsigned local_index=0; local_index<num_nodes_in_vertex_element; local_index++)
665 unsigned node_1_index = p_vertex_element->
GetNodeGlobalIndex((local_index+1)%num_nodes_in_vertex_element);
666 unsigned node_2_index = num_vertex_nodes + vertex_elem_index;
668 (*p_elem_file) << tetrahedral_elem_index++ <<
"\t" << node_0_index <<
"\t" << node_1_index <<
"\t" << node_2_index << std::endl;
671 std::pair<unsigned, unsigned> edge_0 = this->
CreateOrderedPair(node_0_index, node_1_index);
672 std::pair<unsigned, unsigned> edge_1 = this->
CreateOrderedPair(node_1_index, node_2_index);
673 std::pair<unsigned, unsigned> edge_2 = this->
CreateOrderedPair(node_2_index, node_0_index);
675 tetrahedral_edges.insert(edge_0);
676 tetrahedral_edges.insert(edge_1);
677 tetrahedral_edges.insert(edge_2);
680 p_elem_file->close();
683 out_stream p_edge_file = output_file_handler.OpenOutputFile(mesh_file_name+
".edge");
684 (*p_edge_file) << std::scientific;
685 (*p_edge_file) << tetrahedral_edges.size() <<
"\t1" << std::endl;
687 unsigned edge_index = 0;
688 for (std::set<std::pair<unsigned, unsigned> >::iterator edge_iter = tetrahedral_edges.begin();
689 edge_iter != tetrahedral_edges.end();
692 std::pair<unsigned, unsigned> this_edge = *edge_iter;
695 bool is_boundary_edge =
false;
702 unsigned is_boundary_edge_unsigned = is_boundary_edge ? 1 : 0;
704 (*p_edge_file) << edge_index++ <<
"\t" << this_edge.first <<
"\t" << this_edge.second <<
"\t" << is_boundary_edge_unsigned << std::endl;
706 p_edge_file->close();
718 output_file_handler.FindFile(
"").Remove();
726 template<
unsigned DIM>
729 bool non_apoptotic_cell_present =
true;
733 std::set<unsigned> containing_element_indices = this->
GetNode(pdeNodeIndex)->rGetContainingElementIndices();
735 for (std::set<unsigned>::iterator iter = containing_element_indices.begin();
736 iter != containing_element_indices.end();
741 non_apoptotic_cell_present =
false;
755 return non_apoptotic_cell_present;
758 template<
unsigned DIM>
760 unsigned pdeNodeIndex,
761 std::string& rVariableName,
762 bool dirichletBoundaryConditionApplies,
763 double dirichletBoundaryValue)
770 if (pdeNodeIndex >= num_nodes)
773 assert(pdeNodeIndex-num_nodes < num_nodes);
776 value = p_cell->GetCellData()->GetItem(rVariableName);
781 if (dirichletBoundaryConditionApplies)
784 value = dirichletBoundaryValue;
788 assert(pdeNodeIndex < num_nodes);
793 for (std::set<unsigned>::iterator index_iter = containing_elements.begin();
794 index_iter != containing_elements.end();
797 assert(*index_iter < num_nodes);
799 value += p_cell->GetCellData()->GetItem(rVariableName);
801 value /= containing_elements.size();
808 template<
unsigned DIM>
814 template<
unsigned DIM>
817 if (
bool(dynamic_cast<Cylindrical2dVertexMesh*>(&(this->
mrMesh))))
819 *pVizSetupFile <<
"MeshWidth\t" << this->
GetWidth(0) <<
"\n";
823 template<
unsigned DIM>
831 template<
unsigned DIM>
837 template<
unsigned DIM>
void SetOutputCellRearrangementLocations(bool outputCellRearrangementLocations)
void AddCellData(std::string dataName, std::vector< double > dataPayload)
double GetCellRearrangementRatio() const
std::vector< c_vector< double, DIM > > GetLocationsOfT2Swaps()
virtual double GetDefaultTimeStep()
std::vector< unsigned > mCellIdsOfT2Swaps
void AddCellKiller(boost::shared_ptr< AbstractCellKiller< SPACE_DIM > > pCellKiller)
virtual void AcceptPopulationCountWriter(boost::shared_ptr< AbstractCellPopulationCountWriter< DIM, DIM > > pPopulationCountWriter)
unsigned DivideElementAlongGivenAxis(VertexElement< ELEMENT_DIM, SPACE_DIM > *pElement, c_vector< double, SPACE_DIM > axisOfDivision, bool placeOriginalElementBelow=false)
double GetVolumeOfCell(CellPtr pCell)
std::set< unsigned > GetNeighbouringNodeIndices(unsigned nodeIndex)
virtual ~VertexBasedCellPopulation()
virtual CellPtr GetCellUsingLocationIndex(unsigned index)
unsigned GetLocationIndexUsingCell(CellPtr pCell)
std::vector< boost::shared_ptr< AbstractCellWriter< ELEMENT_DIM, SPACE_DIM > > > mCellWriters
unsigned GetNodeGlobalIndex(unsigned localIndex) const
double GetDampingConstantNormal()
unsigned GetNumAllElements() const
std::vector< c_vector< double, DIM > > mLocationsOfT2Swaps
virtual void SimulationSetupHook(AbstractCellBasedSimulation< DIM, DIM > *pSimulation)
unsigned GetNumElements()
double GetDampingConstantMutant()
bool IsBoundaryNode() const
Node< SPACE_DIM > * GetNode(unsigned index) const
#define EXCEPTION(message)
boost::shared_ptr< AbstractVertexBasedDivisionRule< DIM > > mpVertexBasedDivisionRule
MutableVertexMesh< DIM, DIM > * mpMutableVertexMesh
double GetT2Threshold() const
static SimulationTime * Instance()
bool mRestrictVertexMovement
unsigned AddNode(Node< SPACE_DIM > *pNewNode)
double GetCellRearrangementThreshold() const
void ConstructFromMeshReader(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader)
virtual void AcceptCellWriter(boost::shared_ptr< AbstractCellWriter< DIM, DIM > > pCellWriter, CellPtr pCell)
void SetVertexBasedDivisionRule(boost::shared_ptr< AbstractVertexBasedDivisionRule< DIM > > pVertexBasedDivisionRule)
std::vector< unsigned > GetCellIdsOfT2Swaps()
virtual bool IsPdeNodeAssociatedWithNonApoptoticCell(unsigned pdeNodeIndex)
std::set< unsigned > & rGetContainingElementIndices()
virtual void WriteDataToVisualizerSetupFile(out_stream &pVizSetupFile)
unsigned GetTimeStepsElapsed() const
std::set< unsigned > GetNeighbouringNodeIndices(unsigned index)
bool mOutputCellRearrangementLocations
std::string GetOutputDirectoryFullPath() const
VertexElement< ELEMENT_DIM, SPACE_DIM > * GetElement(unsigned index) const
unsigned GetNumAllCells()
boost::shared_ptr< AbstractVertexBasedDivisionRule< DIM > > GetVertexBasedDivisionRule()
bool mOutputResultsForChasteVisualizer
bool IsCellAssociatedWithADeletedLocation(CellPtr pCell)
double GetDampingConstant(unsigned nodeIndex)
void SetRestrictVertexMovementBoolean(bool restrictVertexMovement)
std::set< unsigned > GetNeighbouringLocationIndices(CellPtr pCell)
unsigned GetRosetteRankOfCell(CellPtr pCell)
MutableVertexMesh< DIM, DIM > & rGetMesh()
bool GetRestrictVertexMovementBoolean()
std::pair< unsigned, unsigned > CreateOrderedPair(unsigned index1, unsigned index2)
VertexElementIterator GetElementIteratorBegin(bool skipDeletedElements=true)
#define EXPORT_TEMPLATE_CLASS_SAME_DIMS(CLASS)
virtual void SetNode(unsigned nodeIndex, ChastePoint< SPACE_DIM > point)
std::map< unsigned, std::set< CellPtr > > mLocationCellMap
void SetCellUsingLocationIndex(unsigned index, CellPtr pCell)
virtual void AcceptPopulationWriter(boost::shared_ptr< AbstractCellPopulationWriter< DIM, DIM > > pPopulationWriter)
void Update(bool hasHadBirthsOrDeaths=true)
std::map< Cell *, unsigned > mCellLocationMap
unsigned GetNumNodes() const
void AddLocationOfT2Swap(c_vector< double, DIM > locationOfT2Swap)
VertexBasedCellPopulation(MutableVertexMesh< DIM, DIM > &rMesh, std::vector< CellPtr > &rCells, bool deleteMesh=false, bool validate=true, const std::vector< unsigned > locationIndices=std::vector< unsigned >())
Node< DIM > * GetNode(unsigned index)
unsigned GetNumNodes() const
virtual TetrahedralMesh< DIM, DIM > * GetTetrahedralMeshForPdeModifier()
void WriteVtkUsingMesh(VertexMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, std::string stamp="")
virtual double GetVolumeOfElement(unsigned index)
virtual void CheckForStepSizeException(unsigned nodeIndex, c_vector< double, DIM > &rDisplacement, double dt)
void OutputCellPopulationParameters(out_stream &rParamsFile)
virtual void OutputCellPopulationParameters(out_stream &rParamsFile)
unsigned RemoveDeadCells()
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
std::list< CellPtr > mCells
virtual void ReMesh(VertexElementMap &rElementMap)
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
void SetMeshHasChangedSinceLoading()
void SetNode(unsigned index, ChastePoint< DIM > &rNewLocation)
const c_vector< double, SPACE_DIM > & rGetLocation() const
void DeleteElementPriorToReMesh(unsigned index)
void AddCellIdOfT2Swap(unsigned idOfT2Swap)
double GetWidth(const unsigned &rDimension)
c_vector< double, DIM > GetLocationOfCellCentre(CellPtr pCell)
virtual c_vector< double, SPACE_DIM > GetCentroidOfElement(unsigned index)
unsigned GetNumElements() const
unsigned AddNode(Node< DIM > *pNewNode)
std::set< unsigned > GetNeighbouringElementIndices(unsigned elementIndex)
CellPtr AddCell(CellPtr pNewCell, CellPtr pParentCell=CellPtr())
virtual void WriteVtkResultsToFile(const std::string &rDirectory)
virtual double GetCellDataItemAtPdeNode(unsigned pdeNodeIndex, std::string &rVariableName, bool dirichletBoundaryConditionApplies=false, double dirichletBoundaryValue=0.0)
unsigned GetIndex() const
VertexElementIterator GetElementIteratorEnd()
void ClearLocationsAndCellIdsOfT2Swaps()
virtual void AddCellUsingLocationIndex(unsigned index, CellPtr pCell)
AbstractMesh< ELEMENT_DIM, SPACE_DIM > & mrMesh
VertexElement< DIM, DIM > * GetElement(unsigned elementIndex)
#define MAKE_PTR_ARGS(TYPE, NAME, ARGS)
bool GetOutputCellRearrangementLocations()
VertexElement< DIM, DIM > * GetElementCorrespondingToCell(CellPtr pCell)
unsigned GetRosetteRankOfElement(unsigned index)