11e07b27eSBarry Smith 28d9f7141SDave May #include <petsc/private/petscimpl.h> 3120bdd93SDave May #include <petsc/private/matimpl.h> 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*/ 7575a0592SBarry Smith #include "../src/ksp/pc/impls/telescope/telescope.h" 81e07b27eSBarry Smith 9bf00f589SPatrick Sanan static PetscBool cited = PETSC_FALSE; 10bf00f589SPatrick Sanan static const char citation[] = 11bf00f589SPatrick Sanan "@inproceedings{MaySananRuppKnepleySmith2016,\n" 12bf00f589SPatrick Sanan " title = {Extreme-Scale Multigrid Components within PETSc},\n" 13bf00f589SPatrick Sanan " author = {Dave A. May and Patrick Sanan and Karl Rupp and Matthew G. Knepley and Barry F. Smith},\n" 14bf00f589SPatrick Sanan " booktitle = {Proceedings of the Platform for Advanced Scientific Computing Conference},\n" 15bf00f589SPatrick Sanan " series = {PASC '16},\n" 16bf00f589SPatrick Sanan " isbn = {978-1-4503-4126-4},\n" 17bf00f589SPatrick Sanan " location = {Lausanne, Switzerland},\n" 18bf00f589SPatrick Sanan " pages = {5:1--5:12},\n" 19bf00f589SPatrick Sanan " articleno = {5},\n" 20bf00f589SPatrick Sanan " numpages = {12},\n" 21a8d69d7bSBarry Smith " url = {https://doi.acm.org/10.1145/2929908.2929913},\n" 22bf00f589SPatrick Sanan " doi = {10.1145/2929908.2929913},\n" 23bf00f589SPatrick Sanan " acmid = {2929913},\n" 24bf00f589SPatrick Sanan " publisher = {ACM},\n" 25bf00f589SPatrick Sanan " address = {New York, NY, USA},\n" 26bf00f589SPatrick Sanan " keywords = {GPU, HPC, agglomeration, coarse-level solver, multigrid, parallel computing, preconditioning},\n" 27bf00f589SPatrick Sanan " year = {2016}\n" 28bf00f589SPatrick Sanan "}\n"; 29bf00f589SPatrick Sanan 301e07b27eSBarry Smith /* 31c5083d92SDave May default setup mode 321e07b27eSBarry Smith 33c5083d92SDave May [1a] scatter to (FORWARD) 341e07b27eSBarry Smith x(comm) -> xtmp(comm) 35c5083d92SDave May [1b] local copy (to) ranks with color = 0 361e07b27eSBarry Smith xred(subcomm) <- xtmp 371e07b27eSBarry Smith 38c5083d92SDave May [2] solve on sub KSP to obtain yred(subcomm) 39c5083d92SDave May 40c5083d92SDave May [3a] local copy (from) ranks with color = 0 411e07b27eSBarry Smith yred(subcomm) --> xtmp 42c5083d92SDave May [2b] scatter from (REVERSE) 431e07b27eSBarry Smith xtmp(comm) -> y(comm) 441e07b27eSBarry Smith */ 451e07b27eSBarry Smith 468d9f7141SDave May /* 47d083f849SBarry Smith Collective[comm_f] 488d9f7141SDave May Notes 498d9f7141SDave May * Using comm_f = MPI_COMM_NULL will result in an error 508d9f7141SDave May * Using comm_c = MPI_COMM_NULL is valid. If all instances of comm_c are NULL the subcomm is not valid. 518d9f7141SDave May * If any non NULL comm_c communicator cannot map any of its ranks to comm_f, the subcomm is not valid. 528d9f7141SDave May */ 538d9f7141SDave May PetscErrorCode PCTelescopeTestValidSubcomm(MPI_Comm comm_f,MPI_Comm comm_c,PetscBool *isvalid) 548d9f7141SDave May { 5557f12427SDave May PetscInt valid = 1; 568d9f7141SDave May MPI_Group group_f,group_c; 578d9f7141SDave May PetscErrorCode ierr; 588d9f7141SDave May PetscMPIInt count,k,size_f = 0,size_c = 0,size_c_sum = 0; 595bd1e576SStefano Zampini PetscMPIInt *ranks_f,*ranks_c; 608d9f7141SDave May 6157f12427SDave May PetscFunctionBegin; 628d9f7141SDave May if (comm_f == MPI_COMM_NULL) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"comm_f cannot be MPI_COMM_NULL"); 638d9f7141SDave May 64ffc4695bSBarry Smith ierr = MPI_Comm_group(comm_f,&group_f);CHKERRMPI(ierr); 658d9f7141SDave May if (comm_c != MPI_COMM_NULL) { 66ffc4695bSBarry Smith ierr = MPI_Comm_group(comm_c,&group_c);CHKERRMPI(ierr); 678d9f7141SDave May } 688d9f7141SDave May 69ffc4695bSBarry Smith ierr = MPI_Comm_size(comm_f,&size_f);CHKERRMPI(ierr); 708d9f7141SDave May if (comm_c != MPI_COMM_NULL) { 71ffc4695bSBarry Smith ierr = MPI_Comm_size(comm_c,&size_c);CHKERRMPI(ierr); 728d9f7141SDave May } 738d9f7141SDave May 748d9f7141SDave May /* check not all comm_c's are NULL */ 758d9f7141SDave May size_c_sum = size_c; 76ffc4695bSBarry Smith ierr = MPI_Allreduce(MPI_IN_PLACE,&size_c_sum,1,MPI_INT,MPI_SUM,comm_f);CHKERRMPI(ierr); 775bd1e576SStefano Zampini if (size_c_sum == 0) valid = 0; 788d9f7141SDave May 798d9f7141SDave May /* check we can map at least 1 rank in comm_c to comm_f */ 808d9f7141SDave May ierr = PetscMalloc1(size_f,&ranks_f);CHKERRQ(ierr); 818d9f7141SDave May ierr = PetscMalloc1(size_c,&ranks_c);CHKERRQ(ierr); 825bd1e576SStefano Zampini for (k=0; k<size_f; k++) ranks_f[k] = MPI_UNDEFINED; 835bd1e576SStefano Zampini for (k=0; k<size_c; k++) ranks_c[k] = k; 848d9f7141SDave May 8557f12427SDave May /* 8657f12427SDave May MPI_Group_translate_ranks() returns a non-zero exit code if any rank cannot be translated. 8757f12427SDave May I do not want the code to terminate immediately if this occurs, rather I want to throw 8857f12427SDave May the error later (during PCSetUp_Telescope()) via SETERRQ() with a message indicating 8957f12427SDave May that comm_c is not a valid sub-communicator. 9057f12427SDave May Hence I purposefully do not call CHKERRQ() after MPI_Group_translate_ranks(). 9157f12427SDave May */ 928d9f7141SDave May count = 0; 938d9f7141SDave May if (comm_c != MPI_COMM_NULL) { 9466b79024SDave May (void)MPI_Group_translate_ranks(group_c,size_c,ranks_c,group_f,ranks_f); 958d9f7141SDave May for (k=0; k<size_f; k++) { 968d9f7141SDave May if (ranks_f[k] == MPI_UNDEFINED) { 978d9f7141SDave May count++; 988d9f7141SDave May } 998d9f7141SDave May } 1008d9f7141SDave May } 1015bd1e576SStefano Zampini if (count == size_f) valid = 0; 1028d9f7141SDave May 103ffc4695bSBarry Smith ierr = MPI_Allreduce(MPI_IN_PLACE,&valid,1,MPIU_INT,MPI_MIN,comm_f);CHKERRMPI(ierr); 1045bd1e576SStefano Zampini if (valid == 1) *isvalid = PETSC_TRUE; 1055bd1e576SStefano Zampini else *isvalid = PETSC_FALSE; 1068d9f7141SDave May 1078d9f7141SDave May ierr = PetscFree(ranks_f);CHKERRQ(ierr); 1088d9f7141SDave May ierr = PetscFree(ranks_c);CHKERRQ(ierr); 109ffc4695bSBarry Smith ierr = MPI_Group_free(&group_f);CHKERRMPI(ierr); 1108d9f7141SDave May if (comm_c != MPI_COMM_NULL) { 111ffc4695bSBarry Smith ierr = MPI_Group_free(&group_c);CHKERRMPI(ierr); 1128d9f7141SDave May } 1138d9f7141SDave May PetscFunctionReturn(0); 1148d9f7141SDave May } 1158d9f7141SDave May 1161e07b27eSBarry Smith DM private_PCTelescopeGetSubDM(PC_Telescope sred) 1171e07b27eSBarry Smith { 118c6a0d831SBarry Smith DM subdm = NULL; 1191e07b27eSBarry Smith 12057f12427SDave May if (!PCTelescope_isActiveRank(sred)) { subdm = NULL; } 1211e07b27eSBarry Smith else { 1221e07b27eSBarry Smith switch (sred->sr_type) { 1231e07b27eSBarry Smith case TELESCOPE_DEFAULT: subdm = NULL; 1241e07b27eSBarry Smith break; 1251e07b27eSBarry Smith case TELESCOPE_DMDA: subdm = ((PC_Telescope_DMDACtx*)sred->dm_ctx)->dmrepart; 1261e07b27eSBarry Smith break; 1271e07b27eSBarry Smith case TELESCOPE_DMPLEX: subdm = NULL; 1281e07b27eSBarry Smith break; 1298d9f7141SDave May case TELESCOPE_COARSEDM: if (sred->ksp) { KSPGetDM(sred->ksp,&subdm); } 1308d9f7141SDave May break; 1311e07b27eSBarry Smith } 1321e07b27eSBarry Smith } 1331e07b27eSBarry Smith return(subdm); 1341e07b27eSBarry Smith } 1351e07b27eSBarry Smith 1361e07b27eSBarry Smith PetscErrorCode PCTelescopeSetUp_default(PC pc,PC_Telescope sred) 1371e07b27eSBarry Smith { 1381e07b27eSBarry Smith PetscErrorCode ierr; 1391e07b27eSBarry Smith PetscInt m,M,bs,st,ed; 1401e07b27eSBarry Smith Vec x,xred,yred,xtmp; 1411e07b27eSBarry Smith Mat B; 1421e07b27eSBarry Smith MPI_Comm comm,subcomm; 1431e07b27eSBarry Smith VecScatter scatter; 1441e07b27eSBarry Smith IS isin; 1451e07b27eSBarry Smith 1461e07b27eSBarry Smith PetscFunctionBegin; 1471e07b27eSBarry Smith ierr = PetscInfo(pc,"PCTelescope: setup (default)\n");CHKERRQ(ierr); 1481e07b27eSBarry Smith comm = PetscSubcommParent(sred->psubcomm); 1491e07b27eSBarry Smith subcomm = PetscSubcommChild(sred->psubcomm); 1501e07b27eSBarry Smith 1511e07b27eSBarry Smith ierr = PCGetOperators(pc,NULL,&B);CHKERRQ(ierr); 1521e07b27eSBarry Smith ierr = MatGetSize(B,&M,NULL);CHKERRQ(ierr); 1531e07b27eSBarry Smith ierr = MatGetBlockSize(B,&bs);CHKERRQ(ierr); 1541e07b27eSBarry Smith ierr = MatCreateVecs(B,&x,NULL);CHKERRQ(ierr); 1551e07b27eSBarry Smith 1561e07b27eSBarry Smith xred = NULL; 1573ac26c5eSBarry Smith m = 0; 15857f12427SDave May if (PCTelescope_isActiveRank(sred)) { 1591e07b27eSBarry Smith ierr = VecCreate(subcomm,&xred);CHKERRQ(ierr); 1601e07b27eSBarry Smith ierr = VecSetSizes(xred,PETSC_DECIDE,M);CHKERRQ(ierr); 1611e07b27eSBarry Smith ierr = VecSetBlockSize(xred,bs);CHKERRQ(ierr); 1621e07b27eSBarry Smith ierr = VecSetFromOptions(xred);CHKERRQ(ierr); 163ca43db0aSBarry Smith ierr = VecGetLocalSize(xred,&m);CHKERRQ(ierr); 1641e07b27eSBarry Smith } 1651e07b27eSBarry Smith 1661e07b27eSBarry Smith yred = NULL; 16757f12427SDave May if (PCTelescope_isActiveRank(sred)) { 1681e07b27eSBarry Smith ierr = VecDuplicate(xred,&yred);CHKERRQ(ierr); 1691e07b27eSBarry Smith } 1701e07b27eSBarry Smith 1711e07b27eSBarry Smith ierr = VecCreate(comm,&xtmp);CHKERRQ(ierr); 1721e07b27eSBarry Smith ierr = VecSetSizes(xtmp,m,PETSC_DECIDE);CHKERRQ(ierr); 1731e07b27eSBarry Smith ierr = VecSetBlockSize(xtmp,bs);CHKERRQ(ierr); 1741e07b27eSBarry Smith ierr = VecSetType(xtmp,((PetscObject)x)->type_name);CHKERRQ(ierr); 1751e07b27eSBarry Smith 17657f12427SDave May if (PCTelescope_isActiveRank(sred)) { 1771e07b27eSBarry Smith ierr = VecGetOwnershipRange(xred,&st,&ed);CHKERRQ(ierr); 1781e07b27eSBarry Smith ierr = ISCreateStride(comm,(ed-st),st,1,&isin);CHKERRQ(ierr); 1791e07b27eSBarry Smith } else { 1801e07b27eSBarry Smith ierr = VecGetOwnershipRange(x,&st,&ed);CHKERRQ(ierr); 1813ac26c5eSBarry Smith ierr = ISCreateStride(comm,0,st,1,&isin);CHKERRQ(ierr); 1821e07b27eSBarry Smith } 1831e07b27eSBarry Smith ierr = ISSetBlockSize(isin,bs);CHKERRQ(ierr); 1841e07b27eSBarry Smith 1859448b7f1SJunchao Zhang ierr = VecScatterCreate(x,isin,xtmp,NULL,&scatter);CHKERRQ(ierr); 1861e07b27eSBarry Smith 1871e07b27eSBarry Smith sred->isin = isin; 1881e07b27eSBarry Smith sred->scatter = scatter; 1891e07b27eSBarry Smith sred->xred = xred; 1901e07b27eSBarry Smith sred->yred = yred; 1911e07b27eSBarry Smith sred->xtmp = xtmp; 1921e07b27eSBarry Smith ierr = VecDestroy(&x);CHKERRQ(ierr); 1931e07b27eSBarry Smith PetscFunctionReturn(0); 1941e07b27eSBarry Smith } 1951e07b27eSBarry Smith 1961e07b27eSBarry Smith PetscErrorCode PCTelescopeMatCreate_default(PC pc,PC_Telescope sred,MatReuse reuse,Mat *A) 1971e07b27eSBarry Smith { 1981e07b27eSBarry Smith PetscErrorCode ierr; 1991e07b27eSBarry Smith MPI_Comm comm,subcomm; 2001e07b27eSBarry Smith Mat Bred,B; 2015624f943SPierre Jolivet PetscInt nr,nc,bs; 2021e07b27eSBarry Smith IS isrow,iscol; 2031e07b27eSBarry Smith Mat Blocal,*_Blocal; 2041e07b27eSBarry Smith 2051e07b27eSBarry Smith PetscFunctionBegin; 2061e07b27eSBarry Smith ierr = PetscInfo(pc,"PCTelescope: updating the redundant preconditioned operator (default)\n");CHKERRQ(ierr); 2071e07b27eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 2081e07b27eSBarry Smith subcomm = PetscSubcommChild(sred->psubcomm); 2091e07b27eSBarry Smith ierr = PCGetOperators(pc,NULL,&B);CHKERRQ(ierr); 2101e07b27eSBarry Smith ierr = MatGetSize(B,&nr,&nc);CHKERRQ(ierr); 2111e07b27eSBarry Smith isrow = sred->isin; 212ee5b8cbaSprj- ierr = ISCreateStride(PETSC_COMM_SELF,nc,0,1,&iscol);CHKERRQ(ierr); 213ee5b8cbaSprj- ierr = ISSetIdentity(iscol);CHKERRQ(ierr); 2145624f943SPierre Jolivet ierr = MatGetBlockSizes(B,NULL,&bs);CHKERRQ(ierr); 2155624f943SPierre Jolivet ierr = ISSetBlockSize(iscol,bs);CHKERRQ(ierr); 216ee5b8cbaSprj- ierr = MatSetOption(B,MAT_SUBMAT_SINGLEIS,PETSC_TRUE);CHKERRQ(ierr); 2177dae84e0SHong Zhang ierr = MatCreateSubMatrices(B,1,&isrow,&iscol,MAT_INITIAL_MATRIX,&_Blocal);CHKERRQ(ierr); 2181e07b27eSBarry Smith Blocal = *_Blocal; 2191e07b27eSBarry Smith ierr = PetscFree(_Blocal);CHKERRQ(ierr); 2201e07b27eSBarry Smith Bred = NULL; 22157f12427SDave May if (PCTelescope_isActiveRank(sred)) { 2221e07b27eSBarry Smith PetscInt mm; 2231e07b27eSBarry Smith 2241e07b27eSBarry Smith if (reuse != MAT_INITIAL_MATRIX) { Bred = *A; } 2251e07b27eSBarry Smith 2261e07b27eSBarry Smith ierr = MatGetSize(Blocal,&mm,NULL);CHKERRQ(ierr); 2271e07b27eSBarry Smith ierr = MatCreateMPIMatConcatenateSeqMat(subcomm,Blocal,mm,reuse,&Bred);CHKERRQ(ierr); 2281e07b27eSBarry Smith } 2291e07b27eSBarry Smith *A = Bred; 2301e07b27eSBarry Smith ierr = ISDestroy(&iscol);CHKERRQ(ierr); 2311e07b27eSBarry Smith ierr = MatDestroy(&Blocal);CHKERRQ(ierr); 2321e07b27eSBarry Smith PetscFunctionReturn(0); 2331e07b27eSBarry Smith } 2341e07b27eSBarry Smith 235392968a1SPatrick Sanan static PetscErrorCode PCTelescopeSubNullSpaceCreate_Telescope(PC pc,PC_Telescope sred,MatNullSpace nullspace,MatNullSpace *sub_nullspace) 2361e07b27eSBarry Smith { 2371e07b27eSBarry Smith PetscErrorCode ierr; 2381e07b27eSBarry Smith PetscBool has_const; 2391e07b27eSBarry Smith const Vec *vecs; 240c41e779fSDave May Vec *sub_vecs = NULL; 241392968a1SPatrick Sanan PetscInt i,k,n = 0; 2421e07b27eSBarry Smith MPI_Comm subcomm; 2431e07b27eSBarry Smith 2441e07b27eSBarry Smith PetscFunctionBegin; 2451e07b27eSBarry Smith subcomm = PetscSubcommChild(sred->psubcomm); 2461e07b27eSBarry Smith ierr = MatNullSpaceGetVecs(nullspace,&has_const,&n,&vecs);CHKERRQ(ierr); 2471e07b27eSBarry Smith 24857f12427SDave May if (PCTelescope_isActiveRank(sred)) { 249e3acf2f7SBarry Smith if (n) { 250e3acf2f7SBarry Smith ierr = VecDuplicateVecs(sred->xred,n,&sub_vecs);CHKERRQ(ierr); 2511e07b27eSBarry Smith } 2521e07b27eSBarry Smith } 2531e07b27eSBarry Smith 2541e07b27eSBarry Smith /* copy entries */ 2551e07b27eSBarry Smith for (k=0; k<n; k++) { 2561e07b27eSBarry Smith const PetscScalar *x_array; 2571e07b27eSBarry Smith PetscScalar *LA_sub_vec; 25813c30530SDave May PetscInt st,ed; 2591e07b27eSBarry Smith 2601e07b27eSBarry Smith /* pull in vector x->xtmp */ 2611e07b27eSBarry Smith ierr = VecScatterBegin(sred->scatter,vecs[k],sred->xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 2621e07b27eSBarry Smith ierr = VecScatterEnd(sred->scatter,vecs[k],sred->xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 26347856c66SBarry Smith if (sub_vecs) { 264a04a6428SPatrick Sanan /* copy vector entries into xred */ 2651e07b27eSBarry Smith ierr = VecGetArrayRead(sred->xtmp,&x_array);CHKERRQ(ierr); 266ea2b237eSDave May if (sub_vecs[k]) { 2671e07b27eSBarry Smith ierr = VecGetOwnershipRange(sub_vecs[k],&st,&ed);CHKERRQ(ierr); 2681e07b27eSBarry Smith ierr = VecGetArray(sub_vecs[k],&LA_sub_vec);CHKERRQ(ierr); 2691e07b27eSBarry Smith for (i=0; i<ed-st; i++) { 2701e07b27eSBarry Smith LA_sub_vec[i] = x_array[i]; 2711e07b27eSBarry Smith } 2721e07b27eSBarry Smith ierr = VecRestoreArray(sub_vecs[k],&LA_sub_vec);CHKERRQ(ierr); 2731e07b27eSBarry Smith } 2741e07b27eSBarry Smith ierr = VecRestoreArrayRead(sred->xtmp,&x_array);CHKERRQ(ierr); 2751e07b27eSBarry Smith } 27647856c66SBarry Smith } 2771e07b27eSBarry Smith 27857f12427SDave May if (PCTelescope_isActiveRank(sred)) { 279d8b9d5b7SPatrick Sanan /* create new (near) nullspace for redundant object */ 280392968a1SPatrick Sanan ierr = MatNullSpaceCreate(subcomm,has_const,n,sub_vecs,sub_nullspace);CHKERRQ(ierr); 281392968a1SPatrick Sanan ierr = VecDestroyVecs(n,&sub_vecs);CHKERRQ(ierr); 282d8b9d5b7SPatrick Sanan if (nullspace->remove) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Propagation of custom remove callbacks not supported when propagating (near) nullspaces with PCTelescope"); 283d8b9d5b7SPatrick Sanan if (nullspace->rmctx) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Propagation of custom remove callback context not supported when propagating (near) nullspaces with PCTelescope"); 284d8b9d5b7SPatrick Sanan } 285392968a1SPatrick Sanan PetscFunctionReturn(0); 286392968a1SPatrick Sanan } 287392968a1SPatrick Sanan 288392968a1SPatrick Sanan static PetscErrorCode PCTelescopeMatNullSpaceCreate_default(PC pc,PC_Telescope sred,Mat sub_mat) 289392968a1SPatrick Sanan { 290392968a1SPatrick Sanan PetscErrorCode ierr; 291392968a1SPatrick Sanan Mat B; 292392968a1SPatrick Sanan 293392968a1SPatrick Sanan PetscFunctionBegin; 294392968a1SPatrick Sanan ierr = PCGetOperators(pc,NULL,&B);CHKERRQ(ierr); 295392968a1SPatrick Sanan /* Propagate the nullspace if it exists */ 296392968a1SPatrick Sanan { 297392968a1SPatrick Sanan MatNullSpace nullspace,sub_nullspace; 298392968a1SPatrick Sanan ierr = MatGetNullSpace(B,&nullspace);CHKERRQ(ierr); 299392968a1SPatrick Sanan if (nullspace) { 300392968a1SPatrick Sanan ierr = PetscInfo(pc,"PCTelescope: generating nullspace (default)\n");CHKERRQ(ierr); 301392968a1SPatrick Sanan ierr = PCTelescopeSubNullSpaceCreate_Telescope(pc,sred,nullspace,&sub_nullspace);CHKERRQ(ierr); 30257f12427SDave May if (PCTelescope_isActiveRank(sred)) { 303392968a1SPatrick Sanan ierr = MatSetNullSpace(sub_mat,sub_nullspace);CHKERRQ(ierr); 30441ff1ee9SPatrick Sanan ierr = MatNullSpaceDestroy(&sub_nullspace);CHKERRQ(ierr); 3051e07b27eSBarry Smith } 306392968a1SPatrick Sanan } 307392968a1SPatrick Sanan } 308392968a1SPatrick Sanan /* Propagate the near nullspace if it exists */ 309392968a1SPatrick Sanan { 310392968a1SPatrick Sanan MatNullSpace nearnullspace,sub_nearnullspace; 311392968a1SPatrick Sanan ierr = MatGetNearNullSpace(B,&nearnullspace);CHKERRQ(ierr); 312392968a1SPatrick Sanan if (nearnullspace) { 313392968a1SPatrick Sanan ierr = PetscInfo(pc,"PCTelescope: generating near nullspace (default)\n");CHKERRQ(ierr); 314392968a1SPatrick Sanan ierr = PCTelescopeSubNullSpaceCreate_Telescope(pc,sred,nearnullspace,&sub_nearnullspace);CHKERRQ(ierr); 31557f12427SDave May if (PCTelescope_isActiveRank(sred)) { 316392968a1SPatrick Sanan ierr = MatSetNearNullSpace(sub_mat,sub_nearnullspace);CHKERRQ(ierr); 317392968a1SPatrick Sanan ierr = MatNullSpaceDestroy(&sub_nearnullspace);CHKERRQ(ierr); 318392968a1SPatrick Sanan } 319392968a1SPatrick Sanan } 320392968a1SPatrick Sanan } 3211e07b27eSBarry Smith PetscFunctionReturn(0); 3221e07b27eSBarry Smith } 3231e07b27eSBarry Smith 3241e07b27eSBarry Smith static PetscErrorCode PCView_Telescope(PC pc,PetscViewer viewer) 3251e07b27eSBarry Smith { 3261e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 3271e07b27eSBarry Smith PetscErrorCode ierr; 3281e07b27eSBarry Smith PetscBool iascii,isstring; 3291e07b27eSBarry Smith PetscViewer subviewer; 3301e07b27eSBarry Smith 3311e07b27eSBarry Smith PetscFunctionBegin; 3321e07b27eSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 3331e07b27eSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring);CHKERRQ(ierr); 3341e07b27eSBarry Smith if (iascii) { 3358d9f7141SDave May { 3361e07b27eSBarry Smith MPI_Comm comm,subcomm; 3371e07b27eSBarry Smith PetscMPIInt comm_size,subcomm_size; 3388d9f7141SDave May DM dm = NULL,subdm = NULL; 3391e07b27eSBarry Smith 3401e07b27eSBarry Smith ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 3411e07b27eSBarry Smith subdm = private_PCTelescopeGetSubDM(sred); 3428d9f7141SDave May 3438d9f7141SDave May if (sred->psubcomm) { 3441e07b27eSBarry Smith comm = PetscSubcommParent(sred->psubcomm); 3451e07b27eSBarry Smith subcomm = PetscSubcommChild(sred->psubcomm); 346ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&comm_size);CHKERRMPI(ierr); 347ffc4695bSBarry Smith ierr = MPI_Comm_size(subcomm,&subcomm_size);CHKERRMPI(ierr); 3481e07b27eSBarry Smith 3498d9f7141SDave May ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3508d9f7141SDave May ierr = PetscViewerASCIIPrintf(viewer,"petsc subcomm: parent comm size reduction factor = %D\n",sred->redfactor);CHKERRQ(ierr); 3518d9f7141SDave May ierr = PetscViewerASCIIPrintf(viewer,"petsc subcomm: parent_size = %d , subcomm_size = %d\n",(int)comm_size,(int)subcomm_size);CHKERRQ(ierr); 35248a10b22SPatrick Sanan switch (sred->subcommtype) { 35348a10b22SPatrick Sanan case PETSC_SUBCOMM_INTERLACED : 3548d9f7141SDave May ierr = PetscViewerASCIIPrintf(viewer,"petsc subcomm: type = interlaced\n",sred->subcommtype);CHKERRQ(ierr); 35548a10b22SPatrick Sanan break; 35648a10b22SPatrick Sanan case PETSC_SUBCOMM_CONTIGUOUS : 3578d9f7141SDave May ierr = PetscViewerASCIIPrintf(viewer,"petsc subcomm type = contiguous\n",sred->subcommtype);CHKERRQ(ierr); 35848a10b22SPatrick Sanan break; 35948a10b22SPatrick Sanan default : 36048a10b22SPatrick Sanan SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"General subcomm type not supported by PCTelescope"); 36148a10b22SPatrick Sanan } 3628d9f7141SDave May ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 3638d9f7141SDave May } else { 3648d9f7141SDave May ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 3658d9f7141SDave May subcomm = sred->subcomm; 36657f12427SDave May if (!PCTelescope_isActiveRank(sred)) { 3678d9f7141SDave May subcomm = PETSC_COMM_SELF; 3688d9f7141SDave May } 3698d9f7141SDave May 3708d9f7141SDave May ierr = PetscViewerASCIIPushTab(viewer);CHKERRQ(ierr); 3718d9f7141SDave May ierr = PetscViewerASCIIPrintf(viewer,"subcomm: using user provided sub-communicator\n");CHKERRQ(ierr); 3728d9f7141SDave May ierr = PetscViewerASCIIPopTab(viewer);CHKERRQ(ierr); 3738d9f7141SDave May } 3748d9f7141SDave May 3751e07b27eSBarry Smith ierr = PetscViewerGetSubViewer(viewer,subcomm,&subviewer);CHKERRQ(ierr); 37657f12427SDave May if (PCTelescope_isActiveRank(sred)) { 3771e07b27eSBarry Smith ierr = PetscViewerASCIIPushTab(subviewer);CHKERRQ(ierr); 3781e07b27eSBarry Smith 3791e07b27eSBarry Smith if (dm && sred->ignore_dm) { 380efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(subviewer,"ignoring DM\n");CHKERRQ(ierr); 3811e07b27eSBarry Smith } 3827c5279cbSDave May if (sred->ignore_kspcomputeoperators) { 383efd4aadfSBarry Smith ierr = PetscViewerASCIIPrintf(subviewer,"ignoring KSPComputeOperators\n");CHKERRQ(ierr); 3847c5279cbSDave May } 3851e07b27eSBarry Smith switch (sred->sr_type) { 3861e07b27eSBarry Smith case TELESCOPE_DEFAULT: 3878d9f7141SDave May ierr = PetscViewerASCIIPrintf(subviewer,"setup type: default\n");CHKERRQ(ierr); 3881e07b27eSBarry Smith break; 3891e07b27eSBarry Smith case TELESCOPE_DMDA: 3908d9f7141SDave May ierr = PetscViewerASCIIPrintf(subviewer,"setup type: DMDA auto-repartitioning\n");CHKERRQ(ierr); 3918ef9ca65SPatrick Sanan ierr = DMView_DA_Short(subdm,subviewer);CHKERRQ(ierr); 3921e07b27eSBarry Smith break; 3931e07b27eSBarry Smith case TELESCOPE_DMPLEX: 3948d9f7141SDave May ierr = PetscViewerASCIIPrintf(subviewer,"setup type: DMPLEX auto-repartitioning\n");CHKERRQ(ierr); 3951e07b27eSBarry Smith break; 3968d9f7141SDave May case TELESCOPE_COARSEDM: 3978d9f7141SDave May ierr = PetscViewerASCIIPrintf(subviewer,"setup type: coarse DM\n");CHKERRQ(ierr); 3988d9f7141SDave May break; 3998d9f7141SDave May } 4008d9f7141SDave May 4018d9f7141SDave May if (dm) { 4028d9f7141SDave May PetscObject obj = (PetscObject)dm; 4038d9f7141SDave May ierr = PetscViewerASCIIPrintf(subviewer,"Parent DM object:");CHKERRQ(ierr); 4048d9f7141SDave May PetscViewerASCIIUseTabs(subviewer,PETSC_FALSE); 4058d9f7141SDave May if (obj->type_name) { PetscViewerASCIIPrintf(subviewer," type = %s;",obj->type_name); } 4068d9f7141SDave May if (obj->name) { PetscViewerASCIIPrintf(subviewer," name = %s;",obj->name); } 4078d9f7141SDave May if (obj->prefix) { PetscViewerASCIIPrintf(subviewer," prefix = %s",obj->prefix); } 4088d9f7141SDave May ierr = PetscViewerASCIIPrintf(subviewer,"\n");CHKERRQ(ierr); 4098d9f7141SDave May PetscViewerASCIIUseTabs(subviewer,PETSC_TRUE); 4108d9f7141SDave May } else { 4118d9f7141SDave May ierr = PetscViewerASCIIPrintf(subviewer,"Parent DM object: NULL\n");CHKERRQ(ierr); 4128d9f7141SDave May } 4138d9f7141SDave May if (subdm) { 4148d9f7141SDave May PetscObject obj = (PetscObject)subdm; 4158d9f7141SDave May ierr = PetscViewerASCIIPrintf(subviewer,"Sub DM object:");CHKERRQ(ierr); 4168d9f7141SDave May PetscViewerASCIIUseTabs(subviewer,PETSC_FALSE); 4178d9f7141SDave May if (obj->type_name) { PetscViewerASCIIPrintf(subviewer," type = %s;",obj->type_name); } 4188d9f7141SDave May if (obj->name) { PetscViewerASCIIPrintf(subviewer," name = %s;",obj->name); } 4198d9f7141SDave May if (obj->prefix) { PetscViewerASCIIPrintf(subviewer," prefix = %s",obj->prefix); } 4208d9f7141SDave May ierr = PetscViewerASCIIPrintf(subviewer,"\n");CHKERRQ(ierr); 4218d9f7141SDave May PetscViewerASCIIUseTabs(subviewer,PETSC_TRUE); 4228d9f7141SDave May } else { 4238d9f7141SDave May ierr = PetscViewerASCIIPrintf(subviewer,"Sub DM object: NULL\n");CHKERRQ(ierr); 4241e07b27eSBarry Smith } 4251e07b27eSBarry Smith 4261e07b27eSBarry Smith ierr = KSPView(sred->ksp,subviewer);CHKERRQ(ierr); 4271e07b27eSBarry Smith ierr = PetscViewerASCIIPopTab(subviewer);CHKERRQ(ierr); 4281e07b27eSBarry Smith } 4291e07b27eSBarry Smith ierr = PetscViewerRestoreSubViewer(viewer,subcomm,&subviewer);CHKERRQ(ierr); 4301e07b27eSBarry Smith } 4311e07b27eSBarry Smith } 4321e07b27eSBarry Smith PetscFunctionReturn(0); 4331e07b27eSBarry Smith } 4341e07b27eSBarry Smith 4351e07b27eSBarry Smith static PetscErrorCode PCSetUp_Telescope(PC pc) 4361e07b27eSBarry Smith { 4371e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 4381e07b27eSBarry Smith PetscErrorCode ierr; 439bd49479cSSatish Balay MPI_Comm comm,subcomm=0; 4401e07b27eSBarry Smith PCTelescopeType sr_type; 4411e07b27eSBarry Smith 4421e07b27eSBarry Smith PetscFunctionBegin; 4431e07b27eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 4441e07b27eSBarry Smith 4451e07b27eSBarry Smith /* Determine type of setup/update */ 4461e07b27eSBarry Smith if (!pc->setupcalled) { 4471e07b27eSBarry Smith PetscBool has_dm,same; 4481e07b27eSBarry Smith DM dm; 4491e07b27eSBarry Smith 4501e07b27eSBarry Smith sr_type = TELESCOPE_DEFAULT; 4511e07b27eSBarry Smith has_dm = PETSC_FALSE; 4521e07b27eSBarry Smith ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 4531e07b27eSBarry Smith if (dm) { has_dm = PETSC_TRUE; } 4541e07b27eSBarry Smith if (has_dm) { 4551e07b27eSBarry Smith /* check for dmda */ 4561e07b27eSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&same);CHKERRQ(ierr); 4571e07b27eSBarry Smith if (same) { 4581e07b27eSBarry Smith ierr = PetscInfo(pc,"PCTelescope: found DMDA\n");CHKERRQ(ierr); 4591e07b27eSBarry Smith sr_type = TELESCOPE_DMDA; 4601e07b27eSBarry Smith } 4611e07b27eSBarry Smith /* check for dmplex */ 4621e07b27eSBarry Smith ierr = PetscObjectTypeCompare((PetscObject)dm,DMPLEX,&same);CHKERRQ(ierr); 4631e07b27eSBarry Smith if (same) { 464994fe344SLisandro Dalcin ierr = PetscInfo(pc,"PCTelescope: found DMPLEX\n");CHKERRQ(ierr); 4651e07b27eSBarry Smith sr_type = TELESCOPE_DMPLEX; 4661e07b27eSBarry Smith } 4678d9f7141SDave May 4688d9f7141SDave May if (sred->use_coarse_dm) { 4698d9f7141SDave May ierr = PetscInfo(pc,"PCTelescope: using coarse DM\n");CHKERRQ(ierr); 4708d9f7141SDave May sr_type = TELESCOPE_COARSEDM; 4711e07b27eSBarry Smith } 4721e07b27eSBarry Smith 4731e07b27eSBarry Smith if (sred->ignore_dm) { 4748d9f7141SDave May ierr = PetscInfo(pc,"PCTelescope: ignoring DM\n");CHKERRQ(ierr); 4751e07b27eSBarry Smith sr_type = TELESCOPE_DEFAULT; 4761e07b27eSBarry Smith } 4778d9f7141SDave May } 4781e07b27eSBarry Smith sred->sr_type = sr_type; 4791e07b27eSBarry Smith } else { 4801e07b27eSBarry Smith sr_type = sred->sr_type; 4811e07b27eSBarry Smith } 4821e07b27eSBarry Smith 483d8b9d5b7SPatrick Sanan /* set function pointers for repartition setup, matrix creation/update, matrix (near) nullspace, and reset functionality */ 4841e07b27eSBarry Smith switch (sr_type) { 4851e07b27eSBarry Smith case TELESCOPE_DEFAULT: 4861e07b27eSBarry Smith sred->pctelescope_setup_type = PCTelescopeSetUp_default; 4871e07b27eSBarry Smith sred->pctelescope_matcreate_type = PCTelescopeMatCreate_default; 4881e07b27eSBarry Smith sred->pctelescope_matnullspacecreate_type = PCTelescopeMatNullSpaceCreate_default; 4891e07b27eSBarry Smith sred->pctelescope_reset_type = NULL; 4901e07b27eSBarry Smith break; 4911e07b27eSBarry Smith case TELESCOPE_DMDA: 4921e07b27eSBarry Smith pc->ops->apply = PCApply_Telescope_dmda; 493f650675bSDave May pc->ops->applyrichardson = PCApplyRichardson_Telescope_dmda; 4941e07b27eSBarry Smith sred->pctelescope_setup_type = PCTelescopeSetUp_dmda; 4951e07b27eSBarry Smith sred->pctelescope_matcreate_type = PCTelescopeMatCreate_dmda; 4961e07b27eSBarry Smith sred->pctelescope_matnullspacecreate_type = PCTelescopeMatNullSpaceCreate_dmda; 4971e07b27eSBarry Smith sred->pctelescope_reset_type = PCReset_Telescope_dmda; 4981e07b27eSBarry Smith break; 499b458e8f1SJose E. Roman case TELESCOPE_DMPLEX: 500b458e8f1SJose E. Roman SETERRQ(comm,PETSC_ERR_SUP,"Support for DMPLEX is currently not available"); 5018d9f7141SDave May case TELESCOPE_COARSEDM: 5028d9f7141SDave May pc->ops->apply = PCApply_Telescope_CoarseDM; 5038d9f7141SDave May pc->ops->applyrichardson = PCApplyRichardson_Telescope_CoarseDM; 5048d9f7141SDave May sred->pctelescope_setup_type = PCTelescopeSetUp_CoarseDM; 5058d9f7141SDave May sred->pctelescope_matcreate_type = NULL; 5068d9f7141SDave May sred->pctelescope_matnullspacecreate_type = NULL; /* PCTelescopeMatNullSpaceCreate_CoarseDM; */ 5078d9f7141SDave May sred->pctelescope_reset_type = PCReset_Telescope_CoarseDM; 5081e07b27eSBarry Smith break; 509b458e8f1SJose E. Roman default: 510b458e8f1SJose E. Roman SETERRQ(comm,PETSC_ERR_SUP,"Support only provided for: repartitioning an operator; repartitioning a DMDA; or using a coarse DM"); 5118d9f7141SDave May } 5128d9f7141SDave May 5138d9f7141SDave May /* subcomm definition */ 5148d9f7141SDave May if (!pc->setupcalled) { 5158d9f7141SDave May if ((sr_type == TELESCOPE_DEFAULT) || (sr_type == TELESCOPE_DMDA)) { 5168d9f7141SDave May if (!sred->psubcomm) { 5178d9f7141SDave May ierr = PetscSubcommCreate(comm,&sred->psubcomm);CHKERRQ(ierr); 5188d9f7141SDave May ierr = PetscSubcommSetNumber(sred->psubcomm,sred->redfactor);CHKERRQ(ierr); 5198d9f7141SDave May ierr = PetscSubcommSetType(sred->psubcomm,sred->subcommtype);CHKERRQ(ierr); 5208d9f7141SDave May ierr = PetscLogObjectMemory((PetscObject)pc,sizeof(PetscSubcomm));CHKERRQ(ierr); 5218d9f7141SDave May sred->subcomm = PetscSubcommChild(sred->psubcomm); 5228d9f7141SDave May } 5238d9f7141SDave May } else { /* query PC for DM, check communicators */ 5248d9f7141SDave May DM dm,dm_coarse_partition = NULL; 5258d9f7141SDave May MPI_Comm comm_fine,comm_coarse_partition = MPI_COMM_NULL; 5268d9f7141SDave May PetscMPIInt csize_fine=0,csize_coarse_partition=0,cs[2],csg[2],cnt=0; 5278d9f7141SDave May PetscBool isvalidsubcomm; 5288d9f7141SDave May 5298d9f7141SDave May ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 5308d9f7141SDave May comm_fine = PetscObjectComm((PetscObject)dm); 5318d9f7141SDave May ierr = DMGetCoarseDM(dm,&dm_coarse_partition);CHKERRQ(ierr); 5328d9f7141SDave May if (dm_coarse_partition) { cnt = 1; } 533ffc4695bSBarry Smith ierr = MPI_Allreduce(MPI_IN_PLACE,&cnt,1,MPI_INT,MPI_SUM,comm_fine);CHKERRMPI(ierr); 5348d9f7141SDave May if (cnt == 0) SETERRQ(comm_fine,PETSC_ERR_SUP,"Zero instances of a coarse DM were found"); 5358d9f7141SDave May 536ffc4695bSBarry Smith ierr = MPI_Comm_size(comm_fine,&csize_fine);CHKERRMPI(ierr); 5378d9f7141SDave May if (dm_coarse_partition) { 5388d9f7141SDave May comm_coarse_partition = PetscObjectComm((PetscObject)dm_coarse_partition); 539ffc4695bSBarry Smith ierr = MPI_Comm_size(comm_coarse_partition,&csize_coarse_partition);CHKERRMPI(ierr); 5408d9f7141SDave May } 5418d9f7141SDave May 5428d9f7141SDave May cs[0] = csize_fine; 5438d9f7141SDave May cs[1] = csize_coarse_partition; 544ffc4695bSBarry Smith ierr = MPI_Allreduce(cs,csg,2,MPI_INT,MPI_MAX,comm_fine);CHKERRMPI(ierr); 5458d9f7141SDave May if (csg[0] == csg[1]) SETERRQ(comm_fine,PETSC_ERR_SUP,"Coarse DM uses the same size communicator as the parent DM attached to the PC"); 5468d9f7141SDave May 5478d9f7141SDave May ierr = PCTelescopeTestValidSubcomm(comm_fine,comm_coarse_partition,&isvalidsubcomm);CHKERRQ(ierr); 5488d9f7141SDave May if (!isvalidsubcomm) SETERRQ(comm_fine,PETSC_ERR_SUP,"Coarse DM communicator is not a sub-communicator of parentDM->comm"); 5498d9f7141SDave May sred->subcomm = comm_coarse_partition; 5508d9f7141SDave May } 5518d9f7141SDave May } 5528d9f7141SDave May subcomm = sred->subcomm; 5538d9f7141SDave May 5548d9f7141SDave May /* internal KSP */ 5558d9f7141SDave May if (!pc->setupcalled) { 5568d9f7141SDave May const char *prefix; 5578d9f7141SDave May 55857f12427SDave May if (PCTelescope_isActiveRank(sred)) { 5598d9f7141SDave May ierr = KSPCreate(subcomm,&sred->ksp);CHKERRQ(ierr); 5608d9f7141SDave May ierr = KSPSetErrorIfNotConverged(sred->ksp,pc->erroriffailure);CHKERRQ(ierr); 5618d9f7141SDave May ierr = PetscObjectIncrementTabLevel((PetscObject)sred->ksp,(PetscObject)pc,1);CHKERRQ(ierr); 5628d9f7141SDave May ierr = PetscLogObjectParent((PetscObject)pc,(PetscObject)sred->ksp);CHKERRQ(ierr); 5638d9f7141SDave May ierr = KSPSetType(sred->ksp,KSPPREONLY);CHKERRQ(ierr); 5648d9f7141SDave May ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); 5658d9f7141SDave May ierr = KSPSetOptionsPrefix(sred->ksp,prefix);CHKERRQ(ierr); 5668d9f7141SDave May ierr = KSPAppendOptionsPrefix(sred->ksp,"telescope_");CHKERRQ(ierr); 5678d9f7141SDave May } 5681e07b27eSBarry Smith } 5691e07b27eSBarry Smith 5701e07b27eSBarry Smith /* setup */ 571aaa7a805SDave May if (!pc->setupcalled && sred->pctelescope_setup_type) { 5721e07b27eSBarry Smith ierr = sred->pctelescope_setup_type(pc,sred);CHKERRQ(ierr); 5731e07b27eSBarry Smith } 5741e07b27eSBarry Smith /* update */ 5751e07b27eSBarry Smith if (!pc->setupcalled) { 5761e07b27eSBarry Smith if (sred->pctelescope_matcreate_type) { 5771e07b27eSBarry Smith ierr = sred->pctelescope_matcreate_type(pc,sred,MAT_INITIAL_MATRIX,&sred->Bred);CHKERRQ(ierr); 5781e07b27eSBarry Smith } 5791e07b27eSBarry Smith if (sred->pctelescope_matnullspacecreate_type) { 580392968a1SPatrick Sanan ierr = sred->pctelescope_matnullspacecreate_type(pc,sred,sred->Bred);CHKERRQ(ierr); 5811e07b27eSBarry Smith } 5821e07b27eSBarry Smith } else { 5831e07b27eSBarry Smith if (sred->pctelescope_matcreate_type) { 5841e07b27eSBarry Smith ierr = sred->pctelescope_matcreate_type(pc,sred,MAT_REUSE_MATRIX,&sred->Bred);CHKERRQ(ierr); 5851e07b27eSBarry Smith } 5861e07b27eSBarry Smith } 5871e07b27eSBarry Smith 5881e07b27eSBarry Smith /* common - no construction */ 58957f12427SDave May if (PCTelescope_isActiveRank(sred)) { 5901e07b27eSBarry Smith ierr = KSPSetOperators(sred->ksp,sred->Bred,sred->Bred);CHKERRQ(ierr); 5911e07b27eSBarry Smith if (pc->setfromoptionscalled && !pc->setupcalled) { 5921e07b27eSBarry Smith ierr = KSPSetFromOptions(sred->ksp);CHKERRQ(ierr); 5931e07b27eSBarry Smith } 5941e07b27eSBarry Smith } 5951e07b27eSBarry Smith PetscFunctionReturn(0); 5961e07b27eSBarry Smith } 5971e07b27eSBarry Smith 5981e07b27eSBarry Smith static PetscErrorCode PCApply_Telescope(PC pc,Vec x,Vec y) 5991e07b27eSBarry Smith { 6001e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 6011e07b27eSBarry Smith PetscErrorCode ierr; 6021e07b27eSBarry Smith Vec xtmp,xred,yred; 60313c30530SDave May PetscInt i,st,ed; 6041e07b27eSBarry Smith VecScatter scatter; 6051e07b27eSBarry Smith PetscScalar *array; 6061e07b27eSBarry Smith const PetscScalar *x_array; 6071e07b27eSBarry Smith 6081e07b27eSBarry Smith PetscFunctionBegin; 609bf00f589SPatrick Sanan ierr = PetscCitationsRegister(citation,&cited);CHKERRQ(ierr); 610bf00f589SPatrick Sanan 6111e07b27eSBarry Smith xtmp = sred->xtmp; 6121e07b27eSBarry Smith scatter = sred->scatter; 6131e07b27eSBarry Smith xred = sred->xred; 6141e07b27eSBarry Smith yred = sred->yred; 6151e07b27eSBarry Smith 6161e07b27eSBarry Smith /* pull in vector x->xtmp */ 6171e07b27eSBarry Smith ierr = VecScatterBegin(scatter,x,xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6181e07b27eSBarry Smith ierr = VecScatterEnd(scatter,x,xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6191e07b27eSBarry Smith 620bf00f589SPatrick Sanan /* copy vector entries into xred */ 6211e07b27eSBarry Smith ierr = VecGetArrayRead(xtmp,&x_array);CHKERRQ(ierr); 6221e07b27eSBarry Smith if (xred) { 6231e07b27eSBarry Smith PetscScalar *LA_xred; 6241e07b27eSBarry Smith ierr = VecGetOwnershipRange(xred,&st,&ed);CHKERRQ(ierr); 6251e07b27eSBarry Smith ierr = VecGetArray(xred,&LA_xred);CHKERRQ(ierr); 6261e07b27eSBarry Smith for (i=0; i<ed-st; i++) { 6271e07b27eSBarry Smith LA_xred[i] = x_array[i]; 6281e07b27eSBarry Smith } 6291e07b27eSBarry Smith ierr = VecRestoreArray(xred,&LA_xred);CHKERRQ(ierr); 6301e07b27eSBarry Smith } 6311e07b27eSBarry Smith ierr = VecRestoreArrayRead(xtmp,&x_array);CHKERRQ(ierr); 6321e07b27eSBarry Smith /* solve */ 63357f12427SDave May if (PCTelescope_isActiveRank(sred)) { 6341e07b27eSBarry Smith ierr = KSPSolve(sred->ksp,xred,yred);CHKERRQ(ierr); 635c0decd05SBarry Smith ierr = KSPCheckSolve(sred->ksp,pc,yred);CHKERRQ(ierr); 6361e07b27eSBarry Smith } 6371e07b27eSBarry Smith /* return vector */ 6381e07b27eSBarry Smith ierr = VecGetArray(xtmp,&array);CHKERRQ(ierr); 6391e07b27eSBarry Smith if (yred) { 6401e07b27eSBarry Smith const PetscScalar *LA_yred; 6411e07b27eSBarry Smith ierr = VecGetOwnershipRange(yred,&st,&ed);CHKERRQ(ierr); 6421e07b27eSBarry Smith ierr = VecGetArrayRead(yred,&LA_yred);CHKERRQ(ierr); 6431e07b27eSBarry Smith for (i=0; i<ed-st; i++) { 6441e07b27eSBarry Smith array[i] = LA_yred[i]; 6451e07b27eSBarry Smith } 6461e07b27eSBarry Smith ierr = VecRestoreArrayRead(yred,&LA_yred);CHKERRQ(ierr); 6471e07b27eSBarry Smith } 6481e07b27eSBarry Smith ierr = VecRestoreArray(xtmp,&array);CHKERRQ(ierr); 6491e07b27eSBarry Smith ierr = VecScatterBegin(scatter,xtmp,y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6501e07b27eSBarry Smith ierr = VecScatterEnd(scatter,xtmp,y,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6511e07b27eSBarry Smith PetscFunctionReturn(0); 6521e07b27eSBarry Smith } 6531e07b27eSBarry Smith 654f650675bSDave 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) 655f650675bSDave May { 656f650675bSDave May PC_Telescope sred = (PC_Telescope)pc->data; 657f650675bSDave May PetscErrorCode ierr; 658a1d91a28SDave May Vec xtmp,yred; 659f650675bSDave May PetscInt i,st,ed; 660f650675bSDave May VecScatter scatter; 661f650675bSDave May const PetscScalar *x_array; 662f650675bSDave May PetscBool default_init_guess_value; 663f650675bSDave May 664f650675bSDave May PetscFunctionBegin; 665f650675bSDave May xtmp = sred->xtmp; 666f650675bSDave May scatter = sred->scatter; 667f650675bSDave May yred = sred->yred; 668f650675bSDave May 669f650675bSDave May if (its > 1) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"PCApplyRichardson_Telescope only supports max_it = 1"); 670f650675bSDave May *reason = (PCRichardsonConvergedReason)0; 671f650675bSDave May 672f650675bSDave May if (!zeroguess) { 673f650675bSDave May ierr = PetscInfo(pc,"PCTelescope: Scattering y for non-zero initial guess\n");CHKERRQ(ierr); 674f650675bSDave May /* pull in vector y->xtmp */ 675f650675bSDave May ierr = VecScatterBegin(scatter,y,xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 676f650675bSDave May ierr = VecScatterEnd(scatter,y,xtmp,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 677f650675bSDave May 678bf00f589SPatrick Sanan /* copy vector entries into xred */ 679f650675bSDave May ierr = VecGetArrayRead(xtmp,&x_array);CHKERRQ(ierr); 680f650675bSDave May if (yred) { 681f650675bSDave May PetscScalar *LA_yred; 682f650675bSDave May ierr = VecGetOwnershipRange(yred,&st,&ed);CHKERRQ(ierr); 683f650675bSDave May ierr = VecGetArray(yred,&LA_yred);CHKERRQ(ierr); 684f650675bSDave May for (i=0; i<ed-st; i++) { 685f650675bSDave May LA_yred[i] = x_array[i]; 686f650675bSDave May } 687f650675bSDave May ierr = VecRestoreArray(yred,&LA_yred);CHKERRQ(ierr); 688f650675bSDave May } 689f650675bSDave May ierr = VecRestoreArrayRead(xtmp,&x_array);CHKERRQ(ierr); 690f650675bSDave May } 691f650675bSDave May 69257f12427SDave May if (PCTelescope_isActiveRank(sred)) { 693f650675bSDave May ierr = KSPGetInitialGuessNonzero(sred->ksp,&default_init_guess_value);CHKERRQ(ierr); 694f650675bSDave May if (!zeroguess) ierr = KSPSetInitialGuessNonzero(sred->ksp,PETSC_TRUE);CHKERRQ(ierr); 695f650675bSDave May } 696f650675bSDave May 697f650675bSDave May ierr = PCApply_Telescope(pc,x,y);CHKERRQ(ierr); 698f650675bSDave May 69957f12427SDave May if (PCTelescope_isActiveRank(sred)) { 700f650675bSDave May ierr = KSPSetInitialGuessNonzero(sred->ksp,default_init_guess_value);CHKERRQ(ierr); 701f650675bSDave May } 702f650675bSDave May 703f650675bSDave May if (!*reason) *reason = PCRICHARDSON_CONVERGED_ITS; 704f650675bSDave May *outits = 1; 705f650675bSDave May PetscFunctionReturn(0); 706f650675bSDave May } 707f650675bSDave May 7081e07b27eSBarry Smith static PetscErrorCode PCReset_Telescope(PC pc) 7091e07b27eSBarry Smith { 7101e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 7111e07b27eSBarry Smith PetscErrorCode ierr; 7121e07b27eSBarry Smith 713362febeeSStefano Zampini PetscFunctionBegin; 7141e07b27eSBarry Smith ierr = ISDestroy(&sred->isin);CHKERRQ(ierr); 7151e07b27eSBarry Smith ierr = VecScatterDestroy(&sred->scatter);CHKERRQ(ierr); 716e3acf2f7SBarry Smith ierr = VecDestroy(&sred->xred);CHKERRQ(ierr); 717e3acf2f7SBarry Smith ierr = VecDestroy(&sred->yred);CHKERRQ(ierr); 718e3acf2f7SBarry Smith ierr = VecDestroy(&sred->xtmp);CHKERRQ(ierr); 719e3acf2f7SBarry Smith ierr = MatDestroy(&sred->Bred);CHKERRQ(ierr); 720e3acf2f7SBarry Smith ierr = KSPReset(sred->ksp);CHKERRQ(ierr); 7211e07b27eSBarry Smith if (sred->pctelescope_reset_type) { 7221e07b27eSBarry Smith ierr = sred->pctelescope_reset_type(pc);CHKERRQ(ierr); 7231e07b27eSBarry Smith } 7241e07b27eSBarry Smith PetscFunctionReturn(0); 7251e07b27eSBarry Smith } 7261e07b27eSBarry Smith 7271e07b27eSBarry Smith static PetscErrorCode PCDestroy_Telescope(PC pc) 7281e07b27eSBarry Smith { 7291e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 7301e07b27eSBarry Smith PetscErrorCode ierr; 7311e07b27eSBarry Smith 7321e07b27eSBarry Smith PetscFunctionBegin; 7331e07b27eSBarry Smith ierr = PCReset_Telescope(pc);CHKERRQ(ierr); 734e3acf2f7SBarry Smith ierr = KSPDestroy(&sred->ksp);CHKERRQ(ierr); 7351e07b27eSBarry Smith ierr = PetscSubcommDestroy(&sred->psubcomm);CHKERRQ(ierr); 736e3acf2f7SBarry Smith ierr = PetscFree(sred->dm_ctx);CHKERRQ(ierr); 737e3acf2f7SBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 7381e07b27eSBarry Smith PetscFunctionReturn(0); 7391e07b27eSBarry Smith } 7401e07b27eSBarry Smith 7414416b707SBarry Smith static PetscErrorCode PCSetFromOptions_Telescope(PetscOptionItems *PetscOptionsObject,PC pc) 7421e07b27eSBarry Smith { 7431e07b27eSBarry Smith PC_Telescope sred = (PC_Telescope)pc->data; 7441e07b27eSBarry Smith PetscErrorCode ierr; 7451e07b27eSBarry Smith MPI_Comm comm; 7461e07b27eSBarry Smith PetscMPIInt size; 74748a10b22SPatrick Sanan PetscBool flg; 74848a10b22SPatrick Sanan PetscSubcommType subcommtype; 7491e07b27eSBarry Smith 7501e07b27eSBarry Smith PetscFunctionBegin; 7511e07b27eSBarry Smith ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 752ffc4695bSBarry Smith ierr = MPI_Comm_size(comm,&size);CHKERRMPI(ierr); 7531e07b27eSBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"Telescope options");CHKERRQ(ierr); 75448a10b22SPatrick Sanan ierr = PetscOptionsEnum("-pc_telescope_subcomm_type","Subcomm type (interlaced or contiguous)","PCTelescopeSetSubcommType",PetscSubcommTypes,(PetscEnum)sred->subcommtype,(PetscEnum*)&subcommtype,&flg);CHKERRQ(ierr); 75548a10b22SPatrick Sanan if (flg) { 75648a10b22SPatrick Sanan ierr = PCTelescopeSetSubcommType(pc,subcommtype);CHKERRQ(ierr); 75748a10b22SPatrick Sanan } 7580a545947SLisandro Dalcin ierr = PetscOptionsInt("-pc_telescope_reduction_factor","Factor to reduce comm size by","PCTelescopeSetReductionFactor",sred->redfactor,&sred->redfactor,NULL);CHKERRQ(ierr); 7591e07b27eSBarry Smith if (sred->redfactor > size) SETERRQ(comm,PETSC_ERR_ARG_WRONG,"-pc_telescope_reduction_factor <= comm size"); 7600a545947SLisandro Dalcin ierr = PetscOptionsBool("-pc_telescope_ignore_dm","Ignore any DM attached to the PC","PCTelescopeSetIgnoreDM",sred->ignore_dm,&sred->ignore_dm,NULL);CHKERRQ(ierr); 7610a545947SLisandro Dalcin ierr = PetscOptionsBool("-pc_telescope_ignore_kspcomputeoperators","Ignore method used to compute A","PCTelescopeSetIgnoreKSPComputeOperators",sred->ignore_kspcomputeoperators,&sred->ignore_kspcomputeoperators,NULL);CHKERRQ(ierr); 7620a545947SLisandro Dalcin ierr = PetscOptionsBool("-pc_telescope_use_coarse_dm","Define sub-communicator from the coarse DM","PCTelescopeSetUseCoarseDM",sred->use_coarse_dm,&sred->use_coarse_dm,NULL);CHKERRQ(ierr); 7631e07b27eSBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 7641e07b27eSBarry Smith PetscFunctionReturn(0); 7651e07b27eSBarry Smith } 7661e07b27eSBarry Smith 7671e07b27eSBarry Smith /* PC simplementation specific API's */ 7681e07b27eSBarry Smith 7691e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetKSP_Telescope(PC pc,KSP *ksp) 7701e07b27eSBarry Smith { 7711e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 772bd49479cSSatish Balay PetscFunctionBegin; 7731e07b27eSBarry Smith if (ksp) *ksp = red->ksp; 774bd49479cSSatish Balay PetscFunctionReturn(0); 7751e07b27eSBarry Smith } 7761e07b27eSBarry Smith 77748a10b22SPatrick Sanan static PetscErrorCode PCTelescopeGetSubcommType_Telescope(PC pc,PetscSubcommType *subcommtype) 77848a10b22SPatrick Sanan { 77948a10b22SPatrick Sanan PC_Telescope red = (PC_Telescope)pc->data; 78048a10b22SPatrick Sanan PetscFunctionBegin; 78148a10b22SPatrick Sanan if (subcommtype) *subcommtype = red->subcommtype; 78248a10b22SPatrick Sanan PetscFunctionReturn(0); 78348a10b22SPatrick Sanan } 78448a10b22SPatrick Sanan 78548a10b22SPatrick Sanan static PetscErrorCode PCTelescopeSetSubcommType_Telescope(PC pc,PetscSubcommType subcommtype) 78648a10b22SPatrick Sanan { 78748a10b22SPatrick Sanan PC_Telescope red = (PC_Telescope)pc->data; 78848a10b22SPatrick Sanan 78948a10b22SPatrick Sanan PetscFunctionBegin; 79048a10b22SPatrick 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."); 79148a10b22SPatrick Sanan red->subcommtype = subcommtype; 79248a10b22SPatrick Sanan PetscFunctionReturn(0); 79348a10b22SPatrick Sanan } 79448a10b22SPatrick Sanan 7951e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetReductionFactor_Telescope(PC pc,PetscInt *fact) 7961e07b27eSBarry Smith { 7971e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 798bd49479cSSatish Balay PetscFunctionBegin; 7991e07b27eSBarry Smith if (fact) *fact = red->redfactor; 800bd49479cSSatish Balay PetscFunctionReturn(0); 8011e07b27eSBarry Smith } 8021e07b27eSBarry Smith 8031e07b27eSBarry Smith static PetscErrorCode PCTelescopeSetReductionFactor_Telescope(PC pc,PetscInt fact) 8041e07b27eSBarry Smith { 8051e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 8061e07b27eSBarry Smith PetscMPIInt size; 8071e07b27eSBarry Smith PetscErrorCode ierr; 8081e07b27eSBarry Smith 809bd49479cSSatish Balay PetscFunctionBegin; 810ffc4695bSBarry Smith ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRMPI(ierr); 8111e07b27eSBarry Smith if (fact <= 0) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Reduction factor of telescoping PC %D must be positive",fact); 8121e07b27eSBarry Smith if (fact > size) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONG,"Reduction factor of telescoping PC %D must be <= comm.size",fact); 8131e07b27eSBarry Smith red->redfactor = fact; 814bd49479cSSatish Balay PetscFunctionReturn(0); 8151e07b27eSBarry Smith } 8161e07b27eSBarry Smith 8171e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetIgnoreDM_Telescope(PC pc,PetscBool *v) 8181e07b27eSBarry Smith { 8191e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 820bd49479cSSatish Balay PetscFunctionBegin; 8211e07b27eSBarry Smith if (v) *v = red->ignore_dm; 822bd49479cSSatish Balay PetscFunctionReturn(0); 8231e07b27eSBarry Smith } 82448a10b22SPatrick Sanan 8251e07b27eSBarry Smith static PetscErrorCode PCTelescopeSetIgnoreDM_Telescope(PC pc,PetscBool v) 8261e07b27eSBarry Smith { 8271e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 828bd49479cSSatish Balay PetscFunctionBegin; 8291e07b27eSBarry Smith red->ignore_dm = v; 830bd49479cSSatish Balay PetscFunctionReturn(0); 8311e07b27eSBarry Smith } 8321e07b27eSBarry Smith 8338d9f7141SDave May static PetscErrorCode PCTelescopeGetUseCoarseDM_Telescope(PC pc,PetscBool *v) 8348d9f7141SDave May { 8358d9f7141SDave May PC_Telescope red = (PC_Telescope)pc->data; 8368d9f7141SDave May PetscFunctionBegin; 8378d9f7141SDave May if (v) *v = red->use_coarse_dm; 8388d9f7141SDave May PetscFunctionReturn(0); 8398d9f7141SDave May } 8408d9f7141SDave May 8418d9f7141SDave May static PetscErrorCode PCTelescopeSetUseCoarseDM_Telescope(PC pc,PetscBool v) 8428d9f7141SDave May { 8438d9f7141SDave May PC_Telescope red = (PC_Telescope)pc->data; 8448d9f7141SDave May PetscFunctionBegin; 8458d9f7141SDave May red->use_coarse_dm = v; 8468d9f7141SDave May PetscFunctionReturn(0); 8478d9f7141SDave May } 8488d9f7141SDave May 8490ae7c45bSDave May static PetscErrorCode PCTelescopeGetIgnoreKSPComputeOperators_Telescope(PC pc,PetscBool *v) 8500ae7c45bSDave May { 8510ae7c45bSDave May PC_Telescope red = (PC_Telescope)pc->data; 8520ae7c45bSDave May PetscFunctionBegin; 8530ae7c45bSDave May if (v) *v = red->ignore_kspcomputeoperators; 8540ae7c45bSDave May PetscFunctionReturn(0); 8550ae7c45bSDave May } 85648a10b22SPatrick Sanan 8570ae7c45bSDave May static PetscErrorCode PCTelescopeSetIgnoreKSPComputeOperators_Telescope(PC pc,PetscBool v) 8580ae7c45bSDave May { 8590ae7c45bSDave May PC_Telescope red = (PC_Telescope)pc->data; 8600ae7c45bSDave May PetscFunctionBegin; 8610ae7c45bSDave May red->ignore_kspcomputeoperators = v; 8620ae7c45bSDave May PetscFunctionReturn(0); 8630ae7c45bSDave May } 8640ae7c45bSDave May 8651e07b27eSBarry Smith static PetscErrorCode PCTelescopeGetDM_Telescope(PC pc,DM *dm) 8661e07b27eSBarry Smith { 8671e07b27eSBarry Smith PC_Telescope red = (PC_Telescope)pc->data; 868bd49479cSSatish Balay PetscFunctionBegin; 8691e07b27eSBarry Smith *dm = private_PCTelescopeGetSubDM(red); 870bd49479cSSatish Balay PetscFunctionReturn(0); 8711e07b27eSBarry Smith } 8721e07b27eSBarry Smith 8731e07b27eSBarry Smith /*@ 8741e07b27eSBarry Smith PCTelescopeGetKSP - Gets the KSP created by the telescoping PC. 8751e07b27eSBarry Smith 8761e07b27eSBarry Smith Not Collective 8771e07b27eSBarry Smith 8781e07b27eSBarry Smith Input Parameter: 8791e07b27eSBarry Smith . pc - the preconditioner context 8801e07b27eSBarry Smith 8811e07b27eSBarry Smith Output Parameter: 8821e07b27eSBarry Smith . subksp - the KSP defined the smaller set of processes 8831e07b27eSBarry Smith 8841e07b27eSBarry Smith Level: advanced 8851e07b27eSBarry Smith 8861e07b27eSBarry Smith @*/ 8871e07b27eSBarry Smith PetscErrorCode PCTelescopeGetKSP(PC pc,KSP *subksp) 8881e07b27eSBarry Smith { 889bd49479cSSatish Balay PetscErrorCode ierr; 890bd49479cSSatish Balay PetscFunctionBegin; 891163d334eSBarry Smith ierr = PetscUseMethod(pc,"PCTelescopeGetKSP_C",(PC,KSP*),(pc,subksp));CHKERRQ(ierr); 892bd49479cSSatish Balay PetscFunctionReturn(0); 8931e07b27eSBarry Smith } 8941e07b27eSBarry Smith 8951e07b27eSBarry Smith /*@ 8961e07b27eSBarry Smith PCTelescopeGetReductionFactor - Gets the factor by which the original number of processes has been reduced by. 8971e07b27eSBarry Smith 8981e07b27eSBarry Smith Not Collective 8991e07b27eSBarry Smith 9001e07b27eSBarry Smith Input Parameter: 9011e07b27eSBarry Smith . pc - the preconditioner context 9021e07b27eSBarry Smith 9031e07b27eSBarry Smith Output Parameter: 9041e07b27eSBarry Smith . fact - the reduction factor 9051e07b27eSBarry Smith 9061e07b27eSBarry Smith Level: advanced 9071e07b27eSBarry Smith 9081e07b27eSBarry Smith @*/ 9091e07b27eSBarry Smith PetscErrorCode PCTelescopeGetReductionFactor(PC pc,PetscInt *fact) 9101e07b27eSBarry Smith { 911bd49479cSSatish Balay PetscErrorCode ierr; 912bd49479cSSatish Balay PetscFunctionBegin; 913163d334eSBarry Smith ierr = PetscUseMethod(pc,"PCTelescopeGetReductionFactor_C",(PC,PetscInt*),(pc,fact));CHKERRQ(ierr); 914bd49479cSSatish Balay PetscFunctionReturn(0); 9151e07b27eSBarry Smith } 9161e07b27eSBarry Smith 9171e07b27eSBarry Smith /*@ 9181e07b27eSBarry Smith PCTelescopeSetReductionFactor - Sets the factor by which the original number of processes has been reduced by. 9191e07b27eSBarry Smith 9201e07b27eSBarry Smith Not Collective 9211e07b27eSBarry Smith 9221e07b27eSBarry Smith Input Parameter: 9231e07b27eSBarry Smith . pc - the preconditioner context 9241e07b27eSBarry Smith 9251e07b27eSBarry Smith Output Parameter: 9261e07b27eSBarry Smith . fact - the reduction factor 9271e07b27eSBarry Smith 9281e07b27eSBarry Smith Level: advanced 9291e07b27eSBarry Smith 9301e07b27eSBarry Smith @*/ 9311e07b27eSBarry Smith PetscErrorCode PCTelescopeSetReductionFactor(PC pc,PetscInt fact) 9321e07b27eSBarry Smith { 933bd49479cSSatish Balay PetscErrorCode ierr; 934bd49479cSSatish Balay PetscFunctionBegin; 935bd49479cSSatish Balay ierr = PetscTryMethod(pc,"PCTelescopeSetReductionFactor_C",(PC,PetscInt),(pc,fact));CHKERRQ(ierr); 936bd49479cSSatish Balay PetscFunctionReturn(0); 9371e07b27eSBarry Smith } 9381e07b27eSBarry Smith 9391e07b27eSBarry Smith /*@ 9401e07b27eSBarry Smith PCTelescopeGetIgnoreDM - Get the flag indicating if any DM attached to the PC will be used. 9411e07b27eSBarry Smith 9421e07b27eSBarry Smith Not Collective 9431e07b27eSBarry Smith 9441e07b27eSBarry Smith Input Parameter: 9451e07b27eSBarry Smith . pc - the preconditioner context 9461e07b27eSBarry Smith 9471e07b27eSBarry Smith Output Parameter: 9481e07b27eSBarry Smith . v - the flag 9491e07b27eSBarry Smith 9501e07b27eSBarry Smith Level: advanced 9511e07b27eSBarry Smith 9521e07b27eSBarry Smith @*/ 9531e07b27eSBarry Smith PetscErrorCode PCTelescopeGetIgnoreDM(PC pc,PetscBool *v) 9541e07b27eSBarry Smith { 955bd49479cSSatish Balay PetscErrorCode ierr; 956bd49479cSSatish Balay PetscFunctionBegin; 957163d334eSBarry Smith ierr = PetscUseMethod(pc,"PCTelescopeGetIgnoreDM_C",(PC,PetscBool*),(pc,v));CHKERRQ(ierr); 958bd49479cSSatish Balay PetscFunctionReturn(0); 9591e07b27eSBarry Smith } 9601e07b27eSBarry Smith 9611e07b27eSBarry Smith /*@ 9621e07b27eSBarry Smith PCTelescopeSetIgnoreDM - Set a flag to ignore any DM attached to the PC. 9631e07b27eSBarry Smith 9641e07b27eSBarry Smith Not Collective 9651e07b27eSBarry Smith 9661e07b27eSBarry Smith Input Parameter: 9671e07b27eSBarry Smith . pc - the preconditioner context 9681e07b27eSBarry Smith 9691e07b27eSBarry Smith Output Parameter: 9701e07b27eSBarry Smith . v - Use PETSC_TRUE to ignore any DM 9711e07b27eSBarry Smith 9721e07b27eSBarry Smith Level: advanced 9731e07b27eSBarry Smith 9741e07b27eSBarry Smith @*/ 975bfd6bcc6SSatish Balay PetscErrorCode PCTelescopeSetIgnoreDM(PC pc,PetscBool v) 9761e07b27eSBarry Smith { 977bd49479cSSatish Balay PetscErrorCode ierr; 978bd49479cSSatish Balay PetscFunctionBegin; 979bd49479cSSatish Balay ierr = PetscTryMethod(pc,"PCTelescopeSetIgnoreDM_C",(PC,PetscBool),(pc,v));CHKERRQ(ierr); 980bd49479cSSatish Balay PetscFunctionReturn(0); 9811e07b27eSBarry Smith } 9821e07b27eSBarry Smith 9831e07b27eSBarry Smith /*@ 9848d9f7141SDave May PCTelescopeGetUseCoarseDM - Get the flag indicating if the coarse DM attached to DM associated with the PC will be used. 9858d9f7141SDave May 9868d9f7141SDave May Not Collective 9878d9f7141SDave May 9888d9f7141SDave May Input Parameter: 9898d9f7141SDave May . pc - the preconditioner context 9908d9f7141SDave May 9918d9f7141SDave May Output Parameter: 9928d9f7141SDave May . v - the flag 9938d9f7141SDave May 9948d9f7141SDave May Level: advanced 9958d9f7141SDave May 9968d9f7141SDave May @*/ 9978d9f7141SDave May PetscErrorCode PCTelescopeGetUseCoarseDM(PC pc,PetscBool *v) 9988d9f7141SDave May { 9998d9f7141SDave May PetscErrorCode ierr; 10008d9f7141SDave May PetscFunctionBegin; 10018d9f7141SDave May ierr = PetscUseMethod(pc,"PCTelescopeGetUseCoarseDM_C",(PC,PetscBool*),(pc,v));CHKERRQ(ierr); 10028d9f7141SDave May PetscFunctionReturn(0); 10038d9f7141SDave May } 10048d9f7141SDave May 10058d9f7141SDave May /*@ 10068d9f7141SDave May PCTelescopeSetUseCoarseDM - Set a flag to query the DM attached to the PC if it also has a coarse DM 10078d9f7141SDave May 10088d9f7141SDave May Not Collective 10098d9f7141SDave May 10108d9f7141SDave May Input Parameter: 10118d9f7141SDave May . pc - the preconditioner context 10128d9f7141SDave May 10138d9f7141SDave May Output Parameter: 1014aaa7a805SDave May . v - Use PETSC_FALSE to ignore any coarse DM 10158d9f7141SDave May 10168d9f7141SDave May Notes: 10178d9f7141SDave May When you have specified to use a coarse DM, the communicator used to create the sub-KSP within PCTelescope 10188d9f7141SDave May will be that of the coarse DM. Hence the flags -pc_telescope_reduction_factor and 10198d9f7141SDave May -pc_telescope_subcomm_type will no longer have any meaning. 10208d9f7141SDave May It is required that the communicator associated with the parent (fine) and the coarse DM are of different sizes. 10218d9f7141SDave May An error will occur of the size of the communicator associated with the coarse DM 10228d9f7141SDave May is the same as that of the parent DM. 10238d9f7141SDave May Furthermore, it is required that the communicator on the coarse DM is a sub-communicator of the parent. 10248d9f7141SDave May This will be checked at the time the preconditioner is setup and an error will occur if 10258d9f7141SDave May the coarse DM does not define a sub-communicator of that used by the parent DM. 10268d9f7141SDave May 10278d9f7141SDave May The particular Telescope setup invoked when using a coarse DM is agnostic with respect to the type of 10288d9f7141SDave May the DM used (e.g. it supports DMSHELL, DMPLEX, etc). 10298d9f7141SDave May 10308d9f7141SDave May Support is currently only provided for the case when you are using KSPSetComputeOperators() 10318d9f7141SDave May 10328d9f7141SDave May The user is required to compose a function with the parent DM to facilitate the transfer of fields (Vec) between the different decompositions defined by the fine and coarse DMs. 10338d9f7141SDave May In the user code, this is achieved via 10348d9f7141SDave May .vb 10358d9f7141SDave May { 10368d9f7141SDave May DM dm_fine; 10378d9f7141SDave May PetscObjectCompose((PetscObject)dm_fine,"PCTelescopeFieldScatter",your_field_scatter_method); 10388d9f7141SDave May } 10398d9f7141SDave May .ve 10408d9f7141SDave May The signature of the user provided field scatter method is 10418d9f7141SDave May .vb 10428d9f7141SDave May PetscErrorCode your_field_scatter_method(DM dm_fine,Vec x_fine,ScatterMode mode,DM dm_coarse,Vec x_coarse); 10438d9f7141SDave May .ve 10448d9f7141SDave May The user must provide support for both mode = SCATTER_FORWARD and mode = SCATTER_REVERSE. 10458d9f7141SDave May SCATTER_FORWARD implies the direction of transfer is from the parent (fine) DM to the coarse DM. 10468d9f7141SDave May 10478d9f7141SDave May Optionally, the user may also compose a function with the parent DM to facilitate the transfer 10488d9f7141SDave May of state variables between the fine and coarse DMs. 10498d9f7141SDave May In the context of a finite element discretization, an example state variable might be 10508d9f7141SDave May values associated with quadrature points within each element. 10518d9f7141SDave May A user provided state scatter method is composed via 10528d9f7141SDave May .vb 10538d9f7141SDave May { 10548d9f7141SDave May DM dm_fine; 10558d9f7141SDave May PetscObjectCompose((PetscObject)dm_fine,"PCTelescopeStateScatter",your_state_scatter_method); 10568d9f7141SDave May } 10578d9f7141SDave May .ve 10588d9f7141SDave May The signature of the user provided state scatter method is 10598d9f7141SDave May .vb 10608d9f7141SDave May PetscErrorCode your_state_scatter_method(DM dm_fine,ScatterMode mode,DM dm_coarse); 10618d9f7141SDave May .ve 10628d9f7141SDave May SCATTER_FORWARD implies the direction of transfer is from the fine DM to the coarse DM. 10638d9f7141SDave May The user is only required to support mode = SCATTER_FORWARD. 10648d9f7141SDave May No assumption is made about the data type of the state variables. 10658d9f7141SDave May These must be managed by the user and must be accessible from the DM. 10668d9f7141SDave May 10678d9f7141SDave May Care must be taken in defining the user context passed to KSPSetComputeOperators() which is to be 10688d9f7141SDave May associated with the sub-KSP residing within PCTelescope. 10698d9f7141SDave May In general, PCTelescope assumes that the context on the fine and coarse DM used with 10708d9f7141SDave May KSPSetComputeOperators() should be "similar" in type or origin. 10718d9f7141SDave May Specifically the following rules are used to infer what context on the sub-KSP should be. 10728d9f7141SDave May 10738d9f7141SDave May First the contexts from the KSP and the fine and coarse DMs are retrieved. 10748d9f7141SDave May Note that the special case of a DMSHELL context is queried. 10758d9f7141SDave May 10768d9f7141SDave May .vb 10778d9f7141SDave May DMKSPGetComputeOperators(dm_fine,&dmfine_kspfunc,&dmfine_kspctx); 10788d9f7141SDave May DMGetApplicationContext(dm_fine,&dmfine_appctx); 10798d9f7141SDave May DMShellGetContext(dm_fine,&dmfine_shellctx); 10808d9f7141SDave May 10818d9f7141SDave May DMGetApplicationContext(dm_coarse,&dmcoarse_appctx); 10828d9f7141SDave May DMShellGetContext(dm_coarse,&dmcoarse_shellctx); 10838d9f7141SDave May .ve 10848d9f7141SDave May 10858d9f7141SDave May The following rules are then enforced: 10868d9f7141SDave May 10878d9f7141SDave May 1. If dmfine_kspctx = NULL, then we provide a NULL pointer as the context for the sub-KSP: 10888d9f7141SDave May KSPSetComputeOperators(sub_ksp,dmfine_kspfunc,NULL); 10898d9f7141SDave May 10908d9f7141SDave May 2. If dmfine_kspctx != NULL and dmfine_kspctx == dmfine_appctx, 10918d9f7141SDave May check that dmcoarse_appctx is also non-NULL. If this is true, then: 10928d9f7141SDave May KSPSetComputeOperators(sub_ksp,dmfine_kspfunc,dmcoarse_appctx); 10938d9f7141SDave May 10948d9f7141SDave May 3. If dmfine_kspctx != NULL and dmfine_kspctx == dmfine_shellctx, 10958d9f7141SDave May check that dmcoarse_shellctx is also non-NULL. If this is true, then: 10968d9f7141SDave May KSPSetComputeOperators(sub_ksp,dmfine_kspfunc,dmcoarse_shellctx); 10978d9f7141SDave May 10988d9f7141SDave May If neither of the above three tests passed, then PCTelescope cannot safely determine what 10998d9f7141SDave May context should be provided to KSPSetComputeOperators() for use with the sub-KSP. 11008d9f7141SDave May In this case, an additional mechanism is provided via a composed function which will return 11018d9f7141SDave May the actual context to be used. To use this feature you must compose the "getter" function 11028d9f7141SDave May with the coarse DM, e.g. 11038d9f7141SDave May .vb 11048d9f7141SDave May { 11058d9f7141SDave May DM dm_coarse; 11068d9f7141SDave May PetscObjectCompose((PetscObject)dm_coarse,"PCTelescopeGetCoarseDMKSPContext",your_coarse_context_getter); 11078d9f7141SDave May } 11088d9f7141SDave May .ve 11098d9f7141SDave May The signature of the user provided method is 11108d9f7141SDave May .vb 11118d9f7141SDave May PetscErrorCode your_coarse_context_getter(DM dm_coarse,void **your_kspcontext); 11128d9f7141SDave May .ve 11138d9f7141SDave May 11148d9f7141SDave May Level: advanced 11158d9f7141SDave May 11168d9f7141SDave May @*/ 11178d9f7141SDave May PetscErrorCode PCTelescopeSetUseCoarseDM(PC pc,PetscBool v) 11188d9f7141SDave May { 11198d9f7141SDave May PetscErrorCode ierr; 11208d9f7141SDave May PetscFunctionBegin; 11218d9f7141SDave May ierr = PetscTryMethod(pc,"PCTelescopeSetUseCoarseDM_C",(PC,PetscBool),(pc,v));CHKERRQ(ierr); 11228d9f7141SDave May PetscFunctionReturn(0); 11238d9f7141SDave May } 11248d9f7141SDave May 11258d9f7141SDave May /*@ 11260ae7c45bSDave May PCTelescopeGetIgnoreKSPComputeOperators - Get the flag indicating if KSPComputeOperators will be used. 11270ae7c45bSDave May 11280ae7c45bSDave May Not Collective 11290ae7c45bSDave May 11300ae7c45bSDave May Input Parameter: 11310ae7c45bSDave May . pc - the preconditioner context 11320ae7c45bSDave May 11330ae7c45bSDave May Output Parameter: 11340ae7c45bSDave May . v - the flag 11350ae7c45bSDave May 11360ae7c45bSDave May Level: advanced 11370ae7c45bSDave May 11380ae7c45bSDave May @*/ 11390ae7c45bSDave May PetscErrorCode PCTelescopeGetIgnoreKSPComputeOperators(PC pc,PetscBool *v) 11400ae7c45bSDave May { 11410ae7c45bSDave May PetscErrorCode ierr; 11420ae7c45bSDave May PetscFunctionBegin; 1143163d334eSBarry Smith ierr = PetscUseMethod(pc,"PCTelescopeGetIgnoreKSPComputeOperators_C",(PC,PetscBool*),(pc,v));CHKERRQ(ierr); 11440ae7c45bSDave May PetscFunctionReturn(0); 11450ae7c45bSDave May } 11460ae7c45bSDave May 11470ae7c45bSDave May /*@ 11480ae7c45bSDave May PCTelescopeSetIgnoreKSPComputeOperators - Set a flag to ignore KSPComputeOperators. 11490ae7c45bSDave May 11500ae7c45bSDave May Not Collective 11510ae7c45bSDave May 11520ae7c45bSDave May Input Parameter: 11530ae7c45bSDave May . pc - the preconditioner context 11540ae7c45bSDave May 11550ae7c45bSDave May Output Parameter: 1156a954d8f4SDave May . v - Use PETSC_TRUE to ignore the method (if defined) set via KSPSetComputeOperators on pc 11570ae7c45bSDave May 11580ae7c45bSDave May Level: advanced 11590ae7c45bSDave May 11600ae7c45bSDave May @*/ 11610ae7c45bSDave May PetscErrorCode PCTelescopeSetIgnoreKSPComputeOperators(PC pc,PetscBool v) 11620ae7c45bSDave May { 11630ae7c45bSDave May PetscErrorCode ierr; 11640ae7c45bSDave May PetscFunctionBegin; 11650ae7c45bSDave May ierr = PetscTryMethod(pc,"PCTelescopeSetIgnoreKSPComputeOperators_C",(PC,PetscBool),(pc,v));CHKERRQ(ierr); 11660ae7c45bSDave May PetscFunctionReturn(0); 11670ae7c45bSDave May } 11680ae7c45bSDave May 11690ae7c45bSDave May /*@ 11701e07b27eSBarry Smith PCTelescopeGetDM - Get the re-partitioned DM attached to the sub KSP. 11711e07b27eSBarry Smith 11721e07b27eSBarry Smith Not Collective 11731e07b27eSBarry Smith 11741e07b27eSBarry Smith Input Parameter: 11751e07b27eSBarry Smith . pc - the preconditioner context 11761e07b27eSBarry Smith 11771e07b27eSBarry Smith Output Parameter: 11781e07b27eSBarry Smith . subdm - The re-partitioned DM 11791e07b27eSBarry Smith 11801e07b27eSBarry Smith Level: advanced 11811e07b27eSBarry Smith 11821e07b27eSBarry Smith @*/ 11831e07b27eSBarry Smith PetscErrorCode PCTelescopeGetDM(PC pc,DM *subdm) 11841e07b27eSBarry Smith { 1185bd49479cSSatish Balay PetscErrorCode ierr; 1186bd49479cSSatish Balay PetscFunctionBegin; 1187163d334eSBarry Smith ierr = PetscUseMethod(pc,"PCTelescopeGetDM_C",(PC,DM*),(pc,subdm));CHKERRQ(ierr); 1188bd49479cSSatish Balay PetscFunctionReturn(0); 11891e07b27eSBarry Smith } 11901e07b27eSBarry Smith 119148a10b22SPatrick Sanan /*@ 119248a10b22SPatrick Sanan PCTelescopeSetSubcommType - set subcommunicator type (interlaced or contiguous) 119348a10b22SPatrick Sanan 119448a10b22SPatrick Sanan Logically Collective 119548a10b22SPatrick Sanan 1196*d8d19677SJose E. Roman Input Parameters: 11971dae98e4SBarry Smith + pc - the preconditioner context 11981dae98e4SBarry Smith - subcommtype - the subcommunicator type (see PetscSubcommType) 119948a10b22SPatrick Sanan 120048a10b22SPatrick Sanan Level: advanced 120148a10b22SPatrick Sanan 120248a10b22SPatrick Sanan .seealso: PetscSubcommType, PetscSubcomm, PCTELESCOPE 120348a10b22SPatrick Sanan @*/ 120448a10b22SPatrick Sanan PetscErrorCode PCTelescopeSetSubcommType(PC pc, PetscSubcommType subcommtype) 120548a10b22SPatrick Sanan { 120648a10b22SPatrick Sanan PetscErrorCode ierr; 120748a10b22SPatrick Sanan PetscFunctionBegin; 120848a10b22SPatrick Sanan ierr = PetscTryMethod(pc,"PCTelescopeSetSubcommType_C",(PC,PetscSubcommType),(pc,subcommtype));CHKERRQ(ierr); 120948a10b22SPatrick Sanan PetscFunctionReturn(0); 121048a10b22SPatrick Sanan } 121148a10b22SPatrick Sanan 121248a10b22SPatrick Sanan /*@ 121348a10b22SPatrick Sanan PCTelescopeGetSubcommType - Get the subcommunicator type (interlaced or contiguous) 121448a10b22SPatrick Sanan 121548a10b22SPatrick Sanan Not Collective 121648a10b22SPatrick Sanan 121748a10b22SPatrick Sanan Input Parameter: 121848a10b22SPatrick Sanan . pc - the preconditioner context 121948a10b22SPatrick Sanan 122048a10b22SPatrick Sanan Output Parameter: 122148a10b22SPatrick Sanan . subcommtype - the subcommunicator type (see PetscSubcommType) 122248a10b22SPatrick Sanan 122348a10b22SPatrick Sanan Level: advanced 122448a10b22SPatrick Sanan 12251dae98e4SBarry Smith .seealso: PetscSubcomm, PetscSubcommType, PCTELESCOPE 122648a10b22SPatrick Sanan @*/ 12271dae98e4SBarry Smith PetscErrorCode PCTelescopeGetSubcommType(PC pc, PetscSubcommType *subcommtype) 122848a10b22SPatrick Sanan { 122948a10b22SPatrick Sanan PetscErrorCode ierr; 123048a10b22SPatrick Sanan PetscFunctionBegin; 123148a10b22SPatrick Sanan ierr = PetscUseMethod(pc,"PCTelescopeGetSubcommType_C",(PC,PetscSubcommType*),(pc,subcommtype));CHKERRQ(ierr); 123248a10b22SPatrick Sanan PetscFunctionReturn(0); 123348a10b22SPatrick Sanan } 123448a10b22SPatrick Sanan 12351e07b27eSBarry Smith /* -------------------------------------------------------------------------------------*/ 12361e07b27eSBarry Smith /*MC 123700fea0ebSDave May PCTELESCOPE - Runs a KSP solver on a sub-communicator. MPI ranks not in the sub-communicator are idle during the solve. 12381e07b27eSBarry Smith 12391e07b27eSBarry Smith Options Database: 124000fea0ebSDave May + -pc_telescope_reduction_factor <r> - factor to reduce the communicator size by. e.g. with 64 MPI ranks and r=4, the new sub-communicator will have 64/4 = 16 ranks. 124100fea0ebSDave May . -pc_telescope_ignore_dm - flag to indicate whether an attached DM should be ignored. 124200fea0ebSDave May . -pc_telescope_subcomm_type <interlaced,contiguous> - defines the selection of MPI ranks on the sub-communicator. see PetscSubcomm for more information. 124300fea0ebSDave May . -pc_telescope_ignore_kspcomputeoperators - flag to indicate whether KSPSetComputeOperators should be used on the sub-KSP. 124400fea0ebSDave May - -pc_telescope_use_coarse_dm - flag to indicate whether the coarse DM should be used to define the sub-communicator. 12451e07b27eSBarry Smith 12461e07b27eSBarry Smith Level: advanced 12471e07b27eSBarry Smith 12481e07b27eSBarry Smith Notes: 124900fea0ebSDave May Assuming that the parent preconditioner (PC) is defined on a communicator c, this implementation 125000fea0ebSDave May creates a child sub-communicator (c') containing fewer MPI ranks than the original parent preconditioner (PC). 12516fc41876SBarry Smith The preconditioner is deemed telescopic as it only calls KSPSolve() on a single 12528439623fSPatrick Sanan sub-communicator, in contrast with PCREDUNDANT which calls KSPSolve() on N sub-communicators. 125300fea0ebSDave May This means there will be MPI ranks which will be idle during the application of this preconditioner. 125400fea0ebSDave May Additionally, in comparison with PCREDUNDANT, PCTELESCOPE can utilize an attached DM. 12556fc41876SBarry Smith 125600fea0ebSDave May The default type of the sub KSP (the KSP defined on c') is PREONLY. 125700fea0ebSDave May 125800fea0ebSDave May There are three setup mechanisms for PCTelescope. Features support by each type are described below. 125900fea0ebSDave May In the following, we will refer to the operators B and B', these are the Bmat provided to the KSP on the 126000fea0ebSDave May communicators c and c' respectively. 126100fea0ebSDave May 126200fea0ebSDave May [1] Default setup 126300fea0ebSDave May The sub-communicator c' is created via PetscSubcommCreate(). 1264a5b23f4aSJose E. Roman Explicitly defined nullspace and near nullspace vectors will be propagated from B to B'. 126500fea0ebSDave May Currently there is no support define nullspaces via a user supplied method (e.g. as passed to MatNullSpaceSetFunction()). 126600fea0ebSDave May No support is provided for KSPSetComputeOperators(). 126700fea0ebSDave May Currently there is no support for the flag -pc_use_amat. 126800fea0ebSDave May 126900fea0ebSDave May [2] DM aware setup 127000fea0ebSDave May If a DM is attached to the PC, it is re-partitioned on the sub-communicator c'. 127100fea0ebSDave May c' is created via PetscSubcommCreate(). 12721e07b27eSBarry Smith Both the Bmat operator and the right hand side vector are permuted into the new DOF ordering defined by the re-partitioned DM. 12731e07b27eSBarry Smith Currently only support for re-partitioning a DMDA is provided. 127400fea0ebSDave May Any explicitly defined nullspace or near nullspace vectors attached to the original Bmat operator (B) are extracted, re-partitioned and set on the re-partitioned Bmat operator (B'). 127500fea0ebSDave May Currently there is no support define nullspaces via a user supplied method (e.g. as passed to MatNullSpaceSetFunction()). 127600fea0ebSDave May Support is provided for KSPSetComputeOperators(). The user provided function and context is propagated to the sub KSP. 127700fea0ebSDave May This is fragile since the user must ensure that their user context is valid for use on c'. 127800fea0ebSDave May Currently there is no support for the flag -pc_use_amat. 12791e07b27eSBarry Smith 128000fea0ebSDave May [3] Coarse DM setup 128100fea0ebSDave May If a DM (dmfine) is attached to the PC, dmfine is queried for a "coarse" DM (call this dmcoarse) via DMGetCoarseDM(). 128200fea0ebSDave May PCTELESCOPE will interpret the coarse DM as being defined on a sub-communicator of c. 128300fea0ebSDave May The communicator associated with dmcoarse will define the c' to be used within PCTELESCOPE. 128400fea0ebSDave May PCTELESCOPE will check that c' is in fact a sub-communicator of c. If it is not, an error will be reported. 128500fea0ebSDave May The intention of this setup type is that PCTELESCOPE will use an existing (e.g. user defined) communicator hierarchy, say as would be 128600fea0ebSDave May available with using multi-grid on unstructured meshes. 128700fea0ebSDave May This setup will not use the command line options -pc_telescope_reduction_factor or -pc_telescope_subcomm_type. 128800fea0ebSDave May Any explicitly defined nullspace or near nullspace vectors attached to the original Bmat operator (B) are extracted, scattered into the correct ordering consistent with dmcoarse and set on B'. 128900fea0ebSDave May Currently there is no support define nullspaces via a user supplied method (e.g. as passed to MatNullSpaceSetFunction()). 129000fea0ebSDave May There is no general method to permute field orderings, hence only KSPSetComputeOperators() is supported. 129100fea0ebSDave May The user must use PetscObjectComposeFunction() with dmfine to define the method to scatter fields from dmfine to dmcoarse. 1292a5b23f4aSJose E. Roman Propagation of the user context for KSPSetComputeOperators() on the sub KSP is attempted by querying the DM contexts associated with dmfine and dmcoarse. Alternatively, the user may use PetscObjectComposeFunction() with dmcoarse to define a method which will return the appropriate user context for KSPSetComputeOperators(). 129300fea0ebSDave May Currently there is no support for the flag -pc_use_amat. 129400fea0ebSDave May This setup can be invoked by the option -pc_telescope_use_coarse_dm or by calling PCTelescopeSetUseCoarseDM(pc,PETSC_TRUE); 129500fea0ebSDave May Further information about the user-provided methods required by this setup type are described here PCTelescopeSetUseCoarseDM(). 12966fc41876SBarry Smith 12976fc41876SBarry Smith Developer Notes: 12986fc41876SBarry Smith During PCSetup, the B operator is scattered onto c'. 12996fc41876SBarry Smith Within PCApply, the RHS vector (x) is scattered into a redundant vector, xred (defined on c'). 13008439623fSPatrick Sanan Then, KSPSolve() is executed on the c' communicator. 13016fc41876SBarry Smith 13026fc41876SBarry Smith The communicator used within the telescoping preconditioner is defined by a PetscSubcomm using the INTERLACED 1303a04a6428SPatrick 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. 13046fc41876SBarry Smith 1305005d9f20SPatrick Sanan The telescoping preconditioner is aware of nullspaces and near nullspaces which are attached to the B operator. 13068439623fSPatrick Sanan In the case where B has a (near) nullspace attached, the (near) nullspace vectors are extracted from B and mapped into 1307005d9f20SPatrick Sanan a new (near) nullspace, defined on the sub-communicator, which is attached to B' (the B operator which was scattered to c') 13086fc41876SBarry Smith 130900fea0ebSDave May The telescoping preconditioner can re-partition an attached DM if it is a DMDA (2D or 3D - 13104c500f23SPierre Jolivet support for 1D DMDAs is not provided). If a DMDA is found, a topologically equivalent DMDA is created on c' 131100fea0ebSDave May and this new DM is attached the sub KSP. The design of telescope is such that it should be possible to extend support 13128439623fSPatrick Sanan for re-partitioning other to DM's (e.g. DMPLEX). The user can supply a flag to ignore attached DMs. 131300fea0ebSDave May Alternatively, user-provided re-partitioned DMs can be used via -pc_telescope_use_coarse_dm. 13146fc41876SBarry Smith 131500fea0ebSDave May With the default setup mode, B' is defined by fusing rows (in order) associated with MPI ranks common to c and c'. 13166fc41876SBarry Smith 13178439623fSPatrick Sanan When a DMDA is attached to the parent preconditioner, B' is defined by: (i) performing a symmetric permutation of B 13187dae84e0SHong Zhang into the ordering defined by the DMDA on c', (ii) extracting the local chunks via MatCreateSubMatrices(), (iii) fusing the 13196fc41876SBarry Smith locally (sequential) matrices defined on the ranks common to c and c' into B' using MatCreateMPIMatConcatenateSeqMat() 13206fc41876SBarry Smith 13218439623fSPatrick Sanan Limitations/improvements include the following. 13228439623fSPatrick Sanan VecPlaceArray() could be used within PCApply() to improve efficiency and reduce memory usage. 132300fea0ebSDave May A unified mechanism to query for user contexts as required by KSPSetComputeOperators() and MatNullSpaceSetFunction(). 13246fc41876SBarry Smith 13256fc41876SBarry Smith The symmetric permutation used when a DMDA is encountered is performed via explicitly assmbleming a permutation matrix P, 13268439623fSPatrick Sanan and performing P^T.A.P. Possibly it might be more efficient to use MatPermute(). We opted to use P^T.A.P as it appears 13278439623fSPatrick Sanan VecPermute() does not supported for the use case required here. By computing P, one can permute both the operator and RHS in a 13286fc41876SBarry Smith consistent manner. 13296fc41876SBarry Smith 133000fea0ebSDave May Mapping of vectors (default setup mode) is performed in the following way. 133100fea0ebSDave May Suppose the parent communicator size was 4, and we set a reduction factor of 2; this would give a comm size on c' of 2. 13328439623fSPatrick Sanan Using the interlaced creation routine, the ranks in c with color = 0 will be rank 0 and 2. 133300fea0ebSDave May We perform the scatter to the sub-communicator in the following way. 1334514db83aSDave May [1] Given a vector x defined on communicator c 13356fc41876SBarry Smith 1336514db83aSDave May .vb 1337514db83aSDave May rank(c) local values of x 1338514db83aSDave May ------- ---------------------------------------- 1339514db83aSDave May 0 [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0 ] 1340514db83aSDave May 1 [ 6.0, 7.0, 8.0, 9.0, 10.0, 11.0 ] 1341514db83aSDave May 2 [ 12.0, 13.0, 14.0, 15.0, 16.0, 17.0 ] 1342514db83aSDave May 3 [ 18.0, 19.0, 20.0, 21.0, 22.0, 23.0 ] 1343514db83aSDave May .ve 13446fc41876SBarry Smith 1345514db83aSDave May scatter into xtmp defined also on comm c, so that we have the following values 13466fc41876SBarry Smith 1347514db83aSDave May .vb 1348514db83aSDave May rank(c) local values of xtmp 1349514db83aSDave May ------- ---------------------------------------------------------------------------- 1350514db83aSDave May 0 [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0 ] 1351514db83aSDave May 1 [ ] 1352514db83aSDave May 2 [ 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0 ] 1353514db83aSDave May 3 [ ] 1354514db83aSDave May .ve 13556fc41876SBarry Smith 13566fc41876SBarry Smith The entries on rank 1 and 3 (ranks which do not have a color = 0 in c') have no values 13576fc41876SBarry Smith 1358514db83aSDave May [2] Copy the values from ranks 0, 2 (indices with respect to comm c) into the vector xred which is defined on communicator c'. 13596fc41876SBarry Smith Ranks 0 and 2 are the only ranks in the subcomm which have a color = 0. 13606fc41876SBarry Smith 1361514db83aSDave May .vb 1362514db83aSDave May rank(c') local values of xred 1363514db83aSDave May -------- ---------------------------------------------------------------------------- 1364514db83aSDave May 0 [ 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0 ] 1365514db83aSDave May 1 [ 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0 ] 1366514db83aSDave May .ve 13671e07b27eSBarry Smith 13681e07b27eSBarry Smith Contributed by Dave May 13691e07b27eSBarry Smith 1370bf00f589SPatrick Sanan Reference: 1371bf00f589SPatrick Sanan Dave A. May, Patrick Sanan, Karl Rupp, Matthew G. Knepley, and Barry F. Smith, "Extreme-Scale Multigrid Components within PETSc". 2016. In Proceedings of the Platform for Advanced Scientific Computing Conference (PASC '16). DOI: 10.1145/2929908.2929913 1372bf00f589SPatrick Sanan 13736fc41876SBarry Smith .seealso: PCTelescopeGetKSP(), PCTelescopeGetDM(), PCTelescopeGetReductionFactor(), PCTelescopeSetReductionFactor(), PCTelescopeGetIgnoreDM(), PCTelescopeSetIgnoreDM(), PCREDUNDANT 13741e07b27eSBarry Smith M*/ 13751e07b27eSBarry Smith PETSC_EXTERN PetscErrorCode PCCreate_Telescope(PC pc) 13761e07b27eSBarry Smith { 13771e07b27eSBarry Smith PetscErrorCode ierr; 13781e07b27eSBarry Smith struct _PC_Telescope *sred; 13791e07b27eSBarry Smith 13801e07b27eSBarry Smith PetscFunctionBegin; 13811e07b27eSBarry Smith ierr = PetscNewLog(pc,&sred);CHKERRQ(ierr); 13822a22aa42SDave May sred->psubcomm = NULL; 138348a10b22SPatrick Sanan sred->subcommtype = PETSC_SUBCOMM_INTERLACED; 13842a22aa42SDave May sred->subcomm = MPI_COMM_NULL; 13851e07b27eSBarry Smith sred->redfactor = 1; 13861e07b27eSBarry Smith sred->ignore_dm = PETSC_FALSE; 13877c5279cbSDave May sred->ignore_kspcomputeoperators = PETSC_FALSE; 13888d9f7141SDave May sred->use_coarse_dm = PETSC_FALSE; 13891e07b27eSBarry Smith pc->data = (void*)sred; 13901e07b27eSBarry Smith 13911e07b27eSBarry Smith pc->ops->apply = PCApply_Telescope; 13921e07b27eSBarry Smith pc->ops->applytranspose = NULL; 1393f650675bSDave May pc->ops->applyrichardson = PCApplyRichardson_Telescope; 13941e07b27eSBarry Smith pc->ops->setup = PCSetUp_Telescope; 13951e07b27eSBarry Smith pc->ops->destroy = PCDestroy_Telescope; 13961e07b27eSBarry Smith pc->ops->reset = PCReset_Telescope; 13971e07b27eSBarry Smith pc->ops->setfromoptions = PCSetFromOptions_Telescope; 13981e07b27eSBarry Smith pc->ops->view = PCView_Telescope; 13991e07b27eSBarry Smith 14001e07b27eSBarry Smith sred->pctelescope_setup_type = PCTelescopeSetUp_default; 14011e07b27eSBarry Smith sred->pctelescope_matcreate_type = PCTelescopeMatCreate_default; 14021e07b27eSBarry Smith sred->pctelescope_matnullspacecreate_type = PCTelescopeMatNullSpaceCreate_default; 14031e07b27eSBarry Smith sred->pctelescope_reset_type = NULL; 14041e07b27eSBarry Smith 14051e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetKSP_C",PCTelescopeGetKSP_Telescope);CHKERRQ(ierr); 140648a10b22SPatrick Sanan ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetSubcommType_C",PCTelescopeGetSubcommType_Telescope);CHKERRQ(ierr); 140748a10b22SPatrick Sanan ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeSetSubcommType_C",PCTelescopeSetSubcommType_Telescope);CHKERRQ(ierr); 14081e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetReductionFactor_C",PCTelescopeGetReductionFactor_Telescope);CHKERRQ(ierr); 14091e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeSetReductionFactor_C",PCTelescopeSetReductionFactor_Telescope);CHKERRQ(ierr); 14101e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetIgnoreDM_C",PCTelescopeGetIgnoreDM_Telescope);CHKERRQ(ierr); 14111e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeSetIgnoreDM_C",PCTelescopeSetIgnoreDM_Telescope);CHKERRQ(ierr); 14120ae7c45bSDave May ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetIgnoreKSPComputeOperators_C",PCTelescopeGetIgnoreKSPComputeOperators_Telescope);CHKERRQ(ierr); 14130ae7c45bSDave May ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeSetIgnoreKSPComputeOperators_C",PCTelescopeSetIgnoreKSPComputeOperators_Telescope);CHKERRQ(ierr); 14141e07b27eSBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetDM_C",PCTelescopeGetDM_Telescope);CHKERRQ(ierr); 14158d9f7141SDave May ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeGetUseCoarseDM_C",PCTelescopeGetUseCoarseDM_Telescope);CHKERRQ(ierr); 14168d9f7141SDave May ierr = PetscObjectComposeFunction((PetscObject)pc,"PCTelescopeSetUseCoarseDM_C",PCTelescopeSetUseCoarseDM_Telescope);CHKERRQ(ierr); 14171e07b27eSBarry Smith PetscFunctionReturn(0); 14181e07b27eSBarry Smith } 1419