xref: /petsc/src/ksp/pc/impls/kaczmarz/kaczmarz.c (revision efd4aadf157bf1ba2d80c2be092fcf4247860003)
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) {
103*efd4aadfSBarry 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 
11869b97631SPeter Brune    Notes: In parallel this is block-Jacobi with Kaczmarz inner solve.
11969b97631SPeter Brune 
12069b97631SPeter Brune    References:
121feaa1ddbSSatish Balay .  1. - S. Kaczmarz, "Angenaherte Auflosing von Systemen Linearer Gleichungen",
12296a0c994SBarry Smith    Bull. Internat. Acad. Polon. Sci. C1. A, 1937.
1233f93e5bdSPeter Brune 
1243f93e5bdSPeter Brune .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC
1253f93e5bdSPeter Brune 
1263f93e5bdSPeter Brune M*/
1273f93e5bdSPeter Brune 
1283f93e5bdSPeter Brune PETSC_EXTERN PetscErrorCode PCCreate_Kaczmarz(PC pc)
1293f93e5bdSPeter Brune {
1303f93e5bdSPeter Brune   PetscErrorCode ierr;
1313f93e5bdSPeter Brune   PC_Kaczmarz    *jac;
1323f93e5bdSPeter Brune 
1333f93e5bdSPeter Brune   PetscFunctionBegin;
1343f93e5bdSPeter Brune   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
1353f93e5bdSPeter Brune 
1363f93e5bdSPeter Brune   pc->ops->apply           = PCApply_Kaczmarz;
1373f93e5bdSPeter Brune   pc->ops->setfromoptions  = PCSetFromOptions_Kaczmarz;
1383f93e5bdSPeter Brune   pc->ops->setup           = 0;
1393f93e5bdSPeter Brune   pc->ops->view            = PCView_Kaczmarz;
1403f93e5bdSPeter Brune   pc->ops->destroy         = PCDestroy_Kaczmarz;
1413f93e5bdSPeter Brune   pc->data                 = (void*)jac;
1423f93e5bdSPeter Brune   jac->lambda              = 1.0;
14369b97631SPeter Brune   jac->symmetric           = PETSC_FALSE;
1443f93e5bdSPeter Brune   PetscFunctionReturn(0);
1453f93e5bdSPeter Brune }
146