Actual source code: ex7.c
petsc-3.4.2 2013-07-02
2: static char help[] = ".\n";
4: /*
6: u_t = u_xx + R(u)
8: Where u(t,x,i) for i=0, .... N-1 where i+1 represents the void size
10: ex9.c is the 2d version of this code
11: */
13: #include <petscdmda.h>
14: #include <petscts.h>
16: /*
17: User-defined data structures and routines
18: */
20: /* AppCtx */
21: typedef struct {
22: PetscInt N; /* number of dofs */
23: } AppCtx;
25: extern PetscErrorCode IFunction(TS,PetscReal,Vec,Vec,Vec,void*);
26: extern PetscErrorCode InitialConditions(DM,Vec);
27: extern PetscErrorCode IJacobian(TS,PetscReal,Vec,Vec,PetscReal,Mat*,Mat*,MatStructure*,void*);
32: int main(int argc,char **argv)
33: {
34: TS ts; /* nonlinear solver */
35: Vec U; /* solution, residual vectors */
36: Mat J; /* Jacobian matrix */
37: PetscInt maxsteps = 1000;
39: DM da;
40: AppCtx user;
41: PetscInt i;
42: char Name[16];
44: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
45: Initialize program
46: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
47: PetscInitialize(&argc,&argv,(char*)0,help);
48: user.N = 1;
49: PetscOptionsGetInt(NULL,"-N",&user.N,NULL);
51: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
52: Create distributed array (DMDA) to manage parallel grid and vectors
53: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
54: DMDACreate1d(PETSC_COMM_WORLD, DMDA_BOUNDARY_MIRROR,-8,user.N,1,NULL,&da);
56: for (i=0; i<user.N; i++) {
57: PetscSNPrintf(Name,16,"Void size %d",(int)(i+1));
58: DMDASetFieldName(da,i,Name);
59: }
61: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
62: Extract global vectors from DMDA; then duplicate for remaining
63: vectors that are the same types
64: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
65: DMCreateGlobalVector(da,&U);
66: DMCreateMatrix(da,MATAIJ,&J);
68: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
69: Create timestepping solver context
70: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
71: TSCreate(PETSC_COMM_WORLD,&ts);
72: TSSetType(ts,TSARKIMEX);
73: TSSetDM(ts,da);
74: TSSetProblemType(ts,TS_NONLINEAR);
75: TSSetIFunction(ts,NULL,IFunction,&user);
76: TSSetIJacobian(ts,J,J,IJacobian,&user);
79: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
80: Set initial conditions
81: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
82: InitialConditions(da,U);
83: TSSetSolution(ts,U);
85: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
86: Set solver options
87: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
88: TSSetInitialTimeStep(ts,0.0,.001);
89: TSSetDuration(ts,maxsteps,1.0);
90: TSSetFromOptions(ts);
92: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
93: Solve nonlinear system
94: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
95: TSSolve(ts,U);
97: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
98: Free work space. All PETSc objects should be destroyed when they
99: are no longer needed.
100: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
101: VecDestroy(&U);
102: MatDestroy(&J);
103: TSDestroy(&ts);
104: DMDestroy(&da);
106: PetscFinalize();
107: return(0);
108: }
109: /* ------------------------------------------------------------------- */
112: /*
113: IFunction - Evaluates nonlinear function, F(U).
115: Input Parameters:
116: . ts - the TS context
117: . U - input vector
118: . ptr - optional user-defined context, as set by SNESSetFunction()
120: Output Parameter:
121: . F - function vector
122: */
123: PetscErrorCode IFunction(TS ts,PetscReal ftime,Vec U,Vec Udot,Vec F,void *ptr)
124: {
125: DM da;
127: PetscInt i,c,Mx,xs,xm,N;
128: PetscReal hx,sx,x;
129: PetscScalar uxx;
130: PetscScalar **u,**f,**udot;
131: Vec localU;
134: TSGetDM(ts,&da);
135: DMGetLocalVector(da,&localU);
136: DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,&N,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
138: hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx);
140: /*
141: Scatter ghost points to local vector,using the 2-step process
142: DMGlobalToLocalBegin(),DMGlobalToLocalEnd().
143: By placing code between these two statements, computations can be
144: done while messages are in transition.
145: */
146: DMGlobalToLocalBegin(da,U,INSERT_VALUES,localU);
147: DMGlobalToLocalEnd(da,U,INSERT_VALUES,localU);
149: /*
150: Get pointers to vector data
151: */
152: DMDAVecGetArrayDOF(da,localU,&u);
153: DMDAVecGetArrayDOF(da,Udot,&udot);
154: DMDAVecGetArrayDOF(da,F,&f);
156: /*
157: Get local grid boundaries
158: */
159: DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);
161: /*
162: Compute function over the locally owned part of the grid
163: */
164: for (i=xs; i<xs+xm; i++) {
165: x = i*hx;
167: /* diffusion term */
168: for (c=0; c<N; c++) {
169: uxx = (-2.0*u[i][c] + u[i-1][c] + u[i+1][c])*sx;
170: f[i][c] = udot[i][c] - uxx;
171: }
173: /* reaction terms */
175: for (c=0; c<N/3; c++) {
176: f[i][c] += 500*u[i][c]*u[i][c] + 500*u[i][c]*u[i][c+1];
177: f[i][c+1] += -500*u[i][c]*u[i][c] + 500*u[i][c]*u[i][c+1];
178: f[i][c+2] -= 500*u[i][c]*u[i][c+1];
179: }
182: /* forcing term */
184: f[i][0] -= 5*PetscExpScalar((1.0 - x)*(1.0 - x));
186: }
188: /*
189: Restore vectors
190: */
191: DMDAVecRestoreArrayDOF(da,localU,&u);
192: DMDAVecRestoreArrayDOF(da,Udot,&udot);
193: DMDAVecRestoreArrayDOF(da,F,&f);
194: DMRestoreLocalVector(da,&localU);
195: return(0);
196: }
200: PetscErrorCode IJacobian(TS ts,PetscReal t,Vec U,Vec Udot,PetscReal a,Mat *J,Mat *Jpre,MatStructure *str,void *ctx)
201: {
203: PetscInt i,c,Mx,xs,xm,nc;
204: DM da;
205: MatStencil col[3],row;
206: PetscScalar vals[3],hx,sx;
207: AppCtx *user = (AppCtx*)ctx;
208: PetscInt N = user->N;
209: PetscScalar **u;
212: TSGetDM(ts,&da);
213: DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
214: DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);
216: hx = 1.0/(PetscReal)(Mx-1); sx = 1.0/(hx*hx);
218: DMDAVecGetArrayDOF(da,U,&u);
220: MatZeroEntries(*Jpre);
221: for (i=xs; i<xs+xm; i++) {
222: for (c=0; c<N; c++) {
223: nc = 0;
224: row.c = c; row.i = i;
225: col[nc].c = c; col[nc].i = i-1; vals[nc++] = -sx;
226: col[nc].c = c; col[nc].i = i; vals[nc++] = 2.0*sx + a;
227: col[nc].c = c; col[nc].i = i+1; vals[nc++] = -sx;
228: MatSetValuesStencil(*Jpre,1,&row,nc,col,vals,ADD_VALUES);
229: }
231: for (c=0; c<N/3; c++) {
232: nc = 0;
233: row.c = c; row.i = i;
234: col[nc].c = c; col[nc].i = i; vals[nc++] = 1000*u[i][c] + 500*u[i][c+1];
235: col[nc].c = c+1; col[nc].i = i; vals[nc++] = 500*u[i][c];
236: MatSetValuesStencil(*Jpre,1,&row,nc,col,vals,ADD_VALUES);
238: nc = 0;
239: row.c = c+1; row.i = i;
240: col[nc].c = c; col[nc].i = i; vals[nc++] = -1000*u[i][c] + 500*u[i][c+1];
241: col[nc].c = c+1; col[nc].i = i; vals[nc++] = 500*u[i][c];
242: MatSetValuesStencil(*Jpre,1,&row,nc,col,vals,ADD_VALUES);
244: nc = 0;
245: row.c = c+2; row.i = i;
246: col[nc].c = c; col[nc].i = i; vals[nc++] = -500*u[i][c+1];
247: col[nc].c = c+1; col[nc].i = i; vals[nc++] = -500*u[i][c];
248: MatSetValuesStencil(*Jpre,1,&row,nc,col,vals,ADD_VALUES);
250: }
251: }
252: MatAssemblyBegin(*Jpre,MAT_FINAL_ASSEMBLY);
253: MatAssemblyEnd(*Jpre,MAT_FINAL_ASSEMBLY);
254: if (*J != *Jpre) {
255: MatAssemblyBegin(*J,MAT_FINAL_ASSEMBLY);
256: MatAssemblyEnd(*J,MAT_FINAL_ASSEMBLY);
257: }
258: DMDAVecRestoreArrayDOF(da,U,&u);
259: return(0);
260: }
262: /* ------------------------------------------------------------------- */
265: PetscErrorCode InitialConditions(DM da,Vec U)
266: {
268: PetscInt i,c,xs,xm,Mx,N;
269: PetscScalar **u;
270: PetscReal hx,x;
273: DMDAGetInfo(da,PETSC_IGNORE,&Mx,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,&N,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE,PETSC_IGNORE);
275: hx = 1.0/(PetscReal)(Mx-1);
277: /*
278: Get pointers to vector data
279: */
280: DMDAVecGetArrayDOF(da,U,&u);
282: /*
283: Get local grid boundaries
284: */
285: DMDAGetCorners(da,&xs,NULL,NULL,&xm,NULL,NULL);
287: /*
288: Compute function over the locally owned part of the grid
289: */
290: for (i=xs; i<xs+xm; i++) {
291: x = i*hx;
292: for (c=0; c<N; c++) u[i][c] = 0.0; /*PetscCosScalar(PETSC_PI*x);*/
293: }
295: /*
296: Restore vectors
297: */
298: DMDAVecRestoreArrayDOF(da,U,&u);
299: return(0);
300: }