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