NodeBasedTissue.cpp
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 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 mpBoxCollection(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 mpBoxCollection(NULL),
00052 mDeleteNodes(deleteNodes)
00053 {
00054
00055 }
00056
00057
00058 template<unsigned DIM>
00059 NodeBasedTissue<DIM>::NodeBasedTissue(const AbstractMesh<DIM,DIM>& rMesh,
00060 std::vector<TissueCell>& rCells)
00061 : AbstractCellCentreBasedTissue<DIM>(rCells),
00062 mAddedNodes(false),
00063 mpBoxCollection(NULL),
00064 mDeleteNodes(true)
00065 {
00066 mNodes.reserve(rMesh.GetNumNodes());
00067
00068 for (unsigned i=0; i<rMesh.GetNumNodes(); i++)
00069 {
00070 Node<DIM>* p_node = new Node<DIM>(*(rMesh.GetNode(i)));
00071 mNodes.push_back(p_node);
00072 }
00073 mAddedNodes = true;
00074 Validate();
00075 }
00076
00077 template<unsigned DIM>
00078 NodeBasedTissue<DIM>::~NodeBasedTissue()
00079 {
00080 Clear();
00081
00082
00083 if (mDeleteNodes)
00084 {
00085 for (unsigned i=0; i<mNodes.size(); i++)
00086 {
00087 delete mNodes[i];
00088 }
00089 }
00090 }
00091
00092
00093 template<unsigned DIM>
00094 void NodeBasedTissue<DIM>::Clear()
00095 {
00096 delete mpBoxCollection;
00097 mpBoxCollection = NULL;
00098 mNodePairs.clear();
00099 mDeletedNodeIndices.clear();
00100 mAddedNodes = false;
00101 }
00102
00103
00104 template<unsigned DIM>
00105 void NodeBasedTissue<DIM>::Validate()
00106 {
00107 std::vector<bool> validated_node(GetNumNodes());
00108 for (unsigned i=0; i<validated_node.size(); i++)
00109 {
00110 validated_node[i] = false;
00111 }
00112
00113 for (typename AbstractTissue<DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
00114 {
00115 unsigned node_index = this->mCellLocationMap[&(*cell_iter)];
00116 validated_node[node_index] = true;
00117 }
00118
00119 for (unsigned i=0; i<validated_node.size(); i++)
00120 {
00121 if (!validated_node[i])
00122 {
00123 std::stringstream ss;
00124 ss << "Node " << i << " does not appear to have a cell associated with it";
00125 EXCEPTION(ss.str());
00126 }
00127 }
00128 }
00129
00130
00131 template<unsigned DIM>
00132 std::vector<Node<DIM>* >& NodeBasedTissue<DIM>::rGetNodes()
00133 {
00134 return mNodes;
00135 }
00136
00137
00138 template<unsigned DIM>
00139 const std::vector<Node<DIM>* >& NodeBasedTissue<DIM>::rGetNodes() const
00140 {
00141 return mNodes;
00142 }
00143
00144
00145 template<unsigned DIM>
00146 void NodeBasedTissue<DIM>::SplitUpIntoBoxes(double cutOffLength, c_vector<double, 2*DIM> domainSize)
00147 {
00148 mpBoxCollection = new BoxCollection<DIM>(cutOffLength, domainSize);
00149 mpBoxCollection->SetupLocalBoxesHalfOnly();
00150
00151 for (unsigned i=0; i<mNodes.size(); i++)
00152 {
00153 unsigned box_index = mpBoxCollection->CalculateContainingBox(mNodes[i]);
00154 mpBoxCollection->rGetBox(box_index).AddNode(mNodes[i]);
00155 }
00156 }
00157
00158
00159 template<unsigned DIM>
00160 void NodeBasedTissue<DIM>::FindMaxAndMin()
00161 {
00162 c_vector<double, DIM> min_posn;
00163 c_vector<double, DIM> max_posn;
00164 for (unsigned i=0; i<DIM; i++)
00165 {
00166 min_posn(i) = DBL_MAX;
00167 max_posn(i) = -DBL_MAX;
00168 }
00169
00170 for (unsigned i=0; i<mNodes.size(); i++)
00171 {
00172 for (unsigned j=0; j<DIM; j++)
00173 {
00174 if (this->GetNode(i)->rGetLocation()[j] > max_posn(j))
00175 {
00176 max_posn(j) = this->GetNode(i)->rGetLocation()[j];
00177 }
00178 if (this->GetNode(i)->rGetLocation()[j] < min_posn(j))
00179 {
00180 min_posn(j) = this->GetNode(i)->rGetLocation()[j];
00181 }
00182 }
00183 }
00184
00185 for (unsigned i=0; i<DIM; i++)
00186 {
00187 assert(min_posn(i) != DBL_MAX);
00188 mMinSpatialPositions(i) = min_posn(i);
00189
00190 assert(max_posn(i) != -DBL_MAX);
00191 mMaxSpatialPositions(i) = max_posn(i);
00192 }
00193 }
00194
00195
00196 template<unsigned DIM>
00197 Node<DIM>* NodeBasedTissue<DIM>::GetNode(unsigned index)
00198 {
00199 return mNodes[index];
00200 }
00201
00202
00203 template<unsigned DIM>
00204 void NodeBasedTissue<DIM>::SetNode(unsigned nodeIndex, ChastePoint<DIM>& rNewLocation)
00205 {
00206 mNodes[nodeIndex]->SetPoint(rNewLocation);
00207 }
00208
00209
00210 template<unsigned DIM>
00211 void NodeBasedTissue<DIM>::Update(bool hasHadBirthsOrDeaths)
00212 {
00213 if (hasHadBirthsOrDeaths)
00214 {
00215
00216 std::vector<Node<DIM>* > old_nodes;
00217 old_nodes.reserve(mNodes.size());
00218
00219
00220 for (unsigned i=0; i<mNodes.size(); i++)
00221 {
00222 if ( !mNodes[i]->IsDeleted() )
00223 {
00224 old_nodes.push_back(mNodes[i]);
00225 }
00226 else
00227 {
00228
00229 delete mNodes[i];
00230 }
00231 }
00232
00233 std::map<unsigned,TissueCell*> old_map = this->mLocationCellMap;
00234 mNodes.clear();
00235
00236
00237 this->mLocationCellMap.clear();
00238 this->mCellLocationMap.clear();
00239
00240
00241 for (unsigned i=0; i<old_nodes.size(); i++)
00242 {
00243
00244 TissueCell* p_live_cell = old_map[old_nodes[i]->GetIndex()];
00245
00246
00247 mNodes.push_back(old_nodes[i]);
00248 mNodes[i]->SetIndex(i);
00249
00250
00251 this->mLocationCellMap[i] = p_live_cell;
00252 this->mCellLocationMap[p_live_cell] = i;
00253 }
00254
00255
00256 Clear();
00257
00258 Validate();
00259 }
00260
00261 if (mpBoxCollection!=NULL)
00262 {
00263 delete mpBoxCollection;
00264 }
00265
00266 FindMaxAndMin();
00267
00268
00269 c_vector<double, 2*DIM> domain_size;
00270
00271 for (unsigned i=0; i<DIM; i++)
00272 {
00273 domain_size(2*i) = mMinSpatialPositions(i);
00274 domain_size(2*i+1) = mMaxSpatialPositions(i);
00275 }
00276
00277 double cut_off_length = TissueConfig::Instance()->GetMechanicsCutOffLength();
00278 if (cut_off_length==DBL_MAX)
00279 {
00280 std::string error = std::string("NodeBasedTissue cannot create boxes if the cut-off length has not been set - ")
00281 + std::string("Call UseCutoffPoint() on the force law, or SetMechanicsCutOffLength on TissueConfig");
00282 EXCEPTION(error);
00283 }
00284
00285
00286
00287 SplitUpIntoBoxes(TissueConfig::Instance()->GetMechanicsCutOffLength(), domain_size);
00288
00289 mpBoxCollection->CalculateNodePairs(mNodes, mNodePairs);
00290
00291
00292 }
00293
00294
00295 template<unsigned DIM>
00296 unsigned NodeBasedTissue<DIM>::RemoveDeadCells()
00297 {
00298 unsigned num_removed = 0;
00299
00300 for (std::list<TissueCell>::iterator cell_iter = this->mCells.begin();
00301 cell_iter != this->mCells.end();
00302 ++cell_iter)
00303 {
00304 if (cell_iter->IsDead())
00305 {
00306
00307 num_removed++;
00308 this->GetNodeCorrespondingToCell(*cell_iter)->MarkAsDeleted();
00309 mDeletedNodeIndices.push_back( this->mCellLocationMap[&(*cell_iter)] );
00310 cell_iter = this->mCells.erase(cell_iter);
00311 --cell_iter;
00312 }
00313 }
00314 return num_removed;
00315 }
00316
00317
00318 template<unsigned DIM>
00319 unsigned NodeBasedTissue<DIM>::AddNode(Node<DIM>* pNewNode)
00320 {
00321 if (mDeletedNodeIndices.empty())
00322 {
00323 pNewNode->SetIndex(mNodes.size());
00324 mNodes.push_back(pNewNode);
00325 }
00326 else
00327 {
00328 unsigned index = mDeletedNodeIndices.back();
00329 pNewNode->SetIndex(index);
00330 mDeletedNodeIndices.pop_back();
00331 delete mNodes[index];
00332 mNodes[index] = pNewNode;
00333 }
00334 mAddedNodes = true;
00335 return pNewNode->GetIndex();
00336 }
00337
00338
00339 template<unsigned DIM>
00340 unsigned NodeBasedTissue<DIM>::GetNumNodes()
00341 {
00342 return mNodes.size() - mDeletedNodeIndices.size();
00343 }
00344
00345
00346 template<unsigned DIM>
00347 BoxCollection<DIM>* NodeBasedTissue<DIM>::GetBoxCollection()
00348 {
00349 return mpBoxCollection;
00350 }
00351
00352
00353 template<unsigned DIM>
00354 std::set< std::pair<Node<DIM>*, Node<DIM>* > >& NodeBasedTissue<DIM>::rGetNodePairs()
00355 {
00356 if (mNodePairs.size()==0)
00357 {
00358 EXCEPTION("No node pairs set up, rGetNodePairs probably called before Update");
00359 }
00360 return mNodePairs;
00361 }
00362
00363
00365
00367
00368 template class NodeBasedTissue<1>;
00369 template class NodeBasedTissue<2>;
00370 template class NodeBasedTissue<3>;
00371
00372
00373
00374 #include "SerializationExportWrapperForCpp.hpp"
00375 EXPORT_TEMPLATE_CLASS_SAME_DIMS(NodeBasedTissue)