Date: 2022-03-31T04:48:45+00:00

Actual source code: ex19.c

      2: static char help[] = "Solves the van der Pol DAE.\n\
      3: Input parameters include:\n";

      5: /*
      6:    Concepts: TS^time-dependent nonlinear problems
      7:    Concepts: TS^van der Pol DAE
      8:    Processors: 1
      9: */
     10: /* ------------------------------------------------------------------------

     12:    This program solves the van der Pol DAE
     13:        y' = -z = f(y,z)        (1)
     14:        0  = y-(z^3/3 - z) = g(y,z)
     15:    on the domain 0 <= x <= 1, with the boundary conditions
     16:        y(0) = -2, y'(0) = -2.355301397608119909925287735864250951918
     17:    This is a nonlinear equation.

     19:    Notes:
     20:    This code demonstrates the TS solver interface with the Van der Pol DAE,
     21:    namely it is the case when there is no RHS (meaning the RHS == 0), and the
     22:    equations are converted to two variants of linear problems, u_t = f(u,t),
     23:    namely turning (1) into a vector equation in terms of u,

     25:    [     y' + z      ] = [ 0 ]
     26:    [ (z^3/3 - z) - y ]   [ 0 ]

     28:    which then we can write as a vector equation

     30:    [      u_1' + u_2       ] = [ 0 ]  (2)
     31:    [ (u_2^3/3 - u_2) - u_1 ]   [ 0 ]

     33:    which is now in the desired form of u_t = f(u,t). As this is a DAE, and
     34:    there is no u_2', there is no need for a split,

     36:    so

     38:    [ F(u',u,t) ] = [ u_1' ] + [         u_2           ]
     39:                    [  0   ]   [ (u_2^3/3 - u_2) - u_1 ]

     41:    Using the definition of the Jacobian of F (from the PETSc user manual),
     42:    in the equation F(u',u,t) = G(u,t),

     44:               dF   dF
     45:    J(F) = a * -- - --
     46:               du'  du

     48:    where d is the partial derivative. In this example,

     50:    dF   [ 1 ; 0 ]
     51:    -- = [       ]
     52:    du'  [ 0 ; 0 ]

     54:    dF   [  0 ;      1     ]
     55:    -- = [                 ]
     56:    du   [ -1 ; 1 - u_2^2  ]

     58:    Hence,

     60:           [ a ;    -1     ]
     61:    J(F) = [               ]
     62:           [ 1 ; u_2^2 - 1 ]

     64:   ------------------------------------------------------------------------- */

     66: #include <petscts.h>

     68: typedef struct _n_User *User;
     69: struct _n_User {
     70:   PetscReal next_output;
     71: };

     73: /*
     74:    User-defined routines
     75: */

     77: static PetscErrorCode IFunction(TS ts,PetscReal t,Vec X,Vec Xdot,Vec F,void *ctx)
     78: {
     79:   PetscScalar       *f;
     80:   const PetscScalar *x,*xdot;

     83:   VecGetArrayRead(X,&x);
     84:   VecGetArrayRead(Xdot,&xdot);
     85:   VecGetArray(F,&f);
     86:   f[0] = xdot[0] + x[1];
     87:   f[1] = (x[1]*x[1]*x[1]/3.0 - x[1])-x[0];
     88:   VecRestoreArrayRead(X,&x);
     89:   VecRestoreArrayRead(Xdot,&xdot);
     90:   VecRestoreArray(F,&f);
     91:   return 0;
     92: }

     94: static PetscErrorCode IJacobian(TS ts,PetscReal t,Vec X,Vec Xdot,PetscReal a,Mat A,Mat B,void *ctx)
     95: {
     96:   PetscInt          rowcol[] = {0,1};
     97:   PetscScalar       J[2][2];
     98:   const PetscScalar *x;

    101:   VecGetArrayRead(X,&x);
    102:   J[0][0] = a;    J[0][1] = -1.;
    103:   J[1][0] = 1.;   J[1][1] = -1. + x[1]*x[1];
    104:   MatSetValues(B,2,rowcol,2,rowcol,&J[0][0],INSERT_VALUES);
    105:   VecRestoreArrayRead(X,&x);

    107:   MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
    108:   MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
    109:   if (A != B) {
    110:     MatAssemblyBegin(B,MAT_FINAL_ASSEMBLY);
    111:     MatAssemblyEnd(B,MAT_FINAL_ASSEMBLY);
    112:   }
    113:   return 0;
    114: }

    116: static PetscErrorCode RegisterMyARK2(void)
    117: {
    119:   {
    120:     const PetscReal
    121:       A[3][3] = {{0,0,0},
    122:                  {0.41421356237309504880,0,0},
    123:                  {0.75,0.25,0}},
    124:       At[3][3] = {{0,0,0},
    125:                   {0.12132034355964257320,0.29289321881345247560,0},
    126:                   {0.20710678118654752440,0.50000000000000000000,0.29289321881345247560}},
    127:     *bembedt = NULL,*bembed = NULL;
    128:     TSARKIMEXRegister("myark2",2,3,&At[0][0],NULL,NULL,&A[0][0],NULL,NULL,bembedt,bembed,0,NULL,NULL);
    129:   }
    130:   return 0;
    131: }

    133: /* Monitor timesteps and use interpolation to output at integer multiples of 0.1 */
    134: static PetscErrorCode Monitor(TS ts,PetscInt step,PetscReal t,Vec X,void *ctx)
    135: {
    136:   const PetscScalar *x;
    137:   PetscReal         tfinal, dt;
    138:   User              user = (User)ctx;
    139:   Vec               interpolatedX;

    142:   TSGetTimeStep(ts,&dt);
    143:   TSGetMaxTime(ts,&tfinal);

    145:   while (user->next_output <= t && user->next_output <= tfinal) {
    146:     VecDuplicate(X,&interpolatedX);
    147:     TSInterpolate(ts,user->next_output,interpolatedX);
    148:     VecGetArrayRead(interpolatedX,&x);
    149:     PetscPrintf(PETSC_COMM_WORLD,"[%.1f] %3D TS %.6f (dt = %.6f) X % 12.6e % 12.6e\n",(double)user->next_output,step,(double)t,(double)dt,(double)PetscRealPart(x[0]),(double)PetscRealPart(x[1]));
    150:     VecRestoreArrayRead(interpolatedX,&x);
    151:     VecDestroy(&interpolatedX);
    152:     user->next_output += PetscRealConstant(0.1);
    153:   }
    154:   return 0;
    155: }

    157: int main(int argc,char **argv)
    158: {
    159:   TS             ts;            /* nonlinear solver */
    160:   Vec            x;             /* solution, residual vectors */
    161:   Mat            A;             /* Jacobian matrix */
    162:   PetscInt       steps;
    163:   PetscReal      ftime   = 0.5;
    164:   PetscBool      monitor = PETSC_FALSE;
    165:   PetscScalar    *x_ptr;
    166:   PetscMPIInt    size;
    167:   struct _n_User user;

    169:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    170:      Initialize program
    171:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    172:   PetscInitialize(&argc,&argv,NULL,help);
    173:   MPI_Comm_size(PETSC_COMM_WORLD,&size);

    176:   RegisterMyARK2();

    178:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    179:     Set runtime options
    180:     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

    182:   user.next_output = 0.0;
    183:   PetscOptionsGetBool(NULL,NULL,"-monitor",&monitor,NULL);

    185:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    186:     Create necessary matrix and vectors, solve same ODE on every process
    187:     - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    188:   MatCreate(PETSC_COMM_WORLD,&A);
    189:   MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,2,2);
    190:   MatSetFromOptions(A);
    191:   MatSetUp(A);
    192:   MatCreateVecs(A,&x,NULL);

    194:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    195:      Create timestepping solver context
    196:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    197:   TSCreate(PETSC_COMM_WORLD,&ts);
    198:   TSSetType(ts,TSBEULER);
    199:   TSSetIFunction(ts,NULL,IFunction,&user);
    200:   TSSetIJacobian(ts,A,A,IJacobian,&user);
    201:   TSSetMaxTime(ts,ftime);
    202:   TSSetExactFinalTime(ts,TS_EXACTFINALTIME_STEPOVER);
    203:   if (monitor) {
    204:     TSMonitorSet(ts,Monitor,&user,NULL);
    205:   }

    207:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    208:      Set initial conditions
    209:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    210:   VecGetArray(x,&x_ptr);
    211:   x_ptr[0] = -2;   x_ptr[1] = -2.355301397608119909925287735864250951918;
    212:   VecRestoreArray(x,&x_ptr);
    213:   TSSetTimeStep(ts,.001);

    215:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    216:      Set runtime options
    217:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    218:   TSSetFromOptions(ts);

    220:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    221:      Solve nonlinear system
    222:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    223:   TSSolve(ts,x);
    224:   TSGetSolveTime(ts,&ftime);
    225:   TSGetStepNumber(ts,&steps);
    226:   PetscPrintf(PETSC_COMM_WORLD,"steps %3D, ftime %g\n",steps,(double)ftime);
    227:   VecView(x,PETSC_VIEWER_STDOUT_WORLD);

    229:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    230:      Free work space.  All PETSc objects should be destroyed when they
    231:      are no longer needed.
    232:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
    233:   MatDestroy(&A);
    234:   VecDestroy(&x);
    235:   TSDestroy(&ts);

    237:   PetscFinalize();
    238:   return 0;
    239: }

    241: /*TEST

    243:    test:
    244:       requires: !single
    245:       suffix: a
    246:       args: -monitor -ts_type bdf -ts_rtol 1e-6 -ts_atol 1e-6 -ts_view -ts_adapt_type dsp
    247:       output_file: output/ex19_pi42.out

    249:    test:
    250:       requires: !single
    251:       suffix: b
    252:       args: -monitor -ts_type bdf -ts_rtol 1e-6 -ts_atol 1e-6 -ts_view -ts_adapt_type dsp -ts_adapt_dsp_filter PI42
    253:       output_file: output/ex19_pi42.out

    255:    test:
    256:       requires: !single
    257:       suffix: c
    258:       args: -monitor -ts_type bdf -ts_rtol 1e-6 -ts_atol 1e-6 -ts_view -ts_adapt_type dsp -ts_adapt_dsp_pid 0.4,0.2
    259:       output_file: output/ex19_pi42.out

    261:    test:
    262:       requires: !single
    263:       suffix: bdf_reject
    264:       args: -ts_type bdf -ts_dt 0.5 -ts_max_steps 1 -ts_max_reject {{0 1 2}separate_output} -ts_error_if_step_fails false -ts_adapt_monitor

    266: TEST*/