11e07b27eSBarry Smith 21e07b27eSBarry Smith 31e07b27eSBarry Smith 46fc41876SBarry Smith #include <petsc/private/pcimpl.h> 51e07b27eSBarry Smith #include <petscksp.h> /*I "petscksp.h" I*/ 61e07b27eSBarry Smith #include <petscdm.h> /*I "petscdm.h" I*/ 71e07b27eSBarry Smith 81e07b27eSBarry Smith #include "telescope.h" 91e07b27eSBarry Smith 101e07b27eSBarry Smith /* 111e07b27eSBarry Smith PCTelescopeSetUp_default() 121e07b27eSBarry Smith PCTelescopeMatCreate_default() 131e07b27eSBarry Smith 141e07b27eSBarry Smith default 151e07b27eSBarry Smith 161e07b27eSBarry Smith // scatter in 171e07b27eSBarry Smith x(comm) -> xtmp(comm) 181e07b27eSBarry Smith 191e07b27eSBarry Smith xred(subcomm) <- xtmp 201e07b27eSBarry Smith yred(subcomm) 211e07b27eSBarry Smith 221e07b27eSBarry Smith yred(subcomm) --> xtmp 231e07b27eSBarry Smith 241e07b27eSBarry Smith // scatter out 251e07b27eSBarry Smith xtmp(comm) -> y(comm) 261e07b27eSBarry Smith */ 271e07b27eSBarry Smith 281e07b27eSBarry Smith PetscBool isActiveRank(PetscSubcomm scomm) 291e07b27eSBarry Smith { 301e07b27eSBarry Smith if (scomm->color == 0) { return PETSC_TRUE; } 311e07b27eSBarry Smith else { return PETSC_FALSE; } 321e07b27eSBarry Smith } 331e07b27eSBarry Smith 341e07b27eSBarry Smith #undef __FUNCT__ 351e07b27eSBarry Smith #define __FUNCT__ "private_PCTelescopeGetSubDM" 361e07b27eSBarry Smith DM private_PCTelescopeGetSubDM(PC_Telescope sred) 371e07b27eSBarry Smith { 38c6a0d831SBarry Smith DM subdm = NULL; 391e07b27eSBarry Smith 401e07b27eSBarry Smith if (!isActiveRank(sred->psubcomm)) { subdm = NULL; } 411e07b27eSBarry Smith else { 421e07b27eSBarry Smith switch (sred->sr_type) { 431e07b27eSBarry Smith case TELESCOPE_DEFAULT: subdm = NULL; 441e07b27eSBarry Smith break; 451e07b27eSBarry Smith case TELESCOPE_DMDA: subdm = ((PC_Telescope_DMDACtx*)sred->dm_ctx)->dmrepart; 461e07b27eSBarry Smith break; 471e07b27eSBarry Smith case TELESCOPE_DMPLEX: subdm = NULL; 481e07b27eSBarry Smith break; 491e07b27eSBarry Smith } 501e07b27eSBarry Smith } 511e07b27eSBarry Smith return(subdm); 521e07b27eSBarry Smith } 531e07b27eSBarry Smith 541e07b27eSBarry Smith #undef __FUNCT__ 551e07b27eSBarry Smith #define __FUNCT__ "PCTelescopeSetUp_default" 561e07b27eSBarry Smith PetscErrorCode PCTelescopeSetUp_default(PC pc,PC_Telescope sred) 571e07b27eSBarry Smith { 581e07b27eSBarry Smith PetscErrorCode ierr; 591e07b27eSBarry Smith PetscInt m,M,bs,st,ed; 601e07b27eSBarry Smith Vec x,xred,yred,xtmp; 611e07b27eSBarry Smith Mat B; 621e07b27eSBarry Smith MPI_Comm comm,subcomm; 631e07b27eSBarry Smith VecScatter scatter; 641e07b27eSBarry Smith IS isin; 651e07b27eSBarry Smith 661e07b27eSBarry Smith PetscFunctionBegin; 671e07b27eSBarry Smith ierr = PetscInfo(pc,"PCTelescope: setup (default)\n");CHKERRQ(ierr); 681e07b27eSBarry Smith comm = PetscSubcommParent(sred->psubcomm); 691e07b27eSBarry Smith subcomm = PetscSubcommChild(sred->psubcomm); 701e07b27eSBarry Smith 711e07b27eSBarry Smith ierr = PCGetOperators(pc,NULL,&B);CHKERRQ(ierr); 721e07b27eSBarry Smith ierr = MatGetSize(B,&M,NULL);CHKERRQ(ierr); 731e07b27eSBarry Smith ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr); 741e07b27eSBarry Smith ierr = MatCreateVecs(B,&x,NULL);CHKERRQ(ierr); 751e07b27eSBarry Smith 761e07b27eSBarry Smith xred = NULL; 773ac26c5eSBarry Smith m = 0; 781e07b27eSBarry Smith if (isActiveRank(sred->psubcomm)) { 791e07b27eSBarry Smith ierr = VecCreate(subcomm,&xred);CHKERRQ(ierr); 801e07b27eSBarry Smith ierr = VecSetSizes(xred,PETSC_DECIDE,M);CHKERRQ(ierr); 811e07b27eSBarry Smith ierr = VecSetBlockSize(xred,bs);CHKERRQ(ierr); 821e07b27eSBarry Smith ierr = VecSetFromOptions(xred);CHKERRQ(ierr); 831e07b27eSBarry Smith ierr = VecGetLocalSize(xred,&m); 841e07b27eSBarry Smith } 851e07b27eSBarry Smith 861e07b27eSBarry Smith yred = NULL; 871e07b27eSBarry Smith if (isActiveRank(sred->psubcomm)) { 881e07b27eSBarry Smith ierr = VecDuplicate(xred,&yred);CHKERRQ(ierr); 891e07b27eSBarry Smith } 901e07b27eSBarry Smith 911e07b27eSBarry Smith ierr = VecCreate(comm,&xtmp);CHKERRQ(ierr); 921e07b27eSBarry Smith ierr = VecSetSizes(xtmp,m,PETSC_DECIDE);CHKERRQ(ierr); 931e07b27eSBarry Smith ierr = VecSetBlockSize(xtmp,bs);CHKERRQ(ierr); 941e07b27eSBarry Smith ierr = VecSetType(xtmp,((PetscObject)x)->type_name);CHKERRQ(ierr); 951e07b27eSBarry Smith 961e07b27eSBarry Smith if (isActiveRank(sred->psubcomm)) { 971e07b27eSBarry Smith ierr = VecGetOwnershipRange(xred,&st,&ed);CHKERRQ(ierr); 981e07b27eSBarry Smith ierr = ISCreateStride(comm,(ed-st),st,1,&isin);CHKERRQ(ierr); 991e07b27eSBarry Smith } else { 1001e07b27eSBarry Smith ierr = VecGetOwnershipRange(x,&st,&ed);CHKERRQ(ierr); 1013ac26c5eSBarry Smith ierr = ISCreateStride(comm,0,st,1,&isin);CHKERRQ(ierr); 1021e07b27eSBarry Smith } 1031e07b27eSBarry Smith ierr = ISSetBlockSize(isin,bs);CHKERRQ(ierr); 1041e07b27eSBarry Smith 1051e07b27eSBarry Smith ierr = VecScatterCreate(x,isin,xtmp,NULL,&scatter);CHKERRQ(ierr); 1061e07b27eSBarry Smith 1071e07b27eSBarry Smith sred->isin = isin; 1081e07b27eSBarry Smith sred->scatter = scatter; 1091e07b27eSBarry Smith sred->xred = xred; 1101e07b27eSBarry Smith sred->yred = yred; 1111e07b27eSBarry Smith sred->xtmp = xtmp; 1121e07b27eSBarry Smith ierr = VecDestroy(&x);CHKERRQ(ierr); 1131e07b27eSBarry Smith PetscFunctionReturn(0); 1141e07b27eSBarry Smith } 1151e07b27eSBarry Smith 1161e07b27eSBarry Smith #undef __FUNCT__ 1171e07b27eSBarry Smith #define __FUNCT__ "PCTelescopeMatCreate_default" 1181e07b27eSBarry Smith PetscErrorCode PCTelescopeMatCreate_default(PC pc,PC_Telescope sred,MatReuse reuse,Mat *A) 1191e07b27eSBarry Smith { 1201e07b27eSBarry Smith PetscErrorCode ierr; 1211e07b27eSBarry Smith MPI_Comm comm,subcomm; 1221e07b27eSBarry Smith Mat Bred,B; 1231e07b27eSBarry Smith PetscInt nr,nc; 1241e07b27eSBarry Smith IS isrow,iscol; 1251e07b27eSBarry Smith Mat Blocal,*_Blocal; 1261e07b27eSBarry Smith 1271e07b27eSBarry Smith PetscFunctionBegin; 1281e07b27eSBarry Smith ierr = PetscInfo(pc,"PCTelescope: updating the redundant preconditioned operator (default)\n");CHKERRQ(ierr); 1291e07b27eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 1301e07b27eSBarry Smith subcomm = PetscSubcommChild(sred->psubcomm); 1311e07b27eSBarry Smith ierr = PCGetOperators(pc,NULL,&B);CHKERRQ(ierr); 1321e07b27eSBarry Smith ierr = MatGetSize(B,&nr,&nc);CHKERRQ(ierr); 1331e07b27eSBarry Smith isrow = sred->isin; 1341e07b27eSBarry Smith ierr = ISCreateStride(comm,nc,0,1,&iscol);CHKERRQ(ierr); 1351e07b27eSBarry Smith ierr = MatGetSubMatrices(B,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&_Blocal);CHKERRQ(ierr); 1361e07b27eSBarry Smith Blocal = *_Blocal; 1371e07b27eSBarry Smith ierr = PetscFree(_Blocal);CHKERRQ(ierr); 1381e07b27eSBarry Smith Bred = NULL; 1391e07b27eSBarry Smith if (isActiveRank(sred->psubcomm)) { 1401e07b27eSBarry Smith PetscInt mm; 1411e07b27eSBarry Smith 1421e07b27eSBarry Smith if (reuse != MAT_INITIAL_MATRIX) { Bred = *A; } 1431e07b27eSBarry Smith 1441e07b27eSBarry Smith ierr = MatGetSize(Blocal,&mm,NULL);CHKERRQ(ierr); 1451e07b27eSBarry Smith ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,Blocal,mm,reuse,&Bred);CHKERRQ(ierr); 1461e07b27eSBarry Smith } 1471e07b27eSBarry Smith *A = Bred; 1481e07b27eSBarry Smith ierr = ISDestroy(&iscol);CHKERRQ(ierr); 1491e07b27eSBarry Smith ierr = MatDestroy(&Blocal);CHKERRQ(ierr); 1501e07b27eSBarry Smith PetscFunctionReturn(0); 1511e07b27eSBarry Smith } 1521e07b27eSBarry Smith 1531e07b27eSBarry Smith #undef __FUNCT__ 1541e07b27eSBarry Smith #define __FUNCT__ "PCTelescopeMatNullSpaceCreate_default" 1551e07b27eSBarry Smith PetscErrorCode PCTelescopeMatNullSpaceCreate_default(PC pc,PC_Telescope sred,Mat sub_mat) 1561e07b27eSBarry Smith { 1571e07b27eSBarry Smith PetscErrorCode ierr; 1581e07b27eSBarry Smith MatNullSpace nullspace,sub_nullspace; 1591e07b27eSBarry Smith Mat A,B; 1601e07b27eSBarry Smith PetscBool has_const; 1611e07b27eSBarry Smith PetscInt i,k,n; 1621e07b27eSBarry Smith const Vec *vecs; 1631e07b27eSBarry Smith Vec *sub_vecs; 1641e07b27eSBarry Smith MPI_Comm subcomm; 1651e07b27eSBarry Smith 1661e07b27eSBarry Smith PetscFunctionBegin; 1671e07b27eSBarry Smith ierr = PCGetOperators(pc,&A,&B);CHKERRQ(ierr); 1681e07b27eSBarry Smith ierr = MatGetNullSpace(B,&nullspace);CHKERRQ(ierr); 1691e07b27eSBarry Smith if (!nullspace) return(0); 1701e07b27eSBarry Smith 1711e07b27eSBarry Smith ierr = PetscInfo(pc,"PCTelescope: generating nullspace (default)\n");CHKERRQ(ierr); 1721e07b27eSBarry Smith subcomm = PetscSubcommChild(sred->psubcomm); 1731e07b27eSBarry Smith ierr = MatNullSpaceGetVecs(nullspace,&has_const,&n,&vecs);CHKERRQ(ierr); 1741e07b27eSBarry Smith 1751e07b27eSBarry Smith if (isActiveRank(sred->psubcomm)) { 176e3acf2f7SBarry Smith if (n) { 177e3acf2f7SBarry Smith ierr = VecDuplicateVecs(sred->xred,n,&sub_vecs);CHKERRQ(ierr); 1781e07b27eSBarry Smith } 1791e07b27eSBarry Smith } 1801e07b27eSBarry Smith 1811e07b27eSBarry Smith /* copy entries */ 1821e07b27eSBarry Smith for (k=0; k<n; k++) { 1831e07b27eSBarry Smith const PetscScalar *x_array; 1841e07b27eSBarry Smith PetscScalar *LA_sub_vec; 1851e07b27eSBarry Smith PetscInt st,ed,bs; 1861e07b27eSBarry Smith 1871e07b27eSBarry Smith /* pull in vector x->xtmp */ 1881e07b27eSBarry Smith ierr = VecScatterBegin(sred->scatter,vecs[k],sred->xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1891e07b27eSBarry Smith ierr = VecScatterEnd(sred->scatter,vecs[k],sred->xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1901e07b27eSBarry Smith /* copy vector entires into xred */ 1911e07b27eSBarry Smith ierr = VecGetBlockSize(sred->xtmp,&bs);CHKERRQ(ierr); 1921e07b27eSBarry Smith ierr = VecGetArrayRead(sred->xtmp,&x_array);CHKERRQ(ierr); 1931e07b27eSBarry Smith if (sub_vecs[k]) { 1941e07b27eSBarry Smith ierr = VecGetOwnershipRange(sub_vecs[k],&st,&ed);CHKERRQ(ierr); 1951e07b27eSBarry Smith ierr = VecGetArray(sub_vecs[k],&LA_sub_vec);CHKERRQ(ierr); 1961e07b27eSBarry Smith for (i=0; i<ed-st; i++) { 1971e07b27eSBarry Smith LA_sub_vec[i] = x_array[i]; 1981e07b27eSBarry Smith } 1991e07b27eSBarry Smith ierr = VecRestoreArray(sub_vecs[k],&LA_sub_vec);CHKERRQ(ierr); 2001e07b27eSBarry Smith } 2011e07b27eSBarry Smith ierr = VecRestoreArrayRead(sred->xtmp,&x_array);CHKERRQ(ierr); 2021e07b27eSBarry Smith } 2031e07b27eSBarry Smith 2041e07b27eSBarry Smith if (isActiveRank(sred->psubcomm)) { 2051e07b27eSBarry Smith /* create new nullspace for redundant object */ 2061e07b27eSBarry Smith ierr = MatNullSpaceCreate(subcomm,has_const,n,sub_vecs,&sub_nullspace);CHKERRQ(ierr); 2071e07b27eSBarry Smith /* attach redundant nullspace to Bred */ 2081e07b27eSBarry Smith ierr = MatSetNullSpace(sub_mat,sub_nullspace);CHKERRQ(ierr); 209e3acf2f7SBarry Smith ierr = VecDestroyVecs(n,&sub_vecs);CHKERRQ(ierr); 2101e07b27eSBarry Smith } 2111e07b27eSBarry Smith PetscFunctionReturn(0); 2121e07b27eSBarry Smith } 2131e07b27eSBarry Smith 2141e07b27eSBarry Smith #undef __FUNCT__ 2151e07b27eSBarry Smith #define __FUNCT__ "PCView_Telescope" 2161e07b27eSBarry Smith static PetscErrorCode PCView_Telescope(PC pc,PetscViewer viewer) 2171e07b27eSBarry Smith { 2181e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 2191e07b27eSBarry Smith PetscErrorCode ierr; 2201e07b27eSBarry Smith PetscBool iascii,isstring; 2211e07b27eSBarry Smith PetscViewer subviewer; 2221e07b27eSBarry Smith 2231e07b27eSBarry Smith PetscFunctionBegin; 2241e07b27eSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 2251e07b27eSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 2261e07b27eSBarry Smith if (iascii) { 2271e07b27eSBarry Smith if (!sred->psubcomm) { 2281e07b27eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Telescope: preconditioner not yet setup\n");CHKERRQ(ierr); 2291e07b27eSBarry Smith } else { 2301e07b27eSBarry Smith MPI_Comm comm,subcomm; 2311e07b27eSBarry Smith PetscMPIInt comm_size,subcomm_size; 2321e07b27eSBarry Smith DM dm,subdm; 2331e07b27eSBarry Smith 2341e07b27eSBarry Smith ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 2351e07b27eSBarry Smith subdm = private_PCTelescopeGetSubDM(sred); 2361e07b27eSBarry Smith comm = PetscSubcommParent(sred->psubcomm); 2371e07b27eSBarry Smith subcomm = PetscSubcommChild(sred->psubcomm); 2381e07b27eSBarry Smith ierr = MPI_Comm_size(comm,&comm_size);CHKERRQ(ierr); 2391e07b27eSBarry Smith ierr = MPI_Comm_size(subcomm,&subcomm_size);CHKERRQ(ierr); 2401e07b27eSBarry Smith 2411e07b27eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Telescope: parent comm size reduction factor = %D\n",sred->redfactor);CHKERRQ(ierr); 2421e07b27eSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," Telescope: comm_size = %d , subcomm_size = %d\n",(int)comm_size,(int)subcomm_size);CHKERRQ(ierr); 2431e07b27eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,subcomm,&subviewer);CHKERRQ(ierr); 2441e07b27eSBarry Smith if (isActiveRank(sred->psubcomm)) { 2451e07b27eSBarry Smith ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 2461e07b27eSBarry Smith 2471e07b27eSBarry Smith if (dm && sred->ignore_dm) { 2481e07b27eSBarry Smith ierr = PetscViewerASCIIPrintf(subviewer," Telescope: ignoring DM\n");CHKERRQ(ierr); 2491e07b27eSBarry Smith } 2501e07b27eSBarry Smith switch (sred->sr_type) { 2511e07b27eSBarry Smith case TELESCOPE_DEFAULT: 2521e07b27eSBarry Smith ierr = PetscViewerASCIIPrintf(subviewer," Telescope: using default setup\n");CHKERRQ(ierr); 2531e07b27eSBarry Smith break; 2541e07b27eSBarry Smith case TELESCOPE_DMDA: 2551e07b27eSBarry Smith ierr = PetscViewerASCIIPrintf(subviewer," Telescope: DMDA detected\n");CHKERRQ(ierr); 2561e07b27eSBarry Smith ierr = DMView_DMDAShort(subdm,subviewer);CHKERRQ(ierr); 2571e07b27eSBarry Smith break; 2581e07b27eSBarry Smith case TELESCOPE_DMPLEX: 2591e07b27eSBarry Smith ierr = PetscViewerASCIIPrintf(subviewer," Telescope: DMPLEX detected\n");CHKERRQ(ierr); 2601e07b27eSBarry Smith break; 2611e07b27eSBarry Smith } 2621e07b27eSBarry Smith 2631e07b27eSBarry Smith ierr = KSPView(sred->ksp,subviewer);CHKERRQ(ierr); 2641e07b27eSBarry Smith ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 2651e07b27eSBarry Smith } 2661e07b27eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,subcomm,&subviewer);CHKERRQ(ierr); 2671e07b27eSBarry Smith } 2681e07b27eSBarry Smith } 2691e07b27eSBarry Smith PetscFunctionReturn(0); 2701e07b27eSBarry Smith } 2711e07b27eSBarry Smith 2721e07b27eSBarry Smith #undef __FUNCT__ 2731e07b27eSBarry Smith #define __FUNCT__ "PCSetUp_Telescope" 2741e07b27eSBarry Smith static PetscErrorCode PCSetUp_Telescope(PC pc) 2751e07b27eSBarry Smith { 2761e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 2771e07b27eSBarry Smith PetscErrorCode ierr; 278bd49479cSSatish Balay MPI_Comm comm,subcomm=0; 2791e07b27eSBarry Smith PCTelescopeType sr_type; 2801e07b27eSBarry Smith 2811e07b27eSBarry Smith PetscFunctionBegin; 2821e07b27eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 2831e07b27eSBarry Smith 2841e07b27eSBarry Smith /* subcomm definition */ 2851e07b27eSBarry Smith if (!pc->setupcalled) { 2861e07b27eSBarry Smith if (!sred->psubcomm) { 2871e07b27eSBarry Smith ierr = PetscSubcommCreate(comm,&sred->psubcomm);CHKERRQ(ierr); 2881e07b27eSBarry Smith ierr = PetscSubcommSetNumber(sred->psubcomm,sred->redfactor);CHKERRQ(ierr); 2891e07b27eSBarry Smith ierr = PetscSubcommSetType(sred->psubcomm,PETSC_SUBCOMM_INTERLACED);CHKERRQ(ierr); 2901e07b27eSBarry Smith /* disable runtime switch of psubcomm type, e.g., '-psubcomm_type interlaced */ 2911e07b27eSBarry Smith /* ierr = PetscSubcommSetFromOptions(sred->psubcomm);CHKERRQ(ierr); */ 2921e07b27eSBarry Smith ierr = PetscLogObjectMemory((PetscObject)pc,sizeof(PetscSubcomm));CHKERRQ(ierr); 2931e07b27eSBarry Smith /* create a new PC that processors in each subcomm have copy of */ 2941e07b27eSBarry Smith } 2951e07b27eSBarry Smith } 2960f6f40a7SSatish Balay subcomm = PetscSubcommChild(sred->psubcomm); 2971e07b27eSBarry Smith 2981e07b27eSBarry Smith /* internal KSP */ 2991e07b27eSBarry Smith if (!pc->setupcalled) { 3001e07b27eSBarry Smith const char *prefix; 3011e07b27eSBarry Smith 3021e07b27eSBarry Smith if (isActiveRank(sred->psubcomm)) { 3031e07b27eSBarry Smith ierr = KSPCreate(subcomm,&sred->ksp);CHKERRQ(ierr); 3041e07b27eSBarry Smith ierr = KSPSetErrorIfNotConverged(sred->ksp,pc->erroriffailure);CHKERRQ(ierr); 3051e07b27eSBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)sred->ksp,(PetscObject)pc,1);CHKERRQ(ierr); 3061e07b27eSBarry Smith ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)sred->ksp);CHKERRQ(ierr); 3071e07b27eSBarry Smith ierr = KSPSetType(sred->ksp,KSPPREONLY);CHKERRQ(ierr); 3081e07b27eSBarry Smith ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); 3091e07b27eSBarry Smith ierr = KSPSetOptionsPrefix(sred->ksp,prefix);CHKERRQ(ierr); 3101e07b27eSBarry Smith ierr = KSPAppendOptionsPrefix(sred->ksp,"telescope_");CHKERRQ(ierr); 3111e07b27eSBarry Smith } 3121e07b27eSBarry Smith } 3131e07b27eSBarry Smith /* Determine type of setup/update */ 3141e07b27eSBarry Smith if (!pc->setupcalled) { 3151e07b27eSBarry Smith PetscBool has_dm,same; 3161e07b27eSBarry Smith DM dm; 3171e07b27eSBarry Smith 3181e07b27eSBarry Smith sr_type = TELESCOPE_DEFAULT; 3191e07b27eSBarry Smith has_dm = PETSC_FALSE; 3201e07b27eSBarry Smith ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 3211e07b27eSBarry Smith if (dm) { has_dm = PETSC_TRUE; } 3221e07b27eSBarry Smith if (has_dm) { 3231e07b27eSBarry Smith /* check for dmda */ 3241e07b27eSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&same);CHKERRQ(ierr); 3251e07b27eSBarry Smith if (same) { 3261e07b27eSBarry Smith ierr = PetscInfo(pc,"PCTelescope: found DMDA\n");CHKERRQ(ierr); 3271e07b27eSBarry Smith sr_type = TELESCOPE_DMDA; 3281e07b27eSBarry Smith } 3291e07b27eSBarry Smith /* check for dmplex */ 3301e07b27eSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)dm,DMPLEX,&same);CHKERRQ(ierr); 3311e07b27eSBarry Smith if (same) { 3321e07b27eSBarry Smith PetscInfo(pc,"PCTelescope: found DMPLEX\n"); 3331e07b27eSBarry Smith sr_type = TELESCOPE_DMPLEX; 3341e07b27eSBarry Smith } 3351e07b27eSBarry Smith } 3361e07b27eSBarry Smith 3371e07b27eSBarry Smith if (sred->ignore_dm) { 3381e07b27eSBarry Smith PetscInfo(pc,"PCTelescope: ignore DM\n"); 3391e07b27eSBarry Smith sr_type = TELESCOPE_DEFAULT; 3401e07b27eSBarry Smith } 3411e07b27eSBarry Smith sred->sr_type = sr_type; 3421e07b27eSBarry Smith } else { 3431e07b27eSBarry Smith sr_type = sred->sr_type; 3441e07b27eSBarry Smith } 3451e07b27eSBarry Smith 3461e07b27eSBarry Smith /* set function pointers for repartition setup, matrix creation/update, matrix nullspace and reset functionality */ 3471e07b27eSBarry Smith switch (sr_type) { 3481e07b27eSBarry Smith case TELESCOPE_DEFAULT: 3491e07b27eSBarry Smith sred->pctelescope_setup_type = PCTelescopeSetUp_default; 3501e07b27eSBarry Smith sred->pctelescope_matcreate_type = PCTelescopeMatCreate_default; 3511e07b27eSBarry Smith sred->pctelescope_matnullspacecreate_type = PCTelescopeMatNullSpaceCreate_default; 3521e07b27eSBarry Smith sred->pctelescope_reset_type = NULL; 3531e07b27eSBarry Smith break; 3541e07b27eSBarry Smith case TELESCOPE_DMDA: 3551e07b27eSBarry Smith pc->ops->apply = PCApply_Telescope_dmda; 3561e07b27eSBarry Smith sred->pctelescope_setup_type = PCTelescopeSetUp_dmda; 3571e07b27eSBarry Smith sred->pctelescope_matcreate_type = PCTelescopeMatCreate_dmda; 3581e07b27eSBarry Smith sred->pctelescope_matnullspacecreate_type = PCTelescopeMatNullSpaceCreate_dmda; 3591e07b27eSBarry Smith sred->pctelescope_reset_type = PCReset_Telescope_dmda; 3601e07b27eSBarry Smith break; 3611e07b27eSBarry Smith case TELESCOPE_DMPLEX: SETERRQ(comm,PETSC_ERR_SUP,"Supprt for DMPLEX is currently not available"); 3621e07b27eSBarry Smith break; 3631e07b27eSBarry Smith default: SETERRQ(comm,PETSC_ERR_SUP,"Only supprt for repartitioning DMDA is provided"); 3641e07b27eSBarry Smith break; 3651e07b27eSBarry Smith } 3661e07b27eSBarry Smith 3671e07b27eSBarry Smith /* setup */ 3681e07b27eSBarry Smith if (sred->pctelescope_setup_type) { 3691e07b27eSBarry Smith ierr = sred->pctelescope_setup_type(pc,sred);CHKERRQ(ierr); 3701e07b27eSBarry Smith } 3711e07b27eSBarry Smith /* update */ 3721e07b27eSBarry Smith if (!pc->setupcalled) { 3731e07b27eSBarry Smith if (sred->pctelescope_matcreate_type) { 3741e07b27eSBarry Smith ierr = sred->pctelescope_matcreate_type(pc,sred,MAT_INITIAL_MATRIX,&sred->Bred);CHKERRQ(ierr); 3751e07b27eSBarry Smith } 3761e07b27eSBarry Smith if (sred->pctelescope_matnullspacecreate_type) { 3771e07b27eSBarry Smith ierr = sred->pctelescope_matnullspacecreate_type(pc,sred,sred->Bred);CHKERRQ(ierr); 3781e07b27eSBarry Smith } 3791e07b27eSBarry Smith } else { 3801e07b27eSBarry Smith if (sred->pctelescope_matcreate_type) { 3811e07b27eSBarry Smith ierr = sred->pctelescope_matcreate_type(pc,sred,MAT_REUSE_MATRIX,&sred->Bred);CHKERRQ(ierr); 3821e07b27eSBarry Smith } 3831e07b27eSBarry Smith } 3841e07b27eSBarry Smith 3851e07b27eSBarry Smith /* common - no construction */ 3861e07b27eSBarry Smith if (isActiveRank(sred->psubcomm)) { 3871e07b27eSBarry Smith ierr = KSPSetOperators(sred->ksp,sred->Bred,sred->Bred);CHKERRQ(ierr); 3881e07b27eSBarry Smith if (pc->setfromoptionscalled && !pc->setupcalled){ 3891e07b27eSBarry Smith ierr = KSPSetFromOptions(sred->ksp);CHKERRQ(ierr); 3901e07b27eSBarry Smith } 3911e07b27eSBarry Smith } 3921e07b27eSBarry Smith PetscFunctionReturn(0); 3931e07b27eSBarry Smith } 3941e07b27eSBarry Smith 3951e07b27eSBarry Smith #undef __FUNCT__ 3961e07b27eSBarry Smith #define __FUNCT__ "PCApply_Telescope" 3971e07b27eSBarry Smith static PetscErrorCode PCApply_Telescope(PC pc,Vec x,Vec y) 3981e07b27eSBarry Smith { 3991e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 4001e07b27eSBarry Smith PetscErrorCode ierr; 4011e07b27eSBarry Smith Vec xtmp,xred,yred; 4021e07b27eSBarry Smith PetscInt i,st,ed,bs; 4031e07b27eSBarry Smith VecScatter scatter; 4041e07b27eSBarry Smith PetscScalar *array; 4051e07b27eSBarry Smith const PetscScalar *x_array; 4061e07b27eSBarry Smith 4071e07b27eSBarry Smith PetscFunctionBegin; 4081e07b27eSBarry Smith xtmp = sred->xtmp; 4091e07b27eSBarry Smith scatter = sred->scatter; 4101e07b27eSBarry Smith xred = sred->xred; 4111e07b27eSBarry Smith yred = sred->yred; 4121e07b27eSBarry Smith 4131e07b27eSBarry Smith /* pull in vector x->xtmp */ 4141e07b27eSBarry Smith ierr = VecScatterBegin(scatter,x,xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4151e07b27eSBarry Smith ierr = VecScatterEnd(scatter,x,xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4161e07b27eSBarry Smith 4171e07b27eSBarry Smith /* copy vector entires into xred */ 4181e07b27eSBarry Smith ierr = VecGetBlockSize(xtmp,&bs);CHKERRQ(ierr); 4191e07b27eSBarry Smith ierr = VecGetArrayRead(xtmp,&x_array);CHKERRQ(ierr); 4201e07b27eSBarry Smith if (xred) { 4211e07b27eSBarry Smith PetscScalar *LA_xred; 4221e07b27eSBarry Smith ierr = VecGetOwnershipRange(xred,&st,&ed);CHKERRQ(ierr); 4231e07b27eSBarry Smith ierr = VecGetArray(xred,&LA_xred);CHKERRQ(ierr); 4241e07b27eSBarry Smith for (i=0; i<ed-st; i++) { 4251e07b27eSBarry Smith LA_xred[i] = x_array[i]; 4261e07b27eSBarry Smith } 4271e07b27eSBarry Smith ierr = VecRestoreArray(xred,&LA_xred);CHKERRQ(ierr); 4281e07b27eSBarry Smith } 4291e07b27eSBarry Smith ierr = VecRestoreArrayRead(xtmp,&x_array);CHKERRQ(ierr); 4301e07b27eSBarry Smith /* solve */ 4311e07b27eSBarry Smith if (isActiveRank(sred->psubcomm)) { 4321e07b27eSBarry Smith ierr = KSPSolve(sred->ksp,xred,yred);CHKERRQ(ierr); 4331e07b27eSBarry Smith } 4341e07b27eSBarry Smith /* return vector */ 4351e07b27eSBarry Smith ierr = VecGetBlockSize(xtmp,&bs);CHKERRQ(ierr); 4361e07b27eSBarry Smith ierr = VecGetArray(xtmp,&array);CHKERRQ(ierr); 4371e07b27eSBarry Smith if (yred) { 4381e07b27eSBarry Smith const PetscScalar *LA_yred; 4391e07b27eSBarry Smith ierr = VecGetOwnershipRange(yred,&st,&ed);CHKERRQ(ierr); 4401e07b27eSBarry Smith ierr = VecGetArrayRead(yred,&LA_yred);CHKERRQ(ierr); 4411e07b27eSBarry Smith for (i=0; i<ed-st; i++) { 4421e07b27eSBarry Smith array[i] = LA_yred[i]; 4431e07b27eSBarry Smith } 4441e07b27eSBarry Smith ierr = VecRestoreArrayRead(yred,&LA_yred);CHKERRQ(ierr); 4451e07b27eSBarry Smith } 4461e07b27eSBarry Smith ierr = VecRestoreArray(xtmp,&array);CHKERRQ(ierr); 4471e07b27eSBarry Smith ierr = VecScatterBegin(scatter,xtmp,y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4481e07b27eSBarry Smith ierr = VecScatterEnd(scatter,xtmp,y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4491e07b27eSBarry Smith PetscFunctionReturn(0); 4501e07b27eSBarry Smith } 4511e07b27eSBarry Smith 4521e07b27eSBarry Smith #undef __FUNCT__ 4531e07b27eSBarry Smith #define __FUNCT__ "PCReset_Telescope" 4541e07b27eSBarry Smith static PetscErrorCode PCReset_Telescope(PC pc) 4551e07b27eSBarry Smith { 4561e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 4571e07b27eSBarry Smith PetscErrorCode ierr; 4581e07b27eSBarry Smith 4591e07b27eSBarry Smith ierr = ISDestroy(&sred->isin);CHKERRQ(ierr); 4601e07b27eSBarry Smith ierr = VecScatterDestroy(&sred->scatter);CHKERRQ(ierr); 461e3acf2f7SBarry Smith ierr = VecDestroy(&sred->xred);CHKERRQ(ierr); 462e3acf2f7SBarry Smith ierr = VecDestroy(&sred->yred);CHKERRQ(ierr); 463e3acf2f7SBarry Smith ierr = VecDestroy(&sred->xtmp);CHKERRQ(ierr); 464e3acf2f7SBarry Smith ierr = MatDestroy(&sred->Bred);CHKERRQ(ierr); 465e3acf2f7SBarry Smith ierr = KSPReset(sred->ksp);CHKERRQ(ierr); 4661e07b27eSBarry Smith if (sred->pctelescope_reset_type) { 4671e07b27eSBarry Smith ierr = sred->pctelescope_reset_type(pc);CHKERRQ(ierr); 4681e07b27eSBarry Smith } 4691e07b27eSBarry Smith PetscFunctionReturn(0); 4701e07b27eSBarry Smith } 4711e07b27eSBarry Smith 4721e07b27eSBarry Smith #undef __FUNCT__ 4731e07b27eSBarry Smith #define __FUNCT__ "PCDestroy_Telescope" 4741e07b27eSBarry Smith static PetscErrorCode PCDestroy_Telescope(PC pc) 4751e07b27eSBarry Smith { 4761e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 4771e07b27eSBarry Smith PetscErrorCode ierr; 4781e07b27eSBarry Smith 4791e07b27eSBarry Smith PetscFunctionBegin; 4801e07b27eSBarry Smith ierr = PCReset_Telescope(pc);CHKERRQ(ierr); 481e3acf2f7SBarry Smith ierr = KSPDestroy(&sred->ksp);CHKERRQ(ierr); 4821e07b27eSBarry Smith ierr = PetscSubcommDestroy(&sred->psubcomm);CHKERRQ(ierr); 483e3acf2f7SBarry Smith ierr = PetscFree(sred->dm_ctx);CHKERRQ(ierr); 484e3acf2f7SBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 4851e07b27eSBarry Smith PetscFunctionReturn(0); 4861e07b27eSBarry Smith } 4871e07b27eSBarry Smith 4881e07b27eSBarry Smith #undef __FUNCT__ 4891e07b27eSBarry Smith #define __FUNCT__ "PCSetFromOptions_Telescope" 490*4416b707SBarry Smith static PetscErrorCode PCSetFromOptions_Telescope(PetscOptionItems *PetscOptionsObject,PC pc) 4911e07b27eSBarry Smith { 4921e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 4931e07b27eSBarry Smith PetscErrorCode ierr; 4941e07b27eSBarry Smith MPI_Comm comm; 4951e07b27eSBarry Smith PetscMPIInt size; 4961e07b27eSBarry Smith 4971e07b27eSBarry Smith PetscFunctionBegin; 4981e07b27eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 4991e07b27eSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 5001e07b27eSBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"Telescope options");CHKERRQ(ierr); 5011e07b27eSBarry Smith ierr = PetscOptionsInt("-pc_telescope_reduction_factor","Factor to reduce comm size by","PCTelescopeSetReductionFactor",sred->redfactor,&sred->redfactor,0);CHKERRQ(ierr); 5021e07b27eSBarry Smith if (sred->redfactor > size) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"-pc_telescope_reduction_factor <= comm size"); 5031e07b27eSBarry Smith ierr = PetscOptionsBool("-pc_telescope_ignore_dm","Ignore any DM attached to the PC","PCTelescopeSetIgnoreDM",sred->ignore_dm,&sred->ignore_dm,0);CHKERRQ(ierr); 5041e07b27eSBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 5051e07b27eSBarry Smith PetscFunctionReturn(0); 5061e07b27eSBarry Smith } 5071e07b27eSBarry Smith 5081e07b27eSBarry Smith /* PC simplementation specific API's */ 5091e07b27eSBarry Smith 5101e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetKSP_Telescope(PC pc,KSP *ksp) 5111e07b27eSBarry Smith { 5121e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 513bd49479cSSatish Balay PetscFunctionBegin; 5141e07b27eSBarry Smith if (ksp) *ksp = red->ksp; 515bd49479cSSatish Balay PetscFunctionReturn(0); 5161e07b27eSBarry Smith } 5171e07b27eSBarry Smith 5181e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetReductionFactor_Telescope(PC pc,PetscInt *fact) 5191e07b27eSBarry Smith { 5201e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 521bd49479cSSatish Balay PetscFunctionBegin; 5221e07b27eSBarry Smith if (fact) *fact = red->redfactor; 523bd49479cSSatish Balay PetscFunctionReturn(0); 5241e07b27eSBarry Smith } 5251e07b27eSBarry Smith 5261e07b27eSBarry Smith static PetscErrorCode PCTelescopeSetReductionFactor_Telescope(PC pc,PetscInt fact) 5271e07b27eSBarry Smith { 5281e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 5291e07b27eSBarry Smith PetscMPIInt size; 5301e07b27eSBarry Smith PetscErrorCode ierr; 5311e07b27eSBarry Smith 532bd49479cSSatish Balay PetscFunctionBegin; 5331e07b27eSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 5341e07b27eSBarry Smith if (fact <= 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Reduction factor of telescoping PC %D must be positive",fact); 5351e07b27eSBarry Smith if (fact > size) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Reduction factor of telescoping PC %D must be <= comm.size",fact); 5361e07b27eSBarry Smith red->redfactor = fact; 537bd49479cSSatish Balay PetscFunctionReturn(0); 5381e07b27eSBarry Smith } 5391e07b27eSBarry Smith 5401e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetIgnoreDM_Telescope(PC pc,PetscBool *v) 5411e07b27eSBarry Smith { 5421e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 543bd49479cSSatish Balay PetscFunctionBegin; 5441e07b27eSBarry Smith if (v) *v = red->ignore_dm; 545bd49479cSSatish Balay PetscFunctionReturn(0); 5461e07b27eSBarry Smith } 5471e07b27eSBarry Smith static PetscErrorCode PCTelescopeSetIgnoreDM_Telescope(PC pc,PetscBool v) 5481e07b27eSBarry Smith { 5491e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 550bd49479cSSatish Balay PetscFunctionBegin; 5511e07b27eSBarry Smith red->ignore_dm = v; 552bd49479cSSatish Balay PetscFunctionReturn(0); 5531e07b27eSBarry Smith } 5541e07b27eSBarry Smith 5551e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetDM_Telescope(PC pc,DM *dm) 5561e07b27eSBarry Smith { 5571e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 558bd49479cSSatish Balay PetscFunctionBegin; 5591e07b27eSBarry Smith *dm = private_PCTelescopeGetSubDM(red); 560bd49479cSSatish Balay PetscFunctionReturn(0); 5611e07b27eSBarry Smith } 5621e07b27eSBarry Smith 5631e07b27eSBarry Smith /*@ 5641e07b27eSBarry Smith PCTelescopeGetKSP - Gets the KSP created by the telescoping PC. 5651e07b27eSBarry Smith 5661e07b27eSBarry Smith Not Collective 5671e07b27eSBarry Smith 5681e07b27eSBarry Smith Input Parameter: 5691e07b27eSBarry Smith . pc - the preconditioner context 5701e07b27eSBarry Smith 5711e07b27eSBarry Smith Output Parameter: 5721e07b27eSBarry Smith . subksp - the KSP defined the smaller set of processes 5731e07b27eSBarry Smith 5741e07b27eSBarry Smith Level: advanced 5751e07b27eSBarry Smith 5761e07b27eSBarry Smith .keywords: PC, telescopting solve 5771e07b27eSBarry Smith @*/ 5781e07b27eSBarry Smith PetscErrorCode PCTelescopeGetKSP(PC pc,KSP *subksp) 5791e07b27eSBarry Smith { 580bd49479cSSatish Balay PetscErrorCode ierr; 581bd49479cSSatish Balay PetscFunctionBegin; 582bd49479cSSatish Balay ierr = PetscTryMethod(pc,"PCTelescopeGetKSP_C",(PC,KSP*),(pc,subksp));CHKERRQ(ierr); 583bd49479cSSatish Balay PetscFunctionReturn(0); 5841e07b27eSBarry Smith } 5851e07b27eSBarry Smith 5861e07b27eSBarry Smith /*@ 5871e07b27eSBarry Smith PCTelescopeGetReductionFactor - Gets the factor by which the original number of processes has been reduced by. 5881e07b27eSBarry Smith 5891e07b27eSBarry Smith Not Collective 5901e07b27eSBarry Smith 5911e07b27eSBarry Smith Input Parameter: 5921e07b27eSBarry Smith . pc - the preconditioner context 5931e07b27eSBarry Smith 5941e07b27eSBarry Smith Output Parameter: 5951e07b27eSBarry Smith . fact - the reduction factor 5961e07b27eSBarry Smith 5971e07b27eSBarry Smith Level: advanced 5981e07b27eSBarry Smith 5991e07b27eSBarry Smith .keywords: PC, telescoping solve 6001e07b27eSBarry Smith @*/ 6011e07b27eSBarry Smith PetscErrorCode PCTelescopeGetReductionFactor(PC pc,PetscInt *fact) 6021e07b27eSBarry Smith { 603bd49479cSSatish Balay PetscErrorCode ierr; 604bd49479cSSatish Balay PetscFunctionBegin; 605bd49479cSSatish Balay ierr = PetscTryMethod(pc,"PCTelescopeGetReductionFactor_C",(PC,PetscInt*),(pc,fact));CHKERRQ(ierr); 606bd49479cSSatish Balay PetscFunctionReturn(0); 6071e07b27eSBarry Smith } 6081e07b27eSBarry Smith 6091e07b27eSBarry Smith /*@ 6101e07b27eSBarry Smith PCTelescopeSetReductionFactor - Sets the factor by which the original number of processes has been reduced by. 6111e07b27eSBarry Smith 6121e07b27eSBarry Smith Not Collective 6131e07b27eSBarry Smith 6141e07b27eSBarry Smith Input Parameter: 6151e07b27eSBarry Smith . pc - the preconditioner context 6161e07b27eSBarry Smith 6171e07b27eSBarry Smith Output Parameter: 6181e07b27eSBarry Smith . fact - the reduction factor 6191e07b27eSBarry Smith 6201e07b27eSBarry Smith Level: advanced 6211e07b27eSBarry Smith 6221e07b27eSBarry Smith .keywords: PC, telescoping solve 6231e07b27eSBarry Smith @*/ 6241e07b27eSBarry Smith PetscErrorCode PCTelescopeSetReductionFactor(PC pc,PetscInt fact) 6251e07b27eSBarry Smith { 626bd49479cSSatish Balay PetscErrorCode ierr; 627bd49479cSSatish Balay PetscFunctionBegin; 628bd49479cSSatish Balay ierr = PetscTryMethod(pc,"PCTelescopeSetReductionFactor_C",(PC,PetscInt),(pc,fact));CHKERRQ(ierr); 629bd49479cSSatish Balay PetscFunctionReturn(0); 6301e07b27eSBarry Smith } 6311e07b27eSBarry Smith 6321e07b27eSBarry Smith /*@ 6331e07b27eSBarry Smith PCTelescopeGetIgnoreDM - Get the flag indicating if any DM attached to the PC will be used. 6341e07b27eSBarry Smith 6351e07b27eSBarry Smith Not Collective 6361e07b27eSBarry Smith 6371e07b27eSBarry Smith Input Parameter: 6381e07b27eSBarry Smith . pc - the preconditioner context 6391e07b27eSBarry Smith 6401e07b27eSBarry Smith Output Parameter: 6411e07b27eSBarry Smith . v - the flag 6421e07b27eSBarry Smith 6431e07b27eSBarry Smith Level: advanced 6441e07b27eSBarry Smith 6451e07b27eSBarry Smith .keywords: PC, telescoping solve 6461e07b27eSBarry Smith @*/ 6471e07b27eSBarry Smith PetscErrorCode PCTelescopeGetIgnoreDM(PC pc,PetscBool *v) 6481e07b27eSBarry Smith { 649bd49479cSSatish Balay PetscErrorCode ierr; 650bd49479cSSatish Balay PetscFunctionBegin; 651bd49479cSSatish Balay ierr = PetscTryMethod(pc,"PCTelescopeGetIgnoreDM_C",(PC,PetscBool*),(pc,v));CHKERRQ(ierr); 652bd49479cSSatish Balay PetscFunctionReturn(0); 6531e07b27eSBarry Smith } 6541e07b27eSBarry Smith 6551e07b27eSBarry Smith /*@ 6561e07b27eSBarry Smith PCTelescopeSetIgnoreDM - Set a flag to ignore any DM attached to the PC. 6571e07b27eSBarry Smith 6581e07b27eSBarry Smith Not Collective 6591e07b27eSBarry Smith 6601e07b27eSBarry Smith Input Parameter: 6611e07b27eSBarry Smith . pc - the preconditioner context 6621e07b27eSBarry Smith 6631e07b27eSBarry Smith Output Parameter: 6641e07b27eSBarry Smith . v - Use PETSC_TRUE to ignore any DM 6651e07b27eSBarry Smith 6661e07b27eSBarry Smith Level: advanced 6671e07b27eSBarry Smith 6681e07b27eSBarry Smith .keywords: PC, telescoping solve 6691e07b27eSBarry Smith @*/ 670bfd6bcc6SSatish Balay PetscErrorCode PCTelescopeSetIgnoreDM(PC pc,PetscBool v) 6711e07b27eSBarry Smith { 672bd49479cSSatish Balay PetscErrorCode ierr; 673bd49479cSSatish Balay PetscFunctionBegin; 674bd49479cSSatish Balay ierr = PetscTryMethod(pc,"PCTelescopeSetIgnoreDM_C",(PC,PetscBool),(pc,v));CHKERRQ(ierr); 675bd49479cSSatish Balay PetscFunctionReturn(0); 6761e07b27eSBarry Smith } 6771e07b27eSBarry Smith 6781e07b27eSBarry Smith /*@ 6791e07b27eSBarry Smith PCTelescopeGetDM - Get the re-partitioned DM attached to the sub KSP. 6801e07b27eSBarry Smith 6811e07b27eSBarry Smith Not Collective 6821e07b27eSBarry Smith 6831e07b27eSBarry Smith Input Parameter: 6841e07b27eSBarry Smith . pc - the preconditioner context 6851e07b27eSBarry Smith 6861e07b27eSBarry Smith Output Parameter: 6871e07b27eSBarry Smith . subdm - The re-partitioned DM 6881e07b27eSBarry Smith 6891e07b27eSBarry Smith Level: advanced 6901e07b27eSBarry Smith 6911e07b27eSBarry Smith .keywords: PC, telescoping solve 6921e07b27eSBarry Smith @*/ 6931e07b27eSBarry Smith PetscErrorCode PCTelescopeGetDM(PC pc,DM *subdm) 6941e07b27eSBarry Smith { 695bd49479cSSatish Balay PetscErrorCode ierr; 696bd49479cSSatish Balay PetscFunctionBegin; 697bd49479cSSatish Balay ierr = PetscTryMethod(pc,"PCTelescopeGetDM_C",(PC,DM*),(pc,subdm));CHKERRQ(ierr); 698bd49479cSSatish Balay PetscFunctionReturn(0); 6991e07b27eSBarry Smith } 7001e07b27eSBarry Smith 7011e07b27eSBarry Smith /* -------------------------------------------------------------------------------------*/ 7021e07b27eSBarry Smith /*MC 7031e07b27eSBarry Smith PCTELESCOPE - Runs a KSP solver on a sub-group of processors. MPI processes not in the sub-communicator are idle during the solve. 7041e07b27eSBarry Smith 7051e07b27eSBarry Smith Options Database: 7061e07b27eSBarry Smith + -pc_telescope_reduction_factor <n> - factor to use communicator size by, for example if you are using 64 MPI processes and 7071e07b27eSBarry Smith use an n of 4, the new sub-communicator will be 4 defined with 64/4 processes 7081e07b27eSBarry Smith - -pc_telescope_ignore_dm <false> - flag to indicate whether an attached DM should be ignored 7091e07b27eSBarry Smith 7101e07b27eSBarry Smith Level: advanced 7111e07b27eSBarry Smith 7121e07b27eSBarry Smith Notes: 7136fc41876SBarry Smith The preconditioner is deemed telescopic as it only calls KSPSolve() on a single 7146fc41876SBarry Smith sub-communicator in contrast with PCREDUNDANT which calls KSPSolve() on N sub-communicators. 7156fc41876SBarry Smith This means there will be MPI processes within c, which will be idle during the application of this preconditioner. 7166fc41876SBarry Smith 7171e07b27eSBarry Smith The default KSP is PREONLY. If a DM is attached to the PC, it is re-partitioned on the sub-communicator. 7181e07b27eSBarry 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. 7191e07b27eSBarry Smith Currently only support for re-partitioning a DMDA is provided. 7201e07b27eSBarry Smith Any nullspace attached to the original Bmat operator are extracted, re-partitioned and set on the repartitioned Bmat operator. 7211e07b27eSBarry Smith KSPSetComputeOperators() is not propagated to the sub KSP. 7221e07b27eSBarry Smith Currently there is no support for the flag -pc_use_amat 7231e07b27eSBarry Smith 7246fc41876SBarry Smith Assuming that the parent preconditioner (PC) is defined on a communicator c, this implementation 7256fc41876SBarry Smith creates a child sub-communicator (c') containing less MPI processes than the original parent preconditioner (PC). 7266fc41876SBarry Smith 7276fc41876SBarry Smith Developer Notes: 7286fc41876SBarry Smith During PCSetup, the B operator is scattered onto c'. 7296fc41876SBarry Smith Within PCApply, the RHS vector (x) is scattered into a redundant vector, xred (defined on c'). 7306fc41876SBarry Smith Then KSPSolve() is executed on the c' communicator. 7316fc41876SBarry Smith 7326fc41876SBarry Smith The communicator used within the telescoping preconditioner is defined by a PetscSubcomm using the INTERLACED 7336fc41876SBarry Smith creation routine. We run the sub KSP on only the ranks within the communicator which have a color equal to zero. 7346fc41876SBarry Smith 7356fc41876SBarry Smith The telescoping preconditioner is aware of nullspaces which are attached to the only B operator. 7366fc41876SBarry Smith In case where B has a n nullspace attached, these nullspaces vectors are extract from B and mapped into 7376fc41876SBarry Smith a new nullspace (defined on the sub-communicator) which is attached to B' (the B operator which was scattered to c') 7386fc41876SBarry Smith 7396fc41876SBarry Smith The telescoping preconditioner is aware of an attached DM. In the event that the DM is of type DMDA (2D or 3D - 7406fc41876SBarry 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 7416fc41876SBarry Smith is attached the sub KSPSolve(). The design of telescope is such that it should be possible to extend support 7426fc41876SBarry Smith for re-partitioning other DM's (e.g. DMPLEX). The user can supply a flag to ignore attached DMs. 7436fc41876SBarry Smith 7446fc41876SBarry Smith By default, B' is defined by simply fusing rows from different MPI processes 7456fc41876SBarry Smith 7466fc41876SBarry Smith When a DMDA is attached to the parent preconditioner, B' is defined by: (i) performing a symmetric permuting of B 7476fc41876SBarry Smith into the ordering defined by the DMDA on c', (ii) extracting the local chunks via MatGetSubMatrices(), (iii) fusing the 7486fc41876SBarry Smith locally (sequential) matrices defined on the ranks common to c and c' into B' using MatCreateMPIMatConcatenateSeqMat() 7496fc41876SBarry Smith 7506fc41876SBarry Smith Limitations/improvements 7516fc41876SBarry Smith VecPlaceArray could be used within PCApply() to improve efficiency and reduce memory usage. 7526fc41876SBarry Smith 7536fc41876SBarry Smith The symmetric permutation used when a DMDA is encountered is performed via explicitly assmbleming a permutation matrix P, 7546fc41876SBarry 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 7556fc41876SBarry Smith VecPermute() does not supported for the use case required here. By computing P, I can permute both the operator and RHS in a 7566fc41876SBarry Smith consistent manner. 7576fc41876SBarry Smith 7586fc41876SBarry Smith Mapping of vectors is performed this way 7596fc41876SBarry 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. 7606fc41876SBarry Smith Using the interlaced creation routine, the ranks in c with color = 0, will be rank 0 and 2. 7616fc41876SBarry Smith We perform the scatter to the sub-comm in the following way, 7626fc41876SBarry Smith [1] Given a vector x defined on comm c 7636fc41876SBarry Smith 7646fc41876SBarry Smith rank(c) : _________ 0 ______ ________ 1 _______ ________ 2 _____________ ___________ 3 __________ 7656fc41876SBarry 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] 7666fc41876SBarry Smith 7676fc41876SBarry Smith scatter to xtmp defined also on comm c so that we have the following values 7686fc41876SBarry Smith 7696fc41876SBarry Smith rank(c) : ___________________ 0 ________________ _1_ ______________________ 2 _______________________ __3_ 7706fc41876SBarry 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] [ ] 7716fc41876SBarry Smith 7726fc41876SBarry Smith The entries on rank 1 and 3 (ranks which do not have a color = 0 in c') have no values 7736fc41876SBarry Smith 7746fc41876SBarry Smith 7756fc41876SBarry 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'. 7766fc41876SBarry Smith Ranks 0 and 2 are the only ranks in the subcomm which have a color = 0. 7776fc41876SBarry Smith 7786fc41876SBarry Smith rank(c') : ___________________ 0 _______________ ______________________ 1 _____________________ 7796fc41876SBarry 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] 7806fc41876SBarry Smith 7811e07b27eSBarry Smith 7821e07b27eSBarry Smith Contributed by Dave May 7831e07b27eSBarry Smith 7846fc41876SBarry Smith .seealso: PCTelescopeGetKSP(), PCTelescopeGetDM(), PCTelescopeGetReductionFactor(), PCTelescopeSetReductionFactor(), PCTelescopeGetIgnoreDM(), PCTelescopeSetIgnoreDM(), PCREDUNDANT 7851e07b27eSBarry Smith M*/ 7861e07b27eSBarry Smith #undef __FUNCT__ 7871e07b27eSBarry Smith #define __FUNCT__ "PCCreate_Telescope" 7881e07b27eSBarry Smith PETSC_EXTERN PetscErrorCode PCCreate_Telescope(PC pc) 7891e07b27eSBarry Smith { 7901e07b27eSBarry Smith PetscErrorCode ierr; 7911e07b27eSBarry Smith struct _PC_Telescope *sred; 7921e07b27eSBarry Smith 7931e07b27eSBarry Smith PetscFunctionBegin; 7941e07b27eSBarry Smith ierr = PetscNewLog(pc,&sred);CHKERRQ(ierr); 7951e07b27eSBarry Smith sred->redfactor = 1; 7961e07b27eSBarry Smith sred->ignore_dm = PETSC_FALSE; 7971e07b27eSBarry Smith pc->data = (void*)sred; 7981e07b27eSBarry Smith 7991e07b27eSBarry Smith pc->ops->apply = PCApply_Telescope; 8001e07b27eSBarry Smith pc->ops->applytranspose = NULL; 8011e07b27eSBarry Smith pc->ops->setup = PCSetUp_Telescope; 8021e07b27eSBarry Smith pc->ops->destroy = PCDestroy_Telescope; 8031e07b27eSBarry Smith pc->ops->reset = PCReset_Telescope; 8041e07b27eSBarry Smith pc->ops->setfromoptions = PCSetFromOptions_Telescope; 8051e07b27eSBarry Smith pc->ops->view = PCView_Telescope; 8061e07b27eSBarry Smith 8071e07b27eSBarry Smith sred->pctelescope_setup_type = PCTelescopeSetUp_default; 8081e07b27eSBarry Smith sred->pctelescope_matcreate_type = PCTelescopeMatCreate_default; 8091e07b27eSBarry Smith sred->pctelescope_matnullspacecreate_type = PCTelescopeMatNullSpaceCreate_default; 8101e07b27eSBarry Smith sred->pctelescope_reset_type = NULL; 8111e07b27eSBarry Smith 8121e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetKSP_C",PCTelescopeGetKSP_Telescope);CHKERRQ(ierr); 8131e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetReductionFactor_C",PCTelescopeGetReductionFactor_Telescope);CHKERRQ(ierr); 8141e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeSetReductionFactor_C",PCTelescopeSetReductionFactor_Telescope);CHKERRQ(ierr); 8151e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetIgnoreDM_C",PCTelescopeGetIgnoreDM_Telescope);CHKERRQ(ierr); 8161e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeSetIgnoreDM_C",PCTelescopeSetIgnoreDM_Telescope);CHKERRQ(ierr); 8171e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetDM_C",PCTelescopeGetDM_Telescope);CHKERRQ(ierr); 8181e07b27eSBarry Smith PetscFunctionReturn(0); 8191e07b27eSBarry Smith } 820