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,PetscBool 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 PetscBool 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 = PetscOptionsBoolGroupBegin("-pc_sor_symmetric","SSOR, not SOR","PCSORSetSymmetric",&flg);CHKERRQ(ierr); 75 if (flg) {ierr = PCSORSetSymmetric(pc,SOR_SYMMETRIC_SWEEP);CHKERRQ(ierr);} 76 ierr = PetscOptionsBoolGroup("-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 = PetscOptionsBoolGroup("-pc_sor_forward","use forward sweep","PCSORSetSymmetric",&flg);CHKERRQ(ierr); 79 if (flg) {ierr = PCSORSetSymmetric(pc,SOR_FORWARD_SWEEP);CHKERRQ(ierr);} 80 ierr = PetscOptionsBoolGroup("-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 = PetscOptionsBoolGroup("-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 = PetscOptionsBoolGroupEnd("-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 PetscBool 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 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 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 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 PCSORSetSymmetric(PC pc,MatSORType flag) 210 { 211 PetscErrorCode ierr; 212 213 PetscFunctionBegin; 214 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 215 PetscValidLogicalCollectiveEnum(pc,flag,2); 216 ierr = PetscTryMethod(pc,"PCSORSetSymmetric_C",(PC,MatSORType),(pc,flag));CHKERRQ(ierr); 217 PetscFunctionReturn(0); 218 } 219 220 #undef __FUNCT__ 221 #define __FUNCT__ "PCSORSetOmega" 222 /*@ 223 PCSORSetOmega - Sets the SOR relaxation coefficient, omega 224 (where omega = 1.0 by default). 225 226 Logically Collective on PC 227 228 Input Parameters: 229 + pc - the preconditioner context 230 - omega - relaxation coefficient (0 < omega < 2). 231 232 Options Database Key: 233 . -pc_sor_omega <omega> - Sets omega 234 235 Level: intermediate 236 237 .keywords: PC, SOR, SSOR, set, relaxation, omega 238 239 .seealso: PCSORSetSymmetric(), PCSORSetIterations(), PCEisenstatSetOmega() 240 @*/ 241 PetscErrorCode PCSORSetOmega(PC pc,PetscReal omega) 242 { 243 PetscErrorCode ierr; 244 245 PetscFunctionBegin; 246 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 247 PetscValidLogicalCollectiveReal(pc,omega,2); 248 ierr = PetscTryMethod(pc,"PCSORSetOmega_C",(PC,PetscReal),(pc,omega));CHKERRQ(ierr); 249 PetscFunctionReturn(0); 250 } 251 252 #undef __FUNCT__ 253 #define __FUNCT__ "PCSORSetIterations" 254 /*@ 255 PCSORSetIterations - Sets the number of inner iterations to 256 be used by the SOR preconditioner. The default is 1. 257 258 Logically Collective on PC 259 260 Input Parameters: 261 + pc - the preconditioner context 262 . lits - number of local iterations, smoothings over just variables on processor 263 - its - number of parallel iterations to use; each parallel iteration has lits local iterations 264 265 Options Database Key: 266 + -pc_sor_its <its> - Sets number of iterations 267 - -pc_sor_lits <lits> - Sets number of local iterations 268 269 Level: intermediate 270 271 Notes: When run on one processor the number of smoothings is lits*its 272 273 .keywords: PC, SOR, SSOR, set, iterations 274 275 .seealso: PCSORSetOmega(), PCSORSetSymmetric() 276 @*/ 277 PetscErrorCode PCSORSetIterations(PC pc,PetscInt its,PetscInt lits) 278 { 279 PetscErrorCode ierr; 280 281 PetscFunctionBegin; 282 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 283 PetscValidLogicalCollectiveInt(pc,its,2); 284 ierr = PetscTryMethod(pc,"PCSORSetIterations_C",(PC,PetscInt,PetscInt),(pc,its,lits));CHKERRQ(ierr); 285 PetscFunctionReturn(0); 286 } 287 288 /*MC 289 PCSOR - (S)SOR (successive over relaxation, Gauss-Seidel) preconditioning 290 291 Options Database Keys: 292 + -pc_sor_symmetric - Activates symmetric version 293 . -pc_sor_backward - Activates backward version 294 . -pc_sor_forward - Activates forward version 295 . -pc_sor_local_forward - Activates local forward version 296 . -pc_sor_local_symmetric - Activates local symmetric version (default version) 297 . -pc_sor_local_backward - Activates local backward version 298 . -pc_sor_omega <omega> - Sets omega 299 . -pc_sor_its <its> - Sets number of iterations (default 1) 300 - -pc_sor_lits <lits> - Sets number of local iterations (default 1) 301 302 Level: beginner 303 304 Concepts: SOR, preconditioners, Gauss-Seidel 305 306 Notes: Only implemented for the AIJ and SeqBAIJ matrix formats. 307 Not a true parallel SOR, in parallel this implementation corresponds to block 308 Jacobi with SOR on each block. 309 310 For SeqBAIJ matrices this implements point-block SOR, but the omega, its, lits options are not supported. 311 312 .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 313 PCSORSetIterations(), PCSORSetSymmetric(), PCSORSetOmega(), PCEISENSTAT 314 M*/ 315 316 EXTERN_C_BEGIN 317 #undef __FUNCT__ 318 #define __FUNCT__ "PCCreate_SOR" 319 PetscErrorCode PCCreate_SOR(PC pc) 320 { 321 PetscErrorCode ierr; 322 PC_SOR *jac; 323 324 PetscFunctionBegin; 325 ierr = PetscNewLog(pc,PC_SOR,&jac);CHKERRQ(ierr); 326 327 pc->ops->apply = PCApply_SOR; 328 pc->ops->applyrichardson = PCApplyRichardson_SOR; 329 pc->ops->setfromoptions = PCSetFromOptions_SOR; 330 pc->ops->setup = 0; 331 pc->ops->view = PCView_SOR; 332 pc->ops->destroy = PCDestroy_SOR; 333 pc->data = (void*)jac; 334 jac->sym = SOR_LOCAL_SYMMETRIC_SWEEP; 335 jac->omega = 1.0; 336 jac->fshift = 0.0; 337 jac->its = 1; 338 jac->lits = 1; 339 340 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCSORSetSymmetric_C","PCSORSetSymmetric_SOR", 341 PCSORSetSymmetric_SOR);CHKERRQ(ierr); 342 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCSORSetOmega_C","PCSORSetOmega_SOR", 343 PCSORSetOmega_SOR);CHKERRQ(ierr); 344 ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCSORSetIterations_C","PCSORSetIterations_SOR", 345 PCSORSetIterations_SOR);CHKERRQ(ierr); 346 347 PetscFunctionReturn(0); 348 } 349 EXTERN_C_END 350 351 352 353 354 355