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); }
/** * 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); }
// 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 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); }
// 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]; }
/** * 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]; }
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."); }
/** * 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(); }
/** * 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); }
/** * 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 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 a Cylindrical2dNodesOnlyMesh * to test periodicity. */ void TestSimplePeriodicMonolayer() throw (Exception) { EXIT_IF_PARALLEL; // HoneycombMeshGenereator does not work in parallel. // Create a simple periodic mesh unsigned num_cells_depth = 3; unsigned num_cells_width = 3; HoneycombMeshGenerator generator(num_cells_width, num_cells_depth, 0); TetrahedralMesh<2,2>* p_generating_mesh = generator.GetMesh(); // Convert this to a Cylindrical2dNodesOnlyMesh double periodic_width = 4.0; Cylindrical2dNodesOnlyMesh mesh(periodic_width); mesh.ConstructNodesWithoutMesh(*p_generating_mesh, periodic_width); // 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("TestOffLatticeSimulationWithPeriodicNodeBasedCellPopulation"); // Run for long enough to see the periodic bounday influencing the cells 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(1.5); simulator.AddForce(p_linear_force); simulator.Solve(); // Check that nothing's gone badly wrong by testing that nodes aren't outside the domain for (unsigned i=0; i<simulator.rGetCellPopulation().GetNumNodes(); i++) { TS_ASSERT_LESS_THAN_EQUALS(0,simulator.rGetCellPopulation().GetNode(i)->rGetLocation()[0]); TS_ASSERT_LESS_THAN_EQUALS(simulator.rGetCellPopulation().GetNode(i)->rGetLocation()[0],periodic_width); } // Now run the simulation again with the periodic boundary in a different place and check its the same // First reset the singletons SimulationTime::Instance()->Destroy(); SimulationTime::Instance()->SetStartTime(0.0); RandomNumberGenerator::Instance()->Reseed(0); double x_offset = periodic_width/2.0; p_generating_mesh->Translate(x_offset,0.0); // Convert this to a Cylindrical2dNodesOnlyMesh Cylindrical2dNodesOnlyMesh mesh_2(periodic_width); mesh_2.ConstructNodesWithoutMesh(*p_generating_mesh, periodic_width); // Create cells std::vector<CellPtr> cells_2; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator_2; cells_generator_2.GenerateBasicRandom(cells_2, mesh_2.GetNumNodes()); // Create a node-based cell population NodeBasedCellPopulation<2> node_based_cell_population_2(mesh_2, cells_2); // Set up cell-based simulation OffLatticeSimulation<2> simulator_2(node_based_cell_population_2); simulator_2.SetOutputDirectory("TestOffLatticeSimulationWith2ndPeriodicNodeBasedCellPopulation"); // Run for long enough to see the periodic boundary influencing the cells simulator_2.SetEndTime(10.0); // Pass the same force law to the simulation simulator_2.AddForce(p_linear_force); simulator_2.Solve(); // Check that nothing's gone badly wrong by testing that nodes aren't outside the domain for (unsigned i=0; i<simulator.rGetCellPopulation().GetNumNodes(); i++) { double x_1 = simulator.rGetCellPopulation().GetNode(i)->rGetLocation()[0]; double x_2 = simulator_2.rGetCellPopulation().GetNode(i)->rGetLocation()[0]; if (x_1 < x_offset) { TS_ASSERT_DELTA(x_1+x_offset, x_2, 1e-6) } else { TS_ASSERT_DELTA(x_1-x_offset, x_2, 1e-6) } TS_ASSERT_DELTA(simulator.rGetCellPopulation().GetNode(i)->rGetLocation()[1],simulator_2.rGetCellPopulation().GetNode(i)->rGetLocation()[1],1e-6); } }
/* * Create and simulate a simple 3D cell population of about 1000 cells within a cuboid box with sloughing on the top edge */ void Test3dNodeBasedInBoxWithSloughing() { double size_of_box = 8.0; unsigned cells_across = 12; double scaling = size_of_box/(double(cells_across-1)); // Create a simple 3D NodeBasedCellPopulation consisting of cells evenly spaced in a regular grid std::vector<Node<3>*> nodes; unsigned index = 0; for (unsigned i=0; i<cells_across; i++) { for (unsigned j=0; j<cells_across; j++) { for (unsigned k=0; k<cells_across; k++) { nodes.push_back(new Node<3>(index, false, (double) i * scaling , (double) j * scaling, (double) k * scaling)); index++; } } } NodesOnlyMesh<3> mesh; mesh.ConstructNodesWithoutMesh(nodes, 1.5); std::vector<CellPtr> cells; MAKE_PTR(TransitCellProliferativeType, p_transit_type); CellsGenerator<UniformCellCycleModel, 3> cells_generator; cells_generator.GenerateBasicRandom(cells, mesh.GetNumNodes(), p_transit_type); NodeBasedCellPopulation<3> node_based_cell_population(mesh, cells); //node_based_cell_population.AddCellPopulationCountWriter<CellProliferativeTypesCountWriter>(); // Set up cell-based simulation OffLatticeSimulation<3> simulator(node_based_cell_population); simulator.SetOutputDirectory("Representative3dNodeBased"); simulator.SetSamplingTimestepMultiple(12); simulator.SetEndTime(10.0); // Create a force law and pass it to the simulation MAKE_PTR(RepulsionForce<3>, p_linear_force); p_linear_force->SetCutOffLength(1.5); simulator.AddForce(p_linear_force); // Create some plane boundary conditions to restrict to box and pass them to the simulation // Restrict to x>0 MAKE_PTR_ARGS(PlaneBoundaryCondition<3>, p_boundary_condition_1, (&node_based_cell_population, zero_vector<double>(3), -unit_vector<double>(3,0))); simulator.AddCellPopulationBoundaryCondition(p_boundary_condition_1); // Restrict to x < size_of_box MAKE_PTR_ARGS(PlaneBoundaryCondition<3>, p_boundary_condition_2, (&node_based_cell_population, size_of_box*unit_vector<double>(3,0), unit_vector<double>(3,0))); simulator.AddCellPopulationBoundaryCondition(p_boundary_condition_2); // Restrict to y>0 MAKE_PTR_ARGS(PlaneBoundaryCondition<3>, p_boundary_condition_3, (&node_based_cell_population, zero_vector<double>(3), -unit_vector<double>(3,1))); simulator.AddCellPopulationBoundaryCondition(p_boundary_condition_3); // Restrict to y < size_of_box MAKE_PTR_ARGS(PlaneBoundaryCondition<3>, p_boundary_condition_4, (&node_based_cell_population, size_of_box*unit_vector<double>(3,1), unit_vector<double>(3,1))); simulator.AddCellPopulationBoundaryCondition(p_boundary_condition_4); // Restrict to z > 0 MAKE_PTR_ARGS(PlaneBoundaryCondition<3>, p_boundary_condition_5, (&node_based_cell_population, zero_vector<double>(3), -unit_vector<double>(3,2))); simulator.AddCellPopulationBoundaryCondition(p_boundary_condition_5); // Create cell killer at z= size_of_box MAKE_PTR_ARGS(PlaneBasedCellKiller<3>, p_cell_killer,(&node_based_cell_population, size_of_box*unit_vector<double>(3,2), unit_vector<double>(3,2))); simulator.AddCellKiller(p_cell_killer); // Run simulation simulator.Solve(); // Check some results TS_ASSERT_EQUALS(simulator.rGetCellPopulation().GetNumRealCells(), 1128u); AbstractCellPopulation<3>::Iterator cell_iter = simulator.rGetCellPopulation().Begin(); for (unsigned i=0; i<100; i++) { ++cell_iter; } c_vector<double,3> node_location = simulator.rGetCellPopulation().GetLocationOfCellCentre(*cell_iter); TS_ASSERT_DELTA(node_location[0],0.9604, 1e-4); TS_ASSERT_DELTA(node_location[1],8.0, 1e-4); TS_ASSERT_DELTA(node_location[2],3.6539, 1e-4); // Avoid memory leak for (unsigned i=0; i<nodes.size(); i++) { delete nodes[i]; } }