AbstractCellPopulation.cpp

00001 /*
00002 
00003 Copyright (c) 2005-2014, University of Oxford.
00004 All rights reserved.
00005 
00006 University of Oxford means the Chancellor, Masters and Scholars of the
00007 University of Oxford, having an administrative office at Wellington
00008 Square, Oxford OX1 2JD, UK.
00009 
00010 This file is part of Chaste.
00011 
00012 Redistribution and use in source and binary forms, with or without
00013 modification, are permitted provided that the following conditions are met:
00014  * Redistributions of source code must retain the above copyright notice,
00015    this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright notice,
00017    this list of conditions and the following disclaimer in the documentation
00018    and/or other materials provided with the distribution.
00019  * Neither the name of the University of Oxford nor the names of its
00020    contributors may be used to endorse or promote products derived from this
00021    software without specific prior written permission.
00022 
00023 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00024 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00025 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00026 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00027 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00028 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
00029 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00031 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
00032 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033 
00034 */
00035 
00036 #include <boost/foreach.hpp>
00037 #include <boost/bind.hpp>
00038 #include <boost/mem_fn.hpp>
00039 
00040 #include <algorithm>
00041 #include <functional>
00042 
00043 #include "AbstractCellPopulation.hpp"
00044 #include "AbstractOdeBasedCellCycleModel.hpp"
00045 #include "Exception.hpp"
00046 #include "PetscTools.hpp"
00047 #include "SmartPointers.hpp"
00048 
00049 // Cell writers
00050 #include "BoundaryNodeWriter.hpp"
00051 #include "CellProliferativeTypesWriter.hpp"
00052 
00053 // Cell population writers
00054 #include "CellMutationStatesCountWriter.hpp"
00055 #include "CellProliferativePhasesCountWriter.hpp"
00056 #include "CellProliferativeTypesCountWriter.hpp"
00057 #include "NodeLocationWriter.hpp"
00058 
00059 
00060 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00061 AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::AbstractCellPopulation( AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00062                                     std::vector<CellPtr>& rCells,
00063                                     const std::vector<unsigned> locationIndices)
00064     : mrMesh(rMesh),
00065       mCells(rCells.begin(), rCells.end()),
00066       mCentroid(zero_vector<double>(SPACE_DIM)),
00067       mpCellPropertyRegistry(CellPropertyRegistry::Instance()->TakeOwnership()),
00068       mOutputResultsForChasteVisualizer(true)
00069 {
00070     /*
00071      * To avoid double-counting problems, clear the passed-in cells vector.
00072      * We force a reallocation of memory so that subsequent usage of the
00073      * vector is more likely to give an error.
00074      */
00075     std::vector<CellPtr>().swap(rCells);
00076 
00077     // There must be a one-one correspondence between cells and location indices
00078     if (!locationIndices.empty())
00079     {
00080         if (mCells.size() != locationIndices.size())
00081         {
00082             EXCEPTION("There is not a one-one correspondence between cells and location indices");
00083         }
00084     }
00085 
00086     // Set up the map between location indices and cells
00087     mLocationCellMap.clear();
00088     mCellLocationMap.clear();
00089 
00090     std::list<CellPtr>::iterator it = mCells.begin();
00091     for (unsigned i=0; it != mCells.end(); ++it, ++i)
00092     {
00093         // Give each cell a pointer to the property registry (we have taken ownership in this constructor)
00094         (*it)->rGetCellPropertyCollection().SetCellPropertyRegistry(mpCellPropertyRegistry.get());
00095     }
00096 
00097     /*
00098      * Initialise cell counts to zero.
00099      *
00100      * Note: In its current form the code requires each cell-cycle model
00101      * to comprise four phases (G1, S, G2, M). This is reflected in the
00102      * explicit use of the variable NUM_CELL_CYCLE_PHASES below.
00103      */
00104     mCellCyclePhaseCount = std::vector<unsigned>(NUM_CELL_CYCLE_PHASES);
00105     for (unsigned i=0; i<mCellCyclePhaseCount.size(); i++)
00106     {
00107         mCellCyclePhaseCount[i] = 0;
00108     }
00109 }
00110 
00111 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00112 AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::AbstractCellPopulation(AbstractMesh<ELEMENT_DIM, SPACE_DIM>& rMesh)
00113     : mrMesh(rMesh)
00114 {
00115 }
00116 
00117 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00118 AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::~AbstractCellPopulation()
00119 {
00120 }
00121 
00122 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00123 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::InitialiseCells()
00124 {
00125     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin();
00126          cell_iter!=this->End();
00127          ++cell_iter)
00128     {
00129         cell_iter->InitialiseCellCycleModel();
00130     }
00131 }
00132 
00133 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00134 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetDataOnAllCells(const std::string& dataName, double dataValue)
00135 {
00136     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin();
00137          cell_iter!=this->End();
00138          ++cell_iter)
00139     {
00140         cell_iter->GetCellData()->SetItem(dataName, dataValue);
00141     }
00142 }
00143 
00144 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00145 AbstractMesh<ELEMENT_DIM, SPACE_DIM>& AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::rGetMesh()
00146 {
00147     return mrMesh;
00148 }
00149 
00150 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00151 std::list<CellPtr>& AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::rGetCells()
00152 {
00153     return mCells;
00154 }
00155 
00156 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00157 unsigned AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetNumRealCells()
00158 {
00159     unsigned counter = 0;
00160     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin();
00161          cell_iter!=this->End();
00162          ++cell_iter)
00163     {
00164         counter++;
00165     }
00166     return counter;
00167 }
00168 
00169 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00170 unsigned AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetNumAllCells()
00171 {
00172     return mCells.size();
00173 }
00174 
00175 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00176 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetCellAncestorsToLocationIndices()
00177 {
00178     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
00179     {
00180         MAKE_PTR_ARGS(CellAncestor, p_cell_ancestor, (mCellLocationMap[(*cell_iter).get()]));
00181         cell_iter->SetAncestor(p_cell_ancestor);
00182     }
00183 }
00184 
00185 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00186 std::set<unsigned> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellAncestors()
00187 {
00188     std::set<unsigned> remaining_ancestors;
00189     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
00190     {
00191         remaining_ancestors.insert(cell_iter->GetAncestor());
00192     }
00193     return remaining_ancestors;
00194 }
00195 
00196 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00197 std::vector<unsigned> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellMutationStateCount()
00198 {
00199     if (!HasWriter<CellMutationStatesCountWriter>())
00200     {
00201         EXCEPTION("Call AddPopulationWriter<CellMutationStatesCountWriter>() before using this function");
00202     }
00203     return mCellMutationStateCount;
00204 }
00205 
00206 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00207 std::vector<unsigned> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellProliferativeTypeCount()
00208 {
00209     if (!HasWriter<CellProliferativeTypesCountWriter>())
00210     {
00211         EXCEPTION("Call AddPopulationWriter<CellProliferativeTypesCountWriter>() before using this function");
00212     }
00213     return mCellProliferativeTypesCount;
00214 }
00215 
00216 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00217 std::vector<unsigned> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellCyclePhaseCount()
00218 {
00219     if (!HasWriter<CellProliferativePhasesCountWriter>())
00220     {
00221         EXCEPTION("Call AddPopulationWriter<CellProliferativePhasesCountWriter>() before using this function");
00222     }
00223     return mCellCyclePhaseCount;
00224 }
00225 
00226 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00227 CellPtr AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellUsingLocationIndex(unsigned index)
00228 {
00229     // Get the set of pointers to cells corresponding to this location index
00230     std::set<CellPtr> cells = mLocationCellMap[index];
00231 
00232     // If there is only one cell attached return the cell. Note currently only one cell per index.
00233     if (cells.size() == 1)
00234     {
00235         return *(cells.begin());
00236     }
00237     if (cells.empty())
00238     {
00239         EXCEPTION("Location index input argument does not correspond to a Cell");
00240     }
00241     else
00242     {
00243         EXCEPTION("Multiple cells are attached to a single location index.");
00244     }
00245 }
00246 
00247 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00248 std::set<CellPtr> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellsUsingLocationIndex(unsigned index)
00249 {
00250     // Return the set of pointers to cells corresponding to this location index, note the set may be empty.
00251     return mLocationCellMap[index];
00252 }
00253 
00254 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00255 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::IsCellAttachedToLocationIndex(unsigned index)
00256 {
00257     // Get the set of pointers to cells corresponding to this location index
00258     std::set<CellPtr> cells = mLocationCellMap[index];
00259 
00260     // Return whether there is a cell attached to the location index
00261     return !(cells.empty());
00262 }
00263 
00264 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00265 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetCellUsingLocationIndex(unsigned index, CellPtr pCell)
00266 {
00267     // Clear the maps
00268     mLocationCellMap[index].clear();
00269     mCellLocationMap.erase(pCell.get());
00270 
00271     // Replace with new cell
00272     mLocationCellMap[index].insert(pCell);
00273 
00274     // Do other half of the map
00275     mCellLocationMap[pCell.get()] = index;
00276 }
00277 
00278 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00279 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::AddCellUsingLocationIndex(unsigned index, CellPtr pCell)
00280 {
00281     mLocationCellMap[index].insert(pCell);
00282     mCellLocationMap[pCell.get()] = index;
00283 }
00284 
00285 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00286 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::RemoveCellUsingLocationIndex(unsigned index, CellPtr pCell)
00287 {
00288     std::set<CellPtr>::iterator cell_iter = mLocationCellMap[index].find(pCell);
00289 
00290     if (cell_iter == mLocationCellMap[index].end())
00291     {
00292         EXCEPTION("Tried to remove a cell which is not attached to the given location index");
00293     }
00294     else
00295     {
00296         mLocationCellMap[index].erase(cell_iter);
00297         mCellLocationMap.erase(pCell.get());
00298     }
00299 }
00300 
00301 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00302 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::MoveCellInLocationMap(CellPtr pCell, unsigned old_index, unsigned new_index)
00303 {
00304     // Remove the cell from its current location
00305     RemoveCellUsingLocationIndex(old_index, pCell);
00306 
00307     // Add it to the new location
00308     AddCellUsingLocationIndex(new_index, pCell);
00309 }
00310 
00311 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00312 unsigned AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetLocationIndexUsingCell(CellPtr pCell)
00313 {
00314     // Check the cell is in the map
00315     assert(this->mCellLocationMap.find(pCell.get()) != this->mCellLocationMap.end());
00316 
00317     return mCellLocationMap[pCell.get()];
00318 }
00319 
00320 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00321 boost::shared_ptr<CellPropertyRegistry> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCellPropertyRegistry()
00322 {
00323     return mpCellPropertyRegistry;
00324 }
00325 
00326 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00327 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetDefaultCellMutationStateAndProliferativeTypeOrdering()
00328 {
00329     boost::shared_ptr<CellPropertyRegistry> p_registry = GetCellPropertyRegistry();
00330     if (!p_registry->HasOrderingBeenSpecified())
00331     {
00332         std::vector<boost::shared_ptr<AbstractCellProperty> > mutations_and_proliferative_types;
00333         mutations_and_proliferative_types.push_back(p_registry->Get<WildTypeCellMutationState>());
00334         mutations_and_proliferative_types.push_back(p_registry->Get<ApcOneHitCellMutationState>());
00335         mutations_and_proliferative_types.push_back(p_registry->Get<ApcTwoHitCellMutationState>());
00336         mutations_and_proliferative_types.push_back(p_registry->Get<BetaCateninOneHitCellMutationState>());
00337         mutations_and_proliferative_types.push_back(p_registry->Get<StemCellProliferativeType>());
00338         mutations_and_proliferative_types.push_back(p_registry->Get<TransitCellProliferativeType>());
00339         mutations_and_proliferative_types.push_back(p_registry->Get<DifferentiatedCellProliferativeType>());
00340         // Parallel process with no cells won't have the default property, so add it in
00341         mutations_and_proliferative_types.push_back(p_registry->Get<DefaultCellProliferativeType>());
00342         p_registry->SpecifyOrdering(mutations_and_proliferative_types);
00343     }
00344 }
00345 
00346 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00347 c_vector<double, SPACE_DIM> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetCentroidOfCellPopulation()
00348 {
00349     mCentroid = zero_vector<double>(SPACE_DIM);
00350     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
00351          cell_iter != this->End();
00352          ++cell_iter)
00353     {
00354         mCentroid += GetLocationOfCellCentre(*cell_iter);
00355     }
00356     mCentroid /= this->GetNumRealCells();
00357 
00358     return mCentroid;
00359 }
00360 
00361 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00362 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::UpdateCellProcessLocation()
00363 {
00364 }
00365 
00366 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00367 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::CloseOutputFiles()
00368 {
00369     typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
00370     typedef AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> pop_writer_t;
00371 
00372     BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
00373     {
00374         p_cell_writer->CloseFile();
00375     }
00376     BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
00377     {
00378         p_pop_writer->CloseFile();
00379     }
00380 
00381 #ifdef CHASTE_VTK
00382     *mpVtkMetaFile << "    </Collection>\n";
00383     *mpVtkMetaFile << "</VTKFile>\n";
00384     mpVtkMetaFile->close();
00385 #endif //CHASTE_VTK
00386 }
00387 
00388 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00389 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::OpenWritersFiles(const std::string& rDirectory)
00390 {
00391 #ifdef CHASTE_VTK
00392     OutputFileHandler output_file_handler(rDirectory, false);
00393     mpVtkMetaFile = output_file_handler.OpenOutputFile("results.pvd");
00394     *mpVtkMetaFile << "<?xml version=\"1.0\"?>\n";
00395     *mpVtkMetaFile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">\n";
00396     *mpVtkMetaFile << "    <Collection>\n";
00397 #endif //CHASTE_VTK
00398 
00399     if (mOutputResultsForChasteVisualizer)
00400     {
00401         if (!HasWriter<NodeLocationWriter>())
00402         {
00403             AddPopulationWriter<NodeLocationWriter>();
00404         }
00405         if (!HasWriter<BoundaryNodeWriter>())
00406         {
00407             AddPopulationWriter<BoundaryNodeWriter>();
00408         }
00409         if (!HasWriter<CellProliferativeTypesWriter>())
00410         {
00411             AddCellWriter<CellProliferativeTypesWriter>();
00412         }
00413     }
00414 
00415     typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
00416     typedef AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> pop_writer_t;
00417     BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
00418     {
00419         p_cell_writer->OpenOutputFile(rDirectory);
00420     }
00421     BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
00422     {
00423         p_pop_writer->OpenOutputFile(rDirectory);
00424         p_pop_writer->WriteHeader(this);
00425     }
00426 }
00427 
00428 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00429 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::OpenWritersFilesForAppend(const std::string& rDirectory)
00430 {
00431     typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
00432     typedef AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> pop_writer_t;
00433     BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
00434     {
00435         p_cell_writer->OpenOutputFileForAppend(rDirectory);
00436     }
00437     BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
00438     {
00439         p_pop_writer->OpenOutputFileForAppend(rDirectory);
00440     }
00441 }
00442 
00443 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00444 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::WriteResultsToFiles(const std::string& rDirectory)
00445 {
00446     typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
00447     typedef AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> pop_writer_t;
00448 
00449     if (!(mCellWriters.empty() && mCellPopulationWriters.empty()))
00450     {
00451         // Reset cell counters
00452         for (unsigned i=0; i<mCellCyclePhaseCount.size(); i++)
00453         {
00454             mCellCyclePhaseCount[i] = 0;
00455         }
00456         mCellProliferativeTypesCount.clear();
00457         mCellMutationStateCount.clear();
00458 
00459         // Populate mCellCyclePhaseCount, mCellProliferativeTypesCount and mCellMutationStateCount
00460         GenerateCellResults();
00461 
00462         PetscTools::BeginRoundRobin();
00463         {
00464             OpenWritersFilesForAppend(rDirectory);
00465 
00466             // The master process writes time stamps
00467             if (PetscTools::AmMaster())
00468             {
00469                 BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
00470                 {
00471                     p_cell_writer->WriteTimeStamp();
00472                 }
00473                 BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
00474                 {
00475                     p_pop_writer->WriteTimeStamp();
00476                 }
00477             }
00478 
00479             for (typename std::set<boost::shared_ptr<AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator pop_writer_iter = mCellPopulationWriters.begin();
00480                  pop_writer_iter != mCellPopulationWriters.end();
00481                  ++pop_writer_iter)
00482             {
00483                 AcceptPopulationWriter(*pop_writer_iter);
00484             }
00485 
00486             for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
00487                  cell_iter != this->End();
00488                  ++cell_iter)
00489             {
00490                 for (typename std::set<boost::shared_ptr<AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator cell_writer_iter = mCellWriters.begin();
00491                      cell_writer_iter != mCellWriters.end();
00492                      ++cell_writer_iter)
00493                 {
00494                     AcceptCellWriter(*cell_writer_iter, *cell_iter);
00495                 }
00496             }
00497 
00498             // The top-most process adds a newline
00499             if (PetscTools::AmTopMost())
00500             {
00501                 BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
00502                 {
00503                     p_cell_writer->WriteNewline();
00504                 }
00505                 BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
00506                 {
00507                     p_pop_writer->WriteNewline();
00508                 }
00509             }
00510             CloseOutputFiles();
00511         }
00512         PetscTools::EndRoundRobin();
00513     }
00514 
00515     // VTK can only be written in 2 or 3 dimensions
00516     if (SPACE_DIM > 1)
00517     {
00518        WriteVtkResultsToFile(rDirectory);
00519     }
00520 }
00521 
00522 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00523 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GenerateCellResults()
00524 {
00525     if (HasWriter<CellProliferativePhasesCountWriter>())
00526     {
00527         for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
00528              cell_iter != this->End();
00529              ++cell_iter)
00530         {
00531             // Update mCellCyclePhaseCount
00532             switch ((*cell_iter)->GetCellCycleModel()->GetCurrentCellCyclePhase())
00533             {
00534                 case G_ZERO_PHASE:
00535                     mCellCyclePhaseCount[0]++;
00536                     break;
00537                 case G_ONE_PHASE:
00538                     mCellCyclePhaseCount[1]++;
00539                     break;
00540                 case S_PHASE:
00541                     mCellCyclePhaseCount[2]++;
00542                     break;
00543                 case G_TWO_PHASE:
00544                     mCellCyclePhaseCount[3]++;
00545                     break;
00546                  case M_PHASE:
00547                      mCellCyclePhaseCount[4]++;
00548                     break;
00549                 default:
00550                     NEVER_REACHED;
00551             }
00552         }
00553 
00554         // Reduce results onto all processes
00555         if (PetscTools::IsParallel())
00556         {
00557             std::vector<unsigned> phase_counts(mCellCyclePhaseCount.size(), 0u);
00558 
00559             for (unsigned i=0; i<phase_counts.size(); i++)
00560             {
00561                 MPI_Allreduce(&mCellCyclePhaseCount[i], &phase_counts[i], 1, MPI_UNSIGNED, MPI_SUM, PetscTools::GetWorld());
00562             }
00563 
00564             mCellCyclePhaseCount = phase_counts;
00565         }
00566     }
00567 
00568     // An ordering must be specified for cell mutation states and cell proliferative types
00569     SetDefaultCellMutationStateAndProliferativeTypeOrdering();
00570 
00571     const std::vector<boost::shared_ptr<AbstractCellProperty> >& r_cell_properties =
00572         mpCellPropertyRegistry->rGetAllCellProperties();
00573 
00574     // Calculate proliferative types count
00575     for (unsigned i=0; i<r_cell_properties.size(); i++)
00576     {
00577         if (r_cell_properties[i]->IsSubType<AbstractCellProliferativeType>())
00578         {
00580             mCellProliferativeTypesCount.push_back(r_cell_properties[i]->GetCellCount());
00581         }
00582     }
00583 
00584     // Reduce results onto all processes
00585     if (PetscTools::IsParallel())
00586     {
00587         // Make sure the vector on each process has the same size
00588         unsigned local_size = mCellProliferativeTypesCount.size();
00589         unsigned global_size;
00590 
00591         MPI_Allreduce(&local_size, &global_size, 1, MPI_UNSIGNED, MPI_MAX, PetscTools::GetWorld());
00592         assert(local_size == global_size);
00593 
00594         std::vector<unsigned> total_types_counts(global_size);
00595         MPI_Allreduce(&mCellProliferativeTypesCount[0], &total_types_counts[0], total_types_counts.size(), MPI_UNSIGNED, MPI_SUM, PetscTools::GetWorld());
00596 
00597         mCellProliferativeTypesCount = total_types_counts;
00598     }
00599 
00600     // Calculate mutation states count
00601     for (unsigned i=0; i<r_cell_properties.size(); i++)
00602     {
00603         if (r_cell_properties[i]->IsSubType<AbstractCellMutationState>())
00604         {
00606             mCellMutationStateCount.push_back(r_cell_properties[i]->GetCellCount());
00607         }
00608     }
00609 
00610     // Reduce results onto all processes
00611     if (PetscTools::IsParallel())
00612     {
00613         // Make sure the vector on each process has the same size
00614         unsigned local_size = mCellMutationStateCount.size();
00615         unsigned global_size;
00616         MPI_Allreduce(&local_size, &global_size, 1, MPI_UNSIGNED, MPI_MAX, PetscTools::GetWorld());
00617         assert(local_size == global_size);
00618 
00619         std::vector<unsigned> mutation_counts(global_size);
00620         MPI_Allreduce(&mCellMutationStateCount[0], &mutation_counts[0], mutation_counts.size(), MPI_UNSIGNED, MPI_SUM, PetscTools::GetWorld());
00621 
00622         mCellMutationStateCount = mutation_counts;
00623     }
00624 }
00625 
00626 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00627 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::OutputCellPopulationInfo(out_stream& rParamsFile)
00628 {
00629     std::string cell_population_type = GetIdentifier();
00630 
00631     *rParamsFile << "\t<" << cell_population_type << ">\n";
00632     OutputCellPopulationParameters(rParamsFile);
00633     *rParamsFile << "\t</" << cell_population_type << ">\n";
00634     *rParamsFile << "\n";
00635     *rParamsFile << "\t<CellCycleModels>\n";
00636 
00643     std::set<std::string> unique_cell_cycle_models;
00644     std::vector<CellPtr> first_cell_with_unique_CCM;
00645     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
00646          cell_iter != this->End();
00647          ++cell_iter)
00648     {
00649         std::string identifier = cell_iter->GetCellCycleModel()->GetIdentifier();
00650         if (unique_cell_cycle_models.count(identifier) == 0)
00651         {
00652             unique_cell_cycle_models.insert(identifier);
00653             first_cell_with_unique_CCM.push_back((*cell_iter));
00654         }
00655     }
00656 
00657     // Loop over unique cell-cycle models
00658     for (unsigned i=0; i<first_cell_with_unique_CCM.size(); i++)
00659     {
00660         // Output cell-cycle model details
00661         first_cell_with_unique_CCM[i]->GetCellCycleModel()->OutputCellCycleModelInfo(rParamsFile);
00662     }
00663 
00664     *rParamsFile << "\t</CellCycleModels>\n";
00665 }
00666 
00667 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00668 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::OutputCellPopulationParameters(out_stream& rParamsFile)
00669 {
00670     *rParamsFile << "\t\t<OutputResultsForChasteVisualizer>" << mOutputResultsForChasteVisualizer << "</OutputResultsForChasteVisualizer>\n";
00671 }
00672 
00673 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00674 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetOutputResultsForChasteVisualizer()
00675 {
00676     return mOutputResultsForChasteVisualizer;
00677 }
00678 
00679 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00680 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetOutputResultsForChasteVisualizer(bool outputResultsForChasteVisualizer)
00681 {
00682     mOutputResultsForChasteVisualizer = outputResultsForChasteVisualizer;
00683 }
00684 
00685 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00686 bool AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::IsRoomToDivide(CellPtr pCell)
00687 {
00688     return true;
00689 }
00690 
00691 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00692 c_vector<double,SPACE_DIM> AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::GetSizeOfCellPopulation()
00693 {
00694     // Compute the centre of mass of the cell population
00695     c_vector<double,SPACE_DIM> centre = GetCentroidOfCellPopulation();
00696 
00697     // Loop over cells and find the maximum distance from the centre of mass in each dimension
00698     c_vector<double,SPACE_DIM> max_distance_from_centre = zero_vector<double>(SPACE_DIM);
00699     for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
00700          cell_iter != this->End();
00701          ++cell_iter)
00702     {
00703         c_vector<double,SPACE_DIM> cell_location = GetLocationOfCellCentre(*cell_iter);
00704 
00705         // Note that we define this vector before setting it as otherwise the profiling build will break (see #2367)
00706         c_vector<double,SPACE_DIM> displacement;
00707         displacement = centre - cell_location;
00708 
00709         for (unsigned i=0; i<SPACE_DIM; i++)
00710         {
00711             if (displacement[i] > max_distance_from_centre[i])
00712             {
00713                 max_distance_from_centre[i] = displacement[i];
00714             }
00715         }
00716     }
00717 
00718     return max_distance_from_centre;
00719 }
00720 
00721 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00722 std::pair<unsigned,unsigned> AbstractCellPopulation<ELEMENT_DIM,SPACE_DIM>::CreateOrderedPair(unsigned index1, unsigned index2)
00723 {
00724     assert(index1 != index2);
00725 
00726     std::pair<unsigned, unsigned> ordered_pair;
00727     if (index1 < index2)
00728     {
00729         ordered_pair.first = index1;
00730         ordered_pair.second = index2;
00731     }
00732     else
00733     {
00734         ordered_pair.first = index2;
00735         ordered_pair.second = index1;
00736     }
00737     return ordered_pair;
00738 }
00739 
00740 // Explicit instantiation
00741 template class AbstractCellPopulation<1,1>;
00742 template class AbstractCellPopulation<1,2>;
00743 template class AbstractCellPopulation<2,2>;
00744 template class AbstractCellPopulation<1,3>;
00745 template class AbstractCellPopulation<2,3>;
00746 template class AbstractCellPopulation<3,3>;

Generated by  doxygen 1.6.2