VertexBasedCellPopulation.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2011
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 
00029 #include "VertexBasedCellPopulation.hpp"
00030 #include "CellwiseData.hpp"
00031 #include "VertexMeshWriter.hpp"
00032 #include "Warnings.hpp"
00033 
00034 template<unsigned DIM>
00035 VertexBasedCellPopulation<DIM>::VertexBasedCellPopulation(MutableVertexMesh<DIM, DIM>& rMesh,
00036                                           std::vector<CellPtr>& rCells,
00037                                           bool deleteMesh,
00038                                           bool validate,
00039                                           const std::vector<unsigned> locationIndices)
00040     : AbstractOffLatticeCellPopulation<DIM>(rCells, locationIndices),
00041       mrMesh(rMesh),
00042       mDeleteMesh(deleteMesh)
00043 {
00044     // Check the mesh contains boundary nodes
00045     bool contains_boundary_nodes = false;
00046     for (typename MutableVertexMesh<DIM,DIM>::NodeIterator node_iter = mrMesh.GetNodeIteratorBegin();
00047          node_iter != mrMesh.GetNodeIteratorEnd();
00048          ++node_iter)
00049     {
00050         if (node_iter->IsBoundaryNode())
00051         {
00052             contains_boundary_nodes = true;
00053         }
00054     }
00055     //if (mrMesh.GetNumBoundaryNodes() == 0)
00057     if (!contains_boundary_nodes)
00058     {
00059         EXCEPTION("No boundary nodes are defined in the supplied vertex mesh which are needed for vertex based simulations.");
00060     }
00061 
00062     // Check each element has only one cell attached
00063     if (validate)
00064     {
00065         Validate();
00066     }
00067 }
00068 
00069 template<unsigned DIM>
00070 VertexBasedCellPopulation<DIM>::VertexBasedCellPopulation(MutableVertexMesh<DIM, DIM>& rMesh)
00071     : AbstractOffLatticeCellPopulation<DIM>(),
00072       mrMesh(rMesh),
00073       mDeleteMesh(true)
00074 {
00075 }
00076 
00077 template<unsigned DIM>
00078 VertexBasedCellPopulation<DIM>::~VertexBasedCellPopulation()
00079 {
00080     if (mDeleteMesh)
00081     {
00082         delete &mrMesh;
00083     }
00084 }
00085 
00086 template<unsigned DIM>
00087 double VertexBasedCellPopulation<DIM>::GetDampingConstant(unsigned nodeIndex)
00088 {
00089     // Take the average of the cells containing this vertex
00090     double average_damping_constant = 0.0;
00091 
00092     std::set<unsigned> containing_elements = GetNode(nodeIndex)->rGetContainingElementIndices();
00093     double temp = 1.0/((double) containing_elements.size());
00094 
00095     for (std::set<unsigned>::iterator iter = containing_elements.begin();
00096          iter != containing_elements.end();
00097          ++iter)
00098     {
00099         CellPtr p_cell = this->GetCellUsingLocationIndex(*iter);
00100         bool cell_is_wild_type = p_cell->GetMutationState()->IsType<WildTypeCellMutationState>();
00101         bool cell_is_labelled = p_cell->HasCellProperty<CellLabel>();
00102 
00103         if (cell_is_wild_type && !cell_is_labelled)
00104         {
00105             average_damping_constant += this->GetDampingConstantNormal()*temp;
00106         }
00107         else
00108         {
00109             average_damping_constant += this->GetDampingConstantMutant()*temp;
00110         }
00111     }
00112 
00113     return average_damping_constant;
00114 }
00115 
00116 template<unsigned DIM>
00117 MutableVertexMesh<DIM, DIM>& VertexBasedCellPopulation<DIM>::rGetMesh()
00118 {
00119     return mrMesh;
00120 }
00121 
00122 template<unsigned DIM>
00123 const MutableVertexMesh<DIM, DIM>& VertexBasedCellPopulation<DIM>::rGetMesh() const
00124 {
00125     return mrMesh;
00126 }
00127 
00128 template<unsigned DIM>
00129 VertexElement<DIM, DIM>* VertexBasedCellPopulation<DIM>::GetElement(unsigned elementIndex)
00130 {
00131     return mrMesh.GetElement(elementIndex);
00132 }
00133 
00134 template<unsigned DIM>
00135 unsigned VertexBasedCellPopulation<DIM>::GetNumNodes()
00136 {
00137     return mrMesh.GetNumNodes();
00138 }
00139 
00140 template<unsigned DIM>
00141 c_vector<double, DIM> VertexBasedCellPopulation<DIM>::GetLocationOfCellCentre(CellPtr pCell)
00142 {
00143     return mrMesh.GetCentroidOfElement(this->mCellLocationMap[pCell.get()]);
00144 }
00145 
00146 template<unsigned DIM>
00147 Node<DIM>* VertexBasedCellPopulation<DIM>::GetNode(unsigned index)
00148 {
00149     return mrMesh.GetNode(index);
00150 }
00151 
00152 template<unsigned DIM>
00153 unsigned VertexBasedCellPopulation<DIM>::AddNode(Node<DIM>* pNewNode)
00154 {
00155     return mrMesh.AddNode(pNewNode);
00156 }
00157 
00158 template<unsigned DIM>
00159 void VertexBasedCellPopulation<DIM>::SetNode(unsigned nodeIndex, ChastePoint<DIM>& rNewLocation)
00160 {
00161     mrMesh.SetNode(nodeIndex, rNewLocation);
00162 }
00163 
00164 template<unsigned DIM>
00165 VertexElement<DIM, DIM>* VertexBasedCellPopulation<DIM>::GetElementCorrespondingToCell(CellPtr pCell)
00166 {
00167     return mrMesh.GetElement(this->mCellLocationMap[pCell.get()]);
00168 }
00169 
00170 template<unsigned DIM>
00171 unsigned VertexBasedCellPopulation<DIM>::GetNumElements()
00172 {
00173     return mrMesh.GetNumElements();
00174 }
00175 
00176 template<unsigned DIM>
00177 CellPtr VertexBasedCellPopulation<DIM>::AddCell(CellPtr pNewCell, const c_vector<double,DIM>& rCellDivisionVector, CellPtr pParentCell)
00178 {
00179     // Get the element associated with this cell
00180     VertexElement<DIM, DIM>* p_element = GetElementCorrespondingToCell(pParentCell);
00181 
00182     // Divide the element
00183     unsigned new_element_index;
00184     if (norm_2(rCellDivisionVector) < DBL_EPSILON)
00185     {
00186         // If the cell division vector is the default zero vector, divide the element along the short axis
00187         new_element_index = mrMesh.DivideElementAlongShortAxis(p_element, true);
00188     }
00189     else
00190     {
00191         // If the cell division vector has any non-zero component, divide the element along this axis
00192         new_element_index = mrMesh.DivideElementAlongGivenAxis(p_element, rCellDivisionVector, true);
00193     }
00194 
00195     // Associate the new cell with the element
00196     this->mCells.push_back(pNewCell);
00197 
00198     // Update location cell map
00199     CellPtr p_created_cell = this->mCells.back();
00200     this->mLocationCellMap[new_element_index] = p_created_cell;
00201     this->mCellLocationMap[p_created_cell.get()] = new_element_index;
00202     return p_created_cell;
00203 }
00204 
00205 template<unsigned DIM>
00206 unsigned VertexBasedCellPopulation<DIM>::RemoveDeadCells()
00207 {
00208     unsigned num_removed = 0;
00209 
00210     for (std::list<CellPtr>::iterator it = this->mCells.begin();
00211          it != this->mCells.end();
00212          ++it)
00213     {
00214         if ((*it)->IsDead())
00215         {
00216             // Remove the element from the mesh
00217             num_removed++;
00218             mrMesh.DeleteElementPriorToReMesh(this->mCellLocationMap[(*it).get()]);
00219             it = this->mCells.erase(it);
00220             --it;
00221         }
00222     }
00223     return num_removed;
00224 }
00225 
00226 template<unsigned DIM>
00227 void VertexBasedCellPopulation<DIM>::UpdateNodeLocations(const std::vector< c_vector<double, DIM> >& rNodeForces, double dt)
00228 {
00229     // Iterate over all nodes associated with real cells to update their positions
00230     for (unsigned node_index=0; node_index<GetNumNodes(); node_index++)
00231     {
00232         // Get the damping constant for this node
00233         double damping_const = this->GetDampingConstant(node_index);
00234 
00235         // Compute the displacement of this node
00236         c_vector<double, DIM> displacement = dt*rNodeForces[node_index]/damping_const;
00237 
00238         /*
00239          * If the displacement of this node is greater than half the cell rearrangement threshold,
00240          * this could result in nodes moving into the interior of other elements, which should not
00241          * be possible. Therefore in this case we restrict the displacement of the node to the cell
00242          * rearrangement threshold and warn the user that a smaller timestep should be used. This
00243          * restriction ensures that vertex elements remain well defined (see #1376).
00244          */
00245         if (norm_2(displacement) > 0.5*mrMesh.GetCellRearrangementThreshold())
00246         {
00247             WARN_ONCE_ONLY("Vertices are moving more than half the CellRearrangementThreshold. This could cause elements to become inverted so the motion has been restricted. Use a smaller timestep to avoid these warnings.");
00248             displacement *= 0.5*mrMesh.GetCellRearrangementThreshold()/norm_2(displacement);
00249         }
00250 
00251         // Get new node location
00252         c_vector<double, DIM> new_node_location = this->GetNode(node_index)->rGetLocation() + displacement;
00253 
00254         for (unsigned i=0; i<DIM; i++)
00255         {
00256             assert(!std::isnan(new_node_location(i)));
00257         }
00258 
00259         // Create ChastePoint for new node location
00260         ChastePoint<DIM> new_point(new_node_location);
00261 
00262         // Move the node
00263         this->SetNode(node_index, new_point);
00264     }
00265 }
00266 
00267 template<unsigned DIM>
00268 bool VertexBasedCellPopulation<DIM>::IsCellAssociatedWithADeletedLocation(CellPtr pCell)
00269 {
00270     return GetElementCorrespondingToCell(pCell)->IsDeleted();;
00271 }
00272 
00273 template<unsigned DIM>
00274 void VertexBasedCellPopulation<DIM>::Update(bool hasHadBirthsOrDeaths)
00275 {
00276     VertexElementMap element_map(mrMesh.GetNumAllElements());
00277 
00278     mrMesh.ReMesh(element_map);
00279 
00280     if (!element_map.IsIdentityMap())
00281     {
00282         // Fix up the mappings between CellPtrs and VertexElements
00283         std::map<Cell*, unsigned> old_map = this->mCellLocationMap;
00284 
00285         this->mCellLocationMap.clear();
00286         this->mLocationCellMap.clear();
00287 
00288         for (std::list<CellPtr>::iterator cell_iter = this->mCells.begin();
00289              cell_iter != this->mCells.end();
00290              ++cell_iter)
00291         {
00292             // This shouldn't ever happen, as the cell vector only contains living cells
00293             unsigned old_elem_index = old_map[(*cell_iter).get()];
00294 
00295             if (element_map.IsDeleted(old_elem_index))
00296             {
00301                 WARNING("Cell removed due to T2Swap this is not counted in the dead cells counter");
00302                 cell_iter = this->mCells.erase(cell_iter);
00303                 --cell_iter;
00304             }
00305             else
00306             {
00307                 unsigned new_elem_index = element_map.GetNewIndex(old_elem_index);
00308 
00309                 this->mLocationCellMap[new_elem_index] = *cell_iter;
00310                 this->mCellLocationMap[(*cell_iter).get()] = new_elem_index;
00311             }
00312         }
00313 
00314         // Check that each VertexElement has only one CellPtr associated with it in the updated cell population
00315         Validate();
00316     }
00317 
00318     element_map.ResetToIdentity();
00319 }
00320 
00321 template<unsigned DIM>
00322 void VertexBasedCellPopulation<DIM>::Validate()
00323 {
00324     // Check each element has only one cell attached
00325     std::vector<unsigned> validated_element = std::vector<unsigned>(this->GetNumElements(), 0);
00326 
00327     for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin();
00328          cell_iter != this->End();
00329          ++cell_iter)
00330     {
00331         unsigned elem_index = GetLocationIndexUsingCell(*cell_iter);
00332         validated_element[elem_index]++;
00333     }
00334 
00335     for (unsigned i=0; i<validated_element.size(); i++)
00336     {
00337         if (validated_element[i] == 0)
00338         {
00339             EXCEPTION("Element " << i << " does not appear to have a cell associated with it");
00340         }
00341 
00342         if (validated_element[i] > 1)
00343         {
00344             EXCEPTION("Element " << i << " appears to have " << validated_element[i] << " cells associated with it");
00345         }
00346     }
00347 }
00348 
00349 template<unsigned DIM>
00350 void VertexBasedCellPopulation<DIM>::WriteResultsToFiles()
00351 {
00352     AbstractOffLatticeCellPopulation<DIM>::WriteResultsToFiles();
00353 
00354     SimulationTime* p_time = SimulationTime::Instance();
00355 
00356     // Write Locations of T1Swaps to file
00357     *mpT1SwapLocationsFile << p_time->GetTime() << "\t";
00358     std::vector< c_vector<double, DIM> > t1_swap_locations = mrMesh.GetLocationsOfT1Swaps();
00359     *mpT1SwapLocationsFile << t1_swap_locations.size() << "\t";
00360     for (unsigned index = 0;  index < t1_swap_locations.size(); index++)
00361     {
00362         for (unsigned i=0; i<DIM; i++)
00363         {
00364             *mpT1SwapLocationsFile << t1_swap_locations[index][i] << "\t";
00365         }
00366     }
00367     *mpT1SwapLocationsFile << "\n";
00368     mrMesh.ClearLocationsOfT1Swaps();
00369 
00370     // Write Locations of T3Swaps to file
00371     *mpT3SwapLocationsFile << p_time->GetTime() << "\t";
00372     std::vector< c_vector<double, DIM> > t3_swap_locations = mrMesh.GetLocationsOfT3Swaps();
00373     *mpT3SwapLocationsFile << t3_swap_locations.size() << "\t";
00374     for (unsigned index = 0;  index < t3_swap_locations.size(); index++)
00375     {
00376         for (unsigned i=0; i<DIM; i++)
00377         {
00378             *mpT3SwapLocationsFile << t3_swap_locations[index][i] << "\t";
00379         }
00380     }
00381     *mpT3SwapLocationsFile << "\n";
00382     mrMesh.ClearLocationsOfT3Swaps();
00383 
00384     // Write element data to file
00385     *mpVizElementsFile << p_time->GetTime() << "\t";
00386 
00387     // Loop over cells and find associated elements so in the same order as the cells in output files
00388     for (std::list<CellPtr>::iterator cell_iter = this->mCells.begin();
00389          cell_iter != this->mCells.end();
00390          ++cell_iter)
00391     {
00392         unsigned elem_index = this->GetLocationIndexUsingCell(*cell_iter);
00393 
00394         // Hack that covers the case where the element is associated with a cell that has just been killed (#1129)
00395         bool elem_corresponds_to_dead_cell = false;
00396 
00397         if (this->mLocationCellMap[elem_index])
00398         {
00399             elem_corresponds_to_dead_cell = this->mLocationCellMap[elem_index]->IsDead();
00400         }
00401 
00402         // Write element data to file
00403         if (!(GetElement(elem_index)->IsDeleted()) && !elem_corresponds_to_dead_cell)
00404         {
00405             VertexElement<DIM, DIM>* p_element = mrMesh.GetElement(elem_index);
00406 
00407             unsigned num_nodes_in_element = p_element->GetNumNodes();
00408 
00409             // First write the number of Nodes belonging to this VertexElement
00410             *mpVizElementsFile << num_nodes_in_element << " ";
00411 
00412             // Then write the global index of each Node in this element
00413             for (unsigned i=0; i<num_nodes_in_element; i++)
00414             {
00415                 *mpVizElementsFile << p_element->GetNodeGlobalIndex(i) << " ";
00416             }
00417         }
00418     }
00419     *mpVizElementsFile << "\n";
00420 }
00421 
00422 template<unsigned DIM>
00423 void VertexBasedCellPopulation<DIM>::WriteCellVolumeResultsToFile()
00424 {
00425     assert(DIM==2);
00426 
00427      // Write time to file
00428     *(this->mpCellVolumesFile) << SimulationTime::Instance()->GetTime() << " ";
00429 
00430     // Loop over cells and find associated elements so in the same order as the cells in output files
00431      for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin();
00432          cell_iter != this->End();
00433          ++cell_iter)
00434     {
00435         unsigned elem_index = this->GetLocationIndexUsingCell(*cell_iter);
00436 
00437         // Hack that covers the case where the element is associated with a cell that has just been killed (#1129)
00438         bool elem_corresponds_to_dead_cell = false;
00439 
00440         if (this->mLocationCellMap[elem_index])
00441         {
00442             elem_corresponds_to_dead_cell = this->mLocationCellMap[elem_index]->IsDead();
00443         }
00444 
00445         // Write node data to file
00446         if (!(GetElement(elem_index)->IsDeleted()) && !elem_corresponds_to_dead_cell)
00447         {
00448             // Write element index to file
00449             *(this->mpCellVolumesFile) << elem_index << " ";
00450 
00451             // Write cell ID to file
00452             unsigned cell_index = (*cell_iter)->GetCellId();
00453             *(this->mpCellVolumesFile) << cell_index << " ";
00454 
00455             // Write location of element centroid to file
00456             c_vector<double, DIM> centre_location = GetLocationOfCellCentre(*cell_iter);
00457             for (unsigned i=0; i<DIM; i++)
00458             {
00459                 *(this->mpCellVolumesFile) << centre_location[i] << " ";
00460             }
00461 
00462             // Write cell volume (in 3D) or area (in 2D) to file
00463             double cell_volume = mrMesh.GetVolumeOfElement(elem_index);
00464             *(this->mpCellVolumesFile) << cell_volume << " ";
00465         }
00466     }
00467     *(this->mpCellVolumesFile) << "\n";
00468 }
00469 
00470 template<unsigned DIM>
00471 void VertexBasedCellPopulation<DIM>::WriteVtkResultsToFile()
00472 {
00473 #ifdef CHASTE_VTK
00474     SimulationTime* p_time = SimulationTime::Instance();
00475 
00476     VertexMeshWriter<DIM, DIM> mesh_writer(this->mDirPath, "results", false);
00477     std::stringstream time;
00478     time << p_time->GetTimeStepsElapsed();
00479 
00480     unsigned num_elements = mrMesh.GetNumElements();
00481     std::vector<double> cell_types(num_elements);
00482     std::vector<double> cell_ancestors(num_elements);
00483     std::vector<double> cell_mutation_states(num_elements);
00484     std::vector<double> cell_ages(num_elements);
00485     std::vector<double> cell_cycle_phases(num_elements);
00486     std::vector<double> cell_volumes(num_elements);
00487     std::vector<std::vector<double> > cellwise_data;
00488 
00489     if (CellwiseData<DIM>::Instance()->IsSetUp())
00490     {
00491         CellwiseData<DIM>* p_data = CellwiseData<DIM>::Instance();
00492         unsigned num_variables = p_data->GetNumVariables();
00493         for (unsigned var=0; var<num_variables; var++)
00494         {
00495             std::vector<double> cellwise_data_var(num_elements);
00496             cellwise_data.push_back(cellwise_data_var);
00497         }
00498     }
00499 
00500     // Loop over vertex elements
00501     for (typename VertexMesh<DIM,DIM>::VertexElementIterator elem_iter = mrMesh.GetElementIteratorBegin();
00502          elem_iter != mrMesh.GetElementIteratorEnd();
00503          ++elem_iter)
00504     {
00505         // Get index of this element in the vertex mesh
00506         unsigned elem_index = elem_iter->GetIndex();
00507 
00508         // Get the cell corresponding to this element
00509         CellPtr p_cell = this->mLocationCellMap[elem_index];
00510         assert(p_cell);
00511 
00512         if (this->mOutputCellAncestors)
00513         {
00514             double ancestor_index = (p_cell->GetAncestor() == UNSIGNED_UNSET) ? (-1.0) : (double)p_cell->GetAncestor();
00515             cell_ancestors[elem_index] = ancestor_index;
00516         }
00517         if (this->mOutputCellProliferativeTypes)
00518         {
00519             double cell_type = p_cell->GetCellCycleModel()->GetCellProliferativeType();
00520             cell_types[elem_index] = cell_type;
00521         }
00522         if (this->mOutputCellMutationStates)
00523         {
00524             double mutation_state = p_cell->GetMutationState()->GetColour();
00525             cell_mutation_states[elem_index] = mutation_state;
00526         }
00527         if (this->mOutputCellAges)
00528         {
00529             double age = p_cell->GetAge();
00530             cell_ages[elem_index] = age;
00531         }
00532         if (this->mOutputCellCyclePhases)
00533         {
00534             double cycle_phase = p_cell->GetCellCycleModel()->GetCurrentCellCyclePhase();
00535             cell_cycle_phases[elem_index] = cycle_phase;
00536         }
00537         if (this->mOutputCellVolumes)
00538         {
00539             double cell_volume = mrMesh.GetVolumeOfElement(elem_index);
00540             cell_volumes[elem_index] = cell_volume;
00541         }
00542         if (CellwiseData<DIM>::Instance()->IsSetUp())
00543         {
00544             CellwiseData<DIM>* p_data = CellwiseData<DIM>::Instance();
00545             unsigned num_variables = p_data->GetNumVariables();
00546 
00547             for (unsigned var=0; var<num_variables; var++)
00548             {
00549                 cellwise_data[var][elem_index] = p_data->GetValue(p_cell, var);
00550             }
00551         }
00552     }
00553 
00554     if (this->mOutputCellProliferativeTypes)
00555     {
00556         mesh_writer.AddCellData("Cell types", cell_types);
00557     }
00558     if (this->mOutputCellAncestors)
00559     {
00560         mesh_writer.AddCellData("Ancestors", cell_ancestors);
00561     }
00562     if (this->mOutputCellMutationStates)
00563     {
00564         mesh_writer.AddCellData("Mutation states", cell_mutation_states);
00565     }
00566     if (this->mOutputCellAges)
00567     {
00568         mesh_writer.AddCellData("Ages", cell_ages);
00569     }
00570     if (this->mOutputCellCyclePhases)
00571     {
00572         mesh_writer.AddCellData("Cycle phases", cell_cycle_phases);
00573     }
00574     if (this->mOutputCellVolumes)
00575     {
00576         mesh_writer.AddCellData("Cell volumes", cell_volumes);
00577     }
00578     if (CellwiseData<DIM>::Instance()->IsSetUp())
00579     {
00580         for (unsigned var=0; var<cellwise_data.size(); var++)
00581         {
00582             std::stringstream data_name;
00583             data_name << "Cellwise data " << var;
00584             std::vector<double> cellwise_data_var = cellwise_data[var];
00585             mesh_writer.AddCellData(data_name.str(), cellwise_data_var);
00586         }
00587     }
00588 
00589     mesh_writer.WriteVtkUsingMesh(mrMesh, time.str());
00590     *(this->mpVtkMetaFile) << "        <DataSet timestep=\"";
00591     *(this->mpVtkMetaFile) << p_time->GetTimeStepsElapsed();
00592     *(this->mpVtkMetaFile) << "\" group=\"\" part=\"0\" file=\"results_";
00593     *(this->mpVtkMetaFile) << p_time->GetTimeStepsElapsed();
00594     *(this->mpVtkMetaFile) << ".vtu\"/>\n";
00595 #endif //CHASTE_VTK
00596 }
00597 
00598 template<unsigned DIM>
00599 void VertexBasedCellPopulation<DIM>::CreateOutputFiles(const std::string& rDirectory, bool cleanOutputDirectory)
00600 {
00601     AbstractOffLatticeCellPopulation<DIM>::CreateOutputFiles(rDirectory, cleanOutputDirectory);
00602 
00603     OutputFileHandler output_file_handler(rDirectory, cleanOutputDirectory);
00604     mpVizElementsFile = output_file_handler.OpenOutputFile("results.vizelements");
00605     mpT1SwapLocationsFile = output_file_handler.OpenOutputFile("T1SwapLocations.dat");
00606     mpT3SwapLocationsFile = output_file_handler.OpenOutputFile("T3SwapLocations.dat");
00607 }
00608 
00609 template<unsigned DIM>
00610 void VertexBasedCellPopulation<DIM>::CloseOutputFiles()
00611 {
00612     AbstractOffLatticeCellPopulation<DIM>::CloseOutputFiles();
00613     mpVizElementsFile->close();
00614     mpT1SwapLocationsFile->close();
00615     mpT3SwapLocationsFile->close();
00616 }
00617 
00618 template<unsigned DIM>
00619 void VertexBasedCellPopulation<DIM>::GenerateCellResultsAndWriteToFiles()
00620 {
00621     // Set up cell type counter
00622     unsigned num_cell_types = this->mCellProliferativeTypeCount.size();
00623     std::vector<unsigned> cell_type_counter(num_cell_types);
00624     for (unsigned i=0; i<num_cell_types; i++)
00625     {
00626         cell_type_counter[i] = 0;
00627     }
00628 
00629     // Set up cell cycle phase counter
00630     unsigned num_cell_cycle_phases = this->mCellCyclePhaseCount.size();
00631     std::vector<unsigned> cell_cycle_phase_counter(num_cell_cycle_phases);
00632     for (unsigned i=0; i<num_cell_cycle_phases; i++)
00633     {
00634         cell_cycle_phase_counter[i] = 0;
00635     }
00636 
00637     for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = this->Begin();
00638          cell_iter != this->End();
00639          ++cell_iter)
00640     {
00641         this->GenerateCellResults(this->GetLocationIndexUsingCell(*cell_iter), cell_type_counter, cell_cycle_phase_counter);
00642     }
00643 
00644     this->WriteCellResultsToFiles(cell_type_counter, cell_cycle_phase_counter);
00645 }
00646 
00647 template<unsigned DIM>
00648 void VertexBasedCellPopulation<DIM>::OutputCellPopulationParameters(out_stream& rParamsFile)
00649 {
00650     *rParamsFile << "\t\t<CellRearrangementThreshold>" << mrMesh.GetCellRearrangementThreshold() << "</CellRearrangementThreshold>\n";
00651     *rParamsFile << "\t\t<T2Threshold>" <<  mrMesh.GetT2Threshold() << "</T2Threshold>\n";
00652     *rParamsFile << "\t\t<CellRearrangementRatio>" << mrMesh.GetCellRearrangementRatio() << "</CellRearrangementRatio>\n";
00653 
00654     // Call method on direct parent class
00655     AbstractOffLatticeCellPopulation<DIM>::OutputCellPopulationParameters(rParamsFile);
00656 }
00657 
00658 template<unsigned DIM>
00659 double VertexBasedCellPopulation<DIM>::GetWidth(const unsigned& rDimension)
00660 {
00661     // Call GetWidth() on the mesh
00662     double width = mrMesh.GetWidth(rDimension);
00663 
00664     return width;
00665 }
00666 
00667 template<unsigned DIM>
00668 std::set<unsigned> VertexBasedCellPopulation<DIM>::GetNeighbouringNodeIndices(unsigned index)
00669 {
00670     return mrMesh.GetNeighbouringNodeIndices(index);
00671 }
00672 
00674 // Explicit instantiation
00676 
00677 template class VertexBasedCellPopulation<1>;
00678 template class VertexBasedCellPopulation<2>;
00679 template class VertexBasedCellPopulation<3>;
00680 
00681 // Serialization for Boost >= 1.36
00682 #include "SerializationExportWrapperForCpp.hpp"
00683 EXPORT_TEMPLATE_CLASS_SAME_DIMS(VertexBasedCellPopulation)
Generated on Thu Dec 22 13:00:05 2011 for Chaste by  doxygen 1.6.3