void TestGenerateBasicRandomWithFixedDurationGenerationBasedCellCycleModelandVertexCells() throw(Exception)
    {
        EXIT_IF_PARALLEL;
        // Create mesh
        HoneycombVertexMeshGenerator mesh_generator(2, 2);
        VertexMesh<2,2>* p_mesh = mesh_generator.GetMesh();

        // Create cells
        std::vector<CellPtr> cells;
        MAKE_PTR(TransitCellProliferativeType, p_transit_type);
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, p_mesh->GetNumElements(), p_transit_type);

        // Test that cells were generated correctly
        TS_ASSERT_EQUALS(cells.size(), p_mesh->GetNumElements());

        for (unsigned i=0; i<cells.size(); i++)
        {
            // Shold lie between -24 and 0
            TS_ASSERT_LESS_THAN_EQUALS(cells[i]->GetBirthTime(), 0.0);
            TS_ASSERT_LESS_THAN_EQUALS(-24.0, cells[i]->GetBirthTime());
            TS_ASSERT_EQUALS(cells[i]->GetCellCycleModel()->GetDimension(), 2u);
            TS_ASSERT_EQUALS(cells[i]->GetCellProliferativeType(), p_transit_type);
        }

        // Test exact random numbers as test re-seeds random number generator.
        TS_ASSERT_DELTA(cells[0]->GetBirthTime(), -7.1141, 1e-4);
        TS_ASSERT_DELTA(cells[1]->GetBirthTime(), -10.1311, 1e-4);
        TS_ASSERT_DELTA(cells[2]->GetBirthTime(), -10.2953, 1e-4);
    }
    void TestCryptCellsGeneratorWithStochasticWntCellCycleModel() throw(Exception)
    {
        // Create mesh
        HoneycombMeshGenerator mesh_generator(5, 10, 0);
        TetrahedralMesh<2,2>* p_mesh = mesh_generator.GetMesh();

        // Get location indices corresponding to real cells
        std::vector<unsigned> location_indices = mesh_generator.GetCellLocationIndices();

        // Create cells
        std::vector<CellPtr> cells;
        CryptCellsGenerator<StochasticWntCellCycleModel> generator;
        generator.Generate(cells, p_mesh, location_indices, false);

        // Test that cells were generated correctly
        TS_ASSERT_EQUALS(cells.size(), p_mesh->GetNumNodes());

        for (unsigned i=0; i<cells.size(); i++)
        {
            TS_ASSERT_DELTA(cells[i]->GetBirthTime(), 0.0, 1e-9);
        }

        // Create cells again with basic
        std::vector<CellPtr> new_cells;
        generator.GenerateBasic(new_cells, p_mesh->GetNumNodes());
        // Test that cells were generated correctly
        TS_ASSERT_EQUALS(new_cells.size(), p_mesh->GetNumNodes());

        for (unsigned i=0; i<new_cells.size(); i++)
        {
            TS_ASSERT_DELTA(new_cells[i]->GetBirthTime(), -(double)(i), 1e-9);
        }
    }
    void TestCryptCellsGeneratorWithUniformlyDistributedGenerationBasedCellCycleModelAndVertexMesh() throw(Exception)
      {
          // Create mesh
          unsigned crypt_width = 4;
          unsigned crypt_height = 6;
          CylindricalHoneycombVertexMeshGenerator mesh_generator(crypt_width, crypt_height);
          Cylindrical2dVertexMesh* p_mesh = mesh_generator.GetCylindricalMesh();

          double y0 = 1.0;
          double y1 = 2.0;
          double y2 = 3.0;
          double y3 = 4.0;

          // Create cells
          std::vector<CellPtr> fixed_cells, stochastic_cells;
          CryptCellsGenerator<FixedDurationGenerationBasedCellCycleModel> fixed_cells_generator;
          fixed_cells_generator.Generate(fixed_cells, p_mesh, std::vector<unsigned>(), true, y0, y1, y2, y3, true);

          CryptCellsGenerator<UniformlyDistributedGenerationBasedCellCycleModel> stochastic_cells_generator;
          stochastic_cells_generator.Generate(stochastic_cells, p_mesh, std::vector<unsigned>(), true, y0, y1, y2, y3, true);

          TS_ASSERT_EQUALS(fixed_cells.size(), p_mesh->GetNumElements());
          TS_ASSERT_EQUALS(stochastic_cells.size(), p_mesh->GetNumElements());

          // Test that cells were generated correctly
          for (unsigned i=0; i<fixed_cells.size(); i++)
          {
              double height = p_mesh->GetCentroidOfElement(i)[1];
              unsigned fixed_generation = static_cast<FixedDurationGenerationBasedCellCycleModel*>(fixed_cells[i]->GetCellCycleModel())->GetGeneration();
              unsigned stochastic_generation = static_cast<UniformlyDistributedGenerationBasedCellCycleModel*>(stochastic_cells[i]->GetCellCycleModel())->GetGeneration();

              if (height <= y0)
              {
                  TS_ASSERT_EQUALS(fixed_generation, 0u);
                  TS_ASSERT_EQUALS(stochastic_generation, 0u);
              }
              else if (height < y1)
              {
                  TS_ASSERT_EQUALS(fixed_generation, 1u);
                  TS_ASSERT_EQUALS(stochastic_generation, 1u);
              }
              else if (height < y2)
              {
                  TS_ASSERT_EQUALS(fixed_generation, 2u);
                  TS_ASSERT_EQUALS(stochastic_generation, 2u);
              }
              else if (height < y3)
              {
                  TS_ASSERT_EQUALS(fixed_generation, 3u);
                  TS_ASSERT_EQUALS(stochastic_generation, 3u);
              }
              else
              {
                  TS_ASSERT_EQUALS(fixed_generation, 4u);
                  TS_ASSERT_EQUALS(stochastic_generation, 4u);
              }
          }
      }
    void TestCryptCellsGeneratorWithFixedDurationGenerationBasedCellCycleModel() throw(Exception)
    {
        // Create mesh
        HoneycombMeshGenerator mesh_generator(5, 10, 0);
        TetrahedralMesh<2,2>* p_mesh = mesh_generator.GetMesh();

        // Get location indices corresponding to real cells
        std::vector<unsigned> location_indices = mesh_generator.GetCellLocationIndices();

        // Create cells
        std::vector<CellPtr> cells;

        double y0 = 0.2;
        double y1 = 1.0;
        double y2 = 2.0;
        double y3 = 3.0;

        CryptCellsGenerator<FixedDurationGenerationBasedCellCycleModel> generator;
        generator.Generate(cells, p_mesh, location_indices, true, y0, y1, y2, y3);

        TS_ASSERT_EQUALS(cells.size(), p_mesh->GetNumNodes());

        // Test that cells were generated correctly
        for (unsigned i=0; i<cells.size(); i++)
        {
            double height = p_mesh->GetNode(i)->rGetLocation()[1];
            unsigned generation = static_cast<FixedDurationGenerationBasedCellCycleModel*>(cells[i]->GetCellCycleModel())->GetGeneration();

            TS_ASSERT_EQUALS(cells[i]->GetCellCycleModel()->GetDimension(), 2u);

            if (height <= y0)
            {
                TS_ASSERT_EQUALS(generation, 0u);
                TS_ASSERT_EQUALS(cells[i]->GetCellProliferativeType()->IsType<StemCellProliferativeType>(), true);
            }
            else if (height < y1)
            {
                TS_ASSERT_EQUALS(generation, 1u);
                TS_ASSERT_EQUALS(cells[i]->GetCellProliferativeType()->IsType<TransitCellProliferativeType>(), true);
            }
            else if (height < y2)
            {
                TS_ASSERT_EQUALS(generation, 2u);
                TS_ASSERT_EQUALS(cells[i]->GetCellProliferativeType()->IsType<TransitCellProliferativeType>(), true);
            }
            else if (height < y3)
            {
                TS_ASSERT_EQUALS(generation, 3u);
                TS_ASSERT_EQUALS(cells[i]->GetCellProliferativeType()->IsType<TransitCellProliferativeType>(), true);
            }
            else
            {
                TS_ASSERT_EQUALS(generation, 4u);
                TS_ASSERT_EQUALS(cells[i]->GetCellProliferativeType()->IsType<DifferentiatedCellProliferativeType>(), true);
            }
        }
    }
      void TestCryptCellsGeneratorWithSimpleWntCellCycleModelAndVertexMesh() throw(Exception)
      {
          // Create mesh
          unsigned crypt_width = 4;
          unsigned crypt_height = 6;
          CylindricalHoneycombVertexMeshGenerator mesh_generator(crypt_width, crypt_height);
          Cylindrical2dVertexMesh* p_mesh = mesh_generator.GetCylindricalMesh();

          // Create cells
          std::vector<CellPtr> cells;
          CryptCellsGenerator<SimpleWntCellCycleModel> cells_generator;
          cells_generator.Generate(cells, p_mesh, std::vector<unsigned>(), true, true);

          // Test that the correct number cells was generated
          TS_ASSERT_EQUALS(cells.size(), p_mesh->GetNumElements());
      }
    void TestCalculateWriteResultsToFile()
    {
        std::string output_directory = "TestDiscreteSystemForceCalculator";

        // Set up a cell population

        HoneycombMeshGenerator mesh_generator(7, 5, 0, 2.0);
        MutableMesh<2,2>* p_mesh = mesh_generator.GetMesh();

        CellsGenerator<FixedG1GenerationalCellCycleModel, 2> cells_generator;
        std::vector<CellPtr> cells;
        cells_generator.GenerateBasic(cells, p_mesh->GetNumNodes());

        MeshBasedCellPopulation<2> cell_population(*p_mesh, cells);

        // Create the force law and pass in to a std::list
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_force);
        std::vector<boost::shared_ptr<AbstractTwoBodyInteractionForce<2> > > force_collection;
        force_collection.push_back(p_force);

        // Create a force calculator
        DiscreteSystemForceCalculator calculator(cell_population, force_collection);

        // Test WriteResultsToFile
        calculator.WriteResultsToFile(output_directory);

        // Compare output with saved files of what they should look like
        OutputFileHandler handler(output_directory, false);
        std::string results_file = handler.GetOutputDirectoryFullPath() + "results_from_time_0/results.vizstress";

        NumericFileComparison node_velocities(results_file, "cell_based/test/data/TestDiscreteSystemForceCalculator/results.vizstress");
        TS_ASSERT(node_velocities.CompareFiles(1e-4));

        // Run a simulation to generate some results.viz<other things> files
        // so the visualizer can display the results.vizstress file.
        // (These lines are not actually necessary for generating results.vizstress)
        OffLatticeSimulation<2> simulator(cell_population);

        simulator.AddForce(p_force);

        simulator.SetEndTime(0.05);
        simulator.SetOutputDirectory(output_directory+"_rerun");
        simulator.Solve();
    }
    void TestGenerateGivenLocationIndicesWithFixedDurationGenerationBasedCellCycleModel() throw(Exception)
    {
        EXIT_IF_PARALLEL;
        // Use a mesh generator to generate some location indices corresponding to real cells
        HoneycombMeshGenerator mesh_generator(6, 7, 2);
        std::vector<unsigned> location_indices = mesh_generator.GetCellLocationIndices();

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        TS_ASSERT_THROWS_THIS(cells_generator.GenerateBasic(cells, 83511u, location_indices),
                              "The size of the locationIndices vector must match the required number of output cells");
        cells_generator.GenerateGivenLocationIndices(cells, location_indices);

        // Test that cells were generated correctly
        for (unsigned i=0; i<cells.size(); i++)
        {
            TS_ASSERT_DELTA(cells[i]->GetBirthTime(), -(double)(location_indices[i]), 1e-9);
            TS_ASSERT_EQUALS(cells[i]->GetCellCycleModel()->GetDimension(), 2u);
        }
    }
    void TestGenerateGivenLocationIndicesWithSpecifiedCellProliferativeType() throw(Exception)
    {
        EXIT_IF_PARALLEL;
        // Use a mesh generator to generate some location indices corresponding to real cells
        HoneycombMeshGenerator mesh_generator(6, 7, 2);
        std::vector<unsigned> location_indices = mesh_generator.GetCellLocationIndices();

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;

        cells_generator.GenerateGivenLocationIndices(cells,
                                                     location_indices,
                                                     CellPropertyRegistry::Instance()->Get<DifferentiatedCellProliferativeType>());

        // Test that cells were generated correctly
        for (unsigned i=0; i<cells.size(); i++)
        {
            TS_ASSERT_DELTA(cells[i]->GetBirthTime(), -(double)(location_indices[i]), 1e-9);
            TS_ASSERT_EQUALS(cells[i]->GetCellCycleModel()->GetDimension(), 2u);
            TS_ASSERT_EQUALS(cells[i]->GetCellProliferativeType()->IsType<DifferentiatedCellProliferativeType>(), true);
        }
    }
    void TestCryptCellsGeneratorWithUniformlyDistributedGenerationBasedCellCycleModel() throw(Exception)
    {
        // Create mesh
        HoneycombMeshGenerator mesh_generator(5, 10, 0);
        TetrahedralMesh<2,2>* p_mesh = mesh_generator.GetMesh();

        // Get location indices corresponding to real cells
        std::vector<unsigned> location_indices = mesh_generator.GetCellLocationIndices();

        // Create cells
        std::vector<CellPtr> cells;
        CryptCellsGenerator<UniformlyDistributedGenerationBasedCellCycleModel> generator;
        generator.Generate(cells, p_mesh, location_indices, false);

        TS_ASSERT_EQUALS(cells.size(), p_mesh->GetNumNodes());

        double y0 = 0.3;
        double y1 = 2.0;
        double y2 = 3.0;
        double y3 = 4.0;

        // Test that cells were generated correctly
        for (unsigned i=0; i<cells.size(); i++)
        {
            double height = p_mesh->GetNode(i)->rGetLocation()[1];
            unsigned generation = static_cast<UniformlyDistributedGenerationBasedCellCycleModel*>(cells[i]->GetCellCycleModel())->GetGeneration();

            if (height <= y0)
            {
                TS_ASSERT_EQUALS(generation, 0u);
            }
            else if (height < y1)
            {
                TS_ASSERT_EQUALS(generation, 1u);
            }
            else if (height < y2)
            {
                TS_ASSERT_EQUALS(generation, 2u);
            }
            else if (height < y3)
            {
                TS_ASSERT_EQUALS(generation, 3u);
            }
            else
            {
                TS_ASSERT_EQUALS(generation, 4u);
            }

            TS_ASSERT_DELTA(cells[i]->GetBirthTime(), 0.0, 1e-9);
        }

        // Create cells again with basic
        std::vector<CellPtr> new_cells;
        generator.GenerateBasic(new_cells, p_mesh->GetNumNodes());
        // Test that cells were generated correctly
        TS_ASSERT_EQUALS(new_cells.size(), p_mesh->GetNumNodes());

        for (unsigned i=0; i<new_cells.size(); i++)
        {
            TS_ASSERT_DELTA(new_cells[i]->GetBirthTime(), -(double)(i), 1e-9);
        }
    }
    void TestPrivateMethods()
    {
        // Set up a cell population
        HoneycombMeshGenerator mesh_generator(7, 5, 0, 2.0);
        MutableMesh<2,2>* p_mesh = mesh_generator.GetMesh();
        std::vector<unsigned> location_indices = mesh_generator.GetCellLocationIndices();

        CellsGenerator<FixedG1GenerationalCellCycleModel,2> cells_generator;
        std::vector<CellPtr> cells;
        cells_generator.GenerateGivenLocationIndices(cells, location_indices);

        MeshBasedCellPopulationWithGhostNodes<2> cell_population(*p_mesh, cells, location_indices);

        // Create the force law and pass in to a std::list
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_force);
        std::vector<boost::shared_ptr<AbstractTwoBodyInteractionForce<2> > > force_collection;
        force_collection.push_back(p_force);

        // Create a force calculator
        DiscreteSystemForceCalculator calculator(cell_population, force_collection);

        unsigned node_index = 8;

        // Test GetNeighbouringNodeIndices
        std::set<unsigned> expected_node_indices;
        expected_node_indices.insert(1u);
        expected_node_indices.insert(2u);
        expected_node_indices.insert(7u);
        expected_node_indices.insert(9u);
        expected_node_indices.insert(15u);
        expected_node_indices.insert(16u);

        std::set<unsigned> neighbouring_node_indices = cell_population.GetNeighbouringNodeIndices(node_index);

        TS_ASSERT(neighbouring_node_indices == expected_node_indices);

        // Test CalculateFtAndFn
        double spring_stiffness = p_force->GetMeinekeSpringStiffness();
        double expected_ft = spring_stiffness*(cos(M_PI/12.0) + cos(5.0*M_PI/12.0) - cos(3.0*M_PI/12.0));
        double expected_fn = spring_stiffness*(sin(M_PI/12.0) + sin(5.0*M_PI/12.0) + sin(3.0*M_PI/12.0));
        std::vector<double> Ft_and_Fn = calculator.CalculateFtAndFn(node_index,M_PI/4.0);
        TS_ASSERT_DELTA(Ft_and_Fn[0], expected_ft, 1e-4);
        TS_ASSERT_DELTA(Ft_and_Fn[1], expected_fn, 1e-4);

        // Test GetSamplingAngles
        std::vector<double> expected_sampling_angles;
        double epsilon = calculator.mEpsilon;

        expected_sampling_angles.push_back(-M_PI +epsilon);
        expected_sampling_angles.push_back(-M_PI +epsilon);

        for (unsigned i=1; i<6; i++)
        {
            expected_sampling_angles.push_back(-M_PI +((double) i)*M_PI/3.0 - epsilon);
            expected_sampling_angles.push_back(-M_PI +((double) i)*M_PI/3.0 - epsilon);
            expected_sampling_angles.push_back(-M_PI +((double) i)*M_PI/3.0 + epsilon);
            expected_sampling_angles.push_back(-M_PI +((double) i)*M_PI/3.0 + epsilon);
        }
        expected_sampling_angles.push_back(M_PI - epsilon);
        expected_sampling_angles.push_back(M_PI - epsilon);

        std::vector<double> sampling_angles = calculator.GetSamplingAngles(node_index);
        for (unsigned i=0; i<sampling_angles.size(); i++)
        {
            // the sampling angles lie in the range (pi,pi]
            if (expected_sampling_angles[i] > M_PI)
            {
                expected_sampling_angles[i] -= 2*M_PI;
            }

            TS_ASSERT_DELTA(sampling_angles[i], expected_sampling_angles[i], 1e-6);
        }

        // Test GetLocalExtremum
        double expected_extremal_angle = -M_PI +M_PI/6.0;
        double calculated_extremal_angle = calculator.GetLocalExtremum(node_index, sampling_angles[1], sampling_angles[2]);

        TS_ASSERT_DELTA(calculated_extremal_angle, expected_extremal_angle, 1e-4);

        // Test GetExtremalAngles
        std::vector<double> calculated_extremal_angles = calculator.GetExtremalAngles(node_index, sampling_angles);

        // the extremal angles lie in the range (pi,pi]
        TS_ASSERT_DELTA(-M_PI + M_PI/6.0, calculated_extremal_angles[0], 1e-4);
        TS_ASSERT_DELTA(-M_PI + M_PI/3.0, calculated_extremal_angles[1], 1e-4);
        TS_ASSERT_DELTA(-M_PI + M_PI/2.0, calculated_extremal_angles[2], 1e-4);
        TS_ASSERT_DELTA(-M_PI + 2.0*M_PI/3.0, calculated_extremal_angles[3], 1e-4);
        TS_ASSERT_DELTA(-M_PI + 5.0*M_PI/6.0, calculated_extremal_angles[4], 1e-4);
    }
    void TestCalculateExtremalNormalForces()
    {
        // Set up a cell population
        HoneycombMeshGenerator mesh_generator(7, 5, 0, 2.0);
        MutableMesh<2,2>* p_mesh = mesh_generator.GetMesh();

        CellsGenerator<FixedG1GenerationalCellCycleModel, 2> cells_generator;
        std::vector<CellPtr> cells;
        cells_generator.GenerateBasic(cells, p_mesh->GetNumNodes());

        MeshBasedCellPopulation<2> cell_population(*p_mesh, cells);

        // Create the force law and pass in to a std::list
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_force);
        std::vector<boost::shared_ptr<AbstractTwoBodyInteractionForce<2> > > force_collection;
        force_collection.push_back(p_force);

        // Create a force calculator
        DiscreteSystemForceCalculator calculator(cell_population, force_collection);

        // Test CalculateExtremalNormalForces
        std::vector< std::vector<double> > calculated_results = calculator.CalculateExtremalNormalForces();
        TS_ASSERT_EQUALS(calculated_results.size(), 2u);
        TS_ASSERT_EQUALS(calculated_results[0].size(), p_mesh->GetNumNodes());
        TS_ASSERT_EQUALS(calculated_results[1].size(), p_mesh->GetNumNodes());

        double spring_stiffness = p_force->GetMeinekeSpringStiffness();
        double expected_minimum_interior = spring_stiffness*( 2.0*sin(M_PI/3.0) );
        double expected_maximum_interior = spring_stiffness*( sin(M_PI/6.0) + sin(M_PI/2.0) + sin(5.0*M_PI/6.0) );

        for (unsigned i=0; i<p_mesh->GetNumNodes(); i++)
        {
            if (!(p_mesh->GetNode(i)->IsBoundaryNode()))
            {
                TS_ASSERT_DELTA(calculated_results[0][i], expected_minimum_interior, 1e-4);
                TS_ASSERT_DELTA(calculated_results[1][i], expected_maximum_interior, 1e-4);
            }
            else
            {
                // Separate cases for the boundary nodes...
                if (i==29 || i==30 || i==31 || i==32 || i==33)
                {
                    TS_ASSERT_DELTA(calculated_results[0][i], 0.0, 1e-4);
                    TS_ASSERT_DELTA(calculated_results[1][i], expected_maximum_interior, 1e-4);
                }
                if (i==7 || i==20 || i==21)
                {
                    TS_ASSERT_DELTA(calculated_results[0][i], spring_stiffness*sin(M_PI/3.0), 1e-4);
                    TS_ASSERT_DELTA(calculated_results[1][i], expected_maximum_interior, 1e-4);

                }
                if (i==1 || i==2 || i==3 || i==4 || i==5)
                {
                    TS_ASSERT_DELTA(calculated_results[0][i], 0.0, 1e-4);
                    TS_ASSERT_DELTA(calculated_results[1][i], expected_maximum_interior, 1e-4);

                }
                if (i==13 || i==14 || i==27)
                {
                    TS_ASSERT_DELTA(calculated_results[0][i], expected_maximum_interior, 1e-4);
                    TS_ASSERT_DELTA(calculated_results[1][i], expected_maximum_interior, 1e-4);
                }
            }
        }
    }