Actual source code: ex88.c
petsc-3.10.2 2018-10-09
2: static char help[] = "Tests MatShift(), MatScale(), and MatDiagonalScale() for SHELL and NEST matrices\n\n";
4: #include <petscmat.h>
6: typedef struct _n_User *User;
7: struct _n_User {
8: Mat B;
9: };
11: static PetscErrorCode MatView_User(Mat A,PetscViewer viewer)
12: {
13: User user;
17: MatShellGetContext(A,&user);
18: MatView(user->B,viewer);
19: return(0);
20: }
22: static PetscErrorCode MatMult_User(Mat A,Vec X,Vec Y)
23: {
24: User user;
28: MatShellGetContext(A,&user);
29: MatMult(user->B,X,Y);
30: return(0);
31: }
33: static PetscErrorCode MatMultTranspose_User(Mat A,Vec X,Vec Y)
34: {
35: User user;
39: MatShellGetContext(A,&user);
40: MatMultTranspose(user->B,X,Y);
41: return(0);
42: }
44: static PetscErrorCode MatGetDiagonal_User(Mat A,Vec X)
45: {
46: User user;
50: MatShellGetContext(A,&user);
51: MatGetDiagonal(user->B,X);
52: return(0);
53: }
55: static PetscErrorCode TestMatrix(Mat A,Vec X,Vec Y,Vec Z)
56: {
58: Vec W1,W2,diff;
59: Mat E;
60: const char *mattypename;
61: PetscViewer viewer = PETSC_VIEWER_STDOUT_WORLD;
62: PetscScalar diag[2] = {2.9678190300000000e+08,1.4173141580000000e+09};
63: PetscReal nrm,norm1,norminf;
66: VecDuplicate(X,&W1);
67: VecDuplicate(X,&W2);
68: MatScale(A,31);
69: MatShift(A,37);
70: MatDiagonalScale(A,X,Y);
71: MatScale(A,41);
72: MatDiagonalScale(A,Y,Z);
73: MatComputeExplicitOperator(A,&E);
75: PetscObjectGetType((PetscObject)A,&mattypename);
76: PetscViewerASCIIPrintf(viewer,"Matrix of type: %s\n",mattypename);
77: MatView(E,viewer);
78: MatMult(A,Z,W1);
79: MatMultTranspose(A,W1,W2);
80: VecView(W2,viewer);
81: MatGetDiagonal(A,W2);
82: VecCreateSeqWithArray(PETSC_COMM_SELF,1,2,diag,&diff);
83: VecAXPY(diff,-1.0,W2);
84: VecNorm(diff,NORM_2,&nrm);
85: if (nrm > PETSC_SMALL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"MatGetDiagonal() produces incorrect result");
86: VecDestroy(&diff);
87: VecView(W2,viewer);
88: MatNorm(A,NORM_1,&norm1);
89: MatNorm(A,NORM_INFINITY,&norminf);
90: PetscViewerASCIIPrintf(viewer,"Norm_1: %g, Norm_infty %g\n",(double)norm1,(double)norminf);
91: /* MATSHELL does not support MatDiagonalSet after MatScale */
92: if (strncmp(mattypename, "shell", 5)) {
93: MatDiagonalSet(A,X,INSERT_VALUES);
94: MatGetDiagonal(A,W1);
95: VecView(W1,viewer);
96: } else {
97: PetscViewerASCIIPrintf(viewer,"MatDiagonalSet not tested on MATSHELL\n");
98: }
99: MatDestroy(&E);
100: VecDestroy(&W1);
101: VecDestroy(&W2);
102: return(0);
103: }
105: int main(int argc,char **args)
106: {
107: const PetscScalar xvals[] = {11,13},yvals[] = {17,19},zvals[] = {23,29};
108: const PetscInt inds[] = {0,1};
109: PetscScalar avals[] = {2,3,5,7};
110: Mat A,S,D[4],N;
111: Vec X,Y,Z;
112: User user;
113: PetscInt i;
114: PetscErrorCode ierr;
116: PetscInitialize(&argc,&args,(char*)0,help);if (ierr) return ierr;
117: MatCreateSeqAIJ(PETSC_COMM_WORLD,2,2,2,NULL,&A);
118: MatSetUp(A);
119: MatSetValues(A,2,inds,2,inds,avals,INSERT_VALUES);
120: VecCreateSeq(PETSC_COMM_WORLD,2,&X);
121: VecDuplicate(X,&Y);
122: VecDuplicate(X,&Z);
123: VecSetValues(X,2,inds,xvals,INSERT_VALUES);
124: VecSetValues(Y,2,inds,yvals,INSERT_VALUES);
125: VecSetValues(Z,2,inds,zvals,INSERT_VALUES);
126: MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY);
127: MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY);
128: VecAssemblyBegin(X);
129: VecAssemblyBegin(Y);
130: VecAssemblyBegin(Z);
131: VecAssemblyEnd(X);
132: VecAssemblyEnd(Y);
133: VecAssemblyEnd(Z);
135: PetscNew(&user);
136: user->B = A;
138: MatCreateShell(PETSC_COMM_WORLD,2,2,2,2,user,&S);
139: MatSetUp(S);
140: MatShellSetOperation(S,MATOP_VIEW,(void (*)(void))MatView_User);
141: MatShellSetOperation(S,MATOP_MULT,(void (*)(void))MatMult_User);
142: MatShellSetOperation(S,MATOP_MULT_TRANSPOSE,(void (*)(void))MatMultTranspose_User);
143: MatShellSetOperation(S,MATOP_GET_DIAGONAL,(void (*)(void))MatGetDiagonal_User);
145: for (i=0; i<4; i++) {
146: MatCreateSeqDense(PETSC_COMM_WORLD,1,1,&avals[i],&D[i]);
147: }
148: MatCreateNest(PETSC_COMM_WORLD,2,NULL,2,NULL,D,&N);
149: MatSetUp(N);
151: TestMatrix(S,X,Y,Z);
152: TestMatrix(A,X,Y,Z);
153: TestMatrix(N,X,Y,Z);
155: for (i=0; i<4; i++) {MatDestroy(&D[i]);}
156: MatDestroy(&A);
157: MatDestroy(&S);
158: MatDestroy(&N);
159: VecDestroy(&X);
160: VecDestroy(&Y);
161: VecDestroy(&Z);
162: PetscFree(user);
163: PetscFinalize();
164: return ierr;
165: }
168: /*TEST
170: test:
172: TEST*/