Actual source code: ex80.c
1: static char help[] = "Test the Fischer-3 initial guess routine.\n\n";
3: #include <petscksp.h>
5: #define SIZE 3
7: int main(int argc, char **args)
8: {
9: {
10: Mat A;
11: PetscInt indices[SIZE] = {0, 1, 2};
12: PetscScalar values[SIZE] = {1.0, 1.0, 1.0};
13: Vec sol, rhs, newsol, newrhs;
15: PetscFunctionBeginUser;
16: PetscCall(PetscInitialize(&argc, &args, NULL, help));
18: /* common data structures */
19: PetscCall(MatCreateSeqDense(PETSC_COMM_SELF, SIZE, SIZE, NULL, &A));
20: for (PetscInt i = 0; i < SIZE; ++i) PetscCall(MatSetValue(A, i, i, 1.0, INSERT_VALUES));
21: PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
22: PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
24: PetscCall(VecCreateSeq(PETSC_COMM_SELF, SIZE, &sol));
25: PetscCall(VecDuplicate(sol, &rhs));
26: PetscCall(VecDuplicate(sol, &newrhs));
27: PetscCall(VecDuplicate(sol, &newsol));
29: PetscCall(VecSetValues(sol, SIZE, indices, values, INSERT_VALUES));
30: PetscCall(VecSetValues(rhs, SIZE - 1, indices, values, INSERT_VALUES));
31: PetscCall(VecSetValues(newrhs, SIZE - 2, indices, values, INSERT_VALUES));
32: PetscCall(VecAssemblyBegin(sol));
33: PetscCall(VecAssemblyBegin(rhs));
34: PetscCall(VecAssemblyBegin(newrhs));
35: PetscCall(VecAssemblyEnd(sol));
36: PetscCall(VecAssemblyEnd(rhs));
37: PetscCall(VecAssemblyEnd(newrhs));
39: /* Test one vector */
40: {
41: KSP ksp;
42: KSPGuess guess;
44: PetscCall(KSPCreate(PETSC_COMM_SELF, &ksp));
45: PetscCall(KSPSetOperators(ksp, A, A));
46: PetscCall(KSPSetFromOptions(ksp));
47: PetscCall(KSPGetGuess(ksp, &guess));
48: /* we aren't calling through the KSP so we call this ourselves */
49: PetscCall(KSPGuessSetUp(guess));
51: PetscCall(KSPGuessUpdate(guess, rhs, sol));
52: PetscCall(KSPGuessFormGuess(guess, newrhs, newsol));
53: PetscCall(VecView(newsol, PETSC_VIEWER_STDOUT_SELF));
55: PetscCall(KSPDestroy(&ksp));
56: }
58: /* Test a singular projection matrix */
59: {
60: KSP ksp;
61: KSPGuess guess;
63: PetscCall(KSPCreate(PETSC_COMM_SELF, &ksp));
64: PetscCall(KSPSetOperators(ksp, A, A));
65: PetscCall(KSPSetFromOptions(ksp));
66: PetscCall(KSPGetGuess(ksp, &guess));
67: PetscCall(KSPGuessSetUp(guess));
69: for (PetscInt i = 0; i < 15; ++i) PetscCall(KSPGuessUpdate(guess, rhs, sol));
70: PetscCall(KSPGuessFormGuess(guess, newrhs, newsol));
71: PetscCall(VecView(newsol, PETSC_VIEWER_STDOUT_SELF));
73: PetscCall(KSPDestroy(&ksp));
74: }
75: PetscCall(VecDestroy(&newsol));
76: PetscCall(VecDestroy(&newrhs));
77: PetscCall(VecDestroy(&rhs));
78: PetscCall(VecDestroy(&sol));
80: PetscCall(MatDestroy(&A));
81: }
83: /* Test something triangular */
84: {
85: PetscInt triangle_size = 10;
86: Mat A;
88: PetscCall(MatCreateSeqDense(PETSC_COMM_SELF, triangle_size, triangle_size, NULL, &A));
89: for (PetscInt i = 0; i < triangle_size; ++i) PetscCall(MatSetValue(A, i, i, 1.0, INSERT_VALUES));
90: PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY));
91: PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY));
93: {
94: KSP ksp;
95: KSPGuess guess;
96: Vec sol, rhs;
97: PetscInt j, indices[] = {0, 1, 2, 3, 4};
98: PetscScalar values[] = {1.0, 2.0, 3.0, 4.0, 5.0};
100: PetscCall(KSPCreate(PETSC_COMM_SELF, &ksp));
101: PetscCall(KSPSetOperators(ksp, A, A));
102: PetscCall(KSPSetFromOptions(ksp));
103: PetscCall(KSPGetGuess(ksp, &guess));
104: PetscCall(KSPGuessSetUp(guess));
106: for (PetscInt i = 0; i < 5; ++i) {
107: PetscCall(VecCreateSeq(PETSC_COMM_SELF, triangle_size, &sol));
108: PetscCall(VecCreateSeq(PETSC_COMM_SELF, triangle_size, &rhs));
109: for (j = 0; j < i; ++j) {
110: PetscCall(VecSetValue(sol, j, (PetscScalar)j, INSERT_VALUES));
111: PetscCall(VecSetValue(rhs, j, (PetscScalar)j, INSERT_VALUES));
112: }
113: PetscCall(VecAssemblyBegin(sol));
114: PetscCall(VecAssemblyBegin(rhs));
115: PetscCall(VecAssemblyEnd(sol));
116: PetscCall(VecAssemblyEnd(rhs));
118: PetscCall(KSPGuessUpdate(guess, rhs, sol));
120: PetscCall(VecDestroy(&rhs));
121: PetscCall(VecDestroy(&sol));
122: }
124: PetscCall(VecCreateSeq(PETSC_COMM_SELF, triangle_size, &sol));
125: PetscCall(VecCreateSeq(PETSC_COMM_SELF, triangle_size, &rhs));
126: PetscCall(VecSetValues(rhs, 5, indices, values, INSERT_VALUES));
127: PetscCall(VecAssemblyBegin(sol));
128: PetscCall(VecAssemblyEnd(sol));
130: PetscCall(KSPGuessFormGuess(guess, rhs, sol));
131: PetscCall(VecView(sol, PETSC_VIEWER_STDOUT_SELF));
133: PetscCall(VecDestroy(&rhs));
134: PetscCall(VecDestroy(&sol));
135: PetscCall(KSPDestroy(&ksp));
136: }
137: PetscCall(MatDestroy(&A));
138: }
139: PetscCall(PetscFinalize());
140: return 0;
141: }
143: /* The relative tolerance here is strict enough to get rid of all the noise in both single and double precision: values as low as 5e-7 also work */
145: /*TEST
147: test:
148: args: -ksp_guess_type fischer -ksp_guess_fischer_model 3,10 -ksp_guess_fischer_monitor -ksp_guess_fischer_tol 1e-6
150: TEST*/