MeshBasedTissue.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 "MeshBasedTissue.hpp"
00029 #include "TrianglesMeshWriter.hpp"
00030 #include "CancerEventHandler.hpp"
00031 
00032 template<unsigned DIM>
00033 MeshBasedTissue<DIM>::MeshBasedTissue(MutableMesh<DIM, DIM>& rMesh,
00034                                       const std::vector<TissueCell>& rCells,
00035                                       const std::vector<unsigned> locationIndices,
00036                                       bool deleteMesh,
00037                                       bool validate)
00038     : AbstractCellCentreBasedTissue<DIM>(rCells, locationIndices),
00039       mrMesh(rMesh),
00040       mpVoronoiTessellation(NULL),
00041       mDeleteMesh(deleteMesh),
00042       mWriteVoronoiData(false),
00043       mFollowLoggedCell(false),
00044       mWriteTissueAreas(false),
00045       mUseAreaBasedDampingConstant(false)
00046 {
00047     // This must always be true
00048     assert( this->mCells.size() <= mrMesh.GetNumNodes() );
00049 
00050     this->mTissueContainsMesh = true;
00051 
00052     if (validate)
00053     {
00054         Validate();
00055     }
00056 }
00057 
00058 template<unsigned DIM>
00059 MeshBasedTissue<DIM>::MeshBasedTissue(MutableMesh<DIM, DIM>& rMesh)
00060              : mrMesh(rMesh)
00061 {
00062     this->mTissueContainsMesh = true;
00063     mpVoronoiTessellation = NULL;
00064     mDeleteMesh = true;
00065 }
00066 
00067 template<unsigned DIM>
00068 MeshBasedTissue<DIM>::~MeshBasedTissue()
00069 {
00070     delete mpVoronoiTessellation;
00071     if (mDeleteMesh)
00072     {
00073         delete &mrMesh;
00074     }
00075 }
00076 
00077 template<unsigned DIM>
00078 bool MeshBasedTissue<DIM>::UseAreaBasedDampingConstant()
00079 {
00080     return mUseAreaBasedDampingConstant;
00081 }
00082 
00083 template<unsigned DIM>
00084 void MeshBasedTissue<DIM>::SetAreaBasedDampingConstant(bool useAreaBasedDampingConstant)
00085 {
00086     assert(DIM==2);
00087     mUseAreaBasedDampingConstant = useAreaBasedDampingConstant;
00088 }
00089 
00090 template<unsigned DIM>
00091 unsigned MeshBasedTissue<DIM>::AddNode(Node<DIM> *pNewNode)
00092 {
00093     return mrMesh.AddNode(pNewNode);
00094 }
00095 
00096 template<unsigned DIM>
00097 void MeshBasedTissue<DIM>::SetNode(unsigned nodeIndex, ChastePoint<DIM>& rNewLocation)
00098 {
00099     mrMesh.SetNode(nodeIndex, rNewLocation, false);
00100 }
00101 
00102 template<unsigned DIM>
00103 bool MeshBasedTissue<DIM>::IsGhostNode(unsigned index)
00104 {
00105     return false;
00106 }
00107 
00108 template<unsigned DIM>
00109 double MeshBasedTissue<DIM>::GetDampingConstant(unsigned nodeIndex)
00110 {
00111     double damping_multiplier = AbstractCellCentreBasedTissue<DIM>::GetDampingConstant(nodeIndex);
00112 
00113     if (mUseAreaBasedDampingConstant)
00114     {
00124         #define COVERAGE_IGNORE
00125         assert(DIM==2);
00126         #undef COVERAGE_IGNORE
00127 
00128         double rest_length = 1.0;
00129         double d0 = CancerParameters::Instance()->GetAreaBasedDampingConstantParameter();
00130 
00136         double d1 = 2.0*(1.0 - d0)/(sqrt(3)*rest_length*rest_length);
00137 
00138         VoronoiTessellation<DIM>& tess = this->rGetVoronoiTessellation();
00139 
00140         double area_cell = tess.GetFaceArea(nodeIndex);
00141 
00147         assert(area_cell < 1000);
00148 
00149         damping_multiplier = d0 + area_cell*d1;
00150     }
00151 
00152     return damping_multiplier;
00153 }
00154 
00155 template<unsigned DIM>
00156 void MeshBasedTissue<DIM>::Validate()
00157 {
00158     std::vector<bool> validated_node = std::vector<bool>(this->GetNumNodes(), false);
00159 
00160     for (typename AbstractTissue<DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
00161     {
00162         unsigned node_index = GetLocationIndexUsingCell(&(*cell_iter));
00163         validated_node[node_index] = true;
00164     }
00165 
00166     for (unsigned i=0; i<validated_node.size(); i++)
00167     {
00168         if (!validated_node[i])
00169         {
00170             std::stringstream ss;
00171             ss << "Node " << i << " does not appear to have a cell associated with it";
00172             EXCEPTION(ss.str());
00173         }
00174     }
00175 }
00176 
00177 template<unsigned DIM>
00178 MutableMesh<DIM, DIM>& MeshBasedTissue<DIM>::rGetMesh()
00179 {
00180     return mrMesh;
00181 }
00182 
00183 template<unsigned DIM>
00184 const MutableMesh<DIM, DIM>& MeshBasedTissue<DIM>::rGetMesh() const
00185 {
00186     return mrMesh;
00187 }
00188 
00189 template<unsigned DIM>
00190 unsigned MeshBasedTissue<DIM>::RemoveDeadCells()
00191 {
00192     unsigned num_removed = 0;
00193     for (std::list<TissueCell>::iterator it = this->mCells.begin();
00194          it != this->mCells.end();
00195          ++it)
00196     {
00197         if (it->IsDead())
00198         {
00199             // Check if this cell is in a marked spring
00200             std::vector<const std::set<TissueCell*>*> pairs_to_remove; // Pairs that must be purged
00201             for (std::set<std::set<TissueCell*> >::iterator it1 = mMarkedSprings.begin();
00202                  it1 != mMarkedSprings.end();
00203                  ++it1)
00204             {
00205                 const std::set<TissueCell*>& r_pair = *it1;
00206                 for (std::set<TissueCell*>::iterator it2 = r_pair.begin();
00207                      it2 != r_pair.end();
00208                      ++it2)
00209                 {
00210                     TissueCell* p_cell = *it2;
00211                     if (p_cell == &(*it))
00212                     {
00213                         // Remember to purge this spring
00214                         pairs_to_remove.push_back(&r_pair);
00215                         break;
00216                     }
00217                 }
00218             }
00219             // Purge any marked springs that contained this cell
00220             for (std::vector<const std::set<TissueCell*>* >::iterator pair_it = pairs_to_remove.begin();
00221                  pair_it != pairs_to_remove.end();
00222                  ++pair_it)
00223             {
00224                 mMarkedSprings.erase(**pair_it);
00225             }
00226 
00227             // Remove the node from the mesh
00228             num_removed++;
00229             mrMesh.DeleteNodePriorToReMesh(this->mCellLocationMap[&(*it)]);
00230 
00231             // Update mappings between cells and location indices
00232             unsigned location_index_of_removed_node = this->mCellLocationMap[&(*it)];
00233             this->mCellLocationMap.erase(&(*it));
00234             this->mLocationCellMap.erase(location_index_of_removed_node);
00235 
00236             // Update vector of cells
00237             it = this->mCells.erase(it);
00238 
00239             --it;
00240         }
00241     }
00242 
00243     return num_removed;
00244 }
00245 
00246 
00247 template<unsigned DIM>
00248 void MeshBasedTissue<DIM>::Update()
00249 {
00250     NodeMap map(mrMesh.GetNumAllNodes());
00251     mrMesh.ReMesh(map);
00252 
00253     if (!map.IsIdentityMap())
00254     {
00255         UpdateGhostNodesAfterReMesh(map);
00256 
00257         // Update the mappings between cells and location indices
00258         std::map<TissueCell*, unsigned> old_map = this->mCellLocationMap;
00259 
00260         // Remove any dead pointers from the maps (needed to avoid archiving errors)
00261         this->mLocationCellMap.clear();
00262         this->mCellLocationMap.clear();
00263 
00264         for (std::list<TissueCell>::iterator it = this->mCells.begin();
00265              it != this->mCells.end();
00266              ++it)
00267         {
00268             unsigned old_node_index = old_map[&(*it)];
00269 
00270             // This shouldn't ever happen, as the cell vector only contains living cells
00271             assert(!map.IsDeleted(old_node_index));
00272 
00273             unsigned new_node_index = map.GetNewIndex(old_node_index);
00274             this->mLocationCellMap[new_node_index] = &(*it);
00275             this->mCellLocationMap[&(*it)] = new_node_index;
00276         }
00277     }
00278 
00279     // Purge any marked springs that are no longer springs
00280     std::vector<const std::set<TissueCell*>*> springs_to_remove;
00281     for (std::set<std::set<TissueCell*> >::iterator spring_it = mMarkedSprings.begin();
00282          spring_it != mMarkedSprings.end();
00283          ++spring_it)
00284     {
00285         const std::set<TissueCell*>& r_pair = *spring_it;
00286         assert(r_pair.size() == 2);
00287         TissueCell* p_cell_1 = *(r_pair.begin());
00288         TissueCell* p_cell_2 = *(++r_pair.begin());
00289         Node<DIM>* p_node_1 = this->GetNodeCorrespondingToCell(p_cell_1);
00290         Node<DIM>* p_node_2 = this->GetNodeCorrespondingToCell(p_cell_2);
00291 
00292         bool joined = false;
00293 
00294         // For each element containing node1, if it also contains node2 then the cells are joined
00295         std::set<unsigned> node2_elements = p_node_2->rGetContainingElementIndices();
00296         for (typename Node<DIM>::ContainingElementIterator elt_it = p_node_1->ContainingElementsBegin();
00297              elt_it != p_node_1->ContainingElementsEnd();
00298              ++elt_it)
00299         {
00300             unsigned elt_index = *elt_it;
00301             if (node2_elements.find(elt_index) != node2_elements.end())
00302             {
00303                 joined = true;
00304                 break;
00305             }
00306         }
00307 
00308         // If no longer joined, remove this spring from the set
00309         if (!joined)
00310         {
00311             springs_to_remove.push_back(&r_pair);
00312         }
00313     }
00314 
00315     // Remove any springs necessary
00316     for (std::vector<const std::set<TissueCell*>* >::iterator spring_it = springs_to_remove.begin();
00317          spring_it != springs_to_remove.end();
00318          ++spring_it)
00319     {
00320         mMarkedSprings.erase(**spring_it);
00321     }
00322 
00323     Validate();
00324 
00325     // Tessellate if needed
00326 
00327     CancerEventHandler::BeginEvent(CancerEventHandler::TESSELLATION);
00328 
00329     if ( GetWriteVoronoiData() || UseAreaBasedDampingConstant() || GetWriteTissueAreas() )
00330     {
00331         CreateVoronoiTessellation();
00332     }
00333     CancerEventHandler::EndEvent(CancerEventHandler::TESSELLATION);
00334 }
00335 
00336 template<unsigned DIM>
00337 Node<DIM>* MeshBasedTissue<DIM>::GetNode(unsigned index)
00338 {
00339     return mrMesh.GetNode(index);
00340 }
00341 
00342 template<unsigned DIM>
00343 unsigned MeshBasedTissue<DIM>::GetNumNodes()
00344 {
00345     return mrMesh.GetNumAllNodes();
00346 }
00347 
00348 template<unsigned DIM>
00349 void MeshBasedTissue<DIM>::SetBottomCellAncestors()
00350 {
00351     unsigned index = 0;
00352     for (typename AbstractTissue<DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
00353     {
00354         if (this->GetNodeCorrespondingToCell(&(*cell_iter))->rGetLocation()[1] < 0.5)
00355         {
00356             cell_iter->SetAncestor(index++);
00357         }
00358     }
00359 }
00360 
00361 template<unsigned DIM>
00362 void MeshBasedTissue<DIM>::SetWriteVoronoiData(bool writeVoronoiData, bool followLoggedCell)
00363 {
00364     assert(DIM == 2);
00365     mWriteVoronoiData = writeVoronoiData;
00366     mFollowLoggedCell = followLoggedCell;
00367 }
00368 
00369 template<unsigned DIM>
00370 void MeshBasedTissue<DIM>::SetWriteTissueAreas(bool writeTissueAreas)
00371 {
00372     assert(DIM == 2);
00373     mWriteTissueAreas = writeTissueAreas;
00374 }
00375 
00376 template<unsigned DIM>
00377 void MeshBasedTissue<DIM>::UpdateGhostNodesAfterReMesh(NodeMap& rMap)
00378 {
00379 }
00380 
00381 template<unsigned DIM>
00382 TissueCell* MeshBasedTissue<DIM>::AddCell(TissueCell& rNewCell, c_vector<double,DIM> newLocation, TissueCell* pParentCell)
00383 {
00384     // Add new cell to tissue
00385     TissueCell* p_created_cell = AbstractCellCentreBasedTissue<DIM>::AddCell(rNewCell, newLocation, pParentCell);
00386 
00387     // Mark spring between parent cell and new cell
00388     MarkSpring(*pParentCell, *p_created_cell);
00389 
00390     // Return pointer to new cell
00391     return p_created_cell;
00392 }
00393 
00395 //                             Output methods                               //
00397 
00398 template<unsigned DIM>
00399 void MeshBasedTissue<DIM>::WriteMeshToFile(const std::string &rArchiveDirectory, const std::string &rMeshFileName)
00400 {
00401     // The false is so the directory isn't cleaned
00402     TrianglesMeshWriter<DIM, DIM> mesh_writer(rArchiveDirectory, rMeshFileName, false);
00403 
00404     mesh_writer.WriteFilesUsingMesh(mrMesh);
00405 }
00406 
00407 
00408 template<unsigned DIM>
00409 void MeshBasedTissue<DIM>::CreateOutputFiles(const std::string &rDirectory,
00410                                              bool rCleanOutputDirectory,
00411                                              bool outputCellMutationStates,
00412                                              bool outputCellTypes,
00413                                              bool outputCellVariables,
00414                                              bool outputCellCyclePhases,
00415                                              bool outputCellAncestors)
00416 {
00417     AbstractTissue<DIM>::CreateOutputFiles(rDirectory,
00418                                            rCleanOutputDirectory,
00419                                            outputCellMutationStates,
00420                                            outputCellTypes,
00421                                            outputCellVariables,
00422                                            outputCellCyclePhases,
00423                                            outputCellAncestors);
00424 
00425     OutputFileHandler output_file_handler(rDirectory, rCleanOutputDirectory);
00426     mpElementFile = output_file_handler.OpenOutputFile("results.vizelements");
00427 
00428     if (mWriteVoronoiData)
00429     {
00430         mpVoronoiFile = output_file_handler.OpenOutputFile("results.vizvoronoi");
00431     }
00432     if (mWriteTissueAreas)
00433     {
00434         mpTissueAreasFile = output_file_handler.OpenOutputFile("tissueareas.dat");
00435     }
00436 }
00437 
00438 template<unsigned DIM>
00439 void MeshBasedTissue<DIM>::CloseOutputFiles(bool outputCellMutationStates,
00440                                             bool outputCellTypes,
00441                                             bool outputCellVariables,
00442                                             bool outputCellCyclePhases,
00443                                             bool outputCellAncestors)
00444 {
00445     AbstractTissue<DIM>::CloseOutputFiles(outputCellMutationStates,
00446                                           outputCellTypes,
00447                                           outputCellVariables,
00448                                           outputCellCyclePhases,
00449                                           outputCellAncestors);
00450     mpElementFile->close();
00451 
00452     if (mWriteVoronoiData)
00453     {
00454         mpVoronoiFile->close();
00455     }
00456     if (mWriteTissueAreas)
00457     {
00458         mpTissueAreasFile->close();
00459     }
00460 }
00461 
00462 template<unsigned DIM>
00463 bool MeshBasedTissue<DIM>::GetWriteVoronoiData()
00464 {
00465     return mWriteVoronoiData;
00466 }
00467 
00468 template<unsigned DIM>
00469 bool MeshBasedTissue<DIM>::GetWriteTissueAreas()
00470 {
00471     return mWriteTissueAreas;
00472 }
00473 
00474 template<unsigned DIM>
00475 void MeshBasedTissue<DIM>::WriteResultsToFiles(bool outputCellMutationStates,
00476                                                bool outputCellTypes,
00477                                                bool outputCellVariables,
00478                                                bool outputCellCyclePhases,
00479                                                bool outputCellAncestors)
00480 {
00481     AbstractCellCentreBasedTissue<DIM>::WriteResultsToFiles(outputCellMutationStates,
00482                                                             outputCellTypes,
00483                                                             outputCellVariables,
00484                                                             outputCellCyclePhases,
00485                                                             outputCellAncestors);
00486 
00487     // Write element data to file
00488 
00489     *mpElementFile <<  SimulationTime::Instance()->GetTime() << "\t";
00490 
00491     for (unsigned elem_index=0; elem_index<mrMesh.GetNumAllElements(); elem_index++)
00492     {
00493         if (!mrMesh.GetElement(elem_index)->IsDeleted())
00494         {
00495             for (unsigned i=0; i<DIM+1; i++)
00496             {
00497                 *mpElementFile << mrMesh.GetElement(elem_index)->GetNodeGlobalIndex(i) << " ";
00498             }
00499         }
00500     }
00501 
00502     *mpElementFile << "\n";
00503 
00504     if (mpVoronoiTessellation!=NULL)
00505     {
00506         // Write Voronoi data to file if required
00507         if (mWriteVoronoiData)
00508         {
00509             WriteVoronoiResultsToFile();
00510         }
00511 
00512         // Write tissue area data to file if required
00513         if (mWriteTissueAreas)
00514         {
00515             WriteTissueAreaResultsToFile();
00516         }
00517     }
00518 }
00519 
00520 template<unsigned DIM>
00521 void MeshBasedTissue<DIM>::WriteVoronoiResultsToFile()
00522 {
00523     // Write time to file
00524     *mpVoronoiFile << SimulationTime::Instance()->GetTime() << " ";
00525 
00526     for (typename AbstractTissue<DIM>::Iterator cell_iter = this->Begin();
00527          cell_iter != this->End();
00528          ++cell_iter)
00529     {
00530         if ((!mFollowLoggedCell) || ((mFollowLoggedCell) && (cell_iter->IsLogged())))
00531         {
00532             unsigned node_index = this->mCellLocationMap[&(*cell_iter)];
00533             double x = this->GetLocationOfCellCentre(&(*cell_iter))[0];
00534             double y = this->GetLocationOfCellCentre(&(*cell_iter))[1];
00535 
00536             double cell_area = rGetVoronoiTessellation().GetFaceArea(node_index);
00537             double cell_perimeter = rGetVoronoiTessellation().GetFacePerimeter(node_index);
00538 
00539             *mpVoronoiFile << node_index << " " << x << " " << y << " " << cell_area << " " << cell_perimeter << " ";
00540 
00541             if (mFollowLoggedCell)
00542             {
00543                 break;
00544             }
00545         }
00546     }
00547     *mpVoronoiFile << "\n";
00548 }
00549 
00550 template<unsigned DIM>
00551 void MeshBasedTissue<DIM>::WriteTissueAreaResultsToFile()
00552 {
00553     // Write time to file
00554     *mpTissueAreasFile << SimulationTime::Instance()->GetTime() << " ";
00555 
00556     // Don't use the Voronoi tessellation to calculate the total area
00557     // because it gives huge areas for boundary cells
00558     double total_area = mrMesh.CalculateVolume();
00559 
00560     double apoptotic_area = 0.0;
00561 
00562     for (typename AbstractTissue<DIM>::Iterator cell_iter = this->Begin();
00563          cell_iter != this->End();
00564          ++cell_iter)
00565     {
00566         // Only bother calculating the cell area if it is apoptotic
00567         if (cell_iter->GetCellType() == APOPTOTIC)
00568         {
00569             unsigned node_index = this->mCellLocationMap[&(*cell_iter)];
00570             double cell_area = rGetVoronoiTessellation().GetFace(node_index)->GetArea();
00571             apoptotic_area += cell_area;
00572         }
00573     }
00574 
00575     *mpTissueAreasFile << total_area << " " << apoptotic_area << "\n";
00576 }
00577 
00579 //                          Spring iterator class                           //
00581 
00582 template<unsigned DIM>
00583 Node<DIM>* MeshBasedTissue<DIM>::SpringIterator::GetNodeA()
00584 {
00585     return mEdgeIter.GetNodeA();
00586 }
00587 
00588 template<unsigned DIM>
00589 Node<DIM>* MeshBasedTissue<DIM>::SpringIterator::GetNodeB()
00590 {
00591     return mEdgeIter.GetNodeB();
00592 }
00593 
00594 template<unsigned DIM>
00595 TissueCell& MeshBasedTissue<DIM>::SpringIterator::rGetCellA()
00596 {
00597     assert((*this) != mrTissue.SpringsEnd());
00598     return mrTissue.rGetCellUsingLocationIndex(mEdgeIter.GetNodeA()->GetIndex());
00599 }
00600 
00601 template<unsigned DIM>
00602 TissueCell& MeshBasedTissue<DIM>::SpringIterator::rGetCellB()
00603 {
00604     assert((*this) != mrTissue.SpringsEnd());
00605     return mrTissue.rGetCellUsingLocationIndex(mEdgeIter.GetNodeB()->GetIndex());
00606 }
00607 
00608 template<unsigned DIM>
00609 bool MeshBasedTissue<DIM>::SpringIterator::operator!=(const MeshBasedTissue<DIM>::SpringIterator& other)
00610 {
00611     return (mEdgeIter != other.mEdgeIter);
00612 }
00613 
00614 template<unsigned DIM>
00615 typename MeshBasedTissue<DIM>::SpringIterator& MeshBasedTissue<DIM>::SpringIterator::operator++()
00616 {
00617     bool edge_is_ghost = false;
00618 
00619     do
00620     {
00621         ++mEdgeIter;
00622         if (*this != mrTissue.SpringsEnd())
00623         {
00624             bool a_is_ghost = mrTissue.IsGhostNode(mEdgeIter.GetNodeA()->GetIndex());
00625             bool b_is_ghost = mrTissue.IsGhostNode(mEdgeIter.GetNodeB()->GetIndex());
00626 
00627             edge_is_ghost = (a_is_ghost || b_is_ghost);
00628         }
00629     }
00630     while (*this!=mrTissue.SpringsEnd() && edge_is_ghost);
00631 
00632     return (*this);
00633 }
00634 
00635 template<unsigned DIM>
00636 MeshBasedTissue<DIM>::SpringIterator::SpringIterator(MeshBasedTissue& rTissue,
00637                                            typename MutableMesh<DIM,DIM>::EdgeIterator edgeIter)
00638     : mrTissue(rTissue),
00639       mEdgeIter(edgeIter)
00640 {
00641     if (mEdgeIter!=mrTissue.mrMesh.EdgesEnd())
00642     {
00643         bool a_is_ghost = mrTissue.IsGhostNode(mEdgeIter.GetNodeA()->GetIndex());
00644         bool b_is_ghost = mrTissue.IsGhostNode(mEdgeIter.GetNodeB()->GetIndex());
00645 
00646         if (a_is_ghost || b_is_ghost)
00647         {
00648             ++(*this);
00649         }
00650     }
00651 }
00652 
00653 template<unsigned DIM>
00654 typename MeshBasedTissue<DIM>::SpringIterator MeshBasedTissue<DIM>::SpringsBegin()
00655 {
00656     return SpringIterator(*this, mrMesh.EdgesBegin());
00657 }
00658 
00659 template<unsigned DIM>
00660 typename MeshBasedTissue<DIM>::SpringIterator MeshBasedTissue<DIM>::SpringsEnd()
00661 {
00662     return SpringIterator(*this, mrMesh.EdgesEnd());
00663 }
00664 
00665 template<unsigned DIM>
00666 void MeshBasedTissue<DIM>::CreateVoronoiTessellation()
00667 {
00668     delete mpVoronoiTessellation;
00669     mpVoronoiTessellation = new VoronoiTessellation<DIM>(mrMesh);
00670 }
00671 
00672 template<>
00673 void MeshBasedTissue<1>::CreateVoronoiTessellation()
00674 {
00675     // No 1D Voronoi tessellation
00676     NEVER_REACHED;
00677 }
00678 
00679 template<unsigned DIM>
00680 VoronoiTessellation<DIM>& MeshBasedTissue<DIM>::rGetVoronoiTessellation()
00681 {
00682     assert(mpVoronoiTessellation!=NULL);
00683     return *mpVoronoiTessellation;
00684 }
00685 
00686 template<unsigned DIM>
00687 void MeshBasedTissue<DIM>::CheckTissueCellPointers()
00688 {
00689     bool res = true;
00690     for (std::list<TissueCell>::iterator it=this->mCells.begin();
00691          it!=this->mCells.end();
00692          ++it)
00693     {
00694         TissueCell* p_cell=&(*it);
00695         assert(p_cell);
00696         AbstractCellCycleModel* p_model = p_cell->GetCellCycleModel();
00697         assert(p_model);
00698 
00699         // Check cell exists in tissue
00700         unsigned node_index = this->mCellLocationMap[p_cell];
00701         std::cout << "Cell at node " << node_index << " addr " << p_cell << std::endl << std::flush;
00702         TissueCell& r_cell = this->rGetCellUsingLocationIndex(node_index);
00703 #define COVERAGE_IGNORE //Debugging code.  Shouldn't fail under normal conditions
00704         if (&r_cell != p_cell)
00705         {
00706             std::cout << "  Mismatch with tissue" << std::endl << std::flush;
00707             res = false;
00708         }
00709 
00710         // Check model links back to cell
00711         if (p_model->GetCell() != p_cell)
00712         {
00713             std::cout << "  Mismatch with cycle model" << std::endl << std::flush;
00714             res = false;
00715         }
00716     }
00717     assert(res);
00718 #undef COVERAGE_IGNORE
00719 
00720     res = true;
00721     for (std::set<std::set<TissueCell*> >::iterator it1 = mMarkedSprings.begin();
00722          it1 != mMarkedSprings.end();
00723          ++it1)
00724     {
00725         const std::set<TissueCell*>& r_pair = *it1;
00726         assert(r_pair.size() == 2);
00727         for (std::set<TissueCell*>::iterator it2 = r_pair.begin();
00728              it2 != r_pair.end();
00729              ++it2)
00730         {
00731             TissueCell* p_cell = *it2;
00732             assert(p_cell);
00733             AbstractCellCycleModel* p_model = p_cell->GetCellCycleModel();
00734             assert(p_model);
00735             unsigned node_index = this->mCellLocationMap[p_cell];
00736             std::cout << "Cell at node " << node_index << " addr " << p_cell << std::endl << std::flush;
00737 
00738 #define COVERAGE_IGNORE //Debugging code.  Shouldn't fail under normal conditions
00739             // Check cell is alive
00740             if (p_cell->IsDead())
00741             {
00742                 std::cout << "  Cell is dead" << std::endl << std::flush;
00743                 res = false;
00744             }
00745 
00746             // Check cell exists in tissue
00747             TissueCell& r_cell = this->rGetCellUsingLocationIndex(node_index);
00748             if (&r_cell != p_cell)
00749             {
00750                 std::cout << "  Mismatch with tissue" << std::endl << std::flush;
00751                 res = false;
00752             }
00753 
00754             // Check model links back to cell
00755             if (p_model->GetCell() != p_cell)
00756             {
00757                 std::cout << "  Mismatch with cycle model" << std::endl << std::flush;
00758                 res = false;
00759             }
00760         }
00761 #undef COVERAGE_IGNORE
00762     }
00763     assert(res);
00764 }
00765 
00766 template<unsigned DIM>
00767 std::set<TissueCell*> MeshBasedTissue<DIM>::CreateCellPair(TissueCell& rCell1, TissueCell& rCell2)
00768 {
00769     std::set<TissueCell *> cell_pair;
00770     cell_pair.insert(&rCell1);
00771     cell_pair.insert(&rCell2);
00772     return cell_pair;
00773 }
00774 
00775 template<unsigned DIM>
00776 bool MeshBasedTissue<DIM>::IsMarkedSpring(TissueCell& rCell1, TissueCell& rCell2)
00777 {
00778     std::set<TissueCell*> cell_pair = CreateCellPair(rCell1, rCell2);
00779     return mMarkedSprings.find(cell_pair) != mMarkedSprings.end();
00780 }
00781 
00782 template<unsigned DIM>
00783 void MeshBasedTissue<DIM>::MarkSpring(TissueCell& rCell1, TissueCell& rCell2)
00784 {
00785     std::set<TissueCell*> cell_pair = CreateCellPair(rCell1, rCell2);
00786     mMarkedSprings.insert(cell_pair);
00787 }
00788 
00789 template<unsigned DIM>
00790 void MeshBasedTissue<DIM>::UnmarkSpring(TissueCell& rCell1, TissueCell& rCell2)
00791 {
00792     std::set<TissueCell*> cell_pair = CreateCellPair(rCell1, rCell2);
00793     mMarkedSprings.erase(cell_pair);
00794 }
00795 
00796 
00798 // Explicit instantiation
00800 
00801 
00802 template class MeshBasedTissue<1>;
00803 template class MeshBasedTissue<2>;
00804 template class MeshBasedTissue<3>;

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