void AbstractCellBasedSimulation<ELEMENT_DIM,SPACE_DIM>::Solve()
{
    CellBasedEventHandler::BeginEvent(CellBasedEventHandler::EVERYTHING);
    CellBasedEventHandler::BeginEvent(CellBasedEventHandler::SETUP);

    // Set up the simulation time
    SimulationTime* p_simulation_time = SimulationTime::Instance();
    double current_time = p_simulation_time->GetTime();

    assert(mDt != DOUBLE_UNSET);  //Subclass constructors take care of this

    if (mEndTime == DOUBLE_UNSET)
    {
        EXCEPTION("SetEndTime has not yet been called.");
    }

    /*
     * Note that mDt is used here for "ideal time step". If this step doesn't divide the time remaining
     * then a *different* time step will be taken by the time-stepper. The real time-step (used in the
     * SimulationTime singleton) is currently not available to this class.
     *
     * \todo Should we over-write the value of mDt, or change this behaviour? (see #2159)
     */
    unsigned num_time_steps = (unsigned) ((mEndTime-current_time)/mDt+0.5);
    if (current_time > 0) // use the reset function if necessary
    {
        p_simulation_time->ResetEndTimeAndNumberOfTimeSteps(mEndTime, num_time_steps);
    }
    else
    {
        if (p_simulation_time->IsEndTimeAndNumberOfTimeStepsSetUp())
        {
            EXCEPTION("End time and number of timesteps already setup. You should not use SimulationTime::SetEndTimeAndNumberOfTimeSteps in cell-based tests.");
        }
        else
        {
            p_simulation_time->SetEndTimeAndNumberOfTimeSteps(mEndTime, num_time_steps);
        }
    }

    if (mOutputDirectory == "")
    {
        EXCEPTION("OutputDirectory not set");
    }

    double time_now = p_simulation_time->GetTime();
    std::ostringstream time_string;
    time_string << time_now;

    std::string results_directory = mOutputDirectory +"/results_from_time_" + time_string.str();
    mSimulationOutputDirectory = results_directory;

    // Set up simulation

    // Create output files for the visualizer
    OutputFileHandler output_file_handler(results_directory+"/", true);

    mrCellPopulation.OpenWritersFiles(results_directory+"/");

    if (mOutputDivisionLocations)
    {
        mpDivisionLocationFile = output_file_handler.OpenOutputFile("divisions.dat");
    }

    if (PetscTools::AmMaster())
    {
        mpVizSetupFile = output_file_handler.OpenOutputFile("results.vizsetup");
    }

    // If any PDEs have been defined, set up results files to store their solution
    if (mpCellBasedPdeHandler != NULL)
    {
        mpCellBasedPdeHandler->OpenResultsFiles(this->mSimulationOutputDirectory);
        if (PetscTools::AmMaster())
        {
            *this->mpVizSetupFile << "PDE \n";
        }

        /*
         * If any PDEs have been defined, solve them here before updating cells and store
         * their solution in results files. This also initializes the relevant CellData.
         * NOTE that this works as the PDEs are elliptic.
         */
        CellBasedEventHandler::BeginEvent(CellBasedEventHandler::PDE);
        mpCellBasedPdeHandler->SolvePdeAndWriteResultsToFile(this->mSamplingTimestepMultiple);
        CellBasedEventHandler::EndEvent(CellBasedEventHandler::PDE);
    }

    SetupSolve();

    // Call SetupSolve() on each modifier
    for (typename std::vector<boost::shared_ptr<AbstractCellBasedSimulationModifier<ELEMENT_DIM, SPACE_DIM> > >::iterator iter = mSimulationModifiers.begin();
         iter != mSimulationModifiers.end();
         ++iter)
    {
        (*iter)->SetupSolve(this->mrCellPopulation,this->mSimulationOutputDirectory);
    }

    /*
     * Age the cells to the correct time. Note that cells are created with
     * negative birth times so that some are initially almost ready to divide.
     */
    LOG(1, "Setting up cells...");
    for (typename AbstractCellPopulation<ELEMENT_DIM,SPACE_DIM>::Iterator cell_iter = mrCellPopulation.Begin();
         cell_iter != mrCellPopulation.End();
         ++cell_iter)
    {
        /*
         * We don't use the result; this call is just to force the cells to age
         * to the current time running their cell-cycle models to get there.
         */
        cell_iter->ReadyToDivide();
    }
    LOG(1, "\tdone\n");

    // Write initial conditions to file for the visualizer
    WriteVisualizerSetupFile();

    if (PetscTools::AmMaster())
    {
        *mpVizSetupFile << std::flush;
    }

    mrCellPopulation.WriteResultsToFiles(results_directory+"/");

    OutputSimulationSetup();
    CellBasedEventHandler::EndEvent(CellBasedEventHandler::SETUP);

    // Enter main time loop
    while (!( p_simulation_time->IsFinished() || StoppingEventHasOccurred() ) )
    {
        LOG(1, "--TIME = " << p_simulation_time->GetTime() << "\n");

        // This function calls DoCellRemoval(), DoCellBirth() and CellPopulation::Update()
        UpdateCellPopulation();

        // Update cell locations and topology
        UpdateCellLocationsAndTopology();

        // Update the assignment of cells to processes.
        mrCellPopulation.UpdateCellProcessLocation();

        // Increment simulation time here, so results files look sensible
        p_simulation_time->IncrementTimeOneStep();

        // If any PDEs have been defined, solve them and store their solution in results files
        if (mpCellBasedPdeHandler != NULL)
        {
            CellBasedEventHandler::BeginEvent(CellBasedEventHandler::PDE);
            mpCellBasedPdeHandler->SolvePdeAndWriteResultsToFile(this->mSamplingTimestepMultiple);
            CellBasedEventHandler::EndEvent(CellBasedEventHandler::PDE);
        }

        // Call UpdateAtEndOfTimeStep(), which may be implemented by child classes
        CellBasedEventHandler::BeginEvent(CellBasedEventHandler::UPDATESIMULATION);
        UpdateAtEndOfTimeStep();

        // Call UpdateAtEndOfTimeStep() on each modifier
        for (typename std::vector<boost::shared_ptr<AbstractCellBasedSimulationModifier<ELEMENT_DIM, SPACE_DIM> > >::iterator iter = mSimulationModifiers.begin();
             iter != mSimulationModifiers.end();
             ++iter)
        {
            (*iter)->UpdateAtEndOfTimeStep(this->mrCellPopulation);
        }
        CellBasedEventHandler::EndEvent(CellBasedEventHandler::UPDATESIMULATION);

        // Output current results to file
        CellBasedEventHandler::BeginEvent(CellBasedEventHandler::OUTPUT);
        if (p_simulation_time->GetTimeStepsElapsed()%mSamplingTimestepMultiple == 0)
        {
            mrCellPopulation.WriteResultsToFiles(results_directory+"/");

            // Call UpdateAtEndOfOutputTimeStep() on each modifier
            for (typename std::vector<boost::shared_ptr<AbstractCellBasedSimulationModifier<ELEMENT_DIM, SPACE_DIM> > >::iterator iter = mSimulationModifiers.begin();
                 iter != mSimulationModifiers.end();
                 ++iter)
            {
                (*iter)->UpdateAtEndOfOutputTimeStep(this->mrCellPopulation);
            }
        }
        CellBasedEventHandler::EndEvent(CellBasedEventHandler::OUTPUT);
    }

    LOG(1, "--END TIME = " << p_simulation_time->GetTime() << "\n");

    /*
     * Carry out a final update so that cell population is coherent with new cell positions.
     * Note that cell birth and death still need to be checked because they may be spatially
     * dependent.
     */
    UpdateCellPopulation();

    // If any PDEs have been defined, close the results files storing their solution
    if (mpCellBasedPdeHandler != NULL)
    {
        mpCellBasedPdeHandler->CloseResultsFiles();
    }

    CellBasedEventHandler::BeginEvent(CellBasedEventHandler::UPDATESIMULATION);
    UpdateAtEndOfSolve();

    // Call UpdateAtEndOfSolve(), on each modifier
    for (typename std::vector<boost::shared_ptr<AbstractCellBasedSimulationModifier<ELEMENT_DIM, SPACE_DIM> > >::iterator iter = mSimulationModifiers.begin();
         iter != mSimulationModifiers.end();
         ++iter)
    {
        (*iter)->UpdateAtEndOfSolve(this->mrCellPopulation);
    }
    CellBasedEventHandler::EndEvent(CellBasedEventHandler::UPDATESIMULATION);

    CellBasedEventHandler::BeginEvent(CellBasedEventHandler::OUTPUT);

    mrCellPopulation.CloseOutputFiles();

    if (mOutputDivisionLocations)
    {
        mpDivisionLocationFile->close();
    }

    if (PetscTools::AmMaster())
    {
        *mpVizSetupFile << "Complete\n";
        mpVizSetupFile->close();
    }

    CellBasedEventHandler::EndEvent(CellBasedEventHandler::OUTPUT);
    CellBasedEventHandler::EndEvent(CellBasedEventHandler::EVERYTHING);
}
unsigned AbstractCellBasedSimulation<ELEMENT_DIM,SPACE_DIM>::DoCellBirth()
{
    if (mNoBirth)
    {
        return 0;
    }

    unsigned num_births_this_step = 0;

    // Iterate over all cells, seeing if each one can be divided
    for (typename AbstractCellPopulation<ELEMENT_DIM,SPACE_DIM>::Iterator cell_iter = mrCellPopulation.Begin();
         cell_iter != mrCellPopulation.End();
         ++cell_iter)
    {
        // Check if this cell is ready to divide
        double cell_age = cell_iter->GetAge();
        if (cell_age > 0.0)
        {
            if (cell_iter->ReadyToDivide())
            {
                // Check if there is room into which the cell may divide
                if (mrCellPopulation.IsRoomToDivide(*cell_iter))
                {
                    // Create a new cell
                    CellPtr p_new_cell = cell_iter->Divide();

                    // Call method that determines how cell division occurs and returns a vector
                    c_vector<double, SPACE_DIM> new_location = CalculateCellDivisionVector(*cell_iter);

                    // If required, output this location to file
                    /**
                     * \todo (#2441)
                     *
                     * For consistency with the rest of the output code, consider removing the
                     * AbstractCellBasedSimulation member mOutputDivisionLocations, adding a new
                     * member mAgesAndLocationsOfDividingCells to AbstractCellPopulation, adding
                     * a new class CellDivisionLocationsWriter to the CellPopulationWriter hierarchy
                     * to output the content of mAgesAndLocationsOfDividingCells to file (remembering
                     * to clear mAgesAndLocationsOfDividingCells at each timestep), and replacing the
                     * following conditional statement with something like
                     *
                     * if (mrCellPopulation.HasWriter<CellDivisionLocationsWriter>())
                     * {
                     *     mCellDivisionLocations.push_back(new_location);
                     * }
                     */
                    if (mOutputDivisionLocations)
                    {
                        *mpDivisionLocationFile << SimulationTime::Instance()->GetTime() << "\t";
                        for (unsigned i=0; i<SPACE_DIM; i++)
                        {
                            *mpDivisionLocationFile << new_location[i] << "\t";
                        }
                        *mpDivisionLocationFile << "\t" << cell_age << "\n";
                    }

                    // Add new cell to the cell population
                    mrCellPopulation.AddCell(p_new_cell, new_location, *cell_iter);

                    // Update counter
                    num_births_this_step++;
                }
            }
        }
    }
    return num_births_this_step;
}