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 PetscFunctionBegin; 11*9566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 123f93e5bdSPeter Brune PetscFunctionReturn(0); 133f93e5bdSPeter Brune } 143f93e5bdSPeter Brune 153f93e5bdSPeter Brune static PetscErrorCode PCApply_Kaczmarz(PC pc,Vec x,Vec y) 163f93e5bdSPeter Brune { 173f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz*)pc->data; 183f93e5bdSPeter Brune PetscInt xs,xe,ys,ye,ncols,i,j; 193f93e5bdSPeter Brune const PetscInt *cols; 20e298bee8SBarry Smith const PetscScalar *vals,*xarray; 213f93e5bdSPeter Brune PetscScalar r; 223f93e5bdSPeter Brune PetscReal anrm; 23e298bee8SBarry Smith PetscScalar *yarray; 243f93e5bdSPeter Brune PetscReal lambda=jac->lambda; 253f93e5bdSPeter Brune 263f93e5bdSPeter Brune PetscFunctionBegin; 27*9566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(pc->pmat,&xs,&xe)); 28*9566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRangeColumn(pc->pmat,&ys,&ye)); 29*9566063dSJacob Faibussowitsch PetscCall(VecSet(y,0.)); 30*9566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x,&xarray)); 31*9566063dSJacob Faibussowitsch PetscCall(VecGetArray(y,&yarray)); 323f93e5bdSPeter Brune for (i=xs;i<xe;i++) { 333f93e5bdSPeter Brune /* get the maximum row width and row norms */ 34*9566063dSJacob Faibussowitsch PetscCall(MatGetRow(pc->pmat,i,&ncols,&cols,&vals)); 353f93e5bdSPeter Brune r = xarray[i-xs]; 363f93e5bdSPeter Brune anrm = 0.; 373f93e5bdSPeter Brune for (j=0;j<ncols;j++) { 383f93e5bdSPeter Brune if (cols[j] >= ys && cols[j] < ye) { 393f93e5bdSPeter Brune r -= yarray[cols[j]-ys]*vals[j]; 403f93e5bdSPeter Brune } 4169b97631SPeter Brune anrm += PetscRealPart(PetscSqr(vals[j])); 423f93e5bdSPeter Brune } 4369b97631SPeter Brune if (anrm > 0.) { 443f93e5bdSPeter Brune for (j=0;j<ncols;j++) { 453f93e5bdSPeter Brune if (cols[j] >= ys && cols[j] < ye) { 463f93e5bdSPeter Brune yarray[cols[j]-ys] += vals[j]*lambda*r/anrm; 473f93e5bdSPeter Brune } 483f93e5bdSPeter Brune } 493f93e5bdSPeter Brune } 50*9566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(pc->pmat,i,&ncols,&cols,&vals)); 513f93e5bdSPeter Brune } 5269b97631SPeter Brune if (jac->symmetric) { 5369b97631SPeter Brune for (i=xe-1;i>=xs;i--) { 54*9566063dSJacob Faibussowitsch PetscCall(MatGetRow(pc->pmat,i,&ncols,&cols,&vals)); 5569b97631SPeter Brune r = xarray[i-xs]; 5669b97631SPeter Brune anrm = 0.; 5769b97631SPeter Brune for (j=0;j<ncols;j++) { 5869b97631SPeter Brune if (cols[j] >= ys && cols[j] < ye) { 5969b97631SPeter Brune r -= yarray[cols[j]-ys]*vals[j]; 6069b97631SPeter Brune } 6169b97631SPeter Brune anrm += PetscRealPart(PetscSqr(vals[j])); 6269b97631SPeter Brune } 6369b97631SPeter Brune if (anrm > 0.) { 6469b97631SPeter Brune for (j=0;j<ncols;j++) { 6569b97631SPeter Brune if (cols[j] >= ys && cols[j] < ye) { 66d6d39189SPeter Brune yarray[cols[j]-ys] += vals[j]*lambda*r/anrm; 6769b97631SPeter Brune } 6869b97631SPeter Brune } 6969b97631SPeter Brune } 70*9566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(pc->pmat,i,&ncols,&cols,&vals)); 7169b97631SPeter Brune } 7269b97631SPeter Brune } 73*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y,&yarray)); 74*9566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x,&xarray)); 753f93e5bdSPeter Brune PetscFunctionReturn(0); 763f93e5bdSPeter Brune } 773f93e5bdSPeter Brune 784416b707SBarry Smith PetscErrorCode PCSetFromOptions_Kaczmarz(PetscOptionItems *PetscOptionsObject,PC pc) 793f93e5bdSPeter Brune { 803f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz*)pc->data; 813f93e5bdSPeter Brune 823f93e5bdSPeter Brune PetscFunctionBegin; 83*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsHead(PetscOptionsObject,"Kaczmarz options")); 84*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_kaczmarz_lambda","relaxation factor (0 < lambda)","",jac->lambda,&jac->lambda,NULL)); 85*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_kaczmarz_symmetric","apply row projections symmetrically","",jac->symmetric,&jac->symmetric,NULL)); 86*9566063dSJacob Faibussowitsch PetscCall(PetscOptionsTail()); 873f93e5bdSPeter Brune PetscFunctionReturn(0); 883f93e5bdSPeter Brune } 893f93e5bdSPeter Brune 903f93e5bdSPeter Brune PetscErrorCode PCView_Kaczmarz(PC pc,PetscViewer viewer) 913f93e5bdSPeter Brune { 923f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz*)pc->data; 933f93e5bdSPeter Brune PetscBool iascii; 943f93e5bdSPeter Brune 953f93e5bdSPeter Brune PetscFunctionBegin; 96*9566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 973f93e5bdSPeter Brune if (iascii) { 98*9566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," lambda = %g\n",(double)jac->lambda)); 993f93e5bdSPeter Brune } 1003f93e5bdSPeter Brune PetscFunctionReturn(0); 1013f93e5bdSPeter Brune } 1023f93e5bdSPeter Brune 1033f93e5bdSPeter Brune /*MC 1043f93e5bdSPeter Brune PCKaczmarz - Kaczmarz iteration 1053f93e5bdSPeter Brune 1063f93e5bdSPeter Brune Options Database Keys: 1073f93e5bdSPeter Brune . -pc_sor_lambda <1.0> - Sets damping parameter lambda 1083f93e5bdSPeter Brune 1093f93e5bdSPeter Brune Level: beginner 1103f93e5bdSPeter Brune 11195452b02SPatrick Sanan Notes: 11295452b02SPatrick Sanan In parallel this is block-Jacobi with Kaczmarz inner solve. 11369b97631SPeter Brune 11469b97631SPeter Brune References: 115606c0280SSatish Balay . * - S. Kaczmarz, "Angenaherte Auflosing von Systemen Linearer Gleichungen", 11696a0c994SBarry Smith Bull. Internat. Acad. Polon. Sci. C1. A, 1937. 1173f93e5bdSPeter Brune 1183f93e5bdSPeter Brune .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC 1193f93e5bdSPeter Brune 1203f93e5bdSPeter Brune M*/ 1213f93e5bdSPeter Brune 1223f93e5bdSPeter Brune PETSC_EXTERN PetscErrorCode PCCreate_Kaczmarz(PC pc) 1233f93e5bdSPeter Brune { 1243f93e5bdSPeter Brune PC_Kaczmarz *jac; 1253f93e5bdSPeter Brune 1263f93e5bdSPeter Brune PetscFunctionBegin; 127*9566063dSJacob Faibussowitsch PetscCall(PetscNewLog(pc,&jac)); 1283f93e5bdSPeter Brune 1293f93e5bdSPeter Brune pc->ops->apply = PCApply_Kaczmarz; 1303f93e5bdSPeter Brune pc->ops->setfromoptions = PCSetFromOptions_Kaczmarz; 1310a545947SLisandro Dalcin pc->ops->setup = NULL; 1323f93e5bdSPeter Brune pc->ops->view = PCView_Kaczmarz; 1333f93e5bdSPeter Brune pc->ops->destroy = PCDestroy_Kaczmarz; 1343f93e5bdSPeter Brune pc->data = (void*)jac; 1353f93e5bdSPeter Brune jac->lambda = 1.0; 13669b97631SPeter Brune jac->symmetric = PETSC_FALSE; 1373f93e5bdSPeter Brune PetscFunctionReturn(0); 1383f93e5bdSPeter Brune } 139