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

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