00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
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 {
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
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
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
00214 std::vector<Node<DIM>* > old_nodes;
00215 old_nodes.reserve(mNodes.size());
00216
00217
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
00227 delete mNodes[i];
00228 }
00229 }
00230
00231 std::map<unsigned,TissueCell*> old_map = this->mLocationCellMap;
00232 mNodes.clear();
00233
00234
00235 this->mLocationCellMap.clear();
00236 this->mCellLocationMap.clear();
00237
00238
00239 for (unsigned i=0; i<old_nodes.size(); i++)
00240 {
00241
00242 TissueCell *p_live_cell = old_map[old_nodes[i]->GetIndex()];
00243
00244
00245 mNodes.push_back(old_nodes[i]);
00246 mNodes[i]->SetIndex(i);
00247
00248
00249 this->mLocationCellMap[i] = p_live_cell;
00250 this->mCellLocationMap[p_live_cell] = i;
00251 }
00252
00253
00254 Clear();
00255
00256 Validate();
00257 }
00258
00259 if (mpNodeBoxCollection!=NULL)
00260 {
00261 delete mpNodeBoxCollection;
00262 }
00263
00264 FindMaxAndMin();
00265
00266
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
00284
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
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
00365
00366 template class NodeBasedTissue<1>;
00367 template class NodeBasedTissue<2>;
00368 template class NodeBasedTissue<3>;