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