1d2567f34SHong Zhang static char help[] = "Solves the constant-coefficient 1D heat equation \n\ 2d2567f34SHong Zhang with an Implicit Runge-Kutta method using MatKAIJ. \n\ 3d2567f34SHong Zhang \n\ 4d2567f34SHong Zhang du d^2 u \n\ 5d2567f34SHong Zhang -- = a ----- ; 0 <= x <= 1; \n\ 6d2567f34SHong Zhang dt dx^2 \n\ 7d2567f34SHong Zhang \n\ 8d2567f34SHong Zhang with periodic boundary conditions \n\ 9d2567f34SHong Zhang \n\ 10d2567f34SHong Zhang 2nd order central discretization in space: \n\ 11d2567f34SHong Zhang \n\ 12d2567f34SHong Zhang [ d^2 u ] u_{i+1} - 2u_i + u_{i-1} \n\ 13d2567f34SHong Zhang [ ----- ] = ------------------------ \n\ 14d2567f34SHong Zhang [ dx^2 ]i h^2 \n\ 15d2567f34SHong Zhang \n\ 16d2567f34SHong Zhang i = grid index; h = x_{i+1}-x_i (Uniform) \n\ 17d2567f34SHong Zhang 0 <= i < n h = 1.0/n \n\ 18d2567f34SHong Zhang \n\ 19d2567f34SHong Zhang Thus, \n\ 20d2567f34SHong Zhang \n\ 21d2567f34SHong Zhang du \n\ 22d2567f34SHong Zhang -- = Ju; J = (a/h^2) tridiagonal(1,-2,1)_n \n\ 23d2567f34SHong Zhang dt \n\ 24d2567f34SHong Zhang \n\ 25d2567f34SHong Zhang This example is a TS version of the KSP ex74.c tutorial. \n"; 26d2567f34SHong Zhang 27d2567f34SHong Zhang #include <petscts.h> 28d2567f34SHong Zhang 29d2567f34SHong Zhang typedef enum { 30d2567f34SHong Zhang PHYSICS_DIFFUSION, 31d2567f34SHong Zhang PHYSICS_ADVECTION 32d2567f34SHong Zhang } PhysicsType; 33d2567f34SHong Zhang const char *const PhysicsTypes[] = {"DIFFUSION","ADVECTION","PhysicsType","PHYSICS_",NULL}; 34d2567f34SHong Zhang 35d2567f34SHong Zhang typedef struct Context { 36d2567f34SHong Zhang PetscReal a; /* diffusion coefficient */ 37d2567f34SHong Zhang PetscReal xmin,xmax; /* domain bounds */ 38d2567f34SHong Zhang PetscInt imax; /* number of grid points */ 39d2567f34SHong Zhang PhysicsType physics_type; 40d2567f34SHong Zhang } UserContext; 41d2567f34SHong Zhang 42d2567f34SHong Zhang static PetscErrorCode ExactSolution(Vec,void*,PetscReal); 43d2567f34SHong Zhang static PetscErrorCode RHSJacobian(TS,PetscReal,Vec,Mat,Mat,void*); 44d2567f34SHong Zhang 45d2567f34SHong Zhang int main(int argc, char **argv) 46d2567f34SHong Zhang { 47d2567f34SHong Zhang TS ts; 48d2567f34SHong Zhang Mat A; 49d2567f34SHong Zhang Vec u,uex; 50d2567f34SHong Zhang UserContext ctxt; 51d2567f34SHong Zhang PetscReal err,ftime; 52d2567f34SHong Zhang PetscErrorCode ierr; 53d2567f34SHong Zhang 54d2567f34SHong Zhang ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; 55d2567f34SHong Zhang 56d2567f34SHong Zhang /* default value */ 57d2567f34SHong Zhang ctxt.a = 0.1; 58d2567f34SHong Zhang ctxt.xmin = 0.0; 59d2567f34SHong Zhang ctxt.xmax = 1.0; 60d2567f34SHong Zhang ctxt.imax = 40; 61d2567f34SHong Zhang ctxt.physics_type = PHYSICS_DIFFUSION; 62d2567f34SHong Zhang 63d2567f34SHong Zhang ierr = PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"IRK options","");CHKERRQ(ierr); 64d2567f34SHong Zhang ierr = PetscOptionsReal("-a","diffusion coefficient","<1.0>",ctxt.a,&ctxt.a,NULL);CHKERRQ(ierr); 65d2567f34SHong Zhang ierr = PetscOptionsInt ("-imax","grid size","<20>",ctxt.imax,&ctxt.imax,NULL);CHKERRQ(ierr); 66d2567f34SHong Zhang ierr = PetscOptionsReal("-xmin","xmin","<0.0>",ctxt.xmin,&ctxt.xmin,NULL);CHKERRQ(ierr); 67d2567f34SHong Zhang ierr = PetscOptionsReal("-xmax","xmax","<1.0>",ctxt.xmax,&ctxt.xmax,NULL);CHKERRQ(ierr); 68d2567f34SHong Zhang ierr = PetscOptionsEnum("-physics_type","Type of process to discretize","",PhysicsTypes,(PetscEnum)ctxt.physics_type,(PetscEnum*)&ctxt.physics_type,NULL);CHKERRQ(ierr); 69d2567f34SHong Zhang ierr = PetscOptionsEnd();CHKERRQ(ierr); 70d2567f34SHong Zhang 71d2567f34SHong Zhang /* allocate and initialize solution vector and exact solution */ 72d2567f34SHong Zhang ierr = VecCreate(PETSC_COMM_WORLD,&u);CHKERRQ(ierr); 73d2567f34SHong Zhang ierr = VecSetSizes(u,PETSC_DECIDE,ctxt.imax);CHKERRQ(ierr); 74d2567f34SHong Zhang ierr = VecSetFromOptions(u);CHKERRQ(ierr); 75d2567f34SHong Zhang ierr = VecDuplicate(u,&uex);CHKERRQ(ierr); 76d2567f34SHong Zhang /* initial solution */ 77d2567f34SHong Zhang ierr = ExactSolution(u,&ctxt,0.0);CHKERRQ(ierr); 78d2567f34SHong Zhang 79d2567f34SHong Zhang ierr = MatCreate(PETSC_COMM_WORLD,&A);CHKERRQ(ierr); 80d2567f34SHong Zhang ierr = MatSetType(A,MATAIJ);CHKERRQ(ierr); 81d2567f34SHong Zhang ierr = MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,ctxt.imax,ctxt.imax);CHKERRQ(ierr); 82d2567f34SHong Zhang ierr = MatSetUp(A);CHKERRQ(ierr); 83d2567f34SHong Zhang 84d2567f34SHong Zhang /* Create and set options for TS */ 85d2567f34SHong Zhang ierr = TSCreate(PETSC_COMM_WORLD,&ts);CHKERRQ(ierr); 86d2567f34SHong Zhang ierr = TSSetProblemType(ts,TS_LINEAR);CHKERRQ(ierr); 87d2567f34SHong Zhang ierr = TSSetTimeStep(ts,0.125);CHKERRQ(ierr); 88d2567f34SHong Zhang ierr = TSSetSolution(ts,u);CHKERRQ(ierr); 89d2567f34SHong Zhang ierr = TSSetMaxSteps(ts,10);CHKERRQ(ierr); 90d2567f34SHong Zhang ierr = TSSetMaxTime(ts,1.0);CHKERRQ(ierr); 91d2567f34SHong Zhang ierr = TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);CHKERRQ(ierr); 92d2567f34SHong Zhang ierr = TSSetRHSFunction(ts,NULL,TSComputeRHSFunctionLinear,&ctxt);CHKERRQ(ierr); 93d2567f34SHong Zhang ierr = RHSJacobian(ts,0,u,A,A,&ctxt);CHKERRQ(ierr); 94d2567f34SHong Zhang ierr = TSSetRHSJacobian(ts,A,A,TSComputeRHSJacobianConstant,&ctxt);CHKERRQ(ierr); 95d2567f34SHong Zhang ierr = TSSetFromOptions(ts);CHKERRQ(ierr); 96d2567f34SHong Zhang ierr = TSSolve(ts,u);CHKERRQ(ierr); 97d2567f34SHong Zhang 98d2567f34SHong Zhang ierr = TSGetSolveTime(ts,&ftime);CHKERRQ(ierr); 99d2567f34SHong Zhang /* exact solution */ 100d2567f34SHong Zhang ierr = ExactSolution(uex,&ctxt,ftime);CHKERRQ(ierr); 101d2567f34SHong Zhang 102d2567f34SHong Zhang /* Calculate error in final solution */ 103d2567f34SHong Zhang ierr = VecAYPX(uex,-1.0,u);CHKERRQ(ierr); 104d2567f34SHong Zhang ierr = VecNorm(uex,NORM_2,&err);CHKERRQ(ierr); 105d2567f34SHong Zhang err = PetscSqrtReal(err*err/((PetscReal)ctxt.imax)); 106d2567f34SHong Zhang ierr = PetscPrintf(PETSC_COMM_WORLD,"L2 norm of the numerical error = %g (time=%g)\n",(double)err,(double)ftime);CHKERRQ(ierr); 107d2567f34SHong Zhang 108d2567f34SHong Zhang /* Free up memory */ 109d2567f34SHong Zhang ierr = TSDestroy(&ts);CHKERRQ(ierr); 110d2567f34SHong Zhang ierr = MatDestroy(&A);CHKERRQ(ierr); 111d2567f34SHong Zhang ierr = VecDestroy(&uex);CHKERRQ(ierr); 112d2567f34SHong Zhang ierr = VecDestroy(&u);CHKERRQ(ierr); 113d2567f34SHong Zhang ierr = PetscFinalize(); 114d2567f34SHong Zhang return ierr; 115d2567f34SHong Zhang } 116d2567f34SHong Zhang 117d2567f34SHong Zhang PetscErrorCode ExactSolution(Vec u,void *c,PetscReal t) 118d2567f34SHong Zhang { 119d2567f34SHong Zhang UserContext *ctxt = (UserContext*) c; 120d2567f34SHong Zhang PetscErrorCode ierr; 121d2567f34SHong Zhang PetscInt i,is,ie; 122d2567f34SHong Zhang PetscScalar *uarr; 123d2567f34SHong Zhang PetscReal x,dx,a=ctxt->a,pi=PETSC_PI; 124d2567f34SHong Zhang 125d2567f34SHong Zhang PetscFunctionBegin; 126d2567f34SHong Zhang dx = (ctxt->xmax - ctxt->xmin)/((PetscReal) ctxt->imax); 127d2567f34SHong Zhang ierr = VecGetOwnershipRange(u,&is,&ie);CHKERRQ(ierr); 128d2567f34SHong Zhang ierr = VecGetArray(u,&uarr);CHKERRQ(ierr); 129d2567f34SHong Zhang for (i=is; i<ie; i++) { 130d2567f34SHong Zhang x = i * dx; 131d2567f34SHong Zhang switch (ctxt->physics_type) { 132d2567f34SHong Zhang case PHYSICS_DIFFUSION: 133d2567f34SHong Zhang uarr[i-is] = PetscExpScalar(-4.0*pi*pi*a*t)*PetscSinScalar(2*pi*x); 134d2567f34SHong Zhang break; 135d2567f34SHong Zhang case PHYSICS_ADVECTION: 136d2567f34SHong Zhang uarr[i-is] = PetscSinScalar(2*pi*(x - a*t)); 137d2567f34SHong Zhang break; 13898921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for physics type %s",PhysicsTypes[ctxt->physics_type]); 139d2567f34SHong Zhang } 140d2567f34SHong Zhang } 141d2567f34SHong Zhang ierr = VecRestoreArray(u,&uarr);CHKERRQ(ierr); 142d2567f34SHong Zhang PetscFunctionReturn(0); 143d2567f34SHong Zhang } 144d2567f34SHong Zhang 145d2567f34SHong Zhang static PetscErrorCode RHSJacobian(TS ts,PetscReal t,Vec U,Mat J,Mat Jpre,void *ctx) 146d2567f34SHong Zhang { 147d2567f34SHong Zhang UserContext *user = (UserContext*) ctx; 148d2567f34SHong Zhang PetscInt matis,matie,i; 149d2567f34SHong Zhang PetscReal dx,dx2; 150d2567f34SHong Zhang PetscErrorCode ierr; 151d2567f34SHong Zhang 152d2567f34SHong Zhang PetscFunctionBegin; 153d2567f34SHong Zhang dx = (user->xmax - user->xmin)/((PetscReal)user->imax); dx2 = dx*dx; 154d2567f34SHong Zhang ierr = MatGetOwnershipRange(J,&matis,&matie);CHKERRQ(ierr); 155d2567f34SHong Zhang for (i=matis; i<matie; i++) { 156d2567f34SHong Zhang PetscScalar values[3]; 157d2567f34SHong Zhang PetscInt col[3]; 158d2567f34SHong Zhang switch (user->physics_type) { 159d2567f34SHong Zhang case PHYSICS_DIFFUSION: 160d2567f34SHong Zhang values[0] = user->a*1.0/dx2; 161d2567f34SHong Zhang values[1] = -user->a*2.0/dx2; 162d2567f34SHong Zhang values[2] = user->a*1.0/dx2; 163d2567f34SHong Zhang break; 164d2567f34SHong Zhang case PHYSICS_ADVECTION: 165d2567f34SHong Zhang values[0] = user->a*.5/dx; 166d2567f34SHong Zhang values[1] = 0.; 167d2567f34SHong Zhang values[2] = -user->a*.5/dx; 168d2567f34SHong Zhang break; 16998921bdaSJacob Faibussowitsch default: SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"No support for physics type %s",PhysicsTypes[user->physics_type]); 170d2567f34SHong Zhang } 171d2567f34SHong Zhang /* periodic boundaries */ 172d2567f34SHong Zhang if (i == 0) { 173d2567f34SHong Zhang col[0] = user->imax-1; 174d2567f34SHong Zhang col[1] = i; 175d2567f34SHong Zhang col[2] = i+1; 176d2567f34SHong Zhang } else if (i == user->imax-1) { 177d2567f34SHong Zhang col[0] = i-1; 178d2567f34SHong Zhang col[1] = i; 179d2567f34SHong Zhang col[2] = 0; 180d2567f34SHong Zhang } else { 181d2567f34SHong Zhang col[0] = i-1; 182d2567f34SHong Zhang col[1] = i; 183d2567f34SHong Zhang col[2] = i+1; 184d2567f34SHong Zhang } 185d2567f34SHong Zhang ierr = MatSetValues(J,1,&i,3,col,values,INSERT_VALUES);CHKERRQ(ierr); 186d2567f34SHong Zhang } 187d2567f34SHong Zhang ierr = MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 188d2567f34SHong Zhang ierr = MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 189d2567f34SHong Zhang PetscFunctionReturn(0); 190d2567f34SHong Zhang } 191d2567f34SHong Zhang 192d2567f34SHong Zhang /*TEST 193d2567f34SHong Zhang 194d2567f34SHong Zhang test: 195d2567f34SHong Zhang requires: double 196d2567f34SHong Zhang suffix: 1 197d2567f34SHong Zhang nsize: {{1 2}} 198d2567f34SHong Zhang args: -ts_max_steps 5 -ts_monitor -ksp_monitor_short -pc_type pbjacobi -ksp_atol 1e-6 -ts_type irk -ts_irk_nstages 2 199d2567f34SHong Zhang 200d2567f34SHong Zhang test: 201d2567f34SHong Zhang requires: double 202d2567f34SHong Zhang suffix: 2 203d2567f34SHong Zhang args: -ts_max_steps 5 -ts_monitor -ksp_monitor_short -pc_type pbjacobi -ksp_atol 1e-6 -ts_type irk -ts_irk_nstages 3 204d2567f34SHong Zhang 205*2dd49c90SPierre Jolivet testset: 206*2dd49c90SPierre Jolivet requires: hpddm 207*2dd49c90SPierre Jolivet args: -ts_max_steps 5 -ts_monitor -ksp_monitor_short -pc_type pbjacobi -ksp_atol 1e-4 -ts_type irk -ts_irk_nstages 3 -ksp_view_final_residual -ksp_hpddm_type gcrodr -ksp_type hpddm -ksp_hpddm_precision {{single double}shared output} 208d2567f34SHong Zhang test: 209d2567f34SHong Zhang suffix: 3 210*2dd49c90SPierre Jolivet requires: double 211*2dd49c90SPierre Jolivet test: 212*2dd49c90SPierre Jolivet suffix: 3_single 213*2dd49c90SPierre Jolivet requires: single 214d2567f34SHong Zhang TEST*/ 215