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 template<unsigned DIM>
00031 NodeBasedTissue<DIM>::NodeBasedTissue(const std::vector<Node<DIM>* > nodes,
00032                                       const std::vector<TissueCell>& rCells,
00033                                       const std::vector<unsigned> locationIndices,
00034                                       bool deleteNodes)
00035     : AbstractCellCentreBasedTissue<DIM>(rCells, locationIndices),
00036       mNodes(nodes.begin(), nodes.end()),
00037       mDeleteNodes(deleteNodes)
00038 {
00039     Clear();
00040     mAddedNodes = true;
00041     Validate();
00042 }
00043 
00044 
00045 template<unsigned DIM>
00046 NodeBasedTissue<DIM>::NodeBasedTissue(const std::vector<Node<DIM>* > nodes, bool deleteNodes)
00047     : AbstractCellCentreBasedTissue<DIM>(),
00048       mNodes(nodes.begin(), nodes.end()),
00049       mDeleteNodes(deleteNodes)
00050 {
00051     Clear();
00052     mAddedNodes = true;
00053 }
00054 
00055 
00056 template<unsigned DIM>
00057 NodeBasedTissue<DIM>::NodeBasedTissue(const AbstractMesh<DIM,DIM>& rMesh,
00058                                       const std::vector<TissueCell>& rCells)
00059     : AbstractCellCentreBasedTissue<DIM>(rCells),
00060       mDeleteNodes(true)
00061 {
00062     Clear();
00063     mNodes.reserve(rMesh.GetNumNodes());
00064     // Copy the actual node objects
00065     for (unsigned i=0; i<rMesh.GetNumNodes(); i++)
00066     {
00067         Node<DIM>* p_node = new Node<DIM>(*(rMesh.GetNode(i)));
00068         mNodes.push_back(p_node);
00069     }
00070     mAddedNodes = true;
00071     Validate();
00072 }
00073 
00074 
00075 template<unsigned DIM>
00076 NodeBasedTissue<DIM>::~NodeBasedTissue()
00077 {
00078     Clear();
00079     // Free node memory
00080     if (mDeleteNodes)
00081     {
00082         for (unsigned i=0; i<mNodes.size(); i++)
00083         {
00084             delete mNodes[i];
00085         }
00086     }
00087 }
00088 
00089 
00090 template<unsigned DIM>
00091 void NodeBasedTissue<DIM>::Clear()
00092 {
00093     mDeletedNodeIndices.clear();
00094     mAddedNodes = false;
00095 }
00096 
00097 
00098 template<unsigned DIM>
00099 void NodeBasedTissue<DIM>::Validate()
00100 {
00101     std::vector<bool> validated_node(GetNumNodes());
00102 
00103     for (typename AbstractTissue<DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
00104     {
00105         unsigned node_index = this->mCellLocationMap[&(*cell_iter)];
00106         validated_node[node_index] = true;
00107     }
00108 
00109     for (unsigned i=0; i<validated_node.size(); i++)
00110     {
00111         if (!validated_node[i])
00112         {
00113             std::stringstream ss;
00114             ss << "Node " << i << " does not appear to have a cell associated with it";
00115             EXCEPTION(ss.str());
00116         }
00117     }
00118 }
00119 
00120 
00121 template<unsigned DIM>
00122 std::vector<Node<DIM>* >& NodeBasedTissue<DIM>::rGetNodes()
00123 {
00124     return mNodes;
00125 }
00126 
00127 
00128 template<unsigned DIM>
00129 const std::vector<Node<DIM>* >& NodeBasedTissue<DIM>::rGetNodes() const
00130 {
00131     return mNodes;
00132 }
00133 
00134 
00135 template<unsigned DIM>
00136 Node<DIM>* NodeBasedTissue<DIM>::GetNode(unsigned index)
00137 {
00138     return mNodes[index];
00139 }
00140 
00141 
00142 template<unsigned DIM>
00143 void NodeBasedTissue<DIM>::SetNode(unsigned nodeIndex, ChastePoint<DIM>& rNewLocation)
00144 {
00145     mNodes[nodeIndex]->SetPoint(rNewLocation);
00146 }
00147 
00148 
00149 template<unsigned DIM>
00150 void NodeBasedTissue<DIM>::Update()
00151 {
00152     // Create and reserve space for a temporary vector
00153     std::vector<Node<DIM>* > old_nodes;
00154     old_nodes.reserve(mNodes.size());
00155 
00156     // Store all non-deleted nodes in the temporary vector
00157     for (unsigned i=0; i<mNodes.size(); i++)
00158     {
00159         if ( !mNodes[i]->IsDeleted() )
00160         {
00161             old_nodes.push_back(mNodes[i]);
00162         }
00163         else
00164         {
00165             // Free node memory
00166             delete mNodes[i];
00167         }
00168     }
00169 
00170     std::map<unsigned,TissueCell*> old_map = this->mLocationCellMap;
00171     mNodes.clear();
00172     
00173     // Clear maps
00174     this->mLocationCellMap.clear();
00175     this->mCellLocationMap.clear();
00176 
00177     // Update mNodes to new indices which go from 0 to NumNodes-1.
00178     for (unsigned i=0; i<old_nodes.size() ; i++)
00179     {
00180         // Get the living cell associated with the old node
00181         TissueCell* p_live_cell = old_map[old_nodes[i]->GetIndex()];
00182         // Set the node up
00183         mNodes.push_back(old_nodes[i]);
00184         mNodes[i]->SetIndex(i);
00185         // Set the maps up
00186         this->mLocationCellMap[i] = p_live_cell;
00187         this->mCellLocationMap[p_live_cell] = i;
00188     }
00189 
00190 
00191     // Remove current dead indices data
00192     Clear();
00193 
00194     Validate();
00195 }
00196 
00197 
00198 template<unsigned DIM>
00199 unsigned NodeBasedTissue<DIM>::RemoveDeadCells()
00200 {
00201     unsigned num_removed = 0;
00202 
00203     for (std::list<TissueCell>::iterator cell_iter = this->mCells.begin();
00204          cell_iter != this->mCells.end();
00205          ++cell_iter)
00206     {
00207         if (cell_iter->IsDead())
00208         {
00209             // Remove the node
00210             num_removed++;
00211             this->GetNodeCorrespondingToCell(&(*cell_iter))->MarkAsDeleted();
00212             mDeletedNodeIndices.push_back( this->mCellLocationMap[&(*cell_iter)] );
00213             cell_iter = this->mCells.erase(cell_iter);
00214             --cell_iter;
00215         }
00216     }
00217     return num_removed;
00218 }
00219 
00220 
00221 template<unsigned DIM>
00222 unsigned NodeBasedTissue<DIM>::AddNode(Node<DIM>* pNewNode)
00223 {
00224     if (mDeletedNodeIndices.empty())
00225     {
00226         pNewNode->SetIndex(mNodes.size());
00227         mNodes.push_back(pNewNode);
00228     }
00229     else
00230     {
00231         unsigned index = mDeletedNodeIndices.back();
00232         pNewNode->SetIndex(index);
00233         mDeletedNodeIndices.pop_back();
00234         delete mNodes[index];
00235         mNodes[index] = pNewNode;
00236     }
00237     mAddedNodes = true;
00238     return pNewNode->GetIndex();
00239 }
00240 
00241 
00242 template<unsigned DIM>
00243 unsigned NodeBasedTissue<DIM>::GetNumNodes()
00244 {
00245     return mNodes.size() - mDeletedNodeIndices.size();
00246 }
00247 
00248 
00250 // Explicit instantiation
00252 
00253 
00254 template class NodeBasedTissue<1>;
00255 template class NodeBasedTissue<2>;
00256 template class NodeBasedTissue<3>;

Generated on Wed Mar 18 12:51:50 2009 for Chaste by  doxygen 1.5.5