/* * 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); }
/** * 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); }