Actual source code: ex37.c
slepc-3.9.1 2018-05-02
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: }