Chaste  Release::3.4
MeshBasedCellPopulation.cpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #include "MeshBasedCellPopulation.hpp"
37 #include "TrianglesMeshWriter.hpp"
38 #include "VtkMeshWriter.hpp"
39 #include "CellBasedEventHandler.hpp"
40 #include "ApoptoticCellProperty.hpp"
41 #include "Cylindrical2dMesh.hpp"
42 #include "Cylindrical2dVertexMesh.hpp"
43 #include "NodesOnlyMesh.hpp"
44 #include "Exception.hpp"
45 
46 // Cell writers
47 #include "CellAgesWriter.hpp"
48 #include "CellAncestorWriter.hpp"
49 #include "CellProliferativePhasesWriter.hpp"
50 #include "CellProliferativeTypesWriter.hpp"
51 #include "CellVolumesWriter.hpp"
52 
53 // Cell population writers
54 #include "CellMutationStatesCountWriter.hpp"
55 #include "CellPopulationElementWriter.hpp"
56 #include "VoronoiDataWriter.hpp"
57 #include "NodeVelocityWriter.hpp"
58 #include "CellPopulationAreaWriter.hpp"
59 
60 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
62  std::vector<CellPtr>& rCells,
63  const std::vector<unsigned> locationIndices,
64  bool deleteMesh,
65  bool validate)
66  : AbstractCentreBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>(rMesh, rCells, locationIndices),
67  mpVoronoiTessellation(NULL),
68  mDeleteMesh(deleteMesh),
69  mUseAreaBasedDampingConstant(false),
70  mAreaBasedDampingConstantParameter(0.1),
71  mWriteVtkAsPoints(false),
72  mOutputMeshInVtk(false),
73  mHasVariableRestLength(false)
74 {
75  mpMutableMesh = static_cast<MutableMesh<ELEMENT_DIM,SPACE_DIM>* >(&(this->mrMesh));
76 
77  assert(this->mCells.size() <= this->mrMesh.GetNumNodes());
78 
79  if (validate)
80  {
81  Validate();
82  }
83 
84  // Initialise the applied force at each node to zero
85  for (typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator node_iter = this->rGetMesh().GetNodeIteratorBegin();
86  node_iter != this->rGetMesh().GetNodeIteratorEnd();
87  ++node_iter)
88  {
89  node_iter->ClearAppliedForce();
90  }
91 }
92 
93 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
95  : AbstractCentreBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>(rMesh)
96 {
97  mpMutableMesh = static_cast<MutableMesh<ELEMENT_DIM,SPACE_DIM>* >(&(this->mrMesh));
98  mpVoronoiTessellation = NULL;
99  mDeleteMesh = true;
100 }
101 
102 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
104 {
105  delete mpVoronoiTessellation;
106 
107  if (mDeleteMesh)
108  {
109  delete &this->mrMesh;
110  }
111 }
112 
113 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
115 {
116  return mUseAreaBasedDampingConstant;
117 }
118 
119 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
121 {
122  assert(SPACE_DIM==2);
123  mUseAreaBasedDampingConstant = useAreaBasedDampingConstant;
124 }
125 
126 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
128 {
129  return mpMutableMesh->AddNode(pNewNode);
130 }
131 
132 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
134 {
135  static_cast<MutableMesh<ELEMENT_DIM,SPACE_DIM>&>((this->mrMesh)).SetNode(nodeIndex, rNewLocation, false);
136 }
137 
138 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
140 {
142 
143  /*
144  * The next code block computes the area-dependent damping constant as given by equation
145  * (5) in the following reference: van Leeuwen et al. 2009. An integrative computational model
146  * for intestinal tissue renewal. Cell Prolif. 42(5):617-636. doi:10.1111/j.1365-2184.2009.00627.x
147  */
148  if (mUseAreaBasedDampingConstant)
149  {
159  assert(SPACE_DIM==2);
160 
161  double rest_length = 1.0;
162  double d0 = mAreaBasedDampingConstantParameter;
163 
169  double d1 = 2.0*(1.0 - d0)/(sqrt(3.0)*rest_length*rest_length);
170 
171  double area_cell = GetVolumeOfVoronoiElement(nodeIndex);
172 
178  assert(area_cell < 1000);
179 
180  damping_multiplier = d0 + area_cell*d1;
181  }
182 
183  return damping_multiplier;
184 }
185 
186 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
188 {
189  std::vector<bool> validated_node = std::vector<bool>(this->GetNumNodes(), false);
190 
191  for (typename AbstractCellPopulation<ELEMENT_DIM,SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
192  {
193  unsigned node_index = this->GetLocationIndexUsingCell(*cell_iter);
194  validated_node[node_index] = true;
195  }
196 
197  for (unsigned i=0; i<validated_node.size(); i++)
198  {
199  if (!validated_node[i])
200  {
201  EXCEPTION("At time " << SimulationTime::Instance()->GetTime() << ", Node " << i << " does not appear to have a cell associated with it");
202  }
203  }
204 }
205 
206 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
208 {
209  return *mpMutableMesh;
210 }
211 
212 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
214 {
215  return *mpMutableMesh;
216 }
217 
218 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
220 {
221  unsigned num_removed = 0;
222  for (std::list<CellPtr>::iterator it = this->mCells.begin();
223  it != this->mCells.end();
224  )
225  {
226  if ((*it)->IsDead())
227  {
228  // Check if this cell is in a marked spring
229  std::vector<const std::pair<CellPtr,CellPtr>*> pairs_to_remove; // Pairs that must be purged
230  for (std::set<std::pair<CellPtr,CellPtr> >::iterator it1 = this->mMarkedSprings.begin();
231  it1 != this->mMarkedSprings.end();
232  ++it1)
233  {
234  const std::pair<CellPtr,CellPtr>& r_pair = *it1;
235 
236  for (unsigned i=0; i<2; i++)
237  {
238  CellPtr p_cell = (i==0 ? r_pair.first : r_pair.second);
239 
240  if (p_cell == *it)
241  {
242  // Remember to purge this spring
243  pairs_to_remove.push_back(&r_pair);
244  break;
245  }
246  }
247  }
248 
249  // Purge any marked springs that contained this cell
250  for (std::vector<const std::pair<CellPtr,CellPtr>* >::iterator pair_it = pairs_to_remove.begin();
251  pair_it != pairs_to_remove.end();
252  ++pair_it)
253  {
254  this->mMarkedSprings.erase(**pair_it);
255  }
256 
257  // Remove the node from the mesh
258  num_removed++;
259  static_cast<MutableMesh<ELEMENT_DIM,SPACE_DIM>&>((this->mrMesh)).DeleteNodePriorToReMesh(this->GetLocationIndexUsingCell((*it)));
260 
261  // Update mappings between cells and location indices
262  unsigned location_index_of_removed_node = this->GetLocationIndexUsingCell((*it));
263  this->RemoveCellUsingLocationIndex(location_index_of_removed_node, (*it));
264 
265  // Update vector of cells
266  it = this->mCells.erase(it);
267  }
268  else
269  {
270  ++it;
271  }
272  }
273 
274  return num_removed;
275 }
276 
277 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
279 {
281  bool output_node_velocities = (this-> template HasWriter<NodeVelocityWriter>());
282 
293  std::map<unsigned, double> old_node_radius_map;
294  old_node_radius_map.clear();
295  if (this->mrMesh.GetNodeIteratorBegin()->HasNodeAttributes())
296  {
297  if (this->mrMesh.GetNodeIteratorBegin()->GetRadius() > 0.0)
298  {
299  for (typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator node_iter = this->mrMesh.GetNodeIteratorBegin();
300  node_iter != this->mrMesh.GetNodeIteratorEnd();
301  ++node_iter)
302  {
303  unsigned node_index = node_iter->GetIndex();
304  old_node_radius_map[node_index] = node_iter->GetRadius();
305  }
306  }
307  }
308 
309  std::map<unsigned, c_vector<double, SPACE_DIM> > old_node_applied_force_map;
310  old_node_applied_force_map.clear();
311  if (output_node_velocities)
312  {
313  /*
314  * If outputting node velocities, we must keep a record of the applied force at each
315  * node, since this will be cleared during the remeshing process. We then restore
316  * these attributes to the nodes after calling ReMesh().
317  */
318  for (typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator node_iter = this->mrMesh.GetNodeIteratorBegin();
319  node_iter != this->mrMesh.GetNodeIteratorEnd();
320  ++node_iter)
321  {
322  unsigned node_index = node_iter->GetIndex();
323  old_node_applied_force_map[node_index] = node_iter->rGetAppliedForce();
324  }
325  }
326 
327  NodeMap node_map(this->mrMesh.GetNumAllNodes());
328 
329  // We must use a static_cast to call ReMesh() as this method is not defined in parent mesh classes
330  static_cast<MutableMesh<ELEMENT_DIM,SPACE_DIM>&>((this->mrMesh)).ReMesh(node_map);
331 
332  if (!node_map.IsIdentityMap())
333  {
334  UpdateGhostNodesAfterReMesh(node_map);
335 
336  // Update the mappings between cells and location indices
337  std::map<Cell*, unsigned> old_cell_location_map = this->mCellLocationMap;
338 
339  // Remove any dead pointers from the maps (needed to avoid archiving errors)
340  this->mLocationCellMap.clear();
341  this->mCellLocationMap.clear();
342 
343  for (std::list<CellPtr>::iterator it = this->mCells.begin(); it != this->mCells.end(); ++it)
344  {
345  unsigned old_node_index = old_cell_location_map[(*it).get()];
346 
347  // This shouldn't ever happen, as the cell vector only contains living cells
348  assert(!node_map.IsDeleted(old_node_index));
349 
350  unsigned new_node_index = node_map.GetNewIndex(old_node_index);
351  this->SetCellUsingLocationIndex(new_node_index,*it);
352 
353  if (old_node_radius_map[old_node_index] > 0.0)
354  {
355  this->GetNode(new_node_index)->SetRadius(old_node_radius_map[old_node_index]);
356  }
357  if (output_node_velocities)
358  {
359  this->GetNode(new_node_index)->AddAppliedForceContribution(old_node_applied_force_map[old_node_index]);
360  }
361  }
362 
363  this->Validate();
364  }
365  else
366  {
367  if (old_node_radius_map[this->mCellLocationMap[(*(this->mCells.begin())).get()]] > 0.0)
368  {
369  for (std::list<CellPtr>::iterator it = this->mCells.begin(); it != this->mCells.end(); ++it)
370  {
371  unsigned node_index = this->mCellLocationMap[(*it).get()];
372  this->GetNode(node_index)->SetRadius(old_node_radius_map[node_index]);
373  }
374  }
375  if (output_node_velocities)
376  {
377  for (std::list<CellPtr>::iterator it = this->mCells.begin(); it != this->mCells.end(); ++it)
378  {
379  unsigned node_index = this->mCellLocationMap[(*it).get()];
380  this->GetNode(node_index)->AddAppliedForceContribution(old_node_applied_force_map[node_index]);
381  }
382  }
383  }
384 
385  // Purge any marked springs that are no longer springs
386  std::vector<const std::pair<CellPtr,CellPtr>*> springs_to_remove;
387  for (std::set<std::pair<CellPtr,CellPtr> >::iterator spring_it = this->mMarkedSprings.begin();
388  spring_it != this->mMarkedSprings.end();
389  ++spring_it)
390  {
391  CellPtr p_cell_1 = spring_it->first;
392  CellPtr p_cell_2 = spring_it->second;
393  Node<SPACE_DIM>* p_node_1 = this->GetNodeCorrespondingToCell(p_cell_1);
394  Node<SPACE_DIM>* p_node_2 = this->GetNodeCorrespondingToCell(p_cell_2);
395 
396  bool joined = false;
397 
398  // For each element containing node1, if it also contains node2 then the cells are joined
399  std::set<unsigned> node2_elements = p_node_2->rGetContainingElementIndices();
400  for (typename Node<SPACE_DIM>::ContainingElementIterator elem_iter = p_node_1->ContainingElementsBegin();
401  elem_iter != p_node_1->ContainingElementsEnd();
402  ++elem_iter)
403  {
404  if (node2_elements.find(*elem_iter) != node2_elements.end())
405  {
406  joined = true;
407  break;
408  }
409  }
410 
411  // If no longer joined, remove this spring from the set
412  if (!joined)
413  {
414  springs_to_remove.push_back(&(*spring_it));
415  }
416  }
417 
418  // Remove any springs necessary
419  for (std::vector<const std::pair<CellPtr,CellPtr>* >::iterator spring_it = springs_to_remove.begin();
420  spring_it != springs_to_remove.end();
421  ++spring_it)
422  {
423  this->mMarkedSprings.erase(**spring_it);
424  }
425 
426  // Tessellate if needed
427  TessellateIfNeeded();
428 
430 }
431 
432 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
434 {
435  if ((SPACE_DIM==2 || SPACE_DIM==3)&&(ELEMENT_DIM==SPACE_DIM))
436  {
437  CellBasedEventHandler::BeginEvent(CellBasedEventHandler::TESSELLATION);
438  if (mUseAreaBasedDampingConstant ||
439  this-> template HasWriter<VoronoiDataWriter>() ||
440  this-> template HasWriter<CellPopulationAreaWriter>() ||
441  this-> template HasWriter<CellVolumesWriter>())
442  {
443  CreateVoronoiTessellation();
444  }
445  CellBasedEventHandler::EndEvent(CellBasedEventHandler::TESSELLATION);
446  }
447 }
448 
449 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
451 {
452  // Only implemented for 2D elements
453  assert(ELEMENT_DIM==2);
454 
455  std::vector<c_vector<unsigned, 5> > new_nodes;
456  new_nodes = rGetMesh().SplitLongEdges(springDivisionThreshold);
457 
458  // Add new cells onto new nodes
459  for (unsigned index=0; index<new_nodes.size(); index++)
460  {
461  // Copy the cell attached to one of the neighbouring nodes onto the new node
462  unsigned new_node_index = new_nodes[index][0];
463  unsigned node_a_index = new_nodes[index][1];
464  unsigned node_b_index = new_nodes[index][2];
465 
466  CellPtr p_neighbour_cell = this->GetCellUsingLocationIndex(node_a_index);
467 
468  // Create copy of cell property collection to modify for daughter cell
469  CellPropertyCollection daughter_property_collection = p_neighbour_cell->rGetCellPropertyCollection();
470 
471  // Remove the CellId from the daughter cell a new one will be assigned in the constructor
472  daughter_property_collection.RemoveProperty<CellId>();
473 
474  CellPtr p_new_cell(new Cell(p_neighbour_cell->GetMutationState(),
475  p_neighbour_cell->GetCellCycleModel()->CreateCellCycleModel(),
476  p_neighbour_cell->GetSrnModel()->CreateSrnModel(),
477  false,
478  daughter_property_collection));
479 
480  // Add new cell to cell population
481  this->mCells.push_back(p_new_cell);
482  this->AddCellUsingLocationIndex(new_node_index,p_new_cell);
483 
484  // Update rest lengths
485 
486  // Remove old node pair // note node_a_index < node_b_index
487  std::pair<unsigned,unsigned> node_pair = this->CreateOrderedPair(node_a_index, node_b_index);
488  double old_rest_length = mSpringRestLengths[node_pair];
489 
490  std::map<std::pair<unsigned,unsigned>, double>::iterator iter = mSpringRestLengths.find(node_pair);
491  mSpringRestLengths.erase(iter);
492 
493  // Add new pairs
494  node_pair = this->CreateOrderedPair(node_a_index, new_node_index);
495  mSpringRestLengths[node_pair] = 0.5*old_rest_length;
496 
497  node_pair = this->CreateOrderedPair(node_b_index, new_node_index);
498  mSpringRestLengths[node_pair] = 0.5*old_rest_length;
499 
500  // If necessary add other new spring rest lengths
501  for (unsigned pair_index=3; pair_index<5; pair_index++)
502  {
503  unsigned other_node_index = new_nodes[index][pair_index];
504 
505  if (other_node_index != UNSIGNED_UNSET)
506  {
507  node_pair = this->CreateOrderedPair(other_node_index, new_node_index);
508  double new_rest_length = rGetMesh().GetDistanceBetweenNodes(new_node_index, other_node_index);
509  mSpringRestLengths[node_pair] = new_rest_length;
510  }
511  }
512  }
513 }
514 
515 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
517 {
518  return this->mrMesh.GetNode(index);
519 }
520 
521 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
523 {
524  return this->mrMesh.GetNumAllNodes();
525 }
526 
527 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
529 {
530 }
531 
532 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
533 CellPtr MeshBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>::AddCell(CellPtr pNewCell, const c_vector<double,SPACE_DIM>& rCellDivisionVector, CellPtr pParentCell)
534 {
535  assert(pNewCell);
536  assert(pParentCell);
537 
538  // Add new cell to cell population
539  CellPtr p_created_cell = AbstractCentreBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>::AddCell(pNewCell, rCellDivisionVector, pParentCell);
540  assert(p_created_cell == pNewCell);
541 
542  // Mark spring between parent cell and new cell
543  std::pair<CellPtr,CellPtr> cell_pair = this->CreateCellPair(pParentCell, p_created_cell);
544  this->MarkSpring(cell_pair);
545 
546  // Return pointer to new cell
547  return p_created_cell;
548 }
549 
551 // Output methods //
553 
554 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
556 {
557  if (this->mOutputResultsForChasteVisualizer)
558  {
559  if (!this-> template HasWriter<CellPopulationElementWriter>())
560  {
561  this-> template AddPopulationWriter<CellPopulationElementWriter>();
562  }
563  }
564 
566 }
567 
568 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
570 {
571  if (SimulationTime::Instance()->GetTimeStepsElapsed() == 0 && this->mpVoronoiTessellation == NULL)
572  {
573  TessellateIfNeeded(); // Update isn't run on time-step zero
574  }
575 
577 }
578 
579 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
581 {
582  pPopulationWriter->Visit(this);
583 }
584 
585 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
587 {
588  pPopulationCountWriter->Visit(this);
589 }
590 
591 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
593 {
594  pCellWriter->VisitCell(pCell, this);
595 }
596 
597 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
599 {
600 #ifdef CHASTE_VTK
601  // Store the present time as a string
602  unsigned num_timesteps = SimulationTime::Instance()->GetTimeStepsElapsed();
603  std::stringstream time;
604  time << num_timesteps;
605 
606  // Store the number of cells for which to output data to VTK
607  unsigned num_cells_from_mesh = GetNumNodes();
608  if (!mWriteVtkAsPoints && (mpVoronoiTessellation != NULL))
609  {
610  num_cells_from_mesh = mpVoronoiTessellation->GetNumElements();
611  }
612 
613  // When outputting any CellData, we assume that the first cell is representative of all cells
614  unsigned num_cell_data_items = this->Begin()->GetCellData()->GetNumItems();
615  std::vector<std::string> cell_data_names = this->Begin()->GetCellData()->GetKeys();
616 
617  std::vector<std::vector<double> > cell_data;
618  for (unsigned var=0; var<num_cell_data_items; var++)
619  {
620  std::vector<double> cell_data_var(num_cells_from_mesh);
621  cell_data.push_back(cell_data_var);
622  }
623 
624  if (mOutputMeshInVtk)
625  {
626  // Create mesh writer for VTK output
627  VtkMeshWriter<ELEMENT_DIM, SPACE_DIM> mesh_writer(rDirectory, "mesh_"+time.str(), false);
628  mesh_writer.WriteFilesUsingMesh(rGetMesh());
629  }
630 
631  if (mWriteVtkAsPoints)
632  {
633  // Create mesh writer for VTK output
634  VtkMeshWriter<SPACE_DIM, SPACE_DIM> cells_writer(rDirectory, "results_"+time.str(), false);
635 
636  // Iterate over any cell writers that are present
637  unsigned num_cells = this->GetNumAllCells();
638  for (typename std::vector<boost::shared_ptr<AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator cell_writer_iter = this->mCellWriters.begin();
639  cell_writer_iter != this->mCellWriters.end();
640  ++cell_writer_iter)
641  {
642  // Create vector to store VTK cell data
643  std::vector<double> vtk_cell_data(num_cells);
644 
645  // Loop over cells
646  for (typename AbstractCellPopulation<ELEMENT_DIM,SPACE_DIM>::Iterator cell_iter = this->Begin();
647  cell_iter != this->End();
648  ++cell_iter)
649  {
650  // Get the node index corresponding to this cell
651  unsigned node_index = this->GetLocationIndexUsingCell(*cell_iter);
652 
653  // Populate the vector of VTK cell data
654  vtk_cell_data[node_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(*cell_iter, this);
655  }
656 
657  cells_writer.AddPointData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data);
658  }
659 
660  // Loop over cells
661  for (typename AbstractCellPopulation<ELEMENT_DIM,SPACE_DIM>::Iterator cell_iter = this->Begin();
662  cell_iter != this->End();
663  ++cell_iter)
664  {
665  // Get the node index corresponding to this cell
666  unsigned node_index = this->GetLocationIndexUsingCell(*cell_iter);
667 
668  for (unsigned var=0; var<num_cell_data_items; var++)
669  {
670  cell_data[var][node_index] = cell_iter->GetCellData()->GetItem(cell_data_names[var]);
671  }
672  }
673  for (unsigned var=0; var<num_cell_data_items; var++)
674  {
675  cells_writer.AddPointData(cell_data_names[var], cell_data[var]);
676  }
677 
678  // Make a copy of the nodes in a disposable mesh for writing
679  {
680  std::vector<Node<SPACE_DIM>* > nodes;
681  for (unsigned index=0; index<this->mrMesh.GetNumNodes(); index++)
682  {
683  Node<SPACE_DIM>* p_node = this->mrMesh.GetNode(index);
684  nodes.push_back(p_node);
685  }
686 
688  mesh.ConstructNodesWithoutMesh(nodes, 1.5); // Arbitrary cut off as connectivity not used.
689  cells_writer.WriteFilesUsingMesh(mesh);
690  }
691 
692  *(this->mpVtkMetaFile) << " <DataSet timestep=\"";
693  *(this->mpVtkMetaFile) << num_timesteps;
694  *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_";
695  *(this->mpVtkMetaFile) << num_timesteps;
696  *(this->mpVtkMetaFile) << ".vtu\"/>\n";
697  }
698  else if (mpVoronoiTessellation != NULL)
699  {
700  // Create mesh writer for VTK output
701  VertexMeshWriter<ELEMENT_DIM, SPACE_DIM> mesh_writer(rDirectory, "results", false);
702  std::vector<double> cell_volumes(num_cells_from_mesh);
703 
704  // Iterate over any cell writers that are present
705  unsigned num_cells = this->GetNumAllCells();
706  for (typename std::vector<boost::shared_ptr<AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator cell_writer_iter = this->mCellWriters.begin();
707  cell_writer_iter != this->mCellWriters.end();
708  ++cell_writer_iter)
709  {
710  // Create vector to store VTK cell data
711  std::vector<double> vtk_cell_data(num_cells);
712 
713  // Loop over elements of mpVoronoiTessellation
714  for (typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator elem_iter = mpVoronoiTessellation->GetElementIteratorBegin();
715  elem_iter != mpVoronoiTessellation->GetElementIteratorEnd();
716  ++elem_iter)
717  {
718  // Get index of this element in mpVoronoiTessellation
719  unsigned elem_index = elem_iter->GetIndex();
720 
721  // Get the cell corresponding to this element, via the index of the corresponding node in mrMesh
722  unsigned node_index = mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index);
723  CellPtr p_cell = this->GetCellUsingLocationIndex(node_index);
724 
725  // Populate the vector of VTK cell data
726  vtk_cell_data[elem_index] = (*cell_writer_iter)->GetCellDataForVtkOutput(p_cell, this);
727  }
728 
729  mesh_writer.AddCellData((*cell_writer_iter)->GetVtkCellDataName(), vtk_cell_data);
730  }
731 
732  // Loop over elements of mpVoronoiTessellation
733  for (typename VertexMesh<ELEMENT_DIM, SPACE_DIM>::VertexElementIterator elem_iter = mpVoronoiTessellation->GetElementIteratorBegin();
734  elem_iter != mpVoronoiTessellation->GetElementIteratorEnd();
735  ++elem_iter)
736  {
737  // Get index of this element in mpVoronoiTessellation
738  unsigned elem_index = elem_iter->GetIndex();
739 
740  // Get the cell corresponding to this element, via the index of the corresponding node in mrMesh
741  unsigned node_index = mpVoronoiTessellation->GetDelaunayNodeIndexCorrespondingToVoronoiElementIndex(elem_index);
742  CellPtr p_cell = this->GetCellUsingLocationIndex(node_index);
743 
744  for (unsigned var=0; var<num_cell_data_items; var++)
745  {
746  cell_data[var][elem_index] = p_cell->GetCellData()->GetItem(cell_data_names[var]);
747  }
748  }
749 
750  for (unsigned var=0; var<cell_data.size(); var++)
751  {
752  mesh_writer.AddCellData(cell_data_names[var], cell_data[var]);
753  }
754 
755  mesh_writer.WriteVtkUsingMesh(*mpVoronoiTessellation, time.str());
756  *(this->mpVtkMetaFile) << " <DataSet timestep=\"";
757  *(this->mpVtkMetaFile) << num_timesteps;
758  *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_";
759  *(this->mpVtkMetaFile) << num_timesteps;
760  *(this->mpVtkMetaFile) << ".vtu\"/>\n";
761  }
762 #endif //CHASTE_VTK
763 }
764 
765 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
767 {
768  double cell_volume = 0;
769 
770  if (ELEMENT_DIM == SPACE_DIM)
771  {
772  // Ensure that the Voronoi tessellation exists
773  if (mpVoronoiTessellation == NULL)
774  {
775  CreateVoronoiTessellation();
776  }
777 
778  // Get the node index corresponding to this cell
779  unsigned node_index = this->GetLocationIndexUsingCell(pCell);
780 
781  // Try to get the element index of the Voronoi tessellation corresponding to this node index
782  try
783  {
784  unsigned element_index = mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(node_index);
785 
786  // Get the cell's volume from the Voronoi tessellation
787  cell_volume = mpVoronoiTessellation->GetVolumeOfElement(element_index);
788  }
789  catch (Exception&)
790  {
791  // If it doesn't exist this must be a boundary cell, so return infinite volume
792  cell_volume = DBL_MAX;
793  }
794  }
795  else if (SPACE_DIM==3 && ELEMENT_DIM==2)
796  {
797  unsigned node_index = this->GetLocationIndexUsingCell(pCell);
798 
799  Node<SPACE_DIM>* p_node = rGetMesh().GetNode(node_index);
800 
801  assert(!(p_node->rGetContainingElementIndices().empty()));
802 
803  for (typename Node<SPACE_DIM>::ContainingElementIterator elem_iter = p_node->ContainingElementsBegin();
804  elem_iter != p_node->ContainingElementsEnd();
805  ++elem_iter)
806  {
807  Element<ELEMENT_DIM,SPACE_DIM>* p_element = rGetMesh().GetElement(*elem_iter);
808 
809  c_matrix<double, SPACE_DIM, ELEMENT_DIM> jacob;
810  double det;
811 
812  p_element->CalculateJacobian(jacob, det);
813 
814  cell_volume += fabs(p_element->GetVolume(det));
815  }
816 
817  // This calculation adds a third of each element to the total area
818  cell_volume /= 3.0;
819  }
820  else
821  {
822  // Not implemented for other dimensions
824  }
825 
826  return cell_volume;
827 }
828 
829 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
831 {
832  mWriteVtkAsPoints = writeVtkAsPoints;
833 }
834 
835 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
837 {
838  return mWriteVtkAsPoints;
839 }
840 
841 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
843 {
844  mOutputMeshInVtk = outputMeshInVtk;
845 }
846 
847 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
849 {
850  return mOutputMeshInVtk;
851 }
852 
854 // Spring iterator class //
856 
857 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
859 {
860  return mEdgeIter.GetNodeA();
861 }
862 
863 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
865 {
866  return mEdgeIter.GetNodeB();
867 }
868 
869 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
871 {
872  assert((*this) != mrCellPopulation.SpringsEnd());
873  return mrCellPopulation.GetCellUsingLocationIndex(mEdgeIter.GetNodeA()->GetIndex());
874 }
875 
876 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
878 {
879  assert((*this) != mrCellPopulation.SpringsEnd());
880  return mrCellPopulation.GetCellUsingLocationIndex(mEdgeIter.GetNodeB()->GetIndex());
881 }
882 
883 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
885 {
886  return (mEdgeIter != rOther.mEdgeIter);
887 }
888 
889 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
891 {
892  bool edge_is_ghost = false;
893 
894  do
895  {
896  ++mEdgeIter;
897  if (*this != mrCellPopulation.SpringsEnd())
898  {
899  bool a_is_ghost = mrCellPopulation.IsGhostNode(mEdgeIter.GetNodeA()->GetIndex());
900  bool b_is_ghost = mrCellPopulation.IsGhostNode(mEdgeIter.GetNodeB()->GetIndex());
901 
902  edge_is_ghost = (a_is_ghost || b_is_ghost);
903  }
904  }
905  while (*this!=mrCellPopulation.SpringsEnd() && edge_is_ghost);
906 
907  return (*this);
908 }
909 
910 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
914  : mrCellPopulation(rCellPopulation),
915  mEdgeIter(edgeIter)
916 {
917  if (mEdgeIter!=static_cast<MutableMesh<ELEMENT_DIM,SPACE_DIM>*>(&(this->mrCellPopulation.mrMesh))->EdgesEnd())
918  {
919  bool a_is_ghost = mrCellPopulation.IsGhostNode(mEdgeIter.GetNodeA()->GetIndex());
920  bool b_is_ghost = mrCellPopulation.IsGhostNode(mEdgeIter.GetNodeB()->GetIndex());
921 
922  if (a_is_ghost || b_is_ghost)
923  {
924  ++(*this);
925  }
926  }
927 }
928 
929 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
931 {
932  return SpringIterator(*this, static_cast<MutableMesh<ELEMENT_DIM,SPACE_DIM>&>((this->mrMesh)).EdgesBegin());
933 }
934 
935 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
937 {
938  return SpringIterator(*this, static_cast<MutableMesh<ELEMENT_DIM,SPACE_DIM>&>((this->mrMesh)).EdgesEnd());
939 }
940 
944 template<>
946 {
947  delete mpVoronoiTessellation;
948 
949  // Check if the mesh associated with this cell population is periodic
950  bool is_mesh_periodic = false;
951  if (dynamic_cast<Cylindrical2dMesh*>(&mrMesh))
952  {
953  is_mesh_periodic = true;
954  mpVoronoiTessellation = new Cylindrical2dVertexMesh(static_cast<Cylindrical2dMesh &>(this->mrMesh));
955  }
956  else
957  {
958  mpVoronoiTessellation = new VertexMesh<2, 2>(static_cast<MutableMesh<2, 2> &>((this->mrMesh)), is_mesh_periodic);
959  }
960 }
964 template<>
966 {
967  // We don't allow tessellation yet.
969 }
970 
976 template<>
978 {
979  delete mpVoronoiTessellation;
980  mpVoronoiTessellation = new VertexMesh<3, 3>(static_cast<MutableMesh<3, 3> &>((this->mrMesh)));
981 }
982 
987 template<>
989 {
990  // No 1D Voronoi tessellation
992 }
993 
998 template<>
1000 {
1001  // No 1D Voronoi tessellation
1002  NEVER_REACHED;
1003 }
1004 
1009 template<>
1011 {
1012  // No 1D Voronoi tessellation
1013  NEVER_REACHED;
1014 }
1015 
1016 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1018 {
1019  assert(mpVoronoiTessellation!=NULL);
1020  return mpVoronoiTessellation;
1021 }
1022 
1023 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1025 {
1026  unsigned element_index = mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index);
1027  double volume = mpVoronoiTessellation->GetVolumeOfElement(element_index);
1028  return volume;
1029 }
1030 
1031 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1033 {
1034  unsigned element_index = mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index);
1035  double surface_area = mpVoronoiTessellation->GetSurfaceAreaOfElement(element_index);
1036  return surface_area;
1037 }
1038 
1039 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1041 {
1042  unsigned element_index1 = mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index1);
1043  unsigned element_index2 = mpVoronoiTessellation->GetVoronoiElementIndexCorrespondingToDelaunayNodeIndex(index2);
1044  try
1045  {
1046  double edge_length = mpVoronoiTessellation->GetEdgeLength(element_index1, element_index2);
1047  return edge_length;
1048  }
1049  catch (Exception&)
1050  {
1051  // The edge was between two (potentially infinite) cells on the boundary of the mesh
1052  EXCEPTION("Spring iterator tried to calculate interaction between degenerate cells on the boundary of the mesh. Have you set ghost layers correctly?");
1053  }
1054 }
1055 
1056 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1058 {
1059  bool res = true;
1060  for (std::list<CellPtr>::iterator it=this->mCells.begin();
1061  it!=this->mCells.end();
1062  ++it)
1063  {
1064  CellPtr p_cell = *it;
1065  assert(p_cell);
1066  AbstractCellCycleModel* p_model = p_cell->GetCellCycleModel();
1067  assert(p_model);
1068 
1069  // Check cell exists in cell population
1070  unsigned node_index = this->GetLocationIndexUsingCell(p_cell);
1071  std::cout << "Cell at node " << node_index << " addr " << p_cell << std::endl << std::flush;
1072  CellPtr p_cell_in_cell_population = this->GetCellUsingLocationIndex(node_index);
1073 #define COVERAGE_IGNORE //Debugging code. Shouldn't fail under normal conditions
1074  if (p_cell_in_cell_population != p_cell)
1075  {
1076  std::cout << " Mismatch with cell population" << std::endl << std::flush;
1077  res = false;
1078  }
1079 
1080  // Check model links back to cell
1081  if (p_model->GetCell() != p_cell)
1082  {
1083  std::cout << " Mismatch with cycle model" << std::endl << std::flush;
1084  res = false;
1085  }
1086  }
1087  UNUSED_OPT(res);
1088  assert(res);
1089 #undef COVERAGE_IGNORE
1090 
1091  res = true;
1092  for (std::set<std::pair<CellPtr,CellPtr> >::iterator it1 = this->mMarkedSprings.begin();
1093  it1 != this->mMarkedSprings.end();
1094  ++it1)
1095  {
1096  const std::pair<CellPtr,CellPtr>& r_pair = *it1;
1097 
1098  for (unsigned i=0; i<2; i++)
1099  {
1100  CellPtr p_cell = (i==0 ? r_pair.first : r_pair.second);
1101 
1102  assert(p_cell);
1103  AbstractCellCycleModel* p_model = p_cell->GetCellCycleModel();
1104  assert(p_model);
1105  unsigned node_index = this->GetLocationIndexUsingCell(p_cell);
1106  std::cout << "Cell at node " << node_index << " addr " << p_cell << std::endl << std::flush;
1107 
1108 #define COVERAGE_IGNORE //Debugging code. Shouldn't fail under normal conditions
1109  // Check cell is alive
1110  if (p_cell->IsDead())
1111  {
1112  std::cout << " Cell is dead" << std::endl << std::flush;
1113  res = false;
1114  }
1115 
1116  // Check cell exists in cell population
1117  CellPtr p_cell_in_cell_population = this->GetCellUsingLocationIndex(node_index);
1118  if (p_cell_in_cell_population != p_cell)
1119  {
1120  std::cout << " Mismatch with cell population" << std::endl << std::flush;
1121  res = false;
1122  }
1123 
1124  // Check model links back to cell
1125  if (p_model->GetCell() != p_cell)
1126  {
1127  std::cout << " Mismatch with cycle model" << std::endl << std::flush;
1128  res = false;
1129  }
1130  }
1131 #undef COVERAGE_IGNORE
1132  }
1133  assert(res);
1134 }
1135 
1136 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1138 {
1140 }
1141 
1142 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1144 {
1145  assert(areaBasedDampingConstantParameter >= 0.0);
1146  mAreaBasedDampingConstantParameter = areaBasedDampingConstantParameter;
1147 }
1148 
1149 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1151 {
1152  //mNodePairs.Clear();
1153  NEVER_REACHED;
1154  return mNodePairs;
1155 }
1156 
1157 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1159 {
1160  *rParamsFile << "\t\t<UseAreaBasedDampingConstant>" << mUseAreaBasedDampingConstant << "</UseAreaBasedDampingConstant>\n";
1161  *rParamsFile << "\t\t<AreaBasedDampingConstantParameter>" << mAreaBasedDampingConstantParameter << "</AreaBasedDampingConstantParameter>\n";
1162  *rParamsFile << "\t\t<WriteVtkAsPoints>" << mWriteVtkAsPoints << "</WriteVtkAsPoints>\n";
1163  *rParamsFile << "\t\t<OutputMeshInVtk>" << mOutputMeshInVtk << "</OutputMeshInVtk>\n";
1164  *rParamsFile << "\t\t<HasVariableRestLength>" << mHasVariableRestLength << "</HasVariableRestLength>\n";
1165 
1166  // Call method on direct parent class
1168 }
1169 
1170 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1172 {
1173  // Call GetWidth() on the mesh
1174  double width = this->mrMesh.GetWidth(rDimension);
1175  return width;
1176 }
1177 
1178 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1180 {
1181  // Get pointer to this node
1182  Node<SPACE_DIM>* p_node = this->mrMesh.GetNode(index);
1183 
1184  // Loop over containing elements
1185  std::set<unsigned> neighbouring_node_indices;
1186  for (typename Node<SPACE_DIM>::ContainingElementIterator elem_iter = p_node->ContainingElementsBegin();
1187  elem_iter != p_node->ContainingElementsEnd();
1188  ++elem_iter)
1189  {
1190  // Get pointer to this containing element
1191  Element<ELEMENT_DIM,SPACE_DIM>* p_element = static_cast<MutableMesh<ELEMENT_DIM,SPACE_DIM>&>((this->mrMesh)).GetElement(*elem_iter);
1192 
1193  // Loop over nodes contained in this element
1194  for (unsigned i=0; i<p_element->GetNumNodes(); i++)
1195  {
1196  // Get index of this node and add its index to the set if not the original node
1197  unsigned node_index = p_element->GetNodeGlobalIndex(i);
1198  if (node_index != index)
1199  {
1200  neighbouring_node_indices.insert(node_index);
1201  }
1202  }
1203  }
1204  return neighbouring_node_indices;
1205 }
1206 
1207 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1209 {
1210  mSpringRestLengths.clear();
1211 
1212  // Iterate over all springs and add calculate separation of adjacent node pairs
1213  for (SpringIterator spring_iterator = SpringsBegin();
1214  spring_iterator != SpringsEnd();
1215  ++spring_iterator)
1216  {
1217  // Note that nodeA_global_index is always less than nodeB_global_index
1218  Node<SPACE_DIM>* p_nodeA = spring_iterator.GetNodeA();
1219  Node<SPACE_DIM>* p_nodeB = spring_iterator.GetNodeB();
1220 
1221  unsigned nodeA_global_index = p_nodeA->GetIndex();
1222  unsigned nodeB_global_index = p_nodeB->GetIndex();
1223 
1224  // Calculate the distance between nodes
1225  double separation = rGetMesh().GetDistanceBetweenNodes(nodeA_global_index, nodeB_global_index);
1226 
1227  // Order node indices
1228  std::pair<unsigned,unsigned> node_pair = this->CreateOrderedPair(nodeA_global_index, nodeB_global_index);
1229 
1230  mSpringRestLengths[node_pair] = separation;
1231  }
1232  mHasVariableRestLength = true;
1233 }
1234 
1235 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1237 {
1239  {
1240  std::pair<unsigned,unsigned> node_pair = this->CreateOrderedPair(indexA, indexB);
1241  std::map<std::pair<unsigned,unsigned>, double>::const_iterator iter = mSpringRestLengths.find(node_pair);
1242 
1243  if (iter != mSpringRestLengths.end())
1244  {
1245  // Return the stored rest length
1246  return iter->second;
1247  }
1248  else
1249  {
1250  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.");
1251  }
1252  }
1253  else
1254  {
1255  return 1.0;
1256  }
1257 }
1258 
1259 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
1260 void MeshBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>::SetRestLength(unsigned indexA, unsigned indexB, double restLength)
1261 {
1263  {
1264  std::pair<unsigned,unsigned> node_pair = this->CreateOrderedPair(indexA, indexB);
1265  std::map<std::pair<unsigned,unsigned>, double>::iterator iter = mSpringRestLengths.find(node_pair);
1266 
1267  if (iter != mSpringRestLengths.end())
1268  {
1269  // modify the stored rest length
1270  iter->second = restLength;
1271  }
1272  else
1273  {
1274  EXCEPTION("Tried to set the rest length of an edge not in the mesh.");
1275  }
1276  }
1277  else
1278  {
1279  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.");
1280  }
1281 }
1282 
1283 // Explicit instantiation
1284 template class MeshBasedCellPopulation<1,1>;
1285 template class MeshBasedCellPopulation<1,2>;
1286 template class MeshBasedCellPopulation<2,2>;
1287 template class MeshBasedCellPopulation<1,3>;
1288 template class MeshBasedCellPopulation<2,3>;
1289 template class MeshBasedCellPopulation<3,3>;
1290 
1291 // Serialization for Boost >= 1.36
double GetSurfaceAreaOfVoronoiElement(unsigned index)
double GetVolumeOfVoronoiElement(unsigned index)
void AddCellData(std::string dataName, std::vector< double > dataPayload)
double GetWidth(const unsigned &rDimension)
double GetVoronoiEdgeLength(unsigned index1, unsigned index2)
Definition: Cell.hpp:77
unsigned AddNode(Node< SPACE_DIM > *pNewNode)
virtual CellPtr AddCell(CellPtr pNewCell, const c_vector< double, SPACE_DIM > &rCellDivisionVector, CellPtr pParentCell)
virtual CellPtr GetCellUsingLocationIndex(unsigned index)
Definition: Node.hpp:58
unsigned GetLocationIndexUsingCell(CellPtr pCell)
double GetVolume(double determinant) const
double GetDampingConstant(unsigned nodeIndex)
unsigned GetNodeGlobalIndex(unsigned localIndex) const
void DeleteNodePriorToReMesh(unsigned index)
virtual void AcceptCellWriter(boost::shared_ptr< AbstractCellWriter< ELEMENT_DIM, SPACE_DIM > > pCellWriter, CellPtr pCell)
std::vector< std::pair< Node< SPACE_DIM > *, Node< SPACE_DIM > * > > & rGetNodePairs()
#define EXCEPTION(message)
Definition: Exception.hpp:143
virtual void AcceptPopulationCountWriter(boost::shared_ptr< AbstractCellPopulationCountWriter< ELEMENT_DIM, SPACE_DIM > > pPopulationCountWriter)
static SimulationTime * Instance()
void SetNode(unsigned nodeIndex, ChastePoint< SPACE_DIM > &rNewLocation)
Element< ELEMENT_DIM, SPACE_DIM > * GetElement(unsigned index) const
std::set< unsigned > & rGetContainingElementIndices()
Definition: Node.cpp:301
virtual void WriteVtkResultsToFile(const std::string &rDirectory)
unsigned GetTimeStepsElapsed() const
#define NEVER_REACHED
Definition: Exception.hpp:206
virtual void WriteResultsToFiles(const std::string &rDirectory)
virtual void SetNode(unsigned index, ChastePoint< SPACE_DIM > point, bool concreteMove=true)
MutableMesh< ELEMENT_DIM, SPACE_DIM > & rGetMesh()
bool operator!=(const typename MeshBasedCellPopulation< ELEMENT_DIM, SPACE_DIM >::SpringIterator &rOther)
virtual void OutputCellPopulationParameters(out_stream &rParamsFile)
void WriteFilesUsingMesh(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, bool keepOriginalElementIndexing=true)
double GetRestLength(unsigned indexA, unsigned indexB)
void SetWriteVtkAsPoints(bool writeVtkAsPoints)
std::pair< unsigned, unsigned > CreateOrderedPair(unsigned index1, unsigned index2)
MutableMesh< ELEMENT_DIM, SPACE_DIM >::EdgeIterator mEdgeIter
ContainingElementIterator ContainingElementsBegin() const
Definition: Node.hpp:444
MutableMesh< ELEMENT_DIM, SPACE_DIM > * mpMutableMesh
void SetOutputMeshInVtk(bool outputMeshInVtk)
void DivideLongSprings(double springDivisionThreshold)
virtual void AcceptPopulationWriter(boost::shared_ptr< AbstractCellPopulationWriter< ELEMENT_DIM, SPACE_DIM > > pPopulationWriter)
VertexMesh< ELEMENT_DIM, SPACE_DIM > * mpVoronoiTessellation
unsigned GetNumNodes() const
SpringIterator(MeshBasedCellPopulation< ELEMENT_DIM, SPACE_DIM > &rCellPopulation, typename MutableMesh< ELEMENT_DIM, SPACE_DIM >::EdgeIterator edgeIter)
virtual void Update(bool hasHadBirthsOrDeaths=true)
const unsigned UNSIGNED_UNSET
Definition: Exception.hpp:52
void WriteVtkUsingMesh(VertexMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, std::string stamp="")
virtual void ReMesh(NodeMap &map)
#define EXPORT_TEMPLATE_CLASS_ALL_DIMS(CLASS)
virtual void UpdateGhostNodesAfterReMesh(NodeMap &rMap)
void SetRestLength(unsigned indexA, unsigned indexB, double restLength)
void SetAreaBasedDampingConstant(bool useAreaBasedDampingConstant)
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
virtual void WriteResultsToFiles(const std::string &rDirectory)
void ConstructNodesWithoutMesh(const std::vector< Node< SPACE_DIM > * > &rNodes, double maxInteractionDistance)
std::set< unsigned > GetNeighbouringNodeIndices(unsigned index)
void SetMeshHasChangedSinceLoading()
void CalculateJacobian(c_matrix< double, SPACE_DIM, ELEMENT_DIM > &rJacobian, double &rJacobianDeterminant)
Node< SPACE_DIM > * GetNode(unsigned index)
#define UNUSED_OPT(var)
Definition: Exception.hpp:216
VertexMesh< ELEMENT_DIM, SPACE_DIM > * GetVoronoiTessellation()
CellPtr AddCell(CellPtr pNewCell, const c_vector< double, SPACE_DIM > &rCellDivisionVector, CellPtr pParentCell=CellPtr())
MeshBasedCellPopulation(MutableMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, std::vector< CellPtr > &rCells, const std::vector< unsigned > locationIndices=std::vector< unsigned >(), bool deleteMesh=false, bool validate=true)
unsigned GetIndex() const
Definition: Node.cpp:159
double GetVolumeOfCell(CellPtr pCell)
void OutputCellPopulationParameters(out_stream &rParamsFile)
std::vector< std::pair< Node< SPACE_DIM > *, Node< SPACE_DIM > * > > mNodePairs
EdgeIterator EdgesEnd()
void SetAreaBasedDampingConstantParameter(double areaBasedDampingConstantParameter)
AbstractMesh< ELEMENT_DIM, SPACE_DIM > & mrMesh
virtual double GetDampingConstant(unsigned nodeIndex)
std::map< std::pair< unsigned, unsigned >, double > mSpringRestLengths
ContainingElementIterator ContainingElementsEnd() const
Definition: Node.hpp:452
std::set< std::pair< CellPtr, CellPtr > > mMarkedSprings
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
MeshBasedCellPopulation< ELEMENT_DIM, SPACE_DIM > & mrCellPopulation