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(KSPConvergenceTestFn *converged, 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: KSPConvergenceTestFn *converged, *converged1;
65: PetscCtxDestroyFn *destroy, *destroy1;
66: void *ctx, *ctx1;
68: {
69: const char *typeP;
70: PetscCall(KSPGetType(ksp, &typeP));
71: PetscCall(PetscStrallocpy(typeP, &type));
72: }
73: PetscCall(PetscStrcmp(type, KSPLSQR, &islsqr));
74: PetscCall(KSPGetConvergenceTest(ksp, &converged, &ctx, &destroy));
75: PetscCall(GetConvergenceTestName(converged, convtestname, 16));
76: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "convergence test: %s\n", convtestname));
77: PetscCall(KSPSetType(ksp, KSPLSQR));
78: PetscCall(KSPGetConvergenceTest(ksp, &converged1, &ctx1, &destroy1));
79: PetscCheck(converged1 == KSPLSQRConvergedDefault, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test should be KSPLSQRConvergedDefault");
80: PetscCheck(destroy1 == KSPConvergedDefaultDestroy, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test destroy function should be KSPConvergedDefaultDestroy");
81: if (islsqr) {
82: PetscCheck(converged1 == converged, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test should be kept");
83: PetscCheck(destroy1 == destroy, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test destroy function should be kept");
84: PetscCheck(ctx1 == ctx, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test context should be kept");
85: }
86: PetscCall(GetConvergenceTestName(converged1, convtestname, 16));
87: PetscCall(KSPViewFromOptions(ksp, NULL, "-ksp1_view"));
88: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "convergence test: %s\n", convtestname));
89: PetscCall(KSPSetType(ksp, type));
90: PetscCall(KSPGetConvergenceTest(ksp, &converged1, &ctx1, &destroy1));
91: PetscCheck(converged1 == converged, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test not reverted properly");
92: PetscCheck(destroy1 == destroy, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test destroy function not reverted properly");
93: PetscCheck(ctx1 == ctx, PETSC_COMM_WORLD, PETSC_ERR_PLIB, "convergence test context not reverted properly");
94: PetscCall(GetConvergenceTestName(converged1, convtestname, 16));
95: PetscCall(KSPViewFromOptions(ksp, NULL, "-ksp2_view"));
96: PetscCall(PetscPrintf(PETSC_COMM_WORLD, "convergence test: %s\n", convtestname));
97: PetscCall(PetscFree(type));
98: }
100: PetscCall(MatMult(C, u, x));
101: PetscCall(VecAXPY(x, -1.0, b));
102: PetscCall(VecNorm(x, NORM_2, &norm));
104: PetscCall(KSPDestroy(&ksp));
105: PetscCall(VecDestroy(&u));
106: PetscCall(VecDestroy(&x));
107: PetscCall(VecDestroy(&b));
108: PetscCall(MatDestroy(&C));
109: PetscCall(PetscFinalize());
110: return 0;
111: }
113: /*TEST
115: test:
116: args: -pc_type jacobi -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always
118: test:
119: suffix: 2
120: nsize: 2
121: args: -pc_type jacobi -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always
123: test:
124: suffix: 3
125: args: -pc_type sor -pc_sor_symmetric -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always
127: test:
128: suffix: 5
129: args: -pc_type eisenstat -ksp_monitor_short -ksp_gmres_cgs_refinement_type refine_always
131: testset:
132: args: -test_lsqr -ksp{,1,2}_view -pc_type jacobi
133: filter: grep -E "(^ type:|preconditioning|norm type|convergence test:)"
134: test:
135: suffix: lsqr_0
136: args: -ksp_convergence_test {{default skip}separate output}
137: test:
138: suffix: lsqr_1
139: args: -ksp_type cg -ksp_convergence_test {{default skip}separate output}
140: test:
141: suffix: lsqr_2
142: args: -ksp_type lsqr
144: TEST*/