xref: /petsc/src/ksp/pc/impls/sor/sor.c (revision f1580f4e3ce5d5b2393648fd039d0d41b440385d)
14b9ad928SBarry Smith /*
24b9ad928SBarry Smith    Defines a  (S)SOR  preconditioner for any Mat implementation
34b9ad928SBarry Smith */
4af0996ceSBarry Smith #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/
54b9ad928SBarry Smith 
64b9ad928SBarry Smith typedef struct {
7c1ac3661SBarry Smith   PetscInt   its;  /* inner iterations, number of sweeps */
8c1ac3661SBarry Smith   PetscInt   lits; /* local inner iterations, number of sweeps applied by the local matrix mat->A */
94b9ad928SBarry Smith   MatSORType sym;  /* forward, reverse, symmetric etc. */
104b9ad928SBarry Smith   PetscReal  omega;
1129c1d7e0SHong Zhang   PetscReal  fshift;
124b9ad928SBarry Smith } PC_SOR;
134b9ad928SBarry Smith 
149371c9d4SSatish Balay static PetscErrorCode PCDestroy_SOR(PC pc) {
154b9ad928SBarry Smith   PetscFunctionBegin;
162e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORSetSymmetric_C", NULL));
172e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORSetOmega_C", NULL));
182e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORSetIterations_C", NULL));
192e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORGetSymmetric_C", NULL));
202e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORGetOmega_C", NULL));
212e956fe4SStefano Zampini   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORGetIterations_C", NULL));
229566063dSJacob Faibussowitsch   PetscCall(PetscFree(pc->data));
234b9ad928SBarry Smith   PetscFunctionReturn(0);
244b9ad928SBarry Smith }
254b9ad928SBarry Smith 
269371c9d4SSatish Balay static PetscErrorCode PCApply_SOR(PC pc, Vec x, Vec y) {
274b9ad928SBarry Smith   PC_SOR  *jac  = (PC_SOR *)pc->data;
28c1ac3661SBarry Smith   PetscInt flag = jac->sym | SOR_ZERO_INITIAL_GUESS;
294b9ad928SBarry Smith 
304b9ad928SBarry Smith   PetscFunctionBegin;
319566063dSJacob Faibussowitsch   PetscCall(MatSOR(pc->pmat, x, jac->omega, (MatSORType)flag, jac->fshift, jac->its, jac->lits, y));
329566063dSJacob Faibussowitsch   PetscCall(MatFactorGetError(pc->pmat, (MatFactorError *)&pc->failedreason));
334b9ad928SBarry Smith   PetscFunctionReturn(0);
344b9ad928SBarry Smith }
354b9ad928SBarry Smith 
369371c9d4SSatish Balay static PetscErrorCode PCApplyTranspose_SOR(PC pc, Vec x, Vec y) {
379d2471e0SBarry Smith   PC_SOR   *jac  = (PC_SOR *)pc->data;
389d2471e0SBarry Smith   PetscInt  flag = jac->sym | SOR_ZERO_INITIAL_GUESS;
399d2471e0SBarry Smith   PetscBool set, sym;
409d2471e0SBarry Smith 
419d2471e0SBarry Smith   PetscFunctionBegin;
429566063dSJacob Faibussowitsch   PetscCall(MatIsSymmetricKnown(pc->pmat, &set, &sym));
437827d75bSBarry Smith   PetscCheck(set && sym && (jac->sym == SOR_SYMMETRIC_SWEEP || jac->sym == SOR_LOCAL_SYMMETRIC_SWEEP), PetscObjectComm((PetscObject)pc), PETSC_ERR_SUP, "Can only apply transpose of SOR if matrix is symmetric and sweep is symmetric");
449566063dSJacob Faibussowitsch   PetscCall(MatSOR(pc->pmat, x, jac->omega, (MatSORType)flag, jac->fshift, jac->its, jac->lits, y));
459566063dSJacob Faibussowitsch   PetscCall(MatFactorGetError(pc->pmat, (MatFactorError *)&pc->failedreason));
469d2471e0SBarry Smith   PetscFunctionReturn(0);
479d2471e0SBarry Smith }
489d2471e0SBarry Smith 
499371c9d4SSatish Balay 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) {
504b9ad928SBarry Smith   PC_SOR    *jac   = (PC_SOR *)pc->data;
517319c654SBarry Smith   MatSORType stype = jac->sym;
524b9ad928SBarry Smith 
534b9ad928SBarry Smith   PetscFunctionBegin;
5463a3b9bcSJacob Faibussowitsch   PetscCall(PetscInfo(pc, "Warning, convergence critera ignored, using %" PetscInt_FMT " iterations\n", its));
552fa5cd67SKarl Rupp   if (guesszero) stype = (MatSORType)(stype | SOR_ZERO_INITIAL_GUESS);
569566063dSJacob Faibussowitsch   PetscCall(MatSOR(pc->pmat, b, jac->omega, stype, jac->fshift, its * jac->its, jac->lits, y));
579566063dSJacob Faibussowitsch   PetscCall(MatFactorGetError(pc->pmat, (MatFactorError *)&pc->failedreason));
584d0a8057SBarry Smith   *outits = its;
594d0a8057SBarry Smith   *reason = PCRICHARDSON_CONVERGED_ITS;
604b9ad928SBarry Smith   PetscFunctionReturn(0);
614b9ad928SBarry Smith }
624b9ad928SBarry Smith 
639371c9d4SSatish Balay PetscErrorCode PCSetFromOptions_SOR(PC pc, PetscOptionItems *PetscOptionsObject) {
644b9ad928SBarry Smith   PC_SOR   *jac = (PC_SOR *)pc->data;
65ace3abfcSBarry Smith   PetscBool flg;
664b9ad928SBarry Smith 
674b9ad928SBarry Smith   PetscFunctionBegin;
68d0609cedSBarry Smith   PetscOptionsHeadBegin(PetscOptionsObject, "(S)SOR options");
699566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_sor_omega", "relaxation factor (0 < omega < 2)", "PCSORSetOmega", jac->omega, &jac->omega, NULL));
709566063dSJacob Faibussowitsch   PetscCall(PetscOptionsReal("-pc_sor_diagonal_shift", "Add to the diagonal entries", "", jac->fshift, &jac->fshift, NULL));
719566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_sor_its", "number of inner SOR iterations", "PCSORSetIterations", jac->its, &jac->its, NULL));
729566063dSJacob Faibussowitsch   PetscCall(PetscOptionsInt("-pc_sor_lits", "number of local inner SOR iterations", "PCSORSetIterations", jac->lits, &jac->lits, NULL));
739566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoolGroupBegin("-pc_sor_symmetric", "SSOR, not SOR", "PCSORSetSymmetric", &flg));
749566063dSJacob Faibussowitsch   if (flg) PetscCall(PCSORSetSymmetric(pc, SOR_SYMMETRIC_SWEEP));
759566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoolGroup("-pc_sor_backward", "use backward sweep instead of forward", "PCSORSetSymmetric", &flg));
769566063dSJacob Faibussowitsch   if (flg) PetscCall(PCSORSetSymmetric(pc, SOR_BACKWARD_SWEEP));
779566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoolGroup("-pc_sor_forward", "use forward sweep", "PCSORSetSymmetric", &flg));
789566063dSJacob Faibussowitsch   if (flg) PetscCall(PCSORSetSymmetric(pc, SOR_FORWARD_SWEEP));
799566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoolGroup("-pc_sor_local_symmetric", "use SSOR separately on each processor", "PCSORSetSymmetric", &flg));
809566063dSJacob Faibussowitsch   if (flg) PetscCall(PCSORSetSymmetric(pc, SOR_LOCAL_SYMMETRIC_SWEEP));
819566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoolGroup("-pc_sor_local_backward", "use backward sweep locally", "PCSORSetSymmetric", &flg));
829566063dSJacob Faibussowitsch   if (flg) PetscCall(PCSORSetSymmetric(pc, SOR_LOCAL_BACKWARD_SWEEP));
839566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBoolGroupEnd("-pc_sor_local_forward", "use forward sweep locally", "PCSORSetSymmetric", &flg));
849566063dSJacob Faibussowitsch   if (flg) PetscCall(PCSORSetSymmetric(pc, SOR_LOCAL_FORWARD_SWEEP));
85d0609cedSBarry Smith   PetscOptionsHeadEnd();
864b9ad928SBarry Smith   PetscFunctionReturn(0);
874b9ad928SBarry Smith }
884b9ad928SBarry Smith 
899371c9d4SSatish Balay PetscErrorCode PCView_SOR(PC pc, PetscViewer viewer) {
904b9ad928SBarry Smith   PC_SOR     *jac = (PC_SOR *)pc->data;
914b9ad928SBarry Smith   MatSORType  sym = jac->sym;
922fc52814SBarry Smith   const char *sortype;
93ace3abfcSBarry Smith   PetscBool   iascii;
944b9ad928SBarry Smith 
954b9ad928SBarry Smith   PetscFunctionBegin;
969566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii));
9732077d6dSBarry Smith   if (iascii) {
989566063dSJacob Faibussowitsch     if (sym & SOR_ZERO_INITIAL_GUESS) PetscCall(PetscViewerASCIIPrintf(viewer, "  zero initial guess\n"));
994b9ad928SBarry Smith     if (sym == SOR_APPLY_UPPER) sortype = "apply_upper";
1004b9ad928SBarry Smith     else if (sym == SOR_APPLY_LOWER) sortype = "apply_lower";
1014b9ad928SBarry Smith     else if (sym & SOR_EISENSTAT) sortype = "Eisenstat";
102db4deed7SKarl Rupp     else if ((sym & SOR_SYMMETRIC_SWEEP) == SOR_SYMMETRIC_SWEEP) sortype = "symmetric";
1034b9ad928SBarry Smith     else if (sym & SOR_BACKWARD_SWEEP) sortype = "backward";
1044b9ad928SBarry Smith     else if (sym & SOR_FORWARD_SWEEP) sortype = "forward";
105db4deed7SKarl Rupp     else if ((sym & SOR_LOCAL_SYMMETRIC_SWEEP) == SOR_LOCAL_SYMMETRIC_SWEEP) sortype = "local_symmetric";
1064b9ad928SBarry Smith     else if (sym & SOR_LOCAL_FORWARD_SWEEP) sortype = "local_forward";
1074b9ad928SBarry Smith     else if (sym & SOR_LOCAL_BACKWARD_SWEEP) sortype = "local_backward";
1084b9ad928SBarry Smith     else sortype = "unknown";
10963a3b9bcSJacob Faibussowitsch     PetscCall(PetscViewerASCIIPrintf(viewer, "  type = %s, iterations = %" PetscInt_FMT ", local iterations = %" PetscInt_FMT ", omega = %g\n", sortype, jac->its, jac->lits, (double)jac->omega));
1104b9ad928SBarry Smith   }
1114b9ad928SBarry Smith   PetscFunctionReturn(0);
1124b9ad928SBarry Smith }
1134b9ad928SBarry Smith 
1149371c9d4SSatish Balay static PetscErrorCode PCSORSetSymmetric_SOR(PC pc, MatSORType flag) {
115c60c7ad4SBarry Smith   PC_SOR *jac = (PC_SOR *)pc->data;
1164b9ad928SBarry Smith 
1174b9ad928SBarry Smith   PetscFunctionBegin;
1184b9ad928SBarry Smith   jac->sym = flag;
1194b9ad928SBarry Smith   PetscFunctionReturn(0);
1204b9ad928SBarry Smith }
1214b9ad928SBarry Smith 
1229371c9d4SSatish Balay static PetscErrorCode PCSORSetOmega_SOR(PC pc, PetscReal omega) {
123c60c7ad4SBarry Smith   PC_SOR *jac = (PC_SOR *)pc->data;
1244b9ad928SBarry Smith 
1254b9ad928SBarry Smith   PetscFunctionBegin;
1262472a847SBarry Smith   PetscCheck(omega > 0.0 && omega < 2.0, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_OUTOFRANGE, "Relaxation out of range");
1274b9ad928SBarry Smith   jac->omega = omega;
1284b9ad928SBarry Smith   PetscFunctionReturn(0);
1294b9ad928SBarry Smith }
1304b9ad928SBarry Smith 
1319371c9d4SSatish Balay static PetscErrorCode PCSORSetIterations_SOR(PC pc, PetscInt its, PetscInt lits) {
132c60c7ad4SBarry Smith   PC_SOR *jac = (PC_SOR *)pc->data;
1334b9ad928SBarry Smith 
1344b9ad928SBarry Smith   PetscFunctionBegin;
1354b9ad928SBarry Smith   jac->its  = its;
1364b9ad928SBarry Smith   jac->lits = lits;
1374b9ad928SBarry Smith   PetscFunctionReturn(0);
1384b9ad928SBarry Smith }
1394b9ad928SBarry Smith 
1409371c9d4SSatish Balay static PetscErrorCode PCSORGetSymmetric_SOR(PC pc, MatSORType *flag) {
141c60c7ad4SBarry Smith   PC_SOR *jac = (PC_SOR *)pc->data;
142c60c7ad4SBarry Smith 
143c60c7ad4SBarry Smith   PetscFunctionBegin;
144c60c7ad4SBarry Smith   *flag = jac->sym;
145c60c7ad4SBarry Smith   PetscFunctionReturn(0);
146c60c7ad4SBarry Smith }
147c60c7ad4SBarry Smith 
1489371c9d4SSatish Balay static PetscErrorCode PCSORGetOmega_SOR(PC pc, PetscReal *omega) {
149c60c7ad4SBarry Smith   PC_SOR *jac = (PC_SOR *)pc->data;
150c60c7ad4SBarry Smith 
151c60c7ad4SBarry Smith   PetscFunctionBegin;
152c60c7ad4SBarry Smith   *omega = jac->omega;
153c60c7ad4SBarry Smith   PetscFunctionReturn(0);
154c60c7ad4SBarry Smith }
155c60c7ad4SBarry Smith 
1569371c9d4SSatish Balay static PetscErrorCode PCSORGetIterations_SOR(PC pc, PetscInt *its, PetscInt *lits) {
157c60c7ad4SBarry Smith   PC_SOR *jac = (PC_SOR *)pc->data;
158c60c7ad4SBarry Smith 
159c60c7ad4SBarry Smith   PetscFunctionBegin;
160c60c7ad4SBarry Smith   if (its) *its = jac->its;
161c60c7ad4SBarry Smith   if (lits) *lits = jac->lits;
162c60c7ad4SBarry Smith   PetscFunctionReturn(0);
163c60c7ad4SBarry Smith }
164c60c7ad4SBarry Smith 
165c60c7ad4SBarry Smith /*@
1661ff2113eSBarry Smith    PCSORGetSymmetric - Gets the form the SOR preconditioner is using;   backward, or forward relaxation.  The local variants perform SOR on
167c60c7ad4SBarry Smith    each processor.  By default forward relaxation is used.
168c60c7ad4SBarry Smith 
169*f1580f4eSBarry Smith    Logically Collective on pc
170c60c7ad4SBarry Smith 
171c60c7ad4SBarry Smith    Input Parameter:
172c60c7ad4SBarry Smith .  pc - the preconditioner context
173c60c7ad4SBarry Smith 
174c60c7ad4SBarry Smith    Output Parameter:
175c60c7ad4SBarry Smith .  flag - one of the following
176c60c7ad4SBarry Smith .vb
177c60c7ad4SBarry Smith     SOR_FORWARD_SWEEP
178c60c7ad4SBarry Smith     SOR_BACKWARD_SWEEP
179c60c7ad4SBarry Smith     SOR_SYMMETRIC_SWEEP
180c60c7ad4SBarry Smith     SOR_LOCAL_FORWARD_SWEEP
181c60c7ad4SBarry Smith     SOR_LOCAL_BACKWARD_SWEEP
182c60c7ad4SBarry Smith     SOR_LOCAL_SYMMETRIC_SWEEP
183c60c7ad4SBarry Smith .ve
184c60c7ad4SBarry Smith 
185c60c7ad4SBarry Smith    Options Database Keys:
186c60c7ad4SBarry Smith +  -pc_sor_symmetric - Activates symmetric version
187c60c7ad4SBarry Smith .  -pc_sor_backward - Activates backward version
188c60c7ad4SBarry Smith .  -pc_sor_local_forward - Activates local forward version
189c60c7ad4SBarry Smith .  -pc_sor_local_symmetric - Activates local symmetric version
190c60c7ad4SBarry Smith -  -pc_sor_local_backward - Activates local backward version
191c60c7ad4SBarry Smith 
192*f1580f4eSBarry Smith    Note:
193*f1580f4eSBarry Smith    To use the Eisenstat trick with SSOR, employ the `PCEISENSTAT` preconditioner,
194c60c7ad4SBarry Smith    which can be chosen with the option
195c60c7ad4SBarry Smith .  -pc_type eisenstat - Activates Eisenstat trick
196c60c7ad4SBarry Smith 
197c60c7ad4SBarry Smith    Level: intermediate
198c60c7ad4SBarry Smith 
199*f1580f4eSBarry Smith .seealso: `PCSOR`, `PCEisenstatSetOmega()`, `PCSORSetIterations()`, `PCSORSetOmega()`, `PCSORSetSymmetric()`
200c60c7ad4SBarry Smith @*/
2019371c9d4SSatish Balay PetscErrorCode PCSORGetSymmetric(PC pc, MatSORType *flag) {
202c60c7ad4SBarry Smith   PetscFunctionBegin;
203c60c7ad4SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
204cac4c232SBarry Smith   PetscUseMethod(pc, "PCSORGetSymmetric_C", (PC, MatSORType *), (pc, flag));
205c60c7ad4SBarry Smith   PetscFunctionReturn(0);
206c60c7ad4SBarry Smith }
207c60c7ad4SBarry Smith 
208c60c7ad4SBarry Smith /*@
209c60c7ad4SBarry Smith    PCSORGetOmega - Gets the SOR relaxation coefficient, omega
210c60c7ad4SBarry Smith    (where omega = 1.0 by default).
211c60c7ad4SBarry Smith 
212*f1580f4eSBarry Smith    Logically Collective on pc
213c60c7ad4SBarry Smith 
214c60c7ad4SBarry Smith    Input Parameter:
215c60c7ad4SBarry Smith .  pc - the preconditioner context
216c60c7ad4SBarry Smith 
217c60c7ad4SBarry Smith    Output Parameter:
218c60c7ad4SBarry Smith .  omega - relaxation coefficient (0 < omega < 2).
219c60c7ad4SBarry Smith 
220c60c7ad4SBarry Smith    Options Database Key:
221c60c7ad4SBarry Smith .  -pc_sor_omega <omega> - Sets omega
222c60c7ad4SBarry Smith 
223c60c7ad4SBarry Smith    Level: intermediate
224c60c7ad4SBarry Smith 
225*f1580f4eSBarry Smith .seealso: `PCSOR`, `PCSORSetSymmetric()`, `PCSORSetIterations()`, `PCEisenstatSetOmega()`, `PCSORSetOmega()`
226c60c7ad4SBarry Smith @*/
2279371c9d4SSatish Balay PetscErrorCode PCSORGetOmega(PC pc, PetscReal *omega) {
228c60c7ad4SBarry Smith   PetscFunctionBegin;
229c60c7ad4SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
230cac4c232SBarry Smith   PetscUseMethod(pc, "PCSORGetOmega_C", (PC, PetscReal *), (pc, omega));
231c60c7ad4SBarry Smith   PetscFunctionReturn(0);
232c60c7ad4SBarry Smith }
233c60c7ad4SBarry Smith 
234c60c7ad4SBarry Smith /*@
235c60c7ad4SBarry Smith    PCSORGetIterations - Gets the number of inner iterations to
236c60c7ad4SBarry Smith    be used by the SOR preconditioner. The default is 1.
237c60c7ad4SBarry Smith 
238*f1580f4eSBarry Smith    Logically Collective on pc
239c60c7ad4SBarry Smith 
240c60c7ad4SBarry Smith    Input Parameter:
241c60c7ad4SBarry Smith .  pc - the preconditioner context
242c60c7ad4SBarry Smith 
243d8d19677SJose E. Roman    Output Parameters:
244c60c7ad4SBarry Smith +  lits - number of local iterations, smoothings over just variables on processor
245c60c7ad4SBarry Smith -  its - number of parallel iterations to use; each parallel iteration has lits local iterations
246c60c7ad4SBarry Smith 
247*f1580f4eSBarry Smith    Options Database Keys:
248c60c7ad4SBarry Smith +  -pc_sor_its <its> - Sets number of iterations
249c60c7ad4SBarry Smith -  -pc_sor_lits <lits> - Sets number of local iterations
250c60c7ad4SBarry Smith 
251c60c7ad4SBarry Smith    Level: intermediate
252c60c7ad4SBarry Smith 
253*f1580f4eSBarry Smith    Note:
25495452b02SPatrick Sanan     When run on one processor the number of smoothings is lits*its
255c60c7ad4SBarry Smith 
256*f1580f4eSBarry Smith .seealso: `PCSOR`, `PCSORSetOmega()`, `PCSORSetSymmetric()`, `PCSORSetIterations()`
257c60c7ad4SBarry Smith @*/
2589371c9d4SSatish Balay PetscErrorCode PCSORGetIterations(PC pc, PetscInt *its, PetscInt *lits) {
259c60c7ad4SBarry Smith   PetscFunctionBegin;
260c60c7ad4SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
261cac4c232SBarry Smith   PetscUseMethod(pc, "PCSORGetIterations_C", (PC, PetscInt *, PetscInt *), (pc, its, lits));
262c60c7ad4SBarry Smith   PetscFunctionReturn(0);
263c60c7ad4SBarry Smith }
264c60c7ad4SBarry Smith 
2654b9ad928SBarry Smith /*@
2664b9ad928SBarry Smith    PCSORSetSymmetric - Sets the SOR preconditioner to use symmetric (SSOR),
2674b9ad928SBarry Smith    backward, or forward relaxation.  The local variants perform SOR on
2684b9ad928SBarry Smith    each processor.  By default forward relaxation is used.
2694b9ad928SBarry Smith 
270*f1580f4eSBarry Smith    Logically Collective on pc
2714b9ad928SBarry Smith 
2724b9ad928SBarry Smith    Input Parameters:
2734b9ad928SBarry Smith +  pc - the preconditioner context
2744b9ad928SBarry Smith -  flag - one of the following
2754b9ad928SBarry Smith .vb
2764b9ad928SBarry Smith     SOR_FORWARD_SWEEP
2774b9ad928SBarry Smith     SOR_BACKWARD_SWEEP
2784b9ad928SBarry Smith     SOR_SYMMETRIC_SWEEP
2794b9ad928SBarry Smith     SOR_LOCAL_FORWARD_SWEEP
2804b9ad928SBarry Smith     SOR_LOCAL_BACKWARD_SWEEP
2814b9ad928SBarry Smith     SOR_LOCAL_SYMMETRIC_SWEEP
2824b9ad928SBarry Smith .ve
2834b9ad928SBarry Smith 
2844b9ad928SBarry Smith    Options Database Keys:
2854b9ad928SBarry Smith +  -pc_sor_symmetric - Activates symmetric version
2864b9ad928SBarry Smith .  -pc_sor_backward - Activates backward version
2874b9ad928SBarry Smith .  -pc_sor_local_forward - Activates local forward version
2884b9ad928SBarry Smith .  -pc_sor_local_symmetric - Activates local symmetric version
2894b9ad928SBarry Smith -  -pc_sor_local_backward - Activates local backward version
2904b9ad928SBarry Smith 
291*f1580f4eSBarry Smith    Note:
2924b9ad928SBarry Smith    To use the Eisenstat trick with SSOR, employ the PCEISENSTAT preconditioner,
2934b9ad928SBarry Smith    which can be chosen with the option
2944b9ad928SBarry Smith .  -pc_type eisenstat - Activates Eisenstat trick
2954b9ad928SBarry Smith 
2964b9ad928SBarry Smith    Level: intermediate
2974b9ad928SBarry Smith 
298*f1580f4eSBarry Smith .seealso: `PCSOR`, `PCEisenstatSetOmega()`, `PCSORSetIterations()`, `PCSORSetOmega()`
2994b9ad928SBarry Smith @*/
3009371c9d4SSatish Balay PetscErrorCode PCSORSetSymmetric(PC pc, MatSORType flag) {
3014b9ad928SBarry Smith   PetscFunctionBegin;
3020700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
303c5eb9154SBarry Smith   PetscValidLogicalCollectiveEnum(pc, flag, 2);
304cac4c232SBarry Smith   PetscTryMethod(pc, "PCSORSetSymmetric_C", (PC, MatSORType), (pc, flag));
3054b9ad928SBarry Smith   PetscFunctionReturn(0);
3064b9ad928SBarry Smith }
3074b9ad928SBarry Smith 
3084b9ad928SBarry Smith /*@
3094b9ad928SBarry Smith    PCSORSetOmega - Sets the SOR relaxation coefficient, omega
3104b9ad928SBarry Smith    (where omega = 1.0 by default).
3114b9ad928SBarry Smith 
312*f1580f4eSBarry Smith    Logically Collective on pc
3134b9ad928SBarry Smith 
3144b9ad928SBarry Smith    Input Parameters:
3154b9ad928SBarry Smith +  pc - the preconditioner context
3164b9ad928SBarry Smith -  omega - relaxation coefficient (0 < omega < 2).
3174b9ad928SBarry Smith 
3184b9ad928SBarry Smith    Options Database Key:
3194b9ad928SBarry Smith .  -pc_sor_omega <omega> - Sets omega
3204b9ad928SBarry Smith 
3214b9ad928SBarry Smith    Level: intermediate
3224b9ad928SBarry Smith 
323485168efSMatthew Knepley    Note:
324*f1580f4eSBarry Smith    If omega != 1, you will need to set the `MAT_USE_INODE`S option to `PETSC_FALSE` on the matrix.
325485168efSMatthew Knepley 
326*f1580f4eSBarry Smith .seealso: `PCSOR`, `PCSORSetSymmetric()`, `PCSORSetIterations()`, `PCEisenstatSetOmega()`, `MatSetOption()`
3274b9ad928SBarry Smith @*/
3289371c9d4SSatish Balay PetscErrorCode PCSORSetOmega(PC pc, PetscReal omega) {
3294b9ad928SBarry Smith   PetscFunctionBegin;
330c5eb9154SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
331c5eb9154SBarry Smith   PetscValidLogicalCollectiveReal(pc, omega, 2);
332cac4c232SBarry Smith   PetscTryMethod(pc, "PCSORSetOmega_C", (PC, PetscReal), (pc, omega));
3334b9ad928SBarry Smith   PetscFunctionReturn(0);
3344b9ad928SBarry Smith }
3354b9ad928SBarry Smith 
3364b9ad928SBarry Smith /*@
3374b9ad928SBarry Smith    PCSORSetIterations - Sets the number of inner iterations to
3384b9ad928SBarry Smith    be used by the SOR preconditioner. The default is 1.
3394b9ad928SBarry Smith 
340*f1580f4eSBarry Smith    Logically Collective on pc
3414b9ad928SBarry Smith 
3424b9ad928SBarry Smith    Input Parameters:
3434b9ad928SBarry Smith +  pc - the preconditioner context
3444b9ad928SBarry Smith .  lits - number of local iterations, smoothings over just variables on processor
3454b9ad928SBarry Smith -  its - number of parallel iterations to use; each parallel iteration has lits local iterations
3464b9ad928SBarry Smith 
347*f1580f4eSBarry Smith    Options Database Keys:
3484b9ad928SBarry Smith +  -pc_sor_its <its> - Sets number of iterations
3494b9ad928SBarry Smith -  -pc_sor_lits <lits> - Sets number of local iterations
3504b9ad928SBarry Smith 
3514b9ad928SBarry Smith    Level: intermediate
3524b9ad928SBarry Smith 
353*f1580f4eSBarry Smith    Note:
35495452b02SPatrick Sanan     When run on one processor the number of smoothings is lits*its
3554b9ad928SBarry Smith 
356*f1580f4eSBarry Smith .seealso: `PCSOR`, `PCSORSetOmega()`, `PCSORSetSymmetric()`
3574b9ad928SBarry Smith @*/
3589371c9d4SSatish Balay PetscErrorCode PCSORSetIterations(PC pc, PetscInt its, PetscInt lits) {
3594b9ad928SBarry Smith   PetscFunctionBegin;
3600700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
361c5eb9154SBarry Smith   PetscValidLogicalCollectiveInt(pc, its, 2);
362cac4c232SBarry Smith   PetscTryMethod(pc, "PCSORSetIterations_C", (PC, PetscInt, PetscInt), (pc, its, lits));
3634b9ad928SBarry Smith   PetscFunctionReturn(0);
3644b9ad928SBarry Smith }
3654b9ad928SBarry Smith 
3664b9ad928SBarry Smith /*MC
3674b9ad928SBarry Smith      PCSOR - (S)SOR (successive over relaxation, Gauss-Seidel) preconditioning
3684b9ad928SBarry Smith 
3694b9ad928SBarry Smith    Options Database Keys:
3704b9ad928SBarry Smith +  -pc_sor_symmetric - Activates symmetric version
3714b9ad928SBarry Smith .  -pc_sor_backward - Activates backward version
372a9510f2eSBarry Smith .  -pc_sor_forward - Activates forward version
3734b9ad928SBarry Smith .  -pc_sor_local_forward - Activates local forward version
374a9510f2eSBarry Smith .  -pc_sor_local_symmetric - Activates local symmetric version  (default version)
3754b9ad928SBarry Smith .  -pc_sor_local_backward - Activates local backward version
3764b9ad928SBarry Smith .  -pc_sor_omega <omega> - Sets omega
377422a814eSBarry Smith .  -pc_sor_diagonal_shift <shift> - shift the diagonal entries; useful if the matrix has zeros on the diagonal
378a9510f2eSBarry Smith .  -pc_sor_its <its> - Sets number of iterations   (default 1)
379a9510f2eSBarry Smith -  -pc_sor_lits <lits> - Sets number of local iterations  (default 1)
3804b9ad928SBarry Smith 
3814b9ad928SBarry Smith    Level: beginner
3824b9ad928SBarry Smith 
38395452b02SPatrick Sanan    Notes:
384*f1580f4eSBarry Smith    Only implemented for the `MATAIJ`  and `MATSEQBAIJ` matrix formats.
385*f1580f4eSBarry Smith 
3864b9ad928SBarry Smith    Not a true parallel SOR, in parallel this implementation corresponds to block
3874b9ad928SBarry Smith    Jacobi with SOR on each block.
3884b9ad928SBarry Smith 
389*f1580f4eSBarry Smith           For `MATAIJ` matrices if a diagonal entry is zero (and the diagonal shift is zero) then by default the inverse of that
390*f1580f4eSBarry Smith           zero will be used and hence the `KSPSolve()` will terminate with `KSP_DIVERGED_NANORIF`. If the option
391*f1580f4eSBarry Smith           `KSPSetErrorIfNotConverged()` or -ksp_error_if_not_converged the code will terminate as soon as it detects the
392422a814eSBarry Smith           zero pivot.
393422a814eSBarry Smith 
394*f1580f4eSBarry Smith           For `MATSEQBAIJ` matrices this implements point-block SOR, but the omega, its, lits options are not supported.
39537a17b4dSBarry Smith 
396*f1580f4eSBarry Smith           For `MATSEQBAIJ` the diagonal blocks are inverted using dense LU with partial pivoting. If a zero pivot is detected
397422a814eSBarry Smith           the computation is stopped with an error
398422a814eSBarry Smith 
399*f1580f4eSBarry Smith           If used with `KSPRICHARDSON` and no monitors the convergence test is skipped to improve speed, thus it always iterates
400*f1580f4eSBarry Smith           the maximum number of iterations you've selected for `KSP`. It is usually used in this mode as a smoother for multigrid.
40167991ba4SBarry Smith 
402*f1580f4eSBarry Smith           If omega != 1, you will need to set the `MAT_USE_INODES` option to `PETSC_FALSE` on the matrix.
403485168efSMatthew Knepley 
404*f1580f4eSBarry Smith .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCJACOBI`,
405db781477SPatrick Sanan           `PCSORSetIterations()`, `PCSORSetSymmetric()`, `PCSORSetOmega()`, `PCEISENSTAT`, `MatSetOption()`
4064b9ad928SBarry Smith M*/
4074b9ad928SBarry Smith 
4089371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PCCreate_SOR(PC pc) {
4094b9ad928SBarry Smith   PC_SOR *jac;
4104b9ad928SBarry Smith 
4114b9ad928SBarry Smith   PetscFunctionBegin;
4129566063dSJacob Faibussowitsch   PetscCall(PetscNewLog(pc, &jac));
4134b9ad928SBarry Smith 
4144b9ad928SBarry Smith   pc->ops->apply           = PCApply_SOR;
4159d2471e0SBarry Smith   pc->ops->applytranspose  = PCApplyTranspose_SOR;
4164b9ad928SBarry Smith   pc->ops->applyrichardson = PCApplyRichardson_SOR;
4174b9ad928SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_SOR;
4180a545947SLisandro Dalcin   pc->ops->setup           = NULL;
4194b9ad928SBarry Smith   pc->ops->view            = PCView_SOR;
4204b9ad928SBarry Smith   pc->ops->destroy         = PCDestroy_SOR;
4214b9ad928SBarry Smith   pc->data                 = (void *)jac;
422d9bc8e36SBarry Smith   jac->sym                 = SOR_LOCAL_SYMMETRIC_SWEEP;
4234b9ad928SBarry Smith   jac->omega               = 1.0;
42496fc60bcSBarry Smith   jac->fshift              = 0.0;
4254b9ad928SBarry Smith   jac->its                 = 1;
4264b9ad928SBarry Smith   jac->lits                = 1;
4274b9ad928SBarry Smith 
4289566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORSetSymmetric_C", PCSORSetSymmetric_SOR));
4299566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORSetOmega_C", PCSORSetOmega_SOR));
4309566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORSetIterations_C", PCSORSetIterations_SOR));
4319566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORGetSymmetric_C", PCSORGetSymmetric_SOR));
4329566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORGetOmega_C", PCSORGetOmega_SOR));
4339566063dSJacob Faibussowitsch   PetscCall(PetscObjectComposeFunction((PetscObject)pc, "PCSORGetIterations_C", PCSORGetIterations_SOR));
4344b9ad928SBarry Smith   PetscFunctionReturn(0);
4354b9ad928SBarry Smith }
436