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

  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