Chaste  Release::2017.1
AbstractCellBasedSimulation.cpp
1 /*
2 
3 Copyright (c) 2005-2017, 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 <cmath>
37 #include <iostream>
38 #include <fstream>
39 #include <set>
40 
41 #include "AbstractCellBasedSimulation.hpp"
42 #include "CellBasedEventHandler.hpp"
43 #include "LogFile.hpp"
44 #include "ExecutableSupport.hpp"
45 #include "AbstractPdeModifier.hpp"
46 
47 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
49  bool deleteCellPopulationInDestructor,
50  bool initialiseCells)
51  : mDt(DOUBLE_UNSET),
52  mEndTime(DOUBLE_UNSET), // hours - this is set later on
53  mrCellPopulation(rCellPopulation),
54  mDeleteCellPopulationInDestructor(deleteCellPopulationInDestructor),
55  mInitialiseCells(initialiseCells),
56  mNoBirth(false),
57  mUpdateCellPopulation(true),
58  mOutputDirectory(""),
59  mSimulationOutputDirectory(mOutputDirectory),
60  mNumBirths(0),
61  mNumDeaths(0),
62  mOutputDivisionLocations(false),
63  mOutputCellVelocities(false),
64  mSamplingTimestepMultiple(1)
65 {
66  // Set a random seed of 0 if it wasn't specified earlier
68 
69  if (mInitialiseCells)
70  {
71  mrCellPopulation.InitialiseCells();
72  }
73 
74  /*
75  * Specify a default time step to use, which may depend on the cell population type.
76  * Note that the time step may be reset using SetDt().
77  */
78  mDt = rCellPopulation.GetDefaultTimeStep();
79 }
80 
81 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
83 {
85  {
86  delete &mrCellPopulation;
87  }
88 }
89 
90 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
92 {
93  if (mNoBirth)
94  {
95  return 0;
96  }
97 
98  unsigned num_births_this_step = 0;
99 
100  // Iterate over all cells, seeing if each one can be divided
102  cell_iter != mrCellPopulation.End();
103  ++cell_iter)
104  {
105  // Check if this cell is ready to divide
106  double cell_age = cell_iter->GetAge();
107  if (cell_age > 0.0)
108  {
109  if (cell_iter->ReadyToDivide())
110  {
111  // Check if there is room into which the cell may divide
112  if (mrCellPopulation.IsRoomToDivide(*cell_iter))
113  {
114  // Store parent ID for output if required
115  unsigned parent_cell_id = cell_iter->GetCellId();
116 
117  // Create a new cell
118  CellPtr p_new_cell = cell_iter->Divide();
119 
139  {
140  c_vector<double, SPACE_DIM> cell_location = mrCellPopulation.GetLocationOfCellCentre(*cell_iter);
141 
143  for (unsigned i=0; i<SPACE_DIM; i++)
144  {
145  *mpDivisionLocationFile << cell_location[i] << "\t";
146  }
147  *mpDivisionLocationFile << "\t" << cell_age << "\t" << parent_cell_id << "\t" << cell_iter->GetCellId() << "\t" << p_new_cell->GetCellId() << "\n";
148  }
149 
150  // Add the new cell to the cell population
151  mrCellPopulation.AddCell(p_new_cell, *cell_iter);
152 
153  // Update counter
154  num_births_this_step++;
155  }
156  }
157  }
158  }
159  return num_births_this_step;
160 }
161 
162 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
164 {
165  unsigned num_deaths_this_step = 0;
166 
167  /*
168  * This labels cells as dead or apoptosing. It does not actually remove the cells,
169  * mrCellPopulation.RemoveDeadCells() needs to be called for this.
170  */
171  for (typename std::vector<boost::shared_ptr<AbstractCellKiller<SPACE_DIM> > >::iterator killer_iter = mCellKillers.begin();
172  killer_iter != mCellKillers.end();
173  ++killer_iter)
174  {
175  (*killer_iter)->CheckAndLabelCellsForApoptosisOrDeath();
176  }
177 
178  num_deaths_this_step += mrCellPopulation.RemoveDeadCells();
179 
180  return num_deaths_this_step;
181 }
182 
183 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
185 {
186  assert(dt > 0);
187  mDt = dt;
188 }
189 
190 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
192 {
193  return mDt;
194 }
195 
196 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
198 {
199  return mNumBirths;
200 }
201 
202 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
204 {
205  return mNumDeaths;
206 }
207 
208 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
210 {
211  assert(endTime > 0);
212  mEndTime = endTime;
213 }
214 
215 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
217 {
218  mOutputDirectory = outputDirectory;
220 }
221 
222 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
224 {
225  return mOutputDirectory;
226 }
227 
228 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
230 {
231  assert(samplingTimestepMultiple > 0);
232  mSamplingTimestepMultiple = samplingTimestepMultiple;
233 }
234 
235 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
237 {
238  return mrCellPopulation;
239 }
240 
241 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
243 {
244  return mrCellPopulation;
245 }
246 
247 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
249 {
250  mUpdateCellPopulation = updateCellPopulation;
251 }
252 
253 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
255 {
256  return mUpdateCellPopulation;
257 }
258 
259 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
261 {
262  mNoBirth = noBirth;
263 }
264 
265 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
267 {
268  mCellKillers.push_back(pCellKiller);
269 }
270 
271 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
273 {
274  mCellKillers.clear();
275 }
276 
277 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
279 {
280  mSimulationModifiers.push_back(pSimulationModifier);
281 }
282 
283 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
284 std::vector<boost::shared_ptr<AbstractCellBasedSimulationModifier<ELEMENT_DIM, SPACE_DIM> > >* AbstractCellBasedSimulation<ELEMENT_DIM,SPACE_DIM>::GetSimulationModifiers()
285 {
286  return &mSimulationModifiers;
287 }
288 
289 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
290 std::vector<double> AbstractCellBasedSimulation<ELEMENT_DIM,SPACE_DIM>::GetNodeLocation(const unsigned& rNodeIndex)
291 {
292  std::vector<double> location;
293  for (unsigned i=0; i<SPACE_DIM; i++)
294  {
295  location.push_back(mrCellPopulation.GetNode(rNodeIndex)->rGetLocation()[i]);
296  }
297  return location;
298 }
299 
300 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
302 {
303  CellBasedEventHandler::BeginEvent(CellBasedEventHandler::EVERYTHING);
304  CellBasedEventHandler::BeginEvent(CellBasedEventHandler::SETUP);
305 
306  // Set up the simulation time
307  SimulationTime* p_simulation_time = SimulationTime::Instance();
308  double current_time = p_simulation_time->GetTime();
309 
310  assert(mDt != DOUBLE_UNSET); //Subclass constructors take care of this
311 
312  if (mEndTime == DOUBLE_UNSET)
313  {
314  EXCEPTION("SetEndTime has not yet been called.");
315  }
316 
317  /*
318  * Note that mDt is used here for "ideal time step". If this step doesn't divide the time remaining
319  * then a *different* time step will be taken by the time-stepper. The real time-step (used in the
320  * SimulationTime singleton) is currently not available to this class.
321  *
322  * \todo Should we over-write the value of mDt, or change this behaviour? (see #2159)
323  */
324  unsigned num_time_steps = (unsigned) ((mEndTime-current_time)/mDt+0.5);
325  if (current_time > 0) // use the reset function if necessary
326  {
327  p_simulation_time->ResetEndTimeAndNumberOfTimeSteps(mEndTime, num_time_steps);
328  }
329  else
330  {
331  if (p_simulation_time->IsEndTimeAndNumberOfTimeStepsSetUp())
332  {
333  EXCEPTION("End time and number of timesteps already setup. You should not use SimulationTime::SetEndTimeAndNumberOfTimeSteps in cell-based tests.");
334  }
335  else
336  {
337  p_simulation_time->SetEndTimeAndNumberOfTimeSteps(mEndTime, num_time_steps);
338  }
339  }
340 
341  if (mOutputDirectory == "")
342  {
343  EXCEPTION("OutputDirectory not set");
344  }
345 
346  double time_now = p_simulation_time->GetTime();
347  std::ostringstream time_string;
348  time_string << time_now;
349 
350  std::string results_directory = mOutputDirectory +"/results_from_time_" + time_string.str();
351  mSimulationOutputDirectory = results_directory;
352 
353  // Set up simulation
354 
355  // Create output files for the visualizer
356  OutputFileHandler output_file_handler(results_directory+"/", true);
357 
358  mrCellPopulation.OpenWritersFiles(output_file_handler);
359 
361  {
362  mpDivisionLocationFile = output_file_handler.OpenOutputFile("divisions.dat");
363  }
365  {
366  OutputFileHandler output_file_handler2(this->mSimulationOutputDirectory+"/", false);
367  mpCellVelocitiesFile = output_file_handler2.OpenOutputFile("cellvelocities.dat");
368  }
369 
370  if (PetscTools::AmMaster())
371  {
372  mpVizSetupFile = output_file_handler.OpenOutputFile("results.vizsetup");
373 
374  for (typename std::vector<boost::shared_ptr<AbstractCellBasedSimulationModifier<ELEMENT_DIM, SPACE_DIM> > >::iterator iter = mSimulationModifiers.begin();
375  iter != mSimulationModifiers.end();
376  ++iter)
377  {
378  if (boost::dynamic_pointer_cast<AbstractPdeModifier<SPACE_DIM> >(*iter))
379  {
380  *this->mpVizSetupFile << "PDE \n";
381  }
382  }
383  }
384 
385  this->mrCellPopulation.SimulationSetupHook(this);
386 
387  SetupSolve();
388 
389  // Call SetupSolve() on each modifier
390  for (typename std::vector<boost::shared_ptr<AbstractCellBasedSimulationModifier<ELEMENT_DIM, SPACE_DIM> > >::iterator iter = mSimulationModifiers.begin();
391  iter != mSimulationModifiers.end();
392  ++iter)
393  {
394  (*iter)->SetupSolve(this->mrCellPopulation,this->mSimulationOutputDirectory);
395  }
396 
397  /*
398  * Age the cells to the correct time. Note that cells are created with
399  * negative birth times so that some are initially almost ready to divide.
400  */
401  LOG(1, "Setting up cells...");
403  cell_iter != mrCellPopulation.End();
404  ++cell_iter)
405  {
406  /*
407  * We don't use the result; this call is just to force the cells to age
408  * to the current time running their cell-cycle models to get there.
409  */
410  cell_iter->ReadyToDivide();
411  }
412  LOG(1, "\tdone\n");
413 
414  // Write initial conditions to file for the visualizer
416 
417  if (PetscTools::AmMaster())
418  {
419  *mpVizSetupFile << std::flush;
420  }
421 
422  mrCellPopulation.WriteResultsToFiles(results_directory+"/");
423 
425  CellBasedEventHandler::EndEvent(CellBasedEventHandler::SETUP);
426 
427  // Enter main time loop
428  while (!( p_simulation_time->IsFinished() || StoppingEventHasOccurred() ) )
429  {
430  LOG(1, "--TIME = " << p_simulation_time->GetTime() << "\n");
431 
432  // This function calls DoCellRemoval(), DoCellBirth() and CellPopulation::Update()
434 
435  // Store whether we are sampling results at the current timestep
437  bool at_sampling_timestep = (p_time->GetTimeStepsElapsed()%this->mSamplingTimestepMultiple == 0);
438 
439  /*
440  * If required, store the current locations of cell centres. Note that we need to
441  * use a std::map between cells and locations, rather than (say) a std::vector with
442  * location indices corresponding to cells, since once we call UpdateCellLocations()
443  * the location index of each cell may change. This is especially true in the case
444  * of a CaBasedCellPopulation.
445  */
446  std::map<CellPtr, c_vector<double, SPACE_DIM> > old_cell_locations;
447  if (mOutputCellVelocities && at_sampling_timestep)
448  {
450  cell_iter != mrCellPopulation.End();
451  ++cell_iter)
452  {
453  old_cell_locations[*cell_iter] = mrCellPopulation.GetLocationOfCellCentre(*cell_iter);
454  }
455  }
456 
457  // Update cell locations and topology
459 
460  // Now write cell velocities to file if required
461  if (mOutputCellVelocities && at_sampling_timestep)
462  {
463  // Offset as doing this before we increase time by mDt
464  *mpCellVelocitiesFile << p_time->GetTime() + mDt<< "\t";
465 
467  cell_iter != mrCellPopulation.End();
468  ++cell_iter)
469  {
470  unsigned index = mrCellPopulation.GetLocationIndexUsingCell(*cell_iter);
471  const c_vector<double,SPACE_DIM>& position = mrCellPopulation.GetLocationOfCellCentre(*cell_iter);
472 
473  c_vector<double, SPACE_DIM> velocity; // Two lines for profile build
474  velocity = (position - old_cell_locations[*cell_iter])/mDt;
475 
476  *mpCellVelocitiesFile << index << " ";
477  for (unsigned i=0; i<SPACE_DIM; i++)
478  {
479  *mpCellVelocitiesFile << position[i] << " ";
480  }
481 
482  for (unsigned i=0; i<SPACE_DIM; i++)
483  {
484  *mpCellVelocitiesFile << velocity[i] << " ";
485  }
486  }
487  *mpCellVelocitiesFile << "\n";
488  }
489 
490  // Update the assignment of cells to processes.
491  mrCellPopulation.UpdateCellProcessLocation();
492 
493  // Increment simulation time here, so results files look sensible
494  p_simulation_time->IncrementTimeOneStep();
495 
496  // Call UpdateAtEndOfTimeStep() on each modifier
497  CellBasedEventHandler::BeginEvent(CellBasedEventHandler::UPDATESIMULATION);
498  for (typename std::vector<boost::shared_ptr<AbstractCellBasedSimulationModifier<ELEMENT_DIM, SPACE_DIM> > >::iterator iter = mSimulationModifiers.begin();
499  iter != mSimulationModifiers.end();
500  ++iter)
501  {
502  (*iter)->UpdateAtEndOfTimeStep(this->mrCellPopulation);
503  }
504  CellBasedEventHandler::EndEvent(CellBasedEventHandler::UPDATESIMULATION);
505 
506  // Output current results to file
507  CellBasedEventHandler::BeginEvent(CellBasedEventHandler::OUTPUT);
508  if (p_simulation_time->GetTimeStepsElapsed()%mSamplingTimestepMultiple == 0)// should be at_sampling_timestep !
509  {
510  mrCellPopulation.WriteResultsToFiles(results_directory+"/");
511 
512  // Call UpdateAtEndOfOutputTimeStep() on each modifier
513  for (typename std::vector<boost::shared_ptr<AbstractCellBasedSimulationModifier<ELEMENT_DIM, SPACE_DIM> > >::iterator iter = mSimulationModifiers.begin();
514  iter != mSimulationModifiers.end();
515  ++iter)
516  {
517  (*iter)->UpdateAtEndOfOutputTimeStep(this->mrCellPopulation);
518  }
519  }
520  CellBasedEventHandler::EndEvent(CellBasedEventHandler::OUTPUT);
521  }
522 
523  LOG(1, "--END TIME = " << p_simulation_time->GetTime() << "\n");
524 
525  /*
526  * Carry out a final update so that cell population is coherent with new cell positions.
527  * Note that cell birth and death still need to be checked because they may be spatially
528  * dependent.
529  */
531 
532  CellBasedEventHandler::BeginEvent(CellBasedEventHandler::UPDATESIMULATION);
533  // Call UpdateAtEndOfSolve(), on each modifier
534  for (typename std::vector<boost::shared_ptr<AbstractCellBasedSimulationModifier<ELEMENT_DIM, SPACE_DIM> > >::iterator iter = mSimulationModifiers.begin();
535  iter != mSimulationModifiers.end();
536  ++iter)
537  {
538  (*iter)->UpdateAtEndOfSolve(this->mrCellPopulation);
539  }
540  CellBasedEventHandler::EndEvent(CellBasedEventHandler::UPDATESIMULATION);
541 
542  CellBasedEventHandler::BeginEvent(CellBasedEventHandler::OUTPUT);
543 
544  mrCellPopulation.CloseWritersFiles();
545 
547  {
548  mpDivisionLocationFile->close();
549  }
551  {
552  mpCellVelocitiesFile->close();
553  }
554 
555  if (PetscTools::AmMaster())
556  {
557  *mpVizSetupFile << "Complete\n";
558  mpVizSetupFile->close();
559  }
560 
561  CellBasedEventHandler::EndEvent(CellBasedEventHandler::OUTPUT);
562  CellBasedEventHandler::EndEvent(CellBasedEventHandler::EVERYTHING);
563 }
564 
565 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
567 {
568  return false;
569 }
570 
571 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
573 {
574  // Remove dead cells
575  CellBasedEventHandler::BeginEvent(CellBasedEventHandler::DEATH);
576  unsigned deaths_this_step = DoCellRemoval();
577  mNumDeaths += deaths_this_step;
578  LOG(1, "\tNum deaths = " << mNumDeaths << "\n");
579  CellBasedEventHandler::EndEvent(CellBasedEventHandler::DEATH);
580 
581  // Divide cells
582  CellBasedEventHandler::BeginEvent(CellBasedEventHandler::BIRTH);
583  unsigned births_this_step = DoCellBirth();
584  mNumBirths += births_this_step;
585  LOG(1, "\tNum births = " << mNumBirths << "\n");
586  CellBasedEventHandler::EndEvent(CellBasedEventHandler::BIRTH);
587 
588  // This allows NodeBasedCellPopulation::Update() to do the minimum amount of work
589  bool births_or_death_occurred = ((births_this_step>0) || (deaths_this_step>0));
590 
591  // Update topology of cell population
592  CellBasedEventHandler::BeginEvent(CellBasedEventHandler::UPDATECELLPOPULATION);
594  {
595  LOG(1, "\tUpdating cell population...");
596  mrCellPopulation.Update(births_or_death_occurred);
597  LOG(1, "\tdone.\n");
598  }
599  else if (births_or_death_occurred)
600  {
601  EXCEPTION("CellPopulation has had births or deaths but mUpdateCellPopulation is set to false, please set it to true.");
602  }
603  CellBasedEventHandler::EndEvent(CellBasedEventHandler::UPDATECELLPOPULATION);
604 }
605 
606 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
608 {
610 }
611 
612 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
614 {
615  mOutputDivisionLocations = outputDivisionLocations;
616 }
617 
618 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
620 {
621  return mOutputCellVelocities;
622 }
623 
624 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
626 {
627  mOutputCellVelocities = outputCellVelocities;
628 }
629 
630 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
632 {
633  OutputFileHandler output_file_handler(this->mSimulationOutputDirectory + "/", false);
634 
635  // Output machine information
638 
639  if (PetscTools::AmMaster())
640  {
641  // Output Chaste provenance information
642  out_stream build_info_file = output_file_handler.OpenOutputFile("build.info");
643  std::string build_info;
645  *build_info_file << build_info;
646  build_info_file->close();
647 
648  // Output simulation parameter and setup details
649  out_stream parameter_file = output_file_handler.OpenOutputFile("results.parameters");
650 
651  // Output simulation details
652  std::string simulation_type = GetIdentifier();
653 
654  *parameter_file << "<Chaste>\n";
655  *parameter_file << "\n\t<" << simulation_type << ">\n";
656  OutputSimulationParameters(parameter_file);
657  *parameter_file << "\t</" << simulation_type << ">\n";
658  *parameter_file << "\n";
659 
660  // Output cell population details (includes cell-cycle model details)
661  mrCellPopulation.OutputCellPopulationInfo(parameter_file);
662 
663  // Loop over cell killers
664  *parameter_file << "\n\t<CellKillers>\n";
665  for (typename std::vector<boost::shared_ptr<AbstractCellKiller<SPACE_DIM> > >::iterator iter = mCellKillers.begin();
666  iter != mCellKillers.end();
667  ++iter)
668  {
669  // Output cell killer details
670  (*iter)->OutputCellKillerInfo(parameter_file);
671  }
672  *parameter_file << "\t</CellKillers>\n";
673 
674  // Iterate over simulationmodifiers
675  *parameter_file << "\n\t<SimulationModifiers>\n";
676  for (typename std::vector<boost::shared_ptr<AbstractCellBasedSimulationModifier<ELEMENT_DIM, SPACE_DIM> > >::iterator iter = mSimulationModifiers.begin();
677  iter != mSimulationModifiers.end();
678  ++iter)
679  {
680  // Output simulation modifier details
681  (*iter)->OutputSimulationModifierInfo(parameter_file);
682  }
683  *parameter_file << "\t</SimulationModifiers>\n";
684 
685  // This is used to output information about subclasses
686  OutputAdditionalSimulationSetup(parameter_file);
687 
688  *parameter_file << "\n</Chaste>\n";
689  parameter_file->close();
690  }
691 }
692 
693 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
695 {
696  *rParamsFile << "\t\t<Dt>" << mDt << "</Dt>\n";
697  *rParamsFile << "\t\t<EndTime>" << mEndTime << "</EndTime>\n";
698  *rParamsFile << "\t\t<SamplingTimestepMultiple>" << mSamplingTimestepMultiple << "</SamplingTimestepMultiple>\n";
699  *rParamsFile << "\t\t<OutputDivisionLocations>" << mOutputDivisionLocations << "</OutputDivisionLocations>\n";
700  *rParamsFile << "\t\t<OutputCellVelocities>" << mOutputCellVelocities << "</OutputCellVelocities>\n";
701 }
702 
703 // Explicit instantiation
704 template class AbstractCellBasedSimulation<1,1>;
705 template class AbstractCellBasedSimulation<1,2>;
706 template class AbstractCellBasedSimulation<2,2>;
707 template class AbstractCellBasedSimulation<1,3>;
708 template class AbstractCellBasedSimulation<2,3>;
709 template class AbstractCellBasedSimulation<3,3>;
void AddCellKiller(boost::shared_ptr< AbstractCellKiller< SPACE_DIM > > pCellKiller)
bool IsEndTimeAndNumberOfTimeStepsSetUp() const
#define EXCEPTION(message)
Definition: Exception.hpp:143
static SimulationTime * Instance()
bool IsFinished() const
AbstractCellBasedSimulation(AbstractCellPopulation< ELEMENT_DIM, SPACE_DIM > &rCellPopulation, bool deleteCellPopulationInDestructor=false, bool initialiseCells=true)
static bool AmMaster()
Definition: PetscTools.cpp:120
AbstractCellPopulation< ELEMENT_DIM, SPACE_DIM > & rGetCellPopulation()
unsigned GetTimeStepsElapsed() const
void SetOutputCellVelocities(bool outputCellVelocities)
std::string GetOutputDirectoryFullPath() const
const double DOUBLE_UNSET
Definition: Exception.hpp:56
virtual void OutputAdditionalSimulationSetup(out_stream &rParamsFile)=0
void SetUpdateCellPopulationRule(bool updateCellPopulation)
out_stream OpenOutputFile(const std::string &rFileName, std::ios_base::openmode mode=std::ios::out|std::ios::trunc) const
std::vector< boost::shared_ptr< AbstractCellKiller< SPACE_DIM > > > mCellKillers
void SetOutputDivisionLocations(bool outputDivisionLocations)
virtual void OutputSimulationParameters(out_stream &rParamsFile)=0
virtual void UpdateCellLocationsAndTopology()=0
void SetOutputDirectory(std::string outputDirectory)
void SetEndTimeAndNumberOfTimeSteps(double endTime, unsigned totalTimeStepsInSimulation)
static RandomNumberGenerator * Instance()
double GetTime() const
std::vector< double > GetNodeLocation(const unsigned &rNodeIndex)
void AddSimulationModifier(boost::shared_ptr< AbstractCellBasedSimulationModifier< ELEMENT_DIM, SPACE_DIM > > pSimulationModifier)
static void GetBuildInfo(std::string &rInfo)
std::string GetIdentifier() const
virtual double GetDefaultTimeStep()=0
std::vector< boost::shared_ptr< AbstractCellBasedSimulationModifier< ELEMENT_DIM, SPACE_DIM > > > mSimulationModifiers
void IncrementTimeOneStep()
static void WriteMachineInfoFile(std::string fileBaseName)
std::vector< boost::shared_ptr< AbstractCellBasedSimulationModifier< ELEMENT_DIM, SPACE_DIM > > > * GetSimulationModifiers()
void ResetEndTimeAndNumberOfTimeSteps(const double &rEndTime, const unsigned &rNumberOfTimeStepsInThisRun)
static void SetOutputDirectory(const std::string &rOutputDirectory)
void SetSamplingTimestepMultiple(unsigned samplingTimestepMultiple)
AbstractCellPopulation< ELEMENT_DIM, SPACE_DIM > & mrCellPopulation