Chaste Commit::9e4a273f0754a391514ab12ed9d4a38fc9933db2
AbstractCentreBasedCellPopulation.cpp
1/*
2
3Copyright (c) 2005-2026, University of Oxford.
4All rights reserved.
5
6University of Oxford means the Chancellor, Masters and Scholars of the
7University of Oxford, having an administrative office at Wellington
8Square, Oxford OX1 2JD, UK.
9
10This file is part of Chaste.
11
12Redistribution and use in source and binary forms, with or without
13modification, 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
23THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33
34*/
35
36#include "AbstractCentreBasedCellPopulation.hpp"
37
38#include "RandomDirectionCentreBasedDivisionRule.hpp"
39#include "RandomNumberGenerator.hpp"
40#include "StepSizeException.hpp"
41#include "WildTypeCellMutationState.hpp"
42
43template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
45 std::vector<CellPtr>& rCells,
46 const std::vector<unsigned> locationIndices)
47 : AbstractOffLatticeCellPopulation<ELEMENT_DIM, SPACE_DIM>(rMesh, rCells, locationIndices),
48 mMeinekeDivisionSeparation(0.3) // educated guess
49{
50 // If no location indices are specified, associate with nodes from the mesh.
51 std::list<CellPtr>::iterator it = this->mCells.begin();
53
54 for (unsigned i = 0; it != this->mCells.end(); ++it, ++i, ++node_iter)
55 {
56 unsigned index = locationIndices.empty() ? node_iter->GetIndex() : locationIndices[i]; // assume that the ordering matches
58 }
59
61}
62
63template <unsigned ELEMENT_DIM, unsigned SPACE_DIM>
65 : AbstractOffLatticeCellPopulation<ELEMENT_DIM, SPACE_DIM>(rMesh),
66 mMeinekeDivisionSeparation(0.3) // educated guess
67{
68}
69
70template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
72{
73 return GetNodeCorrespondingToCell(pCell)->rGetLocation();
74}
75
76template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
78{
79 unsigned index = this->GetLocationIndexUsingCell(pCell);
80 return this->GetNode(index);
81}
82
83template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
85 unsigned pdeNodeIndex,
86 std::string& rVariableName,
87 bool dirichletBoundaryConditionApplies,
88 double dirichletBoundaryValue)
89{
90 CellPtr p_cell = this->GetCellUsingLocationIndex(pdeNodeIndex);
91 double value = p_cell->GetCellData()->GetItem(rVariableName);
92
93 return value;
94}
95
96template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
97CellPtr AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::AddCell(CellPtr pNewCell, CellPtr pParentCell)
98{
99 // Calculate the locations of the two daughter cells
100 std::pair<c_vector<double, SPACE_DIM>, c_vector<double, SPACE_DIM> > positions = mpCentreBasedDivisionRule->CalculateCellDivisionVector(pParentCell, *this);
101
102 c_vector<double, SPACE_DIM> parent_position = positions.first;
103 c_vector<double, SPACE_DIM> daughter_position = positions.second;
104
105 // Set the parent cell to use this location
106 ChastePoint<SPACE_DIM> parent_point(parent_position);
107 unsigned node_index = this->GetLocationIndexUsingCell(pParentCell);
108 this->SetNode(node_index, parent_point);
109
110 // Create a new node
111 Node<SPACE_DIM>* p_new_node = new Node<SPACE_DIM>(this->GetNumNodes(), daughter_position, false); // never on boundary
112
113 // Clear the applied force on the new node, in case velocity is ouptut on the same timestep as this cell's division
114 p_new_node->ClearAppliedForce();
115
116 // Copy any node attributes from the parent node
117 if (this->GetNode(node_index)->HasNodeAttributes())
118 {
119 p_new_node->rGetNodeAttributes() = this->GetNode(node_index)->rGetNodeAttributes();
120 }
121
122 unsigned new_node_index = this->AddNode(p_new_node); // use copy constructor so it doesn't matter that new_node goes out of scope
123
124 // Update cells vector
125 this->mCells.push_back(pNewCell);
126
127 // Update mappings between cells and location indices
128 this->SetCellUsingLocationIndex(new_node_index, pNewCell);
129 this->mCellLocationMap[pNewCell.get()] = new_node_index;
130
131 return pNewCell;
132}
134template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
135std::pair<CellPtr,CellPtr> AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::CreateCellPair(CellPtr pCell1, CellPtr pCell2)
136{
137 assert(pCell1);
138 assert(pCell2);
139
140 std::pair<CellPtr,CellPtr> cell_pair;
141
142 if (pCell1->GetCellId() < pCell2->GetCellId())
143 {
144 cell_pair.first = pCell1;
145 cell_pair.second = pCell2;
146 }
147 else
148 {
149 cell_pair.first = pCell2;
150 cell_pair.second = pCell1;
151 }
152 return cell_pair;
153}
155template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
157{
158 // the pair should be ordered like this (CreateCellPair will ensure this)
159 assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
160
161 return mMarkedSprings.find(rCellPair) != mMarkedSprings.end();
162}
163
164template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
166{
167 // the pair should be ordered like this (CreateCellPair will ensure this)
168 assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
169
170 mMarkedSprings.insert(rCellPair);
172
173template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
175{
176 // the pair should be ordered like this (CreateCellPair will ensure this)
177 assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
178
179 mMarkedSprings.erase(rCellPair);
180}
181
182template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
185 return GetNodeCorrespondingToCell(pCell)->IsDeleted();
186}
187
188template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
190{
191 unsigned node_index = this->GetLocationIndexUsingCell(pCell);
192 return this->GetNeighbouringNodeIndices(node_index);
193}
194
195template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
196void AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::CheckForStepSizeException(unsigned nodeIndex, c_vector<double,SPACE_DIM>& rDisplacement, double dt)
197{
198 if ((!this->IsGhostNode(nodeIndex)) && (!this->IsParticle(nodeIndex)))
199 {
200 // Call method on parent class
203}
204
205template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
207{
208 if (this->IsGhostNode(nodeIndex) || this->IsParticle(nodeIndex))
210 return this->GetDampingConstantNormal();
211 }
212 else
213 {
214 CellPtr p_cell = this->GetCellUsingLocationIndex(nodeIndex);
215 if (p_cell->GetMutationState()->IsType<WildTypeCellMutationState>())
217 return this->GetDampingConstantNormal();
218 }
219 else
220 {
221 return this->GetDampingConstantMutant();
222 }
223 }
224}
226template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
228{
229 return false;
230}
231
232template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
234{
235 return false;
236}
237
238template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
243
244template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
247 assert(divisionSeparation <= 1.0);
248 assert(divisionSeparation >= 0.0);
249 mMeinekeDivisionSeparation = divisionSeparation;
250}
251
252template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
254{
255 for (typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator node_iter = this->rGetMesh().GetNodeIteratorBegin();
256 node_iter != this->rGetMesh().GetNodeIteratorEnd();
257 ++node_iter)
258 {
259 for (typename std::vector<boost::shared_ptr<AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator cell_writer_iter = this->mCellWriters.begin();
260 cell_writer_iter != this->mCellWriters.end();
261 ++cell_writer_iter)
262 {
263 CellPtr cell_from_node = this->GetCellUsingLocationIndex(node_iter->GetIndex());
264 this->AcceptCellWriter(*cell_writer_iter, cell_from_node);
265 }
266 }
267}
268
269template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
270boost::shared_ptr<AbstractCentreBasedDivisionRule<ELEMENT_DIM, SPACE_DIM> > AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCentreBasedDivisionRule()
271{
272 return mpCentreBasedDivisionRule;
273}
275template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
277{
278 mpCentreBasedDivisionRule = pCentreBasedDivisionRule;
279}
280
281template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
283{
284 *rParamsFile << "\t\t<MeinekeDivisionSeparation>" << mMeinekeDivisionSeparation << "</MeinekeDivisionSeparation>\n";
285
286 // Add the division rule parameters
287 *rParamsFile << "\t\t<CentreBasedDivisionRule>\n";
288 mpCentreBasedDivisionRule->OutputCellCentreBasedDivisionRuleInfo(rParamsFile);
289 *rParamsFile << "\t\t</CentreBasedDivisionRule>\n";
290
291 // Call method on direct parent class
293}
294
295template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
300
virtual void AddCellUsingLocationIndex(unsigned index, CellPtr pCell)
void MarkSpring(std::pair< CellPtr, CellPtr > &rCellPair)
void UnmarkSpring(std::pair< CellPtr, CellPtr > &rCellPair)
virtual void OutputCellPopulationParameters(out_stream &rParamsFile)
AbstractCentreBasedCellPopulation(AbstractMesh< ELEMENT_DIM, SPACE_DIM > &rMesh)
virtual void CheckForStepSizeException(unsigned nodeIndex, c_vector< double, SPACE_DIM > &rDisplacement, double dt)
std::pair< CellPtr, CellPtr > CreateCellPair(CellPtr pCell1, CellPtr pCell2)
void SetCentreBasedDivisionRule(boost::shared_ptr< AbstractCentreBasedDivisionRule< ELEMENT_DIM, SPACE_DIM > > pCentreBasedDivisionRule)
void SetMeinekeDivisionSeparation(double divisionSeparation)
virtual double GetDampingConstant(unsigned nodeIndex)
bool IsMarkedSpring(const std::pair< CellPtr, CellPtr > &rCellPair)
boost::shared_ptr< AbstractCentreBasedDivisionRule< ELEMENT_DIM, SPACE_DIM > > mpCentreBasedDivisionRule
c_vector< double, SPACE_DIM > GetLocationOfCellCentre(CellPtr pCell)
virtual double GetCellDataItemAtPdeNode(unsigned pdeNodeIndex, std::string &rVariableName, bool dirichletBoundaryConditionApplies=false, double dirichletBoundaryValue=0.0)
virtual std::set< unsigned > GetNeighbouringLocationIndices(CellPtr pCell)
Node< SPACE_DIM > * GetNodeCorrespondingToCell(CellPtr pCell)
CellPtr AddCell(CellPtr pNewCell, CellPtr pParentCell=CellPtr())
boost::shared_ptr< AbstractCentreBasedDivisionRule< ELEMENT_DIM, SPACE_DIM > > GetCentreBasedDivisionRule()
NodeIterator GetNodeIteratorBegin(bool skipDeletedNodes=true)
virtual void CheckForStepSizeException(unsigned nodeIndex, c_vector< double, SPACE_DIM > &rDisplacement, double dt)
virtual void OutputCellPopulationParameters(out_stream &rParamsFile)
Definition Node.hpp:59
void ClearAppliedForce()
Definition Node.cpp:216
std::vector< double > & rGetNodeAttributes()
Definition Node.cpp:178