Actual source code: ex1.c petsc-3.6.2 2015-10-02 
   
  2:  static char help[] = "Nonlinear Reaction Problem from Chemistry.\n" ;
 
                 
 35:  /* 
 36:        Project: Generate a nicely formated HTML page using 
 37:           1) the HTML version of the source code and text in this file, use make html to generate the file ex1.c.html 
 38:           2) the images (Draw_XXX_0_0.Gif Draw_YYY_0_0.Gif Draw_ZZZ_1_0.Gif) and 
 39:           3) the text output (output.txt) generated by running the following commands. 
 40:           4) <iframe src="generated_topics.html" scrolling="no" frameborder="0"  width=600 height=300></iframe> 
 42:        rm -rf *.Gif 
 43:        ./ex1 -ts_monitor_lg_error -1 -ts_monitor_lg_solution -1   -draw_pause -2 -ts_max_steps 100 -ts_monitor_lg_timestep -1 -draw_save -draw_virtual -ts_monitor -ts_adapt_monitor -ts_view  > output.txt 
 45:        For example something like 
 46:  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
 47:  <html> 
 48:    <head> 
 49:      <meta http-equiv="content-type" content="text/html;charset=utf-8"> 
 50:      <title>PETSc Example -- Nonlinear Reaction Problem from Chemistry</title> 
 51:    </head> 
 52:    <body> 
 53:    <iframe src="ex1.c.html" scrolling="yes" frameborder="1"  width=2000 height=400></iframe> 
 54:    <img alt="" src="Draw_0x84000000_0_0.Gif"/><img alt="" src="Draw_0x84000001_0_0.Gif"/><img alt="" src="Draw_0x84000001_1_0.Gif"/> 
 55:    <iframe src="output.txt" scrolling="yes" frameborder="1"  width=2000 height=1000></iframe> 
 56:    </body> 
 57:  </html> 
 59:  */ 
 61:  /* 
 62:     Include "petscts.h" so that we can use TS  solvers.  Note that this 
 63:     file automatically includes: 
 64:       petscsys.h       - base PETSc routines   petscvec.h - vectors 
 65:       petscmat.h - matrices 
 66:       petscis.h     - index sets            petscksp.h - Krylov subspace methods 
 67:       petscviewer.h - viewers               petscpc.h  - preconditioners 
 68:       petscksp.h   - linear solvers 
 69:  */ 
 70:  #include <petscts.h> 
 72:  typedef  struct  {
 73:    PetscScalar  k;
 74:    Vec          initialsolution;
 75:  } AppCtx;
 79:  PetscErrorCode  IFunctionView(AppCtx *ctx,PetscViewer  v) 80:  {
 84:    PetscViewerBinaryWrite (v,&ctx->k,1,PETSC_SCALAR,PETSC_FALSE );
 85:    return (0);
 86:  }
 90:  PetscErrorCode  IFunctionLoad(AppCtx **ctx,PetscViewer  v) 91:  {
 95:    PetscMalloc (sizeof (AppCtx),ctx);
 96:    PetscViewerBinaryRead (v,&(*ctx)->k,1,NULL,PETSC_SCALAR);
 97:    return (0);
 98:  }
102:  /* 
103:       Defines the ODE passed to the ODE solver 
104:  */ 
105:  PetscErrorCode  IFunction(TS  ts,PetscReal  t,Vec  U,Vec  Udot,Vec  F,AppCtx *ctx)106:  {
107:    PetscErrorCode     ierr;
108:    PetscScalar        *f;
109:    const PetscScalar  *u,*udot;
112:    /*  The next three lines allow us to access the entries of the vectors directly */ 
113:    VecGetArrayRead (U,&u);
114:    VecGetArrayRead (Udot,&udot);
115:    VecGetArray (F,&f);
116:    f[0] = udot[0] + ctx->k*u[0]*u[1];
117:    f[1] = udot[1] + ctx->k*u[0]*u[1];
118:    f[2] = udot[2] - ctx->k*u[0]*u[1];
119:    VecRestoreArrayRead (U,&u);
120:    VecRestoreArrayRead (Udot,&udot);
121:    VecRestoreArray (F,&f);
122:    return (0);
123:  }
127:  /* 
128:       Defines the Jacobian of the ODE passed to the ODE solver. See TSSetIJacobian () for the meaning of a and the Jacobian. 
129:  */ 
130:  PetscErrorCode  IJacobian(TS  ts,PetscReal  t,Vec  U,Vec  Udot,PetscReal  a,Mat  A,Mat  B,AppCtx *ctx)131:  {
132:    PetscErrorCode     ierr;
133:    PetscInt           rowcol[] = {0,1,2};
134:    PetscScalar        J[3][3];
135:    const PetscScalar  *u,*udot;
138:    VecGetArrayRead (U,&u);
139:    VecGetArrayRead (Udot,&udot);
140:    J[0][0] = a + ctx->k*u[1];   J[0][1] = ctx->k*u[0];       J[0][2] = 0.0;
141:    J[1][0] = ctx->k*u[1];       J[1][1] = a + ctx->k*u[0];   J[1][2] = 0.0;
142:    J[2][0] = -ctx->k*u[1];      J[2][1] = -ctx->k*u[0];      J[2][2] = a;
143:    MatSetValues (B,3,rowcol,3,rowcol,&J[0][0],INSERT_VALUES );
144:    VecRestoreArrayRead (U,&u);
145:    VecRestoreArrayRead (Udot,&udot);
147:    MatAssemblyBegin (A,MAT_FINAL_ASSEMBLY);
148:    MatAssemblyEnd (A,MAT_FINAL_ASSEMBLY);
149:    if  (A != B) {
150:      MatAssemblyBegin (B,MAT_FINAL_ASSEMBLY);
151:      MatAssemblyEnd (B,MAT_FINAL_ASSEMBLY);
152:    }
153:    return (0);
154:  }
158:  /* 
159:       Defines the exact (analytic) solution to the ODE 
160:  */ 
161:  PetscErrorCode  Solution(TS  ts,PetscReal  t,Vec  U,AppCtx *ctx)162:  {
163:    PetscErrorCode     ierr;
164:    const PetscScalar  *uinit;
165:    PetscScalar        *u,d0,q;
168:    VecGetArrayRead (ctx->initialsolution,&uinit);
169:    VecGetArray (U,&u);
170:    d0   = uinit[0] - uinit[1];
171:    if  (d0 == 0.0) q = ctx->k*t;
172:    else  q = (1.0 - PetscExpScalar(-ctx->k*t*d0))/d0;
173:    u[0] = uinit[0]/(1.0 + uinit[1]*q);
174:    u[1] = u[0] - d0;
175:    u[2] = uinit[1] + uinit[2] - u[1];
176:    VecRestoreArray (U,&u);
177:    VecRestoreArrayRead (ctx->initialsolution,&uinit);
178:    return (0);
179:  }
183:  184:  {
185:    TS              ts;            /* ODE integrator */ 
186:    Vec             U;             /* solution will be stored here */ 
187:    Mat             A;             /* Jacobian matrix */ 
189:    PetscMPIInt     size;
190:    PetscInt        n = 3;
191:    AppCtx         ctx;
192:    PetscScalar     *u;
193:    const char     * const names[] = {"U1" ,"U2" ,"U3" ,NULL};
195:    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
196:       Initialize program 
197:       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
198:    PetscInitialize (&argc,&argv,(char*)0,help);
199:    MPI_Comm_size (PETSC_COMM_WORLD ,&size);
200:    if  (size > 1) SETERRQ (PETSC_COMM_WORLD ,PETSC_ERR_SUP,"Only for sequential runs" );
202:    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
203:      Create necessary matrix and vectors 
204:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
205:    MatCreate (PETSC_COMM_WORLD ,&A);
206:    MatSetSizes (A,n,n,PETSC_DETERMINE ,PETSC_DETERMINE );
207:    MatSetFromOptions (A);
208:    MatSetUp (A);
210:    MatCreateVecs (A,&U,NULL);
212:    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
213:      Set runtime options 
214:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
215:    ctx.k = .9;
216:    PetscOptionsGetScalar (NULL,"-k" ,&ctx.k,NULL);
217:    VecDuplicate (U,&ctx.initialsolution);
218:    VecGetArray (ctx.initialsolution,&u);
219:    u[0]  = 1;
220:    u[1]  = .7;
221:    u[2]  = 0;
222:    VecRestoreArray (ctx.initialsolution,&u);
223:    PetscOptionsGetVec(NULL,"-initial" ,ctx.initialsolution,NULL);
225:    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
226:       Create timestepping solver context 
227:       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
228:    TSCreate (PETSC_COMM_WORLD ,&ts);
229:    TSSetProblemType (ts,TS_NONLINEAR);
230:    TSSetType (ts,TSROSW );
231:    TSSetIFunction (ts,NULL,(TSIFunction) IFunction,&ctx);
232:    TSSetIJacobian (ts,A,A,(TSIJacobian)IJacobian,&ctx);
233:    TSSetSolutionFunction (ts,(TSSolutionFunction)Solution,&ctx);
235:    {
236:      DM    dm;
237:      void *ptr;
238:      TSGetDM (ts,&dm);
239:      PetscDLSym (NULL,"IFunctionView" ,&ptr);
240:      PetscDLSym (NULL,"IFunctionLoad" ,&ptr);
241:      DMTSSetIFunctionSerialize (dm,(PetscErrorCode  (*)(void*,PetscViewer ))IFunctionView,(PetscErrorCode  (*)(void**,PetscViewer ))IFunctionLoad);
242:      DMTSSetIJacobianSerialize (dm,(PetscErrorCode  (*)(void*,PetscViewer ))IFunctionView,(PetscErrorCode  (*)(void**,PetscViewer ))IFunctionLoad);
243:    }
245:    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
246:       Set initial conditions 
247:     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
248:    Solution(ts,0,U,&ctx);
249:    TSSetSolution (ts,U);
251:    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
252:       Set solver options 
253:     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
254:    TSSetDuration (ts,1000,20.0);
255:    TSSetInitialTimeStep (ts,0.0,.001);
256:    TSSetFromOptions (ts);
257:    TSMonitorLGSetVariableNames (ts,names);
259:    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
260:       Solve nonlinear system 
261:       - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
262:    TSSolve (ts,U);
264:    TSView (ts,PETSC_VIEWER_BINARY_WORLD );
266:    /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
267:       Free work space.  All PETSc objects should be destroyed when they are no longer needed. 
268:     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ 
269:    VecDestroy (&ctx.initialsolution);
270:    MatDestroy (&A);
271:    VecDestroy (&U);
272:    TSDestroy (&ts);
274:    PetscFinalize ();
275:    return (0);
276:  }