Chaste  Release::3.4
AbstractCellPopulation.cpp
1 /*
2 
3 Copyright (c) 2005-2016, University of Oxford.
4 All rights reserved.
5 
6 University of Oxford means the Chancellor, Masters and Scholars of the
7 University of Oxford, having an administrative office at Wellington
8 Square, Oxford OX1 2JD, UK.
9 
10 This file is part of Chaste.
11 
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions are met:
14  * Redistributions of source code must retain the above copyright notice,
15  this list of conditions and the following disclaimer.
16  * Redistributions in binary form must reproduce the above copyright notice,
17  this list of conditions and the following disclaimer in the documentation
18  and/or other materials provided with the distribution.
19  * Neither the name of the University of Oxford nor the names of its
20  contributors may be used to endorse or promote products derived from this
21  software without specific prior written permission.
22 
23 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
29 GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 
34 */
35 
36 #include <boost/bind.hpp>
37 #include <boost/mem_fn.hpp>
38 
39 #include <algorithm>
40 #include <functional>
41 
42 #include "AbstractCellPopulation.hpp"
43 #include "AbstractOdeBasedCellCycleModel.hpp"
44 #include "Exception.hpp"
45 #include "PetscTools.hpp"
46 #include "SmartPointers.hpp"
47 
48 // Cell writers
49 #include "BoundaryNodeWriter.hpp"
50 #include "CellProliferativeTypesWriter.hpp"
51 
52 // Cell population writers
53 #include "CellMutationStatesCountWriter.hpp"
54 #include "CellProliferativePhasesCountWriter.hpp"
55 #include "CellProliferativeTypesCountWriter.hpp"
56 #include "NodeLocationWriter.hpp"
57 
58 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
60  std::vector<CellPtr>& rCells,
61  const std::vector<unsigned> locationIndices)
62  : mrMesh(rMesh),
63  mCells(rCells.begin(), rCells.end()),
64  mCentroid(zero_vector<double>(SPACE_DIM)),
65  mpCellPropertyRegistry(CellPropertyRegistry::Instance()->TakeOwnership()),
66  mOutputResultsForChasteVisualizer(true)
67 {
68  /*
69  * To avoid double-counting problems, clear the passed-in cells vector.
70  * We force a reallocation of memory so that subsequent usage of the
71  * vector is more likely to give an error.
72  */
73  std::vector<CellPtr>().swap(rCells);
74 
75  // There must be a one-one correspondence between cells and location indices
76  if (!locationIndices.empty())
77  {
78  if (mCells.size() != locationIndices.size())
79  {
80  EXCEPTION("There is not a one-one correspondence between cells and location indices");
81  }
82  }
83 
84  // Set up the map between location indices and cells
85  mLocationCellMap.clear();
86  mCellLocationMap.clear();
87 
88  std::list<CellPtr>::iterator it = mCells.begin();
89  for (unsigned i=0; it != mCells.end(); ++it, ++i)
90  {
91  // Give each cell a pointer to the property registry (we have taken ownership in this constructor)
92  (*it)->rGetCellPropertyCollection().SetCellPropertyRegistry(mpCellPropertyRegistry.get());
93  }
94 }
95 
96 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
98  : mrMesh(rMesh)
99 {
100 }
101 
102 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
104 {
105 }
106 
107 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
109 {
110  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin();
111  cell_iter!=this->End();
112  ++cell_iter)
113  {
114  cell_iter->InitialiseCellCycleModel();
115  cell_iter->InitialiseSrnModel();
116  }
117 }
118 
119 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
120 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::SetDataOnAllCells(const std::string& rDataName, double dataValue)
121 {
122  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin();
123  cell_iter!=this->End();
124  ++cell_iter)
125  {
126  cell_iter->GetCellData()->SetItem(rDataName, dataValue);
127  }
128 }
129 
130 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
132 {
133  return mrMesh;
134 }
135 
136 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
138 {
139  return mCells;
140 }
141 
142 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
144 {
145  unsigned counter = 0;
146  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin();
147  cell_iter!=this->End();
148  ++cell_iter)
149  {
150  counter++;
151  }
152  return counter;
153 }
154 
155 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
157 {
158  return mCells.size();
159 }
160 
161 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
163 {
164  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
165  {
166  MAKE_PTR_ARGS(CellAncestor, p_cell_ancestor, (mCellLocationMap[(*cell_iter).get()]));
167  cell_iter->SetAncestor(p_cell_ancestor);
168  }
169 }
170 
171 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
173 {
174  std::set<unsigned> remaining_ancestors;
175  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter=this->Begin(); cell_iter!=this->End(); ++cell_iter)
176  {
177  remaining_ancestors.insert(cell_iter->GetAncestor());
178  }
179  return remaining_ancestors;
180 }
181 
182 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
184 {
185  std::vector<unsigned> mutation_state_count;
186  const std::vector<boost::shared_ptr<AbstractCellProperty> >& r_cell_properties
187  = mpCellPropertyRegistry->rGetAllCellProperties();
188 
189  // Calculate mutation states count
190  for (unsigned i=0; i<r_cell_properties.size(); i++)
191  {
192  if (r_cell_properties[i]->IsSubType<AbstractCellMutationState>())
193  {
194  mutation_state_count.push_back(r_cell_properties[i]->GetCellCount());
195  }
196  }
197 
198  // Reduce results onto all processes
200  {
201  // Make sure the vector on each process has the same size
202  unsigned local_size = mutation_state_count.size();
203  unsigned global_size;
204  MPI_Allreduce(&local_size, &global_size, 1, MPI_UNSIGNED, MPI_MAX, PetscTools::GetWorld());
205  assert(local_size == global_size);
206 
207  std::vector<unsigned> mutation_counts(global_size);
208  MPI_Allreduce(&mutation_state_count[0], &mutation_counts[0], mutation_counts.size(), MPI_UNSIGNED, MPI_SUM, PetscTools::GetWorld());
209 
210  mutation_state_count = mutation_counts;
211  }
212 
213  return mutation_state_count;
214 }
215 
216 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
218 {
219  std::vector<unsigned> proliferative_type_count;
220  const std::vector<boost::shared_ptr<AbstractCellProperty> >& r_cell_properties
221  = mpCellPropertyRegistry->rGetAllCellProperties();
222 
223  // Calculate proliferative types count
224  for (unsigned i=0; i<r_cell_properties.size(); i++)
225  {
226  if (r_cell_properties[i]->IsSubType<AbstractCellProliferativeType>())
227  {
228  proliferative_type_count.push_back(r_cell_properties[i]->GetCellCount());
229  }
230  }
231 
232  // Reduce results onto all processes
234  {
235  // Make sure the vector on each process has the same size
236  unsigned local_size = proliferative_type_count.size();
237  unsigned global_size;
238 
239  MPI_Allreduce(&local_size, &global_size, 1, MPI_UNSIGNED, MPI_MAX, PetscTools::GetWorld());
240  assert(local_size == global_size);
241 
242  std::vector<unsigned> total_types_counts(global_size);
243  MPI_Allreduce(&proliferative_type_count[0], &total_types_counts[0], total_types_counts.size(), MPI_UNSIGNED, MPI_SUM, PetscTools::GetWorld());
244 
245  proliferative_type_count = total_types_counts;
246  }
247 
248  return proliferative_type_count;
249 }
250 
251 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
253 {
254  std::vector<unsigned> cell_cycle_phase_count(5);
255  for (unsigned i=0; i<5; i++)
256  {
257  cell_cycle_phase_count[i] = 0;
258  }
259 
260  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
261  cell_iter != this->End();
262  ++cell_iter)
263  {
264  switch ((*cell_iter)->GetCellCycleModel()->GetCurrentCellCyclePhase())
265  {
266  case G_ZERO_PHASE:
267  cell_cycle_phase_count[0]++;
268  break;
269  case G_ONE_PHASE:
270  cell_cycle_phase_count[1]++;
271  break;
272  case S_PHASE:
273  cell_cycle_phase_count[2]++;
274  break;
275  case G_TWO_PHASE:
276  cell_cycle_phase_count[3]++;
277  break;
278  case M_PHASE:
279  cell_cycle_phase_count[4]++;
280  break;
281  default:
283  }
284  }
285 
286  // Reduce results onto all processes
288  {
289  std::vector<unsigned> phase_counts(cell_cycle_phase_count.size(), 0u);
290  MPI_Allreduce(&cell_cycle_phase_count[0], &phase_counts[0], phase_counts.size(), MPI_UNSIGNED, MPI_SUM, PetscTools::GetWorld());
291 
292  cell_cycle_phase_count = phase_counts;
293  }
294 
295  return cell_cycle_phase_count;
296 }
297 
298 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
300 {
301  // Get the set of pointers to cells corresponding to this location index
302  std::set<CellPtr> cells = mLocationCellMap[index];
303 
304  // If there is only one cell attached return the cell. Note currently only one cell per index.
305  if (cells.size() == 1)
306  {
307  return *(cells.begin());
308  }
309  if (cells.empty())
310  {
311  EXCEPTION("Location index input argument does not correspond to a Cell");
312  }
313  else
314  {
315  EXCEPTION("Multiple cells are attached to a single location index.");
316  }
317 }
318 
319 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
321 {
322  // Return the set of pointers to cells corresponding to this location index, note the set may be empty.
323  return mLocationCellMap[index];
324 }
325 
326 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
328 {
329  // Get the set of pointers to cells corresponding to this location index
330  std::set<CellPtr> cells = mLocationCellMap[index];
331 
332  // Return whether there is a cell attached to the location index
333  return !(cells.empty());
334 }
335 
336 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
338 {
339  // Clear the maps
340  mLocationCellMap[index].clear();
341  mCellLocationMap.erase(pCell.get());
342 
343  // Replace with new cell
344  mLocationCellMap[index].insert(pCell);
345 
346  // Do other half of the map
347  mCellLocationMap[pCell.get()] = index;
348 }
349 
350 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
352 {
353  mLocationCellMap[index].insert(pCell);
354  mCellLocationMap[pCell.get()] = index;
355 }
356 
357 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
359 {
360  std::set<CellPtr>::iterator cell_iter = mLocationCellMap[index].find(pCell);
361 
362  if (cell_iter == mLocationCellMap[index].end())
363  {
364  EXCEPTION("Tried to remove a cell which is not attached to the given location index");
365  }
366  else
367  {
368  mLocationCellMap[index].erase(cell_iter);
369  mCellLocationMap.erase(pCell.get());
370  }
371 }
372 
373 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
374 void AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::MoveCellInLocationMap(CellPtr pCell, unsigned old_index, unsigned new_index)
375 {
376  // Remove the cell from its current location
377  RemoveCellUsingLocationIndex(old_index, pCell);
378 
379  // Add it to the new location
380  AddCellUsingLocationIndex(new_index, pCell);
381 }
382 
383 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
385 {
386  // Check the cell is in the map
387  assert(this->mCellLocationMap.find(pCell.get()) != this->mCellLocationMap.end());
388 
389  return mCellLocationMap[pCell.get()];
390 }
391 
392 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
394 {
395  return mpCellPropertyRegistry;
396 }
397 
398 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
400 {
401  boost::shared_ptr<CellPropertyRegistry> p_registry = GetCellPropertyRegistry();
402  if (!p_registry->HasOrderingBeenSpecified())
403  {
404  std::vector<boost::shared_ptr<AbstractCellProperty> > mutations_and_proliferative_types;
405  mutations_and_proliferative_types.push_back(p_registry->Get<WildTypeCellMutationState>());
406  mutations_and_proliferative_types.push_back(p_registry->Get<ApcOneHitCellMutationState>());
407  mutations_and_proliferative_types.push_back(p_registry->Get<ApcTwoHitCellMutationState>());
408  mutations_and_proliferative_types.push_back(p_registry->Get<BetaCateninOneHitCellMutationState>());
409  mutations_and_proliferative_types.push_back(p_registry->Get<StemCellProliferativeType>());
410  mutations_and_proliferative_types.push_back(p_registry->Get<TransitCellProliferativeType>());
411  mutations_and_proliferative_types.push_back(p_registry->Get<DifferentiatedCellProliferativeType>());
412  // Parallel process with no cells won't have the default property, so add it in
413  mutations_and_proliferative_types.push_back(p_registry->Get<DefaultCellProliferativeType>());
414  p_registry->SpecifyOrdering(mutations_and_proliferative_types);
415  }
416 }
417 
418 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
420 {
421  mCentroid = zero_vector<double>(SPACE_DIM);
422  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
423  cell_iter != this->End();
424  ++cell_iter)
425  {
426  mCentroid += GetLocationOfCellCentre(*cell_iter);
427  }
428  mCentroid /= this->GetNumRealCells();
429 
430  return mCentroid;
431 }
432 
433 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
435 {
436 }
437 
438 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
440 {
441  typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
442  BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
443  {
444  p_cell_writer->CloseFile();
445  }
446 
448  BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
449  {
450  p_pop_writer->CloseFile();
451  }
452 }
453 
454 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
456 {
457  typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
458  BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
459  {
460  p_cell_writer->CloseFile();
461  }
462 
464  BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
465  {
466  p_pop_writer->CloseFile();
467  }
468 
469 #ifdef CHASTE_VTK
470  *mpVtkMetaFile << " </Collection>\n";
471  *mpVtkMetaFile << "</VTKFile>\n";
472  mpVtkMetaFile->close();
473 #endif //CHASTE_VTK
474 }
475 
476 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
478 {
479 #ifdef CHASTE_VTK
480  mpVtkMetaFile = rOutputFileHandler.OpenOutputFile("results.pvd");
481  *mpVtkMetaFile << "<?xml version=\"1.0\"?>\n";
482  *mpVtkMetaFile << "<VTKFile type=\"Collection\" version=\"0.1\" byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">\n";
483  *mpVtkMetaFile << " <Collection>\n";
484 #endif //CHASTE_VTK
485 
486  if (mOutputResultsForChasteVisualizer)
487  {
488  if (!HasWriter<NodeLocationWriter>())
489  {
490  AddPopulationWriter<NodeLocationWriter>();
491  }
492  if (!HasWriter<BoundaryNodeWriter>())
493  {
494  AddPopulationWriter<BoundaryNodeWriter>();
495  }
496  if (!HasWriter<CellProliferativeTypesWriter>())
497  {
498  AddCellWriter<CellProliferativeTypesWriter>();
499  }
500  }
501 
502  // Open output files for any cell writers
503  typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
504  BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
505  {
506  p_cell_writer->OpenOutputFile(rOutputFileHandler);
507  }
508 
509  // Open output files and write headers for any population writers
511  BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
512  {
513  p_pop_writer->OpenOutputFile(rOutputFileHandler);
514  p_pop_writer->WriteHeader(this);
515  }
516 
517  // Open output files and write headers for any population count writers
519  BOOST_FOREACH(boost::shared_ptr<count_writer_t> p_count_writer, mCellPopulationCountWriters)
520  {
521  p_count_writer->OpenOutputFile(rOutputFileHandler);
522  p_count_writer->WriteHeader(this);
523  }
524 }
525 
526 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
528 {
529  typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
531  BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
532  {
533  p_cell_writer->OpenOutputFileForAppend(rOutputFileHandler);
534  }
535  BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
536  {
537  p_pop_writer->OpenOutputFileForAppend(rOutputFileHandler);
538  }
539 }
540 
541 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
543 {
544  typedef AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> cell_writer_t;
546  OutputFileHandler output_file_handler(rDirectory, false);
547 
548  if (!(mCellWriters.empty() && mCellPopulationWriters.empty() && mCellPopulationCountWriters.empty()))
549  {
550  // An ordering must be specified for cell mutation states and cell proliferative types
551  SetDefaultCellMutationStateAndProliferativeTypeOrdering();
552 
554  {
555  OpenRoundRobinWritersFilesForAppend(output_file_handler);
556 
557  // The master process writes time stamps
558  if (PetscTools::AmMaster())
559  {
560  BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
561  {
562  p_cell_writer->WriteTimeStamp();
563  }
564  BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
565  {
566  p_pop_writer->WriteTimeStamp();
567  }
568  }
569 
570  for (typename std::vector<boost::shared_ptr<AbstractCellPopulationWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator pop_writer_iter = mCellPopulationWriters.begin();
571  pop_writer_iter != mCellPopulationWriters.end();
572  ++pop_writer_iter)
573  {
574  AcceptPopulationWriter(*pop_writer_iter);
575  }
576 
577  AcceptCellWritersAcrossPopulation();
578 
579  // The top-most process adds a newline
580  if (PetscTools::AmTopMost())
581  {
582  BOOST_FOREACH(boost::shared_ptr<cell_writer_t> p_cell_writer, mCellWriters)
583  {
584  p_cell_writer->WriteNewline();
585  }
586  BOOST_FOREACH(boost::shared_ptr<pop_writer_t> p_pop_writer, mCellPopulationWriters)
587  {
588  p_pop_writer->WriteNewline();
589  }
590  }
591  CloseRoundRobinWritersFiles();
592  }
594 
595  // Outside the round robin, deal with population count writers
597 
598  if (PetscTools::AmMaster())
599  {
600  // Open mCellPopulationCountWriters in append mode for writing, and write time stamps
601  BOOST_FOREACH(boost::shared_ptr<count_writer_t> p_count_writer, mCellPopulationCountWriters)
602  {
603  p_count_writer->OpenOutputFileForAppend(output_file_handler);
604  p_count_writer->WriteTimeStamp();
605  }
606  }
607  for (typename std::vector<boost::shared_ptr<AbstractCellPopulationCountWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator count_writer_iter = mCellPopulationCountWriters.begin();
608  count_writer_iter != mCellPopulationCountWriters.end();
609  ++count_writer_iter)
610  {
611  AcceptPopulationCountWriter(*count_writer_iter);
612  }
613 
614  if (PetscTools::AmMaster())
615  {
616  // Add a newline and close any output files
617  BOOST_FOREACH(boost::shared_ptr<count_writer_t> p_count_writer, mCellPopulationCountWriters)
618  {
619  p_count_writer->WriteNewline();
620  p_count_writer->CloseFile();
621  }
622  }
623  }
624 
625  // VTK can only be written in 2 or 3 dimensions
626  if (SPACE_DIM > 1)
627  {
628  WriteVtkResultsToFile(rDirectory);
629  }
630 }
631 
632 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
634 {
635  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
636  cell_iter != this->End();
637  ++cell_iter)
638  {
639  for (typename std::vector<boost::shared_ptr<AbstractCellWriter<ELEMENT_DIM, SPACE_DIM> > >::iterator cell_writer_iter = mCellWriters.begin();
640  cell_writer_iter != mCellWriters.end();
641  ++cell_writer_iter)
642  {
643  AcceptCellWriter(*cell_writer_iter, *cell_iter);
644  }
645  }
646 }
647 
648 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
650 {
651  std::string cell_population_type = GetIdentifier();
652 
653  *rParamsFile << "\t<" << cell_population_type << ">\n";
654  OutputCellPopulationParameters(rParamsFile);
655  *rParamsFile << "\t</" << cell_population_type << ">\n";
656  *rParamsFile << "\n";
657  *rParamsFile << "\t<CellCycleModels>\n";
658 
665  std::set<std::string> unique_cell_cycle_models;
666  std::vector<CellPtr> first_cell_with_unique_CCM;
667  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
668  cell_iter != this->End();
669  ++cell_iter)
670  {
671  std::string identifier = cell_iter->GetCellCycleModel()->GetIdentifier();
672  if (unique_cell_cycle_models.count(identifier) == 0)
673  {
674  unique_cell_cycle_models.insert(identifier);
675  first_cell_with_unique_CCM.push_back((*cell_iter));
676  }
677  }
678 
679  // Loop over unique cell-cycle models
680  for (unsigned i=0; i<first_cell_with_unique_CCM.size(); i++)
681  {
682  // Output cell-cycle model details
683  first_cell_with_unique_CCM[i]->GetCellCycleModel()->OutputCellCycleModelInfo(rParamsFile);
684  }
685  *rParamsFile << "\t</CellCycleModels>\n";
686 
687  *rParamsFile << "\n";
688  *rParamsFile << "\t<SrnModels>\n";
689 
696  std::set<std::string> unique_srn_models;
697  std::vector<CellPtr> first_cell_with_unique_SRN;
698  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
699  cell_iter != this->End();
700  ++cell_iter)
701  {
702  std::string identifier = cell_iter->GetSrnModel()->GetIdentifier();
703  if (unique_srn_models.count(identifier) == 0)
704  {
705  unique_srn_models.insert(identifier);
706  first_cell_with_unique_SRN.push_back((*cell_iter));
707  }
708  }
709 
710  // Loop over unique SRN models
711  for (unsigned i=0; i<first_cell_with_unique_SRN.size(); i++)
712  {
713  // Output SRN model details
714  first_cell_with_unique_SRN[i]->GetSrnModel()->OutputSrnModelInfo(rParamsFile);
715  }
716 
717  *rParamsFile << "\t</SrnModels>\n";
718 }
719 
720 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
722 {
723  *rParamsFile << "\t\t<OutputResultsForChasteVisualizer>" << mOutputResultsForChasteVisualizer << "</OutputResultsForChasteVisualizer>\n";
724 }
725 
726 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
728 {
729  return mOutputResultsForChasteVisualizer;
730 }
731 
732 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
734 {
735  mOutputResultsForChasteVisualizer = outputResultsForChasteVisualizer;
736 }
737 
738 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
740 {
741  return true;
742 }
743 
744 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
746 {
747  // Compute the centre of mass of the cell population
748  c_vector<double,SPACE_DIM> centre = GetCentroidOfCellPopulation();
749 
750  // Loop over cells and find the maximum distance from the centre of mass in each dimension
751  c_vector<double,SPACE_DIM> max_distance_from_centre = zero_vector<double>(SPACE_DIM);
752  for (typename AbstractCellPopulation<ELEMENT_DIM, SPACE_DIM>::Iterator cell_iter = this->Begin();
753  cell_iter != this->End();
754  ++cell_iter)
755  {
756  c_vector<double,SPACE_DIM> cell_location = GetLocationOfCellCentre(*cell_iter);
757 
758  // Note that we define this vector before setting it as otherwise the profiling build will break (see #2367)
759  c_vector<double,SPACE_DIM> displacement;
760  displacement = centre - cell_location;
761 
762  for (unsigned i=0; i<SPACE_DIM; i++)
763  {
764  if (displacement[i] > max_distance_from_centre[i])
765  {
766  max_distance_from_centre[i] = displacement[i];
767  }
768  }
769  }
770 
771  return max_distance_from_centre;
772 }
773 
774 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
775 std::pair<unsigned,unsigned> AbstractCellPopulation<ELEMENT_DIM,SPACE_DIM>::CreateOrderedPair(unsigned index1, unsigned index2)
776 {
777  assert(index1 != index2);
778 
779  std::pair<unsigned, unsigned> ordered_pair;
780  if (index1 < index2)
781  {
782  ordered_pair.first = index1;
783  ordered_pair.second = index2;
784  }
785  else
786  {
787  ordered_pair.first = index2;
788  ordered_pair.second = index1;
789  }
790  return ordered_pair;
791 }
792 
793 // Explicit instantiation
794 template class AbstractCellPopulation<1,1>;
795 template class AbstractCellPopulation<1,2>;
796 template class AbstractCellPopulation<2,2>;
797 template class AbstractCellPopulation<1,3>;
798 template class AbstractCellPopulation<2,3>;
799 template class AbstractCellPopulation<3,3>;
c_vector< double, SPACE_DIM > GetCentroidOfCellPopulation()
void OpenOutputFileForAppend(OutputFileHandler &rOutputFileHandler)
virtual CellPtr GetCellUsingLocationIndex(unsigned index)
void SetDefaultCellMutationStateAndProliferativeTypeOrdering()
unsigned GetLocationIndexUsingCell(CellPtr pCell)
void SetDataOnAllCells(const std::string &rDataName, double dataValue)
boost::shared_ptr< CellPropertyRegistry > mpCellPropertyRegistry
virtual void RemoveCellUsingLocationIndex(unsigned index, CellPtr pCell)
virtual void OutputCellPopulationParameters(out_stream &rParamsFile)=0
#define EXCEPTION(message)
Definition: Exception.hpp:143
static bool AmMaster()
Definition: PetscTools.cpp:120
static MPI_Comm GetWorld()
Definition: PetscTools.cpp:174
std::set< CellPtr > GetCellsUsingLocationIndex(unsigned index)
bool IsCellAttachedToLocationIndex(unsigned index)
#define NEVER_REACHED
Definition: Exception.hpp:206
virtual void WriteResultsToFiles(const std::string &rDirectory)
void SetOutputResultsForChasteVisualizer(bool outputResultsForChasteVisualizer)
void MoveCellInLocationMap(CellPtr pCell, unsigned old_index, unsigned new_index)
std::list< CellPtr > & rGetCells()
std::vector< unsigned > GetCellCyclePhaseCount()
out_stream OpenOutputFile(const std::string &rFileName, std::ios_base::openmode mode=std::ios::out|std::ios::trunc) const
c_vector< double, SPACE_DIM > GetSizeOfCellPopulation()
virtual void AcceptCellWritersAcrossPopulation()
std::pair< unsigned, unsigned > CreateOrderedPair(unsigned index1, unsigned index2)
std::map< unsigned, std::set< CellPtr > > mLocationCellMap
void SetCellUsingLocationIndex(unsigned index, CellPtr pCell)
std::map< Cell *, unsigned > mCellLocationMap
static void EndRoundRobin()
Definition: PetscTools.cpp:160
boost::shared_ptr< CellPropertyRegistry > GetCellPropertyRegistry()
static void BeginRoundRobin()
Definition: PetscTools.cpp:150
void OpenRoundRobinWritersFilesForAppend(OutputFileHandler &rOutputFileHandler)
virtual void OpenWritersFiles(OutputFileHandler &rOutputFileHandler)
static bool IsParallel()
Definition: PetscTools.cpp:97
void OutputCellPopulationInfo(out_stream &rParamsFile)
virtual bool IsRoomToDivide(CellPtr pCell)
AbstractMesh< ELEMENT_DIM, SPACE_DIM > & rGetMesh()
virtual void OpenOutputFile(OutputFileHandler &rOutputFileHandler)
static bool AmTopMost()
Definition: PetscTools.cpp:126
AbstractCellPopulation(AbstractMesh< ELEMENT_DIM, SPACE_DIM > &rMesh)
virtual void AddCellUsingLocationIndex(unsigned index, CellPtr pCell)
std::vector< unsigned > GetCellProliferativeTypeCount()
#define MAKE_PTR_ARGS(TYPE, NAME, ARGS)
std::vector< unsigned > GetCellMutationStateCount()
std::set< unsigned > GetCellAncestors()