xref: /petsc/src/ksp/pc/impls/kaczmarz/kaczmarz.c (revision 4416b707960d1402d451ea66f392b9e9d922d271)
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