Actual source code: ex25.c

  2: /*$Id: ex22.c,v 1.19 2001/08/07 21:30:54 bsmith Exp $*/
  3: /*
  4:  Partial differential equation

  6:    d  (1 + e*sine(2*pi*k*x)) d u = 1, 0 < x < 1,
  7:    --                        ---
  8:    dx                        dx
  9: with boundary conditions

 11:    u = 0 for x = 0, x = 1

 13:    This uses multigrid to solve the linear system

 15: */

 17: static char help[] = "Solves 1D variable coefficient Laplacian using multigrid.nn";

 19:  #include petscda.h
 20:  #include petscsles.h

 22: extern int ComputeJacobian(DMMG,Mat);
 23: extern int ComputeRHS(DMMG,Vec);

 25: typedef struct {
 26:   int         k;
 27:   PetscScalar e;
 28: } AppCtx;

 30: int main(int argc,char **argv)
 31: {
 32:   int         ierr;
 33:   DMMG        *dmmg;
 34:   PetscScalar mone = -1.0;
 35:   PetscReal   norm;
 36:   DA          da;
 37:   AppCtx      user;

 39:   PetscInitialize(&argc,&argv,(char *)0,help);

 41:   user.k = 1;
 42:   user.e = .99;
 43:   PetscOptionsGetInt(0,"-k",&user.k,0);
 44:   PetscOptionsGetScalar(0,"-e",&user.e,0);

 46:   DMMGCreate(PETSC_COMM_WORLD,3,&user,&dmmg);
 47:   DACreate1d(PETSC_COMM_WORLD,DA_NONPERIODIC,-3,1,1,0,&da);
 48:   DMMGSetDM(dmmg,(DM)da);
 49:   DADestroy(da);

 51:   DMMGSetSLES(dmmg,ComputeRHS,ComputeJacobian);

 53:   DMMGSolve(dmmg);

 55:   MatMult(DMMGGetJ(dmmg),DMMGGetx(dmmg),DMMGGetr(dmmg));
 56:   VecAXPY(&mone,DMMGGetb(dmmg),DMMGGetr(dmmg));
 57:   VecNorm(DMMGGetr(dmmg),NORM_2,&norm);
 58:   /* PetscPrintf(PETSC_COMM_WORLD,"Residual norm %gn",norm); */

 60:   DMMGDestroy(dmmg);
 61:   PetscFinalize();

 63:   return 0;
 64: }

 66: int ComputeRHS(DMMG dmmg,Vec b)
 67: {
 68:   int         ierr,mx,idx[2];
 69:   PetscScalar h,v[2];

 72:   ierr   = DAGetInfo((DA)dmmg->dm,0,&mx,0,0,0,0,0,0,0,0,0);
 73:   h      = 1.0/((mx-1));
 74:   ierr   = VecSet(&h,b);
 75:   idx[0] = 0; idx[1] = mx -1;
 76:   v[0]   = v[1] = 0.0;
 77:   ierr   = VecSetValues(b,2,idx,v,INSERT_VALUES);
 78:   ierr   = VecAssemblyBegin(b);
 79:   ierr   = VecAssemblyEnd(b);
 80:   return(0);
 81: }
 82: 
 83: int ComputeJacobian(DMMG dmmg,Mat jac)
 84: {
 85:   DA           da = (DA)dmmg->dm;
 86:   int          ierr,i,mx,xm,xs;
 87:   PetscScalar  v[3],h,xlow,xhigh;
 88:   MatStencil   row,col[3];
 89:   AppCtx       *user = (AppCtx*)dmmg->user;

 91:   DAGetInfo(da,0,&mx,0,0,0,0,0,0,0,0,0);
 92:   DAGetCorners(da,&xs,0,0,&xm,0,0);
 93:   h    = 1.0/(mx-1);

 95:   for(i=xs; i<xs+xm; i++){
 96:     row.i = i;
 97:     if (i==0 || i==mx-1){
 98:       v[0] = 2.0;
 99:       MatSetValuesStencil(jac,1,&row,1,&row,v,INSERT_VALUES);
100:     } else {
101:        xlow  = h*(PetscReal)i - .5*h;
102:        xhigh = xlow + h;
103:        v[0] = (-1.0 - user->e*PetscSinScalar(2.0*PETSC_PI*user->k*xlow))/h;col[0].i = i-1;
104:        v[1] = (2.0 + user->e*PetscSinScalar(2.0*PETSC_PI*user->k*xlow) + user->e*PetscSinScalar(2.0*PETSC_PI*user->k*xhigh))/h;col[1].i = row.i;
105:        v[2] = (-1.0 - user->e*PetscSinScalar(2.0*PETSC_PI*user->k*xhigh))/h;col[2].i = i+1;
106:       MatSetValuesStencil(jac,1,&row,3,col,v,INSERT_VALUES);
107:     }
108:   }
109:   MatAssemblyBegin(jac,MAT_FINAL_ASSEMBLY);
110:   MatAssemblyEnd(jac,MAT_FINAL_ASSEMBLY);
111:   return 0;
112: }