NodeBasedTissue.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 #include "NodeBasedTissue.hpp"
00029 
00030 
00031 template<unsigned DIM>
00032 NodeBasedTissue<DIM>::NodeBasedTissue(const std::vector<Node<DIM>* > nodes,
00033                                       const std::vector<TissueCell>& rCells,
00034                                       const std::vector<unsigned> locationIndices,
00035                                       bool deleteNodes)
00036     : AbstractCellCentreBasedTissue<DIM>(rCells, locationIndices),
00037       mNodes(nodes.begin(), nodes.end()),
00038       mAddedNodes(true),
00039       mpNodeBoxCollection(NULL),
00040       mDeleteNodes(deleteNodes)
00041 {
00042     Validate();
00043 }
00044 
00045 // archiving constructor
00046 template<unsigned DIM>
00047 NodeBasedTissue<DIM>::NodeBasedTissue(const std::vector<Node<DIM>* > nodes, bool deleteNodes)
00048     : AbstractCellCentreBasedTissue<DIM>(),
00049       mNodes(nodes.begin(), nodes.end()),
00050       mAddedNodes(true),
00051       mpNodeBoxCollection(NULL),
00052       mDeleteNodes(deleteNodes)
00053 {   // No Validate() because the cells are not associated with the tissue yet in archiving
00054 }
00055 
00056 
00057 template<unsigned DIM>
00058 NodeBasedTissue<DIM>::NodeBasedTissue(const AbstractMesh<DIM,DIM>& rMesh,
00059                                       const std::vector<TissueCell>& rCells)
00060     : AbstractCellCentreBasedTissue<DIM>(rCells),
00061       mAddedNodes(false),
00062       mpNodeBoxCollection(NULL),
00063       mDeleteNodes(true)
00064 {
00065     mNodes.reserve(rMesh.GetNumNodes());
00066     // Copy the actual node objects from mesh to this (mesh-less) tissue.
00067     for (unsigned i=0; i<rMesh.GetNumNodes(); i++)
00068     {
00069         Node<DIM> *p_node = new Node<DIM>(*(rMesh.GetNode(i)));
00070         mNodes.push_back(p_node);
00071     }
00072     mAddedNodes = true;
00073     Validate();
00074 }
00075 
00076 template<unsigned DIM>
00077 NodeBasedTissue<DIM>::~NodeBasedTissue()
00078 {
00079     Clear();
00080 
00081     // Free node memory
00082     if (mDeleteNodes)
00083     {
00084         for (unsigned i=0; i<mNodes.size(); i++)
00085         {
00086             delete mNodes[i];
00087         }
00088     }
00089 }
00090 
00091 
00092 template<unsigned DIM>
00093 void NodeBasedTissue<DIM>::Clear()
00094 {
00095     delete mpNodeBoxCollection;
00096     mpNodeBoxCollection = NULL;
00097     mNodePairs.clear();
00098     mDeletedNodeIndices.clear();
00099     mAddedNodes = false;
00100 }
00101 
00102 
00103 template<unsigned DIM>
00104 void NodeBasedTissue<DIM>::Validate()
00105 {
00106     std::vector<bool> validated_node(GetNumNodes());
00107     for (unsigned i=0; i<validated_node.size(); i++)
00108     {
00109         validated_node[i]=false;
00110     }
00111 
00112     for (typename AbstractTissue<DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
00113     {
00114         unsigned node_index = this->mCellLocationMap[&(*cell_iter)];
00115         validated_node[node_index] = true;
00116     }
00117 
00118     for (unsigned i=0; i<validated_node.size(); i++)
00119     {
00120         if (!validated_node[i])
00121         {
00122             std::stringstream ss;
00123             ss << "Node " << i << " does not appear to have a cell associated with it";
00124             EXCEPTION(ss.str());
00125         }
00126     }
00127 }
00128 
00129 
00130 template<unsigned DIM>
00131 std::vector<Node<DIM>* >& NodeBasedTissue<DIM>::rGetNodes()
00132 {
00133     return mNodes;
00134 }
00135 
00136 
00137 template<unsigned DIM>
00138 const std::vector<Node<DIM>* >& NodeBasedTissue<DIM>::rGetNodes() const
00139 {
00140     return mNodes;
00141 }
00142 
00143 
00144 template<unsigned DIM>
00145 void NodeBasedTissue<DIM>::SplitUpIntoBoxes(double cutOffLength, c_vector<double, 2*DIM> domainSize)
00146 {
00147     mpNodeBoxCollection = new NodeBoxCollection<DIM>(cutOffLength, domainSize);
00148 
00149     for (unsigned i=0; i<mNodes.size(); i++)
00150     {
00151         unsigned box_index = mpNodeBoxCollection->CalculateContainingBox(mNodes[i]);
00152         mpNodeBoxCollection->rGetBox(box_index).AddNode(mNodes[i]);
00153     }
00154 }
00155 
00156 
00157 template<unsigned DIM>
00158 void NodeBasedTissue<DIM>::FindMaxAndMin()
00159 {
00160     c_vector<double, DIM> min_posn;
00161     c_vector<double, DIM> max_posn;
00162     for (unsigned i=0; i<DIM; i++)
00163     {
00164         min_posn(i) = DBL_MAX;
00165         max_posn(i) = -DBL_MAX;
00166     }
00167 
00168     for (unsigned i=0; i<mNodes.size(); i++)
00169     {
00170         for (unsigned j=0; j<DIM; j++)
00171         {
00172             if (this->GetNode(i)->rGetLocation()[j] > max_posn(j))
00173             {
00174                 max_posn(j) = this->GetNode(i)->rGetLocation()[j];
00175             }
00176             if (this->GetNode(i)->rGetLocation()[j] < min_posn(j))
00177             {
00178                 min_posn(j) = this->GetNode(i)->rGetLocation()[j];
00179             }
00180         }
00181     }
00182 
00183     for (unsigned i=0; i<DIM; i++)
00184     {
00185         assert(min_posn(i) != DBL_MAX);
00186         mMinSpatialPositions(i) = min_posn(i);
00187 
00188         assert(max_posn(i) != -DBL_MAX);
00189         mMaxSpatialPositions(i) = max_posn(i);
00190     }
00191 }
00192 
00193 
00194 template<unsigned DIM>
00195 Node<DIM>* NodeBasedTissue<DIM>::GetNode(unsigned index)
00196 {
00197     return mNodes[index];
00198 }
00199 
00200 
00201 template<unsigned DIM>
00202 void NodeBasedTissue<DIM>::SetNode(unsigned nodeIndex, ChastePoint<DIM>& rNewLocation)
00203 {
00204     mNodes[nodeIndex]->SetPoint(rNewLocation);
00205 }
00206 
00207 
00208 template<unsigned DIM>
00209 void NodeBasedTissue<DIM>::Update(bool hasHadBirthsOrDeaths)
00210 {
00211     if (hasHadBirthsOrDeaths)
00212     {
00213         // Create and reserve space for a temporary vector
00214         std::vector<Node<DIM>* > old_nodes;
00215         old_nodes.reserve(mNodes.size());
00216 
00217         // Store all non-deleted nodes in the temporary vector
00218         for (unsigned i=0; i<mNodes.size(); i++)
00219         {
00220             if ( !mNodes[i]->IsDeleted() )
00221             {
00222                 old_nodes.push_back(mNodes[i]);
00223             }
00224             else
00225             {
00226                 // Free node memory
00227                 delete mNodes[i];
00228             }
00229         }
00230 
00231         std::map<unsigned,TissueCell*> old_map = this->mLocationCellMap;
00232         mNodes.clear();
00233 
00234         // Clear maps
00235         this->mLocationCellMap.clear();
00236         this->mCellLocationMap.clear();
00237 
00238         // Update mNodes to new indices which go from 0 to NumNodes-1
00239         for (unsigned i=0; i<old_nodes.size(); i++)
00240         {
00241             // Get the living cell associated with the old node
00242             TissueCell *p_live_cell = old_map[old_nodes[i]->GetIndex()];
00243 
00244             // Set the node up
00245             mNodes.push_back(old_nodes[i]);
00246             mNodes[i]->SetIndex(i);
00247 
00248             // Set the maps up
00249             this->mLocationCellMap[i] = p_live_cell;
00250             this->mCellLocationMap[p_live_cell] = i;
00251         }
00252 
00253         // Remove current dead indices data
00254         Clear();
00255 
00256         Validate();
00257     }
00258 
00259     if (mpNodeBoxCollection!=NULL)
00260     {
00261         delete mpNodeBoxCollection;
00262     }
00263 
00264     FindMaxAndMin();
00265 
00266     // Something here to set up the domain size (max and min of each node position dimension)
00267     c_vector<double, 2*DIM> domain_size;
00268 
00269     for (unsigned i=0; i<DIM; i++)
00270     {
00271         domain_size(2*i) = mMinSpatialPositions(i);
00272         domain_size(2*i+1) = mMaxSpatialPositions(i);
00273     }
00274 
00275     double cut_off_length = TissueConfig::Instance()->GetMechanicsCutOffLength();
00276     if (cut_off_length==DBL_MAX)
00277     {
00278         std::string error =  std::string("NodeBasedTissue cannot create boxes if the cut-off length has not been set - ")
00279                            + std::string("Call UseCutoffPoint() on the force law, or SetMechanicsCutOffLength on TissueConfig");
00280         EXCEPTION(error);
00281     }
00282 
00283     // Add this cancer parameter and suggest that mechanics systems set it.
00284     // Allocates memory for mpNodeBoxCollection and does the splitting and putting nodes into boxes
00285     SplitUpIntoBoxes(TissueConfig::Instance()->GetMechanicsCutOffLength(), domain_size);
00286 
00287     mpNodeBoxCollection->CalculateNodePairs(mNodes, mNodePairs);
00288 
00289     assert(mNodePairs.size() > 0);
00290 }
00291 
00292 
00293 template<unsigned DIM>
00294 unsigned NodeBasedTissue<DIM>::RemoveDeadCells()
00295 {
00296     unsigned num_removed = 0;
00297 
00298     for (std::list<TissueCell>::iterator cell_iter = this->mCells.begin();
00299          cell_iter != this->mCells.end();
00300          ++cell_iter)
00301     {
00302         if (cell_iter->IsDead())
00303         {
00304             // Remove the node
00305             num_removed++;
00306             this->GetNodeCorrespondingToCell(&(*cell_iter))->MarkAsDeleted();
00307             mDeletedNodeIndices.push_back( this->mCellLocationMap[&(*cell_iter)] );
00308             cell_iter = this->mCells.erase(cell_iter);
00309             --cell_iter;
00310         }
00311     }
00312     return num_removed;
00313 }
00314 
00315 
00316 template<unsigned DIM>
00317 unsigned NodeBasedTissue<DIM>::AddNode(Node<DIM>* pNewNode)
00318 {
00319     if (mDeletedNodeIndices.empty())
00320     {
00321         pNewNode->SetIndex(mNodes.size());
00322         mNodes.push_back(pNewNode);
00323     }
00324     else
00325     {
00326         unsigned index = mDeletedNodeIndices.back();
00327         pNewNode->SetIndex(index);
00328         mDeletedNodeIndices.pop_back();
00329         delete mNodes[index];
00330         mNodes[index] = pNewNode;
00331     }
00332     mAddedNodes = true;
00333     return pNewNode->GetIndex();
00334 }
00335 
00336 
00337 template<unsigned DIM>
00338 unsigned NodeBasedTissue<DIM>::GetNumNodes()
00339 {
00340     return mNodes.size() - mDeletedNodeIndices.size();
00341 }
00342 
00343 
00344 template<unsigned DIM>
00345 NodeBoxCollection<DIM>* NodeBasedTissue<DIM>::GetNodeBoxCollection()
00346 {
00347     return mpNodeBoxCollection;
00348 }
00349 
00350 
00351 template<unsigned DIM>
00352 std::set< std::pair<Node<DIM>*, Node<DIM>* > >& NodeBasedTissue<DIM>::rGetNodePairs()
00353 {
00354     if (mNodePairs.size()==0)
00355     {
00356         EXCEPTION("No node pairs set up, rGetNodePairs probably called before Update");
00357     }
00358     return mNodePairs;
00359 }
00360 
00361 
00363 // Explicit instantiation
00365 
00366 template class NodeBasedTissue<1>;
00367 template class NodeBasedTissue<2>;
00368 template class NodeBasedTissue<3>;

Generated on Tue Aug 4 16:10:21 2009 for Chaste by  doxygen 1.5.5