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