Actual source code: ex1.c
2: static char help[] = "Tests solving linear system on 0 by 0 matrix, and KSPLSQR convergence test handling.\n\n";
4: #include <petscksp.h>
6: static PetscErrorCode GetConvergenceTestName(PetscErrorCode (*converged)(KSP, PetscInt, PetscReal, KSPConvergedReason *, void *), char name[], size_t n)
7: {
8: PetscFunctionBegin;
9: if (converged == KSPConvergedDefault) {
10: PetscCall(PetscStrncpy(name, "default", n));
11: } else if (converged == KSPConvergedSkip) {
12: PetscCall(PetscStrncpy(name, "skip", n));
13: } else if (converged == KSPLSQRConvergedDefault) {
14: PetscCall(PetscStrncpy(name, "lsqr", n));
15: } else {
16: PetscCall(PetscStrncpy(name, "other", n));
17: }
18: PetscFunctionReturn(PETSC_SUCCESS);
19: }
21: int main(int argc, char **args)
22: {
23: Mat C;
24: PetscInt N = 0;
25: Vec u, b, x;
26: KSP ksp;
27: PetscReal norm;
28: PetscBool flg = PETSC_FALSE;
30: PetscFunctionBeginUser;
31: PetscCall(PetscInitialize(&argc, &args, (char *)0, help));
33: /* create stiffness matrix */
34: PetscCall(MatCreate(PETSC_COMM_WORLD, &C));
35: PetscCall(MatSetSizes(C, PETSC_DECIDE, PETSC_DECIDE, N, N));
36: PetscCall(MatSetFromOptions(C));
37: PetscCall(MatSetUp(C));
38: PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY));
39: PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY));
41: /* create right hand side and solution */
42: PetscCall(VecCreate(PETSC_COMM_WORLD, &u));
43: PetscCall(VecSetSizes(u, PETSC_DECIDE, N));
44: PetscCall(VecSetFromOptions(u));
45: PetscCall(VecDuplicate(u, &b));
46: PetscCall(VecDuplicate(u, &x));
47: PetscCall(VecSet(u, 0.0));
48: PetscCall(VecSet(b, 0.0));
50: PetscCall(VecAssemblyBegin(b));
51: PetscCall(VecAssemblyEnd(b));
53: /* solve linear system */
54: PetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp));
55: PetscCall(KSPSetOperators(ksp, C, C));
56: PetscCall(KSPSetFromOptions(ksp));
57: PetscCall(KSPSolve(ksp, b, u));
59: /* test proper handling of convergence test by KSPLSQR */
60: PetscCall(PetscOptionsGetBool(NULL, NULL, "-test_lsqr", &flg, NULL));
61: if (flg) {
62: char *type;
63: char convtestname[16];
64: PetscBool islsqr;
65: PetscErrorCode (*converged)(KSP, PetscInt, PetscReal, KSPConvergedReason *, void *);
66: PetscErrorCode (*converged1)(KSP, PetscInt, PetscReal, KSPConvergedReason *, void *);
67: PetscErrorCode (*destroy)(void *), (*destroy1)(void *);
68: void *ctx, *ctx1;
70: {
71: const char *typeP;
72: PetscCall(KSPGetType(ksp, &typeP));
73: PetscCall(PetscStrallocpy(typeP, &type));
74: }
75: PetscCall(PetscStrcmp(type, KSPLSQR, &islsqr));
76: PetscCall(KSPGetConvergenceTest(ksp, &converged, &ctx, &destroy));
77: PetscCall(GetConvergenceTestName(converged, convtestname, 16));
78: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "convergence test: %s\n", convtestname));
79: PetscCall(KSPSetType(ksp, KSPLSQR));
80: PetscCall(KSPGetConvergenceTest(ksp, &converged1, &ctx1, &destroy1));
81: PetscCheck(converged1 == KSPLSQRConvergedDefault, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test should be KSPLSQRConvergedDefault");
82: PetscCheck(destroy1 == KSPConvergedDefaultDestroy, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test destroy function should be KSPConvergedDefaultDestroy");
83: if (islsqr) {
84: PetscCheck(converged1 == converged, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test should be kept");
85: PetscCheck(destroy1 == destroy, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test destroy function should be kept");
86: PetscCheck(ctx1 == ctx, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test context should be kept");
87: }
88: PetscCall(GetConvergenceTestName(converged1, convtestname, 16));
89: PetscCall(KSPViewFromOptions(ksp, NULL, "-ksp1_view"));
90: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "convergence test: %s\n", convtestname));
91: PetscCall(KSPSetType(ksp, type));
92: PetscCall(KSPGetConvergenceTest(ksp, &converged1, &ctx1, &destroy1));
93: PetscCheck(converged1 == converged, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test not reverted properly");
94: PetscCheck(destroy1 == destroy, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test destroy function not reverted properly");
95: PetscCheck(ctx1 == ctx, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test context not reverted properly");
96: PetscCall(GetConvergenceTestName(converged1, convtestname, 16));
97: PetscCall(KSPViewFromOptions(ksp, NULL, "-ksp2_view"));
98: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "convergence test: %s\n", convtestname));
99: PetscCall(PetscFree(type));
100: }
102: PetscCall(MatMult(C, u, x));
103: PetscCall(VecAXPY(x, -1.0, b));
104: PetscCall(VecNorm(x, NORM_2, &norm));
106: PetscCall(KSPDestroy(&ksp));
107: PetscCall(VecDestroy(&u));
108: PetscCall(VecDestroy(&x));
109: PetscCall(VecDestroy(&b));
110: PetscCall(MatDestroy(&C));
111: PetscCall(PetscFinalize());
112: return 0;
113: }
115: /*TEST
117: test:
118: args: -pc_type jacobi -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always
120: test:
121: suffix: 2
122: nsize: 2
123: args: -pc_type jacobi -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always
125: test:
126: suffix: 3
127: args: -pc_type sor -pc_sor_symmetric -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always
129: test:
130: suffix: 5
131: args: -pc_type eisenstat -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always
133: testset:
134: args: -test_lsqr -ksp{,1,2}_view -pc_type jacobi
135: filter: grep -E "(^ type:|preconditioning|norm type|convergence test:)"
136: test:
137: suffix: lsqr_0
138: args: -ksp_convergence_test {{default skip}separate output}
139: test:
140: suffix: lsqr_1
141: args: -ksp_type cg -ksp_convergence_test {{default skip}separate output}
142: test:
143: suffix: lsqr_2
144: args: -ksp_type lsqr
146: TEST*/