xref: /petsc/src/snes/impls/ksponly/ksponly.c (revision 7087cfbefd1a42b179f217f9994fb6cb0d0c1824)
1b79b07cfSJed Brown #define PETSCSNES_DLL
2b79b07cfSJed Brown 
3b79b07cfSJed Brown #include "private/snesimpl.h"
4b79b07cfSJed Brown 
5b79b07cfSJed Brown #undef __FUNCT__
6b79b07cfSJed Brown #define __FUNCT__ "SNESSolve_KSPONLY"
7b79b07cfSJed Brown static PetscErrorCode SNESSolve_KSPONLY(SNES snes)
8b79b07cfSJed Brown {
9b79b07cfSJed Brown   PetscErrorCode     ierr;
10b79b07cfSJed Brown   PetscInt           lits;
11b79b07cfSJed Brown   MatStructure       flg = DIFFERENT_NONZERO_PATTERN;
12b79b07cfSJed Brown   Vec                Y,X,F;
13b79b07cfSJed Brown   KSPConvergedReason kspreason;
14b79b07cfSJed Brown 
15b79b07cfSJed Brown   PetscFunctionBegin;
16b79b07cfSJed Brown   snes->numFailures            = 0;
17b79b07cfSJed Brown   snes->numLinearSolveFailures = 0;
18b79b07cfSJed Brown   snes->reason                 = SNES_CONVERGED_ITERATING;
19b79b07cfSJed Brown   snes->iter                   = 0;
20b79b07cfSJed Brown   snes->norm                   = 0.0;
21b79b07cfSJed Brown 
22b79b07cfSJed Brown   X = snes->vec_sol;
23b79b07cfSJed Brown   F = snes->vec_func;
24b79b07cfSJed Brown   Y = snes->vec_sol_update;
25b79b07cfSJed Brown 
26b79b07cfSJed Brown   ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
27b79b07cfSJed Brown   if (snes->domainerror) {
28b79b07cfSJed Brown     snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
29b79b07cfSJed Brown     PetscFunctionReturn(0);
30b79b07cfSJed Brown   }
31b79b07cfSJed Brown 
32b79b07cfSJed Brown   /* Solve J Y = F, where J is Jacobian matrix */
33b79b07cfSJed Brown   ierr = SNESComputeJacobian(snes,X,&snes->jacobian,&snes->jacobian_pre,&flg);CHKERRQ(ierr);
34b79b07cfSJed Brown   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre,flg);CHKERRQ(ierr);
35b79b07cfSJed Brown   ierr = KSPSolve(snes->ksp,F,Y);CHKERRQ(ierr);
36b79b07cfSJed Brown   ierr = KSPGetConvergedReason(snes->ksp,&kspreason);CHKERRQ(ierr);
37b79b07cfSJed Brown   if (kspreason < 0 && ++snes->numLinearSolveFailures >= snes->maxLinearSolveFailures) {
38b79b07cfSJed Brown     ierr = PetscInfo2(snes,"iter=%D, number linear solve failures %D greater than current SNES allowed, stopping solve\n",snes->iter,snes->numLinearSolveFailures);CHKERRQ(ierr);
39b79b07cfSJed Brown     snes->reason = SNES_DIVERGED_LINEAR_SOLVE;
40b79b07cfSJed Brown   } else {
41b79b07cfSJed Brown     snes->reason = SNES_CONVERGED_ITS;
42b79b07cfSJed Brown   }
43b79b07cfSJed Brown   ierr = KSPGetIterationNumber(snes->ksp,&lits);CHKERRQ(ierr);
44b79b07cfSJed Brown   snes->linear_its += lits;
45b79b07cfSJed Brown   ierr = PetscInfo2(snes,"iter=%D, linear solve iterations=%D\n",snes->iter,lits);CHKERRQ(ierr);
46b79b07cfSJed Brown   snes->iter++;
47b79b07cfSJed Brown 
48b79b07cfSJed Brown   /* Take the computed step. */
49b79b07cfSJed Brown   ierr = VecAXPY(X,-1.0,Y);CHKERRQ(ierr);
50b79b07cfSJed Brown   PetscFunctionReturn(0);
51b79b07cfSJed Brown }
52b79b07cfSJed Brown 
53b79b07cfSJed Brown #undef __FUNCT__
54b79b07cfSJed Brown #define __FUNCT__ "SNESSetUp_KSPONLY"
55b79b07cfSJed Brown static PetscErrorCode SNESSetUp_KSPONLY(SNES snes)
56b79b07cfSJed Brown {
57b79b07cfSJed Brown   PetscErrorCode ierr;
58b79b07cfSJed Brown 
59b79b07cfSJed Brown   PetscFunctionBegin;
60b79b07cfSJed Brown   if (!snes->vec_sol_update) {
61b79b07cfSJed Brown     ierr = VecDuplicate(snes->vec_sol,&snes->vec_sol_update);CHKERRQ(ierr);
62b79b07cfSJed Brown     ierr = PetscLogObjectParent(snes,snes->vec_sol_update);CHKERRQ(ierr);
63b79b07cfSJed Brown   }
64b79b07cfSJed Brown   PetscFunctionReturn(0);
65b79b07cfSJed Brown }
66b79b07cfSJed Brown 
67b79b07cfSJed Brown #undef __FUNCT__
68b79b07cfSJed Brown #define __FUNCT__ "SNESDestroy_KSPONLY"
69b79b07cfSJed Brown static PetscErrorCode SNESDestroy_KSPONLY(SNES snes)
70b79b07cfSJed Brown {
71b79b07cfSJed Brown   PetscErrorCode ierr;
72b79b07cfSJed Brown 
73b79b07cfSJed Brown   PetscFunctionBegin;
74b79b07cfSJed Brown   if (snes->vec_sol_update) {
75b79b07cfSJed Brown     ierr = VecDestroy(snes->vec_sol_update);CHKERRQ(ierr);
76b79b07cfSJed Brown     snes->vec_sol_update = PETSC_NULL;
77b79b07cfSJed Brown   }
78b79b07cfSJed Brown   PetscFunctionReturn(0);
79b79b07cfSJed Brown }
80b79b07cfSJed Brown 
81b79b07cfSJed Brown /* -------------------------------------------------------------------------- */
82b79b07cfSJed Brown /*MC
83b79b07cfSJed Brown       SNESKSPONLY - Nonlinear solver that only performs one Newton step and does not compute any norms.
84b79b07cfSJed Brown       The main purpose of this solver is to solve linear problems using the SNES interface, without
85b79b07cfSJed Brown       any additional overhead in the form of vector operations.
86b79b07cfSJed Brown 
87b79b07cfSJed Brown    Level: beginner
88b79b07cfSJed Brown 
89b79b07cfSJed Brown .seealso:  SNESCreate(), SNES, SNESSetType(), SNESLS, SNESTR
90b79b07cfSJed Brown M*/
91b79b07cfSJed Brown EXTERN_C_BEGIN
92b79b07cfSJed Brown #undef __FUNCT__
93b79b07cfSJed Brown #define __FUNCT__ "SNESCreate_KSPONLY"
94*7087cfbeSBarry Smith PetscErrorCode  SNESCreate_KSPONLY(SNES snes)
95b79b07cfSJed Brown {
96b79b07cfSJed Brown 
97b79b07cfSJed Brown   PetscFunctionBegin;
98b79b07cfSJed Brown   snes->ops->setup   = SNESSetUp_KSPONLY;
99b79b07cfSJed Brown   snes->ops->solve   = SNESSolve_KSPONLY;
100b79b07cfSJed Brown   snes->ops->destroy = SNESDestroy_KSPONLY;
101b79b07cfSJed Brown 
102b79b07cfSJed Brown   snes->data = 0;
103b79b07cfSJed Brown   PetscFunctionReturn(0);
104b79b07cfSJed Brown }
105b79b07cfSJed Brown EXTERN_C_END
106