AbstractCellBasedSimulation.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029 #include <cmath>
00030 #include <ctime>
00031 #include <iostream>
00032 #include <fstream>
00033 #include <set>
00034
00035 #include "AbstractCellBasedSimulation.hpp"
00036 #include "CellBasedEventHandler.hpp"
00037 #include "LogFile.hpp"
00038 #include "Version.hpp"
00039 #include "ExecutableSupport.hpp"
00040 #include "Exception.hpp"
00041
00042 #include <typeinfo>
00043
00044 template<unsigned DIM>
00045 AbstractCellBasedSimulation<DIM>::AbstractCellBasedSimulation(AbstractCellPopulation<DIM>& rCellPopulation,
00046 bool deleteCellPopulationInDestructor,
00047 bool initialiseCells)
00048 : mDt(DOUBLE_UNSET),
00049 mEndTime(0.0),
00050 mrCellPopulation(rCellPopulation),
00051 mDeleteCellPopulationInDestructor(deleteCellPopulationInDestructor),
00052 mInitialiseCells(initialiseCells),
00053 mNoBirth(false),
00054 mUpdateCellPopulation(true),
00055 mOutputDirectory(""),
00056 mSimulationOutputDirectory(mOutputDirectory),
00057 mNumBirths(0),
00058 mNumDeaths(0),
00059 mSamplingTimestepMultiple(1),
00060 mpCellBasedPdeHandler(NULL)
00061 {
00062
00063 RandomNumberGenerator::Instance();
00064
00065 if (mInitialiseCells)
00066 {
00067 mrCellPopulation.InitialiseCells();
00068 }
00069 }
00070
00071 template<unsigned DIM>
00072 AbstractCellBasedSimulation<DIM>::~AbstractCellBasedSimulation()
00073 {
00074 if (mDeleteCellPopulationInDestructor)
00075 {
00076 delete &mrCellPopulation;
00077 delete mpCellBasedPdeHandler;
00078 }
00079 }
00080
00081 template<unsigned DIM>
00082 void AbstractCellBasedSimulation<DIM>::SetCellBasedPdeHandler(CellBasedPdeHandler<DIM>* pCellBasedPdeHandler)
00083 {
00084 mpCellBasedPdeHandler = pCellBasedPdeHandler;
00085 }
00086
00087 template<unsigned DIM>
00088 CellBasedPdeHandler<DIM>* AbstractCellBasedSimulation<DIM>::GetCellBasedPdeHandler()
00089 {
00090 return mpCellBasedPdeHandler;
00091 }
00092
00093 template<unsigned DIM>
00094 unsigned AbstractCellBasedSimulation<DIM>::DoCellBirth()
00095 {
00096 if (mNoBirth)
00097 {
00098 return 0;
00099 }
00100
00101 unsigned num_births_this_step = 0;
00102
00103
00104 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = mrCellPopulation.Begin();
00105 cell_iter != mrCellPopulation.End();
00106 ++cell_iter)
00107 {
00108
00109 if (cell_iter->GetAge() > 0.0)
00110 {
00111 if (cell_iter->ReadyToDivide())
00112 {
00113
00114 CellPtr p_new_cell = cell_iter->Divide();
00115
00116
00117 c_vector<double, DIM> new_location = CalculateCellDivisionVector(*cell_iter);
00118
00119
00120 mrCellPopulation.AddCell(p_new_cell, new_location, *cell_iter);
00121
00122
00123 num_births_this_step++;
00124 }
00125 }
00126 }
00127 return num_births_this_step;
00128 }
00129
00130 template<unsigned DIM>
00131 unsigned AbstractCellBasedSimulation<DIM>::DoCellRemoval()
00132 {
00133 unsigned num_deaths_this_step = 0;
00134
00135
00136
00137
00138
00139 for (typename std::vector<boost::shared_ptr<AbstractCellKiller<DIM> > >::iterator killer_iter = mCellKillers.begin();
00140 killer_iter != mCellKillers.end();
00141 ++killer_iter)
00142 {
00143 (*killer_iter)->TestAndLabelCellsForApoptosisOrDeath();
00144 }
00145
00146 num_deaths_this_step += mrCellPopulation.RemoveDeadCells();
00147
00148 return num_deaths_this_step;
00149 }
00150
00151 template<unsigned DIM>
00152 void AbstractCellBasedSimulation<DIM>::SetDt(double dt)
00153 {
00154 assert(dt > 0);
00155 mDt = dt;
00156 }
00157
00158 template<unsigned DIM>
00159 double AbstractCellBasedSimulation<DIM>::GetDt()
00160 {
00161 return mDt;
00162 }
00163
00164 template<unsigned DIM>
00165 unsigned AbstractCellBasedSimulation<DIM>::GetNumBirths()
00166 {
00167 return mNumBirths;
00168 }
00169
00170 template<unsigned DIM>
00171 unsigned AbstractCellBasedSimulation<DIM>::GetNumDeaths()
00172 {
00173 return mNumDeaths;
00174 }
00175
00176 template<unsigned DIM>
00177 void AbstractCellBasedSimulation<DIM>::SetEndTime(double endTime)
00178 {
00179 assert(endTime > 0);
00180 mEndTime = endTime;
00181 }
00182
00183 template<unsigned DIM>
00184 void AbstractCellBasedSimulation<DIM>::SetOutputDirectory(std::string outputDirectory)
00185 {
00186 mOutputDirectory = outputDirectory;
00187 mSimulationOutputDirectory = mOutputDirectory;
00188 }
00189
00190 template<unsigned DIM>
00191 std::string AbstractCellBasedSimulation<DIM>::GetOutputDirectory()
00192 {
00193 return mOutputDirectory;
00194 }
00195
00196 template<unsigned DIM>
00197 void AbstractCellBasedSimulation<DIM>::SetSamplingTimestepMultiple(unsigned samplingTimestepMultiple)
00198 {
00199 assert(samplingTimestepMultiple > 0);
00200 mSamplingTimestepMultiple = samplingTimestepMultiple;
00201 }
00202
00203 template<unsigned DIM>
00204 AbstractCellPopulation<DIM>& AbstractCellBasedSimulation<DIM>::rGetCellPopulation()
00205 {
00206 return mrCellPopulation;
00207 }
00208
00209 template<unsigned DIM>
00210 const AbstractCellPopulation<DIM>& AbstractCellBasedSimulation<DIM>::rGetCellPopulation() const
00211 {
00212 return mrCellPopulation;
00213 }
00214
00215 template<unsigned DIM>
00216 void AbstractCellBasedSimulation<DIM>::SetUpdateCellPopulationRule(bool updateCellPopulation)
00217 {
00218 mUpdateCellPopulation = updateCellPopulation;
00219 }
00220
00221 template<unsigned DIM>
00222 void AbstractCellBasedSimulation<DIM>::SetNoBirth(bool noBirth)
00223 {
00224 mNoBirth = noBirth;
00225 }
00226
00227 template<unsigned DIM>
00228 void AbstractCellBasedSimulation<DIM>::AddCellKiller(boost::shared_ptr<AbstractCellKiller<DIM> > pCellKiller)
00229 {
00230 mCellKillers.push_back(pCellKiller);
00231 }
00232
00233 template<unsigned DIM>
00234 std::vector<double> AbstractCellBasedSimulation<DIM>::GetNodeLocation(const unsigned& rNodeIndex)
00235 {
00236 std::vector<double> location;
00237 for (unsigned i=0; i<DIM; i++)
00238 {
00239 location.push_back(mrCellPopulation.GetNode(rNodeIndex)->rGetLocation()[i]);
00240 }
00241 return location;
00242 }
00243
00244 template<unsigned DIM>
00245 void AbstractCellBasedSimulation<DIM>::SetupSolve()
00246 {
00247 if (mpCellBasedPdeHandler != NULL)
00248 {
00249 mpCellBasedPdeHandler->OpenResultsFiles(this->mSimulationOutputDirectory);
00250 *this->mpVizSetupFile << "PDE \n";
00251 }
00252 }
00253
00254 template<unsigned DIM>
00255 void AbstractCellBasedSimulation<DIM>::PostSolve()
00256 {
00257 if (mpCellBasedPdeHandler != NULL)
00258 {
00259 CellBasedEventHandler::BeginEvent(CellBasedEventHandler::PDE);
00260 mpCellBasedPdeHandler->SolvePdeAndWriteResultsToFile(this->mSamplingTimestepMultiple);
00261 CellBasedEventHandler::EndEvent(CellBasedEventHandler::PDE);
00262 }
00263 }
00264
00265 template<unsigned DIM>
00266 void AbstractCellBasedSimulation<DIM>::AfterSolve()
00267 {
00268 if (mpCellBasedPdeHandler != NULL)
00269 {
00270 mpCellBasedPdeHandler->CloseResultsFiles();
00271 }
00272 }
00273
00274 template<unsigned DIM>
00275 void AbstractCellBasedSimulation<DIM>::Solve()
00276 {
00277 CellBasedEventHandler::BeginEvent(CellBasedEventHandler::EVERYTHING);
00278 CellBasedEventHandler::BeginEvent(CellBasedEventHandler::SETUP);
00279
00280
00281 SimulationTime* p_simulation_time = SimulationTime::Instance();
00282 double current_time = p_simulation_time->GetTime();
00283
00284 unsigned num_time_steps = (unsigned) ((mEndTime-current_time)/mDt+0.5);
00285
00286 if (current_time > 0)
00287 {
00288 p_simulation_time->ResetEndTimeAndNumberOfTimeSteps(mEndTime, num_time_steps);
00289 }
00290 else
00291 {
00292 if(p_simulation_time->IsEndTimeAndNumberOfTimeStepsSetUp())
00293 {
00294 EXCEPTION("End time and number of timesteps already setup. You should not use SimulationTime::SetEndTimeAndNumberOfTimeSteps in cell-based tests.");
00295 }
00296 else
00297 {
00298 p_simulation_time->SetEndTimeAndNumberOfTimeSteps(mEndTime, num_time_steps);
00299 }
00300
00301 }
00302
00303 if (mOutputDirectory=="")
00304 {
00305 EXCEPTION("OutputDirectory not set");
00306 }
00307
00308 double time_now = p_simulation_time->GetTime();
00309 std::ostringstream time_string;
00310 time_string << time_now;
00311
00312 std::string results_directory = mOutputDirectory +"/results_from_time_" + time_string.str();
00313 mSimulationOutputDirectory = results_directory;
00314
00315
00316
00317
00318 OutputFileHandler output_file_handler(results_directory+"/", true);
00319
00320 mrCellPopulation.CreateOutputFiles(results_directory+"/", false);
00321
00322 mpVizSetupFile = output_file_handler.OpenOutputFile("results.vizsetup");
00323
00324 SetupSolve();
00325
00326
00327
00328 LOG(1, "Setting up cells...");
00329 for (typename AbstractCellPopulation<DIM>::Iterator cell_iter = mrCellPopulation.Begin();
00330 cell_iter != mrCellPopulation.End();
00331 ++cell_iter)
00332 {
00333
00334
00335 cell_iter->ReadyToDivide();
00336 }
00337 LOG(1, "\tdone\n");
00338
00339
00340 WriteVisualizerSetupFile();
00341
00342 *mpVizSetupFile << std::flush;
00343
00344 mrCellPopulation.WriteResultsToFiles();
00345
00346 OutputSimulationSetup();
00347
00348 CellBasedEventHandler::EndEvent(CellBasedEventHandler::SETUP);
00349
00350
00351 while (!( p_simulation_time->IsFinished() || StoppingEventHasOccurred() ) )
00352 {
00353 LOG(1, "--TIME = " << p_simulation_time->GetTime() << "\n");
00354
00355
00356 UpdateCellPopulation();
00357
00358
00359 UpdateCellLocationsAndTopology();
00360
00361
00362 PostSolve();
00363
00364
00365 p_simulation_time->IncrementTimeOneStep();
00366
00367
00368 CellBasedEventHandler::BeginEvent(CellBasedEventHandler::OUTPUT);
00369 if (p_simulation_time->GetTimeStepsElapsed()%mSamplingTimestepMultiple == 0)
00370 {
00371 mrCellPopulation.WriteResultsToFiles();
00372 }
00373 CellBasedEventHandler::EndEvent(CellBasedEventHandler::OUTPUT);
00374 }
00375
00376 LOG(1, "--END TIME = " << p_simulation_time->GetTime() << "\n");
00377
00378
00379
00380 UpdateCellPopulation();
00381
00382 AfterSolve();
00383
00384 CellBasedEventHandler::BeginEvent(CellBasedEventHandler::OUTPUT);
00385
00386 mrCellPopulation.CloseOutputFiles();
00387
00388 *mpVizSetupFile << "Complete\n";
00389 mpVizSetupFile->close();
00390
00391 CellBasedEventHandler::EndEvent(CellBasedEventHandler::OUTPUT);
00392 CellBasedEventHandler::EndEvent(CellBasedEventHandler::EVERYTHING);
00393 }
00394
00395 template<unsigned DIM>
00396 bool AbstractCellBasedSimulation<DIM>::StoppingEventHasOccurred()
00397 {
00398 return false;
00399 }
00400
00401 template<unsigned DIM>
00402 void AbstractCellBasedSimulation<DIM>::UpdateCellPopulation()
00403 {
00404
00405 CellBasedEventHandler::BeginEvent(CellBasedEventHandler::DEATH);
00406 unsigned deaths_this_step = DoCellRemoval();
00407 mNumDeaths += deaths_this_step;
00408 LOG(1, "\tNum deaths = " << mNumDeaths << "\n");
00409 CellBasedEventHandler::EndEvent(CellBasedEventHandler::DEATH);
00410
00411
00412 CellBasedEventHandler::BeginEvent(CellBasedEventHandler::BIRTH);
00413 unsigned births_this_step = DoCellBirth();
00414 mNumBirths += births_this_step;
00415 LOG(1, "\tNum births = " << mNumBirths << "\n");
00416 CellBasedEventHandler::EndEvent(CellBasedEventHandler::BIRTH);
00417
00418
00419 bool births_or_death_occurred = ((births_this_step>0) || (deaths_this_step>0));
00420
00421
00422 CellBasedEventHandler::BeginEvent(CellBasedEventHandler::UPDATECELLPOPULATION);
00423 if (mUpdateCellPopulation)
00424 {
00425 LOG(1, "\tUpdating cell population...");
00426 mrCellPopulation.Update(births_or_death_occurred);
00427 LOG(1, "\tdone.\n");
00428 }
00429 else if (births_or_death_occurred)
00430 {
00431 EXCEPTION("CellPopulation has had births or deaths but mUpdateCellPopulation is set to false, please set it to true.");
00432 }
00433 CellBasedEventHandler::EndEvent(CellBasedEventHandler::UPDATECELLPOPULATION);
00434 }
00435
00436 template<unsigned DIM>
00437 void AbstractCellBasedSimulation<DIM>::OutputSimulationSetup()
00438 {
00439 OutputFileHandler output_file_handler(this->mSimulationOutputDirectory + "/", false);
00440
00441
00442 ExecutableSupport::WriteMachineInfoFile(this->mSimulationOutputDirectory + "/system_info");
00443
00444
00445 out_stream build_info_file = output_file_handler.OpenOutputFile("build.info");
00446 ExecutableSupport::WriteLibraryInfo(build_info_file);
00447 build_info_file->close();
00448
00449
00450 out_stream parameter_file = output_file_handler.OpenOutputFile("results.parameters");
00451
00452
00453 std::string simulation_type = GetIdentifier();
00454
00455 *parameter_file << "<Chaste>\n";
00456 *parameter_file << "\n\t<" << simulation_type << ">\n";
00457 OutputSimulationParameters(parameter_file);
00458 *parameter_file << "\t</" << simulation_type << ">\n";
00459 *parameter_file << "\n";
00460
00461
00462 mrCellPopulation.OutputCellPopulationInfo(parameter_file);
00463
00464
00465 *parameter_file << "\n\t<CellKillers>\n";
00466 for (typename std::vector<boost::shared_ptr<AbstractCellKiller<DIM> > >::iterator iter = mCellKillers.begin();
00467 iter != mCellKillers.end();
00468 ++iter)
00469 {
00470
00471 (*iter)->OutputCellKillerInfo(parameter_file);
00472 }
00473 *parameter_file << "\t</CellKillers>\n";
00474
00475
00476 OutputAdditionalSimulationSetup(parameter_file);
00477
00478 *parameter_file << "\n</Chaste>\n";
00479 parameter_file->close();
00480 }
00481
00482 template<unsigned DIM>
00483 void AbstractCellBasedSimulation<DIM>::OutputSimulationParameters(out_stream& rParamsFile)
00484 {
00485 if (mpCellBasedPdeHandler != NULL)
00486 {
00487 mpCellBasedPdeHandler->OutputParameters(rParamsFile);
00488 }
00489
00490 *rParamsFile << "\t\t<Dt>" << mDt << "</Dt>\n";
00491 *rParamsFile << "\t\t<EndTime>" << mEndTime << "</EndTime>\n";
00492 *rParamsFile << "\t\t<SamplingTimestepMultiple>" << mSamplingTimestepMultiple << "</SamplingTimestepMultiple>\n";
00493 }
00494
00496
00498
00499 template class AbstractCellBasedSimulation<1>;
00500 template class AbstractCellBasedSimulation<2>;
00501 template class AbstractCellBasedSimulation<3>;