1*4b9ad928SBarry Smith /*$Id: redundant.c,v 1.29 2001/04/10 19:36:17 bsmith Exp $*/ 2*4b9ad928SBarry Smith /* 3*4b9ad928SBarry Smith This file defines a "solve the problem redundantly on each processor" preconditioner. 4*4b9ad928SBarry Smith 5*4b9ad928SBarry Smith */ 6*4b9ad928SBarry Smith #include "src/ksp/pc/pcimpl.h" /*I "petscpc.h" I*/ 7*4b9ad928SBarry Smith #include "petscksp.h" 8*4b9ad928SBarry Smith 9*4b9ad928SBarry Smith typedef struct { 10*4b9ad928SBarry Smith PC pc; /* actual preconditioner used on each processor */ 11*4b9ad928SBarry Smith Vec x,b; /* sequential vectors to hold parallel vectors */ 12*4b9ad928SBarry Smith Mat *pmats; /* matrix and optional preconditioner matrix */ 13*4b9ad928SBarry Smith VecScatter scatterin,scatterout; /* scatter used to move all values to each processor */ 14*4b9ad928SBarry Smith PetscTruth useparallelmat; 15*4b9ad928SBarry Smith } PC_Redundant; 16*4b9ad928SBarry Smith 17*4b9ad928SBarry Smith #undef __FUNCT__ 18*4b9ad928SBarry Smith #define __FUNCT__ "PCView_Redundant" 19*4b9ad928SBarry Smith static int PCView_Redundant(PC pc,PetscViewer viewer) 20*4b9ad928SBarry Smith { 21*4b9ad928SBarry Smith PC_Redundant *red = (PC_Redundant*)pc->data; 22*4b9ad928SBarry Smith int ierr,rank; 23*4b9ad928SBarry Smith PetscTruth isascii,isstring; 24*4b9ad928SBarry Smith PetscViewer sviewer; 25*4b9ad928SBarry Smith 26*4b9ad928SBarry Smith PetscFunctionBegin; 27*4b9ad928SBarry Smith ierr = MPI_Comm_rank(pc->comm,&rank);CHKERRQ(ierr); 28*4b9ad928SBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr); 29*4b9ad928SBarry Smith ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_STRING,&isstring);CHKERRQ(ierr); 30*4b9ad928SBarry Smith if (isascii) { 31*4b9ad928SBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Redundant solver preconditioner: Actual PC follows\n");CHKERRQ(ierr); 32*4b9ad928SBarry Smith ierr = PetscViewerGetSingleton(viewer,&sviewer);CHKERRQ(ierr); 33*4b9ad928SBarry Smith if (!rank) { 34*4b9ad928SBarry Smith ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 35*4b9ad928SBarry Smith ierr = PCView(red->pc,sviewer);CHKERRQ(ierr); 36*4b9ad928SBarry Smith ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 37*4b9ad928SBarry Smith } 38*4b9ad928SBarry Smith ierr = PetscViewerRestoreSingleton(viewer,&sviewer);CHKERRQ(ierr); 39*4b9ad928SBarry Smith } else if (isstring) { 40*4b9ad928SBarry Smith ierr = PetscViewerStringSPrintf(viewer," Redundant solver preconditioner");CHKERRQ(ierr); 41*4b9ad928SBarry Smith ierr = PetscViewerGetSingleton(viewer,&sviewer);CHKERRQ(ierr); 42*4b9ad928SBarry Smith if (!rank) { 43*4b9ad928SBarry Smith ierr = PCView(red->pc,sviewer);CHKERRQ(ierr); 44*4b9ad928SBarry Smith } 45*4b9ad928SBarry Smith ierr = PetscViewerRestoreSingleton(viewer,&sviewer);CHKERRQ(ierr); 46*4b9ad928SBarry Smith } else { 47*4b9ad928SBarry Smith SETERRQ1(1,"Viewer type %s not supported for PC redundant",((PetscObject)viewer)->type_name); 48*4b9ad928SBarry Smith } 49*4b9ad928SBarry Smith PetscFunctionReturn(0); 50*4b9ad928SBarry Smith } 51*4b9ad928SBarry Smith 52*4b9ad928SBarry Smith #undef __FUNCT__ 53*4b9ad928SBarry Smith #define __FUNCT__ "PCSetUp_Redundant" 54*4b9ad928SBarry Smith static int PCSetUp_Redundant(PC pc) 55*4b9ad928SBarry Smith { 56*4b9ad928SBarry Smith PC_Redundant *red = (PC_Redundant*)pc->data; 57*4b9ad928SBarry Smith int ierr,mstart,mlocal,m,size; 58*4b9ad928SBarry Smith IS isl; 59*4b9ad928SBarry Smith MatReuse reuse = MAT_INITIAL_MATRIX; 60*4b9ad928SBarry Smith MatStructure str = DIFFERENT_NONZERO_PATTERN; 61*4b9ad928SBarry Smith MPI_Comm comm; 62*4b9ad928SBarry Smith 63*4b9ad928SBarry Smith PetscFunctionBegin; 64*4b9ad928SBarry Smith ierr = PCSetFromOptions(red->pc);CHKERRQ(ierr); 65*4b9ad928SBarry Smith ierr = VecGetSize(pc->vec,&m);CHKERRQ(ierr); 66*4b9ad928SBarry Smith if (!pc->setupcalled) { 67*4b9ad928SBarry Smith ierr = VecGetLocalSize(pc->vec,&mlocal);CHKERRQ(ierr); 68*4b9ad928SBarry Smith ierr = VecCreateSeq(PETSC_COMM_SELF,m,&red->x);CHKERRQ(ierr); 69*4b9ad928SBarry Smith ierr = VecDuplicate(red->x,&red->b);CHKERRQ(ierr); 70*4b9ad928SBarry Smith ierr = PCSetVector(red->pc,red->x);CHKERRQ(ierr); 71*4b9ad928SBarry Smith if (!red->scatterin) { 72*4b9ad928SBarry Smith 73*4b9ad928SBarry Smith /* 74*4b9ad928SBarry Smith Create the vectors and vector scatter to get the entire vector onto each processor 75*4b9ad928SBarry Smith */ 76*4b9ad928SBarry Smith ierr = VecGetOwnershipRange(pc->vec,&mstart,PETSC_NULL);CHKERRQ(ierr); 77*4b9ad928SBarry Smith ierr = VecScatterCreate(pc->vec,0,red->x,0,&red->scatterin);CHKERRQ(ierr); 78*4b9ad928SBarry Smith ierr = ISCreateStride(pc->comm,mlocal,mstart,1,&isl);CHKERRQ(ierr); 79*4b9ad928SBarry Smith ierr = VecScatterCreate(red->x,isl,pc->vec,isl,&red->scatterout);CHKERRQ(ierr); 80*4b9ad928SBarry Smith ierr = ISDestroy(isl);CHKERRQ(ierr); 81*4b9ad928SBarry Smith } 82*4b9ad928SBarry Smith } 83*4b9ad928SBarry Smith 84*4b9ad928SBarry Smith /* if pmatrix set by user is sequential then we do not need to gather the parallel matrix*/ 85*4b9ad928SBarry Smith 86*4b9ad928SBarry Smith ierr = PetscObjectGetComm((PetscObject)pc->pmat,&comm);CHKERRQ(ierr); 87*4b9ad928SBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);CHKERRQ(ierr); 88*4b9ad928SBarry Smith if (size == 1) { 89*4b9ad928SBarry Smith red->useparallelmat = PETSC_FALSE; 90*4b9ad928SBarry Smith } 91*4b9ad928SBarry Smith 92*4b9ad928SBarry Smith if (red->useparallelmat) { 93*4b9ad928SBarry Smith if (pc->setupcalled == 1 && pc->flag == DIFFERENT_NONZERO_PATTERN) { 94*4b9ad928SBarry Smith /* destroy old matrices */ 95*4b9ad928SBarry Smith if (red->pmats) { 96*4b9ad928SBarry Smith ierr = MatDestroyMatrices(1,&red->pmats);CHKERRQ(ierr); 97*4b9ad928SBarry Smith } 98*4b9ad928SBarry Smith } else if (pc->setupcalled == 1) { 99*4b9ad928SBarry Smith reuse = MAT_REUSE_MATRIX; 100*4b9ad928SBarry Smith str = SAME_NONZERO_PATTERN; 101*4b9ad928SBarry Smith } 102*4b9ad928SBarry Smith 103*4b9ad928SBarry Smith /* 104*4b9ad928SBarry Smith grab the parallel matrix and put it on each processor 105*4b9ad928SBarry Smith */ 106*4b9ad928SBarry Smith ierr = ISCreateStride(PETSC_COMM_SELF,m,0,1,&isl);CHKERRQ(ierr); 107*4b9ad928SBarry Smith ierr = MatGetSubMatrices(pc->pmat,1,&isl,&isl,reuse,&red->pmats);CHKERRQ(ierr); 108*4b9ad928SBarry Smith ierr = ISDestroy(isl);CHKERRQ(ierr); 109*4b9ad928SBarry Smith 110*4b9ad928SBarry Smith /* tell sequential PC its operators */ 111*4b9ad928SBarry Smith ierr = PCSetOperators(red->pc,red->pmats[0],red->pmats[0],str);CHKERRQ(ierr); 112*4b9ad928SBarry Smith } else { 113*4b9ad928SBarry Smith ierr = PCSetOperators(red->pc,pc->mat,pc->pmat,pc->flag);CHKERRQ(ierr); 114*4b9ad928SBarry Smith } 115*4b9ad928SBarry Smith ierr = PCSetFromOptions(red->pc);CHKERRQ(ierr); 116*4b9ad928SBarry Smith ierr = PCSetVector(red->pc,red->b);CHKERRQ(ierr); 117*4b9ad928SBarry Smith ierr = PCSetUp(red->pc);CHKERRQ(ierr); 118*4b9ad928SBarry Smith PetscFunctionReturn(0); 119*4b9ad928SBarry Smith } 120*4b9ad928SBarry Smith 121*4b9ad928SBarry Smith 122*4b9ad928SBarry Smith #undef __FUNCT__ 123*4b9ad928SBarry Smith #define __FUNCT__ "PCApply_Redundant" 124*4b9ad928SBarry Smith static int PCApply_Redundant(PC pc,Vec x,Vec y) 125*4b9ad928SBarry Smith { 126*4b9ad928SBarry Smith PC_Redundant *red = (PC_Redundant*)pc->data; 127*4b9ad928SBarry Smith int ierr; 128*4b9ad928SBarry Smith 129*4b9ad928SBarry Smith PetscFunctionBegin; 130*4b9ad928SBarry Smith /* move all values to each processor */ 131*4b9ad928SBarry Smith ierr = VecScatterBegin(x,red->b,INSERT_VALUES,SCATTER_FORWARD,red->scatterin);CHKERRQ(ierr); 132*4b9ad928SBarry Smith ierr = VecScatterEnd(x,red->b,INSERT_VALUES,SCATTER_FORWARD,red->scatterin);CHKERRQ(ierr); 133*4b9ad928SBarry Smith 134*4b9ad928SBarry Smith /* apply preconditioner on each processor */ 135*4b9ad928SBarry Smith ierr = PCApply(red->pc,red->b,red->x,PC_LEFT);CHKERRQ(ierr); 136*4b9ad928SBarry Smith 137*4b9ad928SBarry Smith /* move local part of values into y vector */ 138*4b9ad928SBarry Smith ierr = VecScatterBegin(red->x,y,INSERT_VALUES,SCATTER_FORWARD,red->scatterout);CHKERRQ(ierr); 139*4b9ad928SBarry Smith ierr = VecScatterEnd(red->x,y,INSERT_VALUES,SCATTER_FORWARD,red->scatterout);CHKERRQ(ierr); 140*4b9ad928SBarry Smith PetscFunctionReturn(0); 141*4b9ad928SBarry Smith } 142*4b9ad928SBarry Smith 143*4b9ad928SBarry Smith 144*4b9ad928SBarry Smith #undef __FUNCT__ 145*4b9ad928SBarry Smith #define __FUNCT__ "PCDestroy_Redundant" 146*4b9ad928SBarry Smith static int PCDestroy_Redundant(PC pc) 147*4b9ad928SBarry Smith { 148*4b9ad928SBarry Smith PC_Redundant *red = (PC_Redundant*)pc->data; 149*4b9ad928SBarry Smith int ierr; 150*4b9ad928SBarry Smith 151*4b9ad928SBarry Smith PetscFunctionBegin; 152*4b9ad928SBarry Smith if (red->scatterin) {ierr = VecScatterDestroy(red->scatterin);CHKERRQ(ierr);} 153*4b9ad928SBarry Smith if (red->scatterout) {ierr = VecScatterDestroy(red->scatterout);CHKERRQ(ierr);} 154*4b9ad928SBarry Smith if (red->x) {ierr = VecDestroy(red->x);CHKERRQ(ierr);} 155*4b9ad928SBarry Smith if (red->b) {ierr = VecDestroy(red->b);CHKERRQ(ierr);} 156*4b9ad928SBarry Smith if (red->pmats) { 157*4b9ad928SBarry Smith ierr = MatDestroyMatrices(1,&red->pmats);CHKERRQ(ierr); 158*4b9ad928SBarry Smith } 159*4b9ad928SBarry Smith ierr = PCDestroy(red->pc);CHKERRQ(ierr); 160*4b9ad928SBarry Smith ierr = PetscFree(red);CHKERRQ(ierr); 161*4b9ad928SBarry Smith PetscFunctionReturn(0); 162*4b9ad928SBarry Smith } 163*4b9ad928SBarry Smith 164*4b9ad928SBarry Smith #undef __FUNCT__ 165*4b9ad928SBarry Smith #define __FUNCT__ "PCSetFromOptions_Redundant" 166*4b9ad928SBarry Smith static int PCSetFromOptions_Redundant(PC pc) 167*4b9ad928SBarry Smith { 168*4b9ad928SBarry Smith PetscFunctionBegin; 169*4b9ad928SBarry Smith PetscFunctionReturn(0); 170*4b9ad928SBarry Smith } 171*4b9ad928SBarry Smith 172*4b9ad928SBarry Smith EXTERN_C_BEGIN 173*4b9ad928SBarry Smith #undef __FUNCT__ 174*4b9ad928SBarry Smith #define __FUNCT__ "PCRedundantSetScatter_Redundant" 175*4b9ad928SBarry Smith int PCRedundantSetScatter_Redundant(PC pc,VecScatter in,VecScatter out) 176*4b9ad928SBarry Smith { 177*4b9ad928SBarry Smith PC_Redundant *red = (PC_Redundant*)pc->data; 178*4b9ad928SBarry Smith int ierr; 179*4b9ad928SBarry Smith 180*4b9ad928SBarry Smith PetscFunctionBegin; 181*4b9ad928SBarry Smith red->scatterin = in; 182*4b9ad928SBarry Smith red->scatterout = out; 183*4b9ad928SBarry Smith ierr = PetscObjectReference((PetscObject)in);CHKERRQ(ierr); 184*4b9ad928SBarry Smith ierr = PetscObjectReference((PetscObject)out);CHKERRQ(ierr); 185*4b9ad928SBarry Smith PetscFunctionReturn(0); 186*4b9ad928SBarry Smith } 187*4b9ad928SBarry Smith EXTERN_C_END 188*4b9ad928SBarry Smith 189*4b9ad928SBarry Smith #undef __FUNCT__ 190*4b9ad928SBarry Smith #define __FUNCT__ "PCRedundantSetScatter" 191*4b9ad928SBarry Smith /*@ 192*4b9ad928SBarry Smith PCRedundantSetScatter - Sets the scatter used to copy values into the 193*4b9ad928SBarry Smith redundant local solve and the scatter to move them back into the global 194*4b9ad928SBarry Smith vector. 195*4b9ad928SBarry Smith 196*4b9ad928SBarry Smith Collective on PC 197*4b9ad928SBarry Smith 198*4b9ad928SBarry Smith Input Parameters: 199*4b9ad928SBarry Smith + pc - the preconditioner context 200*4b9ad928SBarry Smith . in - the scatter to move the values in 201*4b9ad928SBarry Smith - out - the scatter to move them out 202*4b9ad928SBarry Smith 203*4b9ad928SBarry Smith Level: advanced 204*4b9ad928SBarry Smith 205*4b9ad928SBarry Smith .keywords: PC, redundant solve 206*4b9ad928SBarry Smith @*/ 207*4b9ad928SBarry Smith int PCRedundantSetScatter(PC pc,VecScatter in,VecScatter out) 208*4b9ad928SBarry Smith { 209*4b9ad928SBarry Smith int ierr,(*f)(PC,VecScatter,VecScatter); 210*4b9ad928SBarry Smith 211*4b9ad928SBarry Smith PetscFunctionBegin; 212*4b9ad928SBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE); 213*4b9ad928SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)pc,"PCRedundantSetScatter_C",(void (**)(void))&f);CHKERRQ(ierr); 214*4b9ad928SBarry Smith if (f) { 215*4b9ad928SBarry Smith ierr = (*f)(pc,in,out);CHKERRQ(ierr); 216*4b9ad928SBarry Smith } 217*4b9ad928SBarry Smith PetscFunctionReturn(0); 218*4b9ad928SBarry Smith } 219*4b9ad928SBarry Smith 220*4b9ad928SBarry Smith EXTERN_C_BEGIN 221*4b9ad928SBarry Smith #undef __FUNCT__ 222*4b9ad928SBarry Smith #define __FUNCT__ "PCRedundantGetPC_Redundant" 223*4b9ad928SBarry Smith int PCRedundantGetPC_Redundant(PC pc,PC *innerpc) 224*4b9ad928SBarry Smith { 225*4b9ad928SBarry Smith PC_Redundant *red = (PC_Redundant*)pc->data; 226*4b9ad928SBarry Smith 227*4b9ad928SBarry Smith PetscFunctionBegin; 228*4b9ad928SBarry Smith *innerpc = red->pc; 229*4b9ad928SBarry Smith PetscFunctionReturn(0); 230*4b9ad928SBarry Smith } 231*4b9ad928SBarry Smith EXTERN_C_END 232*4b9ad928SBarry Smith 233*4b9ad928SBarry Smith #undef __FUNCT__ 234*4b9ad928SBarry Smith #define __FUNCT__ "PCRedundantGetPC" 235*4b9ad928SBarry Smith /*@ 236*4b9ad928SBarry Smith PCRedundantGetPC - Gets the sequential PC created by the redundant PC. 237*4b9ad928SBarry Smith 238*4b9ad928SBarry Smith Not Collective 239*4b9ad928SBarry Smith 240*4b9ad928SBarry Smith Input Parameter: 241*4b9ad928SBarry Smith . pc - the preconditioner context 242*4b9ad928SBarry Smith 243*4b9ad928SBarry Smith Output Parameter: 244*4b9ad928SBarry Smith . innerpc - the sequential PC 245*4b9ad928SBarry Smith 246*4b9ad928SBarry Smith Level: advanced 247*4b9ad928SBarry Smith 248*4b9ad928SBarry Smith .keywords: PC, redundant solve 249*4b9ad928SBarry Smith @*/ 250*4b9ad928SBarry Smith int PCRedundantGetPC(PC pc,PC *innerpc) 251*4b9ad928SBarry Smith { 252*4b9ad928SBarry Smith int ierr,(*f)(PC,PC*); 253*4b9ad928SBarry Smith 254*4b9ad928SBarry Smith PetscFunctionBegin; 255*4b9ad928SBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE); 256*4b9ad928SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)pc,"PCRedundantGetPC_C",(void (**)(void))&f);CHKERRQ(ierr); 257*4b9ad928SBarry Smith if (f) { 258*4b9ad928SBarry Smith ierr = (*f)(pc,innerpc);CHKERRQ(ierr); 259*4b9ad928SBarry Smith } 260*4b9ad928SBarry Smith PetscFunctionReturn(0); 261*4b9ad928SBarry Smith } 262*4b9ad928SBarry Smith 263*4b9ad928SBarry Smith EXTERN_C_BEGIN 264*4b9ad928SBarry Smith #undef __FUNCT__ 265*4b9ad928SBarry Smith #define __FUNCT__ "PCRedundantGetOperators_Redundant" 266*4b9ad928SBarry Smith int PCRedundantGetOperators_Redundant(PC pc,Mat *mat,Mat *pmat) 267*4b9ad928SBarry Smith { 268*4b9ad928SBarry Smith PC_Redundant *red = (PC_Redundant*)pc->data; 269*4b9ad928SBarry Smith 270*4b9ad928SBarry Smith PetscFunctionBegin; 271*4b9ad928SBarry Smith if (mat) *mat = red->pmats[0]; 272*4b9ad928SBarry Smith if (pmat) *pmat = red->pmats[0]; 273*4b9ad928SBarry Smith PetscFunctionReturn(0); 274*4b9ad928SBarry Smith } 275*4b9ad928SBarry Smith EXTERN_C_END 276*4b9ad928SBarry Smith 277*4b9ad928SBarry Smith #undef __FUNCT__ 278*4b9ad928SBarry Smith #define __FUNCT__ "PCRedundantGetOperators" 279*4b9ad928SBarry Smith /*@ 280*4b9ad928SBarry Smith PCRedundantGetOperators - gets the sequential matrix and preconditioner matrix 281*4b9ad928SBarry Smith 282*4b9ad928SBarry Smith Not Collective 283*4b9ad928SBarry Smith 284*4b9ad928SBarry Smith Input Parameter: 285*4b9ad928SBarry Smith . pc - the preconditioner context 286*4b9ad928SBarry Smith 287*4b9ad928SBarry Smith Output Parameters: 288*4b9ad928SBarry Smith + mat - the matrix 289*4b9ad928SBarry Smith - pmat - the (possibly different) preconditioner matrix 290*4b9ad928SBarry Smith 291*4b9ad928SBarry Smith Level: advanced 292*4b9ad928SBarry Smith 293*4b9ad928SBarry Smith .keywords: PC, redundant solve 294*4b9ad928SBarry Smith @*/ 295*4b9ad928SBarry Smith int PCRedundantGetOperators(PC pc,Mat *mat,Mat *pmat) 296*4b9ad928SBarry Smith { 297*4b9ad928SBarry Smith int ierr,(*f)(PC,Mat*,Mat*); 298*4b9ad928SBarry Smith 299*4b9ad928SBarry Smith PetscFunctionBegin; 300*4b9ad928SBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE); 301*4b9ad928SBarry Smith ierr = PetscObjectQueryFunction((PetscObject)pc,"PCRedundantGetOperators_C",(void (**)(void))&f);CHKERRQ(ierr); 302*4b9ad928SBarry Smith if (f) { 303*4b9ad928SBarry Smith ierr = (*f)(pc,mat,pmat);CHKERRQ(ierr); 304*4b9ad928SBarry Smith } 305*4b9ad928SBarry Smith PetscFunctionReturn(0); 306*4b9ad928SBarry Smith } 307*4b9ad928SBarry Smith 308*4b9ad928SBarry Smith /* -------------------------------------------------------------------------------------*/ 309*4b9ad928SBarry Smith EXTERN_C_BEGIN 310*4b9ad928SBarry Smith #undef __FUNCT__ 311*4b9ad928SBarry Smith #define __FUNCT__ "PCCreate_Redundant" 312*4b9ad928SBarry Smith int PCCreate_Redundant(PC pc) 313*4b9ad928SBarry Smith { 314*4b9ad928SBarry Smith int ierr; 315*4b9ad928SBarry Smith PC_Redundant *red; 316*4b9ad928SBarry Smith char *prefix; 317*4b9ad928SBarry Smith 318*4b9ad928SBarry Smith PetscFunctionBegin; 319*4b9ad928SBarry Smith ierr = PetscNew(PC_Redundant,&red);CHKERRQ(ierr); 320*4b9ad928SBarry Smith PetscLogObjectMemory(pc,sizeof(PC_Redundant)); 321*4b9ad928SBarry Smith ierr = PetscMemzero(red,sizeof(PC_Redundant));CHKERRQ(ierr); 322*4b9ad928SBarry Smith red->useparallelmat = PETSC_TRUE; 323*4b9ad928SBarry Smith 324*4b9ad928SBarry Smith /* create the sequential PC that each processor has copy of */ 325*4b9ad928SBarry Smith ierr = PCCreate(PETSC_COMM_SELF,&red->pc);CHKERRQ(ierr); 326*4b9ad928SBarry Smith ierr = PCSetType(red->pc,PCLU);CHKERRQ(ierr); 327*4b9ad928SBarry Smith ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); 328*4b9ad928SBarry Smith ierr = PCSetOptionsPrefix(red->pc,prefix);CHKERRQ(ierr); 329*4b9ad928SBarry Smith ierr = PCAppendOptionsPrefix(red->pc,"redundant_");CHKERRQ(ierr); 330*4b9ad928SBarry Smith 331*4b9ad928SBarry Smith pc->ops->apply = PCApply_Redundant; 332*4b9ad928SBarry Smith pc->ops->applytranspose = 0; 333*4b9ad928SBarry Smith pc->ops->setup = PCSetUp_Redundant; 334*4b9ad928SBarry Smith pc->ops->destroy = PCDestroy_Redundant; 335*4b9ad928SBarry Smith pc->ops->setfromoptions = PCSetFromOptions_Redundant; 336*4b9ad928SBarry Smith pc->ops->setuponblocks = 0; 337*4b9ad928SBarry Smith pc->ops->view = PCView_Redundant; 338*4b9ad928SBarry Smith pc->ops->applyrichardson = 0; 339*4b9ad928SBarry Smith 340*4b9ad928SBarry Smith pc->data = (void*)red; 341*4b9ad928SBarry Smith 342*4b9ad928SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCRedundantSetScatter_C","PCRedundantSetScatter_Redundant", 343*4b9ad928SBarry Smith PCRedundantSetScatter_Redundant);CHKERRQ(ierr); 344*4b9ad928SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCRedundantGetPC_C","PCRedundantGetPC_Redundant", 345*4b9ad928SBarry Smith PCRedundantGetPC_Redundant);CHKERRQ(ierr); 346*4b9ad928SBarry Smith ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCRedundantGetOperators_C","PCRedundantGetOperators_Redundant", 347*4b9ad928SBarry Smith PCRedundantGetOperators_Redundant);CHKERRQ(ierr); 348*4b9ad928SBarry Smith 349*4b9ad928SBarry Smith PetscFunctionReturn(0); 350*4b9ad928SBarry Smith } 351*4b9ad928SBarry Smith EXTERN_C_END 352