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