Actual source code: sor.c

petsc-master 2014-12-18
Report Typos and Errors
  2: /*
  3:    Defines a  (S)SOR  preconditioner for any Mat implementation
  4: */
  5: #include <petsc-private/pcimpl.h>               /*I "petscpc.h" I*/

  7: typedef struct {
  8:   PetscInt   its;         /* inner iterations, number of sweeps */
  9:   PetscInt   lits;        /* local inner iterations, number of sweeps applied by the local matrix mat->A */
 10:   MatSORType sym;         /* forward, reverse, symmetric etc. */
 11:   PetscReal  omega;
 12:   PetscReal  fshift;
 13: } PC_SOR;

 17: static PetscErrorCode PCDestroy_SOR(PC pc)
 18: {

 22:   PetscFree(pc->data);
 23:   return(0);
 24: }

 28: static PetscErrorCode PCApply_SOR(PC pc,Vec x,Vec y)
 29: {
 30:   PC_SOR         *jac = (PC_SOR*)pc->data;
 32:   PetscInt       flag = jac->sym | SOR_ZERO_INITIAL_GUESS;

 35:   MatSOR(pc->pmat,x,jac->omega,(MatSORType)flag,jac->fshift,jac->its,jac->lits,y);
 36:   return(0);
 37: }

 41: static PetscErrorCode PCApplyRichardson_SOR(PC pc,Vec b,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt its,PetscBool guesszero,PetscInt *outits,PCRichardsonConvergedReason *reason)
 42: {
 43:   PC_SOR         *jac = (PC_SOR*)pc->data;
 45:   MatSORType     stype = jac->sym;

 48:   PetscInfo1(pc,"Warning, convergence critera ignored, using %D iterations\n",its);
 49:   if (guesszero) stype = (MatSORType) (stype | SOR_ZERO_INITIAL_GUESS);
 50:   MatSOR(pc->pmat,b,jac->omega,stype,jac->fshift,its*jac->its,jac->lits,y);
 51:   *outits = its;
 52:   *reason = PCRICHARDSON_CONVERGED_ITS;
 53:   return(0);
 54: }

 58: PetscErrorCode PCSetFromOptions_SOR(PC pc)
 59: {
 60:   PC_SOR         *jac = (PC_SOR*)pc->data;
 62:   PetscBool      flg;

 65:   PetscOptionsHead("(S)SOR options");
 66:   PetscOptionsReal("-pc_sor_omega","relaxation factor (0 < omega < 2)","PCSORSetOmega",jac->omega,&jac->omega,NULL);
 67:   PetscOptionsReal("-pc_sor_diagonal_shift","Add to the diagonal entries","",jac->fshift,&jac->fshift,NULL);
 68:   PetscOptionsInt("-pc_sor_its","number of inner SOR iterations","PCSORSetIterations",jac->its,&jac->its,NULL);
 69:   PetscOptionsInt("-pc_sor_lits","number of local inner SOR iterations","PCSORSetIterations",jac->lits,&jac->lits,NULL);
 70:   PetscOptionsBoolGroupBegin("-pc_sor_symmetric","SSOR, not SOR","PCSORSetSymmetric",&flg);
 71:   if (flg) {PCSORSetSymmetric(pc,SOR_SYMMETRIC_SWEEP);}
 72:   PetscOptionsBoolGroup("-pc_sor_backward","use backward sweep instead of forward","PCSORSetSymmetric",&flg);
 73:   if (flg) {PCSORSetSymmetric(pc,SOR_BACKWARD_SWEEP);}
 74:   PetscOptionsBoolGroup("-pc_sor_forward","use forward sweep","PCSORSetSymmetric",&flg);
 75:   if (flg) {PCSORSetSymmetric(pc,SOR_FORWARD_SWEEP);}
 76:   PetscOptionsBoolGroup("-pc_sor_local_symmetric","use SSOR separately on each processor","PCSORSetSymmetric",&flg);
 77:   if (flg) {PCSORSetSymmetric(pc,SOR_LOCAL_SYMMETRIC_SWEEP);}
 78:   PetscOptionsBoolGroup("-pc_sor_local_backward","use backward sweep locally","PCSORSetSymmetric",&flg);
 79:   if (flg) {PCSORSetSymmetric(pc,SOR_LOCAL_BACKWARD_SWEEP);}
 80:   PetscOptionsBoolGroupEnd("-pc_sor_local_forward","use forward sweep locally","PCSORSetSymmetric",&flg);
 81:   if (flg) {PCSORSetSymmetric(pc,SOR_LOCAL_FORWARD_SWEEP);}
 82:   PetscOptionsTail();
 83:   return(0);
 84: }

 88: PetscErrorCode PCView_SOR(PC pc,PetscViewer viewer)
 89: {
 90:   PC_SOR         *jac = (PC_SOR*)pc->data;
 91:   MatSORType     sym  = jac->sym;
 92:   const char     *sortype;
 94:   PetscBool      iascii;

 97:   PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);
 98:   if (iascii) {
 99:     if (sym & SOR_ZERO_INITIAL_GUESS) {PetscViewerASCIIPrintf(viewer,"  SOR:  zero initial guess\n");}
100:     if (sym == SOR_APPLY_UPPER)                                              sortype = "apply_upper";
101:     else if (sym == SOR_APPLY_LOWER)                                         sortype = "apply_lower";
102:     else if (sym & SOR_EISENSTAT)                                            sortype = "Eisenstat";
103:     else if ((sym & SOR_SYMMETRIC_SWEEP) == SOR_SYMMETRIC_SWEEP)             sortype = "symmetric";
104:     else if (sym & SOR_BACKWARD_SWEEP)                                       sortype = "backward";
105:     else if (sym & SOR_FORWARD_SWEEP)                                        sortype = "forward";
106:     else if ((sym & SOR_LOCAL_SYMMETRIC_SWEEP) == SOR_LOCAL_SYMMETRIC_SWEEP) sortype = "local_symmetric";
107:     else if (sym & SOR_LOCAL_FORWARD_SWEEP)                                  sortype = "local_forward";
108:     else if (sym & SOR_LOCAL_BACKWARD_SWEEP)                                 sortype = "local_backward";
109:     else                                                                     sortype = "unknown";
110:     PetscViewerASCIIPrintf(viewer,"  SOR: type = %s, iterations = %D, local iterations = %D, omega = %g\n",sortype,jac->its,jac->lits,(double)jac->omega);
111:   }
112:   return(0);
113: }


116: /* ------------------------------------------------------------------------------*/
119: static PetscErrorCode  PCSORSetSymmetric_SOR(PC pc,MatSORType flag)
120: {
121:   PC_SOR *jac = (PC_SOR*)pc->data;

124:   jac->sym = flag;
125:   return(0);
126: }

130: static PetscErrorCode  PCSORSetOmega_SOR(PC pc,PetscReal omega)
131: {
132:   PC_SOR *jac = (PC_SOR*)pc->data;

135:   if (omega >= 2.0 || omega <= 0.0) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_OUTOFRANGE,"Relaxation out of range");
136:   jac->omega = omega;
137:   return(0);
138: }

142: static PetscErrorCode  PCSORSetIterations_SOR(PC pc,PetscInt its,PetscInt lits)
143: {
144:   PC_SOR *jac = (PC_SOR*)pc->data;

147:   jac->its  = its;
148:   jac->lits = lits;
149:   return(0);
150: }

154: static PetscErrorCode  PCSORGetSymmetric_SOR(PC pc,MatSORType *flag)
155: {
156:   PC_SOR *jac = (PC_SOR*)pc->data;

159:   *flag = jac->sym;
160:   return(0);
161: }

165: static PetscErrorCode  PCSORGetOmega_SOR(PC pc,PetscReal *omega)
166: {
167:   PC_SOR *jac = (PC_SOR*)pc->data;

170:   *omega = jac->omega;
171:   return(0);
172: }

176: static PetscErrorCode  PCSORGetIterations_SOR(PC pc,PetscInt *its,PetscInt *lits)
177: {
178:   PC_SOR *jac = (PC_SOR*)pc->data;

181:   if (its)  *its = jac->its;
182:   if (lits) *lits = jac->lits;
183:   return(0);
184: }

186: /* ------------------------------------------------------------------------------*/
189: /*@
190:    PCSORGetSymmetric - Gets the form the SOR preconditioner is using;   backward, or forward relaxation.  The local variants perform SOR on
191:    each processor.  By default forward relaxation is used.

193:    Logically Collective on PC

195:    Input Parameter:
196: .  pc - the preconditioner context

198:    Output Parameter:
199: .  flag - one of the following
200: .vb
201:     SOR_FORWARD_SWEEP
202:     SOR_BACKWARD_SWEEP
203:     SOR_SYMMETRIC_SWEEP
204:     SOR_LOCAL_FORWARD_SWEEP
205:     SOR_LOCAL_BACKWARD_SWEEP
206:     SOR_LOCAL_SYMMETRIC_SWEEP
207: .ve

209:    Options Database Keys:
210: +  -pc_sor_symmetric - Activates symmetric version
211: .  -pc_sor_backward - Activates backward version
212: .  -pc_sor_local_forward - Activates local forward version
213: .  -pc_sor_local_symmetric - Activates local symmetric version
214: -  -pc_sor_local_backward - Activates local backward version

216:    Notes:
217:    To use the Eisenstat trick with SSOR, employ the PCEISENSTAT preconditioner,
218:    which can be chosen with the option
219: .  -pc_type eisenstat - Activates Eisenstat trick

221:    Level: intermediate

223: .keywords: PC, SOR, SSOR, set, relaxation, sweep, forward, backward, symmetric

225: .seealso: PCEisenstatSetOmega(), PCSORSetIterations(), PCSORSetOmega(), PCSORSetSymmetric()
226: @*/
227: PetscErrorCode  PCSORGetSymmetric(PC pc,MatSORType *flag)
228: {

233:   PetscUseMethod(pc,"PCSORGetSymmetric_C",(PC,MatSORType*),(pc,flag));
234:   return(0);
235: }

239: /*@
240:    PCSORGetOmega - Gets the SOR relaxation coefficient, omega
241:    (where omega = 1.0 by default).

243:    Logically Collective on PC

245:    Input Parameter:
246: .  pc - the preconditioner context

248:    Output Parameter:
249: .  omega - relaxation coefficient (0 < omega < 2).

251:    Options Database Key:
252: .  -pc_sor_omega <omega> - Sets omega

254:    Level: intermediate

256: .keywords: PC, SOR, SSOR, set, relaxation, omega

258: .seealso: PCSORSetSymmetric(), PCSORSetIterations(), PCEisenstatSetOmega(), PCSORSetOmega()
259: @*/
260: PetscErrorCode  PCSORGetOmega(PC pc,PetscReal *omega)
261: {

266:   PetscUseMethod(pc,"PCSORGetOmega_C",(PC,PetscReal*),(pc,omega));
267:   return(0);
268: }

272: /*@
273:    PCSORGetIterations - Gets the number of inner iterations to
274:    be used by the SOR preconditioner. The default is 1.

276:    Logically Collective on PC

278:    Input Parameter:
279: .  pc - the preconditioner context

281:    Output Parameter:
282: +  lits - number of local iterations, smoothings over just variables on processor
283: -  its - number of parallel iterations to use; each parallel iteration has lits local iterations

285:    Options Database Key:
286: +  -pc_sor_its <its> - Sets number of iterations
287: -  -pc_sor_lits <lits> - Sets number of local iterations

289:    Level: intermediate

291:    Notes: When run on one processor the number of smoothings is lits*its

293: .keywords: PC, SOR, SSOR, set, iterations

295: .seealso: PCSORSetOmega(), PCSORSetSymmetric(), PCSORSetIterations()
296: @*/
297: PetscErrorCode  PCSORGetIterations(PC pc,PetscInt *its,PetscInt *lits)
298: {

303:   PetscUseMethod(pc,"PCSORGetIterations_C",(PC,PetscInt*,PetscInt*),(pc,its,lits));
304:   return(0);
305: }

309: /*@
310:    PCSORSetSymmetric - Sets the SOR preconditioner to use symmetric (SSOR),
311:    backward, or forward relaxation.  The local variants perform SOR on
312:    each processor.  By default forward relaxation is used.

314:    Logically Collective on PC

316:    Input Parameters:
317: +  pc - the preconditioner context
318: -  flag - one of the following
319: .vb
320:     SOR_FORWARD_SWEEP
321:     SOR_BACKWARD_SWEEP
322:     SOR_SYMMETRIC_SWEEP
323:     SOR_LOCAL_FORWARD_SWEEP
324:     SOR_LOCAL_BACKWARD_SWEEP
325:     SOR_LOCAL_SYMMETRIC_SWEEP
326: .ve

328:    Options Database Keys:
329: +  -pc_sor_symmetric - Activates symmetric version
330: .  -pc_sor_backward - Activates backward version
331: .  -pc_sor_local_forward - Activates local forward version
332: .  -pc_sor_local_symmetric - Activates local symmetric version
333: -  -pc_sor_local_backward - Activates local backward version

335:    Notes:
336:    To use the Eisenstat trick with SSOR, employ the PCEISENSTAT preconditioner,
337:    which can be chosen with the option
338: .  -pc_type eisenstat - Activates Eisenstat trick

340:    Level: intermediate

342: .keywords: PC, SOR, SSOR, set, relaxation, sweep, forward, backward, symmetric

344: .seealso: PCEisenstatSetOmega(), PCSORSetIterations(), PCSORSetOmega()
345: @*/
346: PetscErrorCode  PCSORSetSymmetric(PC pc,MatSORType flag)
347: {

353:   PetscTryMethod(pc,"PCSORSetSymmetric_C",(PC,MatSORType),(pc,flag));
354:   return(0);
355: }

359: /*@
360:    PCSORSetOmega - Sets the SOR relaxation coefficient, omega
361:    (where omega = 1.0 by default).

363:    Logically Collective on PC

365:    Input Parameters:
366: +  pc - the preconditioner context
367: -  omega - relaxation coefficient (0 < omega < 2).

369:    Options Database Key:
370: .  -pc_sor_omega <omega> - Sets omega

372:    Level: intermediate

374: .keywords: PC, SOR, SSOR, set, relaxation, omega

376: .seealso: PCSORSetSymmetric(), PCSORSetIterations(), PCEisenstatSetOmega()
377: @*/
378: PetscErrorCode  PCSORSetOmega(PC pc,PetscReal omega)
379: {

385:   PetscTryMethod(pc,"PCSORSetOmega_C",(PC,PetscReal),(pc,omega));
386:   return(0);
387: }

391: /*@
392:    PCSORSetIterations - Sets the number of inner iterations to
393:    be used by the SOR preconditioner. The default is 1.

395:    Logically Collective on PC

397:    Input Parameters:
398: +  pc - the preconditioner context
399: .  lits - number of local iterations, smoothings over just variables on processor
400: -  its - number of parallel iterations to use; each parallel iteration has lits local iterations

402:    Options Database Key:
403: +  -pc_sor_its <its> - Sets number of iterations
404: -  -pc_sor_lits <lits> - Sets number of local iterations

406:    Level: intermediate

408:    Notes: When run on one processor the number of smoothings is lits*its

410: .keywords: PC, SOR, SSOR, set, iterations

412: .seealso: PCSORSetOmega(), PCSORSetSymmetric()
413: @*/
414: PetscErrorCode  PCSORSetIterations(PC pc,PetscInt its,PetscInt lits)
415: {

421:   PetscTryMethod(pc,"PCSORSetIterations_C",(PC,PetscInt,PetscInt),(pc,its,lits));
422:   return(0);
423: }

425: /*MC
426:      PCSOR - (S)SOR (successive over relaxation, Gauss-Seidel) preconditioning

428:    Options Database Keys:
429: +  -pc_sor_symmetric - Activates symmetric version
430: .  -pc_sor_backward - Activates backward version
431: .  -pc_sor_forward - Activates forward version
432: .  -pc_sor_local_forward - Activates local forward version
433: .  -pc_sor_local_symmetric - Activates local symmetric version  (default version)
434: .  -pc_sor_local_backward - Activates local backward version
435: .  -pc_sor_omega <omega> - Sets omega
436: .  -pc_sor_its <its> - Sets number of iterations   (default 1)
437: -  -pc_sor_lits <lits> - Sets number of local iterations  (default 1)

439:    Level: beginner

441:   Concepts: SOR, preconditioners, Gauss-Seidel

443:    Notes: Only implemented for the AIJ  and SeqBAIJ matrix formats.
444:           Not a true parallel SOR, in parallel this implementation corresponds to block
445:           Jacobi with SOR on each block.

447:           For SeqBAIJ matrices this implements point-block SOR, but the omega, its, lits options are not supported.

449: .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
450:            PCSORSetIterations(), PCSORSetSymmetric(), PCSORSetOmega(), PCEISENSTAT
451: M*/

455: PETSC_EXTERN PetscErrorCode PCCreate_SOR(PC pc)
456: {
458:   PC_SOR         *jac;

461:   PetscNewLog(pc,&jac);

463:   pc->ops->apply           = PCApply_SOR;
464:   pc->ops->applyrichardson = PCApplyRichardson_SOR;
465:   pc->ops->setfromoptions  = PCSetFromOptions_SOR;
466:   pc->ops->setup           = 0;
467:   pc->ops->view            = PCView_SOR;
468:   pc->ops->destroy         = PCDestroy_SOR;
469:   pc->data                 = (void*)jac;
470:   jac->sym                 = SOR_LOCAL_SYMMETRIC_SWEEP;
471:   jac->omega               = 1.0;
472:   jac->fshift              = 0.0;
473:   jac->its                 = 1;
474:   jac->lits                = 1;

476:   PetscObjectComposeFunction((PetscObject)pc,"PCSORSetSymmetric_C",PCSORSetSymmetric_SOR);
477:   PetscObjectComposeFunction((PetscObject)pc,"PCSORSetOmega_C",PCSORSetOmega_SOR);
478:   PetscObjectComposeFunction((PetscObject)pc,"PCSORSetIterations_C",PCSORSetIterations_SOR);
479:   PetscObjectComposeFunction((PetscObject)pc,"PCSORGetSymmetric_C",PCSORGetSymmetric_SOR);
480:   PetscObjectComposeFunction((PetscObject)pc,"PCSORGetOmega_C",PCSORGetOmega_SOR);
481:   PetscObjectComposeFunction((PetscObject)pc,"PCSORGetIterations_C",PCSORGetIterations_SOR);
482:   return(0);
483: }