Actual source code: test10.c
slepc-3.17.1 2022-04-11
1: /*
2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3: SLEPc - Scalable Library for Eigenvalue Problem Computations
4: Copyright (c) 2002-, 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[] = "Test Phi functions.\n\n";
13: #include <slepcfn.h>
15: /*
16: Evaluates phi_k function on a scalar and on a matrix
17: */
18: PetscErrorCode TestPhiFunction(FN fn,PetscScalar x,Mat A,PetscBool verbose)
19: {
20: PetscScalar y,yp;
21: char strx[50],str[50];
22: Vec v,f;
23: PetscReal nrm;
26: PetscPrintf(PETSC_COMM_WORLD,"\n");
27: FNView(fn,NULL);
28: SlepcSNPrintfScalar(strx,sizeof(strx),x,PETSC_FALSE);
29: FNEvaluateFunction(fn,x,&y);
30: FNEvaluateDerivative(fn,x,&yp);
31: SlepcSNPrintfScalar(str,sizeof(str),y,PETSC_FALSE);
32: PetscPrintf(PETSC_COMM_WORLD,"\nf(%s)=%s\n",strx,str);
33: SlepcSNPrintfScalar(str,sizeof(str),yp,PETSC_FALSE);
34: PetscPrintf(PETSC_COMM_WORLD,"f'(%s)=%s\n",strx,str);
35: /* compute phi_k(A)*e_1 */
36: MatCreateVecs(A,&v,&f);
37: MatSetOption(A,MAT_HERMITIAN,PETSC_TRUE);
38: FNEvaluateFunctionMatVec(fn,A,f); /* reference result by diagonalization */
39: MatSetOption(A,MAT_HERMITIAN,PETSC_FALSE);
40: FNEvaluateFunctionMatVec(fn,A,v);
41: VecAXPY(v,-1.0,f);
42: VecNorm(v,NORM_2,&nrm);
43: if (nrm>100*PETSC_MACHINE_EPSILON) PetscPrintf(PETSC_COMM_WORLD,"Warning: the norm of f(A)*e_1-ref is %g\n",(double)nrm);
44: if (verbose) {
45: PetscPrintf(PETSC_COMM_WORLD,"f(A)*e_1 =\n");
46: VecView(v,NULL);
47: }
48: VecDestroy(&v);
49: VecDestroy(&f);
50: PetscFunctionReturn(0);
51: }
53: int main(int argc,char **argv)
54: {
55: FN phi0,phi1,phik,phicopy;
56: Mat A;
57: PetscInt i,j,n=8,k;
58: PetscScalar tau,eta,*As;
59: PetscBool verbose;
61: SlepcInitialize(&argc,&argv,(char*)0,help);
62: PetscOptionsGetInt(NULL,NULL,"-n",&n,NULL);
63: PetscOptionsHasName(NULL,NULL,"-verbose",&verbose);
64: PetscPrintf(PETSC_COMM_WORLD,"Test Phi functions, n=%" PetscInt_FMT ".\n",n);
66: /* Create matrix, fill it with 1-D Laplacian */
67: MatCreateSeqDense(PETSC_COMM_SELF,n,n,NULL,&A);
68: PetscObjectSetName((PetscObject)A,"A");
69: MatDenseGetArray(A,&As);
70: for (i=0;i<n;i++) As[i+i*n]=2.0;
71: j=1;
72: for (i=0;i<n-j;i++) { As[i+(i+j)*n]=-1.0; As[(i+j)+i*n]=-1.0; }
73: MatDenseRestoreArray(A,&As);
75: /* phi_0(x) = exp(x) */
76: FNCreate(PETSC_COMM_WORLD,&phi0);
77: FNSetType(phi0,FNPHI);
78: FNPhiSetIndex(phi0,0);
79: TestPhiFunction(phi0,2.2,A,verbose);
81: /* phi_1(x) = (exp(x)-1)/x with scaling factors eta*phi_1(tau*x) */
82: FNCreate(PETSC_COMM_WORLD,&phi1);
83: FNSetType(phi1,FNPHI); /* default index should be 1 */
84: tau = 0.2;
85: eta = 1.3;
86: FNSetScale(phi1,tau,eta);
87: TestPhiFunction(phi1,2.2,A,verbose);
89: /* phi_k(x) with index set from command-line arguments */
90: FNCreate(PETSC_COMM_WORLD,&phik);
91: FNSetType(phik,FNPHI);
92: FNSetFromOptions(phik);
94: FNDuplicate(phik,PETSC_COMM_WORLD,&phicopy);
95: FNPhiGetIndex(phicopy,&k);
96: PetscPrintf(PETSC_COMM_WORLD,"Index of phi function is %" PetscInt_FMT "\n",k);
97: TestPhiFunction(phicopy,2.2,A,verbose);
99: FNDestroy(&phi0);
100: FNDestroy(&phi1);
101: FNDestroy(&phik);
102: FNDestroy(&phicopy);
103: MatDestroy(&A);
104: SlepcFinalize();
105: return 0;
106: }
108: /*TEST
110: test:
111: suffix: 1
112: nsize: 1
113: args: -fn_phi_index 3
115: TEST*/