Chaste  Release::3.4
AbstractCentreBasedCellPopulation.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 "AbstractCentreBasedCellPopulation.hpp"
37 
38 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
40  std::vector<CellPtr>& rCells,
41  const std::vector<unsigned> locationIndices)
42  : AbstractOffLatticeCellPopulation<ELEMENT_DIM, SPACE_DIM>(rMesh, rCells, locationIndices),
43  mMeinekeDivisionSeparation(0.3) // educated guess
44 {
45  // If no location indices are specified, associate with nodes from the mesh.
46  std::list<CellPtr>::iterator it = this->mCells.begin();
48 
49  for (unsigned i=0; it != this->mCells.end(); ++it, ++i, ++node_iter)
50  {
51  unsigned index = locationIndices.empty() ? node_iter->GetIndex() : locationIndices[i]; // assume that the ordering matches
53  }
54 }
55 
56 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
58  : AbstractOffLatticeCellPopulation<ELEMENT_DIM, SPACE_DIM>(rMesh),
59  mMeinekeDivisionSeparation(0.3) // educated guess
60 
61 {
62 }
63 
64 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
66 {
67  return GetNodeCorrespondingToCell(pCell)->rGetLocation();
68 }
69 
70 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
72 {
73  unsigned index = this->GetLocationIndexUsingCell(pCell);
74  return this->GetNode(index);
75 }
76 
77 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
78 CellPtr AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::AddCell(CellPtr pNewCell, const c_vector<double,SPACE_DIM>& rCellDivisionVector, CellPtr pParentCell)
79 {
80  // Create a new node
81  Node<SPACE_DIM>* p_new_node = new Node<SPACE_DIM>(this->GetNumNodes(), rCellDivisionVector, false); // never on boundary
82  unsigned new_node_index = this->AddNode(p_new_node); // use copy constructor so it doesn't matter that new_node goes out of scope
83 
84  // Update cells vector
85  this->mCells.push_back(pNewCell);
86 
87  // Update mappings between cells and location indices
88  this->SetCellUsingLocationIndex(new_node_index, pNewCell);
89  this->mCellLocationMap[pNewCell.get()] = new_node_index;
90 
91  return pNewCell;
92 }
93 
94 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
95 std::pair<CellPtr,CellPtr> AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::CreateCellPair(CellPtr pCell1, CellPtr pCell2)
96 {
97  assert(pCell1);
98  assert(pCell2);
99 
100  std::pair<CellPtr,CellPtr> cell_pair;
101 
102  if (pCell1->GetCellId() < pCell2->GetCellId())
103  {
104  cell_pair.first = pCell1;
105  cell_pair.second = pCell2;
106  }
107  else
108  {
109  cell_pair.first = pCell2;
110  cell_pair.second = pCell1;
111  }
112  return cell_pair;
113 }
114 
115 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
116 bool AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::IsMarkedSpring(const std::pair<CellPtr,CellPtr>& rCellPair)
117 {
118  // the pair should be ordered like this (CreateCellPair will ensure this)
119  assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
120 
121  return mMarkedSprings.find(rCellPair) != mMarkedSprings.end();
122 }
123 
124 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
126 {
127  // the pair should be ordered like this (CreateCellPair will ensure this)
128  assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
129 
130  mMarkedSprings.insert(rCellPair);
131 }
132 
133 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
135 {
136  // the pair should be ordered like this (CreateCellPair will ensure this)
137  assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
138 
139  mMarkedSprings.erase(rCellPair);
140 }
141 
142 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
144 {
145  return GetNodeCorrespondingToCell(pCell)->IsDeleted();
146 }
147 
148 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
150 {
151  unsigned node_index = this->GetLocationIndexUsingCell(pCell);
152  return this->GetNeighbouringNodeIndices(node_index);
153 }
154 
155 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
157 {
158  // Iterate over all nodes associated with real cells to update their positions
159  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
160  cell_iter != this->End();
161  ++cell_iter)
162  {
163  // Get index of node associated with cell
164  unsigned node_index = this->GetLocationIndexUsingCell((*cell_iter));
165 
166  // Get damping constant for node
167  double damping_const = this->GetDampingConstant(node_index);
168 
169  // Get displacement
170  c_vector<double,SPACE_DIM> displacement=dt*this->GetNode(node_index)->rGetAppliedForce()/damping_const;
171 
172  // Throws an exception if the cell movement goes beyond mAbsoluteMovementThreshold
173  if (norm_2(displacement) > this->mAbsoluteMovementThreshold)
174  {
175  EXCEPTION("Cells are moving by: " << norm_2(displacement) <<
176  ", which is more than the AbsoluteMovementThreshold: "
177  << this->mAbsoluteMovementThreshold <<
178  ". Use a smaller timestep to avoid this exception.");
179  }
180 
181  // Get new node location
182  c_vector<double, SPACE_DIM> new_node_location = this->GetNode(node_index)->rGetLocation() + displacement;
183 
184  // Create ChastePoint for new node location
185  ChastePoint<SPACE_DIM> new_point(new_node_location);
186 
187  // Move the node
188  this->SetNode(node_index, new_point);
189  }
190 }
191 
192 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
194 {
195  CellPtr p_cell = this->GetCellUsingLocationIndex(nodeIndex);
196  if (p_cell->GetMutationState()->IsType<WildTypeCellMutationState>() && !p_cell->HasCellProperty<CellLabel>())
197  {
198  return this->GetDampingConstantNormal();
199  }
200  else
201  {
202  return this->GetDampingConstantMutant();
203  }
204 }
205 
206 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
208 {
209  return false;
210 }
211 
212 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
214 {
215  return false;
216 }
217 
218 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
220 {
221  return mMeinekeDivisionSeparation;
222 }
223 
224 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
226 {
227  assert(divisionSeparation <= 1.0);
228  assert(divisionSeparation >= 0.0);
229  mMeinekeDivisionSeparation = divisionSeparation;
230 }
231 
232 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
234 {
235  for (typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator node_iter = this->rGetMesh().GetNodeIteratorBegin();
236  node_iter != this->rGetMesh().GetNodeIteratorEnd();
237  ++node_iter)
238  {
239  for (typename std::vector<boost::shared_ptr<AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator cell_writer_iter = this->mCellWriters.begin();
240  cell_writer_iter != this->mCellWriters.end();
241  ++cell_writer_iter)
242  {
243  CellPtr cell_from_node = this->GetCellUsingLocationIndex(node_iter->GetIndex());
244  this->AcceptCellWriter(*cell_writer_iter, cell_from_node);
245  }
246  }
247 }
248 
249 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
251 {
252  *rParamsFile << "\t\t<MeinekeDivisionSeparation>" << mMeinekeDivisionSeparation << "</MeinekeDivisionSeparation>\n";
253 
254  // Call method on direct parent class
256 }
257 
259 // Explicit instantiation
261 
void UnmarkSpring(std::pair< CellPtr, CellPtr > &rCellPair)
Definition: Node.hpp:58
#define EXCEPTION(message)
Definition: Exception.hpp:143
std::pair< CellPtr, CellPtr > CreateCellPair(CellPtr pCell1, CellPtr pCell2)
virtual void OutputCellPopulationParameters(out_stream &rParamsFile)
virtual std::set< unsigned > GetNeighbouringLocationIndices(CellPtr pCell)
AbstractCentreBasedCellPopulation(AbstractMesh< ELEMENT_DIM, SPACE_DIM > &rMesh)
Node< SPACE_DIM > * GetNodeCorrespondingToCell(CellPtr pCell)
NodeIterator GetNodeIteratorBegin(bool skipDeletedNodes=true)
void MarkSpring(std::pair< CellPtr, CellPtr > &rCellPair)
virtual void OutputCellPopulationParameters(out_stream &rParamsFile)
bool IsMarkedSpring(const std::pair< CellPtr, CellPtr > &rCellPair)
CellPtr AddCell(CellPtr pNewCell, const c_vector< double, SPACE_DIM > &rCellDivisionVector, CellPtr pParentCell=CellPtr())
virtual void AddCellUsingLocationIndex(unsigned index, CellPtr pCell)
void SetMeinekeDivisionSeparation(double divisionSeparation)
virtual double GetDampingConstant(unsigned nodeIndex)
c_vector< double, SPACE_DIM > GetLocationOfCellCentre(CellPtr pCell)