xref: /petsc/src/ksp/pc/impls/kaczmarz/kaczmarz.c (revision 3f93e5bd7810365176b4de538c1ab7498b758201)
1*3f93e5bdSPeter Brune #include <petsc-private/pcimpl.h>               /*I "petscpc.h" I*/
2*3f93e5bdSPeter Brune 
3*3f93e5bdSPeter Brune typedef struct {
4*3f93e5bdSPeter Brune   PetscReal  lambda; /* damping parameter */
5*3f93e5bdSPeter Brune } PC_Kaczmarz;
6*3f93e5bdSPeter Brune 
7*3f93e5bdSPeter Brune #undef __FUNCT__
8*3f93e5bdSPeter Brune #define __FUNCT__ "PCDestroy_Kaczmarz"
9*3f93e5bdSPeter Brune static PetscErrorCode PCDestroy_Kaczmarz(PC pc)
10*3f93e5bdSPeter Brune {
11*3f93e5bdSPeter Brune   PetscErrorCode ierr;
12*3f93e5bdSPeter Brune 
13*3f93e5bdSPeter Brune   PetscFunctionBegin;
14*3f93e5bdSPeter Brune   ierr = PetscFree(pc->data);CHKERRQ(ierr);
15*3f93e5bdSPeter Brune   PetscFunctionReturn(0);
16*3f93e5bdSPeter Brune }
17*3f93e5bdSPeter Brune 
18*3f93e5bdSPeter Brune #undef __FUNCT__
19*3f93e5bdSPeter Brune #define __FUNCT__ "PCApply_Kaczmarz"
20*3f93e5bdSPeter Brune static PetscErrorCode PCApply_Kaczmarz(PC pc,Vec x,Vec y)
21*3f93e5bdSPeter Brune {
22*3f93e5bdSPeter Brune   PC_Kaczmarz       *jac = (PC_Kaczmarz*)pc->data;
23*3f93e5bdSPeter Brune   PetscInt          xs,xe,ys,ye,ncols,i,j;
24*3f93e5bdSPeter Brune   const PetscInt    *cols;
25*3f93e5bdSPeter Brune   const PetscScalar *vals;
26*3f93e5bdSPeter Brune   PetscErrorCode    ierr;
27*3f93e5bdSPeter Brune   PetscScalar       r;
28*3f93e5bdSPeter Brune   PetscReal         anrm;
29*3f93e5bdSPeter Brune   PetscScalar       *xarray,*yarray;
30*3f93e5bdSPeter Brune   PetscReal         lambda=jac->lambda;
31*3f93e5bdSPeter Brune 
32*3f93e5bdSPeter Brune   PetscFunctionBegin;
33*3f93e5bdSPeter Brune   ierr = MatGetOwnershipRange(pc->pmat,&xs,&xe);CHKERRQ(ierr);
34*3f93e5bdSPeter Brune   ierr = MatGetOwnershipRangeColumn(pc->pmat,&ys,&ye);CHKERRQ(ierr);
35*3f93e5bdSPeter Brune   ierr = VecSet(y,0);CHKERRQ(ierr);
36*3f93e5bdSPeter Brune   ierr = VecGetArray(x,&xarray);CHKERRQ(ierr);
37*3f93e5bdSPeter Brune   ierr = VecGetArray(y,&yarray);CHKERRQ(ierr);
38*3f93e5bdSPeter Brune   for (i=xs;i<xe;i++) {
39*3f93e5bdSPeter Brune     /* get the maximum row width and row norms */
40*3f93e5bdSPeter Brune     ierr = MatGetRow(pc->pmat,i,&ncols,&cols,&vals);CHKERRQ(ierr);
41*3f93e5bdSPeter Brune     /* form the full residual */
42*3f93e5bdSPeter Brune     r = xarray[i-xs];
43*3f93e5bdSPeter Brune     anrm = 0.;
44*3f93e5bdSPeter Brune     for (j=0;j<ncols;j++) {
45*3f93e5bdSPeter Brune       if (cols[j] >= ys && cols[j] < ye) {
46*3f93e5bdSPeter Brune         r -= yarray[cols[j]-ys]*vals[j];
47*3f93e5bdSPeter Brune       }
48*3f93e5bdSPeter Brune       anrm += PetscRealPart(PetscPowScalar(vals[j],2));
49*3f93e5bdSPeter Brune     }
50*3f93e5bdSPeter Brune     if (anrm > 0) {
51*3f93e5bdSPeter Brune       for (j=0;j<ncols;j++) {
52*3f93e5bdSPeter Brune         if (cols[j] >= ys && cols[j] < ye) {
53*3f93e5bdSPeter Brune           yarray[cols[j]-ys] += vals[j]*lambda*r/anrm;
54*3f93e5bdSPeter Brune         }
55*3f93e5bdSPeter Brune       }
56*3f93e5bdSPeter Brune     }
57*3f93e5bdSPeter Brune     ierr = MatRestoreRow(pc->pmat,i,&ncols,&cols,&vals);CHKERRQ(ierr);
58*3f93e5bdSPeter Brune   }
59*3f93e5bdSPeter Brune   ierr = VecRestoreArray(y,&yarray);CHKERRQ(ierr);
60*3f93e5bdSPeter Brune   ierr = VecRestoreArray(x,&xarray);CHKERRQ(ierr);
61*3f93e5bdSPeter Brune   PetscFunctionReturn(0);
62*3f93e5bdSPeter Brune }
63*3f93e5bdSPeter Brune 
64*3f93e5bdSPeter Brune #undef __FUNCT__
65*3f93e5bdSPeter Brune #define __FUNCT__ "PCSetFromOptions_Kaczmarz"
66*3f93e5bdSPeter Brune PetscErrorCode PCSetFromOptions_Kaczmarz(PC pc)
67*3f93e5bdSPeter Brune {
68*3f93e5bdSPeter Brune   PC_Kaczmarz    *jac = (PC_Kaczmarz*)pc->data;
69*3f93e5bdSPeter Brune   PetscErrorCode ierr;
70*3f93e5bdSPeter Brune 
71*3f93e5bdSPeter Brune   PetscFunctionBegin;
72*3f93e5bdSPeter Brune   ierr = PetscOptionsHead("Kaczmarz options");CHKERRQ(ierr);
73*3f93e5bdSPeter Brune   ierr = PetscOptionsReal("-pc_kaczmarz_lambda","relaxation factor (0 < lambda)","",jac->lambda,&jac->lambda,0);CHKERRQ(ierr);
74*3f93e5bdSPeter Brune   ierr = PetscOptionsTail();CHKERRQ(ierr);
75*3f93e5bdSPeter Brune   PetscFunctionReturn(0);
76*3f93e5bdSPeter Brune }
77*3f93e5bdSPeter Brune 
78*3f93e5bdSPeter Brune #undef __FUNCT__
79*3f93e5bdSPeter Brune #define __FUNCT__ "PCView_Kaczmarz"
80*3f93e5bdSPeter Brune PetscErrorCode PCView_Kaczmarz(PC pc,PetscViewer viewer)
81*3f93e5bdSPeter Brune {
82*3f93e5bdSPeter Brune   PC_Kaczmarz    *jac = (PC_Kaczmarz*)pc->data;
83*3f93e5bdSPeter Brune   PetscErrorCode ierr;
84*3f93e5bdSPeter Brune   PetscBool      iascii;
85*3f93e5bdSPeter Brune 
86*3f93e5bdSPeter Brune   PetscFunctionBegin;
87*3f93e5bdSPeter Brune   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
88*3f93e5bdSPeter Brune   if (iascii) {
89*3f93e5bdSPeter Brune     ierr = PetscViewerASCIIPrintf(viewer,"  Kaczmarz: lambda = %G\n",jac->lambda);CHKERRQ(ierr);
90*3f93e5bdSPeter Brune   }
91*3f93e5bdSPeter Brune   PetscFunctionReturn(0);
92*3f93e5bdSPeter Brune }
93*3f93e5bdSPeter Brune 
94*3f93e5bdSPeter Brune /*MC
95*3f93e5bdSPeter Brune      PCKaczmarz - Kaczmarz iteration
96*3f93e5bdSPeter Brune 
97*3f93e5bdSPeter Brune    Options Database Keys:
98*3f93e5bdSPeter Brune .  -pc_sor_lambda <1.0> - Sets damping parameter lambda
99*3f93e5bdSPeter Brune 
100*3f93e5bdSPeter Brune    Level: beginner
101*3f93e5bdSPeter Brune 
102*3f93e5bdSPeter Brune    Concepts: Kaczmarz, preconditioners, row projection
103*3f93e5bdSPeter Brune 
104*3f93e5bdSPeter Brune    Notes: In parallel this computes off-processor updates at the end of every local sweep
105*3f93e5bdSPeter Brune 
106*3f93e5bdSPeter Brune .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC
107*3f93e5bdSPeter Brune 
108*3f93e5bdSPeter Brune M*/
109*3f93e5bdSPeter Brune 
110*3f93e5bdSPeter Brune #undef __FUNCT__
111*3f93e5bdSPeter Brune #define __FUNCT__ "PCCreate_Kaczmarz"
112*3f93e5bdSPeter Brune PETSC_EXTERN PetscErrorCode PCCreate_Kaczmarz(PC pc)
113*3f93e5bdSPeter Brune {
114*3f93e5bdSPeter Brune   PetscErrorCode ierr;
115*3f93e5bdSPeter Brune   PC_Kaczmarz    *jac;
116*3f93e5bdSPeter Brune 
117*3f93e5bdSPeter Brune   PetscFunctionBegin;
118*3f93e5bdSPeter Brune   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
119*3f93e5bdSPeter Brune 
120*3f93e5bdSPeter Brune   pc->ops->apply           = PCApply_Kaczmarz;
121*3f93e5bdSPeter Brune   pc->ops->setfromoptions  = PCSetFromOptions_Kaczmarz;
122*3f93e5bdSPeter Brune   pc->ops->setup           = 0;
123*3f93e5bdSPeter Brune   pc->ops->view            = PCView_Kaczmarz;
124*3f93e5bdSPeter Brune   pc->ops->destroy         = PCDestroy_Kaczmarz;
125*3f93e5bdSPeter Brune   pc->data                 = (void*)jac;
126*3f93e5bdSPeter Brune   jac->lambda              = 1.0;
127*3f93e5bdSPeter Brune   PetscFunctionReturn(0);
128*3f93e5bdSPeter Brune }
129