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