AbstractCentreBasedCellPopulation.cpp

00001 /*
00002 
00003 Copyright (c) 2005-2015, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #include "AbstractCentreBasedCellPopulation.hpp"
00037 
00038 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00039 AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::AbstractCentreBasedCellPopulation( AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00040                                                                     std::vector<CellPtr>& rCells,
00041                                                                   const std::vector<unsigned> locationIndices)
00042     : AbstractOffLatticeCellPopulation<ELEMENT_DIM, SPACE_DIM>(rMesh, rCells, locationIndices),
00043       mMeinekeDivisionSeparation(0.3) // educated guess
00044 {
00045     // If no location indices are specified, associate with nodes from the mesh.
00046     std::list<CellPtr>::iterator it = this->mCells.begin();
00047     typename AbstractMesh<ELEMENT_DIM, SPACE_DIM>::NodeIterator node_iter = rMesh.GetNodeIteratorBegin();
00048 
00049     for (unsigned i=0; it != this->mCells.end(); ++it, ++i, ++node_iter)
00050     {
00051         unsigned index = locationIndices.empty() ? node_iter->GetIndex() : locationIndices[i]; // assume that the ordering matches
00052         AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::AddCellUsingLocationIndex(index,*it);
00053     }
00054 }
00055 
00056 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00057 AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::AbstractCentreBasedCellPopulation(AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh)
00058     : AbstractOffLatticeCellPopulation<ELEMENT_DIM, SPACE_DIM>(rMesh),
00059       mMeinekeDivisionSeparation(0.3) // educated guess
00060 
00061 {
00062 }
00063 
00064 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00065 c_vector<double, SPACE_DIM> AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetLocationOfCellCentre(CellPtr pCell)
00066 {
00067     return GetNodeCorrespondingToCell(pCell)->rGetLocation();
00068 }
00069 
00070 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00071 Node<SPACE_DIM>* AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetNodeCorrespondingToCell(CellPtr pCell)
00072 {
00073     unsigned index = this->GetLocationIndexUsingCell(pCell);
00074     return this->GetNode(index);
00075 }
00076 
00077 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00078 CellPtr AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::AddCell(CellPtr pNewCell, const c_vector<double,SPACE_DIM>& rCellDivisionVector, CellPtr pParentCell)
00079 {
00080     // Create a new node
00081     Node<SPACE_DIM>* p_new_node = new Node<SPACE_DIM>(this->GetNumNodes(), rCellDivisionVector, false);   // never on boundary
00082     unsigned new_node_index = this->AddNode(p_new_node); // use copy constructor so it doesn't matter that new_node goes out of scope
00083 
00084     // Update cells vector
00085     this->mCells.push_back(pNewCell);
00086 
00087     // Update mappings between cells and location indices
00088     this->SetCellUsingLocationIndex(new_node_index, pNewCell);
00089     this->mCellLocationMap[pNewCell.get()] = new_node_index;
00090 
00091     return pNewCell;
00092 }
00093 
00094 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00095 std::pair<CellPtr,CellPtr> AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::CreateCellPair(CellPtr pCell1, CellPtr pCell2)
00096 {
00097     assert(pCell1);
00098     assert(pCell2);
00099 
00100     std::pair<CellPtr,CellPtr> cell_pair;
00101 
00102     if (pCell1->GetCellId() < pCell2->GetCellId())
00103     {
00104         cell_pair.first = pCell1;
00105         cell_pair.second = pCell2;
00106     }
00107     else
00108     {
00109         cell_pair.first = pCell2;
00110         cell_pair.second = pCell1;
00111     }
00112     return cell_pair;
00113 }
00114 
00115 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00116 bool AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::IsMarkedSpring(const std::pair<CellPtr,CellPtr>& rCellPair)
00117 {
00118     // the pair should be ordered like this (CreateCellPair will ensure this)
00119     assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
00120 
00121     return mMarkedSprings.find(rCellPair) != mMarkedSprings.end();
00122 }
00123 
00124 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00125 void AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::MarkSpring(std::pair<CellPtr,CellPtr>& rCellPair)
00126 {
00127     // the pair should be ordered like this (CreateCellPair will ensure this)
00128     assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
00129 
00130     mMarkedSprings.insert(rCellPair);
00131 }
00132 
00133 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00134 void AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::UnmarkSpring(std::pair<CellPtr,CellPtr>& rCellPair)
00135 {
00136     // the pair should be ordered like this (CreateCellPair will ensure this)
00137     assert(rCellPair.first->GetCellId() < rCellPair.second->GetCellId());
00138 
00139     mMarkedSprings.erase(rCellPair);
00140 }
00141 
00142 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00143 bool AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::IsCellAssociatedWithADeletedLocation(CellPtr pCell)
00144 {
00145     return GetNodeCorrespondingToCell(pCell)->IsDeleted();
00146 }
00147 
00148 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00149 std::set<unsigned> AbstractCentreBasedCellPopulation<ELEMENT_DIM,SPACE_DIM>::GetNeighbouringLocationIndices(CellPtr pCell)
00150 {
00151     unsigned node_index = this->GetLocationIndexUsingCell(pCell);
00152     return this->GetNeighbouringNodeIndices(node_index);
00153 }
00154 
00155 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00156 void AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::UpdateNodeLocations(double dt)
00157 {
00158     // Iterate over all nodes associated with real cells to update their positions
00159     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
00160          cell_iter != this->End();
00161          ++cell_iter)
00162     {
00163         // Get index of node associated with cell
00164         unsigned node_index = this->GetLocationIndexUsingCell((*cell_iter));
00165 
00166         // Get damping constant for node
00167         double damping_const = this->GetDampingConstant(node_index);
00168 
00169         // Get displacement
00170         c_vector<double,SPACE_DIM> displacement=dt*this->GetNode(node_index)->rGetAppliedForce()/damping_const;
00171 
00172         // Throws an exception if the cell movement goes beyond mAbsoluteMovementThreshold
00173         if (norm_2(displacement) > this->mAbsoluteMovementThreshold)
00174         {
00175             EXCEPTION("Cells are moving by: " << norm_2(displacement) <<
00176                     ", which is more than the AbsoluteMovementThreshold: "
00177                     << this->mAbsoluteMovementThreshold <<
00178                     ". Use a smaller timestep to avoid this exception.");
00179         }
00180 
00181         // Get new node location
00182         c_vector<double, SPACE_DIM> new_node_location = this->GetNode(node_index)->rGetLocation() + displacement;
00183 
00184         // Create ChastePoint for new node location
00185         ChastePoint<SPACE_DIM> new_point(new_node_location);
00186 
00187         // Move the node
00188         this->SetNode(node_index, new_point);
00189     }
00190 }
00191 
00192 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00193 double AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetDampingConstant(unsigned nodeIndex)
00194 {
00195     CellPtr p_cell = this->GetCellUsingLocationIndex(nodeIndex);
00196     if (p_cell->GetMutationState()->IsType<WildTypeCellMutationState>() && !p_cell->HasCellProperty<CellLabel>())
00197     {
00198         return this->GetDampingConstantNormal();
00199     }
00200     else
00201     {
00202         return this->GetDampingConstantMutant();
00203     }
00204 }
00205 
00206 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00207 bool AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::IsGhostNode(unsigned index)
00208 {
00209     return false;
00210 }
00211 
00212 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00213 bool AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::IsParticle(unsigned index)
00214 {
00215     return false;
00216 }
00217 
00218 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00219 double AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetMeinekeDivisionSeparation()
00220 {
00221     return mMeinekeDivisionSeparation;
00222 }
00223 
00224 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00225 void AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetMeinekeDivisionSeparation(double divisionSeparation)
00226 {
00227     assert(divisionSeparation <= 1.0);
00228     assert(divisionSeparation >= 0.0);
00229     mMeinekeDivisionSeparation = divisionSeparation;
00230 }
00231 
00232 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00233 void AbstractCentreBasedCellPopulation<ELEMENT_DIM, SPACE_DIM>::OutputCellPopulationParameters(out_stream& rParamsFile)
00234 {
00235     *rParamsFile << "\t\t<MeinekeDivisionSeparation>" << mMeinekeDivisionSeparation << "</MeinekeDivisionSeparation>\n";
00236 
00237     // Call method on direct parent class
00238     AbstractOffLatticeCellPopulation<ELEMENT_DIM, SPACE_DIM>::OutputCellPopulationParameters(rParamsFile);
00239 }
00240 
00242 // Explicit instantiation
00244 
00245 template class AbstractCentreBasedCellPopulation<1,1>;
00246 template class AbstractCentreBasedCellPopulation<1,2>;
00247 template class AbstractCentreBasedCellPopulation<2,2>;
00248 template class AbstractCentreBasedCellPopulation<1,3>;
00249 template class AbstractCentreBasedCellPopulation<2,3>;
00250 template class AbstractCentreBasedCellPopulation<3,3>;

Generated by  doxygen 1.6.2