Exemplo n.º 1
0
    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);
            }
        }
    }
Exemplo n.º 2
0
    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"));
            }
        }
    }
Exemplo n.º 4
0
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");
    }
Exemplo n.º 7
0
    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));
        }
    }
Exemplo n.º 8
0
    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);
    }
Exemplo n.º 9
0
    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().");
    }
Exemplo n.º 11
0
    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);
            }
        }
    }
Exemplo n.º 12
0
    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);
    }
Exemplo n.º 14
0
    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();
    }
Exemplo n.º 15
0
    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);
        }
    }
Exemplo n.º 18
0
    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;
        }
    }
Exemplo n.º 19
0
    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];
        }
    }
Exemplo n.º 20
0
    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);
        }
    }
Exemplo n.º 21
0
    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);
        }
    }
Exemplo n.º 22
0
    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);
            }
        }
    }
Exemplo n.º 23
0
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;
}