Actual source code: ksponly.c
1: #include <petsc/private/snesimpl.h>
3: typedef struct {
4: PetscBool transpose_solve;
5: } SNES_KSPONLY;
7: static PetscErrorCode SNESSolve_KSPONLY(SNES snes)
8: {
9: SNES_KSPONLY *ksponly = (SNES_KSPONLY *)snes->data;
10: PetscInt lits;
11: Vec Y, X, F;
15: snes->numFailures = 0;
16: snes->numLinearSolveFailures = 0;
17: snes->reason = SNES_CONVERGED_ITERATING;
18: snes->iter = 0;
19: snes->norm = 0.0;
21: X = snes->vec_sol;
22: F = snes->vec_func;
23: Y = snes->vec_sol_update;
25: if (!snes->vec_func_init_set) {
26: SNESComputeFunction(snes, X, F);
27: } else snes->vec_func_init_set = PETSC_FALSE;
29: if (snes->numbermonitors) {
30: PetscReal fnorm;
31: VecNorm(F, NORM_2, &fnorm);
32: SNESMonitor(snes, 0, fnorm);
33: }
35: /* Call general purpose update function */
36: PetscTryTypeMethod(snes, update, 0);
38: /* Solve J Y = F, where J is Jacobian matrix */
39: SNESComputeJacobian(snes, X, snes->jacobian, snes->jacobian_pre);
41: SNESCheckJacobianDomainerror(snes);
43: KSPSetOperators(snes->ksp, snes->jacobian, snes->jacobian_pre);
44: if (ksponly->transpose_solve) {
45: KSPSolveTranspose(snes->ksp, F, Y);
46: } else {
47: KSPSolve(snes->ksp, F, Y);
48: }
49: snes->reason = SNES_CONVERGED_ITS;
50: SNESCheckKSPSolve(snes);
52: KSPGetIterationNumber(snes->ksp, &lits);
53: PetscInfo(snes, "iter=%" PetscInt_FMT ", linear solve iterations=%" PetscInt_FMT "\n", snes->iter, lits);
54: snes->iter++;
56: /* Take the computed step. */
57: VecAXPY(X, -1.0, Y);
58: if (snes->numbermonitors) {
59: PetscReal fnorm;
60: SNESComputeFunction(snes, X, F);
61: VecNorm(F, NORM_2, &fnorm);
62: SNESMonitor(snes, 1, fnorm);
63: }
64: return 0;
65: }
67: static PetscErrorCode SNESSetUp_KSPONLY(SNES snes)
68: {
69: SNESSetUpMatrices(snes);
70: return 0;
71: }
73: static PetscErrorCode SNESDestroy_KSPONLY(SNES snes)
74: {
75: PetscFree(snes->data);
76: return 0;
77: }
79: /*MC
80: SNESKSPONLY - Nonlinear solver that performs one Newton step and does not compute any norms.
81: The main purpose of this solver is to solve linear problems using the `SNES` interface, without
82: any additional overhead in the form of vector operations.
84: Level: beginner
86: .seealso: `SNES`, `SNESType`, `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESNEWTONLS`, `SNESNEWTONTR`
87: M*/
88: PETSC_EXTERN PetscErrorCode SNESCreate_KSPONLY(SNES snes)
89: {
90: SNES_KSPONLY *ksponly;
92: snes->ops->setup = SNESSetUp_KSPONLY;
93: snes->ops->solve = SNESSolve_KSPONLY;
94: snes->ops->destroy = SNESDestroy_KSPONLY;
95: snes->ops->setfromoptions = NULL;
96: snes->ops->view = NULL;
97: snes->ops->reset = NULL;
99: snes->usesksp = PETSC_TRUE;
100: snes->usesnpc = PETSC_FALSE;
102: snes->alwayscomputesfinalresidual = PETSC_FALSE;
104: PetscNew(&ksponly);
105: snes->data = (void *)ksponly;
106: return 0;
107: }
109: /*MC
110: SNESKSPTRANSPOSEONLY - Nonlinear solver that performs one Newton step and does not compute any norms.
111: The main purpose of this solver is to solve transposed linear problems using the `SNES` interface, without
112: any additional overhead in the form of vector operations within adjoint solvers.
114: Level: beginner
116: .seealso: `SNES`, `SNESType`, `SNESCreate()`, `SNES`, `SNESSetType()`, `SNESKSPTRANSPOSEONLY`, `SNESNEWTONLS`, `SNESNEWTONTR`
117: M*/
118: PETSC_EXTERN PetscErrorCode SNESCreate_KSPTRANSPOSEONLY(SNES snes)
119: {
120: SNES_KSPONLY *kspo;
122: SNESCreate_KSPONLY(snes);
123: PetscObjectChangeTypeName((PetscObject)snes, SNESKSPTRANSPOSEONLY);
124: kspo = (SNES_KSPONLY *)snes->data;
125: kspo->transpose_solve = PETSC_TRUE;
126: return 0;
127: }