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 89371c9d4SSatish Balay static PetscErrorCode PCDestroy_Kaczmarz(PC pc) { 93f93e5bdSPeter Brune PetscFunctionBegin; 109566063dSJacob Faibussowitsch PetscCall(PetscFree(pc->data)); 113f93e5bdSPeter Brune PetscFunctionReturn(0); 123f93e5bdSPeter Brune } 133f93e5bdSPeter Brune 149371c9d4SSatish Balay static PetscErrorCode PCApply_Kaczmarz(PC pc, Vec x, Vec y) { 153f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz *)pc->data; 163f93e5bdSPeter Brune PetscInt xs, xe, ys, ye, ncols, i, j; 173f93e5bdSPeter Brune const PetscInt *cols; 18e298bee8SBarry Smith const PetscScalar *vals, *xarray; 193f93e5bdSPeter Brune PetscScalar r; 203f93e5bdSPeter Brune PetscReal anrm; 21e298bee8SBarry Smith PetscScalar *yarray; 223f93e5bdSPeter Brune PetscReal lambda = jac->lambda; 233f93e5bdSPeter Brune 243f93e5bdSPeter Brune PetscFunctionBegin; 259566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(pc->pmat, &xs, &xe)); 269566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRangeColumn(pc->pmat, &ys, &ye)); 279566063dSJacob Faibussowitsch PetscCall(VecSet(y, 0.)); 289566063dSJacob Faibussowitsch PetscCall(VecGetArrayRead(x, &xarray)); 299566063dSJacob Faibussowitsch PetscCall(VecGetArray(y, &yarray)); 303f93e5bdSPeter Brune for (i = xs; i < xe; i++) { 313f93e5bdSPeter Brune /* get the maximum row width and row norms */ 329566063dSJacob Faibussowitsch PetscCall(MatGetRow(pc->pmat, i, &ncols, &cols, &vals)); 333f93e5bdSPeter Brune r = xarray[i - xs]; 343f93e5bdSPeter Brune anrm = 0.; 353f93e5bdSPeter Brune for (j = 0; j < ncols; j++) { 36ad540459SPierre Jolivet if (cols[j] >= ys && cols[j] < ye) r -= yarray[cols[j] - ys] * vals[j]; 3769b97631SPeter Brune anrm += PetscRealPart(PetscSqr(vals[j])); 383f93e5bdSPeter Brune } 3969b97631SPeter Brune if (anrm > 0.) { 403f93e5bdSPeter Brune for (j = 0; j < ncols; j++) { 41ad540459SPierre Jolivet if (cols[j] >= ys && cols[j] < ye) yarray[cols[j] - ys] += vals[j] * lambda * r / anrm; 423f93e5bdSPeter Brune } 433f93e5bdSPeter Brune } 449566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(pc->pmat, i, &ncols, &cols, &vals)); 453f93e5bdSPeter Brune } 4669b97631SPeter Brune if (jac->symmetric) { 4769b97631SPeter Brune for (i = xe - 1; i >= xs; i--) { 489566063dSJacob Faibussowitsch PetscCall(MatGetRow(pc->pmat, i, &ncols, &cols, &vals)); 4969b97631SPeter Brune r = xarray[i - xs]; 5069b97631SPeter Brune anrm = 0.; 5169b97631SPeter Brune for (j = 0; j < ncols; j++) { 52ad540459SPierre Jolivet if (cols[j] >= ys && cols[j] < ye) r -= yarray[cols[j] - ys] * vals[j]; 5369b97631SPeter Brune anrm += PetscRealPart(PetscSqr(vals[j])); 5469b97631SPeter Brune } 5569b97631SPeter Brune if (anrm > 0.) { 5669b97631SPeter Brune for (j = 0; j < ncols; j++) { 57ad540459SPierre Jolivet if (cols[j] >= ys && cols[j] < ye) yarray[cols[j] - ys] += vals[j] * lambda * r / anrm; 5869b97631SPeter Brune } 5969b97631SPeter Brune } 609566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(pc->pmat, i, &ncols, &cols, &vals)); 6169b97631SPeter Brune } 6269b97631SPeter Brune } 639566063dSJacob Faibussowitsch PetscCall(VecRestoreArray(y, &yarray)); 649566063dSJacob Faibussowitsch PetscCall(VecRestoreArrayRead(x, &xarray)); 653f93e5bdSPeter Brune PetscFunctionReturn(0); 663f93e5bdSPeter Brune } 673f93e5bdSPeter Brune 689371c9d4SSatish Balay PetscErrorCode PCSetFromOptions_Kaczmarz(PC pc, PetscOptionItems *PetscOptionsObject) { 693f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz *)pc->data; 703f93e5bdSPeter Brune 713f93e5bdSPeter Brune PetscFunctionBegin; 72d0609cedSBarry Smith PetscOptionsHeadBegin(PetscOptionsObject, "Kaczmarz options"); 739566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-pc_kaczmarz_lambda", "relaxation factor (0 < lambda)", "", jac->lambda, &jac->lambda, NULL)); 749566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_kaczmarz_symmetric", "apply row projections symmetrically", "", jac->symmetric, &jac->symmetric, NULL)); 75d0609cedSBarry Smith PetscOptionsHeadEnd(); 763f93e5bdSPeter Brune PetscFunctionReturn(0); 773f93e5bdSPeter Brune } 783f93e5bdSPeter Brune 799371c9d4SSatish Balay PetscErrorCode PCView_Kaczmarz(PC pc, PetscViewer viewer) { 803f93e5bdSPeter Brune PC_Kaczmarz *jac = (PC_Kaczmarz *)pc->data; 813f93e5bdSPeter Brune PetscBool iascii; 823f93e5bdSPeter Brune 833f93e5bdSPeter Brune PetscFunctionBegin; 849566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 8548a46eb9SPierre Jolivet if (iascii) PetscCall(PetscViewerASCIIPrintf(viewer, " lambda = %g\n", (double)jac->lambda)); 863f93e5bdSPeter Brune PetscFunctionReturn(0); 873f93e5bdSPeter Brune } 883f93e5bdSPeter Brune 893f93e5bdSPeter Brune /*MC 903f93e5bdSPeter Brune PCKaczmarz - Kaczmarz iteration 913f93e5bdSPeter Brune 92f1580f4eSBarry Smith Options Database Key: 933f93e5bdSPeter Brune . -pc_sor_lambda <1.0> - Sets damping parameter lambda 943f93e5bdSPeter Brune 953f93e5bdSPeter Brune Level: beginner 963f93e5bdSPeter Brune 97f1580f4eSBarry Smith Note: 9895452b02SPatrick Sanan In parallel this is block-Jacobi with Kaczmarz inner solve. 9969b97631SPeter Brune 10069b97631SPeter Brune References: 101606c0280SSatish Balay . * - S. Kaczmarz, "Angenaherte Auflosing von Systemen Linearer Gleichungen", 10296a0c994SBarry Smith Bull. Internat. Acad. Polon. Sci. C1. A, 1937. 1033f93e5bdSPeter Brune 104f1580f4eSBarry Smith .seealso: `PCCreate()`, `PCSetType()`, `PCType`, `PC`, `PCJACOBI`, `PCBJACOBI` 1053f93e5bdSPeter Brune M*/ 1063f93e5bdSPeter Brune 1079371c9d4SSatish Balay PETSC_EXTERN PetscErrorCode PCCreate_Kaczmarz(PC pc) { 1083f93e5bdSPeter Brune PC_Kaczmarz *jac; 1093f93e5bdSPeter Brune 1103f93e5bdSPeter Brune PetscFunctionBegin; 111*4dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&jac)); 1123f93e5bdSPeter Brune 1133f93e5bdSPeter Brune pc->ops->apply = PCApply_Kaczmarz; 1143f93e5bdSPeter Brune pc->ops->setfromoptions = PCSetFromOptions_Kaczmarz; 1150a545947SLisandro Dalcin pc->ops->setup = NULL; 1163f93e5bdSPeter Brune pc->ops->view = PCView_Kaczmarz; 1173f93e5bdSPeter Brune pc->ops->destroy = PCDestroy_Kaczmarz; 1183f93e5bdSPeter Brune pc->data = (void *)jac; 1193f93e5bdSPeter Brune jac->lambda = 1.0; 12069b97631SPeter Brune jac->symmetric = PETSC_FALSE; 1213f93e5bdSPeter Brune PetscFunctionReturn(0); 1223f93e5bdSPeter Brune } 123