Actual source code: ex7.c
1: /*$Id: ex7.c,v 1.7 2001/08/21 21:04:28 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,PetscReal,Vec,Vec,void*),FormInitialSolution(DA,Vec);
26: extern int Monitor(TS,int,PetscReal,Vec,void*);
28: int main(int argc,char **argv)
29: {
30: TS ts; /* nonlinear solver */
31: Vec x,r; /* solution, residual vectors */
32: Mat J; /* Jacobian matrix */
33: int steps; /* iterations for convergence */
34: int ierr;
35: DA da;
36: MatFDColoring matfdcoloring;
37: ISColoring iscoloring;
38: PetscReal ftime;
40: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
41: Initialize program
42: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
44: PetscInitialize(&argc,&argv,(char *)0,help);
47: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
48: Create distributed array (DA) to manage parallel grid and vectors
49: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
50: DACreate2d(PETSC_COMM_WORLD,DA_NONPERIODIC,DA_STENCIL_STAR,8,8,PETSC_DECIDE,PETSC_DECIDE,
51: 1,1,PETSC_NULL,PETSC_NULL,&da);
53: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
54: Extract global vectors from DA; then duplicate for remaining
55: vectors that are the same types
56: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
57: DACreateGlobalVector(da,&x);
58: VecDuplicate(x,&r);
60: TSCreate(PETSC_COMM_WORLD,&ts);
61: TSSetProblemType(ts,TS_NONLINEAR);
62: TSSetRHSFunction(ts,FormFunction,da);
65: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
66: Create matrix data structure; set Jacobian evaluation routine
68: Set Jacobian matrix data structure and default Jacobian evaluation
69: routine. User can override with:
70: -snes_mf : matrix-free Newton-Krylov method with no preconditioning
71: (unless user explicitly sets preconditioner)
72: -snes_mf_operator : form preconditioning matrix as set by the user,
73: but use matrix-free approx for Jacobian-vector
74: products within Newton-Krylov method
76: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
77: DAGetColoring(da,IS_COLORING_LOCAL,&iscoloring);
78: DAGetMatrix(da,MATMPIAIJ,&J);
79: MatFDColoringCreate(J,iscoloring,&matfdcoloring);
80: ISColoringDestroy(iscoloring);
81: MatFDColoringSetFunction(matfdcoloring,(int (*)(void))FormFunction,da);
82: MatFDColoringSetFromOptions(matfdcoloring);
83: TSSetRHSJacobian(ts,J,J,TSDefaultComputeJacobianColor,matfdcoloring);
84: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
85: Customize nonlinear solver; set runtime options
86: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
87: TSSetInitialTimeStep(ts,0.0,.0001);
88: TSSetType(ts,TS_BEULER);
89: TSSetDuration(ts,100,1.0);
90: TSSetFromOptions(ts);
91: TSSetMonitor(ts,Monitor,0,0);
93: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
94: Set initial conditions
95: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
96: FormInitialSolution(da,x);
98: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
99: Solve nonlinear system
100: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
101: TSSetSolution(ts,x);
102: TSStep(ts,&steps,&ftime);
105: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
106: Free work space. All PETSc objects should be destroyed when they
107: are no longer needed.
108: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
110: MatDestroy(J);
111: MatFDColoringDestroy(matfdcoloring);
112: VecDestroy(x);
113: VecDestroy(r);
114: TSDestroy(ts);
115: DADestroy(da);
116: PetscFinalize();
118: return(0);
119: }
120: /* ------------------------------------------------------------------- */
121: /*
122: FormFunction - Evaluates nonlinear function, F(x).
124: Input Parameters:
125: . ts - the TS context
126: . X - input vector
127: . ptr - optional user-defined context, as set by SNESSetFunction()
129: Output Parameter:
130: . F - function vector
131: */
132: int FormFunction(TS ts,PetscReal time,Vec X,Vec F,void *ptr)
133: {
134: DA da = (DA)ptr;
135: int ierr,i,j,Mx,My,xs,ys,xm,ym;
136: PetscReal two = 2.0,hx,hy,hxdhy,hydhx,sx,sy;
137: PetscScalar u,uxx,uyy,**x,**f;
138: Vec localX;
141: DAGetLocalVector(da,&localX);
142: DAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,
143: PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
145: hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx);
146: hy = 1.0/(PetscReal)(My-1); sy = 1.0/(hy*hy);
147: hxdhy = hx/hy;
148: hydhx = hy/hx;
150: /*
151: Scatter ghost points to local vector,using the 2-step process
152: DAGlobalToLocalBegin(),DAGlobalToLocalEnd().
153: By placing code between these two statements, computations can be
154: done while messages are in transition.
155: */
156: DAGlobalToLocalBegin(da,X,INSERT_VALUES,localX);
157: DAGlobalToLocalEnd(da,X,INSERT_VALUES,localX);
159: /*
160: Get pointers to vector data
161: */
162: DAVecGetArray(da,localX,(void**)&x);
163: DAVecGetArray(da,F,(void**)&f);
165: /*
166: Get local grid boundaries
167: */
168: DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);
170: /*
171: Compute function over the locally owned part of the grid
172: */
173: for (j=ys; j<ys+ym; j++) {
174: for (i=xs; i<xs+xm; i++) {
175: if (i == 0 || j == 0 || i == Mx-1 || j == My-1) {
176: f[j][i] = x[j][i];
177: continue;
178: }
179: u = x[j][i];
180: uxx = (two*u - x[j][i-1] - x[j][i+1])*sx;
181: uyy = (two*u - x[j-1][i] - x[j+1][i])*sy;
182: /* f[j][i] = -(uxx + uyy); */
183: f[j][i] = -u*(uxx + uyy) - (4.0 - 1.0)*((x[j][i+1] - x[j][i-1])*(x[j][i+1] - x[j][i-1])*.25*sx +
184: (x[j+1][i] - x[j-1][i])*(x[j+1][i] - x[j-1][i])*.25*sy);
185: }
186: }
188: /*
189: Restore vectors
190: */
191: DAVecRestoreArray(da,localX,(void**)&x);
192: DAVecRestoreArray(da,F,(void**)&f);
193: DARestoreLocalVector(da,&localX);
194: PetscLogFlops(11*ym*xm);
195: return(0);
196: }
198: /* ------------------------------------------------------------------- */
199: int FormInitialSolution(DA da,Vec U)
200: {
201: int ierr,i,j,xs,ys,xm,ym,Mx,My;
202: PetscScalar **u;
203: PetscReal hx,hy,x,y,r;
206: DAGetInfo(da,PETSC_IGNORE,&Mx,&My,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,
207: PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
209: hx = 1.0/(PetscReal)(Mx-1);
210: hy = 1.0/(PetscReal)(My-1);
212: /*
213: Get pointers to vector data
214: */
215: DAVecGetArray(da,U,(void**)&u);
217: /*
218: Get local grid boundaries
219: */
220: DAGetCorners(da,&xs,&ys,PETSC_NULL,&xm,&ym,PETSC_NULL);
222: /*
223: Compute function over the locally owned part of the grid
224: */
225: for (j=ys; j<ys+ym; j++) {
226: y = j*hy;
227: for (i=xs; i<xs+xm; i++) {
228: x = i*hx;
229: r = PetscSqrtScalar((x-.5)*(x-.5) + (y-.5)*(y-.5));
230: if (r < .125) {
231: u[j][i] = PetscExpScalar(-30.0*r*r*r);
232: } else {
233: u[j][i] = 0.0;
234: }
235: }
236: }
238: /*
239: Restore vectors
240: */
241: DAVecRestoreArray(da,U,(void**)&u);
242: return(0);
243: }
245: int Monitor(TS ts,int step,PetscReal ptime,Vec v,void *ctx)
246: {
247: int ierr;
248: PetscReal norm;
249: MPI_Comm comm;
252: VecNorm(v,NORM_2,&norm);
253: PetscObjectGetComm((PetscObject)ts,&comm);
254: PetscPrintf(comm,"timestep %d time %g norm %gn",step,ptime,norm);
255: return(0);
256: }