xref: /petsc/src/snes/impls/gs/snesgs.c (revision 3542a6bc4c584c7242b42ae25287f99f26705a8b)
1*3542a6bcSPeter Brune #include <private/snesimpl.h>             /*I   "petscsnes.h"   I*/
2*3542a6bcSPeter Brune 
3*3542a6bcSPeter Brune typedef struct {
4*3542a6bcSPeter Brune   PetscInt sweeps;
5*3542a6bcSPeter Brune } SNES_GS;
6*3542a6bcSPeter Brune 
7*3542a6bcSPeter Brune #undef __FUNCT__
8*3542a6bcSPeter Brune #define __FUNCT__ "SNESReset_GS"
9*3542a6bcSPeter Brune PetscErrorCode SNESReset_GS(SNES snes)
10*3542a6bcSPeter Brune {
11*3542a6bcSPeter Brune   PetscFunctionBegin;
12*3542a6bcSPeter Brune   PetscFunctionReturn(0);
13*3542a6bcSPeter Brune }
14*3542a6bcSPeter Brune 
15*3542a6bcSPeter Brune #undef __FUNCT__
16*3542a6bcSPeter Brune #define __FUNCT__ "SNESDestroy_GS"
17*3542a6bcSPeter Brune PetscErrorCode SNESDestroy_GS(SNES snes)
18*3542a6bcSPeter Brune {
19*3542a6bcSPeter Brune   PetscErrorCode ierr;
20*3542a6bcSPeter Brune 
21*3542a6bcSPeter Brune   PetscFunctionBegin;
22*3542a6bcSPeter Brune   ierr = SNESReset_GS(snes);CHKERRQ(ierr);
23*3542a6bcSPeter Brune   ierr = PetscFree(snes->data);
24*3542a6bcSPeter Brune   PetscFunctionReturn(0);
25*3542a6bcSPeter Brune }
26*3542a6bcSPeter Brune 
27*3542a6bcSPeter Brune #undef __FUNCT__
28*3542a6bcSPeter Brune #define __FUNCT__ "SNESSetUp_GS"
29*3542a6bcSPeter Brune PetscErrorCode SNESSetUp_GS(SNES snes)
30*3542a6bcSPeter Brune {
31*3542a6bcSPeter Brune   PetscFunctionBegin;
32*3542a6bcSPeter Brune   PetscFunctionReturn(0);
33*3542a6bcSPeter Brune }
34*3542a6bcSPeter Brune 
35*3542a6bcSPeter Brune #undef __FUNCT__
36*3542a6bcSPeter Brune #define __FUNCT__ "SNESSetFromOptions_GS"
37*3542a6bcSPeter Brune PetscErrorCode SNESSetFromOptions_GS(SNES snes)
38*3542a6bcSPeter Brune {
39*3542a6bcSPeter Brune   PetscErrorCode ierr;
40*3542a6bcSPeter Brune 
41*3542a6bcSPeter Brune   PetscFunctionBegin;
42*3542a6bcSPeter Brune   ierr = PetscOptionsHead("SNES GS options");CHKERRQ(ierr);
43*3542a6bcSPeter Brune   PetscFunctionReturn(0);
44*3542a6bcSPeter Brune }
45*3542a6bcSPeter Brune 
46*3542a6bcSPeter Brune #undef __FUNCT__
47*3542a6bcSPeter Brune #define __FUNCT__ "SNESView_GS"
48*3542a6bcSPeter Brune PetscErrorCode SNESView_GS(SNES snes, PetscViewer viewer)
49*3542a6bcSPeter Brune {
50*3542a6bcSPeter Brune   PetscFunctionBegin;
51*3542a6bcSPeter Brune   PetscFunctionReturn(0);
52*3542a6bcSPeter Brune }
53*3542a6bcSPeter Brune 
54*3542a6bcSPeter Brune #undef __FUNCT__
55*3542a6bcSPeter Brune #define __FUNCT__ "SNESSolve_GS"
56*3542a6bcSPeter Brune PetscErrorCode SNESSolve_GS(SNES snes)
57*3542a6bcSPeter Brune {
58*3542a6bcSPeter Brune   Vec            F;
59*3542a6bcSPeter Brune   Vec            X;
60*3542a6bcSPeter Brune   Vec            B;
61*3542a6bcSPeter Brune   PetscInt       i;
62*3542a6bcSPeter Brune   PetscScalar    fnorm;
63*3542a6bcSPeter Brune   PetscErrorCode ierr;
64*3542a6bcSPeter Brune 
65*3542a6bcSPeter Brune   PetscFunctionBegin;
66*3542a6bcSPeter Brune 
67*3542a6bcSPeter Brune   X = snes->vec_sol;
68*3542a6bcSPeter Brune   F = snes->vec_func;
69*3542a6bcSPeter Brune   B = snes->vec_rhs;
70*3542a6bcSPeter Brune 
71*3542a6bcSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
72*3542a6bcSPeter Brune   snes->iter = 0;
73*3542a6bcSPeter Brune   snes->norm = 0.;
74*3542a6bcSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
75*3542a6bcSPeter Brune 
76*3542a6bcSPeter Brune   snes->reason = SNES_CONVERGED_ITS;
77*3542a6bcSPeter Brune   /* compute the initial function and preconditioned update delX */
78*3542a6bcSPeter Brune   ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
79*3542a6bcSPeter Brune   if (snes->domainerror) {
80*3542a6bcSPeter Brune     snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
81*3542a6bcSPeter Brune     PetscFunctionReturn(0);
82*3542a6bcSPeter Brune   }
83*3542a6bcSPeter Brune   /* convergence test */
84*3542a6bcSPeter Brune   ierr = VecNorm(F, NORM_2, &fnorm);CHKERRQ(ierr); /* fnorm <- ||F||  */
85*3542a6bcSPeter Brune   if (PetscIsInfOrNanReal(fnorm)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
86*3542a6bcSPeter Brune   ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
87*3542a6bcSPeter Brune   snes->norm = fnorm;
88*3542a6bcSPeter Brune   ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
89*3542a6bcSPeter Brune   SNESLogConvHistory(snes,fnorm,0);
90*3542a6bcSPeter Brune   ierr = SNESMonitor(snes,0,fnorm);CHKERRQ(ierr);
91*3542a6bcSPeter Brune 
92*3542a6bcSPeter Brune   /* set parameter for default relative tolerance convergence test */
93*3542a6bcSPeter Brune   snes->ttol = fnorm*snes->rtol;
94*3542a6bcSPeter Brune   /* test convergence */
95*3542a6bcSPeter Brune   ierr = (*snes->ops->converged)(snes,0,0.0,0.0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr);
96*3542a6bcSPeter Brune   if (snes->reason) PetscFunctionReturn(0);
97*3542a6bcSPeter Brune 
98*3542a6bcSPeter Brune   /* Call general purpose update function */
99*3542a6bcSPeter Brune   if (snes->ops->update) {
100*3542a6bcSPeter Brune     ierr = (*snes->ops->update)(snes, snes->iter);CHKERRQ(ierr);
101*3542a6bcSPeter Brune  }
102*3542a6bcSPeter Brune   for(i = 0; i < snes->max_its; i++) {
103*3542a6bcSPeter Brune     ierr = SNESComputeGS(snes, B, X);CHKERRQ(ierr);
104*3542a6bcSPeter Brune     ierr = SNESComputeFunction(snes,X,F);CHKERRQ(ierr);
105*3542a6bcSPeter Brune     if (snes->domainerror) {
106*3542a6bcSPeter Brune       snes->reason = SNES_DIVERGED_FUNCTION_DOMAIN;
107*3542a6bcSPeter Brune       PetscFunctionReturn(0);
108*3542a6bcSPeter Brune     }
109*3542a6bcSPeter Brune     ierr = VecNorm(F, NORM_2, &fnorm);CHKERRQ(ierr); /* fnorm <- ||F||  */
110*3542a6bcSPeter Brune   if (PetscIsInfOrNanReal(fnorm)) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_FP,"Infinite or not-a-number generated in norm");
111*3542a6bcSPeter Brune     /* Monitor convergence */
112*3542a6bcSPeter Brune     ierr = PetscObjectTakeAccess(snes);CHKERRQ(ierr);
113*3542a6bcSPeter Brune     snes->iter = i+1;
114*3542a6bcSPeter Brune     snes->norm = fnorm;
115*3542a6bcSPeter Brune     ierr = PetscObjectGrantAccess(snes);CHKERRQ(ierr);
116*3542a6bcSPeter Brune     SNESLogConvHistory(snes,snes->norm,0);
117*3542a6bcSPeter Brune     ierr = SNESMonitor(snes,snes->iter,snes->norm);CHKERRQ(ierr);
118*3542a6bcSPeter Brune 
119*3542a6bcSPeter Brune     /* Test for convergence */
120*3542a6bcSPeter Brune     ierr = (*snes->ops->converged)(snes,snes->iter,0.0,0.0,fnorm,&snes->reason,snes->cnvP);CHKERRQ(ierr);
121*3542a6bcSPeter Brune     if (snes->reason) PetscFunctionReturn(0);
122*3542a6bcSPeter Brune 
123*3542a6bcSPeter Brune     /* Call general purpose update function */
124*3542a6bcSPeter Brune     if (snes->ops->update) {
125*3542a6bcSPeter Brune       ierr = (*snes->ops->update)(snes, snes->iter);CHKERRQ(ierr);
126*3542a6bcSPeter Brune     }
127*3542a6bcSPeter Brune   }
128*3542a6bcSPeter Brune   ierr = PetscInfo1(snes, "Maximum number of iterations has been reached: %D\n", snes->max_its);CHKERRQ(ierr);
129*3542a6bcSPeter Brune   if (!snes->reason) snes->reason = SNES_DIVERGED_MAX_IT;
130*3542a6bcSPeter Brune   PetscFunctionReturn(0);
131*3542a6bcSPeter Brune }
132*3542a6bcSPeter Brune 
133*3542a6bcSPeter Brune /*MC
134*3542a6bcSPeter Brune   SNESGS - Just calls the user-provided solution routine provided with SNESSetGS()
135*3542a6bcSPeter Brune 
136*3542a6bcSPeter Brune    Level: advanced
137*3542a6bcSPeter Brune 
138*3542a6bcSPeter Brune   Notes:
139*3542a6bcSPeter Brune   the Gauss-Seidel smoother is inherited through composition.  If a solver has been created with SNESGetPC(), it will have
140*3542a6bcSPeter Brune   its parent's Gauss-Seidel routine associated with it.
141*3542a6bcSPeter Brune 
142*3542a6bcSPeter Brune .seealso: SNESCreate(), SNES, SNESSetType(), SNESSetGS(), SNESType (for list of available types)
143*3542a6bcSPeter Brune M*/
144*3542a6bcSPeter Brune 
145*3542a6bcSPeter Brune EXTERN_C_BEGIN
146*3542a6bcSPeter Brune #undef __FUNCT__
147*3542a6bcSPeter Brune #define __FUNCT__ "SNESCreate_GS"
148*3542a6bcSPeter Brune PetscErrorCode SNESCreate_GS(SNES snes)
149*3542a6bcSPeter Brune {
150*3542a6bcSPeter Brune   SNES_GS        *gs;
151*3542a6bcSPeter Brune   PetscErrorCode ierr;
152*3542a6bcSPeter Brune 
153*3542a6bcSPeter Brune   PetscFunctionBegin;
154*3542a6bcSPeter Brune   snes->ops->destroy        = SNESDestroy_GS;
155*3542a6bcSPeter Brune   snes->ops->setup          = SNESSetUp_GS;
156*3542a6bcSPeter Brune   snes->ops->setfromoptions = SNESSetFromOptions_GS;
157*3542a6bcSPeter Brune   snes->ops->view           = SNESView_GS;
158*3542a6bcSPeter Brune   snes->ops->solve          = SNESSolve_GS;
159*3542a6bcSPeter Brune   snes->ops->reset          = SNESReset_GS;
160*3542a6bcSPeter Brune 
161*3542a6bcSPeter Brune   snes->usesksp             = PETSC_FALSE;
162*3542a6bcSPeter Brune   snes->usespc              = PETSC_FALSE;
163*3542a6bcSPeter Brune 
164*3542a6bcSPeter Brune   ierr = PetscNewLog(snes, SNES_GS, &gs);CHKERRQ(ierr);
165*3542a6bcSPeter Brune   snes->data = (void*) gs;
166*3542a6bcSPeter Brune   PetscFunctionReturn(0);
167*3542a6bcSPeter Brune }
168*3542a6bcSPeter Brune EXTERN_C_END
169