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