Date: 2013-07-02T14:51:18+00:00

Actual source code: ex2.c
petsc-3.4.2 2013-07-02

      1: /*
      2:        Formatted test for TS routines.

      4:           Solves U_t=F(t,u)
      5:           Where:

      7:                   [2*u1+u2
      8:           F(t,u)= [u1+2*u2+u3
      9:                   [   u2+2*u3
     10:        We can compare the solutions from euler, beuler and SUNDIALS to
     11:        see what is the difference.

     13: */

     15: static char help[] = "Solves a nonlinear ODE. \n\n";

     17: #include <petscts.h>
     18: #include <petscpc.h>

     20: extern PetscErrorCode RHSFunction(TS,PetscReal,Vec,Vec,void*);
     21: extern PetscErrorCode RHSJacobian(TS,PetscReal,Vec,Mat*,Mat*,MatStructure*,void*);
     22: extern PetscErrorCode Monitor(TS,PetscInt,PetscReal,Vec,void*);
     23: extern PetscErrorCode Initial(Vec,void*);

     25: extern PetscReal solx(PetscReal);
     26: extern PetscReal soly(PetscReal);
     27: extern PetscReal solz(PetscReal);

     31: int main(int argc,char **argv)
     32: {
     34:   PetscInt       time_steps = 100,steps;
     35:   PetscMPIInt    size;
     36:   Vec            global;
     37:   PetscReal      dt,ftime;
     38:   TS             ts;
     39:   MatStructure   A_structure;
     40:   Mat            A = 0;

     42:   PetscInitialize(&argc,&argv,(char*)0,help);
     43:   MPI_Comm_size(PETSC_COMM_WORLD,&size);

     45:   PetscOptionsGetInt(NULL,"-time",&time_steps,NULL);

     47:   /* set initial conditions */
     48:   VecCreate(PETSC_COMM_WORLD,&global);
     49:   VecSetSizes(global,PETSC_DECIDE,3);
     50:   VecSetFromOptions(global);
     51:   Initial(global,NULL);

     53:   /* make timestep context */
     54:   TSCreate(PETSC_COMM_WORLD,&ts);
     55:   TSSetProblemType(ts,TS_NONLINEAR);
     56:   TSMonitorSet(ts,Monitor,NULL,NULL);

     58:   dt = 0.1;

     60:   /*
     61:     The user provides the RHS and Jacobian
     62:   */
     63:   TSSetRHSFunction(ts,NULL,RHSFunction,NULL);
     64:   MatCreate(PETSC_COMM_WORLD,&A);
     65:   MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,3,3);
     66:   MatSetFromOptions(A);
     67:   MatSetUp(A);
     68:   RHSJacobian(ts,0.0,global,&A,&A,&A_structure,NULL);
     69:   TSSetRHSJacobian(ts,A,A,RHSJacobian,NULL);

     71:   TSSetFromOptions(ts);

     73:   TSSetInitialTimeStep(ts,0.0,dt);
     74:   TSSetDuration(ts,time_steps,1);
     75:   TSSetSolution(ts,global);

     77:   TSSolve(ts,global);
     78:   TSGetSolveTime(ts,&ftime);
     79:   TSGetTimeStepNumber(ts,&steps);

     82:   /* free the memories */

     84:   TSDestroy(&ts);
     85:   VecDestroy(&global);
     86:   MatDestroy(&A);

     88:   PetscFinalize();
     89:   return 0;
     90: }

     92: /* -------------------------------------------------------------------*/
     95: /* this test problem has initial values (1,1,1).                      */
     96: PetscErrorCode Initial(Vec global,void *ctx)
     97: {
     98:   PetscScalar    *localptr;
     99:   PetscInt       i,mybase,myend,locsize;

    102:   /* determine starting point of each processor */
    103:   VecGetOwnershipRange(global,&mybase,&myend);
    104:   VecGetLocalSize(global,&locsize);

    106:   /* Initialize the array */
    107:   VecGetArray(global,&localptr);
    108:   for (i=0; i<locsize; i++) localptr[i] = 1.0;

    110:   if (mybase == 0) localptr[0]=1.0;

    112:   VecRestoreArray(global,&localptr);
    113:   return 0;
    114: }

    118: PetscErrorCode Monitor(TS ts,PetscInt step,PetscReal time,Vec global,void *ctx)
    119: {
    120:   VecScatter     scatter;
    121:   IS             from,to;
    122:   PetscInt       i,n,*idx;
    123:   Vec            tmp_vec;
    125:   PetscScalar    *tmp;

    127:   /* Get the size of the vector */
    128:   VecGetSize(global,&n);

    130:   /* Set the index sets */
    131:   PetscMalloc(n*sizeof(PetscInt),&idx);
    132:   for (i=0; i<n; i++) idx[i]=i;

    134:   /* Create local sequential vectors */
    135:   VecCreateSeq(PETSC_COMM_SELF,n,&tmp_vec);

    137:   /* Create scatter context */
    138:   ISCreateGeneral(PETSC_COMM_SELF,n,idx,PETSC_COPY_VALUES,&from);
    139:   ISCreateGeneral(PETSC_COMM_SELF,n,idx,PETSC_COPY_VALUES,&to);
    140:   VecScatterCreate(global,from,tmp_vec,to,&scatter);
    141:   VecScatterBegin(scatter,global,tmp_vec,INSERT_VALUES,SCATTER_FORWARD);
    142:   VecScatterEnd(scatter,global,tmp_vec,INSERT_VALUES,SCATTER_FORWARD);

    144:   VecGetArray(tmp_vec,&tmp);
    145:   PetscPrintf(PETSC_COMM_WORLD,"At t =%14.6e u = %14.6e  %14.6e  %14.6e \n",
    146:                      time,PetscRealPart(tmp[0]),PetscRealPart(tmp[1]),PetscRealPart(tmp[2]));
    147:   PetscPrintf(PETSC_COMM_WORLD,"At t =%14.6e errors = %14.6e  %14.6e  %14.6e \n",
    148:                      time,PetscRealPart(tmp[0]-solx(time)),PetscRealPart(tmp[1]-soly(time)),PetscRealPart(tmp[2]-solz(time)));
    149:   VecRestoreArray(tmp_vec,&tmp);
    150:   VecScatterDestroy(&scatter);
    151:   ISDestroy(&from);
    152:   ISDestroy(&to);
    153:   PetscFree(idx);
    154:   VecDestroy(&tmp_vec);
    155:   return 0;
    156: }

    160: PetscErrorCode RHSFunction(TS ts,PetscReal t,Vec globalin,Vec globalout,void *ctx)
    161: {
    162:   PetscScalar    *inptr,*outptr;
    163:   PetscInt       i,n,*idx;
    165:   IS             from,to;
    166:   VecScatter     scatter;
    167:   Vec            tmp_in,tmp_out;

    169:   /* Get the length of parallel vector */
    170:   VecGetSize(globalin,&n);

    172:   /* Set the index sets */
    173:   PetscMalloc(n*sizeof(PetscInt),&idx);
    174:   for (i=0; i<n; i++) idx[i]=i;

    176:   /* Create local sequential vectors */
    177:   VecCreateSeq(PETSC_COMM_SELF,n,&tmp_in);
    178:   VecDuplicate(tmp_in,&tmp_out);

    180:   /* Create scatter context */
    181:   ISCreateGeneral(PETSC_COMM_SELF,n,idx,PETSC_COPY_VALUES,&from);
    182:   ISCreateGeneral(PETSC_COMM_SELF,n,idx,PETSC_COPY_VALUES,&to);
    183:   VecScatterCreate(globalin,from,tmp_in,to,&scatter);
    184:   VecScatterBegin(scatter,globalin,tmp_in,INSERT_VALUES,SCATTER_FORWARD);
    185:   VecScatterEnd(scatter,globalin,tmp_in,INSERT_VALUES,SCATTER_FORWARD);
    186:   VecScatterDestroy(&scatter);

    188:   /*Extract income array */
    189:   VecGetArray(tmp_in,&inptr);

    191:   /* Extract outcome array*/
    192:   VecGetArray(tmp_out,&outptr);

    194:   outptr[0] = 2.0*inptr[0]+inptr[1];
    195:   outptr[1] = inptr[0]+2.0*inptr[1]+inptr[2];
    196:   outptr[2] = inptr[1]+2.0*inptr[2];

    198:   VecRestoreArray(tmp_in,&inptr);
    199:   VecRestoreArray(tmp_out,&outptr);

    201:   VecScatterCreate(tmp_out,from,globalout,to,&scatter);
    202:   VecScatterBegin(scatter,tmp_out,globalout,INSERT_VALUES,SCATTER_FORWARD);
    203:   VecScatterEnd(scatter,tmp_out,globalout,INSERT_VALUES,SCATTER_FORWARD);

    205:   /* Destroy idx aand scatter */
    206:   ISDestroy(&from);
    207:   ISDestroy(&to);
    208:   VecScatterDestroy(&scatter);
    209:   VecDestroy(&tmp_in);
    210:   VecDestroy(&tmp_out);
    211:   PetscFree(idx);
    212:   return 0;
    213: }

    217: PetscErrorCode RHSJacobian(TS ts,PetscReal t,Vec x,Mat *AA,Mat *BB,MatStructure *str,void *ctx)
    218: {
    219:   Mat            A = *AA;
    220:   PetscScalar    v[3],*tmp;
    221:   PetscInt       idx[3],i;

    224:   *str = SAME_NONZERO_PATTERN;

    226:   idx[0]=0; idx[1]=1; idx[2]=2;
    227:   VecGetArray(x,&tmp);

    229:   i    = 0;
    230:   v[0] = 2.0; v[1] = 1.0; v[2] = 0.0;
    231:   MatSetValues(A,1,&i,3,idx,v,INSERT_VALUES);

    233:   i    = 1;
    234:   v[0] = 1.0; v[1] = 2.0; v[2] = 1.0;
    235:   MatSetValues(A,1,&i,3,idx,v,INSERT_VALUES);

    237:   i    = 2;
    238:   v[0] = 0.0; v[1] = 1.0; v[2] = 2.0;
    239:   MatSetValues(A,1,&i,3,idx,v,INSERT_VALUES);

    241:   MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
    242:   MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);

    244:   VecRestoreArray(x,&tmp);

    246:   return 0;
    247: }

    249: /*
    250:       The exact solutions
    251: */
    252: PetscReal solx(PetscReal t)
    253: {
    254:   return exp((2.0 - PetscSqrtReal(2.0))*t)/2.0 - exp((2.0 - PetscSqrtReal(2.0))*t)/(2.0*PetscSqrtReal(2.0)) +
    255:          exp((2.0 + PetscSqrtReal(2.0))*t)/2.0 + exp((2.0 + PetscSqrtReal(2.0))*t)/(2.0*PetscSqrtReal(2.0));
    256: }

    258: PetscReal soly(PetscReal t)
    259: {
    260:   return exp((2.0 - PetscSqrtReal(2.0))*t)/2.0 - exp((2.0 - PetscSqrtReal(2.0))*t)/PetscSqrtReal(2.0) +
    261:          exp((2.0 + PetscSqrtReal(2.0))*t)/2.0 + exp((2.0 + PetscSqrtReal(2.0))*t)/PetscSqrtReal(2.0);
    262: }

    264: PetscReal solz(PetscReal t)
    265: {
    266:   return exp((2.0 - PetscSqrtReal(2.0))*t)/2.0 - exp((2.0 - PetscSqrtReal(2.0))*t)/(2.0*PetscSqrtReal(2.0)) +
    267:          exp((2.0 + PetscSqrtReal(2.0))*t)/2.0 + exp((2.0 + PetscSqrtReal(2.0))*t)/(2.0*PetscSqrtReal(2.0));
    268: }