xref: /petsc/src/ksp/pc/impls/sor/sor.c (revision 4482741e5b2e2bbc854fb1f8dba65221386520f2)
1 /*$Id: sor.c,v 1.103 2001/08/21 21:03:17 bsmith Exp $*/
2 
3 /*
4    Defines a  (S)SOR  preconditioner for any Mat implementation
5 */
6 #include "src/ksp/pc/pcimpl.h"               /*I "petscpc.h" I*/
7 
8 typedef struct {
9   int        its;        /* inner iterations, number of sweeps */
10   int        lits;       /* local inner iterations, number of sweeps applied by the local matrix mat->A */
11   MatSORType sym;        /* forward, reverse, symmetric etc. */
12   PetscReal  omega;
13 } PC_SOR;
14 
15 #undef __FUNCT__
16 #define __FUNCT__ "PCDestroy_SOR"
17 static int PCDestroy_SOR(PC pc)
18 {
19   PC_SOR *jac = (PC_SOR*)pc->data;
20   int    ierr;
21 
22   PetscFunctionBegin;
23   ierr = PetscFree(jac);CHKERRQ(ierr);
24   PetscFunctionReturn(0);
25 }
26 
27 #undef __FUNCT__
28 #define __FUNCT__ "PCApply_SOR"
29 static int PCApply_SOR(PC pc,Vec x,Vec y)
30 {
31   PC_SOR *jac = (PC_SOR*)pc->data;
32   int    ierr,flag = jac->sym | SOR_ZERO_INITIAL_GUESS;
33 
34   PetscFunctionBegin;
35   ierr = MatRelax(pc->pmat,x,jac->omega,(MatSORType)flag,0.0,jac->its,jac->lits,y);CHKERRQ(ierr);
36   PetscFunctionReturn(0);
37 }
38 
39 #undef __FUNCT__
40 #define __FUNCT__ "PCApplyRichardson_SOR"
41 static int PCApplyRichardson_SOR(PC pc,Vec b,Vec y,Vec w,PetscReal rtol,PetscReal atol, PetscReal dtol,int its)
42 {
43   PC_SOR *jac = (PC_SOR*)pc->data;
44   int    ierr;
45 
46   PetscFunctionBegin;
47   PetscLogInfo(pc,"PCApplyRichardson_SOR: Warning, convergence critera ignored, using %d iterations\n",its);
48   its  = its*jac->its;
49   ierr = MatRelax(pc->pmat,b,jac->omega,(MatSORType)jac->sym,0.0,its,jac->lits,y);CHKERRQ(ierr);
50   PetscFunctionReturn(0);
51 }
52 
53 #undef __FUNCT__
54 #define __FUNCT__ "PCSetFromOptions_SOR"
55 int PCSetFromOptions_SOR(PC pc)
56 {
57   PC_SOR     *jac = (PC_SOR*)pc->data;
58   int        ierr;
59   PetscTruth flg;
60 
61   PetscFunctionBegin;
62   ierr = PetscOptionsHead("(S)SOR options");CHKERRQ(ierr);
63     ierr = PetscOptionsReal("-pc_sor_omega","relaxation factor (0 < omega < 2)","PCSORSetOmega",jac->omega,&jac->omega,0);CHKERRQ(ierr);
64     ierr = PetscOptionsInt("-pc_sor_its","number of inner SOR iterations","PCSORSetIterations",jac->its,&jac->its,0);CHKERRQ(ierr);
65     ierr = PetscOptionsInt("-pc_sor_lits","number of local inner SOR iterations","PCSORSetIterations",jac->lits,&jac->lits,0);CHKERRQ(ierr);
66     ierr = PetscOptionsLogicalGroupBegin("-pc_sor_symmetric","SSOR, not SOR","PCSORSetSymmetric",&flg);CHKERRQ(ierr);
67     if (flg) {ierr = PCSORSetSymmetric(pc,SOR_SYMMETRIC_SWEEP);CHKERRQ(ierr);}
68     ierr = PetscOptionsLogicalGroup("-pc_sor_backward","use backward sweep instead of forward","PCSORSetSymmetric",&flg);CHKERRQ(ierr);
69     if (flg) {ierr = PCSORSetSymmetric(pc,SOR_BACKWARD_SWEEP);CHKERRQ(ierr);}
70     ierr = PetscOptionsLogicalGroup("-pc_sor_local_symmetric","use SSOR seperately on each processor","PCSORSetSymmetric",&flg);CHKERRQ(ierr);
71     if (flg) {ierr = PCSORSetSymmetric(pc,SOR_LOCAL_SYMMETRIC_SWEEP);CHKERRQ(ierr);}
72     ierr = PetscOptionsLogicalGroup("-pc_sor_local_backward","use backward sweep locally","PCSORSetSymmetric",&flg);CHKERRQ(ierr);
73     if (flg) {ierr = PCSORSetSymmetric(pc,SOR_LOCAL_BACKWARD_SWEEP);CHKERRQ(ierr);}
74     ierr = PetscOptionsLogicalGroupEnd("-pc_sor_local_forward","use forward sweep locally","PCSORSetSymmetric",&flg);CHKERRQ(ierr);
75     if (flg) {ierr = PCSORSetSymmetric(pc,SOR_LOCAL_FORWARD_SWEEP);CHKERRQ(ierr);}
76   ierr = PetscOptionsTail();CHKERRQ(ierr);
77   PetscFunctionReturn(0);
78 }
79 
80 #undef __FUNCT__
81 #define __FUNCT__ "PCView_SOR"
82 int PCView_SOR(PC pc,PetscViewer viewer)
83 {
84   PC_SOR     *jac = (PC_SOR*)pc->data;
85   MatSORType sym = jac->sym;
86   const char *sortype;
87   int        ierr;
88   PetscTruth isascii;
89 
90   PetscFunctionBegin;
91   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
92   if (isascii) {
93     if (sym & SOR_ZERO_INITIAL_GUESS) {ierr = PetscViewerASCIIPrintf(viewer,"  SOR:  zero initial guess\n");CHKERRQ(ierr);}
94     if (sym == SOR_APPLY_UPPER)              sortype = "apply_upper";
95     else if (sym == SOR_APPLY_LOWER)         sortype = "apply_lower";
96     else if (sym & SOR_EISENSTAT)            sortype = "Eisenstat";
97     else if ((sym & SOR_SYMMETRIC_SWEEP) == SOR_SYMMETRIC_SWEEP)
98                                              sortype = "symmetric";
99     else if (sym & SOR_BACKWARD_SWEEP)       sortype = "backward";
100     else if (sym & SOR_FORWARD_SWEEP)        sortype = "forward";
101     else if ((sym & SOR_LOCAL_SYMMETRIC_SWEEP) == SOR_LOCAL_SYMMETRIC_SWEEP)
102                                              sortype = "local_symmetric";
103     else if (sym & SOR_LOCAL_FORWARD_SWEEP)  sortype = "local_forward";
104     else if (sym & SOR_LOCAL_BACKWARD_SWEEP) sortype = "local_backward";
105     else                                     sortype = "unknown";
106     ierr = PetscViewerASCIIPrintf(viewer,"  SOR: type = %s, iterations = %d, omega = %g\n",sortype,jac->its,jac->omega);CHKERRQ(ierr);
107   } else {
108     SETERRQ1(1,"Viewer type %s not supported for PCSOR",((PetscObject)viewer)->type_name);
109   }
110   PetscFunctionReturn(0);
111 }
112 
113 
114 /* ------------------------------------------------------------------------------*/
115 EXTERN_C_BEGIN
116 #undef __FUNCT__
117 #define __FUNCT__ "PCSORSetSymmetric_SOR"
118 int PCSORSetSymmetric_SOR(PC pc,MatSORType flag)
119 {
120   PC_SOR *jac;
121 
122   PetscFunctionBegin;
123   jac = (PC_SOR*)pc->data;
124   jac->sym = flag;
125   PetscFunctionReturn(0);
126 }
127 EXTERN_C_END
128 
129 EXTERN_C_BEGIN
130 #undef __FUNCT__
131 #define __FUNCT__ "PCSORSetOmega_SOR"
132 int PCSORSetOmega_SOR(PC pc,PetscReal omega)
133 {
134   PC_SOR *jac;
135 
136   PetscFunctionBegin;
137   if (omega >= 2.0 || omega <= 0.0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Relaxation out of range");
138   jac        = (PC_SOR*)pc->data;
139   jac->omega = omega;
140   PetscFunctionReturn(0);
141 }
142 EXTERN_C_END
143 
144 EXTERN_C_BEGIN
145 #undef __FUNCT__
146 #define __FUNCT__ "PCSORSetIterations_SOR"
147 int PCSORSetIterations_SOR(PC pc,int its,int lits)
148 {
149   PC_SOR *jac;
150 
151   PetscFunctionBegin;
152   jac      = (PC_SOR*)pc->data;
153   jac->its = its;
154   jac->lits = lits;
155   PetscFunctionReturn(0);
156 }
157 EXTERN_C_END
158 
159 /* ------------------------------------------------------------------------------*/
160 #undef __FUNCT__
161 #define __FUNCT__ "PCSORSetSymmetric"
162 /*@
163    PCSORSetSymmetric - Sets the SOR preconditioner to use symmetric (SSOR),
164    backward, or forward relaxation.  The local variants perform SOR on
165    each processor.  By default forward relaxation is used.
166 
167    Collective on PC
168 
169    Input Parameters:
170 +  pc - the preconditioner context
171 -  flag - one of the following
172 .vb
173     SOR_FORWARD_SWEEP
174     SOR_BACKWARD_SWEEP
175     SOR_SYMMETRIC_SWEEP
176     SOR_LOCAL_FORWARD_SWEEP
177     SOR_LOCAL_BACKWARD_SWEEP
178     SOR_LOCAL_SYMMETRIC_SWEEP
179 .ve
180 
181    Options Database Keys:
182 +  -pc_sor_symmetric - Activates symmetric version
183 .  -pc_sor_backward - Activates backward version
184 .  -pc_sor_local_forward - Activates local forward version
185 .  -pc_sor_local_symmetric - Activates local symmetric version
186 -  -pc_sor_local_backward - Activates local backward version
187 
188    Notes:
189    To use the Eisenstat trick with SSOR, employ the PCEISENSTAT preconditioner,
190    which can be chosen with the option
191 .  -pc_type eisenstat - Activates Eisenstat trick
192 
193    Level: intermediate
194 
195 .keywords: PC, SOR, SSOR, set, relaxation, sweep, forward, backward, symmetric
196 
197 .seealso: PCEisenstatSetOmega(), PCSORSetIterations(), PCSORSetOmega()
198 @*/
199 int PCSORSetSymmetric(PC pc,MatSORType flag)
200 {
201   int ierr,(*f)(PC,MatSORType);
202 
203   PetscFunctionBegin;
204   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
205   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCSORSetSymmetric_C",(void (**)(void))&f);CHKERRQ(ierr);
206   if (f) {
207     ierr = (*f)(pc,flag);CHKERRQ(ierr);
208   }
209   PetscFunctionReturn(0);
210 }
211 
212 #undef __FUNCT__
213 #define __FUNCT__ "PCSORSetOmega"
214 /*@
215    PCSORSetOmega - Sets the SOR relaxation coefficient, omega
216    (where omega = 1.0 by default).
217 
218    Collective on PC
219 
220    Input Parameters:
221 +  pc - the preconditioner context
222 -  omega - relaxation coefficient (0 < omega < 2).
223 
224    Options Database Key:
225 .  -pc_sor_omega <omega> - Sets omega
226 
227    Level: intermediate
228 
229 .keywords: PC, SOR, SSOR, set, relaxation, omega
230 
231 .seealso: PCSORSetSymmetric(), PCSORSetIterations(), PCEisenstatSetOmega()
232 @*/
233 int PCSORSetOmega(PC pc,PetscReal omega)
234 {
235   int ierr,(*f)(PC,PetscReal);
236 
237   PetscFunctionBegin;
238   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCSORSetOmega_C",(void (**)(void))&f);CHKERRQ(ierr);
239   if (f) {
240     ierr = (*f)(pc,omega);CHKERRQ(ierr);
241   }
242   PetscFunctionReturn(0);
243 }
244 
245 #undef __FUNCT__
246 #define __FUNCT__ "PCSORSetIterations"
247 /*@
248    PCSORSetIterations - Sets the number of inner iterations to
249    be used by the SOR preconditioner. The default is 1.
250 
251    Collective on PC
252 
253    Input Parameters:
254 +  pc - the preconditioner context
255 .  lits - number of local iterations, smoothings over just variables on processor
256 -  its - number of parallel iterations to use; each parallel iteration has lits local iterations
257 
258    Options Database Key:
259 +  -pc_sor_its <its> - Sets number of iterations
260 -  -pc_sor_lits <lits> - Sets number of local iterations
261 
262    Level: intermediate
263 
264    Notes: When run on one processor the number of smoothings is lits*its
265 
266 .keywords: PC, SOR, SSOR, set, iterations
267 
268 .seealso: PCSORSetOmega(), PCSORSetSymmetric()
269 @*/
270 int PCSORSetIterations(PC pc,int its,int lits)
271 {
272   int ierr,(*f)(PC,int,int);
273 
274   PetscFunctionBegin;
275   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
276   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCSORSetIterations_C",(void (**)(void))&f);CHKERRQ(ierr);
277   if (f) {
278     ierr = (*f)(pc,its,lits);CHKERRQ(ierr);
279   }
280   PetscFunctionReturn(0);
281 }
282 
283 /*MC
284      PCSOR - (S)SOR (successive over relaxation, Gauss-Seidel) preconditioning
285 
286    Options Database Keys:
287 +  -pc_sor_symmetric - Activates symmetric version
288 .  -pc_sor_backward - Activates backward version
289 .  -pc_sor_local_forward - Activates local forward version
290 .  -pc_sor_local_symmetric - Activates local symmetric version
291 .  -pc_sor_local_backward - Activates local backward version
292 .  -pc_sor_omega <omega> - Sets omega
293 .  -pc_sor_its <its> - Sets number of iterations
294 -  -pc_sor_lits <lits> - Sets number of local iterations
295 
296    Level: beginner
297 
298   Concepts: SOR, preconditioners, Gauss-Seidel
299 
300    Notes: Only implemented for the AIJ  and SeqBAIJ matrix formats.
301           Not a true parallel SOR, in parallel this implementation corresponds to block
302           Jacobi with SOR on each block.
303 
304           For SeqBAIJ matrices this implements point-block SOR, but the omega, its, lits options are not supported.
305 
306 .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
307            PCSORSetIterations(), PCSORSetSymmetric(), PCSORSetOmega(), PCEISENSTAT
308 M*/
309 
310 EXTERN_C_BEGIN
311 #undef __FUNCT__
312 #define __FUNCT__ "PCCreate_SOR"
313 int PCCreate_SOR(PC pc)
314 {
315   int    ierr;
316   PC_SOR *jac;
317 
318   PetscFunctionBegin;
319   ierr = PetscNew(PC_SOR,&jac);CHKERRQ(ierr);
320   PetscLogObjectMemory(pc,sizeof(PC_SOR));
321 
322   pc->ops->apply           = PCApply_SOR;
323   pc->ops->applyrichardson = PCApplyRichardson_SOR;
324   pc->ops->setfromoptions  = PCSetFromOptions_SOR;
325   pc->ops->setup           = 0;
326   pc->ops->view            = PCView_SOR;
327   pc->ops->destroy         = PCDestroy_SOR;
328   pc->data           = (void*)jac;
329   jac->sym           = SOR_FORWARD_SWEEP;
330   jac->omega         = 1.0;
331   jac->its           = 1;
332   jac->lits          = 1;
333 
334   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCSORSetSymmetric_C","PCSORSetSymmetric_SOR",
335                     PCSORSetSymmetric_SOR);CHKERRQ(ierr);
336   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCSORSetOmega_C","PCSORSetOmega_SOR",
337                     PCSORSetOmega_SOR);CHKERRQ(ierr);
338   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCSORSetIterations_C","PCSORSetIterations_SOR",
339                     PCSORSetIterations_SOR);CHKERRQ(ierr);
340 
341   PetscFunctionReturn(0);
342 }
343 EXTERN_C_END
344 
345 
346 
347 
348 
349