コード例 #1
0
    void TestUpdateCellProcessLocation() throw (Exception)
    {
        if (PetscTools::GetNumProcs() > 1)
        {
            if (PetscTools::AmMaster())
            {
                // Move node to the next location.
                c_vector<double, 3> new_location = zero_vector<double>(3);
                new_location[2] = 1.6;
                ChastePoint<3> point(new_location);
                mpNodesOnlyMesh->GetNode(0)->SetPoint(point);
            }
            if (PetscTools::GetMyRank() == 1)
            {
                // Move node to the next location.
                c_vector<double, 3> new_location = zero_vector<double>(3);
                new_location[2] = 0.5;
                ChastePoint<3> point(new_location);
                mpNodesOnlyMesh->GetNode(1)->SetPoint(point);
            }
#if BOOST_VERSION < 103700
        TS_ASSERT_THROWS_THIS(mpNodeBasedCellPopulation->SendCellsToNeighbourProcesses(),
                              "Parallel cell-based Chaste requires Boost >= 1.37");
#else
            mpNodeBasedCellPopulation->UpdateCellProcessLocation();

            if (PetscTools::AmMaster())
            {
                TS_ASSERT_EQUALS(mpNodesOnlyMesh->GetNumNodes(), 1u);
                TS_ASSERT_EQUALS(mpNodeBasedCellPopulation->GetNumRealCells(), 1u);
            }
            if (PetscTools::GetMyRank() == 1)
            {
                TS_ASSERT_EQUALS(mpNodesOnlyMesh->GetNumNodes(), 1u);
                TS_ASSERT_EQUALS(mpNodeBasedCellPopulation->GetNumRealCells(), 1u);

                AbstractMesh<3,3>::NodeIterator node_iter = mpNodesOnlyMesh->GetNodeIteratorBegin();
                TS_ASSERT_DELTA(node_iter->rGetLocation()[2], 1.6, 1e-4);
            }
#endif
        }
    }
    /**
     * Create a simulation of a NodeBasedCellPopulation with different cell radii.
     */
    void TestSimpleMonolayerWithDifferentRadii() 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);    // Large cut off as larger cells.

        // Modify the radii of the cells
        if (PetscTools::AmMaster())
        {
            mesh.GetNode(0)->SetRadius(1.0);
            mesh.GetNode(PetscTools::GetNumProcs())->SetRadius(2.0);
        }

        // 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);
        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("TestOffLatticeSimulationWithNodeBasedCellPopulationAndDifferentRadi");
        simulator.SetSamplingTimestepMultiple(12);
        simulator.SetEndTime(12.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 that the radii of all the cells are correct
        // (cell 0 divided into 0 and 3 and cell 1 divided into 1 and 2)
        if (PetscTools::AmMaster())
        {
            TS_ASSERT_DELTA(mesh.GetNode(0)->GetRadius(), 1.0, 1e-6);
            TS_ASSERT_DELTA(mesh.GetNode(PetscTools::GetNumProcs())->GetRadius(), 2.0, 1e-6);
            TS_ASSERT_DELTA(mesh.GetNode(2*PetscTools::GetNumProcs())->GetRadius(), 2.0, 1e-6);
            TS_ASSERT_DELTA(mesh.GetNode(3*PetscTools::GetNumProcs())->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(PetscTools::GetNumProcs())->rGetLocation()), 2.9710, 1e-1);
            TS_ASSERT_DELTA(norm_2(simulator.rGetCellPopulation().GetNode(0)->rGetLocation()-simulator.rGetCellPopulation().GetNode(2*PetscTools::GetNumProcs())->rGetLocation()), 4.7067, 1e-1);
            TS_ASSERT_DELTA(norm_2(simulator.rGetCellPopulation().GetNode(0)->rGetLocation()-simulator.rGetCellPopulation().GetNode(3*PetscTools::GetNumProcs())->rGetLocation()), 2.0, 1e-1);
        }

        // Clean up memory
        for (unsigned i=0; i<nodes.size(); i++)
        {
            delete nodes[i];
        }
    }
    /**
     * 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];
        }
    }
    // Test with particles, checking that the Iterator doesn't loop over particles
    void TestNodeBasedCellPopulationWithParticlesSetup() throw(Exception)
    {
        EXIT_IF_PARALLEL;    // This test doesn't work in parallel.

        unsigned num_cells_depth = 11;
        unsigned num_cells_width = 6;
        HoneycombMeshGenerator generator(num_cells_width, num_cells_depth, 2);
        TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh();

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

        std::vector<unsigned> location_indices = generator.GetCellLocationIndices();

        // Set up cells
        std::vector<CellPtr> cells;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel,2> cells_generator;
        cells_generator.GenerateGivenLocationIndices(cells, location_indices);

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

        // Create a set of node indices corresponding to particles
        std::set<unsigned> node_indices;
        std::set<unsigned> location_indices_set;
        std::set<unsigned> particle_indices;

        for (unsigned i=0; i<mesh.GetNumNodes(); i++)
        {
            node_indices.insert(mesh.GetNode(i)->GetIndex());
        }
        for (unsigned i=0; i<location_indices.size(); i++)
        {
            location_indices_set.insert(location_indices[i]);
        }

        std::set_difference(node_indices.begin(), node_indices.end(),
                            location_indices_set.begin(), location_indices_set.end(),
                            std::inserter(particle_indices, particle_indices.begin()));

        std::vector<bool> is_particle(mesh.GetNumNodes(), false);
        for (std::set<unsigned>::iterator it=particle_indices.begin();
                it!=particle_indices.end();
                it++)
        {
            TS_ASSERT_EQUALS(cell_population.GetNode(*it)->IsParticle(), true)
        }

        // Test the GetParticleIndices method
        std::set<unsigned> particle_indices2 = cell_population.GetParticleIndices();
        TS_ASSERT_EQUALS(particle_indices, particle_indices2);

        // Check the iterator doesn't loop over particles
        unsigned counter = 0;
        for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin();
                cell_iter != cell_population.End();
                ++cell_iter)
        {
            unsigned node_index = cell_population.GetLocationIndexUsingCell(*cell_iter);
            TS_ASSERT(!is_particle[node_index]);
            counter++;
        }

        TS_ASSERT_EQUALS(counter, cell_population.GetNumRealCells());

        // Check counter = num_nodes - num_particles_nodes
        TS_ASSERT_EQUALS(counter + particle_indices.size(), mesh.GetNumNodes());
    }