void TestSendAndRecieveCellsNonBlocking() throw (Exception) { unsigned index_of_node_to_send = mpNodesOnlyMesh->GetNodeIteratorBegin()->GetIndex();; mpNodeBasedCellPopulation->AddNodeAndCellToSendRight(index_of_node_to_send); mpNodeBasedCellPopulation->AddNodeAndCellToSendLeft(index_of_node_to_send); TS_ASSERT_EQUALS(mpNodeBasedCellPopulation->mCellCommunicationTag, 123u); TS_ASSERT(!(mpNodeBasedCellPopulation->mpCellsRecvRight)); TS_ASSERT(!(mpNodeBasedCellPopulation->mpCellsRecvLeft)); #if BOOST_VERSION < 103700 TS_ASSERT_THROWS_THIS(mpNodeBasedCellPopulation->SendCellsToNeighbourProcesses(), "Parallel cell-based Chaste requires Boost >= 1.37"); #else mpNodeBasedCellPopulation->NonBlockingSendCellsToNeighbourProcesses(); mpNodeBasedCellPopulation->GetReceivedCells(); if (!PetscTools::AmTopMost()) { TS_ASSERT_EQUALS(mpNodeBasedCellPopulation->mpCellsRecvRight->size(), 1u); unsigned index = (*mpNodeBasedCellPopulation->mpCellsRecvRight->begin()).second->GetIndex(); TS_ASSERT_EQUALS(index, PetscTools::GetMyRank() + 1); } if (!PetscTools::AmMaster()) { TS_ASSERT_EQUALS(mpNodeBasedCellPopulation->mpCellsRecvLeft->size(), 1u); unsigned index = (*mpNodeBasedCellPopulation->mpCellsRecvLeft->begin()).second->GetIndex(); TS_ASSERT_EQUALS(index, PetscTools::GetMyRank() - 1); } #endif }
NodeBasedCellPopulationWithParticles<DIM>::NodeBasedCellPopulationWithParticles(NodesOnlyMesh<DIM>& rMesh, std::vector<CellPtr>& rCells, const std::vector<unsigned> locationIndices, bool deleteMesh) : NodeBasedCellPopulation<DIM>(rMesh, rCells, locationIndices, deleteMesh, false) { EXCEPT_IF_NOT(PetscTools::IsSequential()); if (!locationIndices.empty()) { // Create a set of node indices corresponding to particles std::set<unsigned> node_indices; std::set<unsigned> location_indices; std::set<unsigned> particle_indices; for (typename AbstractMesh<DIM,DIM>::NodeIterator node_iter = rMesh.GetNodeIteratorBegin(); node_iter != rMesh.GetNodeIteratorEnd(); ++node_iter) { node_indices.insert(node_iter->GetIndex()); } for (unsigned i=0; i<locationIndices.size(); i++) { location_indices.insert(locationIndices[i]); } std::set_difference(node_indices.begin(), node_indices.end(), location_indices.begin(), location_indices.end(), std::inserter(particle_indices, particle_indices.begin())); // This method finishes and then calls Validate() SetParticles(particle_indices); } else { for (typename NodesOnlyMesh<DIM>::NodeIterator node_iter = rMesh.GetNodeIteratorBegin(); node_iter != rMesh.GetNodeIteratorEnd(); ++node_iter) { (*node_iter).SetIsParticle(false); } NodeBasedCellPopulationWithParticles::Validate(); } }
void TestGetCellAndNodePair() throw (Exception) { unsigned node_index = mpNodesOnlyMesh->GetNodeIteratorBegin()->GetIndex(); std::pair<CellPtr, Node<3>* > pair = mpNodeBasedCellPopulation->GetCellNodePair(node_index); TS_ASSERT_EQUALS(pair.second->GetIndex(), node_index); CellPtr p_returned_cell = pair.first; TS_ASSERT_EQUALS(mpNodeBasedCellPopulation->GetLocationIndexUsingCell(p_returned_cell), node_index); }
void TestAddNodeAndCellsToSend() throw (Exception) { unsigned index_of_node_to_send = mpNodesOnlyMesh->GetNodeIteratorBegin()->GetIndex(); mpNodeBasedCellPopulation->AddNodeAndCellToSendRight(index_of_node_to_send); mpNodeBasedCellPopulation->AddNodeAndCellToSendLeft(index_of_node_to_send); TS_ASSERT_EQUALS(mpNodeBasedCellPopulation->mCellsToSendRight.size(), 1u); TS_ASSERT_EQUALS(mpNodeBasedCellPopulation->mCellsToSendLeft.size(), 1u); unsigned node_right_index = (*mpNodeBasedCellPopulation->mCellsToSendRight.begin()).second->GetIndex(); TS_ASSERT_EQUALS(node_right_index, index_of_node_to_send); unsigned node_left_index = (*mpNodeBasedCellPopulation->mCellsToSendLeft.begin()).second->GetIndex(); TS_ASSERT_EQUALS(node_left_index, index_of_node_to_send); }
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]; }
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 } }
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]; } }
void TestRemoveDeadCellsAndReMeshWithParticles() { 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; for (unsigned i=10; i<mesh.GetNumNodes(); i++) { if (i != 80) { cell_location_indices.push_back(i); } } // Set up cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, cell_location_indices.size()); cells[27]->StartApoptosis(); // Create a cell population, with some random particles NodeBasedCellPopulationWithParticles<2> cell_population_with_particles(mesh, cells, cell_location_indices); TS_ASSERT_EQUALS(mesh.GetNumNodes(), 81u); // Num real cells should be num_nodes (81) - num_particles (11) = 70 TS_ASSERT_EQUALS(cell_population_with_particles.GetNumRealCells(), 70u); p_simulation_time->IncrementTimeOneStep(); unsigned num_removed_with_particles = cell_population_with_particles.RemoveDeadCells(); TS_ASSERT_EQUALS(num_removed_with_particles, 1u); TS_ASSERT_EQUALS(mesh.GetNumNodes(), 80u); TS_ASSERT_DIFFERS(cell_population_with_particles.rGetCells().size(), cells.size()); // CellPopulation now copies cells // Num real cells should be num_nodes (81) - num_particle (11) - 1 deleted node = 69 TS_ASSERT_EQUALS(cell_population_with_particles.GetNumRealCells(), 69u); cell_population_with_particles.Update(); // For coverage NodeMap map(mesh.GetNumAllNodes()); map.ResetToIdentity(); cell_population_with_particles.UpdateParticlesAfterReMesh(map); // Num real cells should be new_num_nodes (80) - num_particles (11) TS_ASSERT_EQUALS(cell_population_with_particles.GetNumRealCells(), 69u); TS_ASSERT_EQUALS(mesh.GetNumNodes(), mesh.GetNumAllNodes()); // Nodes 0-9 should not been renumbered so are still particles. // the particle at node 80 is now at 79 as node 27 was deleted.. for (AbstractMesh<2,2>::NodeIterator node_iter = mesh.GetNodeIteratorBegin(); node_iter != mesh.GetNodeIteratorEnd(); ++node_iter) { unsigned index = node_iter->GetIndex(); // True (ie should be a particle) if i<10 or i==79, else false TS_ASSERT_EQUALS(cell_population_with_particles.IsParticle(index), ((index<10)||(index==80))); } // Finally, check the cells node indices have updated // We expect the cell node indices to be {10,11,...,79} std::set<unsigned> expected_node_indices; for (unsigned i=0; i<cell_population_with_particles.GetNumRealCells(); i++) { if (i!=27) { expected_node_indices.insert(i+10); } } expected_node_indices.insert(79); // Get actual cell node indices std::set<unsigned> node_indices_with_particles; for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population_with_particles.Begin(); cell_iter != cell_population_with_particles.End(); ++cell_iter) { // Record node index corresponding to cell unsigned node_index_with_particles = cell_population_with_particles.GetLocationIndexUsingCell(*cell_iter); node_indices_with_particles.insert(node_index_with_particles); } TS_ASSERT_EQUALS(node_indices_with_particles, expected_node_indices); }