void TestSimpleUniformSourceParabolicPdeMethods() throw(Exception) { // Create a PDE object SimpleUniformSourceParabolicPde<2> pde(0.1); // Test that the member variables have been initialised correctly TS_ASSERT_EQUALS(pde.GetCoefficient(),0.1); // Test methods ChastePoint<2> point; TS_ASSERT_DELTA(pde.ComputeSourceTerm(point,DBL_MAX), 0.1, 1e-6); TS_ASSERT_DELTA(pde.ComputeDuDtCoefficientFunction(point), 1.0, 1e-6); c_matrix<double,2,2> diffusion_matrix = pde.ComputeDiffusionTerm(point); for (unsigned i=0; i<2; i++) { for (unsigned j=0; j<2; j++) { double value = 0.0; if (i == j) { value = 1.0; } TS_ASSERT_DELTA(diffusion_matrix(i,j), value, 1e-6); } } }
void TestSimpleUniformSourcePdeMethods() throw(Exception) { EXIT_IF_PARALLEL; // Create a PDE object SimpleUniformSourcePde<2> pde(0.05); // Test that the member variables have been initialised correctly TS_ASSERT_DELTA(pde.GetCoefficient(), 0.05, 1e-6); ChastePoint<2> point; TS_ASSERT_DELTA(pde.ComputeConstantInUSourceTerm(point, NULL), 0.0, 1e-6); TS_ASSERT_DELTA(pde.ComputeLinearInUCoeffInSourceTerm(point, NULL), 0.05, 1e-6); c_matrix<double,2,2> diffusion_matrix = pde.ComputeDiffusionTerm(point); for (unsigned i=0; i<2; i++) { for (unsigned j=0; j<2; j++) { double value = 0.0; if (i == j) { value = 1.0; } TS_ASSERT_DELTA(diffusion_matrix(i,j), value, 1e-6); } } }
/* * Note only solves one PDE */ void TestMultipleCaBasedWithoutCoarseMeshUsingPdeHandlerOnCuboid() throw(Exception) { EXIT_IF_PARALLEL; // Create a simple 2D PottsMesh PottsMeshGenerator<2> generator(10, 0, 0, 10, 0, 0); PottsMesh<2>* p_mesh = generator.GetMesh(); // Create cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, 100); std::vector<unsigned> location_indices; for (unsigned i=0; i<100; i++) { location_indices.push_back(i); } // Create cell population MultipleCaBasedCellPopulation<2> cell_population(*p_mesh, cells, location_indices); // Set up cell-based simulation OnLatticeSimulation<2> simulator(cell_population); simulator.SetOutputDirectory("TestMultipleCaBasedCellPopulationWithPdesOnCuboid"); simulator.SetDt(0.1); simulator.SetEndTime(1); // Set up a PDE with mixed boundary conditions (use zero uptake to check analytic solution) AveragedSourcePde<2> pde(cell_population, 0.0); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_and_bc.SetDependentVariableName("nutrient"); // Pass this to the simulation object via a PDE handler CellBasedPdeHandlerOnCuboid<2> pde_handler(&cell_population); pde_handler.AddPdeAndBc(&pde_and_bc); pde_handler.SetImposeBcsOnCoarseBoundary(false); simulator.SetCellBasedPdeHandler(&pde_handler); // Solve the system simulator.Solve(); // Test that PDE solver is working correctly for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin(); cell_iter != cell_population.End(); ++cell_iter) { c_vector<double, 2> cell_location = simulator.rGetCellPopulation().GetLocationOfCellCentre(*cell_iter); if (cell_location[1] < 1e-6 || cell_location[1] > 9 - 1e-6) { TS_ASSERT_DELTA(cell_iter->GetCellData()->GetItem("nutrient"),1.0, 1e-2); } else { TS_ASSERT_LESS_THAN(1.0,cell_iter->GetCellData()->GetItem("nutrient")); } } }
void* heap_init() { // Reserve 4M as initial heap void* heap_phys_base = (void*)kInfo.freeMem; kInfo.freeMem += 0x400000; heap_base = (void*)K_HEAP_BASE; heap_ptr = heap_base; heap_size = 0; u32 pdi = pde(K_HEAP_BASE); u32 i; for(i = 0; i < 1024; i++) { *((u32*) &lowHeapPT[i]) = 0; lowHeapPT[i].present = 1; lowHeapPT[i].writable = 1; lowHeapPT[i].address = pte((u32)heap_phys_base) + i; } kernelPageDir[pdi].present = 1; kernelPageDir[pdi].writable = 1; kernelPageDir[pdi].address = ((u32)lowHeapPT - KERNEL_BASE) >> 12; return heap_base; }
void TestSchnackenbergCoupledPdeSystem() { // Create PDE system object SchnackenbergCoupledPdeSystem<1> pde(1e-4, 1e-2, 0.1, 0.2, 0.3, 0.1); ChastePoint<1> x(1.0); TS_ASSERT_DELTA(pde.ComputeDuDtCoefficientFunction(x,0), 1.0, 1e-6); c_vector<double,2> pde_solution; pde_solution(0) = 2.0; pde_solution(1) = 0.75; std::vector<double> ode_solution(1); ode_solution[0] = 5.0; TS_ASSERT_DELTA(pde.ComputeSourceTerm(x, pde_solution, ode_solution, 0), 0.0, 1e-6); Node<1> node(0); TS_ASSERT_DELTA(pde.ComputeSourceTermAtNode(node, pde_solution, ode_solution, 0), 0.0, 1e-6); c_matrix<double,1,1> diffusion_term1 = pde.ComputeDiffusionTerm(x, 0); TS_ASSERT_DELTA(diffusion_term1(0,0), 1e-4, 1e-6); c_matrix<double,1,1> diffusion_term2 = pde.ComputeDiffusionTerm(x, 1); TS_ASSERT_DELTA(diffusion_term2(0,0), 1e-2, 1e-6); }
/* * This tests that a sensible error is thrown if the coarse mesh is too small/ */ void TestMultipleCaBasedCellsOutsideMesh() throw(Exception) { EXIT_IF_PARALLEL; // Create a simple 2D PottsMesh PottsMeshGenerator<2> generator(10, 0, 0, 10, 0, 0); PottsMesh<2>* p_mesh = generator.GetMesh(); // Create cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, 100); std::vector<unsigned> location_indices; for (unsigned i=0; i<100; i++) { location_indices.push_back(i); } // Create cell population MultipleCaBasedCellPopulation<2> cell_population(*p_mesh, cells, location_indices); // Set up cell-based simulation OnLatticeSimulation<2> simulator(cell_population); simulator.SetOutputDirectory("TestMultipleCaBasedCellPopulationWithPdesWithCellsOutsideMesh"); simulator.SetDt(0.1); simulator.SetEndTime(1); // Set up PDE and pass to simulation via handler (zero uptake to check analytic solution) AveragedSourcePde<2> pde(cell_population, 0.0); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_and_bc.SetDependentVariableName("nutrient"); CellBasedPdeHandler<2> pde_handler(&cell_population); pde_handler.AddPdeAndBc(&pde_and_bc); pde_handler.SetImposeBcsOnCoarseBoundary(true); // Create coarse mesh smaller than the PottsMesh ChastePoint<2> lower(0.0, 0.0); ChastePoint<2> upper(5.0, 5.0); ChasteCuboid<2> cuboid(lower, upper); pde_handler.UseCoarsePdeMesh(1.0, cuboid); simulator.SetCellBasedPdeHandler(&pde_handler); // Solve the system TS_ASSERT_THROWS_THIS(simulator.Solve(), "Point [6,0] is not in mesh - all elements tested"); }
void TestInitialiseCellPdeElementMapAndFindCoarseElementContainingCell() throw(Exception) { EXIT_IF_PARALLEL; // Create a cell population HoneycombMeshGenerator generator(4, 4, 0); MutableMesh<2,2>* p_generating_mesh = generator.GetMesh(); NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, mesh.GetNumNodes()); NodeBasedCellPopulation<2> cell_population(mesh, cells); // Create a PDE handler object using this cell population CellBasedPdeHandler<2> pde_handler(&cell_population); TS_ASSERT_EQUALS(pde_handler.mCellPdeElementMap.size(), 0u); // Test that InitialiseCellPdeElementMap() throws an exception if mpCoarsePdeMesh is not set up TS_ASSERT_THROWS_THIS(pde_handler.InitialiseCellPdeElementMap(), "InitialiseCellPdeElementMap() should only be called if mpCoarsePdeMesh is set up."); // Set up PDE and pass to handler AveragedSourcePde<2> pde(cell_population, -0.1); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_handler.AddPdeAndBc(&pde_and_bc); // Use a coarse PDE mesh ChastePoint<2> lower(0.0, 0.0); ChastePoint<2> upper(9.0, 9.0); ChasteCuboid<2> cuboid(lower, upper); pde_handler.UseCoarsePdeMesh(3.0, cuboid, true); // Test that mCellPdeElementMap is initialised correctly pde_handler.InitialiseCellPdeElementMap(); TS_ASSERT_EQUALS(pde_handler.mCellPdeElementMap.size(), cell_population.GetNumRealCells()); for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin(); cell_iter != cell_population.End(); ++cell_iter) { unsigned containing_element_index = pde_handler.mCellPdeElementMap[*cell_iter]; TS_ASSERT_LESS_THAN(containing_element_index, pde_handler.GetCoarsePdeMesh()->GetNumElements()); TS_ASSERT_EQUALS(containing_element_index, pde_handler.FindCoarseElementContainingCell(*cell_iter)); } }
void TestVolumeDependentAveragedSourcePdeMethods() throw(Exception) { EXIT_IF_PARALLEL; // Create a cell population HoneycombMeshGenerator generator(5, 5, 0); MutableMesh<2,2>* p_generating_mesh = generator.GetMesh(); NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, mesh.GetNumNodes()); NodeBasedCellPopulation<2> cell_population(mesh, cells); // Create a PDE object VolumeDependentAveragedSourcePde<2> pde(cell_population, 0.05); // Test that the member variables have been initialised correctly TS_ASSERT(pde.mpStaticCastCellPopulation != NULL); // For simplicity we create a very large coarse mesh, so we know that all cells are contained in one element TrianglesMeshReader<2,2> mesh_reader("mesh/test/data/square_2_elements"); TetrahedralMesh<2,2> coarse_mesh; coarse_mesh.ConstructFromMeshReader(mesh_reader); coarse_mesh.Scale(10.0, 10.0); // Test SetupSourceTerms() when no map between cells and coarse mesh elements is supplied pde.SetupSourceTerms(coarse_mesh); TS_ASSERT_EQUALS(pde.mCellDensityOnCoarseElements.size(), 2u); // The first element has area 0.5*10*10 = 50 and there are 5*5 = 25 cells, so the cell density is 25/50 = 0.5 // The radius of each node is 0.5 and the density is normalized with cell area (1/4.0) in `VolumeDependentAveragedSourcePde`. TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[0], 0.5/4.0, 1e-6); // The first element doesn't contain any cells, so the cell density is zero TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[1], 0.0, 1e-6); // Now test SetupSourceTerms() when a map between cells and coarse mesh elements is supplied std::map<CellPtr, unsigned> cell_pde_element_map; for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin(); cell_iter != cell_population.End(); ++cell_iter) { cell_pde_element_map[*cell_iter] = 0; } pde.SetupSourceTerms(coarse_mesh, &cell_pde_element_map); TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[0], 0.5/4.0, 1e-6); TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[1], 0.0, 1e-6); }
void TestUseCoarsePdeMeshNotCentredOnPopulation() throw(Exception) { EXIT_IF_PARALLEL; // Create a cell population HoneycombMeshGenerator generator(4, 4, 0); MutableMesh<2,2>* p_generating_mesh = generator.GetMesh(); NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, mesh.GetNumNodes()); NodeBasedCellPopulation<2> cell_population(mesh, cells); // Create a PDE handler object using this cell population CellBasedPdeHandler<2> pde_handler(&cell_population); // Test that UseCoarsePdeMesh() throws an exception if no PDEs are specified ChastePoint<2> lower(0.0, 0.0); ChastePoint<2> upper(9.0, 9.0); ChasteCuboid<2> cuboid(lower, upper); // Set up PDE and pass to handler AveragedSourcePde<2> pde(cell_population, -0.1); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_handler.AddPdeAndBc(&pde_and_bc); // Test UseCoarsePdeMesh() again pde_handler.UseCoarsePdeMesh(3.0, cuboid); // Check that the centre of the mesh co-incides with centre of the cuboid. c_vector<double,2> centre_of_coarse_mesh = zero_vector<double>(2); for (unsigned i=0; i<pde_handler.GetCoarsePdeMesh()->GetNumNodes(); i++) { centre_of_coarse_mesh += pde_handler.GetCoarsePdeMesh()->GetNode(i)->rGetLocation(); } centre_of_coarse_mesh /= pde_handler.GetCoarsePdeMesh()->GetNumNodes(); c_vector<double,2> centre_of_cuboid = 0.5*(lower.rGetLocation() + upper.rGetLocation()); TS_ASSERT_DELTA(norm_2(centre_of_cuboid - centre_of_coarse_mesh), 0.0, 1e-4); }
void TestPottsBasedWithoutCoarseMeshThrowsException() 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("TestPottsSimulationWithPdesThrowsException"); simulator.SetEndTime(0.1); // Set up PDE and pass to simulation via handler (zero uptake to check analytic solution) AveragedSourcePde<2> pde(cell_population, 0.0); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_and_bc.SetDependentVariableName("nutrient"); CellBasedPdeHandler<2> pde_handler(&cell_population); pde_handler.AddPdeAndBc(&pde_and_bc); 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 TS_ASSERT_THROWS_THIS(simulator.Solve(), "Trying to solve a PDE on a cell population that doesn't have a mesh. Try calling UseCoarsePdeMesh()."); }
void TestCellwiseSourcePdeMethods() throw(Exception) { EXIT_IF_PARALLEL; // Set up cell population HoneycombMeshGenerator generator(5, 5, 0); MutableMesh<2,2>* p_mesh = generator.GetMesh(); std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, p_mesh->GetNumNodes()); MeshBasedCellPopulation<2> cell_population(*p_mesh, cells); // Create a PDE object CellwiseSourcePde<2> pde(cell_population, 0.05); // Test that the member variables have been initialised correctly TS_ASSERT_EQUALS(&(pde.rGetCellPopulation()), &cell_population); TS_ASSERT_DELTA(pde.GetCoefficient(), 0.05, 1e-6); // Test methods Node<2>* p_node = cell_population.GetNodeCorrespondingToCell(*(cell_population.Begin())); TS_ASSERT_DELTA(pde.ComputeLinearInUCoeffInSourceTermAtNode(*p_node), 0.05, 1e-6); ChastePoint<2> point; c_matrix<double,2,2> diffusion_matrix = pde.ComputeDiffusionTerm(point); for (unsigned i=0; i<2; i++) { for (unsigned j=0; j<2; j++) { double value = 0.0; if (i == j) { value = 1.0; } TS_ASSERT_DELTA(diffusion_matrix(i,j), value, 1e-6); } } }
void TestSolvePdeAndWriteResultsToFileCoarsePdeMeshNeumann() throw(Exception) { EXIT_IF_PARALLEL; // Set up SimulationTime SimulationTime::Instance()->SetEndTimeAndNumberOfTimeSteps(0.05, 6); // Create a cigar-shaped mesh TrianglesMeshReader<2,2> mesh_reader("mesh/test/data/disk_522_elements"); MutableMesh<2,2> mesh; mesh.ConstructFromMeshReader(mesh_reader); mesh.Scale(5.0, 1.0); // Create a cell population std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, mesh.GetNumNodes()); MeshBasedCellPopulation<2> cell_population(mesh, cells); // Create a PDE handler object using this cell population CellBasedPdeHandler<2> pde_handler(&cell_population); // Set up PDE and pass to handler AveragedSourcePde<2> pde(cell_population, -0.01); ConstBoundaryCondition<2> bc(0.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, true); // Last boolean specifies Neuman conditions pde_and_bc.SetDependentVariableName("variable"); pde_handler.AddPdeAndBc(&pde_and_bc); // Solve PDEs on a coarse mesh 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(false); // For coverage, provide an initial guess for the solution std::vector<double> data(pde_handler.mpCoarsePdeMesh->GetNumNodes()); for (unsigned i=0; i<pde_handler.mpCoarsePdeMesh->GetNumNodes(); i++) { data[i] = 1.0; } Vec vector = PetscTools::CreateVec(data); pde_and_bc.SetSolution(vector); // Open result file ourselves OutputFileHandler output_file_handler("TestWritePdeSolution", false); pde_handler.mpVizPdeSolutionResultsFile = output_file_handler.OpenOutputFile("results.vizpdesolution"); // Solve PDE (set sampling timestep multiple to be large doesn't do anything as always output on 1st timestep) pde_handler.SolvePdeAndWriteResultsToFile(10); // Close result file ourselves pde_handler.mpVizPdeSolutionResultsFile->close(); // Test that boundary cells experience the right boundary condition for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin(); cell_iter != cell_population.End(); ++cell_iter) { if (cell_population.GetNodeCorrespondingToCell(*cell_iter)->IsBoundaryNode()) { TS_ASSERT_DELTA(cell_iter->GetCellData()->GetItem("variable"), 0.0, 1e-1); } } }
/** * This test provides an example of how to solve a coupled PDE system * where there is no coupled ODE system, and can be used as a template * for solving standard reaction-diffusion problems arising in the * study of pattern formation on fixed domains. */ void TestSchnackenbergCoupledPdeSystemIn1dWithNonZeroDirichlet() { // Create mesh of domain [0,1] TrianglesMeshReader<1,1> mesh_reader("mesh/test/data/1D_0_to_1_1000_elements"); TetrahedralMesh<1,1> mesh; mesh.ConstructFromMeshReader(mesh_reader); // Create PDE system object SchnackenbergCoupledPdeSystem<1> pde(1e-4, 1e-2, 0.1, 0.2, 0.3, 0.1); // Create non-zero Dirichlet boundary conditions for each state variable BoundaryConditionsContainer<1,1,2> bcc; ConstBoundaryCondition<1>* p_bc_for_u = new ConstBoundaryCondition<1>(2.0); ConstBoundaryCondition<1>* p_bc_for_v = new ConstBoundaryCondition<1>(0.75); bcc.AddDirichletBoundaryCondition(mesh.GetNode(0), p_bc_for_u, 0); bcc.AddDirichletBoundaryCondition(mesh.GetNode(0), p_bc_for_v, 1); bcc.AddDirichletBoundaryCondition(mesh.GetNode(mesh.GetNumNodes()-1), p_bc_for_u, 0); bcc.AddDirichletBoundaryCondition(mesh.GetNode(mesh.GetNumNodes()-1), p_bc_for_v, 1); // Create PDE system solver LinearParabolicPdeSystemWithCoupledOdeSystemSolver<1,1,2> solver(&mesh, &pde, &bcc); // Set end time and time step double t_end = 10; solver.SetTimes(0, t_end); solver.SetTimeStep(1e-1); // Create initial conditions that are random perturbations of the uniform steady state std::vector<double> init_conds(2*mesh.GetNumNodes()); for (unsigned i=0; i<mesh.GetNumNodes(); i++) { init_conds[2*i] = fabs(2.0 + RandomNumberGenerator::Instance()->ranf()); init_conds[2*i + 1] = fabs(0.75 + RandomNumberGenerator::Instance()->ranf()); } Vec initial_condition = PetscTools::CreateVec(init_conds); solver.SetInitialCondition(initial_condition); // Solve PDE system and store result Vec solution = solver.Solve(); ReplicatableVector solution_repl(solution); // Write results for visualization in gnuplot OutputFileHandler handler("TestSchnackenbergCoupledPdeSystemIn1dWithNonZeroDirichlet", false); out_stream results_file = handler.OpenOutputFile("schnackenberg.dat"); for (unsigned i=0; i<mesh.GetNumNodes(); i++) { double x = mesh.GetNode(i)->rGetLocation()[0]; double u = solution_repl[2*i]; double v = solution_repl[2*i + 1]; (*results_file) << x << "\t" << u << "\t" << v << "\n" << std::flush; } results_file->close(); std::string results_filename = handler.GetOutputDirectoryFullPath() + "schnackenberg.dat"; NumericFileComparison comp_results(results_filename, "pde/test/data/schnackenberg.dat"); TS_ASSERT(comp_results.CompareFiles(1e-3)); // Tidy up PetscTools::Destroy(initial_condition); PetscTools::Destroy(solution); }
void TestWritingToFile() throw(Exception) { EXIT_IF_PARALLEL; std::string output_directory = "TestCellBasedPdeHandlerWritingToFile"; // Create a cell population HoneycombMeshGenerator generator(4, 4, 0); MutableMesh<2,2>* p_generating_mesh = generator.GetMesh(); NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, mesh.GetNumNodes()); TS_ASSERT_EQUALS(cells.size(), mesh.GetNumNodes()); NodeBasedCellPopulation<2> cell_population(mesh, cells); cell_population.SetDataOnAllCells("variable", 1.0); // Create a PDE handler object using this cell population CellBasedPdeHandler<2> pde_handler(&cell_population); TS_ASSERT_THROWS_THIS(pde_handler.OpenResultsFiles(output_directory), "Trying to solve a PDE on a cell population that doesn't have a mesh. Try calling UseCoarsePdeMesh()."); // Use a coarse PDE mesh since we are using a node-based cell population AveragedSourcePde<2> pde(cell_population, -0.1); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_and_bc.SetDependentVariableName("variable"); pde_handler.AddPdeAndBc(&pde_and_bc); ChastePoint<2> lower(0.0, 0.0); ChastePoint<2> upper(9.0, 9.0); ChasteCuboid<2> cuboid(lower, upper); pde_handler.UseCoarsePdeMesh(3.0, cuboid, true); // For coverage, call SetWriteAverageRadialPdeSolution() prior to output pde_handler.SetWriteAverageRadialPdeSolution("variable", 5, true); // Test that output files are opened correctly pde_handler.OpenResultsFiles(output_directory); FileFinder file_finder(output_directory + "/results.vizcoarsepdesolution", RelativeTo::ChasteTestOutput); TS_ASSERT(file_finder.Exists()); TS_ASSERT(file_finder.IsFile()); FileFinder file_finder2(output_directory + "/radial_dist.dat", RelativeTo::ChasteTestOutput); TS_ASSERT(file_finder2.Exists()); TS_ASSERT(file_finder2.IsFile()); TS_ASSERT_THROWS_NOTHING(pde_handler.CloseResultsFiles()); // For coverage, also test that output files are opened correctly when not using a coarse PDE mesh HoneycombMeshGenerator generator2(5, 5, 0); MutableMesh<2,2>* p_mesh2 = generator2.GetMesh(); std::vector<CellPtr> cells2; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator2; cells_generator2.GenerateBasic(cells2, p_mesh2->GetNumNodes()); MeshBasedCellPopulation<2> cell_population2(*p_mesh2, cells2); cell_population2.SetDataOnAllCells("another variable", 1.0); CellBasedPdeHandler<2> pde_handler2(&cell_population2); pde_handler2.OpenResultsFiles(output_directory); FileFinder file_finder3(output_directory + "/results.vizpdesolution", RelativeTo::ChasteTestOutput); TS_ASSERT(file_finder3.Exists()); TS_ASSERT(file_finder3.IsFile()); pde_handler2.CloseResultsFiles(); }
void TestSolvePdeAndWriteResultsToFileWithoutCoarsePdeMeshNeumann() throw(Exception) { EXIT_IF_PARALLEL; // Set up SimulationTime SimulationTime::Instance()->SetEndTimeAndNumberOfTimeSteps(0.5, 6); // Set up mesh MutableMesh<2,2> mesh; TrianglesMeshReader<2,2> mesh_reader("mesh/test/data/disk_522_elements"); mesh.ConstructFromMeshReader(mesh_reader); // Set up cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, mesh.GetNumNodes()); // Set up cell population MeshBasedCellPopulation<2> cell_population(mesh, cells); // Create a PDE handler object using this cell population CellBasedPdeHandler<2> pde_handler(&cell_population); // Create a single PDE and pass to the handler // Note SimplePdeForTesting wouldnt work as theres no solution with Neuman conditions. // Also note that when using Neuman conditions the only solution that works is u=0 CellwiseSourcePde<2> pde(cell_population, 0.0); ConstBoundaryCondition<2> bc(0.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, true); pde_and_bc.SetDependentVariableName("variable"); // For coverage, provide an initial guess for the solution std::vector<double> data(mesh.GetNumNodes()+1); for (unsigned i=0; i<mesh.GetNumNodes(); i++) { data[i] = 1.0; } Vec vector = PetscTools::CreateVec(data); pde_and_bc.SetSolution(vector); pde_handler.AddPdeAndBc(&pde_and_bc); // Open result file ourselves OutputFileHandler output_file_handler("TestWritePdeSolution", false); pde_handler.mpVizPdeSolutionResultsFile = output_file_handler.OpenOutputFile("results.vizpdesolution"); // Solve PDE (set sampling timestep multiple to be large doesn't do anything as always output on 1st timestep) pde_handler.SolvePdeAndWriteResultsToFile(10); // Close result file ourselves pde_handler.mpVizPdeSolutionResultsFile->close(); // Check the correct solution was obtained for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin(); cell_iter != cell_population.End(); ++cell_iter) { // Test that PDE solver is working correctly TS_ASSERT_DELTA(cell_iter->GetCellData()->GetItem("variable"), 0.0, 0.02); } }
void TestMultipleCaBasedWithCoarseMesh() throw(Exception) { EXIT_IF_PARALLEL; // Create a simple 2D PottsMesh PottsMeshGenerator<2> generator(5, 0, 0, 5, 0, 0); PottsMesh<2>* p_mesh = generator.GetMesh(); // Create cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, 1); std::vector<unsigned> location_indices; location_indices.push_back(12); // Create cell population MultipleCaBasedCellPopulation<2> cell_population(*p_mesh, cells, location_indices); // Set up cell-based simulation OnLatticeSimulation<2> simulator(cell_population); simulator.SetOutputDirectory("TestMultipleCaBasedCellPopulationWithPdes"); simulator.SetEndTime(0.1); // Set up PDE and pass to simulation via handler (zero uptake to check analytic solution) AveragedSourcePde<2> pde(cell_population, 0.0); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_and_bc.SetDependentVariableName("nutrient"); CellBasedPdeHandler<2> pde_handler(&cell_population); pde_handler.AddPdeAndBc(&pde_and_bc); // Create coarse mesh and centre it on the centre of the Potts Mesh c_vector<double,2> centre_of_potts_mesh = zero_vector<double>(2); for (unsigned i=0; i<p_mesh->GetNumNodes(); i++) { centre_of_potts_mesh += p_mesh->GetNode(i)->rGetLocation(); } centre_of_potts_mesh /= p_mesh->GetNumNodes(); ChastePoint<2> lower(0.0, 0.0); ChastePoint<2> upper(5.0, 5.0); c_vector<double, 2> translation = 0.5*(lower.rGetLocation() + upper.rGetLocation()) - centre_of_potts_mesh; lower.rGetLocation() -= translation; upper.rGetLocation() -= translation; ChasteCuboid<2> cuboid(lower, upper); pde_handler.UseCoarsePdeMesh(1.0, cuboid); pde_handler.SetImposeBcsOnCoarseBoundary(true); simulator.SetCellBasedPdeHandler(&pde_handler); // Create update rules and pass to the simulation MAKE_PTR(DiffusionMultipleCaUpdateRule<2>, p_diffusion_update_rule); p_diffusion_update_rule->SetDiffusionParameter(0.5); simulator.AddMultipleCaUpdateRule(p_diffusion_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 TS_ASSERT_DELTA(cell_iter->GetCellData()->GetItem("nutrient"), analytic_solution, 1e-2); } // Find centre of coarse PDE mesh c_vector<double,2> centre_of_coarse_pde_mesh = zero_vector<double>(2); TetrahedralMesh<2,2>* p_coarse_mesh = simulator.GetCellBasedPdeHandler()->GetCoarsePdeMesh(); for (unsigned i=0; i<p_coarse_mesh->GetNumNodes(); i++) { centre_of_coarse_pde_mesh += p_coarse_mesh->GetNode(i)->rGetLocation(); } centre_of_coarse_pde_mesh /= p_coarse_mesh->GetNumNodes(); c_vector<double,2> centre_diff = centre_of_coarse_pde_mesh - centre_of_potts_mesh; // Test that the two centres match TS_ASSERT_DELTA(norm_2(centre_diff), 0.0, 1e-4); // Test FindCoarseElementContainingCell() and initialisation of mCellPdeElementMap for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin(); cell_iter != cell_population.End(); ++cell_iter) { unsigned containing_element_index = simulator.GetCellBasedPdeHandler()->mCellPdeElementMap[*cell_iter]; TS_ASSERT_LESS_THAN(containing_element_index, p_coarse_mesh->GetNumElements()); TS_ASSERT_EQUALS(containing_element_index, simulator.GetCellBasedPdeHandler()->FindCoarseElementContainingCell(*cell_iter)); } // 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("nutrient"), analytic_solution, 1e-2); } }
// In this test there are only 50 cells but 100 lattice sites void TestMultipleCaBasedWithCellwiseSourcePde() throw(Exception) { EXIT_IF_PARALLEL; // Create a simple 2D PottsMesh PottsMeshGenerator<2> generator(10, 0, 0, 10, 0, 0); PottsMesh<2>* p_mesh = generator.GetMesh(); // Create cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, 50); std::vector<unsigned> location_indices; for (unsigned i=0; i<50; i++) { location_indices.push_back(i); } // Create cell population MultipleCaBasedCellPopulation<2> cell_population(*p_mesh, cells, location_indices); // Set up cell-based simulation OnLatticeSimulation<2> simulator(cell_population); simulator.SetOutputDirectory("TestMultipleCaBasedCellPopulationWithPdesOnNaturalMesh"); simulator.SetDt(0.1); simulator.SetEndTime(1); CellwiseSourcePde<2> pde(cell_population, 0.0); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_and_bc.SetDependentVariableName("nutrient"); double pde_coefficient = 0.0; TS_ASSERT_DELTA(pde.ComputeLinearInUCoeffInSourceTermAtNode(*p_mesh->GetNode(0)), pde_coefficient, 1e-3); CellwiseSourcePde<2> non_trivial_pde(cell_population, 1.0); double non_trivial_pde_coefficient = 1.0; for (PottsMesh<2>::NodeIterator node_iter = p_mesh->GetNodeIteratorBegin(); node_iter != p_mesh->GetNodeIteratorEnd(); ++node_iter) { if (node_iter->GetIndex()<50) { TS_ASSERT_DELTA(non_trivial_pde.ComputeLinearInUCoeffInSourceTermAtNode(*node_iter), non_trivial_pde_coefficient, 1e-3); } else { // No cell attached TS_ASSERT_DELTA(non_trivial_pde.ComputeLinearInUCoeffInSourceTermAtNode(*node_iter), 0.0, 1e-3); } } CellBasedPdeHandler<2> pde_handler(&cell_population); pde_handler.AddPdeAndBc(&pde_and_bc); pde_handler.SetImposeBcsOnCoarseBoundary(false); simulator.SetCellBasedPdeHandler(&pde_handler); 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 TS_ASSERT_DELTA(cell_iter->GetCellData()->GetItem("nutrient"), analytic_solution, 1e-2); } }
void TestArchivingOfPdeHandlerOnCuboid() throw(Exception) { EXIT_IF_PARALLEL; FileFinder archive_dir("archive", RelativeTo::ChasteTestOutput); std::string archive_file = "CellBasedPdeHandlerOnCuboid.arch"; ArchiveLocationInfo::SetMeshFilename("pde_handler_mesh"); { // Create a cell population HoneycombMeshGenerator generator(2, 2, 0); MutableMesh<2,2>* p_generating_mesh = generator.GetMesh(); NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, mesh.GetNumNodes()); NodeBasedCellPopulation<2> cell_population(mesh, cells); // Create a PDE handler object using this cell population CellBasedPdeHandlerOnCuboid<2>* const p_pde_handler = new CellBasedPdeHandlerOnCuboid<2>(&cell_population); // Set member variables for testing p_pde_handler->SetWriteAverageRadialPdeSolution("averaged quantity", 5, true); p_pde_handler->SetImposeBcsOnCoarseBoundary(false); // Set up PDE and pass to handler AveragedSourcePde<2> pde(cell_population, -0.1); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_and_bc.SetDependentVariableName("averaged quantity"); p_pde_handler->AddPdeAndBc(&pde_and_bc); // Test UseCoarsePdeMesh() again ChastePoint<2> lower(0.0, 0.0); ChastePoint<2> upper(9.0, 9.0); ChasteCuboid<2> cuboid(lower, upper); p_pde_handler->UseCoarsePdeMesh(3.0, cuboid, true); // Create an output archive ArchiveOpener<boost::archive::text_oarchive, std::ofstream> arch_opener(archive_dir, archive_file); boost::archive::text_oarchive* p_arch = arch_opener.GetCommonArchive(); // Archive object SimulationTime* p_simulation_time = SimulationTime::Instance(); p_simulation_time->SetEndTimeAndNumberOfTimeSteps(1.0, 11); (*p_arch) << static_cast<const SimulationTime&>(*p_simulation_time); (*p_arch) << p_pde_handler; // Tidy up SimulationTime::Destroy(); delete p_pde_handler; } { CellBasedPdeHandlerOnCuboid<2>* p_pde_handler; // Create an input archive ArchiveOpener<boost::archive::text_iarchive, std::ifstream> arch_opener(archive_dir, archive_file); boost::archive::text_iarchive* p_arch = arch_opener.GetCommonArchive(); // Restore object from the archive SimulationTime* p_simulation_time = SimulationTime::Instance(); (*p_arch) >> *p_simulation_time; (*p_arch) >> p_pde_handler; // Test that the member variables were archived correctly TS_ASSERT_EQUALS(p_pde_handler->mpCellPopulation->GetNumRealCells(), 4u); TS_ASSERT_EQUALS(p_pde_handler->GetWriteAverageRadialPdeSolution(), true); TS_ASSERT_EQUALS(p_pde_handler->GetWriteDailyAverageRadialPdeSolution(), true); TS_ASSERT_EQUALS(p_pde_handler->GetImposeBcsOnCoarseBoundary(), false); TS_ASSERT_EQUALS(p_pde_handler->GetNumRadialIntervals(), 5u); TS_ASSERT_EQUALS(p_pde_handler->mAverageRadialSolutionVariableName, "averaged quantity"); ///\todo we currently do not archive mpCoarsePdeMesh - consider doing this (#1891) TS_ASSERT(p_pde_handler->GetCoarsePdeMesh() == NULL); TS_ASSERT_EQUALS(p_pde_handler->mPdeAndBcCollection.size(), 1u); TS_ASSERT_EQUALS(p_pde_handler->mPdeAndBcCollection[0]->IsNeumannBoundaryCondition(), false); // Tidy up delete p_pde_handler->mpCellPopulation; delete p_pde_handler; } }
void TestUseCoarsePdeMesh() throw(Exception) { EXIT_IF_PARALLEL; // Create a cell population HoneycombMeshGenerator generator(4, 4, 0); MutableMesh<2,2>* p_generating_mesh = generator.GetMesh(); NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, mesh.GetNumNodes()); NodeBasedCellPopulation<2> cell_population(mesh, cells); // Create a PDE handler object using this cell population CellBasedPdeHandler<2> pde_handler(&cell_population); // Test that UseCoarsePdeMesh() throws an exception if no PDEs are specified ChastePoint<2> lower(0.0, 0.0); ChastePoint<2> upper(9.0, 9.0); ChasteCuboid<2> cuboid(lower, upper); TS_ASSERT_THROWS_THIS(pde_handler.UseCoarsePdeMesh(3.0, cuboid, true), "mPdeAndBcCollection should be populated prior to calling UseCoarsePdeMesh()."); // Set up PDE and pass to handler AveragedSourcePde<2> pde(cell_population, -0.1); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_handler.AddPdeAndBc(&pde_and_bc); // Test UseCoarsePdeMesh() again pde_handler.UseCoarsePdeMesh(3.0, cuboid, true); // Test that the coarse mesh has the correct number of nodes and elements TetrahedralMesh<2,2>* p_coarse_mesh = pde_handler.GetCoarsePdeMesh(); TS_ASSERT_EQUALS(p_coarse_mesh->GetNumNodes(), 16u); TS_ASSERT_EQUALS(p_coarse_mesh->GetNumElements(), 18u); // Find centre of cell population c_vector<double,2> centre_of_cell_population = cell_population.GetCentroidOfCellPopulation(); // Find centre of coarse PDE mesh c_vector<double,2> centre_of_coarse_pde_mesh = zero_vector<double>(2); for (unsigned i=0; i<p_coarse_mesh->GetNumNodes(); i++) { centre_of_coarse_pde_mesh += p_coarse_mesh->GetNode(i)->rGetLocation(); } centre_of_coarse_pde_mesh /= p_coarse_mesh->GetNumNodes(); // Test that the two centres match c_vector<double,2> centre_difference = centre_of_cell_population - centre_of_coarse_pde_mesh; TS_ASSERT_DELTA(norm_2(centre_difference), 0.0, 1e-4); // Test that UseCoarsePdeMesh() throws an exception if the wrong type of PDE is specified SimpleUniformSourcePde<2> pde2(-0.1); ConstBoundaryCondition<2> bc2(1.0); PdeAndBoundaryConditions<2> pde_and_bc2(&pde2, &bc2, false); pde_and_bc2.SetDependentVariableName("second variable"); pde_handler.AddPdeAndBc(&pde_and_bc2); TS_ASSERT_THROWS_THIS(pde_handler.UseCoarsePdeMesh(3.0, cuboid, true), "UseCoarsePdeMesh() should only be called if averaged-source PDEs are specified."); // Now test the 1D case std::vector<Node<1>*> nodes_1d; nodes_1d.push_back(new Node<1>(0, true, 0.0)); NodesOnlyMesh<1> mesh_1d; mesh_1d.ConstructNodesWithoutMesh(nodes_1d, 1.5); std::vector<CellPtr> cells_1d; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 1> cells_generator_1d; cells_generator_1d.GenerateBasic(cells_1d, mesh_1d.GetNumNodes()); NodeBasedCellPopulation<1> cell_population_1d(mesh_1d, cells_1d); CellBasedPdeHandler<1> pde_handler_1d(&cell_population_1d); AveragedSourcePde<1> pde_1d(cell_population_1d, -0.1); ConstBoundaryCondition<1> bc_1d(1.0); PdeAndBoundaryConditions<1> pde_and_bc_1d(&pde_1d, &bc_1d, false); pde_handler_1d.AddPdeAndBc(&pde_and_bc_1d); ChastePoint<1> lower1(0.0); ChastePoint<1> upper1(9.0); ChasteCuboid<1> cuboid1(lower1, upper1); pde_handler_1d.UseCoarsePdeMesh(3.0, cuboid1, true); // Test that the coarse mesh has the correct number of nodes and elements TetrahedralMesh<1,1>* p_coarse_mesh_1d = pde_handler_1d.GetCoarsePdeMesh(); TS_ASSERT_EQUALS(p_coarse_mesh_1d->GetNumNodes(), 4u); TS_ASSERT_EQUALS(p_coarse_mesh_1d->GetNumElements(), 3u); // Now test the 3D case std::vector<Node<3>*> nodes_3d; nodes_3d.push_back(new Node<3>(0, true, 0.0)); NodesOnlyMesh<3> mesh_3d; mesh_3d.ConstructNodesWithoutMesh(nodes_3d, 1.5); std::vector<CellPtr> cells_3d; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 3> cells_generator_3d; cells_generator_3d.GenerateBasic(cells_3d, mesh_3d.GetNumNodes()); NodeBasedCellPopulation<3> cell_population_3d(mesh_3d, cells_3d); CellBasedPdeHandler<3> pde_handler_3d(&cell_population_3d); AveragedSourcePde<3> pde_3d(cell_population_3d, -0.1); ConstBoundaryCondition<3> bc_3d(1.0); PdeAndBoundaryConditions<3> pde_and_bc_3d(&pde_3d, &bc_3d, false); pde_handler_3d.AddPdeAndBc(&pde_and_bc_3d); ChastePoint<3> lower3(0.0, 0.0, 0.0); ChastePoint<3> upper3(9.0, 9.0, 9.0); ChasteCuboid<3> cuboid3(lower3, upper3); pde_handler_3d.UseCoarsePdeMesh(3.0, cuboid3, true); // Test that the coarse mesh has the correct number of nodes and elements TetrahedralMesh<3,3>* p_coarse_mesh_3d = pde_handler_3d.GetCoarsePdeMesh(); TS_ASSERT_EQUALS(p_coarse_mesh_3d->GetNumNodes(), 64u); TS_ASSERT_EQUALS(p_coarse_mesh_3d->GetNumElements(), 162u); // Avoid memory leak for (unsigned i=0; i<nodes_1d.size(); i++) { delete nodes_1d[i]; delete nodes_3d[i]; } }
void TestSetMethods() throw(Exception) { EXIT_IF_PARALLEL; // Create a cell population HoneycombMeshGenerator generator(2, 2, 0); MutableMesh<2,2>* p_generating_mesh = generator.GetMesh(); NodesOnlyMesh<2> mesh; mesh.ConstructNodesWithoutMesh(*p_generating_mesh, 1.5); std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, mesh.GetNumNodes()); NodeBasedCellPopulation<2> cell_population(mesh, cells); // Create a PDE handler object using this cell population CellBasedPdeHandler<2> pde_handler(&cell_population); // Test set and get methods pde_handler.SetWriteAverageRadialPdeSolution("averaged quantity"); TS_ASSERT_EQUALS(pde_handler.GetWriteAverageRadialPdeSolution(), true); TS_ASSERT_EQUALS(pde_handler.GetWriteDailyAverageRadialPdeSolution(), false); TS_ASSERT_EQUALS(pde_handler.GetNumRadialIntervals(), 10u); pde_handler.SetWriteAverageRadialPdeSolution("averaged quantity", 5, true); TS_ASSERT_EQUALS(pde_handler.GetWriteAverageRadialPdeSolution(), true); TS_ASSERT_EQUALS(pde_handler.GetWriteDailyAverageRadialPdeSolution(), true); TS_ASSERT_EQUALS(pde_handler.GetNumRadialIntervals(), 5u); pde_handler.SetImposeBcsOnCoarseBoundary(false); TS_ASSERT_EQUALS(pde_handler.GetImposeBcsOnCoarseBoundary(), false); // Test AddPdeAndBc() SimpleUniformSourcePde<2> pde(-0.1); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_and_bc.SetDependentVariableName("averaged quantity"); unsigned num_nodes = mesh.GetNumNodes(); std::vector<double> data(num_nodes); for (unsigned i=0; i<num_nodes; i++) { data[i] = i + 0.45; } Vec vector = PetscTools::CreateVec(data); pde_and_bc.SetSolution(vector); pde_handler.AddPdeAndBc(&pde_and_bc); TS_ASSERT_EQUALS(pde_handler.mPdeAndBcCollection[0]->IsNeumannBoundaryCondition(), false); TS_ASSERT_EQUALS(pde_handler.mPdeAndBcCollection[0]->HasAveragedSourcePde(), false); ReplicatableVector solution(pde_handler.GetPdeSolution()); TS_ASSERT_EQUALS(solution.GetSize(), num_nodes); for (unsigned i=0; i<num_nodes; i++) { TS_ASSERT_DELTA(solution[i], i + 0.45, 1e-4); } }
void TestSolvePdeAndWriteResultsToFileWithCoarsePdeMesh() throw(Exception) { EXIT_IF_PARALLEL; // Set up SimulationTime SimulationTime::Instance()->SetEndTimeAndNumberOfTimeSteps(0.05, 6); // Create a cell population HoneycombMeshGenerator generator(5, 5, 0); MutableMesh<2,2>* p_mesh = generator.GetMesh(); std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, p_mesh->GetNumNodes()); MeshBasedCellPopulation<2> cell_population(*p_mesh, cells); // Create a PDE handler object using this cell population CellBasedPdeHandler<2> pde_handler(&cell_population); // Set up PDE and pass to handler AveragedSourcePde<2> pde(cell_population, -0.1); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_and_bc.SetDependentVariableName("quantity 1"); pde_handler.AddPdeAndBc(&pde_and_bc); // Set up second PDE and pass to handler AveragedSourcePde<2> pde2(cell_population, -0.5); PdeAndBoundaryConditions<2> pde_and_bc2(&pde2, &bc, false); TS_ASSERT_THROWS_THIS(pde_handler.AddPdeAndBc(&pde_and_bc2), "When adding more than one PDE to CellBasedPdeHandler set the dependent variable name using SetDependentVariableName(name)."); pde_and_bc2.SetDependentVariableName("quantity 1"); TS_ASSERT_THROWS_THIS(pde_handler.AddPdeAndBc(&pde_and_bc2), "The name quantity 1 has already been used in the PDE collection"); pde_and_bc2.SetDependentVariableName("quantity 2"); pde_handler.AddPdeAndBc(&pde_and_bc2); // Solve PDEs on a coarse mesh 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(false); // Open result file ourselves OutputFileHandler output_file_handler("TestSolvePdeAndWriteResultsToFileWithCoarsePdeMesh", false); pde_handler.mpVizPdeSolutionResultsFile = output_file_handler.OpenOutputFile("results.vizpdesolution"); // Solve PDEs and (for coverage) write results to file pde_handler.SolvePdeAndWriteResultsToFile(1); // Close result file ourselves pde_handler.mpVizPdeSolutionResultsFile->close(); TetrahedralMesh<2,2>* p_coarse_mesh = pde_handler.GetCoarsePdeMesh(); TS_ASSERT(p_coarse_mesh != NULL); TS_ASSERT_THROWS_THIS(pde_handler.GetPdeSolution("quantity 3"), "The PDE collection does not contain a PDE named quantity 3"); ReplicatableVector pde_solution0(pde_handler.GetPdeSolution("quantity 1")); ReplicatableVector pde_solution1(pde_handler.GetPdeSolution("quantity 2")); TS_ASSERT_EQUALS(pde_solution0.GetSize(), pde_solution1.GetSize()); // Test that the solution is 1.0 at each coarse mesh node far from the cells for (unsigned i=0; i<pde_solution0.GetSize(); i++) { c_vector<double,2> centre; centre(0) = 2.5; // assuming 5x5 honeycomb mesh centre(1) = 2.5; c_vector<double,2> position = p_coarse_mesh->GetNode(i)->rGetLocation(); double dist = norm_2(centre - position); double u0 = pde_solution0[i]; double u1 = pde_solution1[i]; if (dist > 4.0) { TS_ASSERT_DELTA(u0, 1.0, 1e-5); TS_ASSERT_DELTA(u1, 1.0, 1e-5); } } /* * Loop over cells, find the coarse mesh element containing it, then * check the interpolated PDE solution is between the min and max of * the PDE solution on the nodes of that element. */ for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin(); cell_iter != cell_population.End(); ++cell_iter) { c_vector<double,2> cell_location = cell_population.GetLocationOfCellCentre(*cell_iter); unsigned elem_index = p_coarse_mesh->GetContainingElementIndex(cell_location); Element<2,2>* p_element = p_coarse_mesh->GetElement(elem_index); unsigned node_0_index = p_element->GetNodeGlobalIndex(0); unsigned node_1_index = p_element->GetNodeGlobalIndex(1); unsigned node_2_index = p_element->GetNodeGlobalIndex(2); double max0 = std::max(pde_solution0[node_0_index], pde_solution0[node_1_index]); max0 = std::max(max0, pde_solution0[node_2_index]); double max1 = std::max(pde_solution1[node_0_index], pde_solution1[node_1_index]); max1 = std::max(max1, pde_solution1[node_2_index]); double min0 = std::min(pde_solution0[node_0_index], pde_solution0[node_1_index]); min0 = std::min(min0, pde_solution0[node_2_index]); double min1 = std::min(pde_solution1[node_0_index], pde_solution1[node_1_index]); min1 = std::min(min1, pde_solution1[node_2_index]); double value0_at_cell = cell_iter->GetCellData()->GetItem("quantity 1"); double value1_at_cell = cell_iter->GetCellData()->GetItem("quantity 2"); TS_ASSERT_LESS_THAN_EQUALS(value1_at_cell, value0_at_cell); TS_ASSERT_LESS_THAN_EQUALS(min0, value0_at_cell + DBL_EPSILON); TS_ASSERT_LESS_THAN_EQUALS(value0_at_cell, max0 + DBL_EPSILON); TS_ASSERT_LESS_THAN_EQUALS(min1, value1_at_cell + DBL_EPSILON); TS_ASSERT_LESS_THAN_EQUALS(value1_at_cell, max1 + DBL_EPSILON); // Now check the GetPdeSolutionAtPoint method matches TS_ASSERT_DELTA(pde_handler.GetPdeSolutionAtPoint(cell_location, "quantity 1"), value0_at_cell, 1e-6); TS_ASSERT_DELTA(pde_handler.GetPdeSolutionAtPoint(cell_location, "quantity 2"), value1_at_cell, 1e-6); } }
void TestAveragedSourcePdeMethods() throw(Exception) { EXIT_IF_PARALLEL; // Set up cell population HoneycombMeshGenerator generator(5, 5, 0); MutableMesh<2,2>* p_mesh = generator.GetMesh(); std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, p_mesh->GetNumNodes()); MeshBasedCellPopulation<2> cell_population(*p_mesh, cells); // Create a PDE object AveragedSourcePde<2> pde(cell_population, 0.05); // Test that the member variables have been initialised correctly TS_ASSERT_EQUALS(&(pde.rGetCellPopulation()), &cell_population); TS_ASSERT_DELTA(pde.GetCoefficient(), 0.05, 1e-6); // For simplicity we create a very large coarse mesh, so we know that all cells are contained in one element TrianglesMeshReader<2,2> mesh_reader("mesh/test/data/square_2_elements"); TetrahedralMesh<2,2> coarse_mesh; coarse_mesh.ConstructFromMeshReader(mesh_reader); coarse_mesh.Scale(10.0, 10.0); // Test SetupSourceTerms() when no map between cells and coarse mesh elements is supplied pde.SetupSourceTerms(coarse_mesh); TS_ASSERT_EQUALS(pde.mCellDensityOnCoarseElements.size(), 2u); // The first element has area 0.5*10*10 = 50 and there are 5*5 = 25 cells, so the cell density is 25/50 = 0.5 TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[0], 0.5, 1e-6); // The first element doesn't contain any cells, so the cell density is zero TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[1], 0.0, 1e-6); // Now test SetupSourceTerms() when a map between cells and coarse mesh elements is supplied std::map<CellPtr, unsigned> cell_pde_element_map; for (AbstractCellPopulation<2>::Iterator cell_iter = cell_population.Begin(); cell_iter != cell_population.End(); ++cell_iter) { cell_pde_element_map[*cell_iter] = 0; } pde.SetupSourceTerms(coarse_mesh, &cell_pde_element_map); TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[0], 0.5, 1e-6); TS_ASSERT_DELTA(pde.mCellDensityOnCoarseElements[1], 0.0, 1e-6); // Test GetUptakeRateForElement() TS_ASSERT_DELTA(pde.GetUptakeRateForElement(0), 0.5, 1e-6); TS_ASSERT_DELTA(pde.GetUptakeRateForElement(1), 0.0, 1e-6); // Test other methods ChastePoint<2> point; TS_ASSERT_DELTA(pde.ComputeLinearInUCoeffInSourceTerm(point, coarse_mesh.GetElement(0)), 0.05*0.5, 1e-6); TS_ASSERT_DELTA(pde.ComputeConstantInUSourceTerm(point, NULL), 0.0, 1e-6); c_matrix<double,2,2> diffusion_matrix = pde.ComputeDiffusionTerm(point); for (unsigned i=0; i<2; i++) { for (unsigned j=0; j<2; j++) { double value = 0.0; if (i == j) { value = 1.0; } TS_ASSERT_DELTA(diffusion_matrix(i,j), value, 1e-6); } } }
double rkck(double ****f, double ****df1, double ***nut, double t, double dt, double ****fout) { static double a2=0.2,a3=0.3,a4=0.6,a5=1.0,a6=0.875,b21=0.2, b31=3.0/40.0,b32=9.0/40.0,b41=0.3,b42 = -0.9,b43=1.2, b51 = -11.0/54.0, b52=2.5,b53 = -70.0/27.0,b54=35.0/27.0, b61=1631.0/55296.0,b62=175.0/512.0,b63=575.0/13824.0, b64=44275.0/110592.0,b65=253.0/4096.0,c1=37.0/378.0, c3=250.0/621.0,c4=125.0/594.0,c6=512.0/1771.0, dc5 = -277.00/14336.0; double dc1=c1-2825.0/27648.0,dc3=c3-18575.0/48384.0, dc4=c4-13525.0/55296.0,dc6=c6-0.25; int i,j,k,l; double err, sca, err1; /*2rd step*/ for(l=0;l<nvar;l++) for(i=ghost;i<mm1;i++) for(j=ghost;j<mm2;j++) for(k=ghost;k<mm3;k++) fout[l][i][j][k] = f[l][i][j][k]+dt*b21*df1[l][i][j][k]; pde(t+a2*dt,fout, df2); /*3rd step*/ for(l=0;l<nvar;l++) for(i=ghost;i<mm1;i++) for(j=ghost;j<mm2;j++) for(k=ghost;k<mm3;k++) fout[l][i][j][k] = f[l][i][j][k]+dt*(b31*df1[l][i][j][k]+ b32*df2[l][i][j][k]); pde(t+a3*dt,fout, df3); /*4th step*/ for(l=0;l<nvar;l++) for(i=ghost;i<mm1;i++) for(j=ghost;j<mm2;j++) for(k=ghost;k<mm3;k++) fout[l][i][j][k] = f[l][i][j][k]+dt*(b41*df1[l][i][j][k]+ b42*df2[l][i][j][k]+ b43*df3[l][i][j][k]); pde(t+a4*dt,fout, df4); /*5th step*/ for(l=0;l<nvar;l++) for(i=ghost;i<mm1;i++) for(j=ghost;j<mm2;j++) for(k=ghost;k<mm3;k++) fout[l][i][j][k] = f[l][i][j][k]+dt*(b51*df1[l][i][j][k]+ b52*df2[l][i][j][k]+ b53*df3[l][i][j][k]+ b54*df4[l][i][j][k]); pde(t+a5*dt,fout, df5); /*6th step*/ for(l=0;l<nvar;l++) for(i=ghost;i<mm1;i++) for(j=ghost;j<mm2;j++) for(k=ghost;k<mm3;k++) fout[l][i][j][k] = f[l][i][j][k]+dt*(b61*df1[l][i][j][k]+ b62*df2[l][i][j][k]+ b63*df3[l][i][j][k]+ b64*df4[l][i][j][k]+ b65*df5[l][i][j][k]); pde(t+a6*dt,fout, df2); /*calculating output matrix and error value*/ err = 0.0; for(l=0;l<nvar;l++) for(i=ghost;i<mm1;i++) for(j=ghost;j<mm2;j++) for(k=ghost;k<mm3;k++) { fout[l][i][j][k] = f[l][i][j][k]+dt*(c1*df1[l][i][j][k]+ c3*df3[l][i][j][k]+ c4*df4[l][i][j][k]+ c6*df2[l][i][j][k]); sca = fabs(f[l][i][j][k])+fabs(dt*df1[l][i][j][k])+MinScale; err1 = fabs(dt*( dc1*df1[l][i][j][k]+ dc3*df3[l][i][j][k]+ dc4*df4[l][i][j][k]+ dc5*df5[l][i][j][k]+ dc6*df2[l][i][j][k]))/sca; err = max(err, err1); } return err; }
// Under construction: Test growth of a population of cells that consumes nutrient void TestOnLatticeSpheroidWithNutrient() throw(Exception) { EXIT_IF_PARALLEL; // Create a simple 2D PottsMesh PottsMeshGenerator<2> generator(10, 0, 0, 10, 0, 0); PottsMesh<2>* p_mesh = generator.GetMesh(); // Create cells std::vector<CellPtr> cells; CellsGenerator<FixedDurationGenerationBasedCellCycleModel, 2> cells_generator; cells_generator.GenerateBasic(cells, 4); std::vector<unsigned> location_indices; location_indices.push_back(55); location_indices.push_back(56); location_indices.push_back(65); location_indices.push_back(66); // Create cell population MultipleCaBasedCellPopulation<2> cell_population(*p_mesh, cells, location_indices); // Set up cell-based simulation OnLatticeSimulation<2> simulator(cell_population); simulator.SetOutputDirectory("TestOnLatticeSpheroidWithNutrient"); simulator.SetDt(0.1); simulator.SetSamplingTimestepMultiple(10); simulator.SetEndTime(10); // Set up PDE and pass to simulation via handler double nutrient_uptake_rate=-0.1; AveragedSourcePde<2> pde(cell_population, nutrient_uptake_rate); ConstBoundaryCondition<2> bc(1.0); PdeAndBoundaryConditions<2> pde_and_bc(&pde, &bc, false); pde_and_bc.SetDependentVariableName("nutrient"); CellBasedPdeHandler<2> pde_handler(&cell_population); pde_handler.AddPdeAndBc(&pde_and_bc); pde_handler.SetImposeBcsOnCoarseBoundary(true); simulator.SetCellBasedPdeHandler(&pde_handler); // Create update rules and pass to the simulation MAKE_PTR(DiffusionMultipleCaUpdateRule<2>, p_diffusion_update_rule); p_diffusion_update_rule->SetDiffusionParameter(0.5); simulator.AddMultipleCaUpdateRule(p_diffusion_update_rule); // Solve the system simulator.Solve(); //Test coarse mesh has the same nodes as the PottsMesh TetrahedralMesh<2,2>* p_coarse_mesh = simulator.GetCellBasedPdeHandler()->GetCoarsePdeMesh(); TS_ASSERT_EQUALS(p_coarse_mesh->GetNumNodes(),p_mesh->GetNumNodes()); TS_ASSERT_DELTA(p_coarse_mesh->GetWidth(0),p_mesh->GetWidth(0),1e-8); TS_ASSERT_DELTA(p_coarse_mesh->GetWidth(1),p_mesh->GetWidth(1),1e-8); for (unsigned i=0; i< p_coarse_mesh->GetNumNodes(); i++) { TS_ASSERT_DELTA(p_coarse_mesh->GetNode(i)->rGetLocation()[0],p_mesh->GetNode(i)->rGetLocation()[0],1e-8); TS_ASSERT_DELTA(p_coarse_mesh->GetNode(i)->rGetLocation()[1],p_mesh->GetNode(i)->rGetLocation()[1],1e-8); } }
/* * Define a particular test. */ void TestSchnackenbergSystemOnButterflyMesh() throw (Exception) { /* As usual, we first create a mesh. Here we are using a 2d mesh of a butterfly-shaped domain. */ TrianglesMeshReader<2,2> mesh_reader("mesh/test/data/butterfly"); TetrahedralMesh<2,2> mesh; mesh.ConstructFromMeshReader(mesh_reader); /* We scale the mesh to an appropriate size. */ mesh.Scale(0.2, 0.2); /* Next, we instantiate the PDE system to be solved. We pass the parameter values into the * constructor. (The order is D,,1,, D,,2,, k,,1,, k,,-1,, k,,2,, k,,3,,) */ SchnackenbergCoupledPdeSystem<2> pde(1e-4, 1e-2, 0.1, 0.2, 0.3, 0.1); /* * Then we have to define the boundary conditions. As we are in 2d, {{{SPACE_DIM}}}=2 and * {{{ELEMENT_DIM}}}=2. We also have two unknowns u and v, * so in this case {{{PROBLEM_DIM}}}=2. The value of each boundary condition is * given by the spatially uniform steady state solution of the Schnackenberg system, * given by u = (k,,1,, + k,,2,,)/k,,-1,,, v = k,,2,,k,,-1,,^2^/k,,3,,(k,,1,, + k,,2,,)^2^. */ BoundaryConditionsContainer<2,2,2> bcc; ConstBoundaryCondition<2>* p_bc_for_u = new ConstBoundaryCondition<2>(2.0); ConstBoundaryCondition<2>* p_bc_for_v = new ConstBoundaryCondition<2>(0.75); for (TetrahedralMesh<2,2>::BoundaryNodeIterator node_iter = mesh.GetBoundaryNodeIteratorBegin(); node_iter != mesh.GetBoundaryNodeIteratorEnd(); ++node_iter) { bcc.AddDirichletBoundaryCondition(*node_iter, p_bc_for_u, 0); bcc.AddDirichletBoundaryCondition(*node_iter, p_bc_for_v, 1); } /* This is the solver for solving coupled systems of linear parabolic PDEs and ODEs, * which takes in the mesh, the PDE system, the boundary conditions and optionally * a vector of ODE systems (one for each node in the mesh). Since in this example * we are solving a system of coupled PDEs only, we do not supply this last argument. */ LinearParabolicPdeSystemWithCoupledOdeSystemSolver<2,2,2> solver(&mesh, &pde, &bcc); /* Then we set the end time and time step and the output directory to which results will be written. */ double t_end = 10; solver.SetTimes(0, t_end); solver.SetTimeStep(1e-1); solver.SetSamplingTimeStep(1); solver.SetOutputDirectory("TestSchnackenbergSystemOnButterflyMesh"); /* We create a vector of initial conditions for u and v that are random perturbations * of the spatially uniform steady state and pass this to the solver. */ std::vector<double> init_conds(2*mesh.GetNumNodes()); for (unsigned i=0; i<mesh.GetNumNodes(); i++) { init_conds[2*i] = fabs(2.0 + RandomNumberGenerator::Instance()->ranf()); init_conds[2*i + 1] = fabs(0.75 + RandomNumberGenerator::Instance()->ranf()); } Vec initial_condition = PetscTools::CreateVec(init_conds); solver.SetInitialCondition(initial_condition); /* We now solve the PDE system and write results to VTK files, for * visualization using Paraview. Results will be written to CHASTE_TEST_OUTPUT/TestSchnackenbergSystemOnButterflyMesh * as a results.pvd file and several results_[time].vtu files. * You should see something like [[Image(u.png, 350px)]] for u and [[Image(v.png, 350px)]] for v. */ solver.SolveAndWriteResultsToFile(); /* * All PETSc {{{Vec}}}s should be destroyed when they are no longer needed. */ PetscTools::Destroy(initial_condition); }
int main() { // Set all ranges Range<double> X(Xfrom,Xto); Range<double> T(Yfrom,Yto); // Declare all TwoVarDFunctions TwoVarDFunction<double,double,double> Sigma(*sigma); TwoVarDFunction<double,double,double> Mu(*mu); TwoVarDFunction<double,double,double> Forcing(*forcing); TwoVarDFunction<double,double,double> B(*b); // Declare all AtomicDFunctions AtomicDFunction<double,double> Ic(*IC); // Change from Call<->Put // AtomicDFunction<double,double> Bcr(*BCR_Topper_p11); AtomicDFunction<double,double> Bcr(*BCR);// Change from Call<->Put AtomicDFunction<double,double> Bcl(*BCL);// Change from Call<->Put // Declare the pde ParabolicPDE<double,double,double> pde(X,T,Sigma,Mu,B,Forcing,Ic,Bcl,Bcr); // Declare the finite difference scheme // ParabolicFDM<double,double,double> FDM(pde,XINTERVALS,YINTERVALS,THETA); // V1 int choice = 3; cout << "1) Explicit Euler 2) Implicit Euler 3) Crank Nicolson "; cin >> choice; //OptionType type = AmericanCallType; OptionType type = EuropeanCallType; ParabolicFDM<double,double,double> FDM(pde,XINTERVALS,YINTERVALS,choice, type); // compute option prices FDM.start(); // Retrieve and store option prices Vector <double,long> result = FDM.line(); // Does include ENDS!! /////////////////////////////////////////////////////////// Vector<double, long> xArr = FDM.xarr(); Vector<double, long> tArr = FDM.tarr(); double h = xArr[2] - xArr[1]; double k = tArr[2] - tArr[1]; cout << "h " << h << endl; // Create and fill Delta vector Vector <double,long> DeltaMesh(xArr.Size()-2, xArr.MinIndex()); for (long kk = DeltaMesh.MinIndex(); kk <= DeltaMesh.MaxIndex(); kk++) { DeltaMesh[kk] = xArr[kk+1]; } Vector <double,long> Delta(result.Size()-2,result.MinIndex()); for (long i = Delta.MinIndex(); i <= Delta.MaxIndex(); i++) { Delta[i] = (result[i+1] - result[i])/(h); } print(result); print(Delta); // Create and fill Gamma vector Vector <double,long> GammaMesh(DeltaMesh.Size()-2, DeltaMesh.MinIndex()); for (long p = GammaMesh.MinIndex(); p <= GammaMesh.MaxIndex(); p++) { GammaMesh[p] = DeltaMesh[p+1]; } Vector <double,long> Gamma(Delta.Size()-2, Delta.MinIndex()); for (long n = Gamma.MinIndex(); n <= Gamma.MaxIndex(); n++) { Gamma[n] = (Delta[n+1] - Delta[n])/(h); } /*// Create and fill Theta vector Vector <double,long> ThetaMesh(tArr.Size()-1, tArr.MinIndex()); for (long m = ThetaMesh.MinIndex(); m <= ThetaMesh.MaxIndex(); m++) { ThetaMesh[m] = tArr[m+1]; }*/ long NP1 = FDM.result().MaxRowIndex(); long NP = FDM.result().MaxRowIndex() -1; Vector <double,long> Theta(result.Size(), result.MinIndex()); for (long ii = Theta.MinIndex(); ii <= Theta.MaxIndex(); ii++) { Theta[ii] = -(FDM.result()(NP1, ii) -FDM.result()(NP, ii) )/k; } try { printOneExcel(FDM.xarr(), result, string("Price")); printOneExcel(DeltaMesh, Delta, string("Delta")); printOneExcel(GammaMesh, Gamma, string("Gamma")); printOneExcel(FDM.xarr(), Theta, string("Theta")); } catch(DatasimException& e) { e.print(); ExcelDriver& excel = ExcelDriver::Instance(); excel.MakeVisible(true); long y = 1; excel.printStringInExcel(e.Message(), y, y, string("Err")); list<string> dump; dump.push_back(e.MessageDump()[0]); dump.push_back(e.MessageDump()[1]); dump.push_back(e.MessageDump()[2]); excel.printStringInExcel(dump, 1, 1, string("Err")); return 0; } return 0; }