void TestPottsBasedWithCoarseMeshTwoEquations() throw(Exception) { EXIT_IF_PARALLEL; // Create a simple 2D PottsMesh PottsMeshGenerator<2> generator(6, 2, 2, 6, 2, 2); PottsMesh<2>* p_mesh = generator.GetMesh(); // Create cells std::vector<CellPtr> cells; MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type); CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasicRandom(cells, p_mesh->GetNumElements(), p_diff_type); // Create cell population PottsBasedCellPopulation<2> cell_population(*p_mesh, cells); // Set up cell-based simulation OnLatticeSimulation<2> simulator(cell_population); simulator.SetOutputDirectory("TestPottsBasedCellPopulationWithTwoPdes"); simulator.SetEndTime(0.1); // Set up PDE and pass to simulation via handler (zero uptake to check analytic solution) AveragedSourcePde<2> pde_1(cell_population, 0.0); ConstBoundaryCondition<2> bc_1(1.0); PdeAndBoundaryConditions<2> pde_and_bc_1(&pde_1, &bc_1, false); pde_and_bc_1.SetDependentVariableName("quantity 1"); AveragedSourcePde<2> pde_2(cell_population, 0.0); ConstBoundaryCondition<2> bc_2(1.0); PdeAndBoundaryConditions<2> pde_and_bc_2(&pde_2, &bc_2, false); pde_and_bc_2.SetDependentVariableName("quantity 2"); CellBasedPdeHandler<2> pde_handler(&cell_population); pde_handler.AddPdeAndBc(&pde_and_bc_1); pde_handler.AddPdeAndBc(&pde_and_bc_2); ChastePoint<2> lower(0.0, 0.0); ChastePoint<2> upper(50.0, 50.0); ChasteCuboid<2> cuboid(lower, upper); pde_handler.UseCoarsePdeMesh(10.0, cuboid, true); pde_handler.SetImposeBcsOnCoarseBoundary(true); simulator.SetCellBasedPdeHandler(&pde_handler); // Create update rules and pass to the simulation MAKE_PTR(VolumeConstraintPottsUpdateRule<2>, p_volume_constraint_update_rule); simulator.AddPottsUpdateRule(p_volume_constraint_update_rule); MAKE_PTR(AdhesionPottsUpdateRule<2>, p_adhesion_update_rule); simulator.AddPottsUpdateRule(p_adhesion_update_rule); // Solve the system simulator.Solve(); // Test solution is constant for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin(); cell_iter != cell_population.End(); ++cell_iter) { double analytic_solution = 1.0; // Test that PDE solver is working correctly on both pdes TS_ASSERT_DELTA(cell_iter->GetCellData()->GetItem("quantity 1"), analytic_solution, 1e-2); TS_ASSERT_DELTA(cell_iter->GetCellData()->GetItem("quantity 2"), analytic_solution, 1e-2); } #ifdef CHASTE_VTK //First file exists FileFinder vtk_file("TestPottsBasedCellPopulationWithTwoPdes/results_from_time_0/pde_results_1.vtu", RelativeTo::ChasteTestOutput); TS_ASSERT(vtk_file.Exists()); // Check that the second VTK file for the solution has the dependent quantities OutputFileHandler handler("TestPottsBasedCellPopulationWithTwoPdes", false); VtkMeshReader<3,3> vtk_reader(handler.GetOutputDirectoryFullPath()+"results_from_time_0/pde_results_2.vtu"); std::vector<double> data1; //There is no Oxygen TS_ASSERT_THROWS_CONTAINS(vtk_reader.GetPointData("Oxygen", data1), "No point data"); TS_ASSERT(data1.empty()); vtk_reader.GetPointData("quantity 1", data1); TS_ASSERT_EQUALS(data1.size(), 6u*6u); std::vector<double> data2; vtk_reader.GetPointData("quantity 2", data2); TS_ASSERT_EQUALS(data1.size(), data2.size()); #endif //CHASTE_VTK }
void TestPottsSpheroidCellSorting() throw (Exception) { EXIT_IF_PARALLEL; // Potts simulations don't work in parallel because they depend on NodesOnlyMesh for writing. // Create a simple 3D PottsMesh unsigned domain_size = 10; unsigned element_number = 4; unsigned element_size = 2; PottsMeshGenerator<3> generator(domain_size, element_number, element_size, domain_size, element_number, element_size, domain_size, element_number, element_size); PottsMesh<3>* p_mesh = generator.GetMesh(); // Create cells std::vector<CellPtr> cells; MAKE_PTR(DifferentiatedCellProliferativeType, p_diff_type); CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 3> cells_generator; cells_generator.GenerateBasicRandom(cells, p_mesh->GetNumElements(), p_diff_type); // Randomly label some cells boost::shared_ptr<AbstractCellProperty> p_label(CellPropertyRegistry::Instance()->Get<CellLabel>()); RandomlyLabelCells(cells, p_label, 0.5); // Create cell population PottsBasedCellPopulation<3> cell_population(*p_mesh, cells); cell_population.AddCellPopulationCountWriter<CellMutationStatesCountWriter>(); // So outputs the labelled cells // Set up cell-based simulation OnLatticeSimulation<3> simulator(cell_population); simulator.SetOutputDirectory("TestPotts3DCellSorting"); simulator.SetDt(0.1); simulator.SetEndTime(1.0); // Create update rules and pass to the simulation MAKE_PTR(VolumeConstraintPottsUpdateRule<3>, p_volume_constraint_update_rule); p_volume_constraint_update_rule->SetMatureCellTargetVolume(element_size*element_size*element_size); p_volume_constraint_update_rule->SetDeformationEnergyParameter(0.2); simulator.AddPottsUpdateRule(p_volume_constraint_update_rule); MAKE_PTR(DifferentialAdhesionPottsUpdateRule<3>, p_differential_adhesion_update_rule); p_differential_adhesion_update_rule->SetLabelledCellLabelledCellAdhesionEnergyParameter(0.16); p_differential_adhesion_update_rule->SetLabelledCellCellAdhesionEnergyParameter(0.11); p_differential_adhesion_update_rule->SetCellCellAdhesionEnergyParameter(0.02); p_differential_adhesion_update_rule->SetLabelledCellBoundaryAdhesionEnergyParameter(0.16); p_differential_adhesion_update_rule->SetCellBoundaryAdhesionEnergyParameter(0.16); simulator.AddPottsUpdateRule(p_differential_adhesion_update_rule); // Run simulation simulator.Solve(); // Check that the same number of cells TS_ASSERT_EQUALS(simulator.rGetCellPopulation().GetNumRealCells(), 64u); // Test no births or deaths TS_ASSERT_EQUALS(simulator.GetNumBirths(), 0u); TS_ASSERT_EQUALS(simulator.GetNumDeaths(), 0u); #ifdef CHASTE_VTK // Test that VTK writer has produced some files OutputFileHandler handler("TestPotts3DCellSorting", false); std::string results_dir = handler.GetOutputDirectoryFullPath(); // Initial condition file FileFinder vtk_file(results_dir + "results_from_time_0/results_0.vtu", RelativeTo::Absolute); TS_ASSERT(vtk_file.Exists()); // Final file FileFinder vtk_file2(results_dir + "results_from_time_0/results_10.vtu", RelativeTo::Absolute); TS_ASSERT(vtk_file2.Exists()); // Check that the second VTK file for Potts specific data (element IDs) VtkMeshReader<3,3> vtk_reader(results_dir + "results_from_time_0/results_10.vtu"); std::vector<double> cell_types; vtk_reader.GetPointData("Cell types", cell_types); TS_ASSERT_EQUALS(cell_types.size(), 1000u); // The cell types are between -1 and 5. Check the maximum TS_ASSERT_DELTA(*max_element(cell_types.begin(), cell_types.end()), 5.0, 1e-12); std::vector<double> cell_ids; vtk_reader.GetPointData("Cell IDs", cell_ids); // Prior to release 3.2 this was called "Element index". // It is changed to cell_id as this is preferable for VTK output. TS_ASSERT_EQUALS(cell_ids.size(), 1000u); TS_ASSERT_DELTA(*max_element(cell_ids.begin(), cell_ids.end()), 63.0, 1e-12); #endif //CHASTE_VTK }