36#include "MeshBasedCellPopulation.hpp"
37#include "VtkMeshWriter.hpp"
38#include "CellBasedEventHandler.hpp"
39#include "Cylindrical2dMesh.hpp"
40#include "Cylindrical2dVertexMesh.hpp"
41#include "Toroidal2dMesh.hpp"
42#include "Toroidal2dVertexMesh.hpp"
43#include "NodesOnlyMesh.hpp"
45#include "CellVolumesWriter.hpp"
46#include "CellPopulationElementWriter.hpp"
47#include "VoronoiDataWriter.hpp"
48#include "NodeVelocityWriter.hpp"
49#include "CellPopulationAreaWriter.hpp"
51template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
53 std::vector<CellPtr>& rCells,
54 const std::vector<unsigned> locationIndices,
58 mpVoronoiTessellation(nullptr),
59 mDeleteMesh(deleteMesh),
60 mUseAreaBasedDampingConstant(false),
61 mAreaBasedDampingConstantParameter(0.1),
62 mWriteVtkAsPoints(false),
63 mBoundVoronoiTessellation(false),
64 mScaleBoundByEdgeLength(false),
65 mBoundedVoroniTesselationLengthCutoff(DBL_MAX),
66 mOffsetNewBoundaryNodes(false),
67 mHasVariableRestLength(false)
71 assert(this->
mCells.size() <= this->mrMesh.GetNumNodes());
82 node_iter != this->
rGetMesh().GetNodeIteratorEnd();
85 node_iter->ClearAppliedForce();
89template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
99template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
102 delete mpVoronoiTessellation;
106 delete &this->mrMesh;
110template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
113 return mUseAreaBasedDampingConstant;
116template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
118 [[maybe_unused]]
bool useAreaBasedDampingConstant)
120 if constexpr (SPACE_DIM == 2)
122 mUseAreaBasedDampingConstant = useAreaBasedDampingConstant;
130template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
133 return mpMutableMesh->AddNode(pNewNode);
136template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
142template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
152 if (mUseAreaBasedDampingConstant)
162 if constexpr (SPACE_DIM == 2)
164 double rest_length = 1.0;
165 double d0 = mAreaBasedDampingConstantParameter;
172 double d1 = 2.0*(1.0 - d0)/(sqrt(3.0)*rest_length*rest_length);
174 double area_cell = GetVolumeOfVoronoiElement(nodeIndex);
181 assert(area_cell < 1000);
183 damping_multiplier = d0 + area_cell*d1;
191 return damping_multiplier;
194template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
197 std::vector<bool> validated_node = std::vector<bool>(this->GetNumNodes(),
false);
201 unsigned node_index = this->GetLocationIndexUsingCell(*cell_iter);
202 validated_node[node_index] =
true;
205 for (
unsigned i=0; i<validated_node.size(); i++)
207 if (!validated_node[i])
214template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
217 return *mpMutableMesh;
220template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
223 return *mpMutableMesh;
226template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
229 return mpMutableMesh;
232template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
235 unsigned num_removed = 0;
236 for (std::list<CellPtr>::iterator it = this->mCells.begin();
237 it != this->mCells.end();
243 std::vector<const std::pair<CellPtr,CellPtr>*> pairs_to_remove;
244 for (std::set<std::pair<CellPtr,CellPtr> >::iterator it1 = this->mMarkedSprings.begin();
245 it1 != this->mMarkedSprings.end();
248 const std::pair<CellPtr,CellPtr>& r_pair = *it1;
250 for (
unsigned i=0; i<2; i++)
252 CellPtr p_cell = (i==0 ? r_pair.first : r_pair.second);
257 pairs_to_remove.push_back(&r_pair);
264 for (std::vector<
const std::pair<CellPtr,CellPtr>* >::iterator pair_it = pairs_to_remove.begin();
265 pair_it != pairs_to_remove.end();
268 this->mMarkedSprings.erase(**pair_it);
276 unsigned location_index_of_removed_node = this->GetLocationIndexUsingCell((*it));
277 this->RemoveCellUsingLocationIndex(location_index_of_removed_node, (*it));
280 it = this->mCells.erase(it);
291template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
294 this->mNodePairs.clear();
295 for (
SpringIterator spring_it = SpringsBegin(); spring_it != SpringsEnd(); ++spring_it)
297 this->mNodePairs.emplace_back(spring_it.GetNodeA(), spring_it.GetNodeB());
301template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
305 bool output_node_velocities = (this->
template HasWriter<NodeVelocityWriter>());
317 std::map<unsigned, double> old_node_radius_map;
318 old_node_radius_map.clear();
319 if (this->mrMesh.GetNodeIteratorBegin()->HasNodeAttributes())
321 if (this->mrMesh.GetNodeIteratorBegin()->GetRadius() > 0.0)
324 node_iter != this->mrMesh.GetNodeIteratorEnd();
327 unsigned node_index = node_iter->GetIndex();
328 old_node_radius_map[node_index] = node_iter->GetRadius();
333 std::map<unsigned, c_vector<double, SPACE_DIM> > old_node_applied_force_map;
334 old_node_applied_force_map.clear();
335 if (output_node_velocities)
343 node_iter != this->mrMesh.GetNodeIteratorEnd();
346 unsigned node_index = node_iter->GetIndex();
347 old_node_applied_force_map[node_index] = node_iter->rGetAppliedForce();
351 NodeMap node_map(this->mrMesh.GetNumAllNodes());
356 if (!node_map.IsIdentityMap())
358 UpdateGhostNodesAfterReMesh(node_map);
361 std::map<Cell*, unsigned> old_cell_location_map = this->mCellLocationMap;
364 this->mLocationCellMap.clear();
365 this->mCellLocationMap.clear();
367 for (std::list<CellPtr>::iterator it = this->mCells.begin(); it != this->mCells.end(); ++it)
369 unsigned old_node_index = old_cell_location_map[(*it).get()];
372 assert(!node_map.IsDeleted(old_node_index));
374 unsigned new_node_index = node_map.GetNewIndex(old_node_index);
375 this->SetCellUsingLocationIndex(new_node_index,*it);
377 if (old_node_radius_map[old_node_index] > 0.0)
379 this->GetNode(new_node_index)->SetRadius(old_node_radius_map[old_node_index]);
381 if (output_node_velocities)
383 this->GetNode(new_node_index)->AddAppliedForceContribution(old_node_applied_force_map[old_node_index]);
391 if (old_node_radius_map[this->mCellLocationMap[(*(this->mCells.begin())).get()]] > 0.0)
393 for (std::list<CellPtr>::iterator it = this->mCells.begin(); it != this->mCells.end(); ++it)
395 unsigned node_index = this->mCellLocationMap[(*it).get()];
396 this->GetNode(node_index)->SetRadius(old_node_radius_map[node_index]);
399 if (output_node_velocities)
401 for (std::list<CellPtr>::iterator it = this->mCells.begin(); it != this->mCells.end(); ++it)
403 unsigned node_index = this->mCellLocationMap[(*it).get()];
404 this->GetNode(node_index)->AddAppliedForceContribution(old_node_applied_force_map[node_index]);
410 std::vector<const std::pair<CellPtr,CellPtr>*> springs_to_remove;
411 for (std::set<std::pair<CellPtr,CellPtr> >::iterator spring_it = this->mMarkedSprings.begin();
412 spring_it != this->mMarkedSprings.end();
415 CellPtr p_cell_1 = spring_it->first;
416 CellPtr p_cell_2 = spring_it->second;
417 Node<SPACE_DIM>* p_node_1 = this->GetNodeCorrespondingToCell(p_cell_1);
418 Node<SPACE_DIM>* p_node_2 = this->GetNodeCorrespondingToCell(p_cell_2);
428 if (node2_elements.find(*elem_iter) != node2_elements.end())
438 springs_to_remove.push_back(&(*spring_it));
443 for (std::vector<
const std::pair<CellPtr,CellPtr>* >::iterator spring_it = springs_to_remove.begin();
444 spring_it != springs_to_remove.end();
447 this->mMarkedSprings.erase(**spring_it);
454 TessellateIfNeeded();
459template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
462 if ((SPACE_DIM==2 || SPACE_DIM==3)&&(ELEMENT_DIM==SPACE_DIM))
465 if (mUseAreaBasedDampingConstant ||
466 this->
template HasWriter<VoronoiDataWriter>() ||
467 this->
template HasWriter<CellPopulationAreaWriter>() ||
468 this->
template HasWriter<CellVolumesWriter>())
470 CreateVoronoiTessellation();
476template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
480 if constexpr (ELEMENT_DIM == 2)
482 std::vector<c_vector<unsigned, 5> > new_nodes;
483 new_nodes = rGetMesh().SplitLongEdges(springDivisionThreshold);
486 for (
unsigned index=0; index<new_nodes.size(); index++)
489 unsigned new_node_index = new_nodes[index][0];
490 unsigned node_a_index = new_nodes[index][1];
491 unsigned node_b_index = new_nodes[index][2];
493 CellPtr p_neighbour_cell = this->GetCellUsingLocationIndex(node_a_index);
501 CellPtr p_new_cell(
new Cell(p_neighbour_cell->GetMutationState(),
502 p_neighbour_cell->GetCellCycleModel()->CreateCellCycleModel(),
503 p_neighbour_cell->GetSrnModel()->CreateSrnModel(),
505 daughter_property_collection));
508 this->mCells.push_back(p_new_cell);
509 this->AddCellUsingLocationIndex(new_node_index,p_new_cell);
514 std::pair<unsigned,unsigned> node_pair = this->CreateOrderedPair(node_a_index, node_b_index);
515 double old_rest_length = mSpringRestLengths[node_pair];
517 std::map<std::pair<unsigned,unsigned>,
double>::iterator iter = mSpringRestLengths.find(node_pair);
518 mSpringRestLengths.erase(iter);
521 node_pair = this->CreateOrderedPair(node_a_index, new_node_index);
522 mSpringRestLengths[node_pair] = 0.5*old_rest_length;
524 node_pair = this->CreateOrderedPair(node_b_index, new_node_index);
525 mSpringRestLengths[node_pair] = 0.5*old_rest_length;
528 for (
unsigned pair_index=3; pair_index<5; pair_index++)
530 unsigned other_node_index = new_nodes[index][pair_index];
534 node_pair = this->CreateOrderedPair(other_node_index, new_node_index);
535 double new_rest_length = rGetMesh().GetDistanceBetweenNodes(new_node_index, other_node_index);
536 mSpringRestLengths[node_pair] = new_rest_length;
547template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
550 return this->mrMesh.GetNode(index);
553template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
556 return this->mrMesh.GetNumAllNodes();
559template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
564template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
572 assert(p_created_cell == pNewCell);
575 std::pair<CellPtr,CellPtr> cell_pair = this->CreateCellPair(pParentCell, p_created_cell);
576 this->MarkSpring(cell_pair);
579 return p_created_cell;
586template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
589 if (this->mOutputResultsForChasteVisualizer)
591 if (!this->
template HasWriter<CellPopulationElementWriter>())
593 this->
template AddPopulationWriter<CellPopulationElementWriter>();
600template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
605 TessellateIfNeeded();
611template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
614 pPopulationWriter->Visit(
this);
617template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
620 pPopulationCountWriter->Visit(
this);
623template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
626 pPopulationEventWriter->Visit(
this);
629template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
632 pCellWriter->VisitCell(pCell,
this);
635template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
641 std::stringstream time;
642 time << num_timesteps;
645 unsigned num_cells_from_mesh = GetNumNodes();
648 unsigned num_cell_data_items = this->Begin()->GetCellData()->GetNumItems();
649 std::vector<std::string> cell_data_names = this->Begin()->GetCellData()->GetKeys();
651 std::vector<std::vector<double> > cell_data;
652 for (
unsigned var=0; var<num_cell_data_items; var++)
654 std::vector<double> cell_data_var(num_cells_from_mesh);
655 cell_data.push_back(cell_data_var);
658 if (mWriteVtkAsPoints)
664 unsigned num_cells = this->GetNumAllCells();
666 cell_writer_iter != this->mCellWriters.end();
670 std::vector<double> vtk_cell_data(num_cells);
674 cell_iter != this->End();
678 unsigned node_index = this->GetLocationIndexUsingCell(*cell_iter);
681 vtk_cell_data[node_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(*cell_iter,
this);
684 cells_writer.AddPointData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data);
689 cell_iter != this->End();
693 unsigned node_index = this->GetLocationIndexUsingCell(*cell_iter);
695 for (
unsigned var=0; var<num_cell_data_items; var++)
697 cell_data[var][node_index] = cell_iter->GetCellData()->GetItem(cell_data_names[var]);
700 for (
unsigned var=0; var<num_cell_data_items; var++)
702 cells_writer.AddPointData(cell_data_names[var], cell_data[var]);
706 cells_writer.WriteFilesUsingMesh(rGetMesh());
707 *(this->mpVtkMetaFile) <<
" <DataSet timestep=\"";
708 *(this->mpVtkMetaFile) << num_timesteps;
709 *(this->mpVtkMetaFile) <<
"\" group=\"\" part=\"0\" file=\"mesh_results_";
710 *(this->mpVtkMetaFile) << num_timesteps;
711 *(this->mpVtkMetaFile) <<
".vtu\"/>\n";
713 if (mpVoronoiTessellation !=
nullptr)
717 std::vector<double> cell_volumes(num_cells_from_mesh);
720 unsigned num_cells = this->GetNumAllCells();
722 cell_writer_iter != this->mCellWriters.end();
726 std::vector<double> vtk_cell_data(num_cells);
730 elem_iter != mpVoronoiTessellation->GetElementIteratorEnd();
734 unsigned elem_index = elem_iter->GetIndex();
737 unsigned node_index = mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index);
738 CellPtr p_cell = this->GetCellUsingLocationIndex(node_index);
741 vtk_cell_data[elem_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell,
this);
744 mesh_writer.AddCellData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data);
749 elem_iter != mpVoronoiTessellation->GetElementIteratorEnd();
753 unsigned elem_index = elem_iter->GetIndex();
756 unsigned node_index = mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index);
757 CellPtr p_cell = this->GetCellUsingLocationIndex(node_index);
759 for (
unsigned var=0; var<num_cell_data_items; var++)
761 cell_data[var][elem_index] = p_cell->GetCellData()->GetItem(cell_data_names[var]);
765 for (
unsigned var=0; var<cell_data.size(); var++)
767 mesh_writer.AddCellData(cell_data_names[var], cell_data[var]);
770 mesh_writer.WriteVtkUsingMesh(*mpVoronoiTessellation, time.str());
771 *(this->mpVtkMetaFile) <<
" <DataSet timestep=\"";
772 *(this->mpVtkMetaFile) << num_timesteps;
773 *(this->mpVtkMetaFile) <<
"\" group=\"\" part=\"0\" file=\"voronoi_results_";
774 *(this->mpVtkMetaFile) << num_timesteps;
775 *(this->mpVtkMetaFile) <<
".vtu\"/>\n";
780template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
783 double cell_volume = 0;
785 if (ELEMENT_DIM == SPACE_DIM)
788 if (mpVoronoiTessellation ==
nullptr)
790 CreateVoronoiTessellation();
794 unsigned node_index = this->GetLocationIndexUsingCell(pCell);
799 unsigned element_index = mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(node_index);
802 cell_volume = mpVoronoiTessellation->GetVolumeOfElement(element_index);
807 cell_volume = DBL_MAX;
810 else if (SPACE_DIM==3 && ELEMENT_DIM==2)
812 unsigned node_index = this->GetLocationIndexUsingCell(pCell);
824 c_matrix<double, SPACE_DIM, ELEMENT_DIM> jacob;
829 cell_volume += fabs(p_element->
GetVolume(det));
844template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
847 mWriteVtkAsPoints = writeVtkAsPoints;
850template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
853 return mWriteVtkAsPoints;
856template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
859 mBoundVoronoiTessellation = boundVoronoiTessellation;
862template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
865 return mBoundVoronoiTessellation;
868template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
871 mScaleBoundByEdgeLength = scaleBoundByEdgeLength;
874template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
877 return mScaleBoundByEdgeLength;
880template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
883 assert(boundedVoroniTesselationLengthCutoff>0);
884 mBoundedVoroniTesselationLengthCutoff = boundedVoroniTesselationLengthCutoff;
887template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
890 return mBoundedVoroniTesselationLengthCutoff;
893template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
896 mOffsetNewBoundaryNodes = offsetNewBoundaryNodes;
899template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
902 return mOffsetNewBoundaryNodes;
907template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
912 *pVizSetupFile <<
"MeshWidth\t" << this->GetWidth(0) <<
"\n";
916 *pVizSetupFile <<
"MeshWidth\t" << this->GetWidth(0) <<
"\n";
917 *pVizSetupFile <<
"MeshHeight\t" << this->GetWidth(1) <<
"\n";
921template <
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
924 if constexpr (ELEMENT_DIM == 1)
929 else if constexpr (ELEMENT_DIM == 2 && SPACE_DIM == 2)
931 delete mpVoronoiTessellation;
934 bool is_mesh_periodic =
false;
937 if(mScaleBoundByEdgeLength || mBoundedVoroniTesselationLengthCutoff<DBL_MAX || mOffsetNewBoundaryNodes)
942 is_mesh_periodic =
true;
947 if(mScaleBoundByEdgeLength || mBoundedVoroniTesselationLengthCutoff<DBL_MAX || mOffsetNewBoundaryNodes)
952 is_mesh_periodic =
true;
957 mpVoronoiTessellation =
new VertexMesh<2, 2>(
static_cast<MutableMesh<2, 2>&
>((this->mrMesh)), is_mesh_periodic, mBoundVoronoiTessellation, mScaleBoundByEdgeLength, mBoundedVoroniTesselationLengthCutoff, mOffsetNewBoundaryNodes);
960 else if constexpr (ELEMENT_DIM == 3)
965 delete mpVoronoiTessellation;
978template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
984template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
987 return mEdgeIter.GetNodeB();
990template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
993 assert((*
this) != mrCellPopulation.SpringsEnd());
994 return mrCellPopulation.GetCellUsingLocationIndex(mEdgeIter.GetNodeA()->GetIndex());
997template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1000 assert((*
this) != mrCellPopulation.SpringsEnd());
1001 return mrCellPopulation.GetCellUsingLocationIndex(mEdgeIter.GetNodeB()->GetIndex());
1004template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1010template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1013 bool edge_is_ghost =
false;
1018 if (*
this != mrCellPopulation.SpringsEnd())
1020 bool a_is_ghost = mrCellPopulation.IsGhostNode(mEdgeIter.GetNodeA()->GetIndex());
1021 bool b_is_ghost = mrCellPopulation.IsGhostNode(mEdgeIter.GetNodeB()->GetIndex());
1023 edge_is_ghost = (a_is_ghost || b_is_ghost);
1026 while (*
this!=mrCellPopulation.SpringsEnd() && edge_is_ghost);
1031template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1035 : mrCellPopulation(rCellPopulation),
1043 if (a_is_ghost || b_is_ghost)
1050template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1056template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1062template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1069template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1072 unsigned element_index =
mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index);
1077template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1080 unsigned element_index =
mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index);
1082 return surface_area;
1085template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1088 unsigned element_index1 =
mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index1);
1089 unsigned element_index2 =
mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index2);
1098 EXCEPTION(
"Spring iterator tried to calculate interaction between degenerate cells on the boundary of the mesh. Have you set ghost layers correctly?");
1102template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1106 for (std::list<CellPtr>::iterator it=this->
mCells.begin();
1110 CellPtr p_cell = *it;
1117 std::cout <<
"Cell at node " << node_index <<
" addr " << p_cell << std::endl << std::flush;
1120 if (p_cell_in_cell_population != p_cell)
1122 std::cout <<
" Mismatch with cell population" << std::endl << std::flush;
1127 if (p_model->
GetCell() != p_cell)
1129 std::cout <<
" Mismatch with cycle model" << std::endl << std::flush;
1138 for (std::set<std::pair<CellPtr,CellPtr> >::iterator it1 = this->
mMarkedSprings.begin();
1142 const std::pair<CellPtr,CellPtr>& r_pair = *it1;
1144 for (
unsigned i=0; i<2; i++)
1146 CellPtr p_cell = (i==0 ? r_pair.first : r_pair.second);
1152 std::cout <<
"Cell at node " << node_index <<
" addr " << p_cell << std::endl << std::flush;
1156 if (p_cell->IsDead())
1158 std::cout <<
" Cell is dead" << std::endl << std::flush;
1164 if (p_cell_in_cell_population != p_cell)
1166 std::cout <<
" Mismatch with cell population" << std::endl << std::flush;
1171 if (p_model->
GetCell() != p_cell)
1173 std::cout <<
" Mismatch with cycle model" << std::endl << std::flush;
1182template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1188template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1191 assert(areaBasedDampingConstantParameter >= 0.0);
1195template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1200 *rParamsFile <<
"\t\t<WriteVtkAsPoints>" <<
mWriteVtkAsPoints <<
"</WriteVtkAsPoints>\n";
1208template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1212 double width = this->
mrMesh.GetWidth(rDimension);
1216template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1223 std::set<unsigned> neighbouring_node_indices;
1232 for (
unsigned i=0; i<p_element->
GetNumNodes(); i++)
1236 if (node_index != index)
1238 neighbouring_node_indices.insert(node_index);
1242 return neighbouring_node_indices;
1245template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1259 unsigned nodeA_global_index = p_nodeA->
GetIndex();
1260 unsigned nodeB_global_index = p_nodeB->
GetIndex();
1263 double separation =
rGetMesh().GetDistanceBetweenNodes(nodeA_global_index, nodeB_global_index);
1266 std::pair<unsigned,unsigned> node_pair = this->
CreateOrderedPair(nodeA_global_index, nodeB_global_index);
1273template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1278 std::pair<unsigned,unsigned> node_pair = this->
CreateOrderedPair(indexA, indexB);
1279 std::map<std::pair<unsigned,unsigned>,
double>::const_iterator iter =
mSpringRestLengths.find(node_pair);
1284 return iter->second;
1288 EXCEPTION(
"Tried to get a rest length of an edge that doesn't exist. You can only use variable rest lengths if SetUpdateCellPopulationRule is set on the simulation.");
1297template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
1302 std::pair<unsigned,unsigned> node_pair = this->
CreateOrderedPair(indexA, indexB);
1303 std::map<std::pair<unsigned,unsigned>,
double>::iterator iter =
mSpringRestLengths.find(node_pair);
1308 iter->second = restLength;
1312 EXCEPTION(
"Tried to set the rest length of an edge not in the mesh.");
1317 EXCEPTION(
"Tried to set a rest length in a simulation with fixed rest length. You can only use variable rest lengths if SetUpdateCellPopulationRule is set on the simulation.");
#define EXCEPTION(message)
const unsigned UNSIGNED_UNSET
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
AbstractMesh< ELEMENT_DIM, SPACE_DIM > & mrMesh
std::list< CellPtr > mCells
unsigned GetLocationIndexUsingCell(CellPtr pCell)
virtual void WriteResultsToFiles(const std::string &rDirectory)
virtual CellPtr GetCellUsingLocationIndex(unsigned index)
std::pair< unsigned, unsigned > CreateOrderedPair(unsigned index1, unsigned index2)
std::set< std::pair< CellPtr, CellPtr > > mMarkedSprings
virtual void OutputCellPopulationParameters(out_stream &rParamsFile)
virtual double GetDampingConstant(unsigned nodeIndex)
CellPtr AddCell(CellPtr pNewCell, CellPtr pParentCell=CellPtr())
unsigned GetNumNodes() const
unsigned GetNodeGlobalIndex(unsigned localIndex) const
void SetMeshHasChangedSinceLoading()
double GetVolume(double determinant) const
void CalculateJacobian(c_matrix< double, SPACE_DIM, ELEMENT_DIM > &rJacobian, double &rJacobianDeterminant)
Element< ELEMENT_DIM, SPACE_DIM > * GetElement(unsigned index) const
static void BeginEvent(unsigned event)
static void EndEvent(unsigned event)
MutableMesh< ELEMENT_DIM, SPACE_DIM >::EdgeIterator mEdgeIter
MeshBasedCellPopulation< ELEMENT_DIM, SPACE_DIM > & mrCellPopulation
bool operator!=(const typename MeshBasedCellPopulation< ELEMENT_DIM, SPACE_DIM >::SpringIterator &rOther)
SpringIterator(MeshBasedCellPopulation< ELEMENT_DIM, SPACE_DIM > &rCellPopulation, typename MutableMesh< ELEMENT_DIM, SPACE_DIM >::EdgeIterator edgeIter)
SpringIterator & operator++()
Node< SPACE_DIM > * GetNodeA()
Node< SPACE_DIM > * GetNodeB()
bool UseAreaBasedDampingConstant()
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
bool GetOffsetNewBoundaryNodes()
virtual void UpdateNodePairs()
double GetBoundedVoroniTesselationLengthCutoff()
std::map< std::pair< unsigned, unsigned >, double > mSpringRestLengths
void TessellateIfNeeded()
void SetBoundedVoroniTesselationLengthCutoff(double boundedVoroniTesselationLengthCutoff)
void OutputCellPopulationParameters(out_stream &rParamsFile)
bool GetBoundVoronoiTessellation()
virtual void WriteResultsToFiles(const std::string &rDirectory)
bool mBoundVoronoiTessellation
virtual void Update(bool hasHadBirthsOrDeaths=true)
bool mUseAreaBasedDampingConstant
bool mHasVariableRestLength
bool GetScaleBoundByEdgeLength()
double GetVoronoiEdgeLength(unsigned index1, unsigned index2)
void SetScaleBoundByEdgeLength(bool scaleBoundByEdgeLength)
virtual void AcceptPopulationWriter(boost::shared_ptr< AbstractCellPopulationWriter< ELEMENT_DIM, SPACE_DIM > > pPopulationWriter)
double GetDampingConstant(unsigned nodeIndex)
virtual ~MeshBasedCellPopulation()
virtual void AcceptCellWriter(boost::shared_ptr< AbstractCellWriter< ELEMENT_DIM, SPACE_DIM > > pCellWriter, CellPtr pCell)
void SetWriteVtkAsPoints(bool writeVtkAsPoints)
double GetWidth(const unsigned &rDimension)
MeshBasedCellPopulation(MutableMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, std::vector< CellPtr > &rCells, const std::vector< unsigned > locationIndices={}, bool deleteMesh=false, bool validate=true)
SpringIterator SpringsEnd()
void SetNode(unsigned nodeIndex, ChastePoint< SPACE_DIM > &rNewLocation)
virtual void AcceptPopulationEventWriter(boost::shared_ptr< AbstractCellPopulationEventWriter< ELEMENT_DIM, SPACE_DIM > > pPopulationEventWriter)
void SetAreaBasedDampingConstant(bool useAreaBasedDampingConstant)
virtual void WriteVtkResultsToFile(const std::string &rDirectory)
virtual TetrahedralMesh< ELEMENT_DIM, SPACE_DIM > * GetTetrahedralMeshForPdeModifier()
SpringIterator SpringsBegin()
VertexMesh< ELEMENT_DIM, SPACE_DIM > * mpVoronoiTessellation
virtual CellPtr AddCell(CellPtr pNewCell, CellPtr pParentCell)
unsigned AddNode(Node< SPACE_DIM > *pNewNode)
double GetSurfaceAreaOfVoronoiElement(unsigned index)
void SetOffsetNewBoundaryNodes(bool offsetNewBoundaryNodes)
std::set< unsigned > GetNeighbouringNodeIndices(unsigned index)
Node< SPACE_DIM > * GetNode(unsigned index)
virtual void UpdateGhostNodesAfterReMesh(NodeMap &rMap)
void SetBoundVoronoiTessellation(bool boundVoronoiTessellation)
void CreateVoronoiTessellation()
virtual void AcceptPopulationCountWriter(boost::shared_ptr< AbstractCellPopulationCountWriter< ELEMENT_DIM, SPACE_DIM > > pPopulationCountWriter)
double GetVolumeOfVoronoiElement(unsigned index)
virtual unsigned RemoveDeadCells()
void SetRestLength(unsigned indexA, unsigned indexB, double restLength)
bool GetWriteVtkAsPoints()
double mAreaBasedDampingConstantParameter
virtual void WriteDataToVisualizerSetupFile(out_stream &pVizSetupFile)
VertexMesh< ELEMENT_DIM, SPACE_DIM > * GetVoronoiTessellation()
MutableMesh< ELEMENT_DIM, SPACE_DIM > * mpMutableMesh
void SetAreaBasedDampingConstantParameter(double areaBasedDampingConstantParameter)
void DivideLongSprings(double springDivisionThreshold)
double GetRestLength(unsigned indexA, unsigned indexB)
double GetVolumeOfCell(CellPtr pCell)
MutableMesh< ELEMENT_DIM, SPACE_DIM > & rGetMesh()
double GetAreaBasedDampingConstantParameter()
void CalculateRestLengths()
virtual void ReMesh(NodeMap &map)
void DeleteNodePriorToReMesh(unsigned index)
virtual void SetNode(unsigned index, ChastePoint< SPACE_DIM > point, bool concreteMove=true)
ContainingElementIterator ContainingElementsEnd() const
std::set< unsigned > & rGetContainingElementIndices()
ContainingElementIterator ContainingElementsBegin() const
unsigned GetIndex() const
static SimulationTime * Instance()
unsigned GetTimeStepsElapsed() const