xref: /petsc/src/ksp/pc/impls/telescope/telescope.c (revision a04a6428007092eb997a1addf5b744d9fc905f9a)
11e07b27eSBarry Smith 
2120bdd93SDave May #include <petsc/private/matimpl.h>
36fc41876SBarry Smith #include <petsc/private/pcimpl.h>
41e07b27eSBarry Smith #include <petscksp.h> /*I "petscksp.h" I*/
51e07b27eSBarry Smith #include <petscdm.h> /*I "petscdm.h" I*/
6575a0592SBarry Smith #include "../src/ksp/pc/impls/telescope/telescope.h"
71e07b27eSBarry Smith 
81e07b27eSBarry Smith /*
91e07b27eSBarry Smith  PCTelescopeSetUp_default()
101e07b27eSBarry Smith  PCTelescopeMatCreate_default()
111e07b27eSBarry Smith 
121e07b27eSBarry Smith  default
131e07b27eSBarry Smith 
141e07b27eSBarry Smith  // scatter in
151e07b27eSBarry Smith  x(comm) -> xtmp(comm)
161e07b27eSBarry Smith 
171e07b27eSBarry Smith  xred(subcomm) <- xtmp
181e07b27eSBarry Smith  yred(subcomm)
191e07b27eSBarry Smith 
201e07b27eSBarry Smith  yred(subcomm) --> xtmp
211e07b27eSBarry Smith 
221e07b27eSBarry Smith  // scatter out
231e07b27eSBarry Smith  xtmp(comm) -> y(comm)
241e07b27eSBarry Smith */
251e07b27eSBarry Smith 
261e07b27eSBarry Smith PetscBool isActiveRank(PetscSubcomm scomm)
271e07b27eSBarry Smith {
281e07b27eSBarry Smith   if (scomm->color == 0) { return PETSC_TRUE; }
291e07b27eSBarry Smith   else { return PETSC_FALSE; }
301e07b27eSBarry Smith }
311e07b27eSBarry Smith 
321e07b27eSBarry Smith #undef __FUNCT__
331e07b27eSBarry Smith #define __FUNCT__ "private_PCTelescopeGetSubDM"
341e07b27eSBarry Smith DM private_PCTelescopeGetSubDM(PC_Telescope sred)
351e07b27eSBarry Smith {
36c6a0d831SBarry Smith   DM subdm = NULL;
371e07b27eSBarry Smith 
381e07b27eSBarry Smith   if (!isActiveRank(sred->psubcomm)) { subdm = NULL; }
391e07b27eSBarry Smith   else {
401e07b27eSBarry Smith     switch (sred->sr_type) {
411e07b27eSBarry Smith     case TELESCOPE_DEFAULT: subdm = NULL;
421e07b27eSBarry Smith       break;
431e07b27eSBarry Smith     case TELESCOPE_DMDA:    subdm = ((PC_Telescope_DMDACtx*)sred->dm_ctx)->dmrepart;
441e07b27eSBarry Smith       break;
451e07b27eSBarry Smith     case TELESCOPE_DMPLEX:  subdm = NULL;
461e07b27eSBarry Smith       break;
471e07b27eSBarry Smith     }
481e07b27eSBarry Smith   }
491e07b27eSBarry Smith   return(subdm);
501e07b27eSBarry Smith }
511e07b27eSBarry Smith 
521e07b27eSBarry Smith #undef __FUNCT__
531e07b27eSBarry Smith #define __FUNCT__ "PCTelescopeSetUp_default"
541e07b27eSBarry Smith PetscErrorCode PCTelescopeSetUp_default(PC pc,PC_Telescope sred)
551e07b27eSBarry Smith {
561e07b27eSBarry Smith   PetscErrorCode ierr;
571e07b27eSBarry Smith   PetscInt       m,M,bs,st,ed;
581e07b27eSBarry Smith   Vec            x,xred,yred,xtmp;
591e07b27eSBarry Smith   Mat            B;
601e07b27eSBarry Smith   MPI_Comm       comm,subcomm;
611e07b27eSBarry Smith   VecScatter     scatter;
621e07b27eSBarry Smith   IS             isin;
631e07b27eSBarry Smith 
641e07b27eSBarry Smith   PetscFunctionBegin;
651e07b27eSBarry Smith   ierr = PetscInfo(pc,"PCTelescope: setup (default)\n");CHKERRQ(ierr);
661e07b27eSBarry Smith   comm = PetscSubcommParent(sred->psubcomm);
671e07b27eSBarry Smith   subcomm = PetscSubcommChild(sred->psubcomm);
681e07b27eSBarry Smith 
691e07b27eSBarry Smith   ierr = PCGetOperators(pc,NULL,&B);CHKERRQ(ierr);
701e07b27eSBarry Smith   ierr = MatGetSize(B,&M,NULL);CHKERRQ(ierr);
711e07b27eSBarry Smith   ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr);
721e07b27eSBarry Smith   ierr = MatCreateVecs(B,&x,NULL);CHKERRQ(ierr);
731e07b27eSBarry Smith 
741e07b27eSBarry Smith   xred = NULL;
753ac26c5eSBarry Smith   m    = 0;
761e07b27eSBarry Smith   if (isActiveRank(sred->psubcomm)) {
771e07b27eSBarry Smith     ierr = VecCreate(subcomm,&xred);CHKERRQ(ierr);
781e07b27eSBarry Smith     ierr = VecSetSizes(xred,PETSC_DECIDE,M);CHKERRQ(ierr);
791e07b27eSBarry Smith     ierr = VecSetBlockSize(xred,bs);CHKERRQ(ierr);
801e07b27eSBarry Smith     ierr = VecSetFromOptions(xred);CHKERRQ(ierr);
81ca43db0aSBarry Smith     ierr = VecGetLocalSize(xred,&m);CHKERRQ(ierr);
821e07b27eSBarry Smith   }
831e07b27eSBarry Smith 
841e07b27eSBarry Smith   yred = NULL;
851e07b27eSBarry Smith   if (isActiveRank(sred->psubcomm)) {
861e07b27eSBarry Smith     ierr = VecDuplicate(xred,&yred);CHKERRQ(ierr);
871e07b27eSBarry Smith   }
881e07b27eSBarry Smith 
891e07b27eSBarry Smith   ierr = VecCreate(comm,&xtmp);CHKERRQ(ierr);
901e07b27eSBarry Smith   ierr = VecSetSizes(xtmp,m,PETSC_DECIDE);CHKERRQ(ierr);
911e07b27eSBarry Smith   ierr = VecSetBlockSize(xtmp,bs);CHKERRQ(ierr);
921e07b27eSBarry Smith   ierr = VecSetType(xtmp,((PetscObject)x)->type_name);CHKERRQ(ierr);
931e07b27eSBarry Smith 
941e07b27eSBarry Smith   if (isActiveRank(sred->psubcomm)) {
951e07b27eSBarry Smith     ierr = VecGetOwnershipRange(xred,&st,&ed);CHKERRQ(ierr);
961e07b27eSBarry Smith     ierr = ISCreateStride(comm,(ed-st),st,1,&isin);CHKERRQ(ierr);
971e07b27eSBarry Smith   } else {
981e07b27eSBarry Smith     ierr = VecGetOwnershipRange(x,&st,&ed);CHKERRQ(ierr);
993ac26c5eSBarry Smith     ierr = ISCreateStride(comm,0,st,1,&isin);CHKERRQ(ierr);
1001e07b27eSBarry Smith   }
1011e07b27eSBarry Smith   ierr = ISSetBlockSize(isin,bs);CHKERRQ(ierr);
1021e07b27eSBarry Smith 
1031e07b27eSBarry Smith   ierr = VecScatterCreate(x,isin,xtmp,NULL,&scatter);CHKERRQ(ierr);
1041e07b27eSBarry Smith 
1051e07b27eSBarry Smith   sred->isin    = isin;
1061e07b27eSBarry Smith   sred->scatter = scatter;
1071e07b27eSBarry Smith   sred->xred    = xred;
1081e07b27eSBarry Smith   sred->yred    = yred;
1091e07b27eSBarry Smith   sred->xtmp    = xtmp;
1101e07b27eSBarry Smith   ierr = VecDestroy(&x);CHKERRQ(ierr);
1111e07b27eSBarry Smith   PetscFunctionReturn(0);
1121e07b27eSBarry Smith }
1131e07b27eSBarry Smith 
1141e07b27eSBarry Smith #undef __FUNCT__
1151e07b27eSBarry Smith #define __FUNCT__ "PCTelescopeMatCreate_default"
1161e07b27eSBarry Smith PetscErrorCode PCTelescopeMatCreate_default(PC pc,PC_Telescope sred,MatReuse reuse,Mat *A)
1171e07b27eSBarry Smith {
1181e07b27eSBarry Smith   PetscErrorCode ierr;
1191e07b27eSBarry Smith   MPI_Comm       comm,subcomm;
1201e07b27eSBarry Smith   Mat            Bred,B;
1211e07b27eSBarry Smith   PetscInt       nr,nc;
1221e07b27eSBarry Smith   IS             isrow,iscol;
1231e07b27eSBarry Smith   Mat            Blocal,*_Blocal;
1241e07b27eSBarry Smith 
1251e07b27eSBarry Smith   PetscFunctionBegin;
1261e07b27eSBarry Smith   ierr = PetscInfo(pc,"PCTelescope: updating the redundant preconditioned operator (default)\n");CHKERRQ(ierr);
1271e07b27eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr);
1281e07b27eSBarry Smith   subcomm = PetscSubcommChild(sred->psubcomm);
1291e07b27eSBarry Smith   ierr = PCGetOperators(pc,NULL,&B);CHKERRQ(ierr);
1301e07b27eSBarry Smith   ierr = MatGetSize(B,&nr,&nc);CHKERRQ(ierr);
1311e07b27eSBarry Smith   isrow = sred->isin;
1321e07b27eSBarry Smith   ierr = ISCreateStride(comm,nc,0,1,&iscol);CHKERRQ(ierr);
1331e07b27eSBarry Smith   ierr = MatGetSubMatrices(B,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&_Blocal);CHKERRQ(ierr);
1341e07b27eSBarry Smith   Blocal = *_Blocal;
1351e07b27eSBarry Smith   ierr = PetscFree(_Blocal);CHKERRQ(ierr);
1361e07b27eSBarry Smith   Bred = NULL;
1371e07b27eSBarry Smith   if (isActiveRank(sred->psubcomm)) {
1381e07b27eSBarry Smith     PetscInt mm;
1391e07b27eSBarry Smith 
1401e07b27eSBarry Smith     if (reuse != MAT_INITIAL_MATRIX) { Bred = *A; }
1411e07b27eSBarry Smith 
1421e07b27eSBarry Smith     ierr = MatGetSize(Blocal,&mm,NULL);CHKERRQ(ierr);
1431e07b27eSBarry Smith     ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,Blocal,mm,reuse,&Bred);CHKERRQ(ierr);
1441e07b27eSBarry Smith   }
1451e07b27eSBarry Smith   *A = Bred;
1461e07b27eSBarry Smith   ierr = ISDestroy(&iscol);CHKERRQ(ierr);
1471e07b27eSBarry Smith   ierr = MatDestroy(&Blocal);CHKERRQ(ierr);
1481e07b27eSBarry Smith   PetscFunctionReturn(0);
1491e07b27eSBarry Smith }
1501e07b27eSBarry Smith 
1511e07b27eSBarry Smith #undef __FUNCT__
1521e07b27eSBarry Smith #define __FUNCT__ "PCTelescopeMatNullSpaceCreate_default"
1531e07b27eSBarry Smith PetscErrorCode PCTelescopeMatNullSpaceCreate_default(PC pc,PC_Telescope sred,Mat sub_mat)
1541e07b27eSBarry Smith {
1551e07b27eSBarry Smith   PetscErrorCode   ierr;
1561e07b27eSBarry Smith   MatNullSpace     nullspace,sub_nullspace;
1571e07b27eSBarry Smith   Mat              A,B;
1581e07b27eSBarry Smith   PetscBool        has_const;
159a947c41eSDave May   PetscInt         i,k,n = 0;
1601e07b27eSBarry Smith   const Vec        *vecs;
161c41e779fSDave May   Vec              *sub_vecs = NULL;
1621e07b27eSBarry Smith   MPI_Comm         subcomm;
1631e07b27eSBarry Smith 
1641e07b27eSBarry Smith   PetscFunctionBegin;
1651e07b27eSBarry Smith   ierr = PCGetOperators(pc,&A,&B);CHKERRQ(ierr);
1661e07b27eSBarry Smith   ierr = MatGetNullSpace(B,&nullspace);CHKERRQ(ierr);
167a947c41eSDave May   if (!nullspace) PetscFunctionReturn(0);
1681e07b27eSBarry Smith 
1691e07b27eSBarry Smith   ierr = PetscInfo(pc,"PCTelescope: generating nullspace (default)\n");CHKERRQ(ierr);
1701e07b27eSBarry Smith   subcomm = PetscSubcommChild(sred->psubcomm);
1711e07b27eSBarry Smith   ierr = MatNullSpaceGetVecs(nullspace,&has_const,&n,&vecs);CHKERRQ(ierr);
1721e07b27eSBarry Smith 
1731e07b27eSBarry Smith   if (isActiveRank(sred->psubcomm)) {
174e3acf2f7SBarry Smith     if (n) {
175e3acf2f7SBarry Smith       ierr = VecDuplicateVecs(sred->xred,n,&sub_vecs);CHKERRQ(ierr);
1761e07b27eSBarry Smith     }
1771e07b27eSBarry Smith   }
1781e07b27eSBarry Smith 
1791e07b27eSBarry Smith   /* copy entries */
1801e07b27eSBarry Smith   for (k=0; k<n; k++) {
1811e07b27eSBarry Smith     const PetscScalar *x_array;
1821e07b27eSBarry Smith     PetscScalar       *LA_sub_vec;
18313c30530SDave May     PetscInt          st,ed;
1841e07b27eSBarry Smith 
1851e07b27eSBarry Smith     /* pull in vector x->xtmp */
1861e07b27eSBarry Smith     ierr = VecScatterBegin(sred->scatter,vecs[k],sred->xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
1871e07b27eSBarry Smith     ierr = VecScatterEnd(sred->scatter,vecs[k],sred->xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
18847856c66SBarry Smith     if (sub_vecs) {
189*a04a6428SPatrick Sanan       /* copy vector entries into xred */
1901e07b27eSBarry Smith       ierr = VecGetArrayRead(sred->xtmp,&x_array);CHKERRQ(ierr);
191ea2b237eSDave May       if (sub_vecs[k]) {
1921e07b27eSBarry Smith         ierr = VecGetOwnershipRange(sub_vecs[k],&st,&ed);CHKERRQ(ierr);
1931e07b27eSBarry Smith         ierr = VecGetArray(sub_vecs[k],&LA_sub_vec);CHKERRQ(ierr);
1941e07b27eSBarry Smith         for (i=0; i<ed-st; i++) {
1951e07b27eSBarry Smith           LA_sub_vec[i] = x_array[i];
1961e07b27eSBarry Smith         }
1971e07b27eSBarry Smith         ierr = VecRestoreArray(sub_vecs[k],&LA_sub_vec);CHKERRQ(ierr);
1981e07b27eSBarry Smith       }
1991e07b27eSBarry Smith       ierr = VecRestoreArrayRead(sred->xtmp,&x_array);CHKERRQ(ierr);
2001e07b27eSBarry Smith     }
20147856c66SBarry Smith   }
2021e07b27eSBarry Smith 
2031e07b27eSBarry Smith   if (isActiveRank(sred->psubcomm)) {
2041e07b27eSBarry Smith     /* create new nullspace for redundant object */
2051e07b27eSBarry Smith     ierr = MatNullSpaceCreate(subcomm,has_const,n,sub_vecs,&sub_nullspace);CHKERRQ(ierr);
206120bdd93SDave May     sub_nullspace->remove = nullspace->remove;
207120bdd93SDave May     sub_nullspace->rmctx = nullspace->rmctx;
208120bdd93SDave May 
2091e07b27eSBarry Smith     /* attach redundant nullspace to Bred */
2101e07b27eSBarry Smith     ierr = MatSetNullSpace(sub_mat,sub_nullspace);CHKERRQ(ierr);
211e3acf2f7SBarry Smith     ierr = VecDestroyVecs(n,&sub_vecs);CHKERRQ(ierr);
2121e07b27eSBarry Smith   }
2131e07b27eSBarry Smith   PetscFunctionReturn(0);
2141e07b27eSBarry Smith }
2151e07b27eSBarry Smith 
2161e07b27eSBarry Smith #undef __FUNCT__
2171e07b27eSBarry Smith #define __FUNCT__ "PCView_Telescope"
2181e07b27eSBarry Smith static PetscErrorCode PCView_Telescope(PC pc,PetscViewer viewer)
2191e07b27eSBarry Smith {
2201e07b27eSBarry Smith   PC_Telescope     sred = (PC_Telescope)pc->data;
2211e07b27eSBarry Smith   PetscErrorCode   ierr;
2221e07b27eSBarry Smith   PetscBool        iascii,isstring;
2231e07b27eSBarry Smith   PetscViewer      subviewer;
2241e07b27eSBarry Smith 
2251e07b27eSBarry Smith   PetscFunctionBegin;
2261e07b27eSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
2271e07b27eSBarry Smith   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr);
2281e07b27eSBarry Smith   if (iascii) {
2291e07b27eSBarry Smith     if (!sred->psubcomm) {
2301e07b27eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Telescope: preconditioner not yet setup\n");CHKERRQ(ierr);
2311e07b27eSBarry Smith     } else {
2321e07b27eSBarry Smith       MPI_Comm    comm,subcomm;
2331e07b27eSBarry Smith       PetscMPIInt comm_size,subcomm_size;
2341e07b27eSBarry Smith       DM          dm,subdm;
2351e07b27eSBarry Smith 
2361e07b27eSBarry Smith       ierr = PCGetDM(pc,&dm);CHKERRQ(ierr);
2371e07b27eSBarry Smith       subdm = private_PCTelescopeGetSubDM(sred);
2381e07b27eSBarry Smith       comm = PetscSubcommParent(sred->psubcomm);
2391e07b27eSBarry Smith       subcomm = PetscSubcommChild(sred->psubcomm);
2401e07b27eSBarry Smith       ierr = MPI_Comm_size(comm,&comm_size);CHKERRQ(ierr);
2411e07b27eSBarry Smith       ierr = MPI_Comm_size(subcomm,&subcomm_size);CHKERRQ(ierr);
2421e07b27eSBarry Smith 
2431e07b27eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Telescope: parent comm size reduction factor = %D\n",sred->redfactor);CHKERRQ(ierr);
2441e07b27eSBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"  Telescope: comm_size = %d , subcomm_size = %d\n",(int)comm_size,(int)subcomm_size);CHKERRQ(ierr);
24548a10b22SPatrick Sanan       switch (sred->subcommtype) {
24648a10b22SPatrick Sanan         case PETSC_SUBCOMM_INTERLACED :
24748a10b22SPatrick Sanan           ierr = PetscViewerASCIIPrintf(viewer,"  Telescope: subcomm type: interlaced\n",sred->subcommtype);CHKERRQ(ierr);
24848a10b22SPatrick Sanan           break;
24948a10b22SPatrick Sanan         case PETSC_SUBCOMM_CONTIGUOUS :
25048a10b22SPatrick Sanan           ierr = PetscViewerASCIIPrintf(viewer,"  Telescope: subcomm type: contiguous\n",sred->subcommtype);CHKERRQ(ierr);
25148a10b22SPatrick Sanan           break;
25248a10b22SPatrick Sanan         default :
25348a10b22SPatrick Sanan           SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"General subcomm type not supported by PCTelescope");
25448a10b22SPatrick Sanan       }
2551e07b27eSBarry Smith       ierr = PetscViewerGetSubViewer(viewer,subcomm,&subviewer);CHKERRQ(ierr);
2561e07b27eSBarry Smith       if (isActiveRank(sred->psubcomm)) {
2571e07b27eSBarry Smith         ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr);
2581e07b27eSBarry Smith 
2591e07b27eSBarry Smith         if (dm && sred->ignore_dm) {
2601e07b27eSBarry Smith           ierr = PetscViewerASCIIPrintf(subviewer,"  Telescope: ignoring DM\n");CHKERRQ(ierr);
2611e07b27eSBarry Smith         }
2627c5279cbSDave May         if (sred->ignore_kspcomputeoperators) {
2637c5279cbSDave May           ierr = PetscViewerASCIIPrintf(subviewer,"  Telescope: ignoring KSPComputeOperators\n");CHKERRQ(ierr);
2647c5279cbSDave May         }
2651e07b27eSBarry Smith         switch (sred->sr_type) {
2661e07b27eSBarry Smith         case TELESCOPE_DEFAULT:
2671e07b27eSBarry Smith           ierr = PetscViewerASCIIPrintf(subviewer,"  Telescope: using default setup\n");CHKERRQ(ierr);
2681e07b27eSBarry Smith           break;
2691e07b27eSBarry Smith         case TELESCOPE_DMDA:
2701e07b27eSBarry Smith           ierr = PetscViewerASCIIPrintf(subviewer,"  Telescope: DMDA detected\n");CHKERRQ(ierr);
2711e07b27eSBarry Smith           ierr = DMView_DMDAShort(subdm,subviewer);CHKERRQ(ierr);
2721e07b27eSBarry Smith           break;
2731e07b27eSBarry Smith         case TELESCOPE_DMPLEX:
2741e07b27eSBarry Smith           ierr = PetscViewerASCIIPrintf(subviewer,"  Telescope: DMPLEX detected\n");CHKERRQ(ierr);
2751e07b27eSBarry Smith           break;
2761e07b27eSBarry Smith         }
2771e07b27eSBarry Smith 
2781e07b27eSBarry Smith         ierr = KSPView(sred->ksp,subviewer);CHKERRQ(ierr);
2791e07b27eSBarry Smith         ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr);
2801e07b27eSBarry Smith       }
2811e07b27eSBarry Smith       ierr = PetscViewerRestoreSubViewer(viewer,subcomm,&subviewer);CHKERRQ(ierr);
2821e07b27eSBarry Smith     }
2831e07b27eSBarry Smith   }
2841e07b27eSBarry Smith   PetscFunctionReturn(0);
2851e07b27eSBarry Smith }
2861e07b27eSBarry Smith 
2871e07b27eSBarry Smith #undef __FUNCT__
2881e07b27eSBarry Smith #define __FUNCT__ "PCSetUp_Telescope"
2891e07b27eSBarry Smith static PetscErrorCode PCSetUp_Telescope(PC pc)
2901e07b27eSBarry Smith {
2911e07b27eSBarry Smith   PC_Telescope      sred = (PC_Telescope)pc->data;
2921e07b27eSBarry Smith   PetscErrorCode    ierr;
293bd49479cSSatish Balay   MPI_Comm          comm,subcomm=0;
2941e07b27eSBarry Smith   PCTelescopeType   sr_type;
2951e07b27eSBarry Smith 
2961e07b27eSBarry Smith   PetscFunctionBegin;
2971e07b27eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr);
2981e07b27eSBarry Smith 
2991e07b27eSBarry Smith   /* subcomm definition */
3001e07b27eSBarry Smith   if (!pc->setupcalled) {
3011e07b27eSBarry Smith     if (!sred->psubcomm) {
3021e07b27eSBarry Smith       ierr = PetscSubcommCreate(comm,&sred->psubcomm);CHKERRQ(ierr);
3031e07b27eSBarry Smith       ierr = PetscSubcommSetNumber(sred->psubcomm,sred->redfactor);CHKERRQ(ierr);
30448a10b22SPatrick Sanan       ierr = PetscSubcommSetType(sred->psubcomm,sred->subcommtype);CHKERRQ(ierr);
3051e07b27eSBarry Smith       ierr = PetscLogObjectMemory((PetscObject)pc,sizeof(PetscSubcomm));CHKERRQ(ierr);
3061e07b27eSBarry Smith     }
3071e07b27eSBarry Smith   }
3080f6f40a7SSatish Balay   subcomm = PetscSubcommChild(sred->psubcomm);
3091e07b27eSBarry Smith 
3101e07b27eSBarry Smith   /* internal KSP */
3111e07b27eSBarry Smith   if (!pc->setupcalled) {
3121e07b27eSBarry Smith     const char *prefix;
3131e07b27eSBarry Smith 
3141e07b27eSBarry Smith     if (isActiveRank(sred->psubcomm)) {
3151e07b27eSBarry Smith       ierr = KSPCreate(subcomm,&sred->ksp);CHKERRQ(ierr);
3161e07b27eSBarry Smith       ierr = KSPSetErrorIfNotConverged(sred->ksp,pc->erroriffailure);CHKERRQ(ierr);
3171e07b27eSBarry Smith       ierr = PetscObjectIncrementTabLevel((PetscObject)sred->ksp,(PetscObject)pc,1);CHKERRQ(ierr);
3181e07b27eSBarry Smith       ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)sred->ksp);CHKERRQ(ierr);
3191e07b27eSBarry Smith       ierr = KSPSetType(sred->ksp,KSPPREONLY);CHKERRQ(ierr);
3201e07b27eSBarry Smith       ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
3211e07b27eSBarry Smith       ierr = KSPSetOptionsPrefix(sred->ksp,prefix);CHKERRQ(ierr);
3221e07b27eSBarry Smith       ierr = KSPAppendOptionsPrefix(sred->ksp,"telescope_");CHKERRQ(ierr);
3231e07b27eSBarry Smith     }
3241e07b27eSBarry Smith   }
3251e07b27eSBarry Smith   /* Determine type of setup/update */
3261e07b27eSBarry Smith   if (!pc->setupcalled) {
3271e07b27eSBarry Smith     PetscBool has_dm,same;
3281e07b27eSBarry Smith     DM        dm;
3291e07b27eSBarry Smith 
3301e07b27eSBarry Smith     sr_type = TELESCOPE_DEFAULT;
3311e07b27eSBarry Smith     has_dm = PETSC_FALSE;
3321e07b27eSBarry Smith     ierr = PCGetDM(pc,&dm);CHKERRQ(ierr);
3331e07b27eSBarry Smith     if (dm) { has_dm = PETSC_TRUE; }
3341e07b27eSBarry Smith     if (has_dm) {
3351e07b27eSBarry Smith       /* check for dmda */
3361e07b27eSBarry Smith       ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&same);CHKERRQ(ierr);
3371e07b27eSBarry Smith       if (same) {
3381e07b27eSBarry Smith         ierr = PetscInfo(pc,"PCTelescope: found DMDA\n");CHKERRQ(ierr);
3391e07b27eSBarry Smith         sr_type = TELESCOPE_DMDA;
3401e07b27eSBarry Smith       }
3411e07b27eSBarry Smith       /* check for dmplex */
3421e07b27eSBarry Smith       ierr = PetscObjectTypeCompare((PetscObject)dm,DMPLEX,&same);CHKERRQ(ierr);
3431e07b27eSBarry Smith       if (same) {
3441e07b27eSBarry Smith         PetscInfo(pc,"PCTelescope: found DMPLEX\n");
3451e07b27eSBarry Smith         sr_type = TELESCOPE_DMPLEX;
3461e07b27eSBarry Smith       }
3471e07b27eSBarry Smith     }
3481e07b27eSBarry Smith 
3491e07b27eSBarry Smith     if (sred->ignore_dm) {
3501e07b27eSBarry Smith       PetscInfo(pc,"PCTelescope: ignore DM\n");
3511e07b27eSBarry Smith       sr_type = TELESCOPE_DEFAULT;
3521e07b27eSBarry Smith     }
3531e07b27eSBarry Smith     sred->sr_type = sr_type;
3541e07b27eSBarry Smith   } else {
3551e07b27eSBarry Smith     sr_type = sred->sr_type;
3561e07b27eSBarry Smith   }
3571e07b27eSBarry Smith 
3581e07b27eSBarry Smith   /* set function pointers for repartition setup, matrix creation/update, matrix nullspace and reset functionality */
3591e07b27eSBarry Smith   switch (sr_type) {
3601e07b27eSBarry Smith   case TELESCOPE_DEFAULT:
3611e07b27eSBarry Smith     sred->pctelescope_setup_type              = PCTelescopeSetUp_default;
3621e07b27eSBarry Smith     sred->pctelescope_matcreate_type          = PCTelescopeMatCreate_default;
3631e07b27eSBarry Smith     sred->pctelescope_matnullspacecreate_type = PCTelescopeMatNullSpaceCreate_default;
3641e07b27eSBarry Smith     sred->pctelescope_reset_type              = NULL;
3651e07b27eSBarry Smith     break;
3661e07b27eSBarry Smith   case TELESCOPE_DMDA:
3671e07b27eSBarry Smith     pc->ops->apply                            = PCApply_Telescope_dmda;
368f650675bSDave May     pc->ops->applyrichardson                  = PCApplyRichardson_Telescope_dmda;
3691e07b27eSBarry Smith     sred->pctelescope_setup_type              = PCTelescopeSetUp_dmda;
3701e07b27eSBarry Smith     sred->pctelescope_matcreate_type          = PCTelescopeMatCreate_dmda;
3711e07b27eSBarry Smith     sred->pctelescope_matnullspacecreate_type = PCTelescopeMatNullSpaceCreate_dmda;
3721e07b27eSBarry Smith     sred->pctelescope_reset_type              = PCReset_Telescope_dmda;
3731e07b27eSBarry Smith     break;
3741e07b27eSBarry Smith   case TELESCOPE_DMPLEX: SETERRQ(comm,PETSC_ERR_SUP,"Supprt for DMPLEX is currently not available");
3751e07b27eSBarry Smith     break;
3761e07b27eSBarry Smith   default: SETERRQ(comm,PETSC_ERR_SUP,"Only supprt for repartitioning DMDA is provided");
377*a04a6428SPatrick Sanan   default: SETERRQ(comm,PETSC_ERR_SUP,"Only support for repartitioning DMDA is provided");
3781e07b27eSBarry Smith     break;
3791e07b27eSBarry Smith   }
3801e07b27eSBarry Smith 
3811e07b27eSBarry Smith   /* setup */
3821e07b27eSBarry Smith   if (sred->pctelescope_setup_type) {
3831e07b27eSBarry Smith     ierr = sred->pctelescope_setup_type(pc,sred);CHKERRQ(ierr);
3841e07b27eSBarry Smith   }
3851e07b27eSBarry Smith   /* update */
3861e07b27eSBarry Smith   if (!pc->setupcalled) {
3871e07b27eSBarry Smith     if (sred->pctelescope_matcreate_type) {
3881e07b27eSBarry Smith       ierr = sred->pctelescope_matcreate_type(pc,sred,MAT_INITIAL_MATRIX,&sred->Bred);CHKERRQ(ierr);
3891e07b27eSBarry Smith     }
3901e07b27eSBarry Smith     if (sred->pctelescope_matnullspacecreate_type) {
3911e07b27eSBarry Smith       ierr = sred->pctelescope_matnullspacecreate_type(pc,sred,sred->Bred);CHKERRQ(ierr);
3921e07b27eSBarry Smith     }
3931e07b27eSBarry Smith   } else {
3941e07b27eSBarry Smith     if (sred->pctelescope_matcreate_type) {
3951e07b27eSBarry Smith       ierr = sred->pctelescope_matcreate_type(pc,sred,MAT_REUSE_MATRIX,&sred->Bred);CHKERRQ(ierr);
3961e07b27eSBarry Smith     }
3971e07b27eSBarry Smith   }
3981e07b27eSBarry Smith 
3991e07b27eSBarry Smith   /* common - no construction */
4001e07b27eSBarry Smith   if (isActiveRank(sred->psubcomm)) {
4011e07b27eSBarry Smith     ierr = KSPSetOperators(sred->ksp,sred->Bred,sred->Bred);CHKERRQ(ierr);
4021e07b27eSBarry Smith     if (pc->setfromoptionscalled && !pc->setupcalled){
4031e07b27eSBarry Smith       ierr = KSPSetFromOptions(sred->ksp);CHKERRQ(ierr);
4041e07b27eSBarry Smith     }
4051e07b27eSBarry Smith   }
4061e07b27eSBarry Smith   PetscFunctionReturn(0);
4071e07b27eSBarry Smith }
4081e07b27eSBarry Smith 
4091e07b27eSBarry Smith #undef __FUNCT__
4101e07b27eSBarry Smith #define __FUNCT__ "PCApply_Telescope"
4111e07b27eSBarry Smith static PetscErrorCode PCApply_Telescope(PC pc,Vec x,Vec y)
4121e07b27eSBarry Smith {
4131e07b27eSBarry Smith   PC_Telescope      sred = (PC_Telescope)pc->data;
4141e07b27eSBarry Smith   PetscErrorCode    ierr;
4151e07b27eSBarry Smith   Vec               xtmp,xred,yred;
41613c30530SDave May   PetscInt          i,st,ed;
4171e07b27eSBarry Smith   VecScatter        scatter;
4181e07b27eSBarry Smith   PetscScalar       *array;
4191e07b27eSBarry Smith   const PetscScalar *x_array;
4201e07b27eSBarry Smith 
4211e07b27eSBarry Smith   PetscFunctionBegin;
4221e07b27eSBarry Smith   xtmp    = sred->xtmp;
4231e07b27eSBarry Smith   scatter = sred->scatter;
4241e07b27eSBarry Smith   xred    = sred->xred;
4251e07b27eSBarry Smith   yred    = sred->yred;
4261e07b27eSBarry Smith 
4271e07b27eSBarry Smith   /* pull in vector x->xtmp */
4281e07b27eSBarry Smith   ierr = VecScatterBegin(scatter,x,xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
4291e07b27eSBarry Smith   ierr = VecScatterEnd(scatter,x,xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
4301e07b27eSBarry Smith 
4311e07b27eSBarry Smith   /* copy vector entires into xred */
4321e07b27eSBarry Smith   ierr = VecGetArrayRead(xtmp,&x_array);CHKERRQ(ierr);
4331e07b27eSBarry Smith   if (xred) {
4341e07b27eSBarry Smith     PetscScalar *LA_xred;
4351e07b27eSBarry Smith     ierr = VecGetOwnershipRange(xred,&st,&ed);CHKERRQ(ierr);
4361e07b27eSBarry Smith     ierr = VecGetArray(xred,&LA_xred);CHKERRQ(ierr);
4371e07b27eSBarry Smith     for (i=0; i<ed-st; i++) {
4381e07b27eSBarry Smith       LA_xred[i] = x_array[i];
4391e07b27eSBarry Smith     }
4401e07b27eSBarry Smith     ierr = VecRestoreArray(xred,&LA_xred);CHKERRQ(ierr);
4411e07b27eSBarry Smith   }
4421e07b27eSBarry Smith   ierr = VecRestoreArrayRead(xtmp,&x_array);CHKERRQ(ierr);
4431e07b27eSBarry Smith   /* solve */
4441e07b27eSBarry Smith   if (isActiveRank(sred->psubcomm)) {
4451e07b27eSBarry Smith     ierr = KSPSolve(sred->ksp,xred,yred);CHKERRQ(ierr);
4461e07b27eSBarry Smith   }
4471e07b27eSBarry Smith   /* return vector */
4481e07b27eSBarry Smith   ierr = VecGetArray(xtmp,&array);CHKERRQ(ierr);
4491e07b27eSBarry Smith   if (yred) {
4501e07b27eSBarry Smith     const PetscScalar *LA_yred;
4511e07b27eSBarry Smith     ierr = VecGetOwnershipRange(yred,&st,&ed);CHKERRQ(ierr);
4521e07b27eSBarry Smith     ierr = VecGetArrayRead(yred,&LA_yred);CHKERRQ(ierr);
4531e07b27eSBarry Smith     for (i=0; i<ed-st; i++) {
4541e07b27eSBarry Smith       array[i] = LA_yred[i];
4551e07b27eSBarry Smith     }
4561e07b27eSBarry Smith     ierr = VecRestoreArrayRead(yred,&LA_yred);CHKERRQ(ierr);
4571e07b27eSBarry Smith   }
4581e07b27eSBarry Smith   ierr = VecRestoreArray(xtmp,&array);CHKERRQ(ierr);
4591e07b27eSBarry Smith   ierr = VecScatterBegin(scatter,xtmp,y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
4601e07b27eSBarry Smith   ierr = VecScatterEnd(scatter,xtmp,y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr);
4611e07b27eSBarry Smith   PetscFunctionReturn(0);
4621e07b27eSBarry Smith }
4631e07b27eSBarry Smith 
4641e07b27eSBarry Smith #undef __FUNCT__
465f650675bSDave May #define __FUNCT__ "PCApplyRichardson_Telescope"
466f650675bSDave May static PetscErrorCode PCApplyRichardson_Telescope(PC pc,Vec x,Vec y,Vec w,PetscReal rtol,PetscReal abstol, PetscReal dtol,PetscInt its,PetscBool zeroguess,PetscInt *outits,PCRichardsonConvergedReason *reason)
467f650675bSDave May {
468f650675bSDave May   PC_Telescope      sred = (PC_Telescope)pc->data;
469f650675bSDave May   PetscErrorCode    ierr;
470a1d91a28SDave May   Vec               xtmp,yred;
471f650675bSDave May   PetscInt          i,st,ed;
472f650675bSDave May   VecScatter        scatter;
473f650675bSDave May   const PetscScalar *x_array;
474f650675bSDave May   PetscBool         default_init_guess_value;
475f650675bSDave May 
476f650675bSDave May   PetscFunctionBegin;
477f650675bSDave May   xtmp    = sred->xtmp;
478f650675bSDave May   scatter = sred->scatter;
479f650675bSDave May   yred    = sred->yred;
480f650675bSDave May 
481f650675bSDave May   if (its > 1) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCApplyRichardson_Telescope only supports max_it = 1");
482f650675bSDave May   *reason = (PCRichardsonConvergedReason)0;
483f650675bSDave May 
484f650675bSDave May   if (!zeroguess) {
485f650675bSDave May     ierr = PetscInfo(pc,"PCTelescope: Scattering y for non-zero initial guess\n");CHKERRQ(ierr);
486f650675bSDave May     /* pull in vector y->xtmp */
487f650675bSDave May     ierr = VecScatterBegin(scatter,y,xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
488f650675bSDave May     ierr = VecScatterEnd(scatter,y,xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr);
489f650675bSDave May 
490f650675bSDave May     /* copy vector entires into xred */
491f650675bSDave May     ierr = VecGetArrayRead(xtmp,&x_array);CHKERRQ(ierr);
492f650675bSDave May     if (yred) {
493f650675bSDave May       PetscScalar *LA_yred;
494f650675bSDave May       ierr = VecGetOwnershipRange(yred,&st,&ed);CHKERRQ(ierr);
495f650675bSDave May       ierr = VecGetArray(yred,&LA_yred);CHKERRQ(ierr);
496f650675bSDave May       for (i=0; i<ed-st; i++) {
497f650675bSDave May         LA_yred[i] = x_array[i];
498f650675bSDave May       }
499f650675bSDave May       ierr = VecRestoreArray(yred,&LA_yred);CHKERRQ(ierr);
500f650675bSDave May     }
501f650675bSDave May     ierr = VecRestoreArrayRead(xtmp,&x_array);CHKERRQ(ierr);
502f650675bSDave May   }
503f650675bSDave May 
504f650675bSDave May   if (isActiveRank(sred->psubcomm)) {
505f650675bSDave May     ierr = KSPGetInitialGuessNonzero(sred->ksp,&default_init_guess_value);CHKERRQ(ierr);
506f650675bSDave May     if (!zeroguess) ierr = KSPSetInitialGuessNonzero(sred->ksp,PETSC_TRUE);CHKERRQ(ierr);
507f650675bSDave May   }
508f650675bSDave May 
509f650675bSDave May   ierr = PCApply_Telescope(pc,x,y);CHKERRQ(ierr);
510f650675bSDave May 
511f650675bSDave May   if (isActiveRank(sred->psubcomm)) {
512f650675bSDave May     ierr = KSPSetInitialGuessNonzero(sred->ksp,default_init_guess_value);CHKERRQ(ierr);
513f650675bSDave May   }
514f650675bSDave May 
515f650675bSDave May   if (!*reason) *reason = PCRICHARDSON_CONVERGED_ITS;
516f650675bSDave May   *outits = 1;
517f650675bSDave May   PetscFunctionReturn(0);
518f650675bSDave May }
519f650675bSDave May 
520f650675bSDave May #undef __FUNCT__
5211e07b27eSBarry Smith #define __FUNCT__ "PCReset_Telescope"
5221e07b27eSBarry Smith static PetscErrorCode PCReset_Telescope(PC pc)
5231e07b27eSBarry Smith {
5241e07b27eSBarry Smith   PC_Telescope   sred = (PC_Telescope)pc->data;
5251e07b27eSBarry Smith   PetscErrorCode ierr;
5261e07b27eSBarry Smith 
5271e07b27eSBarry Smith   ierr = ISDestroy(&sred->isin);CHKERRQ(ierr);
5281e07b27eSBarry Smith   ierr = VecScatterDestroy(&sred->scatter);CHKERRQ(ierr);
529e3acf2f7SBarry Smith   ierr = VecDestroy(&sred->xred);CHKERRQ(ierr);
530e3acf2f7SBarry Smith   ierr = VecDestroy(&sred->yred);CHKERRQ(ierr);
531e3acf2f7SBarry Smith   ierr = VecDestroy(&sred->xtmp);CHKERRQ(ierr);
532e3acf2f7SBarry Smith   ierr = MatDestroy(&sred->Bred);CHKERRQ(ierr);
533e3acf2f7SBarry Smith   ierr = KSPReset(sred->ksp);CHKERRQ(ierr);
5341e07b27eSBarry Smith   if (sred->pctelescope_reset_type) {
5351e07b27eSBarry Smith     ierr = sred->pctelescope_reset_type(pc);CHKERRQ(ierr);
5361e07b27eSBarry Smith   }
5371e07b27eSBarry Smith   PetscFunctionReturn(0);
5381e07b27eSBarry Smith }
5391e07b27eSBarry Smith 
5401e07b27eSBarry Smith #undef __FUNCT__
5411e07b27eSBarry Smith #define __FUNCT__ "PCDestroy_Telescope"
5421e07b27eSBarry Smith static PetscErrorCode PCDestroy_Telescope(PC pc)
5431e07b27eSBarry Smith {
5441e07b27eSBarry Smith   PC_Telescope     sred = (PC_Telescope)pc->data;
5451e07b27eSBarry Smith   PetscErrorCode   ierr;
5461e07b27eSBarry Smith 
5471e07b27eSBarry Smith   PetscFunctionBegin;
5481e07b27eSBarry Smith   ierr = PCReset_Telescope(pc);CHKERRQ(ierr);
549e3acf2f7SBarry Smith   ierr = KSPDestroy(&sred->ksp);CHKERRQ(ierr);
5501e07b27eSBarry Smith   ierr = PetscSubcommDestroy(&sred->psubcomm);CHKERRQ(ierr);
551e3acf2f7SBarry Smith   ierr = PetscFree(sred->dm_ctx);CHKERRQ(ierr);
552e3acf2f7SBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
5531e07b27eSBarry Smith   PetscFunctionReturn(0);
5541e07b27eSBarry Smith }
5551e07b27eSBarry Smith 
5561e07b27eSBarry Smith #undef __FUNCT__
5571e07b27eSBarry Smith #define __FUNCT__ "PCSetFromOptions_Telescope"
5584416b707SBarry Smith static PetscErrorCode PCSetFromOptions_Telescope(PetscOptionItems *PetscOptionsObject,PC pc)
5591e07b27eSBarry Smith {
5601e07b27eSBarry Smith   PC_Telescope     sred = (PC_Telescope)pc->data;
5611e07b27eSBarry Smith   PetscErrorCode   ierr;
5621e07b27eSBarry Smith   MPI_Comm         comm;
5631e07b27eSBarry Smith   PetscMPIInt      size;
56448a10b22SPatrick Sanan   PetscBool        flg;
56548a10b22SPatrick Sanan   PetscSubcommType subcommtype;
5661e07b27eSBarry Smith 
5671e07b27eSBarry Smith   PetscFunctionBegin;
5681e07b27eSBarry Smith   ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr);
5691e07b27eSBarry Smith   ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr);
5701e07b27eSBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Telescope options");CHKERRQ(ierr);
57148a10b22SPatrick Sanan   ierr = PetscOptionsEnum("-pc_telescope_subcomm_type","Subcomm type (interlaced or contiguous)","PCTelescopeSetSubcommType",PetscSubcommTypes,(PetscEnum)sred->subcommtype,(PetscEnum*)&subcommtype,&flg);CHKERRQ(ierr);
57248a10b22SPatrick Sanan   if (flg) {
57348a10b22SPatrick Sanan     ierr = PCTelescopeSetSubcommType(pc,subcommtype);CHKERRQ(ierr);
57448a10b22SPatrick Sanan   }
5751e07b27eSBarry Smith   ierr = PetscOptionsInt("-pc_telescope_reduction_factor","Factor to reduce comm size by","PCTelescopeSetReductionFactor",sred->redfactor,&sred->redfactor,0);CHKERRQ(ierr);
5761e07b27eSBarry Smith   if (sred->redfactor > size) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"-pc_telescope_reduction_factor <= comm size");
5771e07b27eSBarry Smith   ierr = PetscOptionsBool("-pc_telescope_ignore_dm","Ignore any DM attached to the PC","PCTelescopeSetIgnoreDM",sred->ignore_dm,&sred->ignore_dm,0);CHKERRQ(ierr);
5787c5279cbSDave May   ierr = PetscOptionsBool("-pc_telescope_ignore_kspcomputeoperators","Ignore method used to compute A","PCTelescopeSetIgnoreKSPComputeOperators",sred->ignore_kspcomputeoperators,&sred->ignore_kspcomputeoperators,0);CHKERRQ(ierr);
5791e07b27eSBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
5801e07b27eSBarry Smith   PetscFunctionReturn(0);
5811e07b27eSBarry Smith }
5821e07b27eSBarry Smith 
5831e07b27eSBarry Smith /* PC simplementation specific API's */
5841e07b27eSBarry Smith 
58548a10b22SPatrick Sanan #undef __FUNCT__
58648a10b22SPatrick Sanan #define __FUNCT__ "PCTelescopeGetKSP_Telescope"
5871e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetKSP_Telescope(PC pc,KSP *ksp)
5881e07b27eSBarry Smith {
5891e07b27eSBarry Smith   PC_Telescope red = (PC_Telescope)pc->data;
590bd49479cSSatish Balay   PetscFunctionBegin;
5911e07b27eSBarry Smith   if (ksp) *ksp = red->ksp;
592bd49479cSSatish Balay   PetscFunctionReturn(0);
5931e07b27eSBarry Smith }
5941e07b27eSBarry Smith 
59548a10b22SPatrick Sanan #undef __FUNCT__
59648a10b22SPatrick Sanan #define __FUNCT__ "PCTelescopeGetSubcommType_Telescope"
59748a10b22SPatrick Sanan static PetscErrorCode PCTelescopeGetSubcommType_Telescope(PC pc,PetscSubcommType *subcommtype)
59848a10b22SPatrick Sanan {
59948a10b22SPatrick Sanan   PC_Telescope red = (PC_Telescope)pc->data;
60048a10b22SPatrick Sanan   PetscFunctionBegin;
60148a10b22SPatrick Sanan   if (subcommtype) *subcommtype = red->subcommtype;
60248a10b22SPatrick Sanan   PetscFunctionReturn(0);
60348a10b22SPatrick Sanan }
60448a10b22SPatrick Sanan 
60548a10b22SPatrick Sanan #undef __FUNCT__
60648a10b22SPatrick Sanan #define __FUNCT__ "PCTelescopeSetSubcommType_Telescope"
60748a10b22SPatrick Sanan static PetscErrorCode PCTelescopeSetSubcommType_Telescope(PC pc,PetscSubcommType subcommtype)
60848a10b22SPatrick Sanan {
60948a10b22SPatrick Sanan   PC_Telescope     red = (PC_Telescope)pc->data;
61048a10b22SPatrick Sanan 
61148a10b22SPatrick Sanan   PetscFunctionBegin;
61248a10b22SPatrick Sanan   if (pc->setupcalled) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"You cannot change the subcommunicator type for PCTelescope after it has been set up.");
61348a10b22SPatrick Sanan   red->subcommtype = subcommtype;
61448a10b22SPatrick Sanan   PetscFunctionReturn(0);
61548a10b22SPatrick Sanan }
61648a10b22SPatrick Sanan 
61748a10b22SPatrick Sanan #undef __FUNCT__
61848a10b22SPatrick Sanan #define __FUNCT__ "PCTelescopeGetReductionFactor_Telescope"
6191e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetReductionFactor_Telescope(PC pc,PetscInt *fact)
6201e07b27eSBarry Smith {
6211e07b27eSBarry Smith   PC_Telescope red = (PC_Telescope)pc->data;
622bd49479cSSatish Balay   PetscFunctionBegin;
6231e07b27eSBarry Smith   if (fact) *fact = red->redfactor;
624bd49479cSSatish Balay   PetscFunctionReturn(0);
6251e07b27eSBarry Smith }
6261e07b27eSBarry Smith 
62748a10b22SPatrick Sanan #undef __FUNCT__
62848a10b22SPatrick Sanan #define __FUNCT__ "PCTelescopeSetReductionFactor_Telescope"
6291e07b27eSBarry Smith static PetscErrorCode PCTelescopeSetReductionFactor_Telescope(PC pc,PetscInt fact)
6301e07b27eSBarry Smith {
6311e07b27eSBarry Smith   PC_Telescope     red = (PC_Telescope)pc->data;
6321e07b27eSBarry Smith   PetscMPIInt      size;
6331e07b27eSBarry Smith   PetscErrorCode   ierr;
6341e07b27eSBarry Smith 
635bd49479cSSatish Balay   PetscFunctionBegin;
6361e07b27eSBarry Smith   ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr);
6371e07b27eSBarry Smith   if (fact <= 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Reduction factor of telescoping PC %D must be positive",fact);
6381e07b27eSBarry Smith   if (fact > size) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Reduction factor of telescoping PC %D must be <= comm.size",fact);
6391e07b27eSBarry Smith   red->redfactor = fact;
640bd49479cSSatish Balay   PetscFunctionReturn(0);
6411e07b27eSBarry Smith }
6421e07b27eSBarry Smith 
64348a10b22SPatrick Sanan #undef __FUNCT__
64448a10b22SPatrick Sanan #define __FUNCT__ "PCTelescopeGetIgnoreDM_Telescope"
6451e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetIgnoreDM_Telescope(PC pc,PetscBool *v)
6461e07b27eSBarry Smith {
6471e07b27eSBarry Smith   PC_Telescope red = (PC_Telescope)pc->data;
648bd49479cSSatish Balay   PetscFunctionBegin;
6491e07b27eSBarry Smith   if (v) *v = red->ignore_dm;
650bd49479cSSatish Balay   PetscFunctionReturn(0);
6511e07b27eSBarry Smith }
65248a10b22SPatrick Sanan 
65348a10b22SPatrick Sanan #undef __FUNCT__
65448a10b22SPatrick Sanan #define __FUNCT__ "PCTelescopeSetIgnoreDM_Telescope"
6551e07b27eSBarry Smith static PetscErrorCode PCTelescopeSetIgnoreDM_Telescope(PC pc,PetscBool v)
6561e07b27eSBarry Smith {
6571e07b27eSBarry Smith   PC_Telescope red = (PC_Telescope)pc->data;
658bd49479cSSatish Balay   PetscFunctionBegin;
6591e07b27eSBarry Smith   red->ignore_dm = v;
660bd49479cSSatish Balay   PetscFunctionReturn(0);
6611e07b27eSBarry Smith }
6621e07b27eSBarry Smith 
66348a10b22SPatrick Sanan #undef __FUNCT__
66448a10b22SPatrick Sanan #define __FUNCT__ "PCTelescopeGetIgnoreKSPComputeOperators_Telescope"
6650ae7c45bSDave May static PetscErrorCode PCTelescopeGetIgnoreKSPComputeOperators_Telescope(PC pc,PetscBool *v)
6660ae7c45bSDave May {
6670ae7c45bSDave May   PC_Telescope red = (PC_Telescope)pc->data;
6680ae7c45bSDave May   PetscFunctionBegin;
6690ae7c45bSDave May   if (v) *v = red->ignore_kspcomputeoperators;
6700ae7c45bSDave May   PetscFunctionReturn(0);
6710ae7c45bSDave May }
67248a10b22SPatrick Sanan 
67348a10b22SPatrick Sanan #undef __FUNCT__
67448a10b22SPatrick Sanan #define __FUNCT__ "PCTelescopeSetIgnoreKSPComputeOperators_Telescope"
6750ae7c45bSDave May static PetscErrorCode PCTelescopeSetIgnoreKSPComputeOperators_Telescope(PC pc,PetscBool v)
6760ae7c45bSDave May {
6770ae7c45bSDave May   PC_Telescope red = (PC_Telescope)pc->data;
6780ae7c45bSDave May   PetscFunctionBegin;
6790ae7c45bSDave May   red->ignore_kspcomputeoperators = v;
6800ae7c45bSDave May   PetscFunctionReturn(0);
6810ae7c45bSDave May }
6820ae7c45bSDave May 
68348a10b22SPatrick Sanan #undef __FUNCT__
68448a10b22SPatrick Sanan #define __FUNCT__ "PCTelescopeGetDM_Telescope"
6851e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetDM_Telescope(PC pc,DM *dm)
6861e07b27eSBarry Smith {
6871e07b27eSBarry Smith   PC_Telescope red = (PC_Telescope)pc->data;
688bd49479cSSatish Balay   PetscFunctionBegin;
6891e07b27eSBarry Smith   *dm = private_PCTelescopeGetSubDM(red);
690bd49479cSSatish Balay   PetscFunctionReturn(0);
6911e07b27eSBarry Smith }
6921e07b27eSBarry Smith 
6930f43ea10SBarry Smith #undef __FUNCT__
6940f43ea10SBarry Smith #define __FUNCT__ "PCTelescopeGetKSP"
6951e07b27eSBarry Smith /*@
6961e07b27eSBarry Smith  PCTelescopeGetKSP - Gets the KSP created by the telescoping PC.
6971e07b27eSBarry Smith 
6981e07b27eSBarry Smith  Not Collective
6991e07b27eSBarry Smith 
7001e07b27eSBarry Smith  Input Parameter:
7011e07b27eSBarry Smith .  pc - the preconditioner context
7021e07b27eSBarry Smith 
7031e07b27eSBarry Smith  Output Parameter:
7041e07b27eSBarry Smith .  subksp - the KSP defined the smaller set of processes
7051e07b27eSBarry Smith 
7061e07b27eSBarry Smith  Level: advanced
7071e07b27eSBarry Smith 
7081e07b27eSBarry Smith .keywords: PC, telescopting solve
7091e07b27eSBarry Smith @*/
7101e07b27eSBarry Smith PetscErrorCode PCTelescopeGetKSP(PC pc,KSP *subksp)
7111e07b27eSBarry Smith {
712bd49479cSSatish Balay   PetscErrorCode ierr;
713bd49479cSSatish Balay   PetscFunctionBegin;
714163d334eSBarry Smith   ierr = PetscUseMethod(pc,"PCTelescopeGetKSP_C",(PC,KSP*),(pc,subksp));CHKERRQ(ierr);
715bd49479cSSatish Balay   PetscFunctionReturn(0);
7161e07b27eSBarry Smith }
7171e07b27eSBarry Smith 
7180f43ea10SBarry Smith #undef __FUNCT__
7190f43ea10SBarry Smith #define __FUNCT__ "PCTelescopeGetReductionFactor"
7201e07b27eSBarry Smith /*@
7211e07b27eSBarry Smith  PCTelescopeGetReductionFactor - Gets the factor by which the original number of processes has been reduced by.
7221e07b27eSBarry Smith 
7231e07b27eSBarry Smith  Not Collective
7241e07b27eSBarry Smith 
7251e07b27eSBarry Smith  Input Parameter:
7261e07b27eSBarry Smith .  pc - the preconditioner context
7271e07b27eSBarry Smith 
7281e07b27eSBarry Smith  Output Parameter:
7291e07b27eSBarry Smith .  fact - the reduction factor
7301e07b27eSBarry Smith 
7311e07b27eSBarry Smith  Level: advanced
7321e07b27eSBarry Smith 
7331e07b27eSBarry Smith .keywords: PC, telescoping solve
7341e07b27eSBarry Smith @*/
7351e07b27eSBarry Smith PetscErrorCode PCTelescopeGetReductionFactor(PC pc,PetscInt *fact)
7361e07b27eSBarry Smith {
737bd49479cSSatish Balay   PetscErrorCode ierr;
738bd49479cSSatish Balay   PetscFunctionBegin;
739163d334eSBarry Smith   ierr = PetscUseMethod(pc,"PCTelescopeGetReductionFactor_C",(PC,PetscInt*),(pc,fact));CHKERRQ(ierr);
740bd49479cSSatish Balay   PetscFunctionReturn(0);
7411e07b27eSBarry Smith }
7421e07b27eSBarry Smith 
7430f43ea10SBarry Smith #undef __FUNCT__
7440f43ea10SBarry Smith #define __FUNCT__ "PCTelescopeSetReductionFactor"
7451e07b27eSBarry Smith /*@
7461e07b27eSBarry Smith  PCTelescopeSetReductionFactor - Sets the factor by which the original number of processes has been reduced by.
7471e07b27eSBarry Smith 
7481e07b27eSBarry Smith  Not Collective
7491e07b27eSBarry Smith 
7501e07b27eSBarry Smith  Input Parameter:
7511e07b27eSBarry Smith .  pc - the preconditioner context
7521e07b27eSBarry Smith 
7531e07b27eSBarry Smith  Output Parameter:
7541e07b27eSBarry Smith .  fact - the reduction factor
7551e07b27eSBarry Smith 
7561e07b27eSBarry Smith  Level: advanced
7571e07b27eSBarry Smith 
7581e07b27eSBarry Smith .keywords: PC, telescoping solve
7591e07b27eSBarry Smith @*/
7601e07b27eSBarry Smith PetscErrorCode PCTelescopeSetReductionFactor(PC pc,PetscInt fact)
7611e07b27eSBarry Smith {
762bd49479cSSatish Balay   PetscErrorCode ierr;
763bd49479cSSatish Balay   PetscFunctionBegin;
764bd49479cSSatish Balay   ierr = PetscTryMethod(pc,"PCTelescopeSetReductionFactor_C",(PC,PetscInt),(pc,fact));CHKERRQ(ierr);
765bd49479cSSatish Balay   PetscFunctionReturn(0);
7661e07b27eSBarry Smith }
7671e07b27eSBarry Smith 
7680f43ea10SBarry Smith #undef __FUNCT__
7690f43ea10SBarry Smith #define __FUNCT__ "PCTelescopeGetIgnoreDM"
7701e07b27eSBarry Smith /*@
7711e07b27eSBarry Smith  PCTelescopeGetIgnoreDM - Get the flag indicating if any DM attached to the PC will be used.
7721e07b27eSBarry Smith 
7731e07b27eSBarry Smith  Not Collective
7741e07b27eSBarry Smith 
7751e07b27eSBarry Smith  Input Parameter:
7761e07b27eSBarry Smith .  pc - the preconditioner context
7771e07b27eSBarry Smith 
7781e07b27eSBarry Smith  Output Parameter:
7791e07b27eSBarry Smith .  v - the flag
7801e07b27eSBarry Smith 
7811e07b27eSBarry Smith  Level: advanced
7821e07b27eSBarry Smith 
7831e07b27eSBarry Smith .keywords: PC, telescoping solve
7841e07b27eSBarry Smith @*/
7851e07b27eSBarry Smith PetscErrorCode PCTelescopeGetIgnoreDM(PC pc,PetscBool *v)
7861e07b27eSBarry Smith {
787bd49479cSSatish Balay   PetscErrorCode ierr;
788bd49479cSSatish Balay   PetscFunctionBegin;
789163d334eSBarry Smith   ierr = PetscUseMethod(pc,"PCTelescopeGetIgnoreDM_C",(PC,PetscBool*),(pc,v));CHKERRQ(ierr);
790bd49479cSSatish Balay   PetscFunctionReturn(0);
7911e07b27eSBarry Smith }
7921e07b27eSBarry Smith 
7930f43ea10SBarry Smith #undef __FUNCT__
7940f43ea10SBarry Smith #define __FUNCT__ "PCTelescopeSetIgnoreDM"
7951e07b27eSBarry Smith /*@
7961e07b27eSBarry Smith  PCTelescopeSetIgnoreDM - Set a flag to ignore any DM attached to the PC.
7971e07b27eSBarry Smith 
7981e07b27eSBarry Smith  Not Collective
7991e07b27eSBarry Smith 
8001e07b27eSBarry Smith  Input Parameter:
8011e07b27eSBarry Smith .  pc - the preconditioner context
8021e07b27eSBarry Smith 
8031e07b27eSBarry Smith  Output Parameter:
8041e07b27eSBarry Smith .  v - Use PETSC_TRUE to ignore any DM
8051e07b27eSBarry Smith 
8061e07b27eSBarry Smith  Level: advanced
8071e07b27eSBarry Smith 
8081e07b27eSBarry Smith .keywords: PC, telescoping solve
8091e07b27eSBarry Smith @*/
810bfd6bcc6SSatish Balay PetscErrorCode PCTelescopeSetIgnoreDM(PC pc,PetscBool v)
8111e07b27eSBarry Smith {
812bd49479cSSatish Balay   PetscErrorCode ierr;
813bd49479cSSatish Balay   PetscFunctionBegin;
814bd49479cSSatish Balay   ierr = PetscTryMethod(pc,"PCTelescopeSetIgnoreDM_C",(PC,PetscBool),(pc,v));CHKERRQ(ierr);
815bd49479cSSatish Balay   PetscFunctionReturn(0);
8161e07b27eSBarry Smith }
8171e07b27eSBarry Smith 
8180f43ea10SBarry Smith #undef __FUNCT__
8190f43ea10SBarry Smith #define __FUNCT__ "PCTelescopeGetIgnoreKSPComputeOperators"
8201e07b27eSBarry Smith /*@
8210ae7c45bSDave May  PCTelescopeGetIgnoreKSPComputeOperators - Get the flag indicating if KSPComputeOperators will be used.
8220ae7c45bSDave May 
8230ae7c45bSDave May  Not Collective
8240ae7c45bSDave May 
8250ae7c45bSDave May  Input Parameter:
8260ae7c45bSDave May .  pc - the preconditioner context
8270ae7c45bSDave May 
8280ae7c45bSDave May  Output Parameter:
8290ae7c45bSDave May .  v - the flag
8300ae7c45bSDave May 
8310ae7c45bSDave May  Level: advanced
8320ae7c45bSDave May 
8330ae7c45bSDave May .keywords: PC, telescoping solve
8340ae7c45bSDave May @*/
8350ae7c45bSDave May PetscErrorCode PCTelescopeGetIgnoreKSPComputeOperators(PC pc,PetscBool *v)
8360ae7c45bSDave May {
8370ae7c45bSDave May   PetscErrorCode ierr;
8380ae7c45bSDave May   PetscFunctionBegin;
839163d334eSBarry Smith   ierr = PetscUseMethod(pc,"PCTelescopeGetIgnoreKSPComputeOperators_C",(PC,PetscBool*),(pc,v));CHKERRQ(ierr);
8400ae7c45bSDave May   PetscFunctionReturn(0);
8410ae7c45bSDave May }
8420ae7c45bSDave May 
8430f43ea10SBarry Smith #undef __FUNCT__
8440f43ea10SBarry Smith #define __FUNCT__ "PCTelescopeSetIgnoreKSPComputeOperators"
8450ae7c45bSDave May /*@
8460ae7c45bSDave May  PCTelescopeSetIgnoreKSPComputeOperators - Set a flag to ignore KSPComputeOperators.
8470ae7c45bSDave May 
8480ae7c45bSDave May  Not Collective
8490ae7c45bSDave May 
8500ae7c45bSDave May  Input Parameter:
8510ae7c45bSDave May .  pc - the preconditioner context
8520ae7c45bSDave May 
8530ae7c45bSDave May  Output Parameter:
854a954d8f4SDave May .  v - Use PETSC_TRUE to ignore the method (if defined) set via KSPSetComputeOperators on pc
8550ae7c45bSDave May 
8560ae7c45bSDave May  Level: advanced
8570ae7c45bSDave May 
8580ae7c45bSDave May .keywords: PC, telescoping solve
8590ae7c45bSDave May @*/
8600ae7c45bSDave May PetscErrorCode PCTelescopeSetIgnoreKSPComputeOperators(PC pc,PetscBool v)
8610ae7c45bSDave May {
8620ae7c45bSDave May   PetscErrorCode ierr;
8630ae7c45bSDave May   PetscFunctionBegin;
8640ae7c45bSDave May   ierr = PetscTryMethod(pc,"PCTelescopeSetIgnoreKSPComputeOperators_C",(PC,PetscBool),(pc,v));CHKERRQ(ierr);
8650ae7c45bSDave May   PetscFunctionReturn(0);
8660ae7c45bSDave May }
8670ae7c45bSDave May 
8680f43ea10SBarry Smith #undef __FUNCT__
8690f43ea10SBarry Smith #define __FUNCT__ "PCTelescopeGetDM"
8700ae7c45bSDave May /*@
8711e07b27eSBarry Smith  PCTelescopeGetDM - Get the re-partitioned DM attached to the sub KSP.
8721e07b27eSBarry Smith 
8731e07b27eSBarry Smith  Not Collective
8741e07b27eSBarry Smith 
8751e07b27eSBarry Smith  Input Parameter:
8761e07b27eSBarry Smith .  pc - the preconditioner context
8771e07b27eSBarry Smith 
8781e07b27eSBarry Smith  Output Parameter:
8791e07b27eSBarry Smith .  subdm - The re-partitioned DM
8801e07b27eSBarry Smith 
8811e07b27eSBarry Smith  Level: advanced
8821e07b27eSBarry Smith 
8831e07b27eSBarry Smith .keywords: PC, telescoping solve
8841e07b27eSBarry Smith @*/
8851e07b27eSBarry Smith PetscErrorCode PCTelescopeGetDM(PC pc,DM *subdm)
8861e07b27eSBarry Smith {
887bd49479cSSatish Balay   PetscErrorCode ierr;
888bd49479cSSatish Balay   PetscFunctionBegin;
889163d334eSBarry Smith   ierr = PetscUseMethod(pc,"PCTelescopeGetDM_C",(PC,DM*),(pc,subdm));CHKERRQ(ierr);
890bd49479cSSatish Balay   PetscFunctionReturn(0);
8911e07b27eSBarry Smith }
8921e07b27eSBarry Smith 
8930f43ea10SBarry Smith #undef __FUNCT__
8940f43ea10SBarry Smith #define __FUNCT__ "PCTelescopeSetSubcommType"
89548a10b22SPatrick Sanan /*@
89648a10b22SPatrick Sanan  PCTelescopeSetSubcommType - set subcommunicator type (interlaced or contiguous)
89748a10b22SPatrick Sanan 
89848a10b22SPatrick Sanan  Logically Collective
89948a10b22SPatrick Sanan 
90048a10b22SPatrick Sanan  Input Parameter:
9011dae98e4SBarry Smith +  pc - the preconditioner context
9021dae98e4SBarry Smith -  subcommtype - the subcommunicator type (see PetscSubcommType)
90348a10b22SPatrick Sanan 
90448a10b22SPatrick Sanan  Level: advanced
90548a10b22SPatrick Sanan 
90648a10b22SPatrick Sanan .keywords: PC, telescoping solve
90748a10b22SPatrick Sanan 
90848a10b22SPatrick Sanan .seealso: PetscSubcommType, PetscSubcomm, PCTELESCOPE
90948a10b22SPatrick Sanan @*/
91048a10b22SPatrick Sanan PetscErrorCode PCTelescopeSetSubcommType(PC pc, PetscSubcommType subcommtype)
91148a10b22SPatrick Sanan {
91248a10b22SPatrick Sanan   PetscErrorCode ierr;
91348a10b22SPatrick Sanan   PetscFunctionBegin;
91448a10b22SPatrick Sanan   ierr = PetscTryMethod(pc,"PCTelescopeSetSubcommType_C",(PC,PetscSubcommType),(pc,subcommtype));CHKERRQ(ierr);
91548a10b22SPatrick Sanan   PetscFunctionReturn(0);
91648a10b22SPatrick Sanan }
91748a10b22SPatrick Sanan 
9180f43ea10SBarry Smith #undef __FUNCT__
9191dae98e4SBarry Smith #define __FUNCT__ "PCTelescopeGetSubcommType"
92048a10b22SPatrick Sanan /*@
92148a10b22SPatrick Sanan  PCTelescopeGetSubcommType - Get the subcommunicator type (interlaced or contiguous)
92248a10b22SPatrick Sanan 
92348a10b22SPatrick Sanan  Not Collective
92448a10b22SPatrick Sanan 
92548a10b22SPatrick Sanan  Input Parameter:
92648a10b22SPatrick Sanan .  pc - the preconditioner context
92748a10b22SPatrick Sanan 
92848a10b22SPatrick Sanan  Output Parameter:
92948a10b22SPatrick Sanan .  subcommtype - the subcommunicator type (see PetscSubcommType)
93048a10b22SPatrick Sanan 
93148a10b22SPatrick Sanan  Level: advanced
93248a10b22SPatrick Sanan 
93348a10b22SPatrick Sanan .keywords: PC, telescoping solve
93448a10b22SPatrick Sanan 
9351dae98e4SBarry Smith .seealso: PetscSubcomm, PetscSubcommType, PCTELESCOPE
93648a10b22SPatrick Sanan @*/
9371dae98e4SBarry Smith PetscErrorCode PCTelescopeGetSubcommType(PC pc, PetscSubcommType *subcommtype)
93848a10b22SPatrick Sanan {
93948a10b22SPatrick Sanan   PetscErrorCode ierr;
94048a10b22SPatrick Sanan   PetscFunctionBegin;
94148a10b22SPatrick Sanan   ierr = PetscUseMethod(pc,"PCTelescopeGetSubcommType_C",(PC,PetscSubcommType*),(pc,subcommtype));CHKERRQ(ierr);
94248a10b22SPatrick Sanan   PetscFunctionReturn(0);
94348a10b22SPatrick Sanan }
94448a10b22SPatrick Sanan 
9451e07b27eSBarry Smith /* -------------------------------------------------------------------------------------*/
9461e07b27eSBarry Smith /*MC
9471e07b27eSBarry Smith    PCTELESCOPE - Runs a KSP solver on a sub-group of processors. MPI processes not in the sub-communicator are idle during the solve.
9481e07b27eSBarry Smith 
9491e07b27eSBarry Smith    Options Database:
950*a04a6428SPatrick Sanan +  -pc_telescope_reduction_factor <r> - factor to use communicator size by. e.g. with 64 MPI processes and r=4, the new sub-communicator will have 64/4 = 16 ranks.
951*a04a6428SPatrick Sanan -  -pc_telescope_ignore_dm  - flag to indicate whether an attached DM should be ignored
952*a04a6428SPatrick Sanan -  -pc_telescope_subcomm_type <interlaced,contiguous> - how to define the reduced communicator. see PetscSubcomm for more.
9531e07b27eSBarry Smith 
9541e07b27eSBarry Smith    Level: advanced
9551e07b27eSBarry Smith 
9561e07b27eSBarry Smith    Notes:
9576fc41876SBarry Smith    The preconditioner is deemed telescopic as it only calls KSPSolve() on a single
9586fc41876SBarry Smith    sub-communicator in contrast with PCREDUNDANT which calls KSPSolve() on N sub-communicators.
959*a04a6428SPatrick Sanan    This means there will be MPI processes within c which will be idle during the application of this preconditioner.
9606fc41876SBarry Smith 
9611e07b27eSBarry Smith    The default KSP is PREONLY. If a DM is attached to the PC, it is re-partitioned on the sub-communicator.
9621e07b27eSBarry Smith    Both the B mat operator and the right hand side vector are permuted into the new DOF ordering defined by the re-partitioned DM.
9631e07b27eSBarry Smith    Currently only support for re-partitioning a DMDA is provided.
9641e07b27eSBarry Smith    Any nullspace attached to the original Bmat operator are extracted, re-partitioned and set on the repartitioned Bmat operator.
9651e07b27eSBarry Smith    KSPSetComputeOperators() is not propagated to the sub KSP.
9661e07b27eSBarry Smith    Currently there is no support for the flag -pc_use_amat
9671e07b27eSBarry Smith 
9686fc41876SBarry Smith    Assuming that the parent preconditioner (PC) is defined on a communicator c, this implementation
9696fc41876SBarry Smith    creates a child sub-communicator (c') containing less MPI processes than the original parent preconditioner (PC).
9706fc41876SBarry Smith 
9716fc41876SBarry Smith   Developer Notes:
9726fc41876SBarry Smith    During PCSetup, the B operator is scattered onto c'.
9736fc41876SBarry Smith    Within PCApply, the RHS vector (x) is scattered into a redundant vector, xred (defined on c').
9746fc41876SBarry Smith    Then KSPSolve() is executed on the c' communicator.
9756fc41876SBarry Smith 
9766fc41876SBarry Smith    The communicator used within the telescoping preconditioner is defined by a PetscSubcomm using the INTERLACED
977*a04a6428SPatrick Sanan    creation routine by default (this can be changed with -pc_telescope_subcomm_type). We run the sub KSP on only the ranks within the communicator which have a color equal to zero.
9786fc41876SBarry Smith 
9796fc41876SBarry Smith    The telescoping preconditioner is aware of nullspaces which are attached to the only B operator.
9806fc41876SBarry Smith    In case where B has a n nullspace attached, these nullspaces vectors are extract from B and mapped into
9816fc41876SBarry Smith    a new nullspace (defined on the sub-communicator) which is attached to B' (the B operator which was scattered to c')
9826fc41876SBarry Smith 
9836fc41876SBarry Smith    The telescoping preconditioner is aware of an attached DM. In the event that the DM is of type DMDA (2D or 3D -
9846fc41876SBarry Smith    1D support for 1D DMDAs is not provided), a new DMDA is created on c' (e.g. it is re-partitioned), and this new DM
9856fc41876SBarry Smith    is attached the sub KSPSolve(). The design of telescope is such that it should be possible to extend support
9866fc41876SBarry Smith    for re-partitioning other DM's (e.g. DMPLEX). The user can supply a flag to ignore attached DMs.
9876fc41876SBarry Smith 
9886fc41876SBarry Smith    By default, B' is defined by simply fusing rows from different MPI processes
9896fc41876SBarry Smith 
9906fc41876SBarry Smith    When a DMDA is attached to the parent preconditioner, B' is defined by: (i) performing a symmetric permuting of B
9916fc41876SBarry Smith    into the ordering defined by the DMDA on c', (ii) extracting the local chunks via MatGetSubMatrices(), (iii) fusing the
9926fc41876SBarry Smith    locally (sequential) matrices defined on the ranks common to c and c' into B' using MatCreateMPIMatConcatenateSeqMat()
9936fc41876SBarry Smith 
9946fc41876SBarry Smith    Limitations/improvements
9956fc41876SBarry Smith    VecPlaceArray could be used within PCApply() to improve efficiency and reduce memory usage.
9966fc41876SBarry Smith 
9976fc41876SBarry Smith    The symmetric permutation used when a DMDA is encountered is performed via explicitly assmbleming a permutation matrix P,
9986fc41876SBarry Smith    and performing P^T.A.P. Possibly it might be more efficient to use MatPermute(). I opted to use P^T.A.P as it appears
9996fc41876SBarry Smith    VecPermute() does not supported for the use case required here. By computing P, I can permute both the operator and RHS in a
10006fc41876SBarry Smith    consistent manner.
10016fc41876SBarry Smith 
10026fc41876SBarry Smith    Mapping of vectors is performed this way
10036fc41876SBarry Smith    Suppose the parent comm size was 4, and we set a reduction factor of 2, thus would give a comm size on c' of 2.
10046fc41876SBarry Smith    Using the interlaced creation routine, the ranks in c with color = 0, will be rank 0 and 2.
10056fc41876SBarry Smith    We perform the scatter to the sub-comm in the following way,
10066fc41876SBarry Smith    [1] Given a vector x defined on comm c
10076fc41876SBarry Smith 
10086fc41876SBarry Smith    rank(c) : _________ 0 ______  ________ 1 _______  ________ 2 _____________ ___________ 3 __________
10096fc41876SBarry Smith          x : [0, 1, 2, 3, 4, 5] [6, 7, 8, 9, 10, 11] [12, 13, 14, 15, 16, 17] [18, 19, 20, 21, 22, 23]
10106fc41876SBarry Smith 
10116fc41876SBarry Smith    scatter to xtmp defined also on comm c so that we have the following values
10126fc41876SBarry Smith 
10136fc41876SBarry Smith    rank(c) : ___________________ 0 ________________  _1_  ______________________ 2 _______________________  __3_
10146fc41876SBarry Smith       xtmp : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] [  ] [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23] [  ]
10156fc41876SBarry Smith 
10166fc41876SBarry Smith    The entries on rank 1 and 3 (ranks which do not have a color = 0 in c') have no values
10176fc41876SBarry Smith 
10186fc41876SBarry Smith 
10196fc41876SBarry Smith    [2] Copy the value from rank 0, 2 (indices with respect to comm c) into the vector xred which is defined on communicator c'.
10206fc41876SBarry Smith    Ranks 0 and 2 are the only ranks in the subcomm which have a color = 0.
10216fc41876SBarry Smith 
10226fc41876SBarry Smith     rank(c') : ___________________ 0 _______________  ______________________ 1 _____________________
10236fc41876SBarry Smith       xred : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] [12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23]
10246fc41876SBarry Smith 
10251e07b27eSBarry Smith 
10261e07b27eSBarry Smith   Contributed by Dave May
10271e07b27eSBarry Smith 
10286fc41876SBarry Smith .seealso:  PCTelescopeGetKSP(), PCTelescopeGetDM(), PCTelescopeGetReductionFactor(), PCTelescopeSetReductionFactor(), PCTelescopeGetIgnoreDM(), PCTelescopeSetIgnoreDM(), PCREDUNDANT
10291e07b27eSBarry Smith M*/
10301e07b27eSBarry Smith #undef __FUNCT__
10311e07b27eSBarry Smith #define __FUNCT__ "PCCreate_Telescope"
10321e07b27eSBarry Smith PETSC_EXTERN PetscErrorCode PCCreate_Telescope(PC pc)
10331e07b27eSBarry Smith {
10341e07b27eSBarry Smith   PetscErrorCode       ierr;
10351e07b27eSBarry Smith   struct _PC_Telescope *sred;
10361e07b27eSBarry Smith 
10371e07b27eSBarry Smith   PetscFunctionBegin;
10381e07b27eSBarry Smith   ierr = PetscNewLog(pc,&sred);CHKERRQ(ierr);
103948a10b22SPatrick Sanan   sred->subcommtype    = PETSC_SUBCOMM_INTERLACED;
10401e07b27eSBarry Smith   sred->redfactor      = 1;
10411e07b27eSBarry Smith   sred->ignore_dm      = PETSC_FALSE;
10427c5279cbSDave May   sred->ignore_kspcomputeoperators = PETSC_FALSE;
10431e07b27eSBarry Smith   pc->data             = (void*)sred;
10441e07b27eSBarry Smith 
10451e07b27eSBarry Smith   pc->ops->apply           = PCApply_Telescope;
10461e07b27eSBarry Smith   pc->ops->applytranspose  = NULL;
1047f650675bSDave May   pc->ops->applyrichardson = PCApplyRichardson_Telescope;
10481e07b27eSBarry Smith   pc->ops->setup           = PCSetUp_Telescope;
10491e07b27eSBarry Smith   pc->ops->destroy         = PCDestroy_Telescope;
10501e07b27eSBarry Smith   pc->ops->reset           = PCReset_Telescope;
10511e07b27eSBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_Telescope;
10521e07b27eSBarry Smith   pc->ops->view            = PCView_Telescope;
10531e07b27eSBarry Smith 
10541e07b27eSBarry Smith   sred->pctelescope_setup_type              = PCTelescopeSetUp_default;
10551e07b27eSBarry Smith   sred->pctelescope_matcreate_type          = PCTelescopeMatCreate_default;
10561e07b27eSBarry Smith   sred->pctelescope_matnullspacecreate_type = PCTelescopeMatNullSpaceCreate_default;
10571e07b27eSBarry Smith   sred->pctelescope_reset_type              = NULL;
10581e07b27eSBarry Smith 
10591e07b27eSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetKSP_C",PCTelescopeGetKSP_Telescope);CHKERRQ(ierr);
106048a10b22SPatrick Sanan   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetSubcommType_C",PCTelescopeGetSubcommType_Telescope);CHKERRQ(ierr);
106148a10b22SPatrick Sanan   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeSetSubcommType_C",PCTelescopeSetSubcommType_Telescope);CHKERRQ(ierr);
10621e07b27eSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetReductionFactor_C",PCTelescopeGetReductionFactor_Telescope);CHKERRQ(ierr);
10631e07b27eSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeSetReductionFactor_C",PCTelescopeSetReductionFactor_Telescope);CHKERRQ(ierr);
10641e07b27eSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetIgnoreDM_C",PCTelescopeGetIgnoreDM_Telescope);CHKERRQ(ierr);
10651e07b27eSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeSetIgnoreDM_C",PCTelescopeSetIgnoreDM_Telescope);CHKERRQ(ierr);
10660ae7c45bSDave May   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetIgnoreKSPComputeOperators_C",PCTelescopeGetIgnoreKSPComputeOperators_Telescope);CHKERRQ(ierr);
10670ae7c45bSDave May   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeSetIgnoreKSPComputeOperators_C",PCTelescopeSetIgnoreKSPComputeOperators_Telescope);CHKERRQ(ierr);
10681e07b27eSBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetDM_C",PCTelescopeGetDM_Telescope);CHKERRQ(ierr);
10691e07b27eSBarry Smith   PetscFunctionReturn(0);
10701e07b27eSBarry Smith }
1071