예제 #1
0
파일: automata.c 프로젝트: kylc/automata
struct cells_t *apply_rule(cell_state rule[8], struct cells_t *cells) {
  struct cells_t *new_cells = cells_copy(cells);

  for(size_t i = 1; i < cells_length(cells) - 1; i++) {
    cell_state newval = lookup_rule_table(rule, cells, i);
    cells_set_state(new_cells, i, newval);
  }

  return new_cells;
}
    /*
    * 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");
    }
    void TestValidate() throw (Exception)
    {
        // Create a simple Potts mesh
        PottsMeshGenerator<2> generator(4, 2, 2, 4, 2, 2);
        PottsMesh<2>* p_mesh = generator.GetMesh();

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

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

        // This should throw an exception as the number of cells does not equal the number of elements
        std::vector<CellPtr> cells_copy(cells);
        TS_ASSERT_THROWS_THIS(PottsBasedCellPopulation<2> cell_population(*p_mesh, cells_copy),
                "At time 0, Element 3 does not appear to have a cell associated with it");

        MAKE_PTR(WildTypeCellMutationState, p_state);
        MAKE_PTR(StemCellProliferativeType, p_stem_type);
        FixedDurationGenerationBasedCellCycleModel* p_model = new FixedDurationGenerationBasedCellCycleModel();
        CellPtr p_cell1(new Cell(p_state, p_model));
        p_cell1->SetCellProliferativeType(p_stem_type);

        double birth_time = 0.0 - p_mesh->GetNumElements()-1;
        p_cell1->SetBirthTime(birth_time);

        cells.push_back(p_cell1);
        cell_location_indices.push_back(p_mesh->GetNumElements()-1);

        // This should pass as the number of cells equals the number of elements
        std::vector<CellPtr> cells_copy2(cells);
        TS_ASSERT_THROWS_NOTHING(PottsBasedCellPopulation<2> cell_population(*p_mesh, cells_copy2));

        // Create cell population
        PottsBasedCellPopulation<2> cell_population(*p_mesh, cells);

        // Check correspondence between elements and cells
        for (PottsMesh<2>::PottsElementIterator iter = p_mesh->GetElementIteratorBegin();
             iter != p_mesh->GetElementIteratorEnd();
             ++iter)
        {
            std::set<unsigned> expected_node_indices;
            unsigned expected_index = iter->GetIndex();

            for (unsigned i=0; i<iter->GetNumNodes(); i++)
            {
                expected_node_indices.insert(iter->GetNodeGlobalIndex(i));
            }

            std::set<unsigned> actual_node_indices;
            unsigned elem_index = iter->GetIndex();
            CellPtr p_cell = cell_population.GetCellUsingLocationIndex(elem_index);
            PottsElement<2>* p_actual_element = cell_population.GetElementCorrespondingToCell(p_cell);
            unsigned actual_index = p_actual_element->GetIndex();

            for (unsigned i=0; i<p_actual_element->GetNumNodes(); i++)
            {
                actual_node_indices.insert(p_actual_element->GetNodeGlobalIndex(i));
            }

            TS_ASSERT_EQUALS(actual_index, expected_index);
            TS_ASSERT_EQUALS(actual_node_indices, expected_node_indices);
        }

        // Create another simple potts-based mesh
        PottsMeshGenerator<2> generator2(4, 2, 2, 4, 2, 2);
        PottsMesh<2>* p_mesh2 = generator2.GetMesh();

        // Create cells
        std::vector<CellPtr> cells2;
        CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator2;
        cells_generator2.GenerateBasic(cells2, p_mesh2->GetNumElements()+1);

        std::vector<unsigned> cell_location_indices2;
        for (unsigned i=0; i<cells2.size(); i++)
        {
            cell_location_indices2.push_back(i%p_mesh2->GetNumElements()); // Element 0 will have 2 cells
        }

        // This should throw a never-reached exception as the number of cells
        // does not equal the number of elements
        TS_ASSERT_THROWS_THIS(PottsBasedCellPopulation<2> cell_population2(*p_mesh2, cells2, false, true, cell_location_indices2),
            "At time 0, Element 0 appears to have 2 cells associated with it");
    }