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: }