Actual source code: ct_vdp_imex.c

petsc-3.7.3 2016-07-24
Report Typos and Errors
  1: /*
  2:  * ex_vdp.c
  3:  *
  4:  *  Created on: Jun 1, 2012
  5:  *      Author: Hong Zhang
  6:  */
  7: static char help[] = "Solves the van der Pol equation. \n Input parameters include:\n";

  9: /*
 10:  * Processors:1
 11:  */

 13: /*
 14:  * This program solves the van der Pol equation
 15:  * y' = z                               (1)
 16:  * z' = (((1-y^2)*z-y)/eps              (2)
 17:  * on the domain 0<=x<=0.5, with the initial conditions
 18:  * y(0) = 2,
 19:  * z(0) = -2/3 + 10/81*eps - 292/2187*eps^2-1814/19683*eps^3
 20:  * IMEX schemes are applied to the splitted equation
 21:  * [y'] = [z]  + [0                 ]
 22:  * [z']   [0]    [(((1-y^2)*z-y)/eps]
 23:  *
 24:  * F(x)= [z]
 25:  *       [0]
 26:  *
 27:  * G(x)= [y'] -   [0                 ]
 28:  *       [z']     [(((1-y^2)*z-y)/eps]
 29:  *
 30:  * JG(x) =  G_x + a G_xdot
 31:  */

 33: #include <petscdmda.h>
 34: #include <petscts.h>

 36: typedef struct _User *User;
 37: struct _User {
 38:   PetscReal mu;  /*stiffness control coefficient: epsilon*/
 39: };

 41: static PetscErrorCode RHSFunction(TS,PetscReal,Vec,Vec,void*);
 42: static PetscErrorCode IFunction(TS,PetscReal,Vec,Vec,Vec,void*);
 43: static PetscErrorCode IJacobian(TS,PetscReal,Vec,Vec,PetscReal,Mat,Mat,void*);


 48: int main(int argc, char **argv)
 49: {
 50:   TS                ts;
 51:   Vec               x; /*solution vector*/
 52:   Mat               A; /*Jacobian*/
 53:   PetscInt          steps,maxsteps,mx,eimex_rowcol[2],two;
 54:   PetscErrorCode    ierr;
 55:   PetscScalar       *x_ptr;
 56:   PetscReal         ftime,dt,norm;
 57:   Vec               ref;
 58:   struct _User      user;       /* user-defined work context */
 59:   PetscViewer       viewer;

 61:   PetscInitialize(&argc,&argv,NULL,help);

 63:   /* Initialize user application context */
 64:   PetscOptionsBegin(PETSC_COMM_WORLD,NULL,"van der Pol options","");
 65:   user.mu      = 1e0;
 66:   PetscOptionsReal("-eps","Stiffness controller","",user.mu,&user.mu,NULL);
 67:   PetscOptionsEnd();

 69:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 70:    Set runtime options
 71:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 72:   /*
 73:    PetscOptionsGetBool(NULL,NULL,"-monitor",&monitor,NULL);
 74:    */

 76:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 77:    Create necessary matrix and vectors, solve same ODE on every process
 78:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 79:   MatCreate(PETSC_COMM_WORLD,&A);
 80:   MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,2,2);
 81:   MatSetFromOptions(A);
 82:   MatSetUp(A);
 83:   MatCreateVecs(A,&x,NULL);

 85:   MatCreateVecs(A,&ref,NULL);
 86:   VecGetArray(ref,&x_ptr);
 87:   /*
 88:    * [0,1], mu=10^-3
 89:    */
 90:   /*
 91:    x_ptr[0] = -1.8881254106283;
 92:    x_ptr[1] =  0.7359074233370;*/

 94:   /*
 95:    * [0,0.5],mu=10^-3
 96:    */
 97:   /*
 98:    x_ptr[0] = 1.596980778659137;
 99:    x_ptr[1] = -1.029103015879544;
100:    */
101:   /*
102:    * [0,0.5],mu=1
103:    */
104:   x_ptr[0] = 1.619084329683235;
105:   x_ptr[1] = -0.803530465176385;

107:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
108:    Create timestepping solver context
109:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
110:   TSCreate(PETSC_COMM_WORLD,&ts);
111:   TSSetType(ts,TSEIMEX);
112:   TSSetRHSFunction(ts,NULL,RHSFunction,&user);
113:   TSSetIFunction(ts,NULL,IFunction,&user);
114:   TSSetIJacobian(ts,A,A,IJacobian,&user);

116:   ftime = 1.1;
117:   dt    = 0.00001;
118:   maxsteps = 100000;
119:   TSSetDuration(ts,maxsteps,ftime);
120:   TSSetInitialTimeStep(ts,0.0,dt);
121:   TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);
122:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
123:    Set initial conditions
124:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
125:   VecGetArray(x,&x_ptr);
126:   x_ptr[0] = 2.;
127:   x_ptr[1] = -2./3. + 10./81.*(user.mu) - 292./2187.* (user.mu) * (user.mu)
128:     -1814./19683.*(user.mu)*(user.mu)*(user.mu);
129:   TSSetSolution(ts,x);
130:   VecGetSize(x,&mx);

132:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
133:    Set runtime options
134:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
135:   TSSetFromOptions(ts);

137:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
138:    Solve nonlinear system
139:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
140:   TSSolve(ts,x);
141:   TSGetTime(ts,&ftime);
142:   TSGetTimeStepNumber(ts,&steps);

144:   VecAXPY(x,-1.0,ref);
145:   VecNorm(x,NORM_2,&norm);
146:   TSGetTimeStep(ts,&dt);

148:   eimex_rowcol[0] = 0; eimex_rowcol[1] = 0; two = 2;
149:   PetscOptionsGetIntArray(NULL,NULL,"-ts_eimex_row_col",eimex_rowcol,&two,NULL);
150:   PetscPrintf(PETSC_COMM_WORLD,"order %11s %18s %37s\n","dt","norm","final solution components 0 and 1");
151:   VecGetArray(x,&x_ptr);
152:   PetscPrintf(PETSC_COMM_WORLD,"(%D,%D) %10.8f %18.15f %18.15f %18.15f\n",eimex_rowcol[0],eimex_rowcol[1],(double)dt,(double)norm,(double)PetscRealPart(x_ptr[0]),(double)PetscRealPart(x_ptr[1]));
153:   VecRestoreArray(x,&x_ptr);

155:   /* Write line in convergence log */
156:   PetscViewerCreate(PETSC_COMM_WORLD,&viewer);
157:   PetscViewerSetType(viewer,PETSCVIEWERASCII);
158:   PetscViewerFileSetMode(viewer,FILE_MODE_APPEND);
159:   PetscViewerFileSetName(viewer,"eimex_nonstiff_vdp.txt");
160:   PetscViewerASCIIPrintf(viewer,"%D %D %10.8f %18.15f\n",eimex_rowcol[0],eimex_rowcol[1],(double)dt,(double)norm);
161:   PetscViewerDestroy(&viewer);

163:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
164:    Free work space.
165:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
166:   MatDestroy(&A);
167:   VecDestroy(&x);
168:   VecDestroy(&ref);
169:   TSDestroy(&ts);
170:   PetscFinalize();
171:   return(0);
172: }


177: static PetscErrorCode RHSFunction(TS ts,PetscReal t,Vec X,Vec F,void *ptr)
178: {
179:   PetscErrorCode    ierr;
180:   PetscScalar       *f;
181:   const PetscScalar *x;

184:   VecGetArrayRead(X,&x);
185:   VecGetArray(F,&f);
186:   f[0] = x[1];
187:   f[1] = 0.0;
188:   VecRestoreArrayRead(X,&x);
189:   VecRestoreArray(F,&f);
190:   return(0);
191: }

195: static PetscErrorCode IFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ptr)
196: {
197:   User              user = (User)ptr;
198:   PetscScalar       *f;
199:   const PetscScalar *x,*xdot;
200:   PetscErrorCode    ierr;
201: 
203:   VecGetArrayRead(X,&x);
204:   VecGetArrayRead(Xdot,&xdot);
205:   VecGetArray(F,&f);
206:   f[0] = xdot[0];
207:   f[1] = xdot[1]-((1.-x[0]*x[0])*x[1]-x[0])/user->mu;
208:   VecRestoreArrayRead(X,&x);
209:   VecRestoreArrayRead(Xdot,&xdot);
210:   VecRestoreArray(F,&f);
211:   return(0);
212: }

216: static PetscErrorCode IJacobian(TS  ts,PetscReal t,Vec X,Vec Xdot,PetscReal a,Mat A,Mat B,void *ptr)
217: {
218:   PetscErrorCode    ierr;
219:   User              user = (User)ptr;
220:   PetscReal         mu = user->mu;
221:   PetscInt          rowcol[] = {0,1};
222:   PetscScalar       J[2][2];
223:   const PetscScalar *x;

226:   VecGetArrayRead(X,&x);
227:   J[0][0] = a;
228:   J[0][1] = 0;
229:   J[1][0] = (2.*x[0]*x[1]+1.)/mu;
230:   J[1][1] = a - (1. - x[0]*x[0])/mu;
231:   MatSetValues(B,2,rowcol,2,rowcol,&J[0][0],INSERT_VALUES);
232:   VecRestoreArrayRead(X,&x);

234:   MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
235:   MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
236:   if (A != B) {
237:     MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
238:     MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
239:   }
240:   return(0);
241: }