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 static PetscErrorCode PCDestroy_Kaczmarz(PC pc) 93f93e5bdSPeter Brune { 103f93e5bdSPeter Brune PetscErrorCode ierr; 113f93e5bdSPeter Brune 123f93e5bdSPeter Brune PetscFunctionBegin; 133f93e5bdSPeter Brune ierr = PetscFree(pc->data);CHKERRQ(ierr); 143f93e5bdSPeter Brune PetscFunctionReturn(0); 153f93e5bdSPeter Brune } 163f93e5bdSPeter Brune 173f93e5bdSPeter Brune static PetscErrorCode PCApply_Kaczmarz(PC pc,Vec x,Vec y) 183f93e5bdSPeter Brune { 193f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz*)pc->data; 203f93e5bdSPeter Brune PetscInt xs,xe,ys,ye,ncols,i,j; 213f93e5bdSPeter Brune const PetscInt *cols; 22e298bee8SBarry Smith const PetscScalar *vals,*xarray; 233f93e5bdSPeter Brune PetscErrorCode ierr; 243f93e5bdSPeter Brune PetscScalar r; 253f93e5bdSPeter Brune PetscReal anrm; 26e298bee8SBarry Smith PetscScalar *yarray; 273f93e5bdSPeter Brune PetscReal lambda=jac->lambda; 283f93e5bdSPeter Brune 293f93e5bdSPeter Brune PetscFunctionBegin; 303f93e5bdSPeter Brune ierr = MatGetOwnershipRange(pc->pmat,&xs,&xe);CHKERRQ(ierr); 313f93e5bdSPeter Brune ierr = MatGetOwnershipRangeColumn(pc->pmat,&ys,&ye);CHKERRQ(ierr); 3269b97631SPeter Brune ierr = VecSet(y,0.);CHKERRQ(ierr); 33e298bee8SBarry Smith ierr = VecGetArrayRead(x,&xarray);CHKERRQ(ierr); 343f93e5bdSPeter Brune ierr = VecGetArray(y,&yarray);CHKERRQ(ierr); 353f93e5bdSPeter Brune for (i=xs;i<xe;i++) { 363f93e5bdSPeter Brune /* get the maximum row width and row norms */ 373f93e5bdSPeter Brune ierr = MatGetRow(pc->pmat,i,&ncols,&cols,&vals);CHKERRQ(ierr); 383f93e5bdSPeter Brune r = xarray[i-xs]; 393f93e5bdSPeter Brune anrm = 0.; 403f93e5bdSPeter Brune for (j=0;j<ncols;j++) { 413f93e5bdSPeter Brune if (cols[j] >= ys && cols[j] < ye) { 423f93e5bdSPeter Brune r -= yarray[cols[j]-ys]*vals[j]; 433f93e5bdSPeter Brune } 4469b97631SPeter Brune anrm += PetscRealPart(PetscSqr(vals[j])); 453f93e5bdSPeter Brune } 4669b97631SPeter Brune if (anrm > 0.) { 473f93e5bdSPeter Brune for (j=0;j<ncols;j++) { 483f93e5bdSPeter Brune if (cols[j] >= ys && cols[j] < ye) { 493f93e5bdSPeter Brune yarray[cols[j]-ys] += vals[j]*lambda*r/anrm; 503f93e5bdSPeter Brune } 513f93e5bdSPeter Brune } 523f93e5bdSPeter Brune } 533f93e5bdSPeter Brune ierr = MatRestoreRow(pc->pmat,i,&ncols,&cols,&vals);CHKERRQ(ierr); 543f93e5bdSPeter Brune } 5569b97631SPeter Brune if (jac->symmetric) { 5669b97631SPeter Brune for (i=xe-1;i>=xs;i--) { 5769b97631SPeter Brune ierr = MatGetRow(pc->pmat,i,&ncols,&cols,&vals);CHKERRQ(ierr); 5869b97631SPeter Brune r = xarray[i-xs]; 5969b97631SPeter Brune anrm = 0.; 6069b97631SPeter Brune for (j=0;j<ncols;j++) { 6169b97631SPeter Brune if (cols[j] >= ys && cols[j] < ye) { 6269b97631SPeter Brune r -= yarray[cols[j]-ys]*vals[j]; 6369b97631SPeter Brune } 6469b97631SPeter Brune anrm += PetscRealPart(PetscSqr(vals[j])); 6569b97631SPeter Brune } 6669b97631SPeter Brune if (anrm > 0.) { 6769b97631SPeter Brune for (j=0;j<ncols;j++) { 6869b97631SPeter Brune if (cols[j] >= ys && cols[j] < ye) { 69d6d39189SPeter Brune yarray[cols[j]-ys] += vals[j]*lambda*r/anrm; 7069b97631SPeter Brune } 7169b97631SPeter Brune } 7269b97631SPeter Brune } 7369b97631SPeter Brune ierr = MatRestoreRow(pc->pmat,i,&ncols,&cols,&vals);CHKERRQ(ierr); 7469b97631SPeter Brune } 7569b97631SPeter Brune } 763f93e5bdSPeter Brune ierr = VecRestoreArray(y,&yarray);CHKERRQ(ierr); 77e298bee8SBarry Smith ierr = VecRestoreArrayRead(x,&xarray);CHKERRQ(ierr); 783f93e5bdSPeter Brune PetscFunctionReturn(0); 793f93e5bdSPeter Brune } 803f93e5bdSPeter Brune 814416b707SBarry Smith PetscErrorCode PCSetFromOptions_Kaczmarz(PetscOptionItems *PetscOptionsObject,PC pc) 823f93e5bdSPeter Brune { 833f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz*)pc->data; 843f93e5bdSPeter Brune PetscErrorCode ierr; 853f93e5bdSPeter Brune 863f93e5bdSPeter Brune PetscFunctionBegin; 871a1499c8SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"Kaczmarz options");CHKERRQ(ierr); 888afaa268SBarry Smith ierr = PetscOptionsReal("-pc_kaczmarz_lambda","relaxation factor (0 < lambda)","",jac->lambda,&jac->lambda,NULL);CHKERRQ(ierr); 898afaa268SBarry Smith ierr = PetscOptionsBool("-pc_kaczmarz_symmetric","apply row projections symmetrically","",jac->symmetric,&jac->symmetric,NULL);CHKERRQ(ierr); 903f93e5bdSPeter Brune ierr = PetscOptionsTail();CHKERRQ(ierr); 913f93e5bdSPeter Brune PetscFunctionReturn(0); 923f93e5bdSPeter Brune } 933f93e5bdSPeter Brune 943f93e5bdSPeter Brune PetscErrorCode PCView_Kaczmarz(PC pc,PetscViewer viewer) 953f93e5bdSPeter Brune { 963f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz*)pc->data; 973f93e5bdSPeter Brune PetscErrorCode ierr; 983f93e5bdSPeter Brune PetscBool iascii; 993f93e5bdSPeter Brune 1003f93e5bdSPeter Brune PetscFunctionBegin; 1013f93e5bdSPeter Brune ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1023f93e5bdSPeter Brune if (iascii) { 103efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," lambda = %g\n",(double)jac->lambda);CHKERRQ(ierr); 1043f93e5bdSPeter Brune } 1053f93e5bdSPeter Brune PetscFunctionReturn(0); 1063f93e5bdSPeter Brune } 1073f93e5bdSPeter Brune 1083f93e5bdSPeter Brune /*MC 1093f93e5bdSPeter Brune PCKaczmarz - Kaczmarz iteration 1103f93e5bdSPeter Brune 1113f93e5bdSPeter Brune Options Database Keys: 1123f93e5bdSPeter Brune . -pc_sor_lambda <1.0> - Sets damping parameter lambda 1133f93e5bdSPeter Brune 1143f93e5bdSPeter Brune Level: beginner 1153f93e5bdSPeter Brune 1163f93e5bdSPeter Brune Concepts: Kaczmarz, preconditioners, row projection 1173f93e5bdSPeter Brune 118*95452b02SPatrick Sanan Notes: 119*95452b02SPatrick Sanan In parallel this is block-Jacobi with Kaczmarz inner solve. 12069b97631SPeter Brune 12169b97631SPeter Brune References: 122feaa1ddbSSatish Balay . 1. - S. Kaczmarz, "Angenaherte Auflosing von Systemen Linearer Gleichungen", 12396a0c994SBarry Smith Bull. Internat. Acad. Polon. Sci. C1. A, 1937. 1243f93e5bdSPeter Brune 1253f93e5bdSPeter Brune .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC 1263f93e5bdSPeter Brune 1273f93e5bdSPeter Brune M*/ 1283f93e5bdSPeter Brune 1293f93e5bdSPeter Brune PETSC_EXTERN PetscErrorCode PCCreate_Kaczmarz(PC pc) 1303f93e5bdSPeter Brune { 1313f93e5bdSPeter Brune PetscErrorCode ierr; 1323f93e5bdSPeter Brune PC_Kaczmarz *jac; 1333f93e5bdSPeter Brune 1343f93e5bdSPeter Brune PetscFunctionBegin; 1353f93e5bdSPeter Brune ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr); 1363f93e5bdSPeter Brune 1373f93e5bdSPeter Brune pc->ops->apply = PCApply_Kaczmarz; 1383f93e5bdSPeter Brune pc->ops->setfromoptions = PCSetFromOptions_Kaczmarz; 1393f93e5bdSPeter Brune pc->ops->setup = 0; 1403f93e5bdSPeter Brune pc->ops->view = PCView_Kaczmarz; 1413f93e5bdSPeter Brune pc->ops->destroy = PCDestroy_Kaczmarz; 1423f93e5bdSPeter Brune pc->data = (void*)jac; 1433f93e5bdSPeter Brune jac->lambda = 1.0; 14469b97631SPeter Brune jac->symmetric = PETSC_FALSE; 1453f93e5bdSPeter Brune PetscFunctionReturn(0); 1463f93e5bdSPeter Brune } 147