/*
     * EMPTYLINE
     *
     * To visualize the results, open a new terminal, {{{cd}}} to the Chaste directory,
     * then {{{cd}}} to {{{anim}}}. Then do: {{{java Visualize2dCentreCells /tmp/$USER/testoutput/NodeBasedMonolayer/results_from_time_0}}}.
     * we need to select the 'Cells as circles` option to be able to visualize the cells, as opposed
     * to just the centres.
     * We may have to do: {{{javac Visualize2dCentreCells.java}}} beforehand to create the
     * java executable.
     *
     * Alternatively, to view in Paraview, load the file {{{/tmp/$USER/testoutput/NodeBasedMonolayer/results_from_time_0/results.pvd}}}
     * and add glyphs to represent cells. An option is to use 3D spherical glyphs and then make a planar cut.
     * Note that, for larger simulations, you may need to unclick "Mask Points" (or similar) so as not to limit the number of glyphs
     * displayed by Paraview.
     *
     *
     *
     * EMPTYLINE
     *
     * == Test 2 - a basic node-based simulation in 3D ==
     *
     * EMPTYLINE
     *
     * In the second test we run a simple node-based simulation in 3D. This is very similar
     * to the 2D test with the dimension template (<2,2> and <2>) changed from 2 to 3 and instead of using a mesh
     * generator we generate the nodes directly.
     */
    void TestSpheroid()
    {
        /** The next line is needed because we cannot currently run node based simulations in parallel. */
        EXIT_IF_PARALLEL;

        /*
         * First, we generate a nodes only mesh. This time we specify the nodes manually by first
         * creating a vector of nodes. */
        std::vector<Node<3>*> nodes;
        /* We then create some nodes to add to this vector. */
        nodes.push_back(new Node<3>(0u,  false,  0.5, 0.0, 0.0));
        nodes.push_back(new Node<3>(1u,  false,  -0.5, 0.0, 0.0));
        nodes.push_back(new Node<3>(2u,  false,  0.0, 0.5, 0.0));
        nodes.push_back(new Node<3>(3u,  false,  0.0, -0.5, 0.0));
        /* Finally a {{{NodesOnlyMesh}}} is created and the vector of nodes is passed to
         * the {{{ConstructNodesWithoutMesh}}} method. */
        NodesOnlyMesh<3> mesh;
        /* To run node-based simulations you need to define a cut off length (second argument in
         * {{{ConstructNodesWithoutMesh}}}), which defines the connectivity of the nodes by defining
         * a radius of interaction. */
        mesh.ConstructNodesWithoutMesh(nodes, 1.5);

        /*
         * Having created a mesh, we now create a {{{std::vector}}} of {{{CellPtr}}}s.
         * As before, we do this with the `CellsGenerator` helper class (this time with dimension 3).
         */
        std::vector<CellPtr> cells;
        MAKE_PTR(TransitCellProliferativeType, p_transit_type);
        CellsGenerator<UniformCellCycleModel, 3> cells_generator;
        cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes(), p_transit_type);

        /* We make a {{{NodeBasedCellPopulation}}} (this time with dimension 3) as before.
         */
        NodeBasedCellPopulation<3> cell_population(mesh, cells);

        /* We then pass in the cell population into an {{{OffLatticeSimulation}}},
         * (this time with dimension 3) and set the output directory, output multiple and end time. */
        OffLatticeSimulation<3> simulator(cell_population);
        simulator.SetOutputDirectory("NodeBasedSpheroid");
        simulator.SetSamplingTimestepMultiple(12);
        simulator.SetEndTime(10.0);

        /* Again we create a force law (this time with dimension 3), and pass it to the {{{OffLatticeSimulation}}}.*/
        MAKE_PTR(GeneralisedLinearSpringForce<3>, p_force);
        simulator.AddForce(p_force);

        /* To run the simulation, we call {{{Solve()}}}. */
        simulator.Solve();

        /* The next two lines are for test purposes only and are not part of this tutorial.
         */
        TS_ASSERT_EQUALS(cell_population.GetNumRealCells(), 8u);
        TS_ASSERT_DELTA(SimulationTime::Instance()->GetTime(), 10.0, 1e-10);

        /* To avoid memory leaks, we conclude by deleting any pointers that we created in the test.*/
        for (unsigned i=0; i<nodes.size(); i++)
        {
            delete nodes[i];
        }
    }
Ejemplo n.º 2
0
    void TestConstructor() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        // Create a cell population
        HoneycombMeshGenerator generator(2, 2, 0);
        MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());

        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        // Create a PDE handler object using this cell population
        CellBasedPdeHandler<2> pde_handler(&cell_population);

        // Test that member variables are initialised correctly
        TS_ASSERT_EQUALS(pde_handler.GetCellPopulation(), &cell_population);
        TS_ASSERT_EQUALS(pde_handler.GetWriteAverageRadialPdeSolution(), false);
        TS_ASSERT_EQUALS(pde_handler.GetWriteDailyAverageRadialPdeSolution(), false);
        TS_ASSERT_EQUALS(pde_handler.GetImposeBcsOnCoarseBoundary(), true);
        TS_ASSERT_EQUALS(pde_handler.GetNumRadialIntervals(), UNSIGNED_UNSET);
        TS_ASSERT(pde_handler.GetCoarsePdeMesh() == NULL);
    }
    void TestCellPopulationIteratorWithNoCells() throw(Exception)
    {
        EXIT_IF_PARALLEL;    // This test doesn't work in parallel.

        SimulationTime* p_simulation_time = SimulationTime::Instance();
        p_simulation_time->SetEndTimeAndNumberOfTimeSteps(10.0, 1);

        // Create a simple mesh
        TrianglesMeshReader<2,2> mesh_reader("mesh/test/data/square_128_elements");
        TetrahedralMesh<2,2> generating_mesh;
        generating_mesh.ConstructFromMeshReader(mesh_reader);

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(generating_mesh, 1.2);

        // Create vector of cell location indices
        std::vector<unsigned> cell_location_indices;
        cell_location_indices.push_back(80);

        // Create a single cell
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, cell_location_indices.size());
        cells[0]->StartApoptosis();

        // Create a cell population
        NodeBasedCellPopulationWithParticles<2> cell_population(mesh, cells, cell_location_indices);

        // Iterate over cell population and check there is a single cell
        unsigned counter = 0;
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
                cell_iter != cell_population.End();
                ++cell_iter)
        {
            counter++;
        }
        TS_ASSERT_EQUALS(counter, 1u);
        TS_ASSERT_EQUALS(cell_population.rGetCells().empty(), false);

        // Increment simulation time and update cell population
        p_simulation_time->IncrementTimeOneStep();

        unsigned num_cells_removed = cell_population.RemoveDeadCells();
        TS_ASSERT_EQUALS(num_cells_removed, 1u);

        cell_population.Update();

        // Iterate over cell population and check there are now no cells
        counter = 0;
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
                cell_iter != cell_population.End();
                ++cell_iter)
        {
            counter++;
        }
        TS_ASSERT_EQUALS(counter, 0u);
        TS_ASSERT_EQUALS(cell_population.rGetCells().empty(), true);
    }
Ejemplo n.º 4
0
    void TestVolumeDependentAveragedSourcePdeArchiving() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        // Set up simulation time
        SimulationTime::Instance()->SetEndTimeAndNumberOfTimeSteps(1.0, 1);

        // Set up cell population
        HoneycombMeshGenerator generator(5, 5, 0);
        MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());
        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        FileFinder archive_dir("archive", RelativeTo::ChasteTestOutput);
        std::string archive_file = "VolumeDependentAveragedSourcePde.arch";
        ArchiveLocationInfo::SetMeshFilename("VolumeDependentAveragedSourcePde");

        {
            // Create a PDE object
            AbstractLinearEllipticPde<2,2>* const p_pde = new VolumeDependentAveragedSourcePde<2>(cell_population, 0.05);

            // Create output archive and archive PDE object
            ArchiveOpener<boost::archive::text_oarchive, std::ofstream> arch_opener(archive_dir, archive_file);
            boost::archive::text_oarchive* p_arch = arch_opener.GetCommonArchive();
            (*p_arch) << p_pde;

            // Avoid memory leak
            delete p_pde;
        }

        {
            AbstractLinearEllipticPde<2,2>* p_pde;

            // Create an input archive and restore PDE object from archive
            ArchiveOpener<boost::archive::text_iarchive, std::ifstream> arch_opener(archive_dir, archive_file);
            boost::archive::text_iarchive* p_arch = arch_opener.GetCommonArchive();
            (*p_arch) >> p_pde;

            // Test that the PDE and its member variables were archived correctly
            TS_ASSERT(dynamic_cast<VolumeDependentAveragedSourcePde<2>*>(p_pde) != NULL);

            VolumeDependentAveragedSourcePde<2>* p_static_cast_pde = static_cast<VolumeDependentAveragedSourcePde<2>*>(p_pde);
            TS_ASSERT_DELTA(p_static_cast_pde->GetCoefficient(), 0.05, 1e-6);
            TS_ASSERT_EQUALS(p_static_cast_pde->mrCellPopulation.GetNumRealCells(), 25u);
            TS_ASSERT(p_static_cast_pde->mpStaticCastCellPopulation != NULL);
            TS_ASSERT_EQUALS(p_static_cast_pde->mpStaticCastCellPopulation->GetNumRealCells(), 25u);

            // Avoid memory leaks
            delete &(p_static_cast_pde->mrCellPopulation);
            delete p_pde;
        }
    }
    void TestStandardResultForArchivingTestsBelow() throw (Exception)
    {
        EXIT_IF_PARALLEL;    // HoneycombMeshGenereator does not work in parallel.

        // Create a simple mesh
        int num_cells_depth = 5;
        int num_cells_width = 5;
        HoneycombMeshGenerator generator(num_cells_width, num_cells_depth, 0);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes());

        // Create a node based cell population
        NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells);

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(node_based_cell_population);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithNodeBasedCellPopulationStandardResult");
        simulator.SetEndTime(2.5);

        // Create a force law and pass it to the simulation
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force);
        p_linear_force->SetCutOffLength(1.5);
        simulator.AddForce(p_linear_force);

        // Create some boundary conditions and pass them to the simulation
        c_vector<double,2> normal = zero_vector<double>(2);
        normal(1) =-1.0;
        MAKE_PTR_ARGS(PlaneBoundaryCondition<2>, p_bc, (&node_based_cell_population, zero_vector<double>(2), normal)); // y>0
        simulator.AddCellPopulationBoundaryCondition(p_bc);

        // Solve
        simulator.Solve();

        // Check some results
        mNode3x = 3.0454;
        mNode3y = 0.0000;
        mNode4x = 4.0468;
        mNode4y = 0.0101;

        std::vector<double> node_3_location = simulator.GetNodeLocation(3);
        TS_ASSERT_DELTA(node_3_location[0], mNode3x, 1e-4);
        TS_ASSERT_DELTA(node_3_location[1], mNode3y, 1e-4);

        std::vector<double> node_4_location = simulator.GetNodeLocation(4);
        TS_ASSERT_DELTA(node_4_location[0], mNode4x, 1e-4);
        TS_ASSERT_DELTA(node_4_location[1], mNode4y, 1e-4);
    }
    // Testing Save()
    void TestSave() throw (Exception)
    {
        EXIT_IF_PARALLEL; // HoneycombMeshGenereator does not work in parallel

        // Create a simple mesh
        unsigned num_cells_depth = 5;
        unsigned num_cells_width = 5;
        HoneycombMeshGenerator generator(num_cells_width, num_cells_depth, 0);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes());

        // Create a node based cell population
        NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells);

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(node_based_cell_population);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithNodeBasedCellPopulationSaveAndLoad");
        simulator.SetEndTime(0.1);

        // Create a force law and pass it to the simulation
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force);
        p_linear_force->SetCutOffLength(1.5);
        simulator.AddForce(p_linear_force);

        // Create some boundary conditions and pass them to the simulation
        c_vector<double,2> normal = zero_vector<double>(2);
        normal(1) =-1.0;
        MAKE_PTR_ARGS(PlaneBoundaryCondition<2>, p_bc, (&node_based_cell_population, zero_vector<double>(2), normal)); // y>0
        simulator.AddCellPopulationBoundaryCondition(p_bc);

        /*
         * For more thorough testing of serialization, we 'turn on' adaptivity.
         * Note that this has no effect on the numerical results, since the
         * conditions under which the time step would be adapted are not invoked
         * in this example.
         */
        boost::shared_ptr<AbstractNumericalMethod<2,2> > p_method(new ForwardEulerNumericalMethod<2,2>());
        p_method->SetUseAdaptiveTimestep(true);
        simulator.SetNumericalMethod(p_method);

        // Solve
        simulator.Solve();

        // Save the results
        CellBasedSimulationArchiver<2, OffLatticeSimulation<2> >::Save(&simulator);
    }
    /**
     * Create a simulation of a NodeBasedCellPopulation with a NodeBasedCellPopulationMechanicsSystem.
     * Test that no exceptions are thrown, and write the results to file.
     */
    void TestSimpleMonolayer() throw (Exception)
    {
        EXIT_IF_PARALLEL;    // HoneycombMeshGenereator does not work in parallel.

        // Create a simple mesh
        unsigned num_cells_depth = 5;
        unsigned num_cells_width = 5;
        HoneycombMeshGenerator generator(num_cells_width, num_cells_depth, 0);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes());

        // Create a node-based cell population
        NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells);

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(node_based_cell_population);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithNodeBasedCellPopulation");

        // No need to go for long, don't want any birth or regular grid will be disrupted.
        simulator.SetEndTime(0.5);

        // Create a force law and pass it to the simulation
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force);
        p_linear_force->SetCutOffLength(1.5);
        simulator.AddForce(p_linear_force);

        simulator.Solve();

        // Check that nothing's gone badly wrong by testing that nodes aren't too close together
        double min_distance_between_cells = 1.0;

        for (unsigned i=0; i<simulator.rGetCellPopulation().GetNumNodes(); i++)
        {
            for (unsigned j=i+1; j<simulator.rGetCellPopulation().GetNumNodes(); j++)
            {
                double distance = norm_2(simulator.rGetCellPopulation().GetNode(i)->rGetLocation()-simulator.rGetCellPopulation().GetNode(j)->rGetLocation());

                if (distance < min_distance_between_cells)
                {
                    min_distance_between_cells = distance;
                }
            }
        }

        TS_ASSERT(min_distance_between_cells > 0.999);
    }
    /*
    * Here we set up a test with 5 nodes, make a cell for each. We then set cell
    * 0 to be associated with node 1 instead of node 0, and Validate() throws an
    * exception. We then set node 0 to be a particle node, and Validate() passes.
    */
    void TestValidateNodeBasedCellPopulationWithParticles() throw(Exception)
    {
        EXIT_IF_PARALLEL;    // This test doesn't work in parallel.

        // Create a simple mesh
        TrianglesMeshReader<2,2> mesh_reader("mesh/test/data/square_4_elements");
        TetrahedralMesh<2,2> generating_mesh;
        generating_mesh.ConstructFromMeshReader(mesh_reader);

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(generating_mesh, 1.5);

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes()-1);

        std::vector<unsigned> cell_location_indices;
        for (unsigned i=0; i<cells.size(); i++)
        {
            cell_location_indices.push_back(i);
        }

        // Fails as the cell population constructor is not given the location indices
        // corresponding to real cells, so cannot work out which nodes are
        // particles
        std::vector<CellPtr> cells_copy(cells);
        TS_ASSERT_THROWS_THIS(NodeBasedCellPopulationWithParticles<2> dodgy_cell_population(mesh, cells_copy),
                              "Node 4 does not appear to be a particle or has a cell associated with it");

        // Passes as the cell population constructor automatically works out which
        // cells are particles using the mesh and cell_location_indices
        NodeBasedCellPopulationWithParticles<2> cell_population(mesh, cells, cell_location_indices);

        // Here we set the particles to what they already are
        std::set<unsigned> particle_indices;
        particle_indices.insert(mesh.GetNumNodes()-1);
        cell_population.SetParticles(particle_indices);

        // So validate passes at the moment
        cell_population.Validate();

        // Test GetCellUsingLocationIndex()
        TS_ASSERT_THROWS_NOTHING(cell_population.GetCellUsingLocationIndex(0)); // real cell
        TS_ASSERT_THROWS_THIS(cell_population.GetCellUsingLocationIndex(mesh.GetNumNodes()-1u),"Location index input argument does not correspond to a Cell"); // particles

        // Now we label a real cell's node as particle
        particle_indices.insert(1);

        // Validate detects this inconsistency
        TS_ASSERT_THROWS_THIS(cell_population.SetParticles(particle_indices),"Node 1 is labelled as a particle and has a cell attached");
    }
    /**
     * Create a simulation of a NodeBasedCellPopulation with a BuskeCompressionForce system.
     * Test that no exceptions are thrown, and write the results to file.
     */
    void TestSimpleMonolayerWithBuskeCompressionForce() throw (Exception)
    {
        EXIT_IF_PARALLEL;    // HoneycombMeshGenerator doesn't work in parallel

        // Create a simple mesh
        unsigned num_cells_depth = 5;
        unsigned num_cells_width = 5;
        HoneycombMeshGenerator generator(num_cells_width, num_cells_depth, 0);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

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

        // Create a node-based cell population
        NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells);

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(node_based_cell_population);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithBuskeCompressionForce");
        simulator.SetEndTime(5.0);

        // Create a force law and pass it to the simulation
        MAKE_PTR(BuskeCompressionForce<2>, buske_compression_force);
        buske_compression_force->SetCompressionEnergyParameter(0.01);
        simulator.AddForce(buske_compression_force);

        simulator.Solve();

        // Check that nothing's gone badly wrong by testing that nodes aren't too close together
        double min_distance_between_cells = 1.0;

        for (unsigned i=0; i<simulator.rGetCellPopulation().GetNumNodes(); i++)
        {
            for (unsigned j=i+1; j<simulator.rGetCellPopulation().GetNumNodes(); j++)
            {
                double distance = norm_2(simulator.rGetCellPopulation().GetNode(i)->rGetLocation()-simulator.rGetCellPopulation().GetNode(j)->rGetLocation());
                if (distance < min_distance_between_cells)
                {
                    min_distance_between_cells = distance;
                }
            }
        }

        TS_ASSERT(min_distance_between_cells > 1e-3);
    }
Ejemplo n.º 10
0
    void TestVolumeDependentAveragedSourcePdeMethods() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        // Create a cell population
        HoneycombMeshGenerator generator(5, 5, 0);
        MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());
        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        // Create a PDE object
        VolumeDependentAveragedSourcePde<2> pde(cell_population, 0.05);

        // Test that the member variables have been initialised correctly
        TS_ASSERT(pde.mpStaticCastCellPopulation != NULL);

        // For simplicity we create a very large coarse mesh, so we know that all cells are contained in one element
        TrianglesMeshReader<2,2> mesh_reader("mesh/test/data/square_2_elements");
        TetrahedralMesh<2,2> coarse_mesh;
        coarse_mesh.ConstructFromMeshReader(mesh_reader);
        coarse_mesh.Scale(10.0, 10.0);

        // Test SetupSourceTerms() when no map between cells and coarse mesh elements is supplied
        pde.SetupSourceTerms(coarse_mesh);

        TS_ASSERT_EQUALS(pde.mCellDensityOnCoarseElements.size(), 2u);

        // The first element has area 0.5*10*10 = 50 and there are 5*5 = 25 cells, so the cell density is 25/50 = 0.5
        // The radius of each node is 0.5 and the density is normalized with cell area (1/4.0) in `VolumeDependentAveragedSourcePde`.
        TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[0], 0.5/4.0, 1e-6);

        // The first element doesn't contain any cells, so the cell density is zero
        TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[1], 0.0, 1e-6);

        // Now test SetupSourceTerms() when a map between cells and coarse mesh elements is supplied
        std::map<CellPtr, unsigned> cell_pde_element_map;
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
             cell_iter != cell_population.End();
             ++cell_iter)
        {
            cell_pde_element_map[*cell_iter] = 0;
        }

        pde.SetupSourceTerms(coarse_mesh, &cell_pde_element_map);
        TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[0], 0.5/4.0, 1e-6);
        TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[1], 0.0, 1e-6);
    }
Ejemplo n.º 11
0
    void TestInitialiseCellPdeElementMapAndFindCoarseElementContainingCell() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        // Create a cell population
        HoneycombMeshGenerator generator(4, 4, 0);
        MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());

        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        // Create a PDE handler object using this cell population
        CellBasedPdeHandler<2> pde_handler(&cell_population);

        TS_ASSERT_EQUALS(pde_handler.mCellPdeElementMap.size(), 0u);

        // Test that InitialiseCellPdeElementMap() throws an exception if mpCoarsePdeMesh is not set up
        TS_ASSERT_THROWS_THIS(pde_handler.InitialiseCellPdeElementMap(),
            "InitialiseCellPdeElementMap() should only be called if mpCoarsePdeMesh is set up.");

        // Set up PDE and pass to handler
        AveragedSourcePde<2> pde(cell_population, -0.1);
        ConstBoundaryCondition<2> bc(1.0);
        PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false);
        pde_handler.AddPdeAndBc(&pde_and_bc);

        // Use a coarse PDE mesh
        ChastePoint<2> lower(0.0, 0.0);
        ChastePoint<2> upper(9.0, 9.0);
        ChasteCuboid<2> cuboid(lower, upper);

        pde_handler.UseCoarsePdeMesh(3.0, cuboid, true);

        // Test that mCellPdeElementMap is initialised correctly
        pde_handler.InitialiseCellPdeElementMap();

        TS_ASSERT_EQUALS(pde_handler.mCellPdeElementMap.size(), cell_population.GetNumRealCells());
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
             cell_iter != cell_population.End();
             ++cell_iter)
        {
            unsigned containing_element_index = pde_handler.mCellPdeElementMap[*cell_iter];
            TS_ASSERT_LESS_THAN(containing_element_index, pde_handler.GetCoarsePdeMesh()->GetNumElements());
            TS_ASSERT_EQUALS(containing_element_index, pde_handler.FindCoarseElementContainingCell(*cell_iter));
        }
    }
Ejemplo n.º 12
0
    /*
     * To visualize the results, open a new terminal, {{{cd}}} to the Chaste directory,
     * then {{{cd}}} to {{{anim}}}. Then do: {{{java Visualize2dVertexCells /tmp/$USER/testoutput/CellBasedDemo1/results_from_time_0}}}.
     * We may have to do: {{{javac Visualize2dVertexCells.java}}} beforehand to create the
     * java executable.
     *
     * EMPTYLINE
     *
     * The {{{make_a_movie}}} script can be used to generate a video based on the results of your simulation.
     * To do this, first visualize the results using {{{Visualize2dVertexCells}}} as described above. Click
     * on the box marked "Output" and play through the whole simulation to generate a sequence of {{{.png}}}
     * images, one for each time step. Next, still in the {{{anim}}} folder, do: {{{./make_a_movie}}}.
     * This reads in the {{{.png}}} files and creates a video file called {{{simulation.mpeg}}}.
     *
     * EMPTYLINE
     *
     * Results can also be visualized using Paraview. See the UserTutorials/VisualizingWithParaview tutorial for more information.
     *
     * EMPTYLINE
     *
     * == Test 2 - basic node-based simulation ==
     *
     * We next show how to modify the previous test to implement a 'node-based' simulation,
     * in which cells are represented by overlapping spheres (actually circles, since we're
     * in 2D).
     */
    void TestNodeBasedMonolayer() throw (Exception)
    {
        /* We now need to create a {{{NodesOnlyMesh}}} we do this by first creating a {{{MutableMesh}}}
         * and passing this to a helper method {{{ConstructNodesWithoutMesh}}} along with a interaction cut off length
         * that defines the connectivity in the mesh.
         */
        HoneycombMeshGenerator generator(2, 2); //**Changed**//
        MutableMesh<2,2>* p_generating_mesh = generator.GetMesh(); //**Changed**//
        NodesOnlyMesh<2> mesh; //**Changed**//
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); //**Changed**//

        /* We create the cells as before, only this time we need one cell per node.*/
        std::vector<CellPtr> cells;
        MAKE_PTR(TransitCellProliferativeType, p_transit_type);
        CellsGenerator<StochasticDurationCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes(), p_transit_type); //**Changed**//

        /* This time we create a {{{NodeBasedCellPopulation}}} as we are using a {{{NodesOnlyMesh}}}.*/
        NodeBasedCellPopulation<2> cell_population(mesh, cells);//**Changed**//

        /* We create an {{{OffLatticeSimulation}}} object as before, all we change is the output directory
         * and output results more often as a larger default timestep is used for these simulations. */
        OffLatticeSimulation<2> simulator(cell_population);
        simulator.SetOutputDirectory("CellBasedDemo2"); //**Changed**//
        simulator.SetSamplingTimestepMultiple(12); //**Changed**//
        simulator.SetEndTime(20.0);

        /* We use a different {{{Force}}} which is suitable for node based simulations.
         */
        MAKE_PTR(RepulsionForce<2>, p_force); //**Changed**//
        simulator.AddForce(p_force);

        /* In all types of simulation you may specify how cells are removed from the simulation by specifying
         * a {{{CellKiller}}}. You create these in the same was as the {{{Force}}} and pass them to the {{{CellBasedSimulation}}}.
         * Note that here the constructor for {{{RandomCellKiller}}} requires some arguments to be passed to it, therefore we use the
         * {{{MAKE_PTR_ARGS}}} macro.
         */
        MAKE_PTR_ARGS(RandomCellKiller<2>, p_cell_killer, (&cell_population, 0.01)); //**Changed**//
        simulator.AddCellKiller(p_cell_killer);

        /* Again we call the {{{Solve}}} method on the simulation to run the simulation.*/
        simulator.Solve();

        /* The next two lines are for test purposes only and are not part of this tutorial.
         * Again, we are checking that we reached the end time of the simulation
         * with the correct number of cells.
         */
        TS_ASSERT_EQUALS(cell_population.GetNumRealCells(), 7u);
        TS_ASSERT_DELTA(SimulationTime::Instance()->GetTime(), 20.0, 1e-10);
    }
Ejemplo n.º 13
0
    void TestUseCoarsePdeMeshNotCentredOnPopulation() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        // Create a cell population
        HoneycombMeshGenerator generator(4, 4, 0);
        MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());

        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        // Create a PDE handler object using this cell population
        CellBasedPdeHandler<2> pde_handler(&cell_population);

        // Test that UseCoarsePdeMesh() throws an exception if no PDEs are specified
        ChastePoint<2> lower(0.0, 0.0);
        ChastePoint<2> upper(9.0, 9.0);
        ChasteCuboid<2> cuboid(lower, upper);

        // Set up PDE and pass to handler
        AveragedSourcePde<2> pde(cell_population, -0.1);
        ConstBoundaryCondition<2> bc(1.0);
        PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false);
        pde_handler.AddPdeAndBc(&pde_and_bc);

        // Test UseCoarsePdeMesh() again
        pde_handler.UseCoarsePdeMesh(3.0, cuboid);

        // Check that the centre of the mesh co-incides with centre of the cuboid.
        c_vector<double,2> centre_of_coarse_mesh = zero_vector<double>(2);
        for (unsigned i=0; i<pde_handler.GetCoarsePdeMesh()->GetNumNodes(); i++)
        {
            centre_of_coarse_mesh += pde_handler.GetCoarsePdeMesh()->GetNode(i)->rGetLocation();
        }
        centre_of_coarse_mesh /= pde_handler.GetCoarsePdeMesh()->GetNumNodes();

        c_vector<double,2> centre_of_cuboid = 0.5*(lower.rGetLocation() + upper.rGetLocation());

        TS_ASSERT_DELTA(norm_2(centre_of_cuboid - centre_of_coarse_mesh), 0.0,  1e-4);
    }
    // Testing Save
    void TestSave() throw (Exception)
    {
        EXIT_IF_PARALLEL; // HoneycombMeshGenereator does not work in parallel

        // Create a simple mesh
        int num_cells_depth = 5;
        int num_cells_width = 5;
        HoneycombMeshGenerator generator(num_cells_width, num_cells_depth, 0);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes());

        // Create a node based cell population
        NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells);

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(node_based_cell_population);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithNodeBasedCellPopulationSaveAndLoad");
        simulator.SetEndTime(0.1);

        // Create a force law and pass it to the simulation
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force);
        p_linear_force->SetCutOffLength(1.5);
        simulator.AddForce(p_linear_force);

        // Create some boundary conditions and pass them to the simulation
        c_vector<double,2> normal = zero_vector<double>(2);
        normal(1) =-1.0;
        MAKE_PTR_ARGS(PlaneBoundaryCondition<2>, p_bc, (&node_based_cell_population, zero_vector<double>(2), normal)); // y>0
        simulator.AddCellPopulationBoundaryCondition(p_bc);

        // Solve
        simulator.Solve();

        // Save the results
        CellBasedSimulationArchiver<2, OffLatticeSimulation<2> >::Save(&simulator);
    }
    void TestUpdateCellLocationsAndTopologyWithNoForce()
    {
        // Creates nodes and mesh
        std::vector<Node<2>*> nodes;
        nodes.push_back(new Node<2>(0,  false,  0.0, 0.0));
        nodes.push_back(new Node<2>(0,  false,  0.0, 0.3));
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(nodes, 1.5);

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes());

        // Create a node based cell population
        NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells);
        node_based_cell_population.SetAbsoluteMovementThreshold(1e-6);

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(node_based_cell_population);
        simulator.SetEndTime(0.1);
        simulator.SetOutputDirectory("TestOffLatticeSimulationUpdateCellLocationsAndTopologyWithNoForce");
        simulator.SetupSolve();

        simulator.UpdateCellLocationsAndTopology();

        if (PetscTools::AmMaster())
        {
            for (AbstractMesh<2,2>::NodeIterator node_iter = mesh.GetNodeIteratorBegin();
                    node_iter != mesh.GetNodeIteratorEnd();
                    ++node_iter)
            {
                for (unsigned d=0; d<2; d++)
                {
                    TS_ASSERT_DELTA(node_iter->rGetAppliedForce()[d], 0.0, 1e-15);
                }
            }
        }

        // Avoid memory leak
        delete nodes[0];
        delete nodes[1];
    }
    /**
     * Test that two nodes relax to the equilibrium distance.
     */
    void TestBuskeRelaxationForces() throw (Exception)
    {
        EXIT_IF_PARALLEL;

        // Create a simple mesh with two nodes
        HoneycombMeshGenerator generator(2, 1, 0, 0.9);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        // Create cells
        std::vector<CellPtr> cells;
        MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type);
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator_buske;
        cells_generator_buske.GenerateBasicRandom(cells, mesh.GetNumNodes(), p_diff_type);

        // Create a node-based cell population
        NodeBasedCellPopulation<2> node_based_cell_population_buske(mesh, cells);

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(node_based_cell_population_buske);
        simulator.SetOutputDirectory("TestBuskeRelaxation");
        simulator.SetEndTime(1.0);

        // Create all three Buske force laws and pass to the simulation
        MAKE_PTR(BuskeCompressionForce<2>, p_buske_compression_force);
        MAKE_PTR(BuskeElasticForce<2>, p_buske_elastic_force);
        MAKE_PTR(BuskeAdhesiveForce<2>, p_buske_adhesive_force);
        simulator.AddForce(p_buske_compression_force);
        simulator.AddForce(p_buske_elastic_force);
        simulator.AddForce(p_buske_adhesive_force);

        // Solve
        simulator.Solve();

        // The nodes should be about 0.85 apart as this is the minimum of the sum of the energies.
        TS_ASSERT_DELTA(simulator.rGetCellPopulation().GetNode(0)->rGetLocation()[0], 0.0155,  1e-4);
        TS_ASSERT_DELTA(simulator.rGetCellPopulation().GetNode(1)->rGetLocation()[0], 0.8844,  1e-4);
    }
    void TestVertexCryptBoundaryForceForceWithNonVertexCellPopulation() throw (Exception)
    {
        // Create a NodeBasedCellPopulation
        std::vector<Node<2>*> nodes;
        unsigned num_nodes = 10;
        for (unsigned i=0; i<num_nodes; i++)
        {
            double x = (double)(i);
            double y = (double)(i);
            nodes.push_back(new Node<2>(i, true, x, y));
        }
        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(nodes, 1.5);

        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());

        NodeBasedCellPopulation<2> non_vertex_cell_population(mesh, cells);

        for (AbstractMesh<2,2>::NodeIterator node_iter = mesh.GetNodeIteratorBegin();
                node_iter != mesh.GetNodeIteratorEnd();
                ++node_iter)
        {
            node_iter->ClearAppliedForce();
        }

        // Test that VertexCryptBoundaryForce throws the correct exception
        VertexCryptBoundaryForce<2> force(100);
        TS_ASSERT_THROWS_THIS(force.AddForceContribution(non_vertex_cell_population),
                "VertexCryptBoundaryForce is to be used with VertexBasedCellPopulations only");

        // Avoid memory leak
        for (unsigned i=0; i<nodes.size(); i++)
        {
            delete nodes[i];
        }
    }
    /**
     * Create a simulation of a NodeBasedCellPopulation to test movement threshold.
     */
    void TestMovementThreshold() throw (Exception)
    {
        EXIT_IF_PARALLEL;   // This test doesn't work in parallel because only one process will throw.

        // Creates nodes and mesh
        std::vector<Node<2>*> nodes;
        nodes.push_back(new Node<2>(0,  false,  0.0, 0.0));
        nodes.push_back(new Node<2>(0,  false,  0.0, 0.3));
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(nodes, 1.5);

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes());

        // Create a node based cell population
        NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells);
        node_based_cell_population.SetAbsoluteMovementThreshold(1e-6);

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(node_based_cell_population);
        simulator.SetEndTime(0.1);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithNodeBasedCellPopulationThreshold");

        // Create a force law and pass it to the simulation
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force);
        p_linear_force->SetCutOffLength(1.5);
        simulator.AddForce(p_linear_force);

        // Solve
        TS_ASSERT_THROWS_CONTAINS(simulator.Solve(),
                "which is more than the AbsoluteMovementThreshold:");

        // Avoid memory leak
        delete nodes[0];
        delete nodes[1];
    }
Ejemplo n.º 19
0
    void TestCellBasedPdeHandlerOutputParameters() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        std::string output_directory = "TestCellBasedPdeHandlerOutputParameters";
        OutputFileHandler output_file_handler(output_directory, false);

        // Create a cell population
        HoneycombMeshGenerator generator(2, 2, 0);
        MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());

        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        // Create a PDE handler object using this cell population
        CellBasedPdeHandler<2> pde_handler(&cell_population);

        // Test output methods
        TS_ASSERT_EQUALS(pde_handler.GetIdentifier(), "CellBasedPdeHandler-2");

        out_stream pde_handler_parameter_file = output_file_handler.OpenOutputFile("CellBasedPdeHandler.parameters");
        pde_handler.OutputParameters(pde_handler_parameter_file);
        pde_handler_parameter_file->close();

        {
            // Compare the generated file in test output with a reference copy in the source code.
            FileFinder generated = output_file_handler.FindFile("CellBasedPdeHandler.parameters");
            FileFinder reference("cell_based/test/data/TestCellBasedPdeHandler/CellBasedPdeHandler.parameters",
                    RelativeTo::ChasteSourceRoot);
            FileComparison comparer(generated, reference);
            TS_ASSERT(comparer.CompareFiles());
        }
    }
    void TestOnLatticeSimulationExceptions()
    {
        EXIT_IF_PARALLEL;

        // Create a simple tetrahedral mesh
        HoneycombMeshGenerator generator(3, 3, 0);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes());

        // Create a node-based cell population
        NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells);

        TS_ASSERT_THROWS_THIS(OnLatticeSimulation<2> simulator(node_based_cell_population),
                              "OnLatticeSimulations require a subclass of AbstractOnLatticeCellPopulation.");
    }
    /*
     * === Using the modifier in a cell-based simulation ===
     *
     * We conclude with a brief test demonstrating how {{{CellHeightTrackingModifier}}} can be used
     * in a cell-based simulation.
     */
    void TestOffLatticeSimulationWithCellHeightTrackingModifier()
    {
        /*
         * In this case, we choose to create a small {{{NodeBasedCellPopulation}}} comprising 25 cells.
         * We choose a cut-off for mechanical interactions between cells of 1.5 units and add a
         * simple {{{ReplusionForce}}} to the simulation. We use a {{{UniformCellCycleModel}}}
         * to implement some random proliferation in the simulation.
         */
        HoneycombMeshGenerator generator(2, 2, 0);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        std::vector<CellPtr> cells;
        MAKE_PTR(TransitCellProliferativeType, p_transit_type);
        CellsGenerator<UniformCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes(), p_transit_type);

        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        OffLatticeSimulation<2> simulator(cell_population);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithCellHeightTrackingModifier");
        simulator.SetSamplingTimestepMultiple(12);
        simulator.SetEndTime(20.0);

        MAKE_PTR(RepulsionForce<2>, p_force);
        simulator.AddForce(p_force);

        /*
         * Finally, we add a {{{CellHeightTrackingModifier}}} to the simulation.
         */
        MAKE_PTR(CellHeightTrackingModifier, p_modifier);
        simulator.AddSimulationModifier(p_modifier);

        /* To run the simulation, we call {{{Solve()}}}. */
        simulator.Solve();
    }
    /**
     * Create a simulation of a NodeBasedCellPopulation with all Buske forces.
     * Test that no exceptions are thrown.
     */
    void TestAllBuskeForces() throw (Exception)
    {
        EXIT_IF_PARALLEL;    // HoneycombMeshGenerator doesn't work in parallel

        // Create a simple mesh
        HoneycombMeshGenerator generator(5, 5, 0);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

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

        // Create a node-based cell population
        NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells);

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(node_based_cell_population);
        simulator.SetOutputDirectory("TestAllBuskeForces");
        simulator.SetEndTime(5.0);

        // Create a force law and pass it to the simulation
        MAKE_PTR(BuskeCompressionForce<2>, p_buske_compression_force);
        MAKE_PTR(BuskeElasticForce<2>, p_buske_elastic_force);
        MAKE_PTR(BuskeAdhesiveForce<2>, p_buske_adhesive_force);
        p_buske_compression_force->SetCompressionEnergyParameter(0.01);
        simulator.AddForce(p_buske_compression_force);
        simulator.AddForce(p_buske_elastic_force);
        simulator.AddForce(p_buske_adhesive_force);

        simulator.Solve();
    }
    void setUp()
    {
        AbstractCellBasedTestSuite::setUp();

        std::vector<Node<3>* > nodes;
        for (unsigned i=0; i<PetscTools::GetNumProcs(); i++)
        {
            nodes.push_back(new Node<3>(0, false, 0.0, 0.0, 0.5+(double)i));
        }

        mpNodesOnlyMesh = new NodesOnlyMesh<3>;
        mpNodesOnlyMesh->ConstructNodesWithoutMesh(nodes, 1.0);

        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 3> cells_generator;
        cells_generator.GenerateBasic(cells, mpNodesOnlyMesh->GetNumNodes());

        mpNodeBasedCellPopulation = new NodeBasedCellPopulation<3>(*mpNodesOnlyMesh, cells);

        for (unsigned i=0; i<nodes.size(); i++)
        {
            delete nodes[i];
        }
    }
    /*
     * === Using the cell property in a cell-based simulation ===
     *
     * We conclude with a brief test demonstrating how {{{MotileCellProperty}}} can be used
     * in a cell-based simulation.
     */
    void TestOffLatticeSimulationWithMotileCellProperty() throw(Exception)
    {
        /* Note that HoneycombMeshGenerator, used in this test, is not
         *  yet implemented in parallel. */

        /* We use the {{{HoneycombMeshGenerator}}} to create a honeycomb mesh covering a
         * circular domain of given radius, and use this to generate a {{{NodesOnlyMesh}}}
         * as follows. */
        HoneycombMeshGenerator generator(10, 10);
        MutableMesh<2,2>* p_generating_mesh = generator.GetCircularMesh(5);

        NodesOnlyMesh<2> mesh;
        /* We construct the mesh using the generating mesh and a cut-off 1.5 which defines the
         * connectivity in the mesh.
         */
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        /* We now create a shared pointer to our new property, as follows. */
        MAKE_PTR(MotileCellProperty, p_motile);
        /*
         * Also create a shared pointer to a cell label so we can visualize the
         * different cell types. Note that this is also a {{{CellProperty}}}.
         */
        MAKE_PTR(CellLabel, p_label);

        /* Next, we create some cells. We don't use a Generator as we want to give some cells the new cell property, therefore
         * we create the cells in a loop, as follows.*/
        MAKE_PTR(WildTypeCellMutationState, p_state);
        MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type);
        std::vector<CellPtr> cells;
        for (unsigned i=0; i<mesh.GetNumNodes(); i++)
        {
            /* For each node we create a cell with our cell-cycle model and the wild-type cell mutation state.
             * We then add the property {{{MotileCellProperty}}} to a random selection of the cells, as follows. */
            FixedDurationGenerationBasedCellCycleModel* p_model = new FixedDurationGenerationBasedCellCycleModel();

            CellPropertyCollection collection;
            if (RandomNumberGenerator::Instance()->ranf() < 0.2)
            {
                collection.AddProperty(p_motile);
                collection.AddProperty(p_label);
            }

            CellPtr p_cell(new Cell(p_state, p_model, false, collection));
            p_cell->SetCellProliferativeType(p_diff_type);

            /* Now, we define a random birth time, chosen from [-T,0], where
             * T = t,,1,, + t,,2,,, where t,,1,, is a parameter representing the G,,1,, duration
             * of a stem cell, and t,,2,, is the basic S+G,,2,,+M phases duration.
             */
            double birth_time = - RandomNumberGenerator::Instance()->ranf() *
                                    (p_model->GetStemCellG1Duration()
                                        + p_model->GetSG2MDuration());

            /* Finally, we set the birth time and push the cell back into the vector of cells. */
            p_cell->SetBirthTime(birth_time);
            cells.push_back(p_cell);
        }

        /* Now that we have defined the mesh and cells, we can define the cell population. The constructor
         * takes in the mesh and the cells vector. */
        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        /* In order to visualize labelled cells we need to use the following command.*/
        cell_population.AddCellPopulationCountWriter<CellMutationStatesCountWriter>();

        /* We then pass in the cell population into an {{{OffLatticeSimulation}}},
         * and set the output directory, output multiple, and end time. */
        OffLatticeSimulation<2> simulator(cell_population);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithMotileCellProperty");
        simulator.SetSamplingTimestepMultiple(12);
        simulator.SetEndTime(10.0);

        /* We create a force law and pass it to the {{{OffLatticeSimulation}}}. */
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force);
        p_linear_force->SetCutOffLength(1.5);
        simulator.AddForce(p_linear_force);

        /* Now create a {{{MotlieForce}}} and pass it to the {{{OffLatticeSimulation}}}. */
        MAKE_PTR(MyMotiveForce, p_motive_force);
        simulator.AddForce(p_motive_force);

        /* To run the simulation, we call {{{Solve()}}}. */
        simulator.Solve();
    }
Ejemplo n.º 25
0
    void TestWritingToFile() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        std::string output_directory = "TestCellBasedPdeHandlerWritingToFile";

        // Create a cell population
        HoneycombMeshGenerator generator(4, 4, 0);
        MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());
        TS_ASSERT_EQUALS(cells.size(), mesh.GetNumNodes());
        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        cell_population.SetDataOnAllCells("variable", 1.0);

        // Create a PDE handler object using this cell population
        CellBasedPdeHandler<2> pde_handler(&cell_population);

        TS_ASSERT_THROWS_THIS(pde_handler.OpenResultsFiles(output_directory),
                "Trying to solve a PDE on a cell population that doesn't have a mesh. Try calling UseCoarsePdeMesh().");

        // Use a coarse PDE mesh since we are using a node-based cell population
        AveragedSourcePde<2> pde(cell_population, -0.1);
        ConstBoundaryCondition<2> bc(1.0);
        PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false);
        pde_and_bc.SetDependentVariableName("variable");
        pde_handler.AddPdeAndBc(&pde_and_bc);

        ChastePoint<2> lower(0.0, 0.0);
        ChastePoint<2> upper(9.0, 9.0);
        ChasteCuboid<2> cuboid(lower, upper);

        pde_handler.UseCoarsePdeMesh(3.0, cuboid, true);

        // For coverage, call SetWriteAverageRadialPdeSolution() prior to output
        pde_handler.SetWriteAverageRadialPdeSolution("variable", 5, true);

        // Test that output files are opened correctly
        pde_handler.OpenResultsFiles(output_directory);

        FileFinder file_finder(output_directory + "/results.vizcoarsepdesolution", RelativeTo::ChasteTestOutput);
        TS_ASSERT(file_finder.Exists());
        TS_ASSERT(file_finder.IsFile());

        FileFinder file_finder2(output_directory + "/radial_dist.dat", RelativeTo::ChasteTestOutput);
        TS_ASSERT(file_finder2.Exists());
        TS_ASSERT(file_finder2.IsFile());

        TS_ASSERT_THROWS_NOTHING(pde_handler.CloseResultsFiles());

        // For coverage, also test that output files are opened correctly when not using a coarse PDE mesh
        HoneycombMeshGenerator generator2(5, 5, 0);
        MutableMesh<2,2>* p_mesh2 = generator2.GetMesh();

        std::vector<CellPtr> cells2;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator2;
        cells_generator2.GenerateBasic(cells2, p_mesh2->GetNumNodes());

        MeshBasedCellPopulation<2> cell_population2(*p_mesh2, cells2);

        cell_population2.SetDataOnAllCells("another variable", 1.0);

        CellBasedPdeHandler<2> pde_handler2(&cell_population2);
        pde_handler2.OpenResultsFiles(output_directory);

        FileFinder file_finder3(output_directory + "/results.vizpdesolution", RelativeTo::ChasteTestOutput);
        TS_ASSERT(file_finder3.Exists());
        TS_ASSERT(file_finder3.IsFile());

        pde_handler2.CloseResultsFiles();
    }
    /**
     * Create a simulation of a NodeBasedCellPopulation with variable cell radii.
     */
    void TestSimpleMonolayerWithVariableRadii() throw (Exception)
    {
        // Creates nodes and mesh
        std::vector<Node<2>*> nodes;
        nodes.push_back(new Node<2>(0,  false,  0.0, 0.0));
        nodes.push_back(new Node<2>(1,  false,  1.0, 0.0));
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(nodes, 5.0);    // Larger cut off as bigger cells.

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

        // Store the radius of the cells in Cell Data
        if (PetscTools::AmMaster())
        {
            cells[0]->GetCellData()->SetItem("Radius", 1.0);
            cells[1]->GetCellData()->SetItem("Radius", 2.0);
        }

        // Create a node-based cell population
        NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells);
        node_based_cell_population.SetUseVariableRadii(true);
        node_based_cell_population.AddCellWriter<CellVolumesWriter>();
        node_based_cell_population.Update();

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(node_based_cell_population);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithNodeBasedCellPopulationAndVariableRadii");
        simulator.SetSamplingTimestepMultiple(12);
        simulator.SetEndTime(10.0);

        // Create a force law and pass it to the simulation
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force);
        p_linear_force->SetCutOffLength(5.0); // Different as bigger cells
        simulator.AddForce(p_linear_force);

        simulator.Solve();

        // Check the radii of all the cells are correct; cell 0 divided into 0 and 3 and cell 1 divided into 1 and 2.
        // This testing is designed for sequential code.
        if (PetscTools::IsSequential())
        {
            TS_ASSERT_DELTA(mesh.GetNode(0)->GetRadius(), 1.0, 1e-6);
            TS_ASSERT_DELTA(mesh.GetNode(1)->GetRadius(), 2.0, 1e-6);
            TS_ASSERT_DELTA(mesh.GetNode(2)->GetRadius(), 2.0, 1e-6);
            TS_ASSERT_DELTA(mesh.GetNode(3)->GetRadius(), 1.0, 1e-6);

            // Check the separation of some node pairs
            TS_ASSERT_DELTA(norm_2(simulator.rGetCellPopulation().GetNode(0)->rGetLocation()-simulator.rGetCellPopulation().GetNode(1)->rGetLocation()), 3.0, 1e-1);
            TS_ASSERT_DELTA(norm_2(simulator.rGetCellPopulation().GetNode(0)->rGetLocation()-simulator.rGetCellPopulation().GetNode(2)->rGetLocation()), 4.70670, 1e-1);
            TS_ASSERT_DELTA(norm_2(simulator.rGetCellPopulation().GetNode(0)->rGetLocation()-simulator.rGetCellPopulation().GetNode(3)->rGetLocation()), 2.0, 1e-1);

            // Now set all the Radii to 2.0 Note this could be done inside a cell cycle model.
            for (AbstractCellPopulation<2>::Iterator cell_iter = simulator.rGetCellPopulation().Begin();
                 cell_iter != simulator.rGetCellPopulation().End();
                 ++cell_iter)
            {
                cell_iter->GetCellData()->SetItem("Radius",2.0);
            }

            simulator.SetEndTime(12.0);
            simulator.Solve();

            for (unsigned i=0; i<simulator.rGetCellPopulation().GetNumNodes(); i++)
            {
                TS_ASSERT_DELTA(mesh.GetNode(i)->GetRadius(), 2.0, 1e-6);
            }

            // Check the separation of some node pairs
            TS_ASSERT_DELTA(norm_2(simulator.rGetCellPopulation().GetNode(0)->rGetLocation()-simulator.rGetCellPopulation().GetNode(1)->rGetLocation()), 4.0, 1e-3);
            TS_ASSERT_DELTA(norm_2(simulator.rGetCellPopulation().GetNode(0)->rGetLocation()-simulator.rGetCellPopulation().GetNode(2)->rGetLocation()), 6.9282, 1e-3);
            TS_ASSERT_DELTA(norm_2(simulator.rGetCellPopulation().GetNode(0)->rGetLocation()-simulator.rGetCellPopulation().GetNode(3)->rGetLocation()), 4.0, 1e-3);
        }

        // Clean up memory
        for (unsigned i=0; i<nodes.size(); i++)
        {
            delete nodes[i];
        }
    }
    /**
     * Create a simulation of a NodeBasedCellPopulation with a NodeBasedCellPopulationMechanicsSystem
     * and a CellKiller. Test that no exceptions are thrown, and write the results to file.
     */
    void TestCellDeath() throw (Exception)
    {
        EXIT_IF_PARALLEL;    // HoneycombMeshGenereator does not work in parallel.

        // Create a simple mesh
        int num_cells_depth = 5;
        int num_cells_width = 5;
        HoneycombMeshGenerator generator(num_cells_width, num_cells_depth, 0);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();

        // Convert this to a NodesOnlyMesh
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        // Create cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes());

        // Create a node based cell population
        NodeBasedCellPopulation<2> node_based_cell_population(mesh, cells);

        // Set up cell-based simulation
        OffLatticeSimulation<2> simulator(node_based_cell_population);
        simulator.SetOutputDirectory("TestOffLatticeSimulationWithNodeBasedCellPopulationCellPtrDeath");
        simulator.SetEndTime(0.5);

        // Create a force law and pass it to the simulation
        MAKE_PTR(GeneralisedLinearSpringForce<2>, p_linear_force);
        p_linear_force->SetCutOffLength(1.5);
        simulator.AddForce(p_linear_force);

        // Add cell killer
        MAKE_PTR_ARGS(RandomCellKiller<2>, p_killer, (&node_based_cell_population, 0.997877574));
        simulator.AddCellKiller(p_killer);

        // Solve
        simulator.Solve();

        // Check some results
        TS_ASSERT_EQUALS(simulator.GetNumBirths(), 0u);
        TS_ASSERT_EQUALS(simulator.GetNumDeaths(), 20u);

        std::vector<double> node_8_location = simulator.GetNodeLocation(8);
        TS_ASSERT_DELTA(node_8_location[0], 3.4729, 1e-4);
        TS_ASSERT_DELTA(node_8_location[1], 1.0051, 1e-4);

        std::vector<double> node_3_location = simulator.GetNodeLocation(3);
        TS_ASSERT_DELTA(node_3_location[0], 2.9895, 1e-4);
        TS_ASSERT_DELTA(node_3_location[1], 0.3105, 1e-4);

        // Test the results are written correctly
        FileFinder generated_type_file("TestOffLatticeSimulationWithNodeBasedCellPopulationCellPtrDeath/results_from_time_0/results.vizcelltypes", RelativeTo::ChasteTestOutput);
        FileFinder generated_node_file("TestOffLatticeSimulationWithNodeBasedCellPopulationCellPtrDeath/results_from_time_0/results.viznodes", RelativeTo::ChasteTestOutput);

        FileFinder reference_type_file("cell_based/test/data/TestOffLatticeSimulationWithNodeBasedCellPopulationCellPtrDeath/results.vizcelltypes",RelativeTo::ChasteSourceRoot);
        FileFinder reference_node_file("cell_based/test/data/TestOffLatticeSimulationWithNodeBasedCellPopulationCellPtrDeath/results.viznodes",RelativeTo::ChasteSourceRoot);

        FileComparison type_files(generated_type_file,reference_type_file);
        FileComparison node_files(generated_node_file,reference_node_file);
    }
Ejemplo n.º 28
0
    void TestUseCoarsePdeMesh() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        // Create a cell population
        HoneycombMeshGenerator generator(4, 4, 0);
        MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());

        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        // Create a PDE handler object using this cell population
        CellBasedPdeHandler<2> pde_handler(&cell_population);

        // Test that UseCoarsePdeMesh() throws an exception if no PDEs are specified
        ChastePoint<2> lower(0.0, 0.0);
        ChastePoint<2> upper(9.0, 9.0);
        ChasteCuboid<2> cuboid(lower, upper);
        TS_ASSERT_THROWS_THIS(pde_handler.UseCoarsePdeMesh(3.0, cuboid, true),
            "mPdeAndBcCollection should be populated prior to calling UseCoarsePdeMesh().");

        // Set up PDE and pass to handler
        AveragedSourcePde<2> pde(cell_population, -0.1);
        ConstBoundaryCondition<2> bc(1.0);
        PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false);
        pde_handler.AddPdeAndBc(&pde_and_bc);

        // Test UseCoarsePdeMesh() again
        pde_handler.UseCoarsePdeMesh(3.0, cuboid, true);

        // Test that the coarse mesh has the correct number of nodes and elements
        TetrahedralMesh<2,2>* p_coarse_mesh = pde_handler.GetCoarsePdeMesh();
        TS_ASSERT_EQUALS(p_coarse_mesh->GetNumNodes(), 16u);
        TS_ASSERT_EQUALS(p_coarse_mesh->GetNumElements(), 18u);

        // Find centre of cell population
        c_vector<double,2> centre_of_cell_population = cell_population.GetCentroidOfCellPopulation();

        // Find centre of coarse PDE mesh
        c_vector<double,2> centre_of_coarse_pde_mesh = zero_vector<double>(2);
        for (unsigned i=0; i<p_coarse_mesh->GetNumNodes(); i++)
        {
            centre_of_coarse_pde_mesh += p_coarse_mesh->GetNode(i)->rGetLocation();
        }
        centre_of_coarse_pde_mesh /= p_coarse_mesh->GetNumNodes();

        // Test that the two centres match
        c_vector<double,2> centre_difference = centre_of_cell_population - centre_of_coarse_pde_mesh;
        TS_ASSERT_DELTA(norm_2(centre_difference), 0.0, 1e-4);

        // Test that UseCoarsePdeMesh()  throws an exception if the wrong type of PDE is specified
        SimpleUniformSourcePde<2> pde2(-0.1);
        ConstBoundaryCondition<2> bc2(1.0);
        PdeAndBoundaryConditions<2> pde_and_bc2(&pde2, &bc2, false);
        pde_and_bc2.SetDependentVariableName("second variable");
        pde_handler.AddPdeAndBc(&pde_and_bc2);

        TS_ASSERT_THROWS_THIS(pde_handler.UseCoarsePdeMesh(3.0, cuboid, true),
            "UseCoarsePdeMesh() should only be called if averaged-source PDEs are specified.");

        // Now test the 1D case
        std::vector<Node<1>*> nodes_1d;
        nodes_1d.push_back(new Node<1>(0, true,  0.0));

        NodesOnlyMesh<1> mesh_1d;
        mesh_1d.ConstructNodesWithoutMesh(nodes_1d, 1.5);

        std::vector<CellPtr> cells_1d;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 1> cells_generator_1d;
        cells_generator_1d.GenerateBasic(cells_1d, mesh_1d.GetNumNodes());

        NodeBasedCellPopulation<1> cell_population_1d(mesh_1d, cells_1d);

        CellBasedPdeHandler<1> pde_handler_1d(&cell_population_1d);

        AveragedSourcePde<1> pde_1d(cell_population_1d, -0.1);
        ConstBoundaryCondition<1> bc_1d(1.0);
        PdeAndBoundaryConditions<1> pde_and_bc_1d(&pde_1d, &bc_1d, false);
        pde_handler_1d.AddPdeAndBc(&pde_and_bc_1d);

        ChastePoint<1> lower1(0.0);
        ChastePoint<1> upper1(9.0);
        ChasteCuboid<1> cuboid1(lower1, upper1);
        pde_handler_1d.UseCoarsePdeMesh(3.0, cuboid1, true);

        // Test that the coarse mesh has the correct number of nodes and elements
        TetrahedralMesh<1,1>* p_coarse_mesh_1d = pde_handler_1d.GetCoarsePdeMesh();
        TS_ASSERT_EQUALS(p_coarse_mesh_1d->GetNumNodes(), 4u);
        TS_ASSERT_EQUALS(p_coarse_mesh_1d->GetNumElements(), 3u);

        // Now test the 3D case
        std::vector<Node<3>*> nodes_3d;
        nodes_3d.push_back(new Node<3>(0, true,  0.0));

        NodesOnlyMesh<3> mesh_3d;
        mesh_3d.ConstructNodesWithoutMesh(nodes_3d, 1.5);

        std::vector<CellPtr> cells_3d;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 3> cells_generator_3d;
        cells_generator_3d.GenerateBasic(cells_3d, mesh_3d.GetNumNodes());

        NodeBasedCellPopulation<3> cell_population_3d(mesh_3d, cells_3d);

        CellBasedPdeHandler<3> pde_handler_3d(&cell_population_3d);

        AveragedSourcePde<3> pde_3d(cell_population_3d, -0.1);
        ConstBoundaryCondition<3> bc_3d(1.0);
        PdeAndBoundaryConditions<3> pde_and_bc_3d(&pde_3d, &bc_3d, false);
        pde_handler_3d.AddPdeAndBc(&pde_and_bc_3d);

        ChastePoint<3> lower3(0.0, 0.0, 0.0);
        ChastePoint<3> upper3(9.0, 9.0, 9.0);
        ChasteCuboid<3> cuboid3(lower3, upper3);

        pde_handler_3d.UseCoarsePdeMesh(3.0, cuboid3, true);

        // Test that the coarse mesh has the correct number of nodes and elements
        TetrahedralMesh<3,3>* p_coarse_mesh_3d = pde_handler_3d.GetCoarsePdeMesh();
        TS_ASSERT_EQUALS(p_coarse_mesh_3d->GetNumNodes(), 64u);
        TS_ASSERT_EQUALS(p_coarse_mesh_3d->GetNumElements(), 162u);

        // Avoid memory leak
        for (unsigned i=0; i<nodes_1d.size(); i++)
        {
            delete nodes_1d[i];
            delete nodes_3d[i];
        }
    }
Ejemplo n.º 29
0
    void TestArchivingOfPdeHandlerOnCuboid() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        FileFinder archive_dir("archive", RelativeTo::ChasteTestOutput);
        std::string archive_file = "CellBasedPdeHandlerOnCuboid.arch";
        ArchiveLocationInfo::SetMeshFilename("pde_handler_mesh");

        {
            // Create a cell population
            HoneycombMeshGenerator generator(2, 2, 0);
            MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
            NodesOnlyMesh<2> mesh;
            mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

            std::vector<CellPtr> cells;
            CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
            cells_generator.GenerateBasic(cells, mesh.GetNumNodes());

            NodeBasedCellPopulation<2> cell_population(mesh, cells);

            // Create a PDE handler object using this cell population
            CellBasedPdeHandlerOnCuboid<2>* const p_pde_handler = new CellBasedPdeHandlerOnCuboid<2>(&cell_population);

            // Set member variables for testing
            p_pde_handler->SetWriteAverageRadialPdeSolution("averaged quantity", 5, true);
            p_pde_handler->SetImposeBcsOnCoarseBoundary(false);

            // Set up PDE and pass to handler
            AveragedSourcePde<2> pde(cell_population, -0.1);
            ConstBoundaryCondition<2> bc(1.0);
            PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false);
            pde_and_bc.SetDependentVariableName("averaged quantity");
            p_pde_handler->AddPdeAndBc(&pde_and_bc);

            // Test UseCoarsePdeMesh() again
            ChastePoint<2> lower(0.0, 0.0);
            ChastePoint<2> upper(9.0, 9.0);
            ChasteCuboid<2> cuboid(lower, upper);
            p_pde_handler->UseCoarsePdeMesh(3.0, cuboid, true);

            // Create an output archive
            ArchiveOpener<boost::archive::text_oarchive, std::ofstream> arch_opener(archive_dir, archive_file);
            boost::archive::text_oarchive* p_arch = arch_opener.GetCommonArchive();

            // Archive object
            SimulationTime* p_simulation_time = SimulationTime::Instance();
            p_simulation_time->SetEndTimeAndNumberOfTimeSteps(1.0, 11);
            (*p_arch) << static_cast<const SimulationTime&>(*p_simulation_time);
            (*p_arch) << p_pde_handler;

            // Tidy up
            SimulationTime::Destroy();
            delete p_pde_handler;
        }

        {
            CellBasedPdeHandlerOnCuboid<2>* p_pde_handler;

            // Create an input archive
            ArchiveOpener<boost::archive::text_iarchive, std::ifstream> arch_opener(archive_dir, archive_file);
            boost::archive::text_iarchive* p_arch = arch_opener.GetCommonArchive();

            // Restore object from the archive
            SimulationTime* p_simulation_time = SimulationTime::Instance();
            (*p_arch) >> *p_simulation_time;
            (*p_arch) >> p_pde_handler;

            // Test that the member variables were archived correctly
            TS_ASSERT_EQUALS(p_pde_handler->mpCellPopulation->GetNumRealCells(), 4u);
            TS_ASSERT_EQUALS(p_pde_handler->GetWriteAverageRadialPdeSolution(), true);
            TS_ASSERT_EQUALS(p_pde_handler->GetWriteDailyAverageRadialPdeSolution(), true);
            TS_ASSERT_EQUALS(p_pde_handler->GetImposeBcsOnCoarseBoundary(), false);
            TS_ASSERT_EQUALS(p_pde_handler->GetNumRadialIntervals(), 5u);
            TS_ASSERT_EQUALS(p_pde_handler->mAverageRadialSolutionVariableName, "averaged quantity");

            ///\todo we currently do not archive mpCoarsePdeMesh - consider doing this (#1891)
            TS_ASSERT(p_pde_handler->GetCoarsePdeMesh() == NULL);

            TS_ASSERT_EQUALS(p_pde_handler->mPdeAndBcCollection.size(), 1u);
            TS_ASSERT_EQUALS(p_pde_handler->mPdeAndBcCollection[0]->IsNeumannBoundaryCondition(), false);

            // Tidy up
            delete p_pde_handler->mpCellPopulation;
            delete p_pde_handler;
        }
    }
Ejemplo n.º 30
0
    void TestSetMethods() throw(Exception)
    {
        EXIT_IF_PARALLEL;

        // Create a cell population
        HoneycombMeshGenerator generator(2, 2, 0);
        MutableMesh<2,2>* p_generating_mesh = generator.GetMesh();
        NodesOnlyMesh<2> mesh;
        mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5);

        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator;
        cells_generator.GenerateBasic(cells, mesh.GetNumNodes());

        NodeBasedCellPopulation<2> cell_population(mesh, cells);

        // Create a PDE handler object using this cell population
        CellBasedPdeHandler<2> pde_handler(&cell_population);

        // Test set and get methods
        pde_handler.SetWriteAverageRadialPdeSolution("averaged quantity");

        TS_ASSERT_EQUALS(pde_handler.GetWriteAverageRadialPdeSolution(), true);
        TS_ASSERT_EQUALS(pde_handler.GetWriteDailyAverageRadialPdeSolution(), false);
        TS_ASSERT_EQUALS(pde_handler.GetNumRadialIntervals(), 10u);

        pde_handler.SetWriteAverageRadialPdeSolution("averaged quantity", 5, true);

        TS_ASSERT_EQUALS(pde_handler.GetWriteAverageRadialPdeSolution(), true);
        TS_ASSERT_EQUALS(pde_handler.GetWriteDailyAverageRadialPdeSolution(), true);
        TS_ASSERT_EQUALS(pde_handler.GetNumRadialIntervals(), 5u);

        pde_handler.SetImposeBcsOnCoarseBoundary(false);
        TS_ASSERT_EQUALS(pde_handler.GetImposeBcsOnCoarseBoundary(), false);

        // Test AddPdeAndBc()
        SimpleUniformSourcePde<2> pde(-0.1);
        ConstBoundaryCondition<2> bc(1.0);
        PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false);
        pde_and_bc.SetDependentVariableName("averaged quantity");

        unsigned num_nodes = mesh.GetNumNodes();
        std::vector<double> data(num_nodes);
        for (unsigned i=0; i<num_nodes; i++)
        {
            data[i] = i + 0.45;
        }

        Vec vector = PetscTools::CreateVec(data);
        pde_and_bc.SetSolution(vector);

        pde_handler.AddPdeAndBc(&pde_and_bc);

        TS_ASSERT_EQUALS(pde_handler.mPdeAndBcCollection[0]->IsNeumannBoundaryCondition(), false);
        TS_ASSERT_EQUALS(pde_handler.mPdeAndBcCollection[0]->HasAveragedSourcePde(), false);

        ReplicatableVector solution(pde_handler.GetPdeSolution());

        TS_ASSERT_EQUALS(solution.GetSize(), num_nodes);
        for (unsigned i=0; i<num_nodes; i++)
        {
            TS_ASSERT_DELTA(solution[i], i + 0.45, 1e-4);
        }
    }