1c4762a1bSJed Brown /* 2c4762a1bSJed Brown The Problem: 3c4762a1bSJed Brown Solve the convection-diffusion equation: 4c4762a1bSJed Brown 5c4762a1bSJed Brown u_t+a*(u_x+u_y)=epsilon*(u_xx+u_yy) 6c4762a1bSJed Brown u=0 at x=0, y=0 7c4762a1bSJed Brown u_x=0 at x=1 8c4762a1bSJed Brown u_y=0 at y=1 9c4762a1bSJed Brown u = exp(-20.0*(pow(x-0.5,2.0)+pow(y-0.5,2.0))) at t=0 10c4762a1bSJed Brown 11c4762a1bSJed Brown This program tests the routine of computing the Jacobian by the 12c4762a1bSJed Brown finite difference method as well as PETSc. 13c4762a1bSJed Brown 14c4762a1bSJed Brown */ 15c4762a1bSJed Brown 16c4762a1bSJed Brown static char help[] = "Solve the convection-diffusion equation. \n\n"; 17c4762a1bSJed Brown 18c4762a1bSJed Brown #include <petscts.h> 19c4762a1bSJed Brown 20c4762a1bSJed Brown typedef struct 21c4762a1bSJed Brown { 22c4762a1bSJed Brown PetscInt m; /* the number of mesh points in x-direction */ 23c4762a1bSJed Brown PetscInt n; /* the number of mesh points in y-direction */ 24c4762a1bSJed Brown PetscReal dx; /* the grid space in x-direction */ 25c4762a1bSJed Brown PetscReal dy; /* the grid space in y-direction */ 26c4762a1bSJed Brown PetscReal a; /* the convection coefficient */ 27c4762a1bSJed Brown PetscReal epsilon; /* the diffusion coefficient */ 28c4762a1bSJed Brown PetscReal tfinal; 29c4762a1bSJed Brown } Data; 30c4762a1bSJed Brown 31c4762a1bSJed Brown extern PetscErrorCode Monitor(TS,PetscInt,PetscReal,Vec,void*); 32c4762a1bSJed Brown extern PetscErrorCode Initial(Vec,void*); 33c4762a1bSJed Brown extern PetscErrorCode RHSFunction(TS,PetscReal,Vec,Vec,void*); 34c4762a1bSJed Brown extern PetscErrorCode RHSJacobian(TS,PetscReal,Vec,Mat,Mat,void*); 35c4762a1bSJed Brown extern PetscErrorCode PostStep(TS); 36c4762a1bSJed Brown 37c4762a1bSJed Brown int main(int argc,char **argv) 38c4762a1bSJed Brown { 39c4762a1bSJed Brown PetscErrorCode ierr; 40c4762a1bSJed Brown PetscInt time_steps=100,iout,NOUT=1; 41c4762a1bSJed Brown Vec global; 42c4762a1bSJed Brown PetscReal dt,ftime,ftime_original; 43c4762a1bSJed Brown TS ts; 44c4762a1bSJed Brown PetscViewer viewfile; 45c4762a1bSJed Brown Mat J = 0; 46c4762a1bSJed Brown Vec x; 47c4762a1bSJed Brown Data data; 48c4762a1bSJed Brown PetscInt mn; 49c4762a1bSJed Brown PetscBool flg; 50c4762a1bSJed Brown MatColoring mc; 51c4762a1bSJed Brown ISColoring iscoloring; 52c4762a1bSJed Brown MatFDColoring matfdcoloring = 0; 53c4762a1bSJed Brown PetscBool fd_jacobian_coloring = PETSC_FALSE; 54c4762a1bSJed Brown SNES snes; 55c4762a1bSJed Brown KSP ksp; 56c4762a1bSJed Brown PC pc; 57c4762a1bSJed Brown 58c4762a1bSJed Brown ierr = PetscInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr; 59c4762a1bSJed Brown 60c4762a1bSJed Brown /* set data */ 61c4762a1bSJed Brown data.m = 9; 62c4762a1bSJed Brown data.n = 9; 63c4762a1bSJed Brown data.a = 1.0; 64c4762a1bSJed Brown data.epsilon = 0.1; 65c4762a1bSJed Brown data.dx = 1.0/(data.m+1.0); 66c4762a1bSJed Brown data.dy = 1.0/(data.n+1.0); 67c4762a1bSJed Brown mn = (data.m)*(data.n); 68*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-time",&time_steps,NULL)); 69c4762a1bSJed Brown 70c4762a1bSJed Brown /* set initial conditions */ 71*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreate(PETSC_COMM_WORLD,&global)); 72*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetSizes(global,PETSC_DECIDE,mn)); 73*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecSetFromOptions(global)); 74*5f80ce2aSJacob Faibussowitsch CHKERRQ(Initial(global,&data)); 75*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(global,&x)); 76c4762a1bSJed Brown 77c4762a1bSJed Brown /* create timestep context */ 78*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSCreate(PETSC_COMM_WORLD,&ts)); 79*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSMonitorSet(ts,Monitor,&data,NULL)); 80*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetType(ts,TSEULER)); 81c4762a1bSJed Brown dt = 0.1; 82c4762a1bSJed Brown ftime_original = data.tfinal = 1.0; 83c4762a1bSJed Brown 84*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetTimeStep(ts,dt)); 85*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetMaxSteps(ts,time_steps)); 86*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetMaxTime(ts,ftime_original)); 87*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER)); 88*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetSolution(ts,global)); 89c4762a1bSJed Brown 90c4762a1bSJed Brown /* set user provided RHSFunction and RHSJacobian */ 91*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetRHSFunction(ts,NULL,RHSFunction,&data)); 92*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatCreate(PETSC_COMM_WORLD,&J)); 93*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetSizes(J,PETSC_DECIDE,PETSC_DECIDE,mn,mn)); 94*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetFromOptions(J)); 95*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSeqAIJSetPreallocation(J,5,NULL)); 96*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatMPIAIJSetPreallocation(J,5,NULL,5,NULL)); 97c4762a1bSJed Brown 98*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsHasName(NULL,NULL,"-ts_fd",&flg)); 99c4762a1bSJed Brown if (!flg) { 100*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetRHSJacobian(ts,J,J,RHSJacobian,&data)); 101c4762a1bSJed Brown } else { 102*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetSNES(ts,&snes)); 103*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsHasName(NULL,NULL,"-fd_color",&fd_jacobian_coloring)); 104c4762a1bSJed Brown if (fd_jacobian_coloring) { /* Use finite differences with coloring */ 105c4762a1bSJed Brown /* Get data structure of J */ 106c4762a1bSJed Brown PetscBool pc_diagonal; 107*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsHasName(NULL,NULL,"-pc_diagonal",&pc_diagonal)); 108c4762a1bSJed Brown if (pc_diagonal) { /* the preconditioner of J is a diagonal matrix */ 109c4762a1bSJed Brown PetscInt rstart,rend,i; 110c4762a1bSJed Brown PetscScalar zero=0.0; 111*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatGetOwnershipRange(J,&rstart,&rend)); 112c4762a1bSJed Brown for (i=rstart; i<rend; i++) { 113*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(J,1,&i,1,&i,&zero,INSERT_VALUES)); 114c4762a1bSJed Brown } 115*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY)); 116*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY)); 117c4762a1bSJed Brown } else { 118c4762a1bSJed Brown /* Fill the structure using the expensive SNESComputeJacobianDefault. Temporarily set up the TS so we can call this function */ 119*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetType(ts,TSBEULER)); 120*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetUp(ts)); 121*5f80ce2aSJacob Faibussowitsch CHKERRQ(SNESComputeJacobianDefault(snes,x,J,J,ts)); 122c4762a1bSJed Brown } 123c4762a1bSJed Brown 124c4762a1bSJed Brown /* create coloring context */ 125*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatColoringCreate(J,&mc)); 126*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatColoringSetType(mc,MATCOLORINGSL)); 127*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatColoringSetFromOptions(mc)); 128*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatColoringApply(mc,&iscoloring)); 129*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatColoringDestroy(&mc)); 130*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatFDColoringCreate(J,iscoloring,&matfdcoloring)); 131*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))SNESTSFormFunction,ts)); 132*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatFDColoringSetFromOptions(matfdcoloring)); 133*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatFDColoringSetUp(J,iscoloring,matfdcoloring)); 134*5f80ce2aSJacob Faibussowitsch CHKERRQ(SNESSetJacobian(snes,J,J,SNESComputeJacobianDefaultColor,matfdcoloring)); 135*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISColoringDestroy(&iscoloring)); 136c4762a1bSJed Brown } else { /* Use finite differences (slow) */ 137*5f80ce2aSJacob Faibussowitsch CHKERRQ(SNESSetJacobian(snes,J,J,SNESComputeJacobianDefault,NULL)); 138c4762a1bSJed Brown } 139c4762a1bSJed Brown } 140c4762a1bSJed Brown 141c4762a1bSJed Brown /* Pick up a Petsc preconditioner */ 142c4762a1bSJed Brown /* one can always set method or preconditioner during the run time */ 143*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetSNES(ts,&snes)); 144*5f80ce2aSJacob Faibussowitsch CHKERRQ(SNESGetKSP(snes,&ksp)); 145*5f80ce2aSJacob Faibussowitsch CHKERRQ(KSPGetPC(ksp,&pc)); 146*5f80ce2aSJacob Faibussowitsch CHKERRQ(PCSetType(pc,PCJACOBI)); 147*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER)); 148c4762a1bSJed Brown 149*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetFromOptions(ts)); 150*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetUp(ts)); 151c4762a1bSJed Brown 152c4762a1bSJed Brown /* Test TSSetPostStep() */ 153*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsHasName(NULL,NULL,"-test_PostStep",&flg)); 154c4762a1bSJed Brown if (flg) { 155*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetPostStep(ts,PostStep)); 156c4762a1bSJed Brown } 157c4762a1bSJed Brown 158*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsGetInt(NULL,NULL,"-NOUT",&NOUT,NULL)); 159c4762a1bSJed Brown for (iout=1; iout<=NOUT; iout++) { 160*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetMaxSteps(ts,time_steps)); 161*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetMaxTime(ts,iout*ftime_original/NOUT)); 162*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSolve(ts,global)); 163*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetSolveTime(ts,&ftime)); 164*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetTime(ts,ftime)); 165*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSSetTimeStep(ts,dt)); 166c4762a1bSJed Brown } 167c4762a1bSJed Brown /* Interpolate solution at tfinal */ 168*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetSolution(ts,&global)); 169*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSInterpolate(ts,ftime_original,global)); 170c4762a1bSJed Brown 171*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsHasName(NULL,NULL,"-matlab_view",&flg)); 172c4762a1bSJed Brown if (flg) { /* print solution into a MATLAB file */ 173*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIOpen(PETSC_COMM_WORLD,"out.m",&viewfile)); 174*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerPushFormat(viewfile,PETSC_VIEWER_ASCII_MATLAB)); 175*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecView(global,viewfile)); 176*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerPopFormat(viewfile)); 177*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerDestroy(&viewfile)); 178c4762a1bSJed Brown } 179c4762a1bSJed Brown 180c4762a1bSJed Brown /* free the memories */ 181*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSDestroy(&ts)); 182*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&global)); 183*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&x)); 184*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&J)); 185*5f80ce2aSJacob Faibussowitsch if (fd_jacobian_coloring) CHKERRQ(MatFDColoringDestroy(&matfdcoloring)); 186c4762a1bSJed Brown ierr = PetscFinalize(); 187c4762a1bSJed Brown return ierr; 188c4762a1bSJed Brown } 189c4762a1bSJed Brown 190c4762a1bSJed Brown /* -------------------------------------------------------------------*/ 191c4762a1bSJed Brown /* the initial function */ 192c4762a1bSJed Brown PetscReal f_ini(PetscReal x,PetscReal y) 193c4762a1bSJed Brown { 194c4762a1bSJed Brown PetscReal f; 195c4762a1bSJed Brown 196c4762a1bSJed Brown f=PetscExpReal(-20.0*(PetscPowRealInt(x-0.5,2)+PetscPowRealInt(y-0.5,2))); 197c4762a1bSJed Brown return f; 198c4762a1bSJed Brown } 199c4762a1bSJed Brown 200c4762a1bSJed Brown PetscErrorCode Initial(Vec global,void *ctx) 201c4762a1bSJed Brown { 202c4762a1bSJed Brown Data *data = (Data*)ctx; 203c4762a1bSJed Brown PetscInt m,row,col; 204c4762a1bSJed Brown PetscReal x,y,dx,dy; 205c4762a1bSJed Brown PetscScalar *localptr; 206c4762a1bSJed Brown PetscInt i,mybase,myend,locsize; 207c4762a1bSJed Brown 208c4762a1bSJed Brown PetscFunctionBeginUser; 209c4762a1bSJed Brown /* make the local copies of parameters */ 210c4762a1bSJed Brown m = data->m; 211c4762a1bSJed Brown dx = data->dx; 212c4762a1bSJed Brown dy = data->dy; 213c4762a1bSJed Brown 214c4762a1bSJed Brown /* determine starting point of each processor */ 215*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetOwnershipRange(global,&mybase,&myend)); 216*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetLocalSize(global,&locsize)); 217c4762a1bSJed Brown 218c4762a1bSJed Brown /* Initialize the array */ 219*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayWrite(global,&localptr)); 220c4762a1bSJed Brown 221c4762a1bSJed Brown for (i=0; i<locsize; i++) { 222c4762a1bSJed Brown row = 1+(mybase+i)-((mybase+i)/m)*m; 223c4762a1bSJed Brown col = (mybase+i)/m+1; 224c4762a1bSJed Brown x = dx*row; 225c4762a1bSJed Brown y = dy*col; 226c4762a1bSJed Brown localptr[i] = f_ini(x,y); 227c4762a1bSJed Brown } 228c4762a1bSJed Brown 229*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayWrite(global,&localptr)); 230c4762a1bSJed Brown PetscFunctionReturn(0); 231c4762a1bSJed Brown } 232c4762a1bSJed Brown 233c4762a1bSJed Brown PetscErrorCode Monitor(TS ts,PetscInt step,PetscReal time,Vec global,void *ctx) 234c4762a1bSJed Brown { 235c4762a1bSJed Brown VecScatter scatter; 236c4762a1bSJed Brown IS from,to; 237c4762a1bSJed Brown PetscInt i,n,*idx,nsteps,maxsteps; 238c4762a1bSJed Brown Vec tmp_vec; 239c4762a1bSJed Brown const PetscScalar *tmp; 240c4762a1bSJed Brown 241c4762a1bSJed Brown PetscFunctionBeginUser; 242*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetStepNumber(ts,&nsteps)); 243c4762a1bSJed Brown /* display output at selected time steps */ 244*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetMaxSteps(ts, &maxsteps)); 245c4762a1bSJed Brown if (nsteps % 10 != 0) PetscFunctionReturn(0); 246c4762a1bSJed Brown 247c4762a1bSJed Brown /* Get the size of the vector */ 248*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetSize(global,&n)); 249c4762a1bSJed Brown 250c4762a1bSJed Brown /* Set the index sets */ 251*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(n,&idx)); 252c4762a1bSJed Brown for (i=0; i<n; i++) idx[i]=i; 253c4762a1bSJed Brown 254c4762a1bSJed Brown /* Create local sequential vectors */ 255*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreateSeq(PETSC_COMM_SELF,n,&tmp_vec)); 256c4762a1bSJed Brown 257c4762a1bSJed Brown /* Create scatter context */ 258*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateGeneral(PETSC_COMM_SELF,n,idx,PETSC_COPY_VALUES,&from)); 259*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateGeneral(PETSC_COMM_SELF,n,idx,PETSC_COPY_VALUES,&to)); 260*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterCreate(global,from,tmp_vec,to,&scatter)); 261*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(scatter,global,tmp_vec,INSERT_VALUES,SCATTER_FORWARD)); 262*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd(scatter,global,tmp_vec,INSERT_VALUES,SCATTER_FORWARD)); 263c4762a1bSJed Brown 264*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(tmp_vec,&tmp)); 265*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_WORLD,"At t[%D] =%14.2e u= %14.2e at the center \n",nsteps,(double)time,(double)PetscRealPart(tmp[n/2]))); 266*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(tmp_vec,&tmp)); 267c4762a1bSJed Brown 268*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(idx)); 269*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&from)); 270*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&to)); 271*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterDestroy(&scatter)); 272*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&tmp_vec)); 273c4762a1bSJed Brown PetscFunctionReturn(0); 274c4762a1bSJed Brown } 275c4762a1bSJed Brown 276c4762a1bSJed Brown PetscErrorCode RHSJacobian(TS ts,PetscReal t,Vec x,Mat A,Mat BB,void *ptr) 277c4762a1bSJed Brown { 278c4762a1bSJed Brown Data *data = (Data*)ptr; 279c4762a1bSJed Brown PetscScalar v[5]; 280c4762a1bSJed Brown PetscInt idx[5],i,j,row; 281c4762a1bSJed Brown PetscInt m,n,mn; 282c4762a1bSJed Brown PetscReal dx,dy,a,epsilon,xc,xl,xr,yl,yr; 283c4762a1bSJed Brown 284c4762a1bSJed Brown PetscFunctionBeginUser; 285c4762a1bSJed Brown m = data->m; 286c4762a1bSJed Brown n = data->n; 287c4762a1bSJed Brown mn = m*n; 288c4762a1bSJed Brown dx = data->dx; 289c4762a1bSJed Brown dy = data->dy; 290c4762a1bSJed Brown a = data->a; 291c4762a1bSJed Brown epsilon = data->epsilon; 292c4762a1bSJed Brown 293c4762a1bSJed Brown xc = -2.0*epsilon*(1.0/(dx*dx)+1.0/(dy*dy)); 294c4762a1bSJed Brown xl = 0.5*a/dx+epsilon/(dx*dx); 295c4762a1bSJed Brown xr = -0.5*a/dx+epsilon/(dx*dx); 296c4762a1bSJed Brown yl = 0.5*a/dy+epsilon/(dy*dy); 297c4762a1bSJed Brown yr = -0.5*a/dy+epsilon/(dy*dy); 298c4762a1bSJed Brown 299c4762a1bSJed Brown row = 0; 300c4762a1bSJed Brown v[0] = xc; v[1] = xr; v[2] = yr; 301c4762a1bSJed Brown idx[0] = 0; idx[1] = 2; idx[2] = m; 302*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(A,1,&row,3,idx,v,INSERT_VALUES)); 303c4762a1bSJed Brown 304c4762a1bSJed Brown row = m-1; 305c4762a1bSJed Brown v[0] = 2.0*xl; v[1] = xc; v[2] = yr; 306c4762a1bSJed Brown idx[0] = m-2; idx[1] = m-1; idx[2] = m-1+m; 307*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(A,1,&row,3,idx,v,INSERT_VALUES)); 308c4762a1bSJed Brown 309c4762a1bSJed Brown for (i=1; i<m-1; i++) { 310c4762a1bSJed Brown row = i; 311c4762a1bSJed Brown v[0] = xl; v[1] = xc; v[2] = xr; v[3] = yr; 312c4762a1bSJed Brown idx[0] = i-1; idx[1] = i; idx[2] = i+1; idx[3] = i+m; 313*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(A,1,&row,4,idx,v,INSERT_VALUES)); 314c4762a1bSJed Brown } 315c4762a1bSJed Brown 316c4762a1bSJed Brown for (j=1; j<n-1; j++) { 317c4762a1bSJed Brown row = j*m; 318c4762a1bSJed Brown v[0] = xc; v[1] = xr; v[2] = yl; v[3] = yr; 319c4762a1bSJed Brown idx[0] = j*m; idx[1] = j*m; idx[2] = j*m-m; idx[3] = j*m+m; 320*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(A,1,&row,4,idx,v,INSERT_VALUES)); 321c4762a1bSJed Brown 322c4762a1bSJed Brown row = j*m+m-1; 323c4762a1bSJed Brown v[0] = xc; v[1] = 2.0*xl; v[2] = yl; v[3] = yr; 324c4762a1bSJed Brown idx[0] = j*m+m-1; idx[1] = j*m+m-1-1; idx[2] = j*m+m-1-m; idx[3] = j*m+m-1+m; 325*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(A,1,&row,4,idx,v,INSERT_VALUES)); 326c4762a1bSJed Brown 327c4762a1bSJed Brown for (i=1; i<m-1; i++) { 328c4762a1bSJed Brown row = j*m+i; 329c4762a1bSJed Brown v[0] = xc; v[1] = xl; v[2] = xr; v[3] = yl; v[4]=yr; 330c4762a1bSJed Brown idx[0] = j*m+i; idx[1] = j*m+i-1; idx[2] = j*m+i+1; idx[3] = j*m+i-m; 331c4762a1bSJed Brown idx[4] = j*m+i+m; 332*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(A,1,&row,5,idx,v,INSERT_VALUES)); 333c4762a1bSJed Brown } 334c4762a1bSJed Brown } 335c4762a1bSJed Brown 336c4762a1bSJed Brown row = mn-m; 337c4762a1bSJed Brown v[0] = xc; v[1] = xr; v[2] = 2.0*yl; 338c4762a1bSJed Brown idx[0] = mn-m; idx[1] = mn-m+1; idx[2] = mn-m-m; 339*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(A,1,&row,3,idx,v,INSERT_VALUES)); 340c4762a1bSJed Brown 341c4762a1bSJed Brown row = mn-1; 342c4762a1bSJed Brown v[0] = xc; v[1] = 2.0*xl; v[2] = 2.0*yl; 343c4762a1bSJed Brown idx[0] = mn-1; idx[1] = mn-2; idx[2] = mn-1-m; 344*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(A,1,&i,3,idx,v,INSERT_VALUES)); 345c4762a1bSJed Brown 346c4762a1bSJed Brown for (i=1; i<m-1; i++) { 347c4762a1bSJed Brown row = mn-m+i; 348c4762a1bSJed Brown v[0] = xl; v[1] = xc; v[2] = xr; v[3] = 2.0*yl; 349c4762a1bSJed Brown idx[0] = mn-m+i-1; idx[1] = mn-m+i; idx[2] = mn-m+i+1; idx[3] = mn-m+i-m; 350*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatSetValues(A,1,&row,4,idx,v,INSERT_VALUES)); 351c4762a1bSJed Brown } 352c4762a1bSJed Brown 353*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 354*5f80ce2aSJacob Faibussowitsch CHKERRQ(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 355c4762a1bSJed Brown 356c4762a1bSJed Brown PetscFunctionReturn(0); 357c4762a1bSJed Brown } 358c4762a1bSJed Brown 359c4762a1bSJed Brown /* globalout = -a*(u_x+u_y) + epsilon*(u_xx+u_yy) */ 360c4762a1bSJed Brown PetscErrorCode RHSFunction(TS ts,PetscReal t,Vec globalin,Vec globalout,void *ctx) 361c4762a1bSJed Brown { 362c4762a1bSJed Brown Data *data = (Data*)ctx; 363c4762a1bSJed Brown PetscInt m,n,mn; 364c4762a1bSJed Brown PetscReal dx,dy; 365c4762a1bSJed Brown PetscReal xc,xl,xr,yl,yr; 366c4762a1bSJed Brown PetscReal a,epsilon; 367c4762a1bSJed Brown PetscScalar *outptr; 368c4762a1bSJed Brown const PetscScalar *inptr; 369c4762a1bSJed Brown PetscInt i,j,len; 370c4762a1bSJed Brown IS from,to; 371c4762a1bSJed Brown PetscInt *idx; 372c4762a1bSJed Brown VecScatter scatter; 373c4762a1bSJed Brown Vec tmp_in,tmp_out; 374c4762a1bSJed Brown 375c4762a1bSJed Brown PetscFunctionBeginUser; 376c4762a1bSJed Brown m = data->m; 377c4762a1bSJed Brown n = data->n; 378c4762a1bSJed Brown mn = m*n; 379c4762a1bSJed Brown dx = data->dx; 380c4762a1bSJed Brown dy = data->dy; 381c4762a1bSJed Brown a = data->a; 382c4762a1bSJed Brown epsilon = data->epsilon; 383c4762a1bSJed Brown 384c4762a1bSJed Brown xc = -2.0*epsilon*(1.0/(dx*dx)+1.0/(dy*dy)); 385c4762a1bSJed Brown xl = 0.5*a/dx+epsilon/(dx*dx); 386c4762a1bSJed Brown xr = -0.5*a/dx+epsilon/(dx*dx); 387c4762a1bSJed Brown yl = 0.5*a/dy+epsilon/(dy*dy); 388c4762a1bSJed Brown yr = -0.5*a/dy+epsilon/(dy*dy); 389c4762a1bSJed Brown 390c4762a1bSJed Brown /* Get the length of parallel vector */ 391*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetSize(globalin,&len)); 392c4762a1bSJed Brown 393c4762a1bSJed Brown /* Set the index sets */ 394*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscMalloc1(len,&idx)); 395c4762a1bSJed Brown for (i=0; i<len; i++) idx[i]=i; 396c4762a1bSJed Brown 397c4762a1bSJed Brown /* Create local sequential vectors */ 398*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecCreateSeq(PETSC_COMM_SELF,len,&tmp_in)); 399*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDuplicate(tmp_in,&tmp_out)); 400c4762a1bSJed Brown 401c4762a1bSJed Brown /* Create scatter context */ 402*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateGeneral(PETSC_COMM_SELF,len,idx,PETSC_COPY_VALUES,&from)); 403*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISCreateGeneral(PETSC_COMM_SELF,len,idx,PETSC_COPY_VALUES,&to)); 404*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterCreate(globalin,from,tmp_in,to,&scatter)); 405*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(scatter,globalin,tmp_in,INSERT_VALUES,SCATTER_FORWARD)); 406*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd(scatter,globalin,tmp_in,INSERT_VALUES,SCATTER_FORWARD)); 407*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterDestroy(&scatter)); 408c4762a1bSJed Brown 409c4762a1bSJed Brown /*Extract income array - include ghost points */ 410*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayRead(tmp_in,&inptr)); 411c4762a1bSJed Brown 412c4762a1bSJed Brown /* Extract outcome array*/ 413*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecGetArrayWrite(tmp_out,&outptr)); 414c4762a1bSJed Brown 415c4762a1bSJed Brown outptr[0] = xc*inptr[0]+xr*inptr[1]+yr*inptr[m]; 416c4762a1bSJed Brown outptr[m-1] = 2.0*xl*inptr[m-2]+xc*inptr[m-1]+yr*inptr[m-1+m]; 417c4762a1bSJed Brown for (i=1; i<m-1; i++) { 418c4762a1bSJed Brown outptr[i] = xc*inptr[i]+xl*inptr[i-1]+xr*inptr[i+1]+yr*inptr[i+m]; 419c4762a1bSJed Brown } 420c4762a1bSJed Brown 421c4762a1bSJed Brown for (j=1; j<n-1; j++) { 422c4762a1bSJed Brown outptr[j*m] = xc*inptr[j*m]+xr*inptr[j*m+1]+ yl*inptr[j*m-m]+yr*inptr[j*m+m]; 423c4762a1bSJed Brown outptr[j*m+m-1] = xc*inptr[j*m+m-1]+2.0*xl*inptr[j*m+m-1-1]+ yl*inptr[j*m+m-1-m]+yr*inptr[j*m+m-1+m]; 424c4762a1bSJed Brown for (i=1; i<m-1; i++) { 425c4762a1bSJed Brown outptr[j*m+i] = xc*inptr[j*m+i]+xl*inptr[j*m+i-1]+xr*inptr[j*m+i+1]+yl*inptr[j*m+i-m]+yr*inptr[j*m+i+m]; 426c4762a1bSJed Brown } 427c4762a1bSJed Brown } 428c4762a1bSJed Brown 429c4762a1bSJed Brown outptr[mn-m] = xc*inptr[mn-m]+xr*inptr[mn-m+1]+2.0*yl*inptr[mn-m-m]; 430c4762a1bSJed Brown outptr[mn-1] = 2.0*xl*inptr[mn-2]+xc*inptr[mn-1]+2.0*yl*inptr[mn-1-m]; 431c4762a1bSJed Brown for (i=1; i<m-1; i++) { 432c4762a1bSJed Brown outptr[mn-m+i] = xc*inptr[mn-m+i]+xl*inptr[mn-m+i-1]+xr*inptr[mn-m+i+1]+2*yl*inptr[mn-m+i-m]; 433c4762a1bSJed Brown } 434c4762a1bSJed Brown 435*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayRead(tmp_in,&inptr)); 436*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecRestoreArrayWrite(tmp_out,&outptr)); 437c4762a1bSJed Brown 438*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterCreate(tmp_out,from,globalout,to,&scatter)); 439*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterBegin(scatter,tmp_out,globalout,INSERT_VALUES,SCATTER_FORWARD)); 440*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterEnd(scatter,tmp_out,globalout,INSERT_VALUES,SCATTER_FORWARD)); 441c4762a1bSJed Brown 442c4762a1bSJed Brown /* Destroy idx aand scatter */ 443*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&tmp_in)); 444*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&tmp_out)); 445*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&from)); 446*5f80ce2aSJacob Faibussowitsch CHKERRQ(ISDestroy(&to)); 447*5f80ce2aSJacob Faibussowitsch CHKERRQ(VecScatterDestroy(&scatter)); 448c4762a1bSJed Brown 449*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(idx)); 450c4762a1bSJed Brown PetscFunctionReturn(0); 451c4762a1bSJed Brown } 452c4762a1bSJed Brown 453c4762a1bSJed Brown PetscErrorCode PostStep(TS ts) 454c4762a1bSJed Brown { 455c4762a1bSJed Brown PetscReal t; 456c4762a1bSJed Brown 457c4762a1bSJed Brown PetscFunctionBeginUser; 458*5f80ce2aSJacob Faibussowitsch CHKERRQ(TSGetTime(ts,&t)); 459*5f80ce2aSJacob Faibussowitsch CHKERRQ(PetscPrintf(PETSC_COMM_SELF," PostStep, t: %g\n",(double)t)); 460c4762a1bSJed Brown PetscFunctionReturn(0); 461c4762a1bSJed Brown } 462c4762a1bSJed Brown 463c4762a1bSJed Brown /*TEST 464c4762a1bSJed Brown 465c4762a1bSJed Brown test: 466c4762a1bSJed Brown args: -ts_fd -ts_type beuler 467c4762a1bSJed Brown output_file: output/ex4.out 468c4762a1bSJed Brown 469c4762a1bSJed Brown test: 470c4762a1bSJed Brown suffix: 2 471c4762a1bSJed Brown args: -ts_fd -ts_type beuler 472c4762a1bSJed Brown nsize: 2 473c4762a1bSJed Brown output_file: output/ex4.out 474c4762a1bSJed Brown 475c4762a1bSJed Brown test: 476c4762a1bSJed Brown suffix: 3 477c4762a1bSJed Brown args: -ts_fd -ts_type cn 478c4762a1bSJed Brown 479c4762a1bSJed Brown test: 480c4762a1bSJed Brown suffix: 4 481c4762a1bSJed Brown args: -ts_fd -ts_type cn 482c4762a1bSJed Brown output_file: output/ex4_3.out 483c4762a1bSJed Brown nsize: 2 484c4762a1bSJed Brown 485c4762a1bSJed Brown test: 486c4762a1bSJed Brown suffix: 5 487c4762a1bSJed Brown args: -ts_type beuler -ts_fd -fd_color -mat_coloring_type sl 488c4762a1bSJed Brown output_file: output/ex4.out 489c4762a1bSJed Brown 490c4762a1bSJed Brown test: 491c4762a1bSJed Brown suffix: 6 492c4762a1bSJed Brown args: -ts_type beuler -ts_fd -fd_color -mat_coloring_type sl 493c4762a1bSJed Brown output_file: output/ex4.out 494c4762a1bSJed Brown nsize: 2 495c4762a1bSJed Brown 496c4762a1bSJed Brown test: 497c4762a1bSJed Brown suffix: 7 498c4762a1bSJed Brown requires: !single 499c4762a1bSJed Brown args: -ts_fd -ts_type beuler -test_PostStep -ts_dt .1 500c4762a1bSJed Brown 501c4762a1bSJed Brown test: 502c4762a1bSJed Brown suffix: 8 503c4762a1bSJed Brown requires: !single 504c4762a1bSJed Brown args: -ts_type rk -ts_rk_type 5dp -ts_dt .01 -ts_adapt_type none -ts_view 505c4762a1bSJed Brown 506c4762a1bSJed Brown TEST*/ 507