1 #include <petsc.h>
2 
3 static char help[] = "Solves a linear system with a block of right-hand sides, apply a preconditioner to the same block.\n\n";
4 
MatApply(PC pc,Mat X,Mat Y)5 PetscErrorCode MatApply(PC pc, Mat X, Mat Y)
6 {
7   PetscErrorCode ierr;
8 
9   PetscFunctionBeginUser;
10   ierr = MatCopy(X,Y,SAME_NONZERO_PATTERN);CHKERRQ(ierr);
11   PetscFunctionReturn(0);
12 }
13 
main(int argc,char ** args)14 int main(int argc,char **args)
15 {
16   Mat                X,B;         /* computed solutions and RHS */
17   Mat                A;           /* linear system matrix */
18   KSP                ksp;         /* linear solver context */
19   PC                 pc;          /* preconditioner context */
20   PetscInt           m = 10;
21 #if defined(PETSC_USE_LOG)
22   PetscLogEvent      event;
23 #endif
24   PetscEventPerfInfo info;
25   PetscErrorCode     ierr;
26 
27   ierr = PetscInitialize(&argc,&args,NULL,help);if (ierr) return ierr;
28   ierr = PetscLogDefaultBegin();CHKERRQ(ierr);
29   ierr = PetscOptionsGetInt(NULL,NULL,"-m",&m,NULL);CHKERRQ(ierr);
30   ierr = MatCreateAIJ(PETSC_COMM_WORLD,m,m,PETSC_DECIDE,PETSC_DECIDE,m,NULL,m,NULL,&A);CHKERRQ(ierr);
31   ierr = MatCreateDense(PETSC_COMM_WORLD,m,PETSC_DECIDE,PETSC_DECIDE,m,NULL,&B);CHKERRQ(ierr);
32   ierr = MatCreateDense(PETSC_COMM_WORLD,m,PETSC_DECIDE,PETSC_DECIDE,m,NULL,&X);CHKERRQ(ierr);
33   ierr = MatSetRandom(A,NULL);CHKERRQ(ierr);
34   ierr = MatSetOption(A,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr);
35   ierr = MatShift(A,10.0);CHKERRQ(ierr);
36   ierr = MatSetRandom(B,NULL);CHKERRQ(ierr);
37   ierr = KSPCreate(PETSC_COMM_WORLD,&ksp);CHKERRQ(ierr);
38   ierr = KSPSetOperators(ksp,A,A);CHKERRQ(ierr);
39   ierr = KSPSetFromOptions(ksp);CHKERRQ(ierr);
40   ierr = KSPGetPC(ksp,&pc);CHKERRQ(ierr);
41   ierr = PCShellSetMatApply(pc,MatApply);CHKERRQ(ierr);
42   ierr = KSPMatSolve(ksp,B,X);CHKERRQ(ierr);
43   ierr = PCMatApply(pc,B,X);CHKERRQ(ierr);
44   ierr = MatDestroy(&X);CHKERRQ(ierr);
45   ierr = MatDestroy(&B);CHKERRQ(ierr);
46   ierr = MatDestroy(&A);CHKERRQ(ierr);
47   ierr = KSPDestroy(&ksp);CHKERRQ(ierr);
48   ierr = PetscLogEventRegister("PCApply",PC_CLASSID,&event);CHKERRQ(ierr);
49   ierr = PetscLogEventGetPerfInfo(PETSC_DETERMINE,event,&info);
50   if (PetscDefined(USE_LOG) && m > 1 && info.count) SETERRQ1(PetscObjectComm((PetscObject)ksp),PETSC_ERR_PLIB,"PCApply() called %d times",info.count);
51   ierr = PetscLogEventRegister("PCMatApply",PC_CLASSID,&event);CHKERRQ(ierr);
52   ierr = PetscLogEventGetPerfInfo(PETSC_DETERMINE,event,&info);
53   if (PetscDefined(USE_LOG) && m > 1 && !info.count) SETERRQ(PetscObjectComm((PetscObject)ksp),PETSC_ERR_PLIB,"PCMatApply() never called");
54   ierr = PetscFinalize();
55   return ierr;
56 }
57 
58 /*TEST
59    # KSPHPDDM does either pseudo-blocking or "true" blocking, all tests should succeed with other -ksp_hpddm_type
60    testset:
61       nsize: 1
62       args: -pc_type {{bjacobi lu ilu mat cholesky icc none shell asm gasm}shared output}
63       test:
64          suffix: 1
65          output_file: output/ex77_preonly.out
66          args: -ksp_type preonly
67       test:
68          suffix: 1_hpddm
69          output_file: output/ex77_preonly.out
70          requires: hpddm
71          args: -ksp_type hpddm -ksp_hpddm_type preonly
72 
73    testset:
74       nsize: 1
75       args: -pc_type ksp
76       test:
77          suffix: 2
78          output_file: output/ex77_preonly.out
79          args: -ksp_ksp_type preonly -ksp_type preonly
80       test:
81          suffix: 2_hpddm
82          output_file: output/ex77_preonly.out
83          requires: hpddm
84          args: -ksp_ksp_type hpddm -ksp_type hpddm -ksp_hpddm_type preonly -ksp_ksp_hpddm_type preonly
85 
86    testset:
87       nsize: 1
88       requires: hara
89       args: -pc_type hara
90       test:
91          suffix: 3
92          output_file: output/ex77_preonly.out
93          args: -ksp_type preonly
94       test:
95          suffix: 3_hpddm
96          output_file: output/ex77_preonly.out
97          requires: hpddm
98          args: -ksp_type hpddm -ksp_hpddm_type preonly
99 
100    testset:
101       nsize: 1
102       requires: spai
103       args: -pc_type spai
104       test:
105          suffix: 4
106          output_file: output/ex77_preonly.out
107          args: -ksp_type preonly
108       test:
109          suffix: 4_hpddm
110          output_file: output/ex77_preonly.out
111          requires: hpddm
112          args: -ksp_type hpddm -ksp_hpddm_type preonly
113    # special code path in PCApplyMat() for PCBJACOBI when a block is shared by multiple processes
114    testset:
115       nsize: 2
116       args: -pc_type bjacobi -pc_bjacobi_blocks 1 -sub_pc_type none
117       test:
118          suffix: 5
119          output_file: output/ex77_preonly.out
120          args: -ksp_type preonly -sub_ksp_type preonly
121       test:
122          suffix: 5_hpddm
123          output_file: output/ex77_preonly.out
124          requires: hpddm
125          args: -ksp_type hpddm -ksp_hpddm_type preonly -sub_ksp_type hpddm
126    # special code path in PCApplyMat() for PCGASM when a block is shared by multiple processes
127    testset:
128       nsize: 2
129       args: -pc_type gasm -pc_gasm_total_subdomains 1 -sub_pc_type none
130       test:
131          suffix: 6
132          output_file: output/ex77_preonly.out
133          args: -ksp_type preonly -sub_ksp_type preonly
134       test:
135          suffix: 6_hpddm
136          output_file: output/ex77_preonly.out
137          requires: hpddm
138          args: -ksp_type hpddm -ksp_hpddm_type preonly -sub_ksp_type hpddm
139 
140 
141 TEST*/
142