Actual source code: ex7.c
1: /*$Id: ex7.c,v 1.2 2001/04/10 19:37:12 bsmith Exp $*/
3: /* Program usage: mpirun -np <procs> ex5 [-help] [all PETSc options] */
5: static char help[] = "Nonlinear, time-dependent PDE in 2d.n";
8: /*
9: Include "petscda.h" so that we can use distributed arrays (DAs).
10: Include "petscts.h" so that we can use SNES solvers. Note that this
11: file automatically includes:
12: petsc.h - base PETSc routines petscvec.h - vectors
13: petscsys.h - system routines petscmat.h - matrices
14: petscis.h - index sets petscksp.h - Krylov subspace methods
15: petscviewer.h - viewers petscpc.h - preconditioners
16: petscsles.h - linear solvers
17: */
18: #include "petscda.h"
19: #include "petscts.h"
22: /*
23: User-defined routines
24: */
25: extern int FormFunction(TS,double,Vec,Vec,void*),FormInitialSolution(DA,Vec);
27: int main(int argc,char **argv)
28: {
29: TS ts; /* nonlinear solver */
30: Vec x,r; /* solution, residual vectors */
31: Mat J; /* Jacobian matrix */
32: int steps; /* iterations for convergence */
33: int ierr;
34: DA da;
35: MatFDColoring matfdcoloring;
36: ISColoring iscoloring;
37: double ftime;
39: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
40: Initialize program
41: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
43: PetscInitialize(&argc,&argv,(char *)0,help);
46: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
47: Create distributed array (DA) to manage parallel grid and vectors
48: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
49: DACreate2d(PETSC_COMM_WORLD,DA_NONPERIODIC,DA_STENCIL_STAR,8,8,PETSC_DECIDE,PETSC_DECIDE,
50: 1,1,PETSC_NULL,PETSC_NULL,&da);
52: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
53: Extract global vectors from DA; then duplicate for remaining
54: vectors that are the same types
55: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
56: DACreateGlobalVector(da,&x);
57: VecDuplicate(x,&r);
59: TSCreate(PETSC_COMM_WORLD,TS_NONLINEAR,&ts);
60: TSSetRHSFunction(ts,FormFunction,da);
63: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
64: Create matrix data structure; set Jacobian evaluation routine
66: Set Jacobian matrix data structure and default Jacobian evaluation
67: routine. User can override with:
68: -snes_mf : matrix-free Newton-Krylov method with no preconditioning
69: (unless user explicitly sets preconditioner)
70: -snes_mf_operator : form preconditioning matrix as set by the user,
71: but use matrix-free approx for Jacobian-vector
72: products within Newton-Krylov method
74: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
75: DAGetColoring(da,IS_COLORING_GLOBAL,MATMPIAIJ,&iscoloring,&J);
76: MatFDColoringCreate(J,iscoloring,&matfdcoloring);
77: ISColoringDestroy(iscoloring);
78: MatFDColoringSetFunction(matfdcoloring,(int (*)(void))FormFunction,da);
79: MatFDColoringSetFromOptions(matfdcoloring);
81: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
82: Customize nonlinear solver; set runtime options
83: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
84: TSSetFromOptions(ts);
86: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
87: Set initial conditions
88: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
89: FormInitialSolution(da,x);
91: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
92: Solve nonlinear system
93: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
94: TSSetInitialTimeStep(ts,0.0,.0001);
95: TSSetSolution(ts,x);
96: TSSetType(ts,TS_BEULER);
97: TSSetDuration(ts,100,1.0);
98: TSStep(ts,&steps,&ftime);
101: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
102: Free work space. All PETSc objects should be destroyed when they
103: are no longer needed.
104: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
106: MatDestroy(J);
107: MatFDColoringDestroy(matfdcoloring);
108: VecDestroy(x);
109: VecDestroy(r);
110: TSDestroy(ts);
111: DADestroy(da);
112: PetscFinalize();
114: return(0);
115: }
116: /* ------------------------------------------------------------------- */
117: /*
118: FormFunction - Evaluates nonlinear function, F(x).
120: Input Parameters:
121: . ts - the TS context
122: . X - input vector
123: . ptr - optional user-defined context, as set by SNESSetFunction()
125: Output Parameter:
126: . F - function vector
127: */
128: int FormFunction(TS ts,double time,Vec X,Vec F,void *ptr)
129: {
130: DA da = (DA)ptr;
131: int ierr,i,j,Mx,My,xs,ys,xm,ym;
132: double two = 2.0,hx,hy,hxdhy,hydhx,sx,sy;
133: Scalar u,uxx,uyy,**x,**f;
134: Vec localX;
137: DAGetLocalVector(da,&localX);
138: DAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,
139: PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
141: hx = 1.0/(double)(Mx-1); sx = 1.0/(hx*hx);
142: hy = 1.0/(double)(My-1); sy = 1.0/(hy*hy);
143: hxdhy = hx/hy;
144: hydhx = hy/hx;
146: /*
147: Scatter ghost points to local vector,using the 2-step process
148: DAGlobalToLocalBegin(),DAGlobalToLocalEnd().
149: By placing code between these two statements, computations can be
150: done while messages are in transition.
151: */
152: DAGlobalToLocalBegin(da,X,INSERT_VALUES,localX);
153: DAGlobalToLocalEnd(da,X,INSERT_VALUES,localX);
155: /*
156: Get pointers to vector data
157: */
158: DAVecGetArray(da,localX,(void**)&x);
159: DAVecGetArray(da,F,(void**)&f);
161: /*
162: Get local grid boundaries
163: */
164: DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);
166: /*
167: Compute function over the locally owned part of the grid
168: */
169: for (j=ys; j<ys+ym; j++) {
170: for (i=xs; i<xs+xm; i++) {
171: if (i == 0 || j == 0 || i == Mx-1 || j == My-1) {
172: f[j][i] = x[j][i];
173: continue;
174: }
175: u = x[j][i];
176: uxx = (two*u - x[j][i-1] - x[j][i+1])*sx;
177: uyy = (two*u - x[j-1][i] - x[j+1][i])*sy;
178: /* f[j][i] = -(uxx + uyy); */
179: f[j][i] = u*(uxx + uyy) - (2.0 - 1.0)*((x[j][i+1] - x[j][i-1])*(x[j][i+1] - x[j][i-1])*.25*sx +
180: (x[j+1][i] - x[j-1][i])*(x[j+1][i] - x[j-1][i])*.25*sy);
181: }
182: }
184: /*
185: Restore vectors
186: */
187: DAVecRestoreArray(da,localX,(void**)&x);
188: DAVecRestoreArray(da,F,(void**)&f);
189: DARestoreLocalVector(da,&localX);
190: PetscLogFlops(11*ym*xm);
191: return(0);
192: }
194: /* ------------------------------------------------------------------- */
195: int FormInitialSolution(DA da,Vec U)
196: {
197: int ierr,i,j,xs,ys,xm,ym,Mx,My;
198: Scalar **u;
199: double hx,hy,x,y,r;
202: DAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,
203: PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
205: hx = 1.0/(double)(Mx-1);
206: hy = 1.0/(double)(My-1);
208: /*
209: Get pointers to vector data
210: */
211: DAVecGetArray(da,U,(void**)&u);
213: /*
214: Get local grid boundaries
215: */
216: DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);
218: /*
219: Compute function over the locally owned part of the grid
220: */
221: for (j=ys; j<ys+ym; j++) {
222: y = j*hy;
223: for (i=xs; i<xs+xm; i++) {
224: x = i*hx;
225: r = PetscSqrtScalar((x-.5)*(x-.5) + (y-.5)*(y-.5));
226: if (r < .125) {
227: u[j][i] = PetscExpScalar(-30.0*r*r*r);
228: } else {
229: u[j][i] = 0.0;
230: }
231: }
232: }
234: /*
235: Restore vectors
236: */
237: DAVecRestoreArray(da,U,(void**)&u);
238: return(0);
239: }