Actual source code: ex37.c

slepc-3.9.1 2018-05-02
Report Typos and Errors
  1: /*
  2:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  3:    SLEPc - Scalable Library for Eigenvalue Problem Computations
  4:    Copyright (c) 2002-2018, Universitat Politecnica de Valencia, Spain

  6:    This file is part of SLEPc.
  7:    SLEPc is distributed under a 2-clause BSD license (see LICENSE).
  8:    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  9: */

 11: static char help[] = "Computes exp(t*A)*v for an advection diffusion operator with Peclet number.\n\n"
 12:   "The command line options are:\n"
 13:   "  -n <idim>, where <idim> = dimension of the advection diffusion operator. dim^2.\n"
 14:   "  -t <sval>, where <sval> = scalar value that multiplies the argument.\n"
 15:   "  -peclet <sval>, where <sval> = Peclet value.\n"
 16:   "  -steps <ival>, where <ival> = vectors computed.\n\n";

 18: #include <slepcmfn.h>

 20: int main(int argc,char **argv)
 21: {
 22:   Mat                A;           /* problem matrix */
 23:   MFN                mfn;
 24:   FN                 f;
 25:   PetscInt           i,j,Istart,Iend,II,m,n=10,N,steps=5,its,totits=0,ncv,maxit;
 26:   PetscReal          tol,norm,h,h2,peclet=0.5,epsilon=1.0,c;
 27:   PetscScalar        t=1e-4,sone=1.0,value,upper,diag,lower;
 28:   Vec                v;
 29:   PetscErrorCode     ierr;
 30:   PetscBool          flg;
 31:   MFNConvergedReason reason;

 33:   SlepcInitialize(&argc,&argv,(char*)0,help);if (ierr) return ierr;

 35:   PetscOptionsGetScalar(NULL,NULL,"-t",&t,&flg);
 36:   PetscOptionsGetReal(NULL,NULL,"-peclet",&peclet,&flg);
 37:   PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);
 38:   PetscOptionsGetInt(NULL,NULL,"-steps",&steps,NULL);
 39:   m = n;
 40:   N = m*n;
 41:   /* interval [0,1], homogeneous Dirichlet boundary conditions */
 42:   h = 1.0/(n+1.0);
 43:   h2 = h*h;
 44:   c = 2.0*epsilon*peclet/h;
 45:   upper = (epsilon/h2)+(c/(2.0*h));
 46:   diag = 2.0*(-2.0*epsilon/h2);
 47:   lower = (epsilon/h2)-(c/(2.0*h));

 49:   PetscPrintf(PETSC_COMM_WORLD,"\nMatrix exponential y=exp(k*A)\n\n");
 50:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 51:                 Generate matrix A
 52:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 53:   MatCreate(PETSC_COMM_WORLD,&A);
 54:   MatSetSizes(A,PETSC_DECIDE,PETSC_DECIDE,N,N);
 55:   MatSetFromOptions(A);
 56:   MatSetUp(A);
 57:   MatGetOwnershipRange(A,&Istart,&Iend);
 58:   for (II=Istart;II<Iend;II++) {
 59:     i = II/n; j = II-i*n;
 60:     if (i>0) { MatSetValue(A,II,II-n,lower,INSERT_VALUES); }
 61:     if (i<m-1) { MatSetValue(A,II,II+n,upper,INSERT_VALUES); }
 62:     if (j>0) { MatSetValue(A,II,II-1,lower,INSERT_VALUES); }
 63:     if (j<n-1) { MatSetValue(A,II,II+1,upper,INSERT_VALUES); }
 64:     MatSetValue(A,II,II,diag,INSERT_VALUES);
 65:   }
 66:   MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
 67:   MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
 68:   MatCreateVecs(A,NULL,&v);

 70:   /*
 71:      Set initial vector v = 256*i^2*(1-i)^2*j^2*(1-j)^2
 72:   */
 73:   for (II=Istart;II<Iend;II++) {
 74:     i = II/n; j = II-i*n;
 75:     value = 256.0*(((i+1)*h)*((i+1)*h))*((1.0-((i+1)*h))*(1.0-((i+1)*h)))*(((j+1)*h)*((j+1)*h))*((1.0-((j+1)*h))*(1.0-((j+1)*h)));
 76:     VecSetValue(v,i+j*n,value,INSERT_VALUES);
 77:   }
 78:   VecAssemblyBegin(v);
 79:   VecAssemblyEnd(v);

 81:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 82:                 Create the solver and set various options
 83:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 84:   MFNCreate(PETSC_COMM_WORLD,&mfn);
 85:   MFNSetOperator(mfn,A);
 86:   MFNGetFN(mfn,&f);
 87:   FNSetType(f,FNEXP);
 88:   FNSetScale(f,t,sone);
 89:   MFNSetFromOptions(mfn);

 91:   /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 92:                       Solve the problem, y=exp(k*A)*v
 93:      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
 94:   for(i=0;i<steps;i++) {
 95:     MFNSolve(mfn,v,v);
 96:     MFNGetConvergedReason(mfn,&reason);
 97:     if (reason<0) SETERRQ(PETSC_COMM_WORLD,1,"Solver did not converge");
 98:     MFNGetIterationNumber(mfn,&its);
 99:     totits += its;
100:   }

102:   /*
103:      Optional: Get some information from the solver and display it
104:   */
105:   PetscPrintf(PETSC_COMM_WORLD," Number of iterations of the method: %D\n",totits);
106:   MFNGetDimensions(mfn,&ncv);
107:   PetscPrintf(PETSC_COMM_WORLD," Subspace dimension: %D\n",ncv);
108:   MFNGetTolerances(mfn,&tol,&maxit);
109:   PetscPrintf(PETSC_COMM_WORLD," Stopping condition: tol=%.4g, maxit=%D\n",(double)tol,maxit);
110:   VecNorm(v,NORM_2,&norm);
111:   PetscPrintf(PETSC_COMM_WORLD," Computed vector at time t=%.4g has norm %g\n",(double)PetscRealPart(t)*steps,(double)norm);

113:   /*
114:      Free work space
115:   */
116:   MFNDestroy(&mfn);
117:   MatDestroy(&A);
118:   VecDestroy(&v);
119:   SlepcFinalize();
120:   return ierr;
121: }