xref: /petsc/src/ksp/pc/tests/ex10.c (revision e91c04dfc8a52dee1965211bb1cc8e5bf775178f)
1 #include <petscksp.h>
2 #include <petscpc.h>
3 #include <petscviewer.h>
4 
5 typedef struct {
6   PetscInt  num_levels;
7   PetscInt *n_per_level;
8   Mat       stiff;
9   Mat      *ProlongationOps;
10   PetscBT  *CFMarkers;
11   KSP       kspHypre;
12 } *DataCompression;
13 
14 PetscErrorCode Create1dLaplacian(PetscInt, Mat *);
15 PetscErrorCode DataCompExportMats(DataCompression);
16 PetscErrorCode DataCompDestroy(DataCompression);
17 
18 int main(int Argc, char **Args)
19 {
20   PetscInt        n_nodes = 33;
21   Vec             x, b;
22   PC              pcHypre;
23   DataCompression data_comp;
24 
25   PetscFunctionBeginUser;
26   PetscCall(PetscInitialize(&Argc, &Args, NULL, NULL));
27 
28   PetscCall(PetscNew(&data_comp));
29 
30   // Creating stiffness matrix
31   PetscCall(Create1dLaplacian(n_nodes, &data_comp->stiff));
32   PetscCall(PetscObjectSetName((PetscObject)data_comp->stiff, "Stiffness"));
33 
34   // Set-up BoomerAMG PC to get Prolongation Operators and Coarse/Fine splittings
35   PetscCall(KSPCreate(PETSC_COMM_WORLD, &data_comp->kspHypre));
36   PetscCall(KSPSetType(data_comp->kspHypre, KSPRICHARDSON));
37   PetscCall(KSPGetPC(data_comp->kspHypre, &pcHypre));
38   PetscCall(PCSetType(pcHypre, PCHYPRE));
39   PetscCall(PCHYPRESetType(pcHypre, "boomeramg"));
40   PetscCall(PCSetFromOptions(pcHypre));
41   PetscCall(PCSetOperators(pcHypre, data_comp->stiff, data_comp->stiff));
42   PetscCall(PCSetUp(pcHypre));
43 
44   PetscCall(MatCreateVecs(data_comp->stiff, &x, &b));
45   PetscCall(PCApply(pcHypre, x, b));
46   PetscCall(VecDestroy(&x));
47   PetscCall(VecDestroy(&b));
48 
49   //Viewing the PC and Extracting the Prolongation Operators and CFMarkers
50   PetscCall(PCView(pcHypre, NULL));
51   PetscCall(PCGetInterpolations(pcHypre, &data_comp->num_levels, &data_comp->ProlongationOps));
52   PetscCall(PCHYPREGetCFMarkers(pcHypre, &data_comp->n_per_level, &data_comp->CFMarkers));
53 
54   PetscCall(DataCompExportMats(data_comp));
55   PetscCall(DataCompDestroy(data_comp));
56   PetscCall(PetscFinalize());
57   return 0;
58 }
59 
60 PetscErrorCode Create1dLaplacian(PetscInt n, Mat *mat)
61 {
62   PetscFunctionBeginUser;
63   PetscCall(MatCreateSeqAIJ(PETSC_COMM_SELF, n, n, 3, NULL, mat));
64   PetscCall(MatSetValue(*mat, n - 1, n - 1, 2.0, INSERT_VALUES));
65   for (PetscInt i = 0; i < n - 1; i++) {
66     PetscCall(MatSetValue(*mat, i, i, 2.0, INSERT_VALUES));
67     PetscCall(MatSetValue(*mat, i + 1, i, -1.0, INSERT_VALUES));
68     PetscCall(MatSetValue(*mat, i, i + 1, -1.0, INSERT_VALUES));
69   }
70   PetscCall(MatAssemblyBegin(*mat, MAT_FINAL_ASSEMBLY));
71   PetscCall(MatAssemblyEnd(*mat, MAT_FINAL_ASSEMBLY));
72   PetscFunctionReturn(PETSC_SUCCESS);
73 }
74 
75 PetscErrorCode DataCompExportMats(DataCompression data_comp)
76 {
77   PetscFunctionBeginUser;
78   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Num levels: %" PetscInt_FMT "\n", data_comp->num_levels));
79   PetscCall(PetscPrintf(PETSC_COMM_WORLD, " -- Nodes per level --\n"));
80   for (PetscInt i = 0; i < data_comp->num_levels; i++) { PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Level %" PetscInt_FMT ": %" PetscInt_FMT "\n", i, data_comp->n_per_level[i])); }
81 
82   for (PetscInt i = 0; i < data_comp->num_levels - 1; i++) {
83     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Prolongation Operator - Level %" PetscInt_FMT "\n", i));
84     PetscCall(PetscObjectSetName((PetscObject)data_comp->ProlongationOps[i], "P"));
85     PetscCall(MatView(data_comp->ProlongationOps[i], PETSC_VIEWER_STDOUT_WORLD));
86     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "\n"));
87   }
88 
89   for (PetscInt i = 0; i < data_comp->num_levels - 1; i++) {
90     PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Coarse/Fine splitting - Level %" PetscInt_FMT "\n", i + 1));
91     PetscCall(PetscBTView(data_comp->n_per_level[i + 1], data_comp->CFMarkers[i], PETSC_VIEWER_STDOUT_WORLD));
92   }
93   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Stiffness matrix, sparse format:\n"));
94   PetscCall(MatViewFromOptions(data_comp->stiff, NULL, "-mat_view_stiff"));
95   PetscCall(PetscPrintf(PETSC_COMM_WORLD, "Finished calling the Viewer functions\n"));
96   PetscFunctionReturn(PETSC_SUCCESS);
97 }
98 
99 PetscErrorCode DataCompDestroy(DataCompression data_comp)
100 {
101   PetscFunctionBeginUser;
102   if (data_comp == NULL) PetscFunctionReturn(PETSC_SUCCESS);
103   PetscCall(MatDestroy(&data_comp->stiff));
104   PetscCall(KSPDestroy(&data_comp->kspHypre));
105   for (PetscInt i = 0; i < data_comp->num_levels - 1; i++) {
106     PetscCall(MatDestroy(&data_comp->ProlongationOps[i]));
107     PetscCall(PetscBTDestroy(&data_comp->CFMarkers[i]));
108   }
109   PetscCall(PetscFree(data_comp->ProlongationOps));
110   PetscCall(PetscFree(data_comp->n_per_level));
111   PetscCall(PetscFree(data_comp->CFMarkers));
112   PetscCall(PetscFree(data_comp));
113   PetscFunctionReturn(PETSC_SUCCESS);
114 }
115 
116 /*TEST
117 
118    test:
119       requires: hypre !complex !defined(PETSC_HAVE_HYPRE_DEVICE)
120       args: -pc_hypre_boomeramg_coarsen_type modifiedRuge-Stueben -pc_hypre_boomeramg_interp_type classical -pc_hypre_boomeramg_strong_threshold 0.25 pc_hypre_boomeramg_numfunctions 1 -pc_hypre_boomeramg_max_row_sum 1.0 -mat_view_stiff
121 
122 TEST*/
123