Actual source code: sor.c
1: /*$Id: sor.c,v 1.101 2001/04/10 19:36:08 bsmith Exp $*/
3: /*
4: Defines a (S)SOR preconditioner for any Mat implementation
5: */
6: #include "src/sles/pc/pcimpl.h" /*I "petscpc.h" I*/
8: typedef struct {
9: int its; /* inner iterations, number of sweeps */
10: MatSORType sym; /* forward, reverse, symmetric etc. */
11: PetscReal omega;
12: } PC_SOR;
14: static int PCDestroy_SOR(PC pc)
15: {
16: PC_SOR *jac = (PC_SOR*)pc->data;
17: int ierr;
20: PetscFree(jac);
21: return(0);
22: }
24: static int PCApply_SOR(PC pc,Vec x,Vec y)
25: {
26: PC_SOR *jac = (PC_SOR*)pc->data;
27: int ierr,flag = jac->sym | SOR_ZERO_INITIAL_GUESS;
30: MatRelax(pc->pmat,x,jac->omega,(MatSORType)flag,0.0,jac->its,y);
31: return(0);
32: }
34: static int PCApplyRichardson_SOR(PC pc,Vec b,Vec y,Vec w,int its)
35: {
36: PC_SOR *jac = (PC_SOR*)pc->data;
37: int ierr;
40: MatRelax(pc->mat,b,jac->omega,(MatSORType)jac->sym,0.0,its,y);
41: return(0);
42: }
44: static int PCSetFromOptions_SOR(PC pc)
45: {
46: PC_SOR *jac = (PC_SOR*)pc->data;
47: int ierr;
48: PetscTruth flg;
51: PetscOptionsHead("(S)SOR options");
52: PetscOptionsDouble("-pc_sor_omega","relaxation factor (0 < omega < 2)","PCSORSetOmega",jac->omega,&jac->omega,0);
53: PetscOptionsInt("-pc_sor_its","number of inner SOR iterations","PCSORSetIterations",jac->its,&jac->its,0);
54: PetscOptionsLogicalGroupBegin("-pc_sor_symmetric","SSOR, not SOR","PCSORSetSymmetric",&flg);
55: if (flg) {PCSORSetSymmetric(pc,SOR_SYMMETRIC_SWEEP);}
56: PetscOptionsLogicalGroup("-pc_sor_backward","use backward sweep instead of forward","PCSORSetSymmetric",&flg);
57: if (flg) {PCSORSetSymmetric(pc,SOR_BACKWARD_SWEEP);}
58: PetscOptionsLogicalGroup("-pc_sor_local_symmetric","use SSOR seperately on each processor","PCSORSetSymmetric",&flg);
59: if (flg) {PCSORSetSymmetric(pc,SOR_LOCAL_SYMMETRIC_SWEEP);}
60: PetscOptionsLogicalGroup("-pc_sor_local_backward","use backward sweep locally","PCSORSetSymmetric",&flg);
61: if (flg) {PCSORSetSymmetric(pc,SOR_LOCAL_BACKWARD_SWEEP);}
62: PetscOptionsLogicalGroupEnd("-pc_sor_local_forward","use forward sweep locally","PCSORSetSymmetric",&flg);
63: if (flg) {PCSORSetSymmetric(pc,SOR_LOCAL_FORWARD_SWEEP);}
64: PetscOptionsTail();
65: return(0);
66: }
68: static int PCView_SOR(PC pc,PetscViewer viewer)
69: {
70: PC_SOR *jac = (PC_SOR*)pc->data;
71: MatSORType sym = jac->sym;
72: char *sortype;
73: int ierr;
74: PetscTruth isascii;
77: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);
78: if (isascii) {
79: if (sym & SOR_ZERO_INITIAL_GUESS) {PetscViewerASCIIPrintf(viewer," SOR: zero initial guessn");}
80: if (sym == SOR_APPLY_UPPER) sortype = "apply_upper";
81: else if (sym == SOR_APPLY_LOWER) sortype = "apply_lower";
82: else if (sym & SOR_EISENSTAT) sortype = "Eisenstat";
83: else if ((sym & SOR_SYMMETRIC_SWEEP) == SOR_SYMMETRIC_SWEEP)
84: sortype = "symmetric";
85: else if (sym & SOR_BACKWARD_SWEEP) sortype = "backward";
86: else if (sym & SOR_FORWARD_SWEEP) sortype = "forward";
87: else if ((sym & SOR_LOCAL_SYMMETRIC_SWEEP) == SOR_LOCAL_SYMMETRIC_SWEEP)
88: sortype = "local_symmetric";
89: else if (sym & SOR_LOCAL_FORWARD_SWEEP) sortype = "local_forward";
90: else if (sym & SOR_LOCAL_BACKWARD_SWEEP) sortype = "local_backward";
91: else sortype = "unknown";
92: PetscViewerASCIIPrintf(viewer," SOR: type = %s, iterations = %d, omega = %gn",sortype,jac->its,jac->omega);
93: } else {
94: SETERRQ1(1,"Viewer type %s not supported for PCSOR",((PetscObject)viewer)->type_name);
95: }
96: return(0);
97: }
100: /* ------------------------------------------------------------------------------*/
101: EXTERN_C_BEGIN
102: int PCSORSetSymmetric_SOR(PC pc,MatSORType flag)
103: {
104: PC_SOR *jac;
107: jac = (PC_SOR*)pc->data;
108: jac->sym = flag;
109: return(0);
110: }
111: EXTERN_C_END
113: EXTERN_C_BEGIN
114: int PCSORSetOmega_SOR(PC pc,PetscReal omega)
115: {
116: PC_SOR *jac;
119: if (omega >= 2.0 || omega <= 0.0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Relaxation out of range");
120: jac = (PC_SOR*)pc->data;
121: jac->omega = omega;
122: return(0);
123: }
124: EXTERN_C_END
126: EXTERN_C_BEGIN
127: int PCSORSetIterations_SOR(PC pc,int its)
128: {
129: PC_SOR *jac;
132: jac = (PC_SOR*)pc->data;
133: jac->its = its;
134: return(0);
135: }
136: EXTERN_C_END
138: /* ------------------------------------------------------------------------------*/
139: /*@
140: PCSORSetSymmetric - Sets the SOR preconditioner to use symmetric (SSOR),
141: backward, or forward relaxation. The local variants perform SOR on
142: each processor. By default forward relaxation is used.
144: Collective on PC
146: Input Parameters:
147: + pc - the preconditioner context
148: - flag - one of the following
149: .vb
150: SOR_FORWARD_SWEEP
151: SOR_BACKWARD_SWEEP
152: SOR_SYMMETRIC_SWEEP
153: SOR_LOCAL_FORWARD_SWEEP
154: SOR_LOCAL_BACKWARD_SWEEP
155: SOR_LOCAL_SYMMETRIC_SWEEP
156: .ve
158: Options Database Keys:
159: + -pc_sor_symmetric - Activates symmetric version
160: . -pc_sor_backward - Activates backward version
161: . -pc_sor_local_forward - Activates local forward version
162: . -pc_sor_local_symmetric - Activates local symmetric version
163: - -pc_sor_local_backward - Activates local backward version
165: Notes:
166: To use the Eisenstat trick with SSOR, employ the PCEISENSTAT preconditioner,
167: which can be chosen with the option
168: . -pc_type eisenstat - Activates Eisenstat trick
170: Level: intermediate
172: .keywords: PC, SOR, SSOR, set, relaxation, sweep, forward, backward, symmetric
174: .seealso: PCEisenstatSetOmega(), PCSORSetIterations(), PCSORSetOmega()
175: @*/
176: int PCSORSetSymmetric(PC pc,MatSORType flag)
177: {
178: int ierr,(*f)(PC,MatSORType);
182: PetscObjectQueryFunction((PetscObject)pc,"PCSORSetSymmetric_C",(void (**)())&f);
183: if (f) {
184: (*f)(pc,flag);
185: }
186: return(0);
187: }
189: /*@
190: PCSORSetOmega - Sets the SOR relaxation coefficient, omega
191: (where omega = 1.0 by default).
193: Collective on PC
195: Input Parameters:
196: + pc - the preconditioner context
197: - omega - relaxation coefficient (0 < omega < 2).
199: Options Database Key:
200: . -pc_sor_omega <omega> - Sets omega
202: Level: intermediate
204: .keywords: PC, SOR, SSOR, set, relaxation, omega
206: .seealso: PCSORSetSymmetric(), PCSORSetIterations(), PCEisenstatSetOmega()
207: @*/
208: int PCSORSetOmega(PC pc,PetscReal omega)
209: {
210: int ierr,(*f)(PC,PetscReal);
213: PetscObjectQueryFunction((PetscObject)pc,"PCSORSetOmega_C",(void (**)())&f);
214: if (f) {
215: (*f)(pc,omega);
216: }
217: return(0);
218: }
220: /*@
221: PCSORSetIterations - Sets the number of inner iterations to
222: be used by the SOR preconditioner. The default is 1.
224: Collective on PC
226: Input Parameters:
227: + pc - the preconditioner context
228: - its - number of iterations to use
230: Options Database Key:
231: . -pc_sor_its <its> - Sets number of iterations
233: Level: intermediate
235: .keywords: PC, SOR, SSOR, set, iterations
237: .seealso: PCSORSetOmega(), PCSORSetSymmetric()
238: @*/
239: int PCSORSetIterations(PC pc,int its)
240: {
241: int ierr,(*f)(PC,int);
245: PetscObjectQueryFunction((PetscObject)pc,"PCSORSetIterations_C",(void (**)())&f);
246: if (f) {
247: (*f)(pc,its);
248: }
249: return(0);
250: }
252: EXTERN_C_BEGIN
253: int PCCreate_SOR(PC pc)
254: {
255: int ierr;
256: PC_SOR *jac;
259: PetscNew(PC_SOR,&jac);
260: PetscLogObjectMemory(pc,sizeof(PC_SOR));
262: pc->ops->apply = PCApply_SOR;
263: pc->ops->applyrichardson = PCApplyRichardson_SOR;
264: pc->ops->setfromoptions = PCSetFromOptions_SOR;
265: pc->ops->setup = 0;
266: pc->ops->view = PCView_SOR;
267: pc->ops->destroy = PCDestroy_SOR;
268: pc->data = (void*)jac;
269: jac->sym = SOR_FORWARD_SWEEP;
270: jac->omega = 1.0;
271: jac->its = 1;
273: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCSORSetSymmetric_C","PCSORSetSymmetric_SOR",
274: PCSORSetSymmetric_SOR);
275: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCSORSetOmega_C","PCSORSetOmega_SOR",
276: PCSORSetOmega_SOR);
277: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCSORSetIterations_C","PCSORSetIterations_SOR",
278: PCSORSetIterations_SOR);
280: return(0);
281: }
282: EXTERN_C_END