1af0996ceSBarry Smith #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/ 23f93e5bdSPeter Brune 33f93e5bdSPeter Brune typedef struct { 43f93e5bdSPeter Brune PetscReal lambda; /* damping parameter */ 569b97631SPeter Brune PetscBool symmetric; /* apply the projections symmetrically */ 63f93e5bdSPeter Brune } PC_Kaczmarz; 73f93e5bdSPeter Brune 83f93e5bdSPeter Brune #undef __FUNCT__ 93f93e5bdSPeter Brune #define __FUNCT__ "PCDestroy_Kaczmarz" 103f93e5bdSPeter Brune static PetscErrorCode PCDestroy_Kaczmarz(PC pc) 113f93e5bdSPeter Brune { 123f93e5bdSPeter Brune PetscErrorCode ierr; 133f93e5bdSPeter Brune 143f93e5bdSPeter Brune PetscFunctionBegin; 153f93e5bdSPeter Brune ierr = PetscFree(pc->data);CHKERRQ(ierr); 163f93e5bdSPeter Brune PetscFunctionReturn(0); 173f93e5bdSPeter Brune } 183f93e5bdSPeter Brune 193f93e5bdSPeter Brune #undef __FUNCT__ 203f93e5bdSPeter Brune #define __FUNCT__ "PCApply_Kaczmarz" 213f93e5bdSPeter Brune static PetscErrorCode PCApply_Kaczmarz(PC pc,Vec x,Vec y) 223f93e5bdSPeter Brune { 233f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz*)pc->data; 243f93e5bdSPeter Brune PetscInt xs,xe,ys,ye,ncols,i,j; 253f93e5bdSPeter Brune const PetscInt *cols; 263f93e5bdSPeter Brune const PetscScalar *vals; 273f93e5bdSPeter Brune PetscErrorCode ierr; 283f93e5bdSPeter Brune PetscScalar r; 293f93e5bdSPeter Brune PetscReal anrm; 303f93e5bdSPeter Brune PetscScalar *xarray,*yarray; 313f93e5bdSPeter Brune PetscReal lambda=jac->lambda; 323f93e5bdSPeter Brune 333f93e5bdSPeter Brune PetscFunctionBegin; 343f93e5bdSPeter Brune ierr = MatGetOwnershipRange(pc->pmat,&xs,&xe);CHKERRQ(ierr); 353f93e5bdSPeter Brune ierr = MatGetOwnershipRangeColumn(pc->pmat,&ys,&ye);CHKERRQ(ierr); 3669b97631SPeter Brune ierr = VecSet(y,0.);CHKERRQ(ierr); 373f93e5bdSPeter Brune ierr = VecGetArray(x,&xarray);CHKERRQ(ierr); 383f93e5bdSPeter Brune ierr = VecGetArray(y,&yarray);CHKERRQ(ierr); 393f93e5bdSPeter Brune for (i=xs;i<xe;i++) { 403f93e5bdSPeter Brune /* get the maximum row width and row norms */ 413f93e5bdSPeter Brune ierr = MatGetRow(pc->pmat,i,&ncols,&cols,&vals);CHKERRQ(ierr); 423f93e5bdSPeter Brune r = xarray[i-xs]; 433f93e5bdSPeter Brune anrm = 0.; 443f93e5bdSPeter Brune for (j=0;j<ncols;j++) { 453f93e5bdSPeter Brune if (cols[j] >= ys && cols[j] < ye) { 463f93e5bdSPeter Brune r -= yarray[cols[j]-ys]*vals[j]; 473f93e5bdSPeter Brune } 4869b97631SPeter Brune anrm += PetscRealPart(PetscSqr(vals[j])); 493f93e5bdSPeter Brune } 5069b97631SPeter Brune if (anrm > 0.) { 513f93e5bdSPeter Brune for (j=0;j<ncols;j++) { 523f93e5bdSPeter Brune if (cols[j] >= ys && cols[j] < ye) { 533f93e5bdSPeter Brune yarray[cols[j]-ys] += vals[j]*lambda*r/anrm; 543f93e5bdSPeter Brune } 553f93e5bdSPeter Brune } 563f93e5bdSPeter Brune } 573f93e5bdSPeter Brune ierr = MatRestoreRow(pc->pmat,i,&ncols,&cols,&vals);CHKERRQ(ierr); 583f93e5bdSPeter Brune } 5969b97631SPeter Brune if (jac->symmetric) { 6069b97631SPeter Brune for (i=xe-1;i>=xs;i--) { 6169b97631SPeter Brune ierr = MatGetRow(pc->pmat,i,&ncols,&cols,&vals);CHKERRQ(ierr); 6269b97631SPeter Brune r = xarray[i-xs]; 6369b97631SPeter Brune anrm = 0.; 6469b97631SPeter Brune for (j=0;j<ncols;j++) { 6569b97631SPeter Brune if (cols[j] >= ys && cols[j] < ye) { 6669b97631SPeter Brune r -= yarray[cols[j]-ys]*vals[j]; 6769b97631SPeter Brune } 6869b97631SPeter Brune anrm += PetscRealPart(PetscSqr(vals[j])); 6969b97631SPeter Brune } 7069b97631SPeter Brune if (anrm > 0.) { 7169b97631SPeter Brune for (j=0;j<ncols;j++) { 7269b97631SPeter Brune if (cols[j] >= ys && cols[j] < ye) { 73d6d39189SPeter Brune yarray[cols[j]-ys] += vals[j]*lambda*r/anrm; 7469b97631SPeter Brune } 7569b97631SPeter Brune } 7669b97631SPeter Brune } 7769b97631SPeter Brune ierr = MatRestoreRow(pc->pmat,i,&ncols,&cols,&vals);CHKERRQ(ierr); 7869b97631SPeter Brune } 7969b97631SPeter Brune } 803f93e5bdSPeter Brune ierr = VecRestoreArray(y,&yarray);CHKERRQ(ierr); 813f93e5bdSPeter Brune ierr = VecRestoreArray(x,&xarray);CHKERRQ(ierr); 823f93e5bdSPeter Brune PetscFunctionReturn(0); 833f93e5bdSPeter Brune } 843f93e5bdSPeter Brune 853f93e5bdSPeter Brune #undef __FUNCT__ 863f93e5bdSPeter Brune #define __FUNCT__ "PCSetFromOptions_Kaczmarz" 87*4416b707SBarry Smith PetscErrorCode PCSetFromOptions_Kaczmarz(PetscOptionItems *PetscOptionsObject,PC pc) 883f93e5bdSPeter Brune { 893f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz*)pc->data; 903f93e5bdSPeter Brune PetscErrorCode ierr; 913f93e5bdSPeter Brune 923f93e5bdSPeter Brune PetscFunctionBegin; 931a1499c8SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"Kaczmarz options");CHKERRQ(ierr); 948afaa268SBarry Smith ierr = PetscOptionsReal("-pc_kaczmarz_lambda","relaxation factor (0 < lambda)","",jac->lambda,&jac->lambda,NULL);CHKERRQ(ierr); 958afaa268SBarry Smith ierr = PetscOptionsBool("-pc_kaczmarz_symmetric","apply row projections symmetrically","",jac->symmetric,&jac->symmetric,NULL);CHKERRQ(ierr); 963f93e5bdSPeter Brune ierr = PetscOptionsTail();CHKERRQ(ierr); 973f93e5bdSPeter Brune PetscFunctionReturn(0); 983f93e5bdSPeter Brune } 993f93e5bdSPeter Brune 1003f93e5bdSPeter Brune #undef __FUNCT__ 1013f93e5bdSPeter Brune #define __FUNCT__ "PCView_Kaczmarz" 1023f93e5bdSPeter Brune PetscErrorCode PCView_Kaczmarz(PC pc,PetscViewer viewer) 1033f93e5bdSPeter Brune { 1043f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz*)pc->data; 1053f93e5bdSPeter Brune PetscErrorCode ierr; 1063f93e5bdSPeter Brune PetscBool iascii; 1073f93e5bdSPeter Brune 1083f93e5bdSPeter Brune PetscFunctionBegin; 1093f93e5bdSPeter Brune ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1103f93e5bdSPeter Brune if (iascii) { 1113f93e5bdSPeter Brune ierr = PetscViewerASCIIPrintf(viewer," Kaczmarz: lambda = %G\n",jac->lambda);CHKERRQ(ierr); 1123f93e5bdSPeter Brune } 1133f93e5bdSPeter Brune PetscFunctionReturn(0); 1143f93e5bdSPeter Brune } 1153f93e5bdSPeter Brune 1163f93e5bdSPeter Brune /*MC 1173f93e5bdSPeter Brune PCKaczmarz - Kaczmarz iteration 1183f93e5bdSPeter Brune 1193f93e5bdSPeter Brune Options Database Keys: 1203f93e5bdSPeter Brune . -pc_sor_lambda <1.0> - Sets damping parameter lambda 1213f93e5bdSPeter Brune 1223f93e5bdSPeter Brune Level: beginner 1233f93e5bdSPeter Brune 1243f93e5bdSPeter Brune Concepts: Kaczmarz, preconditioners, row projection 1253f93e5bdSPeter Brune 12669b97631SPeter Brune Notes: In parallel this is block-Jacobi with Kaczmarz inner solve. 12769b97631SPeter Brune 12869b97631SPeter Brune References: 12969b97631SPeter Brune S. Kaczmarz, “Angenaherte Auflosing von Systemen Linearer Gleichungen”, 13069b97631SPeter Brune Bull. Internat. Acad. Polon. Sci. C1. A, pp.335-357, 1937. 1313f93e5bdSPeter Brune 1323f93e5bdSPeter Brune .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC 1333f93e5bdSPeter Brune 1343f93e5bdSPeter Brune M*/ 1353f93e5bdSPeter Brune 1363f93e5bdSPeter Brune #undef __FUNCT__ 1373f93e5bdSPeter Brune #define __FUNCT__ "PCCreate_Kaczmarz" 1383f93e5bdSPeter Brune PETSC_EXTERN PetscErrorCode PCCreate_Kaczmarz(PC pc) 1393f93e5bdSPeter Brune { 1403f93e5bdSPeter Brune PetscErrorCode ierr; 1413f93e5bdSPeter Brune PC_Kaczmarz *jac; 1423f93e5bdSPeter Brune 1433f93e5bdSPeter Brune PetscFunctionBegin; 1443f93e5bdSPeter Brune ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr); 1453f93e5bdSPeter Brune 1463f93e5bdSPeter Brune pc->ops->apply = PCApply_Kaczmarz; 1473f93e5bdSPeter Brune pc->ops->setfromoptions = PCSetFromOptions_Kaczmarz; 1483f93e5bdSPeter Brune pc->ops->setup = 0; 1493f93e5bdSPeter Brune pc->ops->view = PCView_Kaczmarz; 1503f93e5bdSPeter Brune pc->ops->destroy = PCDestroy_Kaczmarz; 1513f93e5bdSPeter Brune pc->data = (void*)jac; 1523f93e5bdSPeter Brune jac->lambda = 1.0; 15369b97631SPeter Brune jac->symmetric = PETSC_FALSE; 1543f93e5bdSPeter Brune PetscFunctionReturn(0); 1553f93e5bdSPeter Brune } 156