xref: /petsc/src/snes/impls/ksponly/ksponly.c (revision c579b30025f7481884435f5d6baf5e954044f830)
1b79b07cfSJed Brown 
2af0996ceSBarry Smith #include <petsc/private/snesimpl.h>
3b79b07cfSJed Brown 
4b79b07cfSJed Brown #undef __FUNCT__
5b79b07cfSJed Brown #define __FUNCT__ "SNESSolve_KSPONLY"
6b79b07cfSJed Brown static PetscErrorCode SNESSolve_KSPONLY(SNES snes)
7b79b07cfSJed Brown {
8b79b07cfSJed Brown   PetscErrorCode     ierr;
9b79b07cfSJed Brown   PetscInt           lits;
10b79b07cfSJed Brown   Vec                Y,X,F;
11b79b07cfSJed Brown   KSPConvergedReason kspreason;
12b79b07cfSJed Brown 
13b79b07cfSJed Brown   PetscFunctionBegin;
14*c579b300SPatrick Farrell 
15*c579b300SPatrick Farrell   if (snes->xl || snes->xu || snes->ops->computevariablebounds) {
16*c579b300SPatrick Farrell     SETERRQ1(PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONGSTATE, "SNES solver %s does not support bounds", ((PetscObject)snes)->type_name);
17*c579b300SPatrick Farrell   }
18*c579b300SPatrick Farrell 
19b79b07cfSJed Brown   snes->numFailures            = 0;
20b79b07cfSJed Brown   snes->numLinearSolveFailures = 0;
21b79b07cfSJed Brown   snes->reason                 = SNES_CONVERGED_ITERATING;
22b79b07cfSJed Brown   snes->iter                   = 0;
23b79b07cfSJed Brown   snes->norm                   = 0.0;
24b79b07cfSJed Brown 
25b79b07cfSJed Brown   X = snes->vec_sol;
26b79b07cfSJed Brown   F = snes->vec_func;
27b79b07cfSJed Brown   Y = snes->vec_sol_update;
28b79b07cfSJed Brown 
29b79b07cfSJed Brown   ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
30b79b07cfSJed Brown   if (snes->domainerror) {
31b79b07cfSJed Brown     snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
32b79b07cfSJed Brown     PetscFunctionReturn(0);
33b79b07cfSJed Brown   }
34a5eaddd9SBarry Smith   if (snes->numbermonitors) {
35a5eaddd9SBarry Smith     PetscReal fnorm;
36a5eaddd9SBarry Smith     ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr);
37a5eaddd9SBarry Smith     ierr = SNESMonitor(snes,0,fnorm);CHKERRQ(ierr);
38a5eaddd9SBarry Smith   }
39b79b07cfSJed Brown 
405341784dSBarry Smith   /* Call general purpose update function */
415341784dSBarry Smith   if (snes->ops->update) {
425341784dSBarry Smith     ierr = (*snes->ops->update)(snes, 0);CHKERRQ(ierr);
435341784dSBarry Smith   }
445341784dSBarry Smith 
45b79b07cfSJed Brown   /* Solve J Y = F, where J is Jacobian matrix */
46d1e9a80fSBarry Smith   ierr = SNESComputeJacobian(snes,X,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr);
4723ee1639SBarry Smith   ierr = KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre);CHKERRQ(ierr);
48b79b07cfSJed Brown   ierr = KSPSolve(snes->ksp,F,Y);CHKERRQ(ierr);
49b79b07cfSJed Brown   ierr = KSPGetConvergedReason(snes->ksp,&kspreason);CHKERRQ(ierr);
50b79b07cfSJed Brown   if (kspreason < 0 && ++snes->numLinearSolveFailures >= snes->maxLinearSolveFailures) {
51b79b07cfSJed 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);
52b79b07cfSJed Brown     snes->reason = SNES_DIVERGED_LINEAR_SOLVE;
531aa26658SKarl Rupp   } else snes->reason = SNES_CONVERGED_ITS;
541aa26658SKarl Rupp 
55b79b07cfSJed Brown   ierr              = KSPGetIterationNumber(snes->ksp,&lits);CHKERRQ(ierr);
56b79b07cfSJed Brown   snes->linear_its += lits;
57b79b07cfSJed Brown   ierr              = PetscInfo2(snes,"iter=%D, linear solve iterations=%D\n",snes->iter,lits);CHKERRQ(ierr);
58b79b07cfSJed Brown   snes->iter++;
59b79b07cfSJed Brown 
60b79b07cfSJed Brown   /* Take the computed step. */
61b79b07cfSJed Brown   ierr = VecAXPY(X,-1.0,Y);CHKERRQ(ierr);
62a5eaddd9SBarry Smith   if (snes->numbermonitors) {
63a5eaddd9SBarry Smith     PetscReal fnorm;
64a5eaddd9SBarry Smith     ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
65a5eaddd9SBarry Smith     ierr = VecNorm(F,NORM_2,&fnorm);CHKERRQ(ierr);
66a5eaddd9SBarry Smith     ierr = SNESMonitor(snes,1,fnorm);CHKERRQ(ierr);
67a5eaddd9SBarry Smith   }
68b79b07cfSJed Brown   PetscFunctionReturn(0);
69b79b07cfSJed Brown }
70b79b07cfSJed Brown 
71b79b07cfSJed Brown #undef __FUNCT__
72b79b07cfSJed Brown #define __FUNCT__ "SNESSetUp_KSPONLY"
73b79b07cfSJed Brown static PetscErrorCode SNESSetUp_KSPONLY(SNES snes)
74b79b07cfSJed Brown {
756cab3a1bSJed Brown   PetscErrorCode ierr;
76b79b07cfSJed Brown 
77b79b07cfSJed Brown   PetscFunctionBegin;
786cab3a1bSJed Brown   ierr = SNESSetUpMatrices(snes);CHKERRQ(ierr);
79b79b07cfSJed Brown   PetscFunctionReturn(0);
80b79b07cfSJed Brown }
81b79b07cfSJed Brown 
82b79b07cfSJed Brown #undef __FUNCT__
83b79b07cfSJed Brown #define __FUNCT__ "SNESDestroy_KSPONLY"
84b79b07cfSJed Brown static PetscErrorCode SNESDestroy_KSPONLY(SNES snes)
85b79b07cfSJed Brown {
86b79b07cfSJed Brown 
87b79b07cfSJed Brown   PetscFunctionBegin;
88b79b07cfSJed Brown   PetscFunctionReturn(0);
89b79b07cfSJed Brown }
90b79b07cfSJed Brown 
91b79b07cfSJed Brown /* -------------------------------------------------------------------------- */
92b79b07cfSJed Brown /*MC
93b79b07cfSJed Brown       SNESKSPONLY - Nonlinear solver that only performs one Newton step and does not compute any norms.
94b79b07cfSJed Brown       The main purpose of this solver is to solve linear problems using the SNES interface, without
95b79b07cfSJed Brown       any additional overhead in the form of vector operations.
96b79b07cfSJed Brown 
97b79b07cfSJed Brown    Level: beginner
98b79b07cfSJed Brown 
9904d7464bSBarry Smith .seealso:  SNESCreate(), SNES, SNESSetType(), SNESNEWTONLS, SNESNEWTONTR
100b79b07cfSJed Brown M*/
101b79b07cfSJed Brown #undef __FUNCT__
102b79b07cfSJed Brown #define __FUNCT__ "SNESCreate_KSPONLY"
1038cc058d9SJed Brown PETSC_EXTERN PetscErrorCode SNESCreate_KSPONLY(SNES snes)
104b79b07cfSJed Brown {
105b79b07cfSJed Brown 
106b79b07cfSJed Brown   PetscFunctionBegin;
107b79b07cfSJed Brown   snes->ops->setup          = SNESSetUp_KSPONLY;
108b79b07cfSJed Brown   snes->ops->solve          = SNESSolve_KSPONLY;
109b79b07cfSJed Brown   snes->ops->destroy        = SNESDestroy_KSPONLY;
11037596af1SLisandro Dalcin   snes->ops->setfromoptions = 0;
11137596af1SLisandro Dalcin   snes->ops->view           = 0;
11237596af1SLisandro Dalcin   snes->ops->reset          = 0;
113b79b07cfSJed Brown 
11442f4f86dSBarry Smith   snes->usesksp = PETSC_TRUE;
11542f4f86dSBarry Smith   snes->usespc  = PETSC_FALSE;
11642f4f86dSBarry Smith 
117b79b07cfSJed Brown   snes->data = 0;
118b79b07cfSJed Brown   PetscFunctionReturn(0);
119b79b07cfSJed Brown }
120