11cf9b237SStefano Zampini #include <../src/mat/impls/aij/seq/aij.h> 2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> 3ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 4674ae819SStefano Zampini #include <petscblaslapack.h> 5daf8a457SStefano Zampini #include <petsc/private/sfimpl.h> 6674ae819SStefano Zampini 71e0482f5SStefano Zampini static PetscErrorCode MatMPIAIJRestrict(Mat,MPI_Comm,Mat*); 81e0482f5SStefano Zampini 9a13144ffSStefano Zampini /* returns B s.t. range(B) _|_ range(A) */ 10a13144ffSStefano Zampini #undef __FUNCT__ 11a13144ffSStefano Zampini #define __FUNCT__ "MatDense_OrthogonalComplement" 12a13144ffSStefano Zampini PetscErrorCode MatDense_OrthogonalComplement(Mat A, PetscInt lw, PetscScalar *work, PetscReal *rwork, Mat *B) 13a13144ffSStefano Zampini { 14a13144ffSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 15a13144ffSStefano Zampini PetscScalar *uwork,*data,*U, ds = 0.; 16a13144ffSStefano Zampini PetscReal *sing; 17a13144ffSStefano Zampini PetscBLASInt bM,bN,lwork,lierr,di = 1; 18a13144ffSStefano Zampini PetscInt ulw,i,nr,nc,n; 19a13144ffSStefano Zampini PetscErrorCode ierr; 20a13144ffSStefano Zampini 21a13144ffSStefano Zampini PetscFunctionBegin; 22a13144ffSStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 23a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"LAPACK _GESVD not available"); 24a13144ffSStefano Zampini #endif 25a13144ffSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 26a13144ffSStefano Zampini if (!nr || !nc) PetscFunctionReturn(0); 27a13144ffSStefano Zampini 28a13144ffSStefano Zampini /* workspace */ 29a13144ffSStefano Zampini if (!work) { 30a13144ffSStefano Zampini ulw = PetscMax(PetscMax(1,5*PetscMin(nr,nc)),3*PetscMin(nr,nc)+PetscMax(nr,nc)); 31f913dca9SStefano Zampini ierr = PetscMalloc1(ulw,&uwork);CHKERRQ(ierr); 32a13144ffSStefano Zampini } else { 33a13144ffSStefano Zampini ulw = lw; 34a13144ffSStefano Zampini uwork = work; 35a13144ffSStefano Zampini } 36a13144ffSStefano Zampini n = PetscMin(nr,nc); 37a13144ffSStefano Zampini if (!rwork) { 38a13144ffSStefano Zampini ierr = PetscMalloc1(n,&sing);CHKERRQ(ierr); 39a13144ffSStefano Zampini } else { 40a13144ffSStefano Zampini sing = rwork; 41a13144ffSStefano Zampini } 42a13144ffSStefano Zampini 43a13144ffSStefano Zampini /* SVD */ 44a13144ffSStefano Zampini ierr = PetscMalloc1(nr*nr,&U);CHKERRQ(ierr); 45a13144ffSStefano Zampini ierr = PetscBLASIntCast(nr,&bM);CHKERRQ(ierr); 46a13144ffSStefano Zampini ierr = PetscBLASIntCast(nc,&bN);CHKERRQ(ierr); 47a13144ffSStefano Zampini ierr = PetscBLASIntCast(ulw,&lwork);CHKERRQ(ierr); 48a13144ffSStefano Zampini ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); 49a13144ffSStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 50a13144ffSStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("A","N",&bM,&bN,data,&bM,sing,U,&bM,&ds,&di,uwork,&lwork,&lierr)); 51a13144ffSStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 52a13144ffSStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 53a13144ffSStefano Zampini ierr = MatDenseRestoreArray(A,&data);CHKERRQ(ierr); 54a13144ffSStefano Zampini for (i=0;i<n;i++) if (sing[i] < PETSC_SMALL) break; 55a13144ffSStefano Zampini if (!rwork) { 56a13144ffSStefano Zampini ierr = PetscFree(sing);CHKERRQ(ierr); 57a13144ffSStefano Zampini } 58a13144ffSStefano Zampini if (!work) { 59a13144ffSStefano Zampini ierr = PetscFree(uwork);CHKERRQ(ierr); 60a13144ffSStefano Zampini } 61a13144ffSStefano Zampini /* create B */ 62a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,nr-i,NULL,B);CHKERRQ(ierr); 63a13144ffSStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 64a13144ffSStefano Zampini ierr = PetscMemcpy(data,U+nr*i,(nr-i)*nr*sizeof(PetscScalar));CHKERRQ(ierr); 65a13144ffSStefano Zampini ierr = MatDenseRestoreArray(*B,&data);CHKERRQ(ierr); 66a13144ffSStefano Zampini ierr = PetscFree(U);CHKERRQ(ierr); 67a13144ffSStefano Zampini #else 68a13144ffSStefano Zampini PetscFunctionBegin; 69a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for complexes"); 70a13144ffSStefano Zampini #endif 71a13144ffSStefano Zampini PetscFunctionReturn(0); 72a13144ffSStefano Zampini } 73a13144ffSStefano Zampini 741e0482f5SStefano Zampini /* TODO REMOVE */ 751e0482f5SStefano Zampini #if defined(PRINT_GDET) 761e0482f5SStefano Zampini static int inc = 0; 771e0482f5SStefano Zampini static int lev = 0; 781e0482f5SStefano Zampini #endif 791e0482f5SStefano Zampini 80a13144ffSStefano Zampini #undef __FUNCT__ 81a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCComputeNedelecChangeEdge" 821e0482f5SStefano Zampini PetscErrorCode PCBDDCComputeNedelecChangeEdge(Mat lG, IS edge, IS extrow, IS extcol, IS corners, Mat* Gins, Mat* GKins, PetscScalar cvals[2], PetscScalar *work, PetscReal *rwork) 83a13144ffSStefano Zampini { 84a13144ffSStefano Zampini PetscErrorCode ierr; 85a13144ffSStefano Zampini Mat GE,GEd; 86a13144ffSStefano Zampini PetscInt rsize,csize,esize; 87a13144ffSStefano Zampini PetscScalar *ptr; 88a13144ffSStefano Zampini 89a13144ffSStefano Zampini PetscFunctionBegin; 90a13144ffSStefano Zampini ierr = ISGetSize(edge,&esize);CHKERRQ(ierr); 91c3c0e390SStefano Zampini if (!esize) PetscFunctionReturn(0); 92a13144ffSStefano Zampini ierr = ISGetSize(extrow,&rsize);CHKERRQ(ierr); 93a13144ffSStefano Zampini ierr = ISGetSize(extcol,&csize);CHKERRQ(ierr); 94a13144ffSStefano Zampini 95a13144ffSStefano Zampini /* gradients */ 96a13144ffSStefano Zampini ptr = work + 5*esize; 97a13144ffSStefano Zampini ierr = MatGetSubMatrix(lG,extrow,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 98a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,rsize,csize,ptr,Gins);CHKERRQ(ierr); 99a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,Gins);CHKERRQ(ierr); 100a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 101a13144ffSStefano Zampini 102a13144ffSStefano Zampini /* constants */ 103a13144ffSStefano Zampini ptr += rsize*csize; 104a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,esize,csize,ptr,&GEd);CHKERRQ(ierr); 105a13144ffSStefano Zampini ierr = MatGetSubMatrix(lG,edge,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 106a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,&GEd);CHKERRQ(ierr); 107a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 108a13144ffSStefano Zampini ierr = MatDense_OrthogonalComplement(GEd,5*esize,work,rwork,GKins);CHKERRQ(ierr); 109a13144ffSStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1101e0482f5SStefano Zampini 1111e0482f5SStefano Zampini if (corners) { 1121e0482f5SStefano Zampini Mat GEc; 1131e0482f5SStefano Zampini PetscScalar *vals,v; 1141e0482f5SStefano Zampini 1151e0482f5SStefano Zampini ierr = MatGetSubMatrix(lG,edge,corners,MAT_INITIAL_MATRIX,&GEc);CHKERRQ(ierr); 1161e0482f5SStefano Zampini ierr = MatTransposeMatMult(GEc,*GKins,MAT_INITIAL_MATRIX,1.0,&GEd);CHKERRQ(ierr); 1171e0482f5SStefano Zampini ierr = MatDenseGetArray(GEd,&vals);CHKERRQ(ierr); 1181e0482f5SStefano Zampini v = PetscAbsScalar(vals[0]); 1191e0482f5SStefano Zampini cvals[0] = vals[0]/v; 1201e0482f5SStefano Zampini cvals[1] = vals[1]/v; 1211e0482f5SStefano Zampini ierr = MatDenseRestoreArray(GEd,&vals);CHKERRQ(ierr); 1221e0482f5SStefano Zampini ierr = MatScale(*GKins,1./v);CHKERRQ(ierr); 1231e0482f5SStefano Zampini #if defined(PRINT_GDET) 1241e0482f5SStefano Zampini { 1251e0482f5SStefano Zampini PetscViewer viewer; 1261e0482f5SStefano Zampini char filename[256]; 1271e0482f5SStefano Zampini sprintf(filename,"Gdet_l%d_r%d_cc%d.m",lev,PetscGlobalRank,inc++); 1281e0482f5SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1291e0482f5SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1301e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEc,"GEc");CHKERRQ(ierr); 1311e0482f5SStefano Zampini ierr = MatView(GEc,viewer);CHKERRQ(ierr); 1321e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)(*GKins),"GK");CHKERRQ(ierr); 1331e0482f5SStefano Zampini ierr = MatView(*GKins,viewer);CHKERRQ(ierr); 1341e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEd,"Gproj");CHKERRQ(ierr); 1351e0482f5SStefano Zampini ierr = MatView(GEd,viewer);CHKERRQ(ierr); 1361e0482f5SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1371e0482f5SStefano Zampini } 1381e0482f5SStefano Zampini #endif 1391e0482f5SStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1401e0482f5SStefano Zampini ierr = MatDestroy(&GEc);CHKERRQ(ierr); 1411e0482f5SStefano Zampini } 1421e0482f5SStefano Zampini 143a13144ffSStefano Zampini PetscFunctionReturn(0); 144a13144ffSStefano Zampini } 145a13144ffSStefano Zampini 146a13144ffSStefano Zampini #undef __FUNCT__ 147a13144ffSStefano Zampini #define __FUNCT__ "PCBDDCNedelecSupport" 148a13144ffSStefano Zampini PetscErrorCode PCBDDCNedelecSupport(PC pc) 149a13144ffSStefano Zampini { 150a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 151a13144ffSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1520569b399SStefano Zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGe,lGinit; 153*eee23b56SStefano Zampini Vec tvec; 154a13144ffSStefano Zampini PetscSF sfv; 1551e0482f5SStefano Zampini ISLocalToGlobalMapping el2g,vl2g,fl2g,al2g; 156a13144ffSStefano Zampini MPI_Comm comm; 157c2151214SStefano Zampini IS lned,primals,allprimals,nedfieldlocal; 158c2151214SStefano Zampini IS *eedges,*extrows,*extcols,*alleedges; 159b03ebc13SStefano Zampini PetscBT btv,bte,btvc,btb,btvcand,btvi,btee,bter; 160a13144ffSStefano Zampini PetscScalar *vals,*work; 161a13144ffSStefano Zampini PetscReal *rwork; 162a13144ffSStefano Zampini const PetscInt *idxs,*ii,*jj,*iit,*jjt; 1631e0482f5SStefano Zampini PetscInt ne,nv,Lv,order,n,field; 164a13144ffSStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 165*eee23b56SStefano Zampini PetscInt i,j,extmem,cum,maxsize,nee; 166b03ebc13SStefano Zampini PetscInt *extrow,*extrowcum,*marks,*vmarks,*gidxs; 167a13144ffSStefano Zampini PetscInt *sfvleaves,*sfvroots; 168b03ebc13SStefano Zampini PetscInt *corners,*cedges; 169b03ebc13SStefano Zampini #if defined(PETSC_USE_DEBUG) 170b03ebc13SStefano Zampini PetscInt *emarks; 171b03ebc13SStefano Zampini #endif 1721e0482f5SStefano Zampini PetscBool print,eerr,done,lrc[2],conforming,global; 173a13144ffSStefano Zampini PetscErrorCode ierr; 174a13144ffSStefano Zampini 175a13144ffSStefano Zampini PetscFunctionBegin; 176a13144ffSStefano Zampini /* test variable order code and print debug info TODO: to be removed */ 177a13144ffSStefano Zampini print = PETSC_FALSE; 178a13144ffSStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_print_nedelec",&print,NULL);CHKERRQ(ierr); 179a13144ffSStefano Zampini ierr = PetscOptionsGetInt(NULL,NULL,"-pc_bddc_nedelec_order",&pcbddc->nedorder,NULL);CHKERRQ(ierr); 180a13144ffSStefano Zampini 181a13144ffSStefano Zampini /* Return to caller if there are no edges in the decomposition */ 182a13144ffSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 1831e0482f5SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&al2g,NULL);CHKERRQ(ierr); 1841e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(al2g,&n);CHKERRQ(ierr); 185a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 186a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 187c2151214SStefano Zampini for (i=0;i<n;i++) { 188a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 189a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 190a13144ffSStefano Zampini break; 191a13144ffSStefano Zampini } 192a13144ffSStefano Zampini } 193a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 194a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 195a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 196a13144ffSStefano Zampini 1971e0482f5SStefano Zampini /* If the discrete gradient is defined for a subset of dofs and global is true, 1981e0482f5SStefano Zampini it assumes G is given in global ordering for all the dofs. 1991e0482f5SStefano Zampini Otherwise, the ordering is global for the Nedelec field */ 200a13144ffSStefano Zampini order = pcbddc->nedorder; 201a13144ffSStefano Zampini conforming = pcbddc->conforming; 202c2151214SStefano Zampini field = pcbddc->nedfield; 2031e0482f5SStefano Zampini global = pcbddc->nedglobal; 204c2151214SStefano Zampini if (pcbddc->n_ISForDofsLocal && field >= pcbddc->n_ISForDofsLocal) SETERRQ2(comm,PETSC_ERR_USER,"Invalid field for Nedelec %d: number of fields is %d",field,pcbddc->n_ISForDofsLocal); 205c2151214SStefano Zampini if (pcbddc->n_ISForDofsLocal && field > -1) { 2061e0482f5SStefano Zampini PetscBool setprimal = PETSC_FALSE; 2071e0482f5SStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_nedelec_field_primal",&setprimal,NULL);CHKERRQ(ierr); 208c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[field]);CHKERRQ(ierr); 209c2151214SStefano Zampini nedfieldlocal = pcbddc->ISForDofsLocal[field]; 210c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 2111e0482f5SStefano Zampini if (setprimal) { 212*eee23b56SStefano Zampini IS enedfieldlocal; 213*eee23b56SStefano Zampini PetscInt *eidxs; 214*eee23b56SStefano Zampini 215*eee23b56SStefano Zampini ierr = PetscMalloc1(ne,&eidxs);CHKERRQ(ierr); 216*eee23b56SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 217*eee23b56SStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 218*eee23b56SStefano Zampini for (i=0,cum=0;i<ne;i++) { 219*eee23b56SStefano Zampini if (PetscRealPart(vals[idxs[i]]) > 2.) { 220*eee23b56SStefano Zampini eidxs[cum++] = idxs[i]; 221*eee23b56SStefano Zampini } 222*eee23b56SStefano Zampini } 223*eee23b56SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 224*eee23b56SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 225*eee23b56SStefano Zampini ierr = ISCreateGeneral(comm,cum,eidxs,PETSC_COPY_VALUES,&enedfieldlocal);CHKERRQ(ierr); 226*eee23b56SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,enedfieldlocal);CHKERRQ(ierr); 227*eee23b56SStefano Zampini ierr = PetscFree(eidxs);CHKERRQ(ierr); 2281e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 229*eee23b56SStefano Zampini ierr = ISDestroy(&enedfieldlocal);CHKERRQ(ierr); 2301e0482f5SStefano Zampini PetscFunctionReturn(0); 2311e0482f5SStefano Zampini } 2321e0482f5SStefano Zampini } else if (!pcbddc->n_ISForDofsLocal) { 233c2151214SStefano Zampini PetscBool testnedfield = PETSC_FALSE; 234c2151214SStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-pc_bddc_nedelec_field",&testnedfield,NULL);CHKERRQ(ierr); 235c2151214SStefano Zampini if (!testnedfield) { 236c2151214SStefano Zampini ne = n; 237c2151214SStefano Zampini nedfieldlocal = NULL; 238c2151214SStefano Zampini } else { 239c2151214SStefano Zampini /* ierr = ISCreateStride(comm,n,0,1,&nedfieldlocal);CHKERRQ(ierr); */ 240c2151214SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 241c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 242c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 243c2151214SStefano Zampini for (i=0;i<n;i++) matis->sf_leafdata[i] = 1; 244c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 245c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 246c2151214SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 247c2151214SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 248c2151214SStefano Zampini for (i=0,cum=0;i<n;i++) { 249c2151214SStefano Zampini if (matis->sf_leafdata[i] > 1) { 250c2151214SStefano Zampini matis->sf_leafdata[cum++] = i; 251c2151214SStefano Zampini } 252c2151214SStefano Zampini } 253c2151214SStefano Zampini ierr = ISCreateGeneral(comm,cum,matis->sf_leafdata,PETSC_COPY_VALUES,&nedfieldlocal);CHKERRQ(ierr); 254c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 255c2151214SStefano Zampini } 2561e0482f5SStefano Zampini global = PETSC_TRUE; 2571e0482f5SStefano Zampini } else { 2581e0482f5SStefano Zampini SETERRQ(comm,PETSC_ERR_USER,"When multiple fields are present, the Nedelec field has to be specified"); 259c2151214SStefano Zampini } 260a13144ffSStefano Zampini 261c2151214SStefano Zampini if (nedfieldlocal) { /* merge with previous code when testing is done */ 262c2151214SStefano Zampini IS is; 263c2151214SStefano Zampini 264c2151214SStefano Zampini /* need to map from the local Nedelec field to local numbering */ 265c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nedfieldlocal,&fl2g);CHKERRQ(ierr); 2661e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering for the whole dofs*/ 2671e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(al2g,nedfieldlocal,&is);CHKERRQ(ierr); 2681e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&al2g);CHKERRQ(ierr); 2691e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering (for Nedelec only) */ 2701e0482f5SStefano Zampini if (global) { 2711e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 2721e0482f5SStefano Zampini el2g = al2g; 2731e0482f5SStefano Zampini } else { 2741e0482f5SStefano Zampini IS gis; 2751e0482f5SStefano Zampini 2761e0482f5SStefano Zampini ierr = ISRenumber(is,NULL,NULL,&gis);CHKERRQ(ierr); 2771e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gis,&el2g);CHKERRQ(ierr); 2781e0482f5SStefano Zampini ierr = ISDestroy(&gis);CHKERRQ(ierr); 2791e0482f5SStefano Zampini } 280c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 281c2151214SStefano Zampini } else { 2821e0482f5SStefano Zampini /* restore default */ 2831e0482f5SStefano Zampini pcbddc->nedfield = -1; 2841e0482f5SStefano Zampini /* one ref for the destruction of al2g, one for el2g */ 2851e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 2861e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 2871e0482f5SStefano Zampini el2g = al2g; 288c2151214SStefano Zampini fl2g = NULL; 289c2151214SStefano Zampini } 290a13144ffSStefano Zampini 291a13144ffSStefano Zampini /* Sanity checks */ 292a13144ffSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 293a13144ffSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 294a13144ffSStefano Zampini if (order && ne%order) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"The number of local edge dofs %d it's not a multiple of the order %d",ne,order); 295a13144ffSStefano Zampini 2961e0482f5SStefano Zampini /* Drop connections for interior edges */ 2971e0482f5SStefano Zampini ierr = MatDuplicate(pcbddc->discretegradient,MAT_COPY_VALUES,&G);CHKERRQ(ierr); 2981e0482f5SStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 299c2151214SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 300c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 301c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 302c2151214SStefano Zampini if (nedfieldlocal) { 303c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 304c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 305c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 306c2151214SStefano Zampini } else { 307c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 308c2151214SStefano Zampini } 309c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 310c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 3111e0482f5SStefano Zampini if (global) { 3121e0482f5SStefano Zampini PetscInt rst; 3131e0482f5SStefano Zampini 314c2151214SStefano Zampini ierr = MatGetOwnershipRange(G,&rst,NULL);CHKERRQ(ierr); 315c2151214SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 316c2151214SStefano Zampini if (matis->sf_rootdata[i] < 2) { 317c2151214SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 318c2151214SStefano Zampini } 319c2151214SStefano Zampini } 320a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 321c2151214SStefano Zampini ierr = MatZeroRows(G,cum,matis->sf_rootdata,0.,NULL,NULL);CHKERRQ(ierr); 3221e0482f5SStefano Zampini } else { 3231e0482f5SStefano Zampini PetscInt *tbz; 3241e0482f5SStefano Zampini 3251e0482f5SStefano Zampini ierr = PetscMalloc1(ne,&tbz);CHKERRQ(ierr); 3261e0482f5SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3271e0482f5SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3281e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3291e0482f5SStefano Zampini for (i=0,cum=0;i<ne;i++) 3301e0482f5SStefano Zampini if (matis->sf_leafdata[idxs[i]] == 1) 3311e0482f5SStefano Zampini tbz[cum++] = i; 3321e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3331e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApply(el2g,cum,tbz,tbz);CHKERRQ(ierr); 3341e0482f5SStefano Zampini ierr = MatZeroRows(G,cum,tbz,0.,NULL,NULL);CHKERRQ(ierr); 3351e0482f5SStefano Zampini ierr = PetscFree(tbz);CHKERRQ(ierr); 3361e0482f5SStefano Zampini } 337a13144ffSStefano Zampini 338a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 339a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 340a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 341a13144ffSStefano Zampini ierr = MatGetSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 342a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 343a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 344a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 345a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 346a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 347a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 348a13144ffSStefano Zampini if (print) { 349a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 350a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 351a13144ffSStefano Zampini } 352a13144ffSStefano Zampini 353a13144ffSStefano Zampini /* SF for nodal communications */ 354c2151214SStefano Zampini ierr = MatGetLocalSize(G,NULL,&Lv);CHKERRQ(ierr); 355a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 356a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 357a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 358a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 359a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 360a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 361a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 362a13144ffSStefano Zampini ierr = PetscMalloc2(nv,&sfvleaves,Lv,&sfvroots);CHKERRQ(ierr); 363a13144ffSStefano Zampini 3641e0482f5SStefano Zampini /* Destroy temporary G created in MATIS format and modified G */ 3651e0482f5SStefano Zampini ierr = MatDestroy(&G);CHKERRQ(ierr); 366a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 367a13144ffSStefano Zampini 3680569b399SStefano Zampini /* Save lG */ 3690569b399SStefano Zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGinit);CHKERRQ(ierr); 3700569b399SStefano Zampini 371a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 3724e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 3734e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 374a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 375a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 376a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 377c2151214SStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 378a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 379a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 380a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 381c2151214SStefano Zampini IS is; 382c2151214SStefano Zampini 383c2151214SStefano Zampini if (fl2g) { 384c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->DirichletBoundariesLocal,&is);CHKERRQ(ierr); 385c2151214SStefano Zampini } else { 386c2151214SStefano Zampini is = pcbddc->DirichletBoundariesLocal; 387c2151214SStefano Zampini } 388c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 389c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 390a13144ffSStefano Zampini for (i=0;i<cum;i++) { 391a13144ffSStefano Zampini if (idxs[i] >= 0) { 392a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 393a13144ffSStefano Zampini } 394a13144ffSStefano Zampini } 395c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 396c2151214SStefano Zampini if (fl2g) { 397c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 398c2151214SStefano Zampini } 399a13144ffSStefano Zampini } 400a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 401c2151214SStefano Zampini IS is; 402c2151214SStefano Zampini 403c2151214SStefano Zampini if (fl2g) { 404c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->NeumannBoundariesLocal,&is);CHKERRQ(ierr); 405c2151214SStefano Zampini } else { 406c2151214SStefano Zampini is = pcbddc->NeumannBoundariesLocal; 407c2151214SStefano Zampini } 408c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 409c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 410a13144ffSStefano Zampini for (i=0;i<cum;i++) { 411a13144ffSStefano Zampini if (idxs[i] >= 0) { 412a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 413a13144ffSStefano Zampini } 414a13144ffSStefano Zampini } 415c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 416c2151214SStefano Zampini if (fl2g) { 417c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 418a13144ffSStefano Zampini } 419c2151214SStefano Zampini } 420c2151214SStefano Zampini 421a13144ffSStefano Zampini /* need to remove coarse faces' dofs to ensure the 422a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 423a13144ffSStefano Zampini ierr = PetscCalloc1(ne,&marks);CHKERRQ(ierr); 42462b0c6f7SStefano Zampini ierr = PetscBTCreate(ne,&btee);CHKERRQ(ierr); 425a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 42662b0c6f7SStefano Zampini for (i=1;i<n_neigh;i++) 42762b0c6f7SStefano Zampini for (j=0;j<n_shared[i];j++) 42862b0c6f7SStefano Zampini marks[shared[i][j]]++; 429a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 43062b0c6f7SStefano Zampini for (i=0;i<ne;i++) { 43162b0c6f7SStefano Zampini if (marks[i] > 1 || (marks[i] == 1 && PetscBTLookup(btb,i))) { 43262b0c6f7SStefano Zampini ierr = PetscBTSet(btee,i);CHKERRQ(ierr); 43362b0c6f7SStefano Zampini } 43462b0c6f7SStefano Zampini } 43562b0c6f7SStefano Zampini 43662b0c6f7SStefano Zampini if (!conforming) { 43762b0c6f7SStefano Zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 43862b0c6f7SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 43962b0c6f7SStefano Zampini } 4404e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 441dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 44262b0c6f7SStefano Zampini cum = 0; 443a13144ffSStefano Zampini for (i=0;i<ne;i++) { 444dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 44562b0c6f7SStefano Zampini if (!PetscBTLookup(btee,i)) { 446a13144ffSStefano Zampini marks[cum++] = i; 447dec27d64SStefano Zampini continue; 448dec27d64SStefano Zampini } 449dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 45062b0c6f7SStefano Zampini if (!conforming) { 45162b0c6f7SStefano Zampini if (ii[i+1]-ii[i] != order + 1) { /* every row of G on the coarse edge should list order+1 nodal dofs */ 452a13144ffSStefano Zampini marks[cum++] = i; 453a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 454a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 455a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 456a13144ffSStefano Zampini } 45762b0c6f7SStefano Zampini } else { 45862b0c6f7SStefano Zampini /* every edge dofs should be connected trough a certain number of nodal dofs 45962b0c6f7SStefano Zampini to other edge dofs belonging to coarse edges 46062b0c6f7SStefano Zampini - at most 2 endpoints 46162b0c6f7SStefano Zampini - order-1 interior nodal dofs 46262b0c6f7SStefano Zampini - no undefined nodal dofs (nconn < order) 46362b0c6f7SStefano Zampini */ 46462b0c6f7SStefano Zampini PetscInt ends = 0,ints = 0, undef = 0; 46562b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 46662b0c6f7SStefano Zampini PetscInt v = jj[j],k; 46762b0c6f7SStefano Zampini PetscInt nconn = iit[v+1]-iit[v]; 46862b0c6f7SStefano Zampini for (k=iit[v];k<iit[v+1];k++) if (!PetscBTLookup(btee,jjt[k])) nconn--; 46962b0c6f7SStefano Zampini if (nconn > order) ends++; 47062b0c6f7SStefano Zampini else if (nconn == order) ints++; 47162b0c6f7SStefano Zampini else undef++; 47262b0c6f7SStefano Zampini } 47362b0c6f7SStefano Zampini if (undef || ends > 2 || ints != order -1) { 47462b0c6f7SStefano Zampini marks[cum++] = i; 47562b0c6f7SStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 47662b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 47762b0c6f7SStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 47862b0c6f7SStefano Zampini } 47962b0c6f7SStefano Zampini } 48062b0c6f7SStefano Zampini } 481a13144ffSStefano Zampini } 482dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 483dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 484dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 485dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 486a13144ffSStefano Zampini } 487dec27d64SStefano Zampini } 48862b0c6f7SStefano Zampini ierr = PetscBTDestroy(&btee);CHKERRQ(ierr); 489dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 4904e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 49162b0c6f7SStefano Zampini if (!conforming) { 49262b0c6f7SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 49362b0c6f7SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 49462b0c6f7SStefano Zampini } 4954e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 496b03ebc13SStefano Zampini /* identify splitpoints and corner candidates */ 4974e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 498a13144ffSStefano Zampini if (print) { 4994e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 5004e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 5014e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 502a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 503a13144ffSStefano Zampini } 504a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 505dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 506a13144ffSStefano Zampini for (i=0;i<nv;i++) { 507dec27d64SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i]; 508b03ebc13SStefano Zampini if (!order) { /* variable order */ 509dec27d64SStefano Zampini PetscReal vorder = 0.; 510dec27d64SStefano Zampini 511dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 512dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 513dec27d64SStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%d)",vorder,test); 514dec27d64SStefano Zampini ord = 1; 515dec27d64SStefano Zampini } 516a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 517dec27d64SStefano Zampini if (test%ord) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected number of edge dofs %d connected with nodal dof %d with order %d",test,i,ord); 518a13144ffSStefano Zampini #endif 519dec27d64SStefano Zampini if (test >= 3*ord) { /* splitpoints */ 520a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %d\n",i); 521a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 522dec27d64SStefano Zampini } else if (test == ord) { 523b03ebc13SStefano Zampini if (order == 1 || (!order && ii[i+1]-ii[i] == 1)) { 524a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %d\n",i); 525a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 526a13144ffSStefano Zampini } else { 527a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %d\n",i); 528a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 529a13144ffSStefano Zampini } 530a13144ffSStefano Zampini } 531a13144ffSStefano Zampini } 532b03ebc13SStefano Zampini 533b03ebc13SStefano Zampini /* a candidate is valid if it is connected to another candidate via a non-primal edge dof */ 534b03ebc13SStefano Zampini if (order != 1) { 535b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"INSPECTING CANDIDATES\n"); 536b03ebc13SStefano Zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 537b03ebc13SStefano Zampini for (i=0;i<nv;i++) { 538b03ebc13SStefano Zampini if (PetscBTLookup(btvcand,i)) { 539b03ebc13SStefano Zampini PetscBool found = PETSC_FALSE; 540b03ebc13SStefano Zampini for (j=ii[i];j<ii[i+1] && !found;j++) { 541b03ebc13SStefano Zampini PetscInt k,e = jj[j]; 542b03ebc13SStefano Zampini if (PetscBTLookup(bte,e)) continue; 543b03ebc13SStefano Zampini for (k=iit[e];k<iit[e+1];k++) { 544b03ebc13SStefano Zampini PetscInt v = jjt[k]; 545b03ebc13SStefano Zampini if (v != i && PetscBTLookup(btvcand,v)) { 546b03ebc13SStefano Zampini found = PETSC_TRUE; 547b03ebc13SStefano Zampini break; 548b03ebc13SStefano Zampini } 549b03ebc13SStefano Zampini } 550b03ebc13SStefano Zampini } 551b03ebc13SStefano Zampini if (!found) { 552b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d CLEARED\n",i); 553b03ebc13SStefano Zampini ierr = PetscBTClear(btvcand,i);CHKERRQ(ierr); 554b03ebc13SStefano Zampini } else { 555b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d ACCEPTED\n",i); 556b03ebc13SStefano Zampini } 557b03ebc13SStefano Zampini } 558b03ebc13SStefano Zampini } 559b03ebc13SStefano Zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 560b03ebc13SStefano Zampini } 561dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 562a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 563b03ebc13SStefano Zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 564a13144ffSStefano Zampini 565a13144ffSStefano Zampini /* Get the local G^T explicitly */ 5660569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 567a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 5684e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 569a13144ffSStefano Zampini 5704e64d54eSstefano_zampini /* Mark interior nodal dofs */ 571a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 5724e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 573a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 574a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 5754e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 576a13144ffSStefano Zampini } 577a13144ffSStefano Zampini } 578a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 579a13144ffSStefano Zampini 580a13144ffSStefano Zampini /* communicate corners and splitpoints */ 581a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 582a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 583a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 584a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 585a13144ffSStefano Zampini 586a13144ffSStefano Zampini if (print) { 587a13144ffSStefano Zampini IS tbz; 588a13144ffSStefano Zampini 589a13144ffSStefano Zampini cum = 0; 590a13144ffSStefano Zampini for (i=0;i<nv;i++) 591a13144ffSStefano Zampini if (sfvleaves[i]) 592a13144ffSStefano Zampini vmarks[cum++] = i; 593a13144ffSStefano Zampini 594a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 595a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 596a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 597a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 598a13144ffSStefano Zampini } 599a13144ffSStefano Zampini 600a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 601a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 602a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 603a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 604a13144ffSStefano Zampini 6054e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 6064e64d54eSstefano_zampini and interior nodal dofs */ 607a13144ffSStefano Zampini cum = 0; 608a13144ffSStefano Zampini for (i=0;i<nv;i++) { 609a13144ffSStefano Zampini if (sfvleaves[i]) { 610a13144ffSStefano Zampini vmarks[cum++] = i; 611a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 612a13144ffSStefano Zampini } 6134e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 614a13144ffSStefano Zampini } 6154e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 616a13144ffSStefano Zampini if (print) { 617a13144ffSStefano Zampini IS tbz; 618a13144ffSStefano Zampini 619a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 6204e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 621a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 622a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 623a13144ffSStefano Zampini } 624a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 625a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 626a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 627a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 628a13144ffSStefano Zampini 629a13144ffSStefano Zampini /* Recompute G */ 630a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 631a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 632a13144ffSStefano Zampini if (print) { 633a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 634a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 635a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 636a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 637a13144ffSStefano Zampini } 638a13144ffSStefano Zampini 639a13144ffSStefano Zampini /* Get primal dofs (if any) */ 640a13144ffSStefano Zampini cum = 0; 641a13144ffSStefano Zampini for (i=0;i<ne;i++) { 642a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 643a13144ffSStefano Zampini } 644c2151214SStefano Zampini if (fl2g) { 645c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 646c2151214SStefano Zampini } 647a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 648a13144ffSStefano Zampini if (print) { 649a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 650a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 651a13144ffSStefano Zampini } 652a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 653c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 654a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 655a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 656a13144ffSStefano Zampini 657a13144ffSStefano Zampini /* Compute edge connectivity */ 658a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 659a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 660a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 661c2151214SStefano Zampini if (fl2g) { 662c2151214SStefano Zampini PetscBT btf; 663c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 664c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 665c2151214SStefano Zampini 666c2151214SStefano Zampini /* create CSR for all local dofs */ 667c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 668c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 669c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Invalid size of CSR graph %d. Should be %d\n",pcbddc->mat_graph->nvtxs_csr,n); 670c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 671c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 672c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 673c2151214SStefano Zampini rest = PETSC_TRUE; 674c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 675c2151214SStefano Zampini } else { 676c2151214SStefano Zampini free = PETSC_TRUE; 677c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 678c2151214SStefano Zampini iiu[0] = 0; 679c2151214SStefano Zampini for (i=0;i<n;i++) { 680c2151214SStefano Zampini iiu[i+1] = i+1; 681c2151214SStefano Zampini jju[i] = -1; 682d904f53bSStefano Zampini } 683c2151214SStefano Zampini } 684c2151214SStefano Zampini 685c2151214SStefano Zampini /* import sizes of CSR */ 686c2151214SStefano Zampini iia[0] = 0; 687c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 688c2151214SStefano Zampini 689c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 690c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 691c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 692c2151214SStefano Zampini for (i=0;i<ne;i++) { 693c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 694c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 695c2151214SStefano Zampini } 696c2151214SStefano Zampini 697c2151214SStefano Zampini /* iia in CSR */ 698c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 699c2151214SStefano Zampini 700c2151214SStefano Zampini /* jja in CSR */ 701c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 702c2151214SStefano Zampini for (i=0;i<n;i++) 703c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 704c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 705c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 706c2151214SStefano Zampini 707c2151214SStefano Zampini /* map edge dofs connectivity */ 7081e0482f5SStefano Zampini if (jj) { 709c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 710c2151214SStefano Zampini for (i=0;i<ne;i++) { 711c2151214SStefano Zampini PetscInt e = idxs[i]; 712c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 713c2151214SStefano Zampini } 7141e0482f5SStefano Zampini } 715c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 716c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 717c2151214SStefano Zampini if (rest) { 718c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 719c2151214SStefano Zampini } 720c2151214SStefano Zampini if (free) { 721c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 722c2151214SStefano Zampini } 723c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 724c2151214SStefano Zampini } else { 7251e0482f5SStefano Zampini if (jj) { 726c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 727c2151214SStefano Zampini } 728c2151214SStefano Zampini } 729c2151214SStefano Zampini 730a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 731a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 732a13144ffSStefano Zampini 733a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 734c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 735a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 736a13144ffSStefano Zampini 737c2151214SStefano Zampini if (fl2g) { 738c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 739c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 740c2151214SStefano Zampini for (i=0;i<nee;i++) { 741c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 742c2151214SStefano Zampini } 743c2151214SStefano Zampini } else { 744c2151214SStefano Zampini eedges = alleedges; 745c2151214SStefano Zampini primals = allprimals; 746c2151214SStefano Zampini } 747c2151214SStefano Zampini 748a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 749a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 750c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 751c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 752c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 753c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 754c2151214SStefano Zampini if (print) { 755c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 756c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 757c2151214SStefano Zampini } 758c2151214SStefano Zampini 759c2151214SStefano Zampini maxsize = 0; 760a13144ffSStefano Zampini for (i=0;i<nee;i++) { 761a13144ffSStefano Zampini PetscInt size,mark = i+1; 762a13144ffSStefano Zampini 763a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 764a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 765a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 766a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 767a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 768a13144ffSStefano Zampini } 769a13144ffSStefano Zampini 770a13144ffSStefano Zampini /* Find coarse edge endpoints */ 771a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 772a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 773a13144ffSStefano Zampini for (i=0;i<nee;i++) { 774a13144ffSStefano Zampini PetscInt mark = i+1,size; 775a13144ffSStefano Zampini 776a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 7771e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 7781e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 779a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 780a13144ffSStefano Zampini if (print) { 781a13144ffSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %d\n",i); 782a13144ffSStefano Zampini ISView(eedges[i],NULL); 783a13144ffSStefano Zampini } 784a13144ffSStefano Zampini for (j=0;j<size;j++) { 785a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 786a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %d\n",ee); 787a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 788a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %d\n",jj[k]); 789a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 790a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %d\n",jj[k]); 791a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 792a13144ffSStefano Zampini PetscInt k2; 793a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 794a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 795c2151214SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," INSPECTING %d: mark %d (ref mark %d), boundary %d\n",jjt[k2],marks[jjt[k2]],mark,!!PetscBTLookup(btb,jjt[k2])); 796c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 797c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 798c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 799a13144ffSStefano Zampini corner = PETSC_TRUE; 800a13144ffSStefano Zampini break; 801a13144ffSStefano Zampini } 802a13144ffSStefano Zampini } 803a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 804a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %d\n",jj[k]); 805a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 806a13144ffSStefano Zampini } else { 807a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 808a13144ffSStefano Zampini } 809a13144ffSStefano Zampini } 810a13144ffSStefano Zampini } 811a13144ffSStefano Zampini } 812a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 813a13144ffSStefano Zampini } 814a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 815a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 816c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 817a13144ffSStefano Zampini 818a13144ffSStefano Zampini /* Reset marked primal dofs */ 819a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 820a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 821a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 822a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 823a13144ffSStefano Zampini 8240569b399SStefano Zampini /* Now use the initial lG */ 8250569b399SStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 8260569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 8270569b399SStefano Zampini lG = lGinit; 8280569b399SStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 8290569b399SStefano Zampini 830a13144ffSStefano Zampini /* Compute extended cols indices */ 831b03ebc13SStefano Zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 832b03ebc13SStefano Zampini ierr = PetscBTCreate(nee,&bter);CHKERRQ(ierr); 833a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 834a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 835a13144ffSStefano Zampini i *= maxsize; 836b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 837a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 838a13144ffSStefano Zampini eerr = PETSC_FALSE; 839a13144ffSStefano Zampini for (i=0;i<nee;i++) { 840b03ebc13SStefano Zampini PetscInt size,found = 0; 841a13144ffSStefano Zampini 842a13144ffSStefano Zampini cum = 0; 843a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8441e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8451e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 846a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 847b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 848a13144ffSStefano Zampini for (j=0;j<size;j++) { 849a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 850b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 851b03ebc13SStefano Zampini PetscInt vv = jj[k]; 852b03ebc13SStefano Zampini if (!PetscBTLookup(btv,vv)) extrow[cum++] = vv; 853b03ebc13SStefano Zampini else if (!PetscBTLookupSet(btvc,vv)) found++; 854b03ebc13SStefano Zampini } 855a13144ffSStefano Zampini } 856a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 857a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 858a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 859a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 860a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 861a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 862a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 863b03ebc13SStefano Zampini if (cum != size -1 || found != 2) { 864b03ebc13SStefano Zampini ierr = PetscBTSet(bter,i);CHKERRQ(ierr); 865a13144ffSStefano Zampini if (print) { 866a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 867a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 868a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 869a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 870a13144ffSStefano Zampini } 871a13144ffSStefano Zampini eerr = PETSC_TRUE; 872a13144ffSStefano Zampini } 873a13144ffSStefano Zampini } 8744e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 875a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 876a13144ffSStefano Zampini if (done) { 877a13144ffSStefano Zampini PetscInt *newprimals; 878a13144ffSStefano Zampini 879a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 880a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 881a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 882a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 883a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 8840569b399SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 885b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"DOING SECOND PASS (eerr %d)\n",eerr); 886a13144ffSStefano Zampini for (i=0;i<nee;i++) { 887b03ebc13SStefano Zampini PetscBool has_candidates = PETSC_FALSE; 888b03ebc13SStefano Zampini if (PetscBTLookup(bter,i)) { 889a13144ffSStefano Zampini PetscInt size,mark = i+1; 890a13144ffSStefano Zampini 891a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 892a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 893c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 894a13144ffSStefano Zampini for (j=0;j<size;j++) { 895a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 896b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"Inspecting edge dof %d [%d %d)\n",ee,ii[ee],ii[ee+1]); 897a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 898a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 899a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 900a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 901b03ebc13SStefano Zampini has_candidates = PETSC_TRUE; 902b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Candidate set to vertex %d\n",vv); 903a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 904a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 905a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 906a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 907a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 908b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected edge dof set to primal %d\n",ee2); 909a13144ffSStefano Zampini newprimals[cum++] = ee2; 910a13144ffSStefano Zampini /* finally set the new corners */ 911a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 912b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected nodal dof set to vertex %d\n",jj[k3]); 913a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 914a13144ffSStefano Zampini } 915a13144ffSStefano Zampini } 916a13144ffSStefano Zampini } 917b03ebc13SStefano Zampini } else { 918b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Not a candidate vertex %d\n",jj[k]); 919a13144ffSStefano Zampini } 920a13144ffSStefano Zampini } 921a13144ffSStefano Zampini } 922b03ebc13SStefano Zampini if (!has_candidates) { /* circular edge */ 923b03ebc13SStefano Zampini PetscInt k, ee = idxs[0],*tmarks; 924b03ebc13SStefano Zampini 925b03ebc13SStefano Zampini ierr = PetscCalloc1(ne,&tmarks);CHKERRQ(ierr); 926b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Circular edge %d\n",i); 927b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 928b03ebc13SStefano Zampini PetscInt k2; 929b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Set to corner %d\n",jj[k]); 930b03ebc13SStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 931b03ebc13SStefano Zampini for (k2=iit[jj[k]];k2<iit[jj[k]+1];k2++) tmarks[jjt[k2]]++; 932b03ebc13SStefano Zampini } 933b03ebc13SStefano Zampini for (j=0;j<size;j++) { 934b03ebc13SStefano Zampini if (tmarks[idxs[j]] > 1) { 935b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Edge dof set to primal %d\n",idxs[j]); 936b03ebc13SStefano Zampini newprimals[cum++] = idxs[j]; 937b03ebc13SStefano Zampini } 938b03ebc13SStefano Zampini } 939b03ebc13SStefano Zampini ierr = PetscFree(tmarks);CHKERRQ(ierr); 940b03ebc13SStefano Zampini } 941a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 942a13144ffSStefano Zampini } 943a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 944a13144ffSStefano Zampini } 945b03ebc13SStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 9460569b399SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 947a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 948c2151214SStefano Zampini if (fl2g) { 949c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 950c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 951c2151214SStefano Zampini for (i=0;i<nee;i++) { 952c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 953c2151214SStefano Zampini } 954c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 955c2151214SStefano Zampini } 956c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 957a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 958a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 959a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 960a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 961a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 962c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 963c2151214SStefano Zampini if (fl2g) { 964c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 965c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 966c2151214SStefano Zampini for (i=0;i<nee;i++) { 967c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 968c2151214SStefano Zampini } 969c2151214SStefano Zampini } else { 970c2151214SStefano Zampini eedges = alleedges; 971c2151214SStefano Zampini primals = allprimals; 972c2151214SStefano Zampini } 973b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 974a13144ffSStefano Zampini 975a13144ffSStefano Zampini /* Mark again */ 976a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 977a13144ffSStefano Zampini for (i=0;i<nee;i++) { 978a13144ffSStefano Zampini PetscInt size,mark = i+1; 979a13144ffSStefano Zampini 980a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 981a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 982a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 983a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 984a13144ffSStefano Zampini } 985a13144ffSStefano Zampini if (print) { 986a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 987a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 988a13144ffSStefano Zampini } 989a13144ffSStefano Zampini 990a13144ffSStefano Zampini /* Recompute extended cols */ 991a13144ffSStefano Zampini eerr = PETSC_FALSE; 992a13144ffSStefano Zampini for (i=0;i<nee;i++) { 993a13144ffSStefano Zampini PetscInt size; 994a13144ffSStefano Zampini 995a13144ffSStefano Zampini cum = 0; 996a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 9971e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 9981e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 999a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1000a13144ffSStefano Zampini for (j=0;j<size;j++) { 1001a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 10021e0482f5SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 1003a13144ffSStefano Zampini } 1004a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1005a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 1006a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 1007a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 1008a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 1009a13144ffSStefano Zampini if (cum != size -1) { 1010a13144ffSStefano Zampini if (print) { 1011a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 1012a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 1013a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 1014a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 1015a13144ffSStefano Zampini } 1016a13144ffSStefano Zampini eerr = PETSC_TRUE; 1017a13144ffSStefano Zampini } 1018a13144ffSStefano Zampini } 1019a13144ffSStefano Zampini } 1020a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1021a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 1022b03ebc13SStefano Zampini ierr = PetscBTDestroy(&bter);CHKERRQ(ierr); 1023a13144ffSStefano Zampini /* an error should not occur at this point */ 1024a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 1025b03ebc13SStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 1026a13144ffSStefano Zampini 10274e64d54eSstefano_zampini /* Check the number of endpoints */ 10280569b399SStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1029b03ebc13SStefano Zampini ierr = PetscMalloc1(2*nee,&corners);CHKERRQ(ierr); 1030b03ebc13SStefano Zampini ierr = PetscMalloc1(nee,&cedges);CHKERRQ(ierr); 10314e64d54eSstefano_zampini for (i=0;i<nee;i++) { 1032b03ebc13SStefano Zampini PetscInt size, found = 0, gc[2]; 10334e64d54eSstefano_zampini 1034b03ebc13SStefano Zampini /* init with defaults */ 1035b03ebc13SStefano Zampini cedges[i] = corners[i*2] = corners[i*2+1] = -1; 10364e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 10371e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 10381e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 10394e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1040b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 10414e64d54eSstefano_zampini for (j=0;j<size;j++) { 10424e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 10434e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 10444e64d54eSstefano_zampini PetscInt vv = jj[k]; 10454e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 1046b03ebc13SStefano Zampini if (found == 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found more then two corners for edge %d\n",i); 1047b03ebc13SStefano Zampini corners[i*2+found++] = vv; 10484e64d54eSstefano_zampini } 10494e64d54eSstefano_zampini } 10504e64d54eSstefano_zampini } 1051b03ebc13SStefano Zampini if (found != 2) { 1052b03ebc13SStefano Zampini PetscInt e; 1053b03ebc13SStefano Zampini if (fl2g) { 1054b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,1,idxs,&e);CHKERRQ(ierr); 1055b03ebc13SStefano Zampini } else { 1056b03ebc13SStefano Zampini e = idxs[0]; 1057b03ebc13SStefano Zampini } 1058b03ebc13SStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %d corners for edge %d (astart %d, estart %d)\n",found,i,e,idxs[0]); 1059b03ebc13SStefano Zampini } 1060*eee23b56SStefano Zampini 1061*eee23b56SStefano Zampini /* get primal dof index on this coarse edge */ 1062b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,2,corners+2*i,gc);CHKERRQ(ierr); 1063b03ebc13SStefano Zampini if (gc[0] > gc[1]) { 1064b03ebc13SStefano Zampini PetscInt swap = corners[2*i]; 1065b03ebc13SStefano Zampini corners[2*i] = corners[2*i+1]; 1066b03ebc13SStefano Zampini corners[2*i+1] = swap; 1067b03ebc13SStefano Zampini } 1068*eee23b56SStefano Zampini cedges[i] = idxs[size-1]; 10694e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1070b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"EDGE %d: ce %d, corners (%d,%d)\n",i,cedges[i],corners[2*i],corners[2*i+1]); 10714e64d54eSstefano_zampini } 10720569b399SStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 10734e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 10744e64d54eSstefano_zampini 1075a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 1076a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 1077a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 1078a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 1079a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1080a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1081a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 1082a13144ffSStefano Zampini 1083a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1084a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 1085a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 1086a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 1087a13144ffSStefano Zampini if (emax < emarks[j]) { 1088a13144ffSStefano Zampini emax = emarks[j]; 1089a13144ffSStefano Zampini eemax = j; 1090a13144ffSStefano Zampini } 1091a13144ffSStefano Zampini } 1092a13144ffSStefano Zampini /* not relevant for edges */ 1093a13144ffSStefano Zampini if (!eemax) continue; 1094a13144ffSStefano Zampini 1095a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 1096a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 1097c2151214SStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Found 2 coarse edges (id %d and %d) connected through the %d nodal dof at edge dof %d\n",marks[jj[j]]-1,eemax,i,jj[j]); 1098a13144ffSStefano Zampini } 1099a13144ffSStefano Zampini } 1100a13144ffSStefano Zampini } 1101a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 1102a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1103a13144ffSStefano Zampini #endif 1104a13144ffSStefano Zampini 1105a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 1106a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1107a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 1108a13144ffSStefano Zampini extmem *= maxsize; 1109a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 1110a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 1111a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 1112a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1113a13144ffSStefano Zampini PetscInt mark = 0,size,start; 1114a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1115a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 1116a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 1117a13144ffSStefano Zampini mark = marks[jj[j]]; 1118a13144ffSStefano Zampini 1119a13144ffSStefano Zampini /* not relevant */ 1120a13144ffSStefano Zampini if (!mark) continue; 1121a13144ffSStefano Zampini 1122a13144ffSStefano Zampini /* import extended row */ 1123a13144ffSStefano Zampini mark--; 1124a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 1125a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 1126a13144ffSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %d > %d",extrowcum[mark] + size,extmem); 1127a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 1128a13144ffSStefano Zampini extrowcum[mark] += size; 1129a13144ffSStefano Zampini } 1130a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1131a13144ffSStefano Zampini cum = 0; 1132a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1133a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 1134a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 1135a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 1136a13144ffSStefano Zampini cum = PetscMax(cum,size); 1137a13144ffSStefano Zampini } 1138a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 1139a13144ffSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 1140a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 1141a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 1142a13144ffSStefano Zampini 1143a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 1144a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 1145a13144ffSStefano Zampini 1146a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 1147a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1148c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 1149c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 1150a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 1151a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 1152a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 11531e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(T,al2g,al2g);CHKERRQ(ierr); 1154a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 1155a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1156a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_IGNORE_ZERO_ENTRIES,PETSC_TRUE);CHKERRQ(ierr); 1157a13144ffSStefano Zampini 1158a13144ffSStefano Zampini /* Defaults to identity */ 1159c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 1160a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 1161a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 1162a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 1163a13144ffSStefano Zampini 11641e0482f5SStefano Zampini /* Create discrete gradient for the coarser level if needed */ 11651e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 11661e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 11671e0482f5SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 11681e0482f5SStefano Zampini ISLocalToGlobalMapping cel2g,cvl2g; 11691e0482f5SStefano Zampini IS wis,gwis; 11701e0482f5SStefano Zampini PetscInt cnv,cne; 11711e0482f5SStefano Zampini 11721e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,nee,cedges,PETSC_COPY_VALUES,&wis);CHKERRQ(ierr); 11731e0482f5SStefano Zampini if (fl2g) { 11741e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(fl2g,wis,&pcbddc->nedclocal);CHKERRQ(ierr); 11751e0482f5SStefano Zampini } else { 11761e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)wis);CHKERRQ(ierr); 11771e0482f5SStefano Zampini pcbddc->nedclocal = wis; 11781e0482f5SStefano Zampini } 11791e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,wis,&gwis);CHKERRQ(ierr); 11801e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 11811e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cne,&wis);CHKERRQ(ierr); 11821e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cel2g);CHKERRQ(ierr); 11831e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 11841e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 11851e0482f5SStefano Zampini 11861e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,2*nee,corners,PETSC_USE_POINTER,&wis);CHKERRQ(ierr); 11871e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(vl2g,wis,&gwis);CHKERRQ(ierr); 11881e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 11891e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cnv,&wis);CHKERRQ(ierr); 11901e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cvl2g);CHKERRQ(ierr); 11911e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 11921e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 11931e0482f5SStefano Zampini 11941e0482f5SStefano Zampini ierr = MatCreate(comm,&pcbddc->nedcG);CHKERRQ(ierr); 11951e0482f5SStefano Zampini ierr = MatSetSizes(pcbddc->nedcG,PETSC_DECIDE,PETSC_DECIDE,cne,cnv);CHKERRQ(ierr); 11961e0482f5SStefano Zampini ierr = MatSetType(pcbddc->nedcG,MATAIJ);CHKERRQ(ierr); 11971e0482f5SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->nedcG,2,NULL);CHKERRQ(ierr); 11981e0482f5SStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->nedcG,2,NULL,2,NULL);CHKERRQ(ierr); 11991e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->nedcG,cel2g,cvl2g);CHKERRQ(ierr); 12001e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cel2g);CHKERRQ(ierr); 12011e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cvl2g);CHKERRQ(ierr); 12021e0482f5SStefano Zampini } 12031e0482f5SStefano Zampini 12041e0482f5SStefano Zampini #if defined(PRINT_GDET) 12051e0482f5SStefano Zampini inc = 0; 12061e0482f5SStefano Zampini lev = pcbddc->current_level; 12071e0482f5SStefano Zampini #endif 1208a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1209a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 12101e0482f5SStefano Zampini IS cornersis = NULL; 12111e0482f5SStefano Zampini PetscScalar cvals[2]; 1212a13144ffSStefano Zampini 12131e0482f5SStefano Zampini if (pcbddc->nedcG) { 12141e0482f5SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,2,corners+2*i,PETSC_USE_POINTER,&cornersis);CHKERRQ(ierr); 12151e0482f5SStefano Zampini } 12161e0482f5SStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],cornersis,&Gins,&GKins,cvals,work,rwork);CHKERRQ(ierr); 1217a13144ffSStefano Zampini if (Gins && GKins) { 1218a13144ffSStefano Zampini PetscScalar *data; 1219a13144ffSStefano Zampini const PetscInt *rows,*cols; 1220a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 1221a13144ffSStefano Zampini 1222a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 1223a13144ffSStefano Zampini /* H1 */ 1224a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 1225a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 1226a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 1227a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 1228a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 1229a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 1230a13144ffSStefano Zampini /* complement */ 1231a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 12321e0482f5SStefano Zampini if (!ncc) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Constant function has not been generated for coarse edge %d",i); 1233a13144ffSStefano Zampini if (ncc + nch != nrc) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"The sum of the number of columns of GKins %d and Gins %d does not match %d",ncc,nch,nrc); 12341e0482f5SStefano Zampini if (ncc != 1 && pcbddc->nedcG) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot generate the dicrete gradient for the next level with ncc %d",ncc); 1235a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 1236a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 1237a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 12381e0482f5SStefano Zampini 12391e0482f5SStefano Zampini /* coarse discrete gradient */ 12401e0482f5SStefano Zampini if (pcbddc->nedcG) { 12411e0482f5SStefano Zampini PetscInt cols[2]; 12421e0482f5SStefano Zampini 12431e0482f5SStefano Zampini cols[0] = 2*i; 12441e0482f5SStefano Zampini cols[1] = 2*i+1; 12451e0482f5SStefano Zampini ierr = MatSetValuesLocal(pcbddc->nedcG,1,&i,2,cols,cvals,INSERT_VALUES);CHKERRQ(ierr); 12461e0482f5SStefano Zampini } 1247a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 1248a13144ffSStefano Zampini } 1249a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 1250a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 12511e0482f5SStefano Zampini ierr = ISDestroy(&cornersis);CHKERRQ(ierr); 1252a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 1253a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 1254a13144ffSStefano Zampini } 1255a13144ffSStefano Zampini 1256a13144ffSStefano Zampini /* Start assembling */ 1257a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12581e0482f5SStefano Zampini if (pcbddc->nedcG) { 12591e0482f5SStefano Zampini ierr = MatAssemblyBegin(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 12601e0482f5SStefano Zampini } 1261a13144ffSStefano Zampini 1262a13144ffSStefano Zampini /* Free */ 1263c2151214SStefano Zampini if (fl2g) { 1264c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1265c2151214SStefano Zampini for (i=0;i<nee;i++) { 1266c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1267c2151214SStefano Zampini } 1268c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1269c2151214SStefano Zampini } 1270*eee23b56SStefano Zampini 1271*eee23b56SStefano Zampini /* hack mat_graph with primal dofs on the coarse edges */ 1272*eee23b56SStefano Zampini { 1273*eee23b56SStefano Zampini PCBDDCGraph graph = pcbddc->mat_graph; 1274*eee23b56SStefano Zampini PetscInt *oqueue = graph->queue; 1275*eee23b56SStefano Zampini PetscInt *ocptr = graph->cptr; 1276*eee23b56SStefano Zampini PetscInt ncc,*idxs; 1277*eee23b56SStefano Zampini 1278*eee23b56SStefano Zampini /* find first primal edge */ 1279*eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1280*eee23b56SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1281*eee23b56SStefano Zampini } else { 1282*eee23b56SStefano Zampini if (fl2g) { 1283*eee23b56SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,nee,cedges,cedges);CHKERRQ(ierr); 1284*eee23b56SStefano Zampini } 1285*eee23b56SStefano Zampini idxs = cedges; 1286*eee23b56SStefano Zampini } 1287*eee23b56SStefano Zampini cum = 0; 1288*eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1289*eee23b56SStefano Zampini 1290*eee23b56SStefano Zampini /* adapt connected components */ 1291*eee23b56SStefano Zampini ierr = PetscMalloc2(graph->nvtxs+1,&graph->cptr,ocptr[graph->ncc],&graph->queue);CHKERRQ(ierr); 1292*eee23b56SStefano Zampini graph->cptr[0] = 0; 1293*eee23b56SStefano Zampini for (i=0,ncc=0;i<graph->ncc;i++) { 1294*eee23b56SStefano Zampini PetscInt lc = ocptr[i+1]-ocptr[i]; 1295*eee23b56SStefano Zampini if (cum != nee && oqueue[ocptr[i+1]-1] == cedges[cum]) { /* this cc has a primal dof */ 1296*eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc]+1; 1297*eee23b56SStefano Zampini graph->queue[graph->cptr[ncc]] = cedges[cum]; 1298*eee23b56SStefano Zampini ncc++; 1299*eee23b56SStefano Zampini lc--; 1300*eee23b56SStefano Zampini cum++; 1301*eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1302*eee23b56SStefano Zampini } 1303*eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc] + lc; 1304*eee23b56SStefano Zampini for (j=0;j<lc;j++) graph->queue[graph->cptr[ncc]+j] = oqueue[ocptr[i]+j]; 1305*eee23b56SStefano Zampini ncc++; 1306*eee23b56SStefano Zampini } 1307*eee23b56SStefano Zampini graph->ncc = ncc; 1308*eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1309*eee23b56SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1310*eee23b56SStefano Zampini } 1311*eee23b56SStefano Zampini ierr = PetscFree2(ocptr,oqueue);CHKERRQ(ierr); 1312*eee23b56SStefano Zampini } 1313c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1314c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1315*eee23b56SStefano Zampini 1316*eee23b56SStefano Zampini 1317c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1318a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 1319a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 1320c2151214SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 13211e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&al2g);CHKERRQ(ierr); 1322c2151214SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 1323a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 1324b03ebc13SStefano Zampini ierr = PetscFree(corners);CHKERRQ(ierr); 1325b03ebc13SStefano Zampini ierr = PetscFree(cedges);CHKERRQ(ierr); 1326a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 1327a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 1328a13144ffSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 1329a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 1330a13144ffSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1331a13144ffSStefano Zampini 1332a13144ffSStefano Zampini /* Complete assembling */ 1333a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13341e0482f5SStefano Zampini if (pcbddc->nedcG) { 13351e0482f5SStefano Zampini ierr = MatAssemblyEnd(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13361e0482f5SStefano Zampini #if 0 13371e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->nedcG,"coarse_G");CHKERRQ(ierr); 13381e0482f5SStefano Zampini ierr = MatView(pcbddc->nedcG,NULL);CHKERRQ(ierr); 13391e0482f5SStefano Zampini #endif 13401e0482f5SStefano Zampini } 1341a13144ffSStefano Zampini 1342a13144ffSStefano Zampini /* set change of basis */ 1343a13144ffSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,PETSC_FALSE);CHKERRQ(ierr); 13441e0482f5SStefano Zampini #if 0 13451e0482f5SStefano Zampini if (pcbddc->current_level) { 13461e0482f5SStefano Zampini PetscViewer viewer; 13471e0482f5SStefano Zampini char filename[256]; 13481e0482f5SStefano Zampini Mat Tned; 13491e0482f5SStefano Zampini IS sub; 13501e0482f5SStefano Zampini PetscInt rst; 13511e0482f5SStefano Zampini 13521e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 13531e0482f5SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 13541e0482f5SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 13551e0482f5SStefano Zampini if (nedfieldlocal) { 13561e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 13571e0482f5SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 13581e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 13591e0482f5SStefano Zampini } else { 13601e0482f5SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 13611e0482f5SStefano Zampini } 13621e0482f5SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 13631e0482f5SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 13641e0482f5SStefano Zampini ierr = MatGetOwnershipRange(pc->pmat,&rst,NULL);CHKERRQ(ierr); 13651e0482f5SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 13661e0482f5SStefano Zampini if (matis->sf_rootdata[i]) { 13671e0482f5SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 13681e0482f5SStefano Zampini } 13691e0482f5SStefano Zampini } 13701e0482f5SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%D] LEVEL %d MY ne %d cum %d\n",PetscGlobalRank,pcbddc->current_level,ne,cum); 13711e0482f5SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),cum,matis->sf_rootdata,PETSC_USE_POINTER,&sub);CHKERRQ(ierr); 13721e0482f5SStefano Zampini ierr = MatGetSubMatrix(T,sub,sub,MAT_INITIAL_MATRIX,&Tned);CHKERRQ(ierr); 13731e0482f5SStefano Zampini ierr = ISDestroy(&sub);CHKERRQ(ierr); 13741e0482f5SStefano Zampini 13751e0482f5SStefano Zampini sprintf(filename,"Change_l%d.m",pcbddc->current_level); 13761e0482f5SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)Tned),filename,&viewer);CHKERRQ(ierr); 13771e0482f5SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 13781e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)Tned,"T");CHKERRQ(ierr); 13791e0482f5SStefano Zampini ierr = MatView(Tned,viewer);CHKERRQ(ierr); 13801e0482f5SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 13811e0482f5SStefano Zampini ierr = MatDestroy(&Tned);CHKERRQ(ierr); 13821e0482f5SStefano Zampini } 13831e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 13841e0482f5SStefano Zampini #endif 1385a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1386a13144ffSStefano Zampini 1387a13144ffSStefano Zampini PetscFunctionReturn(0); 1388a13144ffSStefano Zampini } 1389a13144ffSStefano Zampini 1390d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1391d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1392d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1393d8203eabSStefano Zampini #undef __FUNCT__ 1394d8203eabSStefano Zampini #define __FUNCT__ "PCBDDCNullSpaceCreate" 1395d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1396d8203eabSStefano Zampini { 1397d8203eabSStefano Zampini PetscErrorCode ierr; 1398d8203eabSStefano Zampini PetscInt i; 1399d8203eabSStefano Zampini 1400d8203eabSStefano Zampini PetscFunctionBegin; 1401d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1402d8203eabSStefano Zampini PetscInt first,last; 1403d8203eabSStefano Zampini 1404d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 140586fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1406d8203eabSStefano Zampini if (i>=first && i < last) { 1407d8203eabSStefano Zampini PetscScalar *data; 1408d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1409d8203eabSStefano Zampini if (!has_const) { 1410d8203eabSStefano Zampini data[i-first] = 1.; 1411d8203eabSStefano Zampini } else { 141286fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 141386fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1414d8203eabSStefano Zampini } 1415d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1416d8203eabSStefano Zampini } 1417d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1418d8203eabSStefano Zampini } 1419d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1420d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1421d8203eabSStefano Zampini PetscInt first,last; 1422d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1423d8203eabSStefano Zampini if (i>=first && i < last) { 1424d8203eabSStefano Zampini PetscScalar *data; 1425d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1426d8203eabSStefano Zampini if (!has_const) { 1427d8203eabSStefano Zampini data[i-first] = 0.; 1428d8203eabSStefano Zampini } else { 142986fa73c5SStefano Zampini data[2*i-first] = 0.; 143086fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1431d8203eabSStefano Zampini } 1432d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1433d8203eabSStefano Zampini } 1434d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1435d8203eabSStefano Zampini } 1436d8203eabSStefano Zampini PetscFunctionReturn(0); 1437d8203eabSStefano Zampini } 1438d8203eabSStefano Zampini 1439669cc0f4SStefano Zampini #undef __FUNCT__ 1440669cc0f4SStefano Zampini #define __FUNCT__ "PCBDDCComputeNoNetFlux" 14418ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1442669cc0f4SStefano Zampini { 1443a198735bSStefano Zampini Mat loc_divudotp; 1444fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 14458ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1446669cc0f4SStefano Zampini IS *faces,*edges; 1447669cc0f4SStefano Zampini PetscScalar *vals; 1448669cc0f4SStefano Zampini const PetscScalar *array; 1449669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 14501ae86dd6SStefano Zampini PetscMPIInt rank; 1451a198735bSStefano Zampini PetscErrorCode ierr; 1452669cc0f4SStefano Zampini 1453669cc0f4SStefano Zampini PetscFunctionBegin; 1454669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1455669cc0f4SStefano Zampini if (graph->twodim) { 1456669cc0f4SStefano Zampini lmaxneighs = 2; 1457669cc0f4SStefano Zampini } else { 1458669cc0f4SStefano Zampini lmaxneighs = 1; 1459669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1460669cc0f4SStefano Zampini const PetscInt *idxs; 1461669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1462669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 1463669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1464669cc0f4SStefano Zampini } 1465669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 1466669cc0f4SStefano Zampini } 1467669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 1468669cc0f4SStefano Zampini maxsize = 0; 1469669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1470669cc0f4SStefano Zampini PetscInt nn; 1471669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1472669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1473669cc0f4SStefano Zampini } 1474669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1475669cc0f4SStefano Zampini PetscInt nn; 1476669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1477669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1478669cc0f4SStefano Zampini } 1479669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1480669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1481669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 14828ae0ca82SStefano Zampini if (!transpose) { 14838ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 14848ae0ca82SStefano Zampini } else { 14858ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 14868ae0ca82SStefano Zampini } 1487669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 14881ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1489d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1490669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 14918ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 1492669cc0f4SStefano Zampini } 1493d8203eabSStefano Zampini 1494669cc0f4SStefano Zampini /* compute local quad vec */ 1495a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 14968ae0ca82SStefano Zampini if (!transpose) { 1497a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 14988ae0ca82SStefano Zampini } else { 14998ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 15008ae0ca82SStefano Zampini } 1501669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 15028ae0ca82SStefano Zampini if (!transpose) { 1503a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 15048ae0ca82SStefano Zampini } else { 15058ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 15068ae0ca82SStefano Zampini } 1507fa23a32eSStefano Zampini if (vl2l) { 1508fa23a32eSStefano Zampini ierr = VecGetSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1509fa23a32eSStefano Zampini } else { 1510fa23a32eSStefano Zampini vins = v; 1511fa23a32eSStefano Zampini } 1512fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1513669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 15149a962809SStefano Zampini 15151ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 15161ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1517669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1518669cc0f4SStefano Zampini const PetscInt *idxs; 1519669cc0f4SStefano Zampini PetscInt idx,nn,j; 1520669cc0f4SStefano Zampini 1521669cc0f4SStefano Zampini ierr = ISGetIndices(faces[i],&idxs);CHKERRQ(ierr); 1522669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1523669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 15241ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1525669cc0f4SStefano Zampini idx = -(idx+1); 1526669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1527669cc0f4SStefano Zampini ierr = ISRestoreIndices(faces[i],&idxs);CHKERRQ(ierr); 1528669cc0f4SStefano Zampini } 1529669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1530669cc0f4SStefano Zampini const PetscInt *idxs; 1531669cc0f4SStefano Zampini PetscInt idx,nn,j; 1532669cc0f4SStefano Zampini 1533669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1534669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1535669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 15361ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1537669cc0f4SStefano Zampini idx = -(idx+1); 1538669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1539669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1540669cc0f4SStefano Zampini } 1541c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1542fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1543fa23a32eSStefano Zampini if (vl2l) { 1544fa23a32eSStefano Zampini ierr = VecRestoreSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1545fa23a32eSStefano Zampini } 1546669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1547669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1548669cc0f4SStefano Zampini 1549669cc0f4SStefano Zampini /* assemble near null space */ 1550669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1551669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1552669cc0f4SStefano Zampini } 1553669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1554669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 1555669cc0f4SStefano Zampini } 1556669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1557669cc0f4SStefano Zampini PetscFunctionReturn(0); 1558669cc0f4SStefano Zampini } 1559669cc0f4SStefano Zampini 1560669cc0f4SStefano Zampini 1561a3df083aSStefano Zampini #undef __FUNCT__ 15621f4df5f7SStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalTopologyInfo" 15631f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 15641f4df5f7SStefano Zampini { 15651f4df5f7SStefano Zampini PetscErrorCode ierr; 15661f4df5f7SStefano Zampini Vec local,global; 15671f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15681f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 15691f4df5f7SStefano Zampini 15701f4df5f7SStefano Zampini PetscFunctionBegin; 15711f4df5f7SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 15721f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 15731f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 15741f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 15751f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 15761f4df5f7SStefano Zampini PetscInt i; 15771f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 15781f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 15791f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 15801f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 15811f4df5f7SStefano Zampini } 15821f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 15831f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 15841f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 15851f4df5f7SStefano Zampini } 15861f4df5f7SStefano Zampini } else { 1587986cdee1SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present, create it in local ordering if bs > 1 */ 15881f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1589986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 1590986cdee1SStefano Zampini if (i > 1) { 1591986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 15921f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 15931f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 15941f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 15951f4df5f7SStefano Zampini } 15961f4df5f7SStefano Zampini } 15971f4df5f7SStefano Zampini } 1598986cdee1SStefano Zampini } 15991f4df5f7SStefano Zampini 16001f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 16011f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16021f4df5f7SStefano Zampini } 16031f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 16041f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16051f4df5f7SStefano Zampini } 16061f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 16071f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 16081f4df5f7SStefano Zampini } 16091f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 16101f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 16111f4df5f7SStefano Zampini PetscFunctionReturn(0); 16121f4df5f7SStefano Zampini } 16131f4df5f7SStefano Zampini 16141f4df5f7SStefano Zampini #undef __FUNCT__ 16153e589ea0SStefano Zampini #define __FUNCT__ "PCBDDCBenignRemoveInterior" 16163e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 16173e589ea0SStefano Zampini { 16183e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 16193e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 16203e589ea0SStefano Zampini PetscErrorCode ierr; 16213e589ea0SStefano Zampini 16223e589ea0SStefano Zampini PetscFunctionBegin; 16233e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 16243e589ea0SStefano Zampini PetscFunctionReturn(0); 16253e589ea0SStefano Zampini } 16263e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 16273e589ea0SStefano Zampini Vec swap; 16283e589ea0SStefano Zampini 16293e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 16303e589ea0SStefano Zampini swap = pcbddc->work_change; 16313e589ea0SStefano Zampini pcbddc->work_change = r; 16323e589ea0SStefano Zampini r = swap; 16333e589ea0SStefano Zampini } 16343e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16353e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 16363e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 16373e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 16383e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 16393e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 16403e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1641f913dca9SStefano Zampini pcbddc->work_change = r; 16423e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 16433e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 16443e589ea0SStefano Zampini } 16453e589ea0SStefano Zampini PetscFunctionReturn(0); 16463e589ea0SStefano Zampini } 16473e589ea0SStefano Zampini 16483e589ea0SStefano Zampini #undef __FUNCT__ 1649a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private_Private" 1650a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1651a3df083aSStefano Zampini { 1652a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1653a3df083aSStefano Zampini PetscErrorCode ierr; 1654a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1655a3df083aSStefano Zampini 1656a3df083aSStefano Zampini PetscFunctionBegin; 1657a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1658a3df083aSStefano Zampini if (transpose) { 1659a3df083aSStefano Zampini apply_right = ctx->apply_left; 1660a3df083aSStefano Zampini apply_left = ctx->apply_right; 1661a3df083aSStefano Zampini } else { 1662a3df083aSStefano Zampini apply_right = ctx->apply_right; 1663a3df083aSStefano Zampini apply_left = ctx->apply_left; 1664a3df083aSStefano Zampini } 1665a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1666a3df083aSStefano Zampini if (apply_right) { 1667a3df083aSStefano Zampini const PetscScalar *ax; 1668a3df083aSStefano Zampini PetscInt nl,i; 1669a3df083aSStefano Zampini 1670a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1671a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1672a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1673a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1674a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1675a3df083aSStefano Zampini PetscScalar sum,val; 1676a3df083aSStefano Zampini const PetscInt *idxs; 1677a3df083aSStefano Zampini PetscInt nz,j; 1678a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1679a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1680a3df083aSStefano Zampini sum = 0.; 1681a3df083aSStefano Zampini if (ctx->apply_p0) { 1682a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1683a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1684a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1685a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1686a3df083aSStefano Zampini } 1687a3df083aSStefano Zampini } else { 1688a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1689a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1690a3df083aSStefano Zampini } 1691a3df083aSStefano Zampini } 1692a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1693a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1694a3df083aSStefano Zampini } 1695a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1696a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1697a3df083aSStefano Zampini } 1698a3df083aSStefano Zampini if (transpose) { 1699a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1700a3df083aSStefano Zampini } else { 1701a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1702a3df083aSStefano Zampini } 1703a3df083aSStefano Zampini if (reset_x) { 1704a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1705a3df083aSStefano Zampini } 1706a3df083aSStefano Zampini if (apply_left) { 1707a3df083aSStefano Zampini PetscScalar *ay; 1708a3df083aSStefano Zampini PetscInt i; 1709a3df083aSStefano Zampini 1710a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1711a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1712a3df083aSStefano Zampini PetscScalar sum,val; 1713a3df083aSStefano Zampini const PetscInt *idxs; 1714a3df083aSStefano Zampini PetscInt nz,j; 1715a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1716a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1717a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1718a3df083aSStefano Zampini if (ctx->apply_p0) { 1719a3df083aSStefano Zampini sum = 0.; 1720a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1721a3df083aSStefano Zampini sum += ay[idxs[j]]; 1722a3df083aSStefano Zampini ay[idxs[j]] += val; 1723a3df083aSStefano Zampini } 1724a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1725a3df083aSStefano Zampini } else { 1726a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1727a3df083aSStefano Zampini ay[idxs[j]] += val; 1728a3df083aSStefano Zampini } 1729a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1730a3df083aSStefano Zampini } 1731a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1732a3df083aSStefano Zampini } 1733a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1734a3df083aSStefano Zampini } 1735a3df083aSStefano Zampini PetscFunctionReturn(0); 1736a3df083aSStefano Zampini } 1737a3df083aSStefano Zampini 1738a3df083aSStefano Zampini #undef __FUNCT__ 1739a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMultTranspose_Private" 1740a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1741a3df083aSStefano Zampini { 1742a3df083aSStefano Zampini PetscErrorCode ierr; 1743a3df083aSStefano Zampini 1744a3df083aSStefano Zampini PetscFunctionBegin; 1745a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1746a3df083aSStefano Zampini PetscFunctionReturn(0); 1747a3df083aSStefano Zampini } 1748a3df083aSStefano Zampini 1749a3df083aSStefano Zampini #undef __FUNCT__ 1750a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignMatMult_Private" 1751a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1752a3df083aSStefano Zampini { 1753a3df083aSStefano Zampini PetscErrorCode ierr; 1754a3df083aSStefano Zampini 1755a3df083aSStefano Zampini PetscFunctionBegin; 1756a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1757a3df083aSStefano Zampini PetscFunctionReturn(0); 1758a3df083aSStefano Zampini } 1759a3df083aSStefano Zampini 1760a3df083aSStefano Zampini #undef __FUNCT__ 1761a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignShellMat" 1762a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1763a3df083aSStefano Zampini { 1764a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1765a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1766a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1767a3df083aSStefano Zampini PetscErrorCode ierr; 1768a3df083aSStefano Zampini 1769a3df083aSStefano Zampini PetscFunctionBegin; 1770a3df083aSStefano Zampini if (!restore) { 17711dd7afcfSStefano Zampini Mat A_IB,A_BI; 1772a3df083aSStefano Zampini PetscScalar *work; 1773b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 1774a3df083aSStefano Zampini 17759a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 17769a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 1777a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 1778a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 1779a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1780a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 1781a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 1782a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 1783a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 1784a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 1785a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 1786a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 1787a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 1788a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 1789059032f7SStefano Zampini if (reuse) { 1790a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 17911dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 1792059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 1793059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 1794059032f7SStefano Zampini PetscInt i; 1795059032f7SStefano Zampini 1796059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 1797059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1798059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1799059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1800059032f7SStefano Zampini } 1801059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 18021dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 1803059032f7SStefano Zampini } 1804a3df083aSStefano Zampini ctx->A = pcis->A_IB; 1805a3df083aSStefano Zampini ctx->work = work; 1806a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 1807a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1808a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1809a3df083aSStefano Zampini pcis->A_IB = A_IB; 1810a3df083aSStefano Zampini 1811a3df083aSStefano Zampini /* A_BI as A_IB^T */ 1812a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 1813a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 1814a3df083aSStefano Zampini pcis->A_BI = A_BI; 1815a3df083aSStefano Zampini } else { 18161dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 18171dd7afcfSStefano Zampini PetscFunctionReturn(0); 18181dd7afcfSStefano Zampini } 1819a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 1820a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 1821a3df083aSStefano Zampini pcis->A_IB = ctx->A; 18221dd7afcfSStefano Zampini ctx->A = NULL; 18231dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 18241dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 18251dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 18261dd7afcfSStefano Zampini if (ctx->free) { 1827059032f7SStefano Zampini PetscInt i; 18281dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1829059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1830059032f7SStefano Zampini } 1831059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1832059032f7SStefano Zampini } 1833a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 1834a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 1835a3df083aSStefano Zampini } 1836a3df083aSStefano Zampini PetscFunctionReturn(0); 1837a3df083aSStefano Zampini } 1838a3df083aSStefano Zampini 1839a3df083aSStefano Zampini /* used just in bddc debug mode */ 1840a3df083aSStefano Zampini #undef __FUNCT__ 1841a3df083aSStefano Zampini #define __FUNCT__ "PCBDDCBenignProject" 1842a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 1843a3df083aSStefano Zampini { 1844a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1845a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1846a3df083aSStefano Zampini Mat An; 1847a3df083aSStefano Zampini PetscErrorCode ierr; 1848a3df083aSStefano Zampini 1849a3df083aSStefano Zampini PetscFunctionBegin; 1850a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 1851a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 1852a3df083aSStefano Zampini if (is1) { 1853a3df083aSStefano Zampini ierr = MatGetSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 1854a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 1855a3df083aSStefano Zampini } else { 1856a3df083aSStefano Zampini *B = An; 1857a3df083aSStefano Zampini } 1858a3df083aSStefano Zampini PetscFunctionReturn(0); 1859a3df083aSStefano Zampini } 1860a3df083aSStefano Zampini 18611cf9b237SStefano Zampini /* TODO: add reuse flag */ 18621cf9b237SStefano Zampini #undef __FUNCT__ 18631cf9b237SStefano Zampini #define __FUNCT__ "MatSeqAIJCompress" 18641cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 18651cf9b237SStefano Zampini { 18661cf9b237SStefano Zampini Mat Bt; 18671cf9b237SStefano Zampini PetscScalar *a,*bdata; 18681cf9b237SStefano Zampini const PetscInt *ii,*ij; 18691cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 18701cf9b237SStefano Zampini PetscBool flg_row; 18711cf9b237SStefano Zampini PetscErrorCode ierr; 18721cf9b237SStefano Zampini 18731cf9b237SStefano Zampini PetscFunctionBegin; 18741cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 18751cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 18761cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 18771cf9b237SStefano Zampini nnz = n; 18781cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 18791cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 18801cf9b237SStefano Zampini } 18811cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 18821cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 18831cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 18841cf9b237SStefano Zampini nnz = 0; 18851cf9b237SStefano Zampini bii[0] = 0; 18861cf9b237SStefano Zampini for (i=0;i<n;i++) { 18871cf9b237SStefano Zampini PetscInt j; 18881cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 18891cf9b237SStefano Zampini PetscScalar entry = a[j]; 18901cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 18911cf9b237SStefano Zampini bij[nnz] = ij[j]; 18921cf9b237SStefano Zampini bdata[nnz] = entry; 18931cf9b237SStefano Zampini nnz++; 18941cf9b237SStefano Zampini } 18951cf9b237SStefano Zampini } 18961cf9b237SStefano Zampini bii[i+1] = nnz; 18971cf9b237SStefano Zampini } 18981cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 18991cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 19001cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 19011cf9b237SStefano Zampini { 19021cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 19031cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 19041cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 19051cf9b237SStefano Zampini } 19061cf9b237SStefano Zampini *B = Bt; 19071cf9b237SStefano Zampini PetscFunctionReturn(0); 19081cf9b237SStefano Zampini } 19091cf9b237SStefano Zampini 1910674ae819SStefano Zampini #undef __FUNCT__ 19114f1b2e48SStefano Zampini #define __FUNCT__ "MatDetectDisconnectedComponents" 19124f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 19134f1b2e48SStefano Zampini { 19144f1b2e48SStefano Zampini Mat B; 19154f1b2e48SStefano Zampini IS is_dummy,*cc_n; 19164f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 19174f1b2e48SStefano Zampini PCBDDCGraph graph; 19184f1b2e48SStefano Zampini PetscInt i,n; 19194f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 19204f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 19214f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 19224f1b2e48SStefano Zampini PetscErrorCode ierr; 19234f1b2e48SStefano Zampini 19244f1b2e48SStefano Zampini PetscFunctionBegin; 192563c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 192663c961adSStefano Zampini *ncc = 0; 192763c961adSStefano Zampini *cc = NULL; 192863c961adSStefano Zampini PetscFunctionReturn(0); 192963c961adSStefano Zampini } 19304f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 19314f1b2e48SStefano Zampini if (!isseqaij && filter) { 19321cf9b237SStefano Zampini PetscBool isseqdense; 19331cf9b237SStefano Zampini 19341cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 19351cf9b237SStefano Zampini if (!isseqdense) { 19364f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 19371cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 19381cf9b237SStefano Zampini PetscScalar *array; 19391cf9b237SStefano Zampini PetscReal chop=1.e-6; 19401cf9b237SStefano Zampini 19411cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 19421cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 19431cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 19441cf9b237SStefano Zampini for (i=0;i<n;i++) { 19451cf9b237SStefano Zampini PetscInt j; 19461cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 19471cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 19481cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 19491cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 19501cf9b237SStefano Zampini } 19511cf9b237SStefano Zampini } 19521cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 19539d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 19541cf9b237SStefano Zampini } 19554f1b2e48SStefano Zampini } else { 19564f1b2e48SStefano Zampini B = A; 19574f1b2e48SStefano Zampini } 19584f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 19594f1b2e48SStefano Zampini 19604f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 19614f1b2e48SStefano Zampini if (filter) { 19624f1b2e48SStefano Zampini PetscScalar *data; 19634f1b2e48SStefano Zampini PetscInt j,cum; 19644f1b2e48SStefano Zampini 19654f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 19664f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 19674f1b2e48SStefano Zampini cum = 0; 19684f1b2e48SStefano Zampini for (i=0;i<n;i++) { 19694f1b2e48SStefano Zampini PetscInt t; 19704f1b2e48SStefano Zampini 19714f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 19724f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 19734f1b2e48SStefano Zampini continue; 19744f1b2e48SStefano Zampini } 19754f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 19764f1b2e48SStefano Zampini } 19774f1b2e48SStefano Zampini t = xadj_filtered[i]; 19784f1b2e48SStefano Zampini xadj_filtered[i] = cum; 19794f1b2e48SStefano Zampini cum += t; 19804f1b2e48SStefano Zampini } 19814f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 19824f1b2e48SStefano Zampini } else { 19834f1b2e48SStefano Zampini xadj_filtered = NULL; 19844f1b2e48SStefano Zampini adjncy_filtered = NULL; 19854f1b2e48SStefano Zampini } 19864f1b2e48SStefano Zampini 19874f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 19884f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 19894f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 19904f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 19914f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 1992be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 19934f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 19944f1b2e48SStefano Zampini if (xadj_filtered) { 19954f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 19964f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 19974f1b2e48SStefano Zampini } else { 19984f1b2e48SStefano Zampini graph->xadj = xadj; 19994f1b2e48SStefano Zampini graph->adjncy = adjncy; 20004f1b2e48SStefano Zampini } 20014f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 20024f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 20034f1b2e48SStefano Zampini /* partial clean up */ 20044f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 20054f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 20061cf9b237SStefano Zampini if (A != B) { 20074f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 20084f1b2e48SStefano Zampini } 20094f1b2e48SStefano Zampini 20104f1b2e48SStefano Zampini /* get back data */ 20111cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 20121cf9b237SStefano Zampini if (cc) { 20134f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 20144f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 20154f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,graph->cptr[i+1]-graph->cptr[i],graph->queue+graph->cptr[i],PETSC_COPY_VALUES,&cc_n[i]);CHKERRQ(ierr); 20164f1b2e48SStefano Zampini } 20174f1b2e48SStefano Zampini *cc = cc_n; 20181cf9b237SStefano Zampini } 20194f1b2e48SStefano Zampini /* clean up graph */ 20204f1b2e48SStefano Zampini graph->xadj = 0; 20214f1b2e48SStefano Zampini graph->adjncy = 0; 20224f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 20234f1b2e48SStefano Zampini PetscFunctionReturn(0); 20244f1b2e48SStefano Zampini } 20254f1b2e48SStefano Zampini 20264f1b2e48SStefano Zampini #undef __FUNCT__ 20275408967cSStefano Zampini #define __FUNCT__ "PCBDDCBenignCheck" 20285408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 20295408967cSStefano Zampini { 20305408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 20315408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2032dee84bffSStefano Zampini IS dirIS = NULL; 20334f1b2e48SStefano Zampini PetscInt i; 20345408967cSStefano Zampini PetscErrorCode ierr; 20355408967cSStefano Zampini 20365408967cSStefano Zampini PetscFunctionBegin; 2037dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 20385408967cSStefano Zampini if (zerodiag) { 20395408967cSStefano Zampini Mat A; 20405408967cSStefano Zampini Vec vec3_N; 20415408967cSStefano Zampini PetscScalar *vals; 20425408967cSStefano Zampini const PetscInt *idxs; 2043d12d3064SStefano Zampini PetscInt nz,*count; 20445408967cSStefano Zampini 20455408967cSStefano Zampini /* p0 */ 20465408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 20475408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 20485408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 20495408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 20504f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 20515408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 20525408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 20535408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 20545408967cSStefano Zampini /* v_I */ 20555408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 20565408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 20575408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 20585408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 20595408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 20605408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 20615408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 20625408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 20635408967cSStefano Zampini if (dirIS) { 20645408967cSStefano Zampini PetscInt n; 20655408967cSStefano Zampini 20665408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 20675408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 20685408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 20695408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 20705408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 20715408967cSStefano Zampini } 20725408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 20735408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 20745408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 20755408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2076669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 20775408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 20785408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 20799a962809SStefano Zampini if (PetscAbsScalar(vals[0]) > 1.e-1) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! b(v_I,p_0) = %1.6e (should be numerically 0.)",PetscAbsScalar(vals[0])); 20805408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 20815408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2082d12d3064SStefano Zampini 2083d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 2084d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 2085d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2086d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 2087d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2088d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 20899a962809SStefano Zampini for (i=0;i<nz;i++) if (count[idxs[i]]) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SUP,"Benign trick can not be applied! pressure dof %d is an interface dof",idxs[i]); 2090d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2091d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 20925408967cSStefano Zampini } 2093dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 20945408967cSStefano Zampini 20955408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 20965408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 20974f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 20985408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 20994f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 21005408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2101f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2102f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 2103f2a566d8SStefano Zampini if (val != -PetscGlobalRank-i) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error testing PCBDDCBenignGetOrSetP0! Found %g at %d instead of %g\n",PetscRealPart(pcbddc->benign_p0[i]),i,-PetscGlobalRank-i);CHKERRQ(ierr); 2104f2a566d8SStefano Zampini } 21055408967cSStefano Zampini PetscFunctionReturn(0); 21065408967cSStefano Zampini } 21075408967cSStefano Zampini 21085408967cSStefano Zampini #undef __FUNCT__ 2109339f8db1SStefano Zampini #define __FUNCT__ "PCBDDCBenignDetectSaddlePoint" 2110339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 2111339f8db1SStefano Zampini { 2112339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 21134f1b2e48SStefano Zampini IS pressures,zerodiag,*zerodiag_subs; 2114b0f5fe93SStefano Zampini PetscInt nz,n; 21151f4df5f7SStefano Zampini PetscInt *interior_dofs,n_interior_dofs; 21164f1b2e48SStefano Zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag; 2117339f8db1SStefano Zampini PetscErrorCode ierr; 2118339f8db1SStefano Zampini 2119339f8db1SStefano Zampini PetscFunctionBegin; 21209f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 21219f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 2122a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 2123a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 2124a3df083aSStefano Zampini } 2125a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2126a3df083aSStefano Zampini pcbddc->benign_n = 0; 21271ae86dd6SStefano Zampini /* if a local info on dofs is present, assumes that the last field represents "pressures" 21284f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 21294f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 21304f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 21311ae86dd6SStefano Zampini since the local Schur complements are already SPD 21324f1b2e48SStefano Zampini */ 21334f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 21344f1b2e48SStefano Zampini have_null = PETSC_TRUE; 213540fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 21364f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 21374f1b2e48SStefano Zampini 21384f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 21394f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 21404f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 21414f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 2142ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 214340fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 214440fa8d13SStefano Zampini if (!sorted) { 214540fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 214640fa8d13SStefano Zampini } 214740fa8d13SStefano Zampini } else { 214840fa8d13SStefano Zampini pressures = NULL; 214940fa8d13SStefano Zampini } 215097d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 215197d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 215227b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 215397d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 2154339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 2155339f8db1SStefano Zampini if (!sorted) { 2156339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 2157339f8db1SStefano Zampini } 2158339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 21594f1b2e48SStefano Zampini if (!nz) { 21604f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 21614f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 216240fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 216340fa8d13SStefano Zampini } 21644f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 21654f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 21664f1b2e48SStefano Zampini zerodiag_subs = NULL; 21674f1b2e48SStefano Zampini pcbddc->benign_n = 0; 21681f4df5f7SStefano Zampini n_interior_dofs = 0; 21691f4df5f7SStefano Zampini interior_dofs = NULL; 21701f4df5f7SStefano Zampini if (pcbddc->current_level) { /* need to compute interior nodes */ 21711f4df5f7SStefano Zampini PetscInt n,i,j; 21721f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 21731f4df5f7SStefano Zampini PetscInt *iwork; 21741f4df5f7SStefano Zampini 21751f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 21761f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 21771f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 21781f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 217990648384SStefano Zampini for (i=1;i<n_neigh;i++) 21801f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 21811f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 21821f4df5f7SStefano Zampini for (i=0;i<n;i++) 21831f4df5f7SStefano Zampini if (!iwork[i]) 21841f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 21851f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 21861f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 21871f4df5f7SStefano Zampini } 21884f1b2e48SStefano Zampini if (has_null_pressures) { 21894f1b2e48SStefano Zampini IS *subs; 21901f4df5f7SStefano Zampini PetscInt nsubs,i,j,nl; 21911f4df5f7SStefano Zampini const PetscInt *idxs; 21921f4df5f7SStefano Zampini PetscScalar *array; 21931f4df5f7SStefano Zampini Vec *work; 21941f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 21954f1b2e48SStefano Zampini 21964f1b2e48SStefano Zampini subs = pcbddc->local_subs; 21974f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 21981f4df5f7SStefano Zampini /* these vectors are needed to check if the constant on pressures is in the kernel of the local operator B (i.e. B(v_I,p0) should be zero) */ 21991f4df5f7SStefano Zampini if (pcbddc->current_level) { 22001f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 22011f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 22021f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 22031f4df5f7SStefano Zampini /* work[0] = 1_p */ 22041f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 22051f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 22061f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 22071f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 22081f4df5f7SStefano Zampini /* work[0] = 1_v */ 22091f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 22101f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 22111f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 22121f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 22131f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 22141f4df5f7SStefano Zampini } 22154f1b2e48SStefano Zampini if (nsubs > 1) { 22164f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 22174f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 22184f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 22194f1b2e48SStefano Zampini IS t_zerodiag_subs; 22204f1b2e48SStefano Zampini PetscInt nl; 22214f1b2e48SStefano Zampini 22224f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 22234f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 22244f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 22254f1b2e48SStefano Zampini if (nl) { 22264f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 22274f1b2e48SStefano Zampini 22281f4df5f7SStefano Zampini if (pcbddc->current_level) { 22291f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 22301f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 22311f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 22321f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 22331f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 22341f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 22351f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 22361f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 22371f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 22381f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 22391f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 22401f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 22411f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 22421f4df5f7SStefano Zampini valid = PETSC_FALSE; 22431f4df5f7SStefano Zampini break; 22441f4df5f7SStefano Zampini } 22451f4df5f7SStefano Zampini } 22461f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 22471f4df5f7SStefano Zampini } 22481f4df5f7SStefano Zampini if (valid && pcbddc->NeumannBoundariesLocal) { 22491f4df5f7SStefano Zampini IS t_bc; 22501f4df5f7SStefano Zampini PetscInt nzb; 22511f4df5f7SStefano Zampini 22521f4df5f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pcbddc->NeumannBoundariesLocal,&t_bc);CHKERRQ(ierr); 22531f4df5f7SStefano Zampini ierr = ISGetLocalSize(t_bc,&nzb);CHKERRQ(ierr); 22541f4df5f7SStefano Zampini ierr = ISDestroy(&t_bc);CHKERRQ(ierr); 22551f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 22561f4df5f7SStefano Zampini } 22571f4df5f7SStefano Zampini if (valid && pressures) { 22584f1b2e48SStefano Zampini IS t_pressure_subs; 22594f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 22604f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 22614f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 22624f1b2e48SStefano Zampini } 22634f1b2e48SStefano Zampini if (valid) { 22644f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 22654f1b2e48SStefano Zampini pcbddc->benign_n++; 22664f1b2e48SStefano Zampini } else { 22674f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 22684f1b2e48SStefano Zampini } 22694f1b2e48SStefano Zampini } 22704f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 22714f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 22724f1b2e48SStefano Zampini } 22734f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 22744f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 22751f4df5f7SStefano Zampini 22761f4df5f7SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 22771f4df5f7SStefano Zampini PetscInt nzb; 22781f4df5f7SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nzb);CHKERRQ(ierr); 22791f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 22801f4df5f7SStefano Zampini } 22811f4df5f7SStefano Zampini if (valid && pressures) { 22824f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 22834f1b2e48SStefano Zampini } 22841f4df5f7SStefano Zampini if (valid && pcbddc->current_level) { 22851f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 22861f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 22871f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 22881f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 22891f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 22901f4df5f7SStefano Zampini valid = PETSC_FALSE; 22911f4df5f7SStefano Zampini break; 22921f4df5f7SStefano Zampini } 22931f4df5f7SStefano Zampini } 22941f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 22951f4df5f7SStefano Zampini } 22964f1b2e48SStefano Zampini if (valid) { 22974f1b2e48SStefano Zampini pcbddc->benign_n = 1; 2298ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 22994f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 23004f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 23014f1b2e48SStefano Zampini } 23024f1b2e48SStefano Zampini } 23031f4df5f7SStefano Zampini if (pcbddc->current_level) { 23041f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 23054f1b2e48SStefano Zampini } 23061f4df5f7SStefano Zampini } 23071f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 23084f1b2e48SStefano Zampini 23094f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2310b9b0e38cSStefano Zampini PetscInt n; 2311b9b0e38cSStefano Zampini 23124f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 23134f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2314b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 2315b9b0e38cSStefano Zampini if (n) { 23164f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 23174f1b2e48SStefano Zampini have_null = PETSC_FALSE; 23184f1b2e48SStefano Zampini } 2319b9b0e38cSStefano Zampini } 23204f1b2e48SStefano Zampini 23214f1b2e48SStefano Zampini /* final check for null pressures */ 23224f1b2e48SStefano Zampini if (zerodiag && pressures) { 23234f1b2e48SStefano Zampini PetscInt nz,np; 23244f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 23254f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 23264f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 23274f1b2e48SStefano Zampini } 23284f1b2e48SStefano Zampini 23294f1b2e48SStefano Zampini if (recompute_zerodiag) { 23304f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 23314f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 23324f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 23334f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 23344f1b2e48SStefano Zampini } else { 23354f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 23364f1b2e48SStefano Zampini 23374f1b2e48SStefano Zampini nzn = 0; 23384f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 23394f1b2e48SStefano Zampini PetscInt ns; 23404f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 23414f1b2e48SStefano Zampini nzn += ns; 23424f1b2e48SStefano Zampini } 23434f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 23444f1b2e48SStefano Zampini nzn = 0; 23454f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 23464f1b2e48SStefano Zampini PetscInt ns,*idxs; 23474f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 23484f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 23494f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 23504f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 23514f1b2e48SStefano Zampini nzn += ns; 23524f1b2e48SStefano Zampini } 23534f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 23544f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 23554f1b2e48SStefano Zampini } 23564f1b2e48SStefano Zampini have_null = PETSC_FALSE; 23574f1b2e48SStefano Zampini } 23584f1b2e48SStefano Zampini 2359669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2360a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2361a198735bSStefano Zampini Mat A,loc_divudotp; 2362a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2363a198735bSStefano Zampini IS row,col,isused = NULL; 2364a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2365a198735bSStefano Zampini 23661f4df5f7SStefano Zampini if (pressures) { 23671f4df5f7SStefano Zampini isused = pressures; 23681f4df5f7SStefano Zampini } else { 23691f4df5f7SStefano Zampini isused = zerodiag; 23701f4df5f7SStefano Zampini } 2371a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2372669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 23731ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 23741ae86dd6SStefano Zampini if (!isused && n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_USER,"Don't know how to extract div u dot p! Please provide the pressure field"); 2375a198735bSStefano Zampini n_isused = 0; 2376a198735bSStefano Zampini if (isused) { 2377a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2378a198735bSStefano Zampini } 2379a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2380a198735bSStefano Zampini st = st-n_isused; 23811ae86dd6SStefano Zampini if (n) { 2382a198735bSStefano Zampini const PetscInt *gidxs; 2383a198735bSStefano Zampini 2384a198735bSStefano Zampini ierr = MatGetSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2385a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2386a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2387a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2388a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2389a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 23901ae86dd6SStefano Zampini } else { 2391a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2392a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2393a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2394a198735bSStefano Zampini } 2395a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2396a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2397a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2398a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2399a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2400a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2401a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2402a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2403a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2404a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2405a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2406a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2407a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2408a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 24091ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24101ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 24111ae86dd6SStefano Zampini } 2412b3afcdbeSStefano Zampini 2413b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 24144f1b2e48SStefano Zampini if (has_null_pressures) { 24154f1b2e48SStefano Zampini IS zerodiagc; 24164f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 24174f1b2e48SStefano Zampini PetscInt i,s,*nnz; 24184f1b2e48SStefano Zampini 24194f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2420339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 2421339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 2422339f8db1SStefano Zampini /* local change of basis for pressures */ 2423339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 242497d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2425339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2426339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2427339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 24284f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 24294f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 24304f1b2e48SStefano Zampini PetscInt nzs,j; 24314f1b2e48SStefano Zampini 24324f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 24334f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 24344f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 24354f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 24364f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 24374f1b2e48SStefano Zampini } 2438339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2439339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2440339f8db1SStefano Zampini /* set identity on velocities */ 2441339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 2442339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 2443339f8db1SStefano Zampini } 24444f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 24454f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 24469f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 24474f1b2e48SStefano Zampini ierr = PetscMalloc3(pcbddc->benign_n,&pcbddc->benign_p0_lidx,pcbddc->benign_n,&pcbddc->benign_p0_gidx,pcbddc->benign_n,&pcbddc->benign_p0);CHKERRQ(ierr); 2448339f8db1SStefano Zampini /* set change on pressures */ 24494f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 24504f1b2e48SStefano Zampini PetscScalar *array; 24514f1b2e48SStefano Zampini PetscInt nzs; 24524f1b2e48SStefano Zampini 24534f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 24544f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 24554f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2456339f8db1SStefano Zampini PetscScalar vals[2]; 2457339f8db1SStefano Zampini PetscInt cols[2]; 2458339f8db1SStefano Zampini 2459339f8db1SStefano Zampini cols[0] = idxs[i]; 24604f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2461339f8db1SStefano Zampini vals[0] = 1.; 2462b0f5fe93SStefano Zampini vals[1] = 1.; 24634f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2464339f8db1SStefano Zampini } 24654f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 24664f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 24674f1b2e48SStefano Zampini array[nzs-1] = 1.; 24684f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 24694f1b2e48SStefano Zampini /* store local idxs for p0 */ 24704f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 24714f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2472339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 24734f1b2e48SStefano Zampini } 2474339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2475339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2476a3df083aSStefano Zampini /* project if needed */ 2477a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 24781dd7afcfSStefano Zampini Mat M; 24791dd7afcfSStefano Zampini 24801dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2481339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 24821dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 24831dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2484a3df083aSStefano Zampini } 24854f1b2e48SStefano Zampini /* store global idxs for p0 */ 24864f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2487339f8db1SStefano Zampini } 2488ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 24894f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 2490b0f5fe93SStefano Zampini 2491b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 2492b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 249327b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 249427b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2495339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2496339f8db1SStefano Zampini PetscFunctionReturn(0); 2497339f8db1SStefano Zampini } 2498339f8db1SStefano Zampini 2499339f8db1SStefano Zampini #undef __FUNCT__ 2500015636ebSStefano Zampini #define __FUNCT__ "PCBDDCBenignGetOrSetP0" 2501015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2502efc2fbd9SStefano Zampini { 2503efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2504de9d7bd0SStefano Zampini PetscScalar *array; 2505efc2fbd9SStefano Zampini PetscErrorCode ierr; 2506efc2fbd9SStefano Zampini 2507efc2fbd9SStefano Zampini PetscFunctionBegin; 2508efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 2509efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 25104f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2511efc2fbd9SStefano Zampini } 2512de9d7bd0SStefano Zampini if (get) { 2513efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 25144f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 25154f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 2516efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 2517de9d7bd0SStefano Zampini } else { 2518de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 2519de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2520de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2521de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 2522efc2fbd9SStefano Zampini } 2523efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2524efc2fbd9SStefano Zampini } 2525efc2fbd9SStefano Zampini 2526efc2fbd9SStefano Zampini #undef __FUNCT__ 2527c263805aSStefano Zampini #define __FUNCT__ "PCBDDCBenignPopOrPushB0" 2528c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 2529c263805aSStefano Zampini { 2530c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2531c263805aSStefano Zampini PetscErrorCode ierr; 2532c263805aSStefano Zampini 2533c263805aSStefano Zampini PetscFunctionBegin; 2534c263805aSStefano Zampini /* TODO: add error checking 2535c263805aSStefano Zampini - avoid nested pop (or push) calls. 2536c263805aSStefano Zampini - cannot push before pop. 25371c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2538c263805aSStefano Zampini */ 25394f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2540efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2541efc2fbd9SStefano Zampini } 2542c263805aSStefano Zampini if (pop) { 2543a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 25444f1b2e48SStefano Zampini IS is_p0; 25454f1b2e48SStefano Zampini MatReuse reuse; 2546c263805aSStefano Zampini 2547c263805aSStefano Zampini /* extract B_0 */ 25484f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 25494f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 25504f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 25514f1b2e48SStefano Zampini } 25524f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 25534f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2554c263805aSStefano Zampini /* remove rows and cols from local problem */ 2555c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 255697d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 25574f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 25584f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2559a3df083aSStefano Zampini } else { 2560a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2561a3df083aSStefano Zampini PetscScalar *vals; 2562a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2563a3df083aSStefano Zampini 2564a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2565a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2566a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 25670b5adadeSStefano Zampini PetscInt *nnz; 2568a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2569a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2570a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2571331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2572331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2573331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2574331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2575331e053bSStefano Zampini } 2576331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2577331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2578331e053bSStefano Zampini } 2579a3df083aSStefano Zampini 2580a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2581a3df083aSStefano Zampini PetscScalar *array; 2582a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2583a3df083aSStefano Zampini 2584a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2585a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2586a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2587a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2588a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2589a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2590a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2591a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2592a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2593a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2594a3df083aSStefano Zampini cum = 0; 2595a3df083aSStefano Zampini for (j=0;j<n;j++) { 259622db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2597a3df083aSStefano Zampini vals[cum] = array[j]; 2598a3df083aSStefano Zampini idxs_ins[cum] = j; 2599a3df083aSStefano Zampini cum++; 2600a3df083aSStefano Zampini } 2601a3df083aSStefano Zampini } 2602a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2603a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2604a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2605a3df083aSStefano Zampini } 2606a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2607a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2608a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2609a3df083aSStefano Zampini } 2610c263805aSStefano Zampini } else { /* push */ 2611a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 26124f1b2e48SStefano Zampini PetscInt i; 26134f1b2e48SStefano Zampini 26144f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 26154f1b2e48SStefano Zampini PetscScalar *B0_vals; 26164f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 26174f1b2e48SStefano Zampini 26184f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 26194f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 26207b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 26214f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 26224f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 26234f1b2e48SStefano Zampini } 2624c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2625c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2626a3df083aSStefano Zampini } else { 2627a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 2628a3df083aSStefano Zampini } 2629c263805aSStefano Zampini } 2630c263805aSStefano Zampini PetscFunctionReturn(0); 2631c263805aSStefano Zampini } 2632c263805aSStefano Zampini 2633c263805aSStefano Zampini #undef __FUNCT__ 2634b1b3d7a2SStefano Zampini #define __FUNCT__ "PCBDDCAdaptiveSelection" 263508122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 2636b1b3d7a2SStefano Zampini { 2637b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 263808122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 263908122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 264008122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 264108122e43SStefano Zampini PetscScalar *work,lwork; 264208122e43SStefano Zampini PetscScalar *St,*S,*eigv; 264308122e43SStefano Zampini PetscScalar *Sarray,*Starray; 264408122e43SStefano Zampini PetscReal *eigs,thresh; 26451b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 2646f6f667cfSStefano Zampini PetscBool allocated_S_St; 264708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 264808122e43SStefano Zampini PetscReal *rwork; 264908122e43SStefano Zampini #endif 2650b1b3d7a2SStefano Zampini PetscErrorCode ierr; 2651b1b3d7a2SStefano Zampini 2652b1b3d7a2SStefano Zampini PetscFunctionBegin; 2653b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 2654af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 2655af25d912SStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adaptive selection not yet implemented for general matrix pencils (herm %d, posdef %d)\n",sub_schurs->is_hermitian,sub_schurs->is_posdef); 265606a4e24aSStefano Zampini 2657fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2658fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2659fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2660fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 26611575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2662fd14bc51SStefano Zampini } 2663fd14bc51SStefano Zampini 2664e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 2665e496cd5dSStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d cc %d (%d,%d).\n",PetscGlobalRank,sub_schurs->n_subs,sub_schurs->is_hermitian,sub_schurs->is_posdef); 2666e496cd5dSStefano Zampini } 2667e496cd5dSStefano Zampini 266808122e43SStefano Zampini /* max size of subsets */ 266908122e43SStefano Zampini mss = 0; 267008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 267108122e43SStefano Zampini PetscInt subset_size; 2672862806e4SStefano Zampini 267308122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 267408122e43SStefano Zampini mss = PetscMax(mss,subset_size); 267508122e43SStefano Zampini } 267608122e43SStefano Zampini 267708122e43SStefano Zampini /* min/max and threshold */ 267808122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 2679f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 268008122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 2681f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 2682f6f667cfSStefano Zampini if (nmin) { 2683f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 2684f6f667cfSStefano Zampini } 268508122e43SStefano Zampini 268608122e43SStefano Zampini /* allocate lapack workspace */ 268708122e43SStefano Zampini cum = cum2 = 0; 268808122e43SStefano Zampini maxneigs = 0; 268908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 269008122e43SStefano Zampini PetscInt n,subset_size; 2691f6f667cfSStefano Zampini 269208122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 269308122e43SStefano Zampini n = PetscMin(subset_size,nmax); 26949162d606SStefano Zampini cum += subset_size; 26959162d606SStefano Zampini cum2 += subset_size*n; 269608122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 269708122e43SStefano Zampini } 269808122e43SStefano Zampini if (mss) { 26999ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 270008122e43SStefano Zampini PetscBLASInt B_itype = 1; 270108122e43SStefano Zampini PetscBLASInt B_N = mss; 27024c6709b3SStefano Zampini PetscReal zero = 0.0; 27034c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 270408122e43SStefano Zampini 270508122e43SStefano Zampini B_lwork = -1; 270608122e43SStefano Zampini S = NULL; 270708122e43SStefano Zampini St = NULL; 2708a58a30b4SStefano Zampini eigs = NULL; 2709a58a30b4SStefano Zampini eigv = NULL; 2710a58a30b4SStefano Zampini B_iwork = NULL; 2711a58a30b4SStefano Zampini B_ifail = NULL; 2712d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2713d1710679SStefano Zampini rwork = NULL; 2714d1710679SStefano Zampini #endif 27158bec7fa6SStefano Zampini thresh = 1.0; 271608122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 271708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 271808122e43SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&zero,&thresh,&B_dummyint,&B_dummyint,&eps,&B_neigs,eigs,eigv,&B_N,&lwork,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 271908122e43SStefano Zampini #else 272008122e43SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&zero,&thresh,&B_dummyint,&B_dummyint,&eps,&B_neigs,eigs,eigv,&B_N,&lwork,&B_lwork,B_iwork,B_ifail,&B_ierr)); 272108122e43SStefano Zampini #endif 272208122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 272308122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 272408122e43SStefano Zampini } else { 272508122e43SStefano Zampini /* TODO */ 272608122e43SStefano Zampini } 272708122e43SStefano Zampini } else { 272808122e43SStefano Zampini lwork = 0; 272908122e43SStefano Zampini } 273008122e43SStefano Zampini 273108122e43SStefano Zampini nv = 0; 2732d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { /* complement set of active subsets, each entry is a vertex (boundary made by active subsets, vertices and dirichlet dofs) */ 2733d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 273408122e43SStefano Zampini } 27354c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 2736f6f667cfSStefano Zampini if (allocated_S_St) { 2737f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 2738f6f667cfSStefano Zampini } 2739f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 274008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 274108122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 274208122e43SStefano Zampini #endif 27439162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 27449162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 27459162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 274608122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 27479162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 274808122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 274908122e43SStefano Zampini 275008122e43SStefano Zampini maxneigs = 0; 275172b8c272SStefano Zampini cum = cumarray = 0; 27529162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 27539162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 2754d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 275508122e43SStefano Zampini const PetscInt *idxs; 275608122e43SStefano Zampini 2757d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 275808122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 275908122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 276008122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 276108122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 27629162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 27639162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 276408122e43SStefano Zampini } 2765d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 276608122e43SStefano Zampini } 276708122e43SStefano Zampini 276808122e43SStefano Zampini if (mss) { /* multilevel */ 276908122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 277008122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 277108122e43SStefano Zampini } 277208122e43SStefano Zampini 2773ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 277408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 277508122e43SStefano Zampini const PetscInt *idxs; 27769d54b7f4SStefano Zampini PetscReal upper,lower; 2777862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 277808122e43SStefano Zampini PetscBLASInt B_N; 2779aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 278008122e43SStefano Zampini 27819d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 27829d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 27839d54b7f4SStefano Zampini lower = thresh; 27849d54b7f4SStefano Zampini } else { 27859d54b7f4SStefano Zampini upper = 1./thresh; 27869d54b7f4SStefano Zampini lower = 0.; 27879d54b7f4SStefano Zampini } 2788862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 2789ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 2790f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 2791f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 27929ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 2793aff50787SStefano Zampini PetscInt j,k; 2794aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 2795aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 2796aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 279708122e43SStefano Zampini } 279808122e43SStefano Zampini for (j=0;j<subset_size;j++) { 2799aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 2800aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 2801aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 2802aff50787SStefano Zampini } 280308122e43SStefano Zampini } 280408122e43SStefano Zampini } else { 280508122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 280608122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 280708122e43SStefano Zampini } 28088bec7fa6SStefano Zampini } else { 2809f6f667cfSStefano Zampini S = Sarray + cumarray; 2810f6f667cfSStefano Zampini St = Starray + cumarray; 28118bec7fa6SStefano Zampini } 2812aff50787SStefano Zampini /* see if we can save some work */ 2813b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 2814aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 2815aff50787SStefano Zampini } 2816aff50787SStefano Zampini 2817b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 2818aff50787SStefano Zampini B_neigs = 0; 2819aff50787SStefano Zampini } else { 28209ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 282108122e43SStefano Zampini PetscBLASInt B_itype = 1; 2822f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 28234c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 28249552c7c7SStefano Zampini PetscInt nmin_s; 2825b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 282608122e43SStefano Zampini 2827fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2828*eee23b56SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %d/%d size %d count %d fid %d.\n",i,sub_schurs->n_subs,subset_size,pcbddc->mat_graph->count[idxs[0]]+1,pcbddc->mat_graph->which_dof[idxs[0]]); 2829fd14bc51SStefano Zampini } 2830d16cbb6bSStefano Zampini 2831b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 2832b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 2833b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 2834b7ab4a40SStefano Zampini } 2835b7ab4a40SStefano Zampini 283608122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2837b7ab4a40SStefano Zampini if (compute_range) { 2838d16cbb6bSStefano Zampini 2839d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 284008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 28419d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 284208122e43SStefano Zampini #else 28439d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 284408122e43SStefano Zampini #endif 2845b7ab4a40SStefano Zampini } else if (!same_data) { 2846d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 2847d16cbb6bSStefano Zampini B_IL = 1; 2848d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 28499d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 2850d16cbb6bSStefano Zampini #else 28519d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 2852d16cbb6bSStefano Zampini #endif 2853b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 2854b7ab4a40SStefano Zampini PetscInt k; 2855b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 2856b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 2857b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 2858b7ab4a40SStefano Zampini nmin = nmax; 2859b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 2860b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 2861b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 2862b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 2863b7ab4a40SStefano Zampini } 2864d16cbb6bSStefano Zampini } 286508122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 286608122e43SStefano Zampini if (B_ierr) { 28676c4ed002SBarry Smith if (B_ierr < 0 ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 28686c4ed002SBarry Smith else if (B_ierr <= B_N) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 28696c4ed002SBarry Smith else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: leading minor of order %d is not positive definite",(int)B_ierr-B_N-1); 287008122e43SStefano Zampini } 287108122e43SStefano Zampini 287208122e43SStefano Zampini if (B_neigs > nmax) { 2873fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2874fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 2875fd14bc51SStefano Zampini } 28769d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 287708122e43SStefano Zampini B_neigs = nmax; 287808122e43SStefano Zampini } 287908122e43SStefano Zampini 28809552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 28819552c7c7SStefano Zampini if (B_neigs < nmin_s) { 288208122e43SStefano Zampini PetscBLASInt B_neigs2; 288308122e43SStefano Zampini 28849d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2885f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 28869d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 28879d54b7f4SStefano Zampini } else { 28889d54b7f4SStefano Zampini B_IL = B_neigs + 1; 28899d54b7f4SStefano Zampini B_IU = nmin_s; 28909d54b7f4SStefano Zampini } 2891fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2892fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, less than minimum required %d. Asking for %d to %d incl (fortran like)\n",B_neigs,nmin,B_IL,B_IU); 2893fd14bc51SStefano Zampini } 28949ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 28951ae86dd6SStefano Zampini PetscInt j,k; 289608122e43SStefano Zampini for (j=0;j<subset_size;j++) { 28971ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 28981ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 28991ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 290008122e43SStefano Zampini } 290108122e43SStefano Zampini } 290208122e43SStefano Zampini } else { 290308122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 290408122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 290508122e43SStefano Zampini } 290608122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 290708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 29089d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*subset_size,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 290908122e43SStefano Zampini #else 29109d54b7f4SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*subset_size,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 291108122e43SStefano Zampini #endif 291208122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 291308122e43SStefano Zampini B_neigs += B_neigs2; 291408122e43SStefano Zampini } 291508122e43SStefano Zampini if (B_ierr) { 29166c4ed002SBarry Smith if (B_ierr < 0 ) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: illegal value for argument %d",-(int)B_ierr); 29176c4ed002SBarry Smith else if (B_ierr <= B_N) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: %d eigenvalues failed to converge",(int)B_ierr); 29186c4ed002SBarry Smith else SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYGVX Lapack routine: leading minor of order %d is not positive definite",(int)B_ierr-B_N-1); 291908122e43SStefano Zampini } 2920fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2921ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 292208122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 292308122e43SStefano Zampini if (eigs[j] == 0.0) { 2924ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 292508122e43SStefano Zampini } else { 29269d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 2927ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 29289d54b7f4SStefano Zampini } else { 29299d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 29309d54b7f4SStefano Zampini } 2931fd14bc51SStefano Zampini } 293208122e43SStefano Zampini } 293308122e43SStefano Zampini } 293408122e43SStefano Zampini } else { 293508122e43SStefano Zampini /* TODO */ 293608122e43SStefano Zampini } 2937aff50787SStefano Zampini } 29386c3e6151SStefano Zampini /* change the basis back to the original one */ 29396c3e6151SStefano Zampini if (sub_schurs->change) { 294072b8c272SStefano Zampini Mat change,phi,phit; 29416c3e6151SStefano Zampini 29426c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 29436c3e6151SStefano Zampini PetscInt ii; 29446c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 29456c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 29466c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 2947684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2948684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 2949684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 2950684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2951684229deSStefano Zampini #else 29526c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 2953684229deSStefano Zampini #endif 29546c3e6151SStefano Zampini } 29556c3e6151SStefano Zampini } 29566c3e6151SStefano Zampini } 295772b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 29586c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 295972b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 29606c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 29616c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 29626c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 29636c3e6151SStefano Zampini } 29648bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 29658bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 29669162d606SStefano Zampini if (B_neigs) { 29679162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_data+pcbddc->adaptive_constraints_data_ptr[cum],eigv+eigs_start*subset_size,B_neigs*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 2968fd14bc51SStefano Zampini 2969fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 29709552c7c7SStefano Zampini PetscInt ii; 29719552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 2972ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 29739552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 2974ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 2975ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2976ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 2977ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 2978ac47001eSStefano Zampini #else 2979ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]);CHKERRQ(ierr); 2980ac47001eSStefano Zampini #endif 29819552c7c7SStefano Zampini } 29829552c7c7SStefano Zampini } 2983fd14bc51SStefano Zampini } 29849162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 29859162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 29869162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 29879162d606SStefano Zampini cum++; 298808122e43SStefano Zampini } 298908122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 299008122e43SStefano Zampini /* shift for next computation */ 299108122e43SStefano Zampini cumarray += subset_size*subset_size; 299208122e43SStefano Zampini } 2993fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2994fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2995fd14bc51SStefano Zampini } 299608122e43SStefano Zampini 299708122e43SStefano Zampini if (mss) { 299808122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 299908122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 3000f6f667cfSStefano Zampini /* destroy matrices (junk) */ 3001f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 3002f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 300308122e43SStefano Zampini } 3004f6f667cfSStefano Zampini if (allocated_S_St) { 3005f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 3006f6f667cfSStefano Zampini } 3007f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 300808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 300908122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 301008122e43SStefano Zampini #endif 301108122e43SStefano Zampini if (pcbddc->dbg_flag) { 30121b968477SStefano Zampini PetscInt maxneigs_r; 3013b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 30149b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 301508122e43SStefano Zampini } 301608122e43SStefano Zampini PetscFunctionReturn(0); 301708122e43SStefano Zampini } 3018b1b3d7a2SStefano Zampini 3019674ae819SStefano Zampini #undef __FUNCT__ 3020c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSolvers" 3021c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 3022c8587f34SStefano Zampini { 30238629588bSStefano Zampini PetscScalar *coarse_submat_vals; 3024c8587f34SStefano Zampini PetscErrorCode ierr; 3025c8587f34SStefano Zampini 3026c8587f34SStefano Zampini PetscFunctionBegin; 3027f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 30285e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3029c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3030c8587f34SStefano Zampini 3031684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 30320fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3033684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3034c8587f34SStefano Zampini 30358629588bSStefano Zampini /* 30368629588bSStefano Zampini Setup local correction and local part of coarse basis. 30378629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 30388629588bSStefano Zampini */ 303947f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 30408629588bSStefano Zampini 30418629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 30428629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 30438629588bSStefano Zampini 30448629588bSStefano Zampini /* free */ 30458629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3046c8587f34SStefano Zampini PetscFunctionReturn(0); 3047c8587f34SStefano Zampini } 3048c8587f34SStefano Zampini 3049c8587f34SStefano Zampini #undef __FUNCT__ 3050674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetCustomization" 3051674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3052674ae819SStefano Zampini { 3053674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3054674ae819SStefano Zampini PetscErrorCode ierr; 3055674ae819SStefano Zampini 3056674ae819SStefano Zampini PetscFunctionBegin; 3057674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 305830368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3059674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3060785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3061674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3062f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3063f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3064785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 306563602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 306663602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3067674ae819SStefano Zampini PetscFunctionReturn(0); 3068674ae819SStefano Zampini } 3069674ae819SStefano Zampini 3070674ae819SStefano Zampini #undef __FUNCT__ 3071674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetTopography" 3072674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3073674ae819SStefano Zampini { 3074674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 30754f1b2e48SStefano Zampini PetscInt i; 3076674ae819SStefano Zampini PetscErrorCode ierr; 3077674ae819SStefano Zampini 3078674ae819SStefano Zampini PetscFunctionBegin; 30791e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 30801e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3081a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3082b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3083674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 308416909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 30851dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3086674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3087669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3088fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 3089a13144ffSStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 3090674ae819SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 30914f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 30924f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 30934f1b2e48SStefano Zampini } 30944f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3095b334f244SStefano Zampini if (pcbddc->sub_schurs) { 3096b96c3477SStefano Zampini ierr = PCBDDCSubSchursReset(pcbddc->sub_schurs);CHKERRQ(ierr); 3097b334f244SStefano Zampini } 3098c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 30998af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 3100674ae819SStefano Zampini PetscFunctionReturn(0); 3101674ae819SStefano Zampini } 3102674ae819SStefano Zampini 3103674ae819SStefano Zampini #undef __FUNCT__ 3104674ae819SStefano Zampini #define __FUNCT__ "PCBDDCResetSolvers" 3105674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3106674ae819SStefano Zampini { 3107674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3108674ae819SStefano Zampini PetscErrorCode ierr; 3109674ae819SStefano Zampini 3110674ae819SStefano Zampini PetscFunctionBegin; 3111674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 311258da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3113ca92afb2SStefano Zampini PetscScalar *array; 311406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 311506656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 311658da7f69SStefano Zampini } 3117674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3118674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 311915aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 312015aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3121674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3122674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3123674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 312406656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3125674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3126674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 31278ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3128674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3129674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3130674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 3131f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_D);CHKERRQ(ierr); 3132f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->ksp_R);CHKERRQ(ierr); 3133f4ddd8eeSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 3134f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3135727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 31360e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3137f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 313870cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 313981d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 31400369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 31411dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 31424f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 31438b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3144ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3145ca92afb2SStefano Zampini PetscInt i; 3146ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3147ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3148ca92afb2SStefano Zampini } 3149ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3150ca92afb2SStefano Zampini } 31514f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3152674ae819SStefano Zampini PetscFunctionReturn(0); 3153674ae819SStefano Zampini } 3154674ae819SStefano Zampini 3155674ae819SStefano Zampini #undef __FUNCT__ 3156f4ddd8eeSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalWorkVectors" 3157f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 31586bfb1811SStefano Zampini { 31596bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 31606bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 31616bfb1811SStefano Zampini VecType impVecType; 31624f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 31636bfb1811SStefano Zampini PetscErrorCode ierr; 31646bfb1811SStefano Zampini 31656bfb1811SStefano Zampini PetscFunctionBegin; 31666c4ed002SBarry Smith if (!pcbddc->ConstraintMatrix) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Constraint matrix has not been created"); 3167e7b262bdSStefano Zampini /* get sizes */ 31684f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3169b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 31706bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3171e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3172e7b262bdSStefano Zampini /* R nodes */ 3173e7b262bdSStefano Zampini old_size = -1; 3174e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3175e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3176e7b262bdSStefano Zampini } 3177e7b262bdSStefano Zampini if (n_R != old_size) { 3178e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3179e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 31806bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 31816bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 31826bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 31836bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3184e7b262bdSStefano Zampini } 3185e7b262bdSStefano Zampini /* local primal dofs */ 3186e7b262bdSStefano Zampini old_size = -1; 3187e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3188e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3189e7b262bdSStefano Zampini } 3190e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3191e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 319283b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3193e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 31946bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3195e7b262bdSStefano Zampini } 3196e7b262bdSStefano Zampini /* local explicit constraints */ 3197e7b262bdSStefano Zampini old_size = -1; 3198e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3199e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3200e7b262bdSStefano Zampini } 3201e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3202e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 320383b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 320483b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 320583b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 320683b7ccabSStefano Zampini } 32076bfb1811SStefano Zampini PetscFunctionReturn(0); 32086bfb1811SStefano Zampini } 32096bfb1811SStefano Zampini 32106bfb1811SStefano Zampini #undef __FUNCT__ 321147f4ddc3SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCorrection" 321247f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 321388ebb749SStefano Zampini { 321425084f0cSStefano Zampini PetscErrorCode ierr; 321525084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 321688ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 321788ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3218d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 321925084f0cSStefano Zampini /* submatrices of local problem */ 322080677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 322106656605SStefano Zampini /* submatrices of local coarse problem */ 322206656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 322325084f0cSStefano Zampini /* working matrices */ 322406656605SStefano Zampini Mat C_CR; 322525084f0cSStefano Zampini /* additional working stuff */ 322606656605SStefano Zampini PC pc_R; 32274f1b2e48SStefano Zampini Mat F; 32285cbda25cSStefano Zampini Vec dummy_vec; 3229a3df083aSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction; 323025084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 323106656605SStefano Zampini PetscScalar *work; 323206656605SStefano Zampini PetscInt *idx_V_B; 3233ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 323406656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 3235ffd830a3SStefano Zampini 323625084f0cSStefano Zampini /* some shortcuts to scalars */ 323706656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 323888ebb749SStefano Zampini 323988ebb749SStefano Zampini PetscFunctionBegin; 32409a962809SStefano Zampini if (!pcbddc->symmetric_primal && pcbddc->benign_n) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Non-symmetric primal basis computation with benign trick not yet implemented"); 3241ffd830a3SStefano Zampini 3242ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3243b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 32444f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3245b371cd4fSStefano Zampini n_B = pcis->n_B; 3246b371cd4fSStefano Zampini n_D = pcis->n - n_B; 324788ebb749SStefano Zampini n_R = pcis->n - n_vertices; 324888ebb749SStefano Zampini 324988ebb749SStefano Zampini /* vertices in boundary numbering */ 3250785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 32510e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 32526c4ed002SBarry Smith if (i != n_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D\n",n_vertices,i); 325388ebb749SStefano Zampini 325406656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3255019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 325606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 325706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 325806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 325906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 326006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 326106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 326206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 326306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 326406656605SStefano Zampini 326506656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 326606656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 326706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 326806656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 326906656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 3270ffd830a3SStefano Zampini lda_rhs = n_R; 3271a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 327206656605SStefano Zampini if (isLU || isILU || isCHOL) { 327306656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 3274b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 3275df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3276d62866d3SStefano Zampini MatFactorType type; 3277d62866d3SStefano Zampini 3278df4d28bfSStefano Zampini F = reuse_solver->F; 32796816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 3280d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 3281ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 328222db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 328306656605SStefano Zampini } else { 328406656605SStefano Zampini F = NULL; 328506656605SStefano Zampini } 328606656605SStefano Zampini 3287ffd830a3SStefano Zampini /* allocate workspace */ 3288ffd830a3SStefano Zampini n = 0; 3289ffd830a3SStefano Zampini if (n_constraints) { 3290ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3291ffd830a3SStefano Zampini } 3292ffd830a3SStefano Zampini if (n_vertices) { 3293ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3294ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3295ffd830a3SStefano Zampini } 3296ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3297ffd830a3SStefano Zampini 32985cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 32995cbda25cSStefano Zampini dummy_vec = NULL; 33005cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 33015cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 33025cbda25cSStefano Zampini } 33035cbda25cSStefano Zampini 330488ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 330588ebb749SStefano Zampini if (n_constraints) { 330672b8c272SStefano Zampini Mat M1,M2,M3,C_B; 330706656605SStefano Zampini IS is_aux; 330880677318SStefano Zampini PetscScalar *array,*array2; 330906656605SStefano Zampini 3310f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 331180677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 331288ebb749SStefano Zampini 331325084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 331425084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 33158ce42a96SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 331672b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 331788ebb749SStefano Zampini 331880677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 331980677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 3320ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 332188ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 332206656605SStefano Zampini const PetscScalar *row_cmat_values; 332306656605SStefano Zampini const PetscInt *row_cmat_indices; 332406656605SStefano Zampini PetscInt size_of_constraint,j; 332588ebb749SStefano Zampini 332606656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 332706656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 3328ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 332906656605SStefano Zampini } 333006656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 333106656605SStefano Zampini } 3332ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 333306656605SStefano Zampini if (F) { 333406656605SStefano Zampini Mat B; 333506656605SStefano Zampini 3336ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 3337a3df083aSStefano Zampini if (need_benign_correction) { 3338df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3339a3df083aSStefano Zampini 334072b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 334172b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 3342a3df083aSStefano Zampini } 334380677318SStefano Zampini ierr = MatMatSolve(F,B,local_auxmat2_R);CHKERRQ(ierr); 3344a3df083aSStefano Zampini if (need_benign_correction) { 3345a3df083aSStefano Zampini PetscScalar *marr; 3346df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3347a3df083aSStefano Zampini 3348a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 33495cbda25cSStefano Zampini if (lda_rhs != n_R) { 33505cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 33515cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 33525cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 33535cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 33545cbda25cSStefano Zampini } 33555cbda25cSStefano Zampini } else { 3356a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 3357a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 33585cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3359a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3360a3df083aSStefano Zampini } 33615cbda25cSStefano Zampini } 3362a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 3363a3df083aSStefano Zampini } 336406656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 336506656605SStefano Zampini } else { 336680677318SStefano Zampini PetscScalar *marr; 336780677318SStefano Zampini 336880677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 336906656605SStefano Zampini for (i=0;i<n_constraints;i++) { 3370ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3371ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 337206656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 337306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 337406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 337506656605SStefano Zampini } 337680677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 337706656605SStefano Zampini } 337880677318SStefano Zampini if (!pcbddc->switch_static) { 337980677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 338080677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 338180677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 338280677318SStefano Zampini for (i=0;i<n_constraints;i++) { 3383ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 338480677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 338580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 338680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 338780677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 338880677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 338980677318SStefano Zampini } 339080677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 339180677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 339272b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 339380677318SStefano Zampini } else { 3394ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3395ffd830a3SStefano Zampini IS dummy; 3396ffd830a3SStefano Zampini 3397ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 339872b8c272SStefano Zampini ierr = MatGetSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 3399ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 3400ffd830a3SStefano Zampini } else { 340180677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 340280677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 3403ffd830a3SStefano Zampini } 340425084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 340580677318SStefano Zampini } 340680677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 340780677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 340880677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 340906656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 341006656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 341180677318SStefano Zampini if (isCHOL) { 341280677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 341380677318SStefano Zampini } else { 341425084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 341580677318SStefano Zampini } 341680677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 341706656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 341825084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 341925084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 342025084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 342180677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 342272b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 342372b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 342406656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 342506656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 3426f4ddd8eeSStefano Zampini } 3427fc227af8SStefano Zampini 3428fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 342988ebb749SStefano Zampini if (n_vertices) { 343006656605SStefano Zampini IS is_aux; 34313a50541eSStefano Zampini 3432b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 34336816873aSStefano Zampini IS tis; 34346816873aSStefano Zampini 34356816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 34366816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 34376816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 34386816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 34396816873aSStefano Zampini } else { 34403a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 34416816873aSStefano Zampini } 34429577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 34439577ea80SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 344404708bb6SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 344525084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 344688ebb749SStefano Zampini } 344788ebb749SStefano Zampini 344888ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 3449f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 345006656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 345106656605SStefano Zampini if (pcbddc->coarse_phi_D) { 345206656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 345306656605SStefano Zampini } 3454f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 345506656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 345606656605SStefano Zampini PetscScalar *marray; 345706656605SStefano Zampini 345806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 345906656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 3460f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3461f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3462f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3463f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3464f4ddd8eeSStefano Zampini } 3465f4ddd8eeSStefano Zampini } 346606656605SStefano Zampini 3467f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 346806656605SStefano Zampini PetscScalar *marray; 346988ebb749SStefano Zampini 347006656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 34718eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 347206656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 347388ebb749SStefano Zampini } 34743301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 347506656605SStefano Zampini n *= 2; 347688ebb749SStefano Zampini } 347706656605SStefano Zampini ierr = PetscCalloc1(n,&marray);CHKERRQ(ierr); 347806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 347906656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 34808eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 348106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 348206656605SStefano Zampini n += n_D*pcbddc->local_primal_size; 348388ebb749SStefano Zampini } 34843301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 348506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 34868eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 348706656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 348806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marray+n,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 348988ebb749SStefano Zampini } 349088ebb749SStefano Zampini } else { 3491c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 3492c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 34931b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3494c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 3495c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 3496c0553b1fSStefano Zampini } 349788ebb749SStefano Zampini } 349806656605SStefano Zampini } 3499019a44ceSStefano Zampini 350006656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 35014f1b2e48SStefano Zampini p0_lidx_I = NULL; 35024f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 3503d12edf2fSStefano Zampini const PetscInt *idxs; 3504d12edf2fSStefano Zampini 3505d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 35064f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 35074f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 35084f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 35094f1b2e48SStefano Zampini } 3510d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 3511d12edf2fSStefano Zampini } 3512d16cbb6bSStefano Zampini 351306656605SStefano Zampini /* vertices */ 351406656605SStefano Zampini if (n_vertices) { 351516f15bc4SStefano Zampini 3516af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 351704708bb6SStefano Zampini 351816f15bc4SStefano Zampini if (n_R) { 351914393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 352006656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 352116f15bc4SStefano Zampini PetscScalar *x,*y; 352204708bb6SStefano Zampini PetscBool isseqaij; 352306656605SStefano Zampini 352421eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 352514393ed6SStefano Zampini if (need_benign_correction) { 352614393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 352714393ed6SStefano Zampini IS is_p0; 352814393ed6SStefano Zampini PetscInt *idxs_p0,n; 352914393ed6SStefano Zampini 353014393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 353114393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 353214393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 3533af25d912SStefano Zampini if (n != pcbddc->benign_n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in R numbering for benign p0! %d != %d\n",n,pcbddc->benign_n); 353414393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 353514393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 353614393ed6SStefano Zampini ierr = MatGetSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 353714393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 353814393ed6SStefano Zampini } 353914393ed6SStefano Zampini 3540ffd830a3SStefano Zampini if (lda_rhs == n_R) { 3541af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3542ffd830a3SStefano Zampini } else { 3543ca92afb2SStefano Zampini PetscScalar *av,*array; 3544ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 3545ca92afb2SStefano Zampini PetscInt n; 3546ca92afb2SStefano Zampini PetscBool flg_row; 3547ffd830a3SStefano Zampini 3548ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 3549ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 35509d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3551ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3552ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 3553ca92afb2SStefano Zampini for (i=0;i<n;i++) { 3554ca92afb2SStefano Zampini PetscInt j; 3555ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 3556ffd830a3SStefano Zampini } 3557ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3558ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3559ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 3560ffd830a3SStefano Zampini } 3561ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3562a3df083aSStefano Zampini if (need_benign_correction) { 3563df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3564a3df083aSStefano Zampini PetscScalar *marr; 3565a3df083aSStefano Zampini 3566a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 356714393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 356814393ed6SStefano Zampini 356914393ed6SStefano Zampini | 0 0 0 | (V) 357014393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 357114393ed6SStefano Zampini | 0 0 -1 | (p0) 357214393ed6SStefano Zampini 357314393ed6SStefano Zampini */ 3574df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 357514393ed6SStefano Zampini const PetscScalar *vals; 357614393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 357714393ed6SStefano Zampini PetscInt n,j,nz; 357814393ed6SStefano Zampini 3579df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3580df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 358114393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 358214393ed6SStefano Zampini for (j=0;j<n;j++) { 358314393ed6SStefano Zampini PetscScalar val = vals[j]; 358414393ed6SStefano Zampini PetscInt k,col = idxs[j]; 358514393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 358614393ed6SStefano Zampini } 358714393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3588df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 358914393ed6SStefano Zampini } 359072b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 359172b8c272SStefano Zampini } 359272b8c272SStefano Zampini if (F) { 359314393ed6SStefano Zampini /* need to correct the rhs */ 359472b8c272SStefano Zampini if (need_benign_correction) { 359572b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 359672b8c272SStefano Zampini PetscScalar *marr; 359772b8c272SStefano Zampini 359872b8c272SStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 35995cbda25cSStefano Zampini if (lda_rhs != n_R) { 36005cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 36015cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 36025cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 36035cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 36045cbda25cSStefano Zampini } 36055cbda25cSStefano Zampini } else { 3606a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3607a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 36085cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3609a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3610a3df083aSStefano Zampini } 36115cbda25cSStefano Zampini } 3612a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 3613a3df083aSStefano Zampini } 361406656605SStefano Zampini ierr = MatMatSolve(F,A_RV,A_RRmA_RV);CHKERRQ(ierr); 361514393ed6SStefano Zampini /* need to correct the solution */ 3616a3df083aSStefano Zampini if (need_benign_correction) { 3617df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3618a3df083aSStefano Zampini PetscScalar *marr; 3619a3df083aSStefano Zampini 3620a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 36215cbda25cSStefano Zampini if (lda_rhs != n_R) { 36225cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 36235cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 36245cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 36255cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 36265cbda25cSStefano Zampini } 36275cbda25cSStefano Zampini } else { 3628a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3629a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 36305cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3631a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3632a3df083aSStefano Zampini } 36335cbda25cSStefano Zampini } 3634a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 3635a3df083aSStefano Zampini } 363606656605SStefano Zampini } else { 363706656605SStefano Zampini ierr = MatDenseGetArray(A_RV,&y);CHKERRQ(ierr); 363806656605SStefano Zampini for (i=0;i<n_vertices;i++) { 3639ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 3640ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 364106656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 364206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 364306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 364406656605SStefano Zampini } 364506656605SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&y);CHKERRQ(ierr); 364606656605SStefano Zampini } 364780677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3648ffd830a3SStefano Zampini /* S_VV and S_CV */ 364906656605SStefano Zampini if (n_constraints) { 365006656605SStefano Zampini Mat B; 365180677318SStefano Zampini 3652ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 365380677318SStefano Zampini for (i=0;i<n_vertices;i++) { 3654ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3655ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 365680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 365780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 365880677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 365980677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 366080677318SStefano Zampini } 3661ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 366280677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 366380677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 3664ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 366580677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 366606656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 3667ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 3668ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 366906656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 367006656605SStefano Zampini } 367104708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 367204708bb6SStefano Zampini if (!isseqaij) { /* MatMatMult with SEQ(S)BAIJ below will raise an error */ 3673511c6705SHong Zhang ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 367404708bb6SStefano Zampini } 3675ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3676ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 3677ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3678ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 3679ffd830a3SStefano Zampini } 368006656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 368114393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 368214393ed6SStefano Zampini if (need_benign_correction) { 3683df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 368414393ed6SStefano Zampini PetscScalar *marr,*sums; 368514393ed6SStefano Zampini 368614393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 3687f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 3688df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 368914393ed6SStefano Zampini const PetscScalar *vals; 369014393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 369114393ed6SStefano Zampini PetscInt n,j,nz; 369214393ed6SStefano Zampini 3693df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3694df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 369514393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 369614393ed6SStefano Zampini PetscInt k; 369714393ed6SStefano Zampini sums[j] = 0.; 369814393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 369914393ed6SStefano Zampini } 370014393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 370114393ed6SStefano Zampini for (j=0;j<n;j++) { 370214393ed6SStefano Zampini PetscScalar val = vals[j]; 370314393ed6SStefano Zampini PetscInt k; 370414393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 370514393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 370614393ed6SStefano Zampini } 370714393ed6SStefano Zampini } 370814393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3709df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 371014393ed6SStefano Zampini } 371114393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 3712f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 371314393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 371414393ed6SStefano Zampini } 371580677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 371606656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 371706656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 371806656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 371906656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 372006656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 372106656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 372206656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3723d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 3724019a44ceSStefano Zampini } else { 3725d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3726d16cbb6bSStefano Zampini } 372721eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 3728d16cbb6bSStefano Zampini 372906656605SStefano Zampini /* coarse basis functions */ 373006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 373116f15bc4SStefano Zampini PetscScalar *y; 373216f15bc4SStefano Zampini 3733ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 373406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 373506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 373606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 373706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 373806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 373906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 374006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 374106656605SStefano Zampini 374206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 37434f1b2e48SStefano Zampini PetscInt j; 37444f1b2e48SStefano Zampini 374506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 374606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 374706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 374806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 374906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 37504f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 375106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 375206656605SStefano Zampini } 375306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 375406656605SStefano Zampini } 375504708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 375604708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 375706656605SStefano Zampini } 37585cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 375906656605SStefano Zampini 376006656605SStefano Zampini if (n_constraints) { 376106656605SStefano Zampini Mat B; 376206656605SStefano Zampini 3763ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 376406656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 376580677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 376606656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 376706656605SStefano Zampini if (n_vertices) { 376880677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 376980677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 377080677318SStefano Zampini } else { 377180677318SStefano Zampini Mat S_VCt; 377280677318SStefano Zampini 3773ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3774ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 377572b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 3776ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 3777ffd830a3SStefano Zampini } 377880677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 377980677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 378080677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 378180677318SStefano Zampini } 378206656605SStefano Zampini } 378306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 378406656605SStefano Zampini /* coarse basis functions */ 378506656605SStefano Zampini for (i=0;i<n_constraints;i++) { 378606656605SStefano Zampini PetscScalar *y; 378706656605SStefano Zampini 3788ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 378906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 379006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 379106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 379206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 379306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 379406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 379506656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 37964f1b2e48SStefano Zampini PetscInt j; 37974f1b2e48SStefano Zampini 379806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 379906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 380006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 380106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 380206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 38034f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 380406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 380506656605SStefano Zampini } 380606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 380706656605SStefano Zampini } 380806656605SStefano Zampini } 380980677318SStefano Zampini if (n_constraints) { 381080677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 381180677318SStefano Zampini } 38124f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 381372b8c272SStefano Zampini 381472b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 381572b8c272SStefano Zampini if (pcbddc->benign_n) { 381672b8c272SStefano Zampini Mat B0_B,B0_BPHI; 381772b8c272SStefano Zampini IS is_dummy; 381872b8c272SStefano Zampini PetscScalar *data; 381972b8c272SStefano Zampini PetscInt j; 382072b8c272SStefano Zampini 382172b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 382272b8c272SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 382372b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 382472b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 382586c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 382672b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 382772b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 382872b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 382972b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 383072b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 383172b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 383272b8c272SStefano Zampini } 383372b8c272SStefano Zampini } 383472b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 383572b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 383672b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 383772b8c272SStefano Zampini } 3838019a44ceSStefano Zampini 383906656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 38403301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 3841ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 3842ffd830a3SStefano Zampini PetscScalar *marray; 384306656605SStefano Zampini 384406656605SStefano Zampini if (n_constraints) { 3845ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 384606656605SStefano Zampini 3847af25d912SStefano Zampini ierr = MatTranspose(C_CR,MAT_INPLACE_MATRIX,&C_CRT);CHKERRQ(ierr); 384806656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 3849ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 385016f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 385106656605SStefano Zampini if (n_vertices) { 3852ffd830a3SStefano Zampini Mat S_VCT; 385306656605SStefano Zampini 385406656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 3855ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 385616f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 385706656605SStefano Zampini } 3858ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 38595b782168SStefano Zampini } else { 38605b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 386106656605SStefano Zampini } 386216f15bc4SStefano Zampini if (n_vertices && n_R) { 3863ffd830a3SStefano Zampini PetscScalar *av,*marray; 3864ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 3865ffd830a3SStefano Zampini PetscInt n; 3866ffd830a3SStefano Zampini PetscBool flg_row; 386706656605SStefano Zampini 3868ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 3869af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 3870ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3871ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 3872ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3873ffd830a3SStefano Zampini for (i=0;i<n;i++) { 3874ffd830a3SStefano Zampini PetscInt j; 3875ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 3876ffd830a3SStefano Zampini } 3877ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 3878ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3879ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 388006656605SStefano Zampini } 388106656605SStefano Zampini 3882ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 3883ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 3884ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 3885ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 3886ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 388706656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 388806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 388906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 389006656605SStefano Zampini } 3891ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 38925b782168SStefano Zampini if (B_C) { 3893ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 3894ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 3895ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 3896ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 3897ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 3898ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3899ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 390006656605SStefano Zampini } 3901ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 39025b782168SStefano Zampini } 390306656605SStefano Zampini /* coarse basis functions */ 390406656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 390506656605SStefano Zampini PetscScalar *y; 390606656605SStefano Zampini 3907ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 390806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 390906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 391006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 391106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 391206656605SStefano Zampini if (i<n_vertices) { 391306656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 391406656605SStefano Zampini } 391506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 391606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 391706656605SStefano Zampini 391806656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 391906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 392006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 392106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 392206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 392306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 392406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 392506656605SStefano Zampini } 392606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 392706656605SStefano Zampini } 3928ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 3929ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 393006656605SStefano Zampini } 3931d62866d3SStefano Zampini /* free memory */ 393288ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 393306656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 393406656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 393506656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 393606656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 3937d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 3938d62866d3SStefano Zampini if (n_vertices) { 3939d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 3940d62866d3SStefano Zampini } 3941d62866d3SStefano Zampini if (n_constraints) { 3942d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 3943d62866d3SStefano Zampini } 394488ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 394588ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 394688ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 3947d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 394888ebb749SStefano Zampini Mat coarse_sub_mat; 394925084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 395088ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 395188ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 395288ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 39538bec7fa6SStefano Zampini Mat C_B,CPHI; 39548bec7fa6SStefano Zampini IS is_dummy; 39558bec7fa6SStefano Zampini Vec mones; 395688ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 395788ebb749SStefano Zampini PetscReal real_value; 395888ebb749SStefano Zampini 3959a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 3960a3df083aSStefano Zampini Mat A; 3961a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 3962a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 3963a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 3964a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 3965a3df083aSStefano Zampini ierr = MatGetSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3966a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 3967a3df083aSStefano Zampini } else { 396888ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 396988ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 397088ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 397188ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 3972a3df083aSStefano Zampini } 397388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 397488ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 3975ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 397688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 397788ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 397888ebb749SStefano Zampini } 397988ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 398088ebb749SStefano Zampini 398125084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 39823301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 398325084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3984ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 398588ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 398688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 398788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 398888ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 398988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 399088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 399188ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 399288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 399388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 399488ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 399588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 399688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 399788ebb749SStefano Zampini } else { 399888ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 399988ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 400088ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 400188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 400288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 400388ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 400488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 400588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 400688ebb749SStefano Zampini } 400788ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 400888ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 400988ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 4010511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 40114f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4012fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 4013d12edf2fSStefano Zampini PetscScalar *data,*data2; 40144f1b2e48SStefano Zampini PetscInt j; 4015d12edf2fSStefano Zampini 40164f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 4017fc227af8SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 4018d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 401986c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 4020d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 4021d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 40224f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 40234f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 4024d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 40254f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 40264f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 40274f1b2e48SStefano Zampini } 4028d12edf2fSStefano Zampini } 4029d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 4030d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 4031d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4032d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4033d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4034d12edf2fSStefano Zampini } 4035d12edf2fSStefano Zampini #if 0 4036d12edf2fSStefano Zampini { 4037d12edf2fSStefano Zampini PetscViewer viewer; 4038d12edf2fSStefano Zampini char filename[256]; 4039ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4040d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4041d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4042ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4043ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4044ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4045d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 404672b8c272SStefano Zampini if (save_change) { 404772b8c272SStefano Zampini Mat phi_B; 404872b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 404972b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 405072b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 405172b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 405272b8c272SStefano Zampini } else { 4053ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4054ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 405572b8c272SStefano Zampini } 4056ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4057ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4058ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4059ffd830a3SStefano Zampini } 4060ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4061ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4062ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4063ffd830a3SStefano Zampini } 406472b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4065ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4066ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4067ffd830a3SStefano Zampini } 4068d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4069d12edf2fSStefano Zampini } 4070d12edf2fSStefano Zampini #endif 407181d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 40728bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 40731575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 407406656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 40758bec7fa6SStefano Zampini 40768bec7fa6SStefano Zampini /* check constraints */ 4077a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 4078a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 40794f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 40808bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4081a00504b5SStefano Zampini } else { 4082a00504b5SStefano Zampini PetscScalar *data; 4083a00504b5SStefano Zampini Mat tmat; 4084a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4085a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4086a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4087a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4088a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4089a00504b5SStefano Zampini } 40908bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 40918bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 40928bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 40938bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4094bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4095ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4096bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4097bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4098bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4099bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4100bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 410188ebb749SStefano Zampini } 41028bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 41038bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 41048bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 41058bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 410625084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 410788ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 410888ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 410988ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 411088ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 411188ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 411288ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 411388ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 411488ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 411588ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 411688ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4117ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 411888ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 411988ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 412088ebb749SStefano Zampini } 412188ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 412288ebb749SStefano Zampini } 41238629588bSStefano Zampini /* get back data */ 41248629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 412588ebb749SStefano Zampini PetscFunctionReturn(0); 412688ebb749SStefano Zampini } 412788ebb749SStefano Zampini 412888ebb749SStefano Zampini #undef __FUNCT__ 4129d65f70fdSStefano Zampini #define __FUNCT__ "MatGetSubMatrixUnsorted" 4130d648f858SStefano Zampini PetscErrorCode MatGetSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4131aa0d41d4SStefano Zampini { 4132d65f70fdSStefano Zampini Mat *work_mat; 4133d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4134d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4135c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4136aa0d41d4SStefano Zampini PetscErrorCode ierr; 4137aa0d41d4SStefano Zampini 4138aa0d41d4SStefano Zampini PetscFunctionBegin; 4139d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4140d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4141d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4142d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4143aa0d41d4SStefano Zampini 4144d65f70fdSStefano Zampini if (!rsorted) { 4145906d46d4SStefano Zampini const PetscInt *idxs; 4146906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4147aa0d41d4SStefano Zampini 4148d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4149d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4150d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4151d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4152aa0d41d4SStefano Zampini } 4153d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4154d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4155d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4156d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4157aa0d41d4SStefano Zampini } 4158d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4159d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4160d65f70fdSStefano Zampini } else { 4161d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4162d65f70fdSStefano Zampini isrow_s = isrow; 4163aa0d41d4SStefano Zampini } 4164906d46d4SStefano Zampini 4165d65f70fdSStefano Zampini if (!csorted) { 4166d65f70fdSStefano Zampini if (isrow == iscol) { 4167d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4168d65f70fdSStefano Zampini iscol_s = isrow_s; 4169d65f70fdSStefano Zampini } else { 4170d65f70fdSStefano Zampini const PetscInt *idxs; 4171d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4172906d46d4SStefano Zampini 4173d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4174d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4175d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4176d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4177d65f70fdSStefano Zampini } 4178d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 4179d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 4180d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4181d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 4182d65f70fdSStefano Zampini } 4183d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 4184d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 4185d65f70fdSStefano Zampini } 4186d65f70fdSStefano Zampini } else { 4187d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 4188d65f70fdSStefano Zampini iscol_s = iscol; 4189d65f70fdSStefano Zampini } 4190d65f70fdSStefano Zampini 4191d648f858SStefano Zampini ierr = MatGetSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4192d65f70fdSStefano Zampini 4193d65f70fdSStefano Zampini if (!rsorted || !csorted) { 4194906d46d4SStefano Zampini Mat new_mat; 4195d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 4196906d46d4SStefano Zampini 4197d65f70fdSStefano Zampini if (!rsorted) { 4198d65f70fdSStefano Zampini PetscInt *idxs_r,i; 4199d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 4200d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4201d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 4202906d46d4SStefano Zampini } 4203d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 4204d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 4205d65f70fdSStefano Zampini } else { 4206d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 4207906d46d4SStefano Zampini } 4208d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 4209d65f70fdSStefano Zampini 4210d65f70fdSStefano Zampini if (!csorted) { 4211d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 4212d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 4213d65f70fdSStefano Zampini is_perm_c = is_perm_r; 4214d65f70fdSStefano Zampini } else { 4215d65f70fdSStefano Zampini PetscInt *idxs_c,i; 4216f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 4217d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 4218d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4219d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 4220d65f70fdSStefano Zampini } 4221d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 4222d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 4223d65f70fdSStefano Zampini } 4224d65f70fdSStefano Zampini } else { 4225d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 4226d65f70fdSStefano Zampini } 4227d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 4228d65f70fdSStefano Zampini 4229d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 4230d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 4231d65f70fdSStefano Zampini work_mat[0] = new_mat; 4232d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 4233d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 4234d65f70fdSStefano Zampini } 4235d65f70fdSStefano Zampini 4236d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 4237d65f70fdSStefano Zampini *B = work_mat[0]; 4238d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 4239d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 4240d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 4241d65f70fdSStefano Zampini PetscFunctionReturn(0); 4242d65f70fdSStefano Zampini } 4243d65f70fdSStefano Zampini 4244d65f70fdSStefano Zampini #undef __FUNCT__ 42455e8657edSStefano Zampini #define __FUNCT__ "PCBDDCComputeLocalMatrix" 42465e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 4247aa0d41d4SStefano Zampini { 4248aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 42495e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4250d65f70fdSStefano Zampini Mat new_mat; 42515e8657edSStefano Zampini IS is_local,is_global; 4252d65f70fdSStefano Zampini PetscInt local_size; 4253d65f70fdSStefano Zampini PetscBool isseqaij; 4254aa0d41d4SStefano Zampini PetscErrorCode ierr; 4255aa0d41d4SStefano Zampini 4256aa0d41d4SStefano Zampini PetscFunctionBegin; 4257aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 42585e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 42595e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 4260b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 4261aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 4262d648f858SStefano Zampini ierr = MatGetSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 4263aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 4264906d46d4SStefano Zampini 4265906d46d4SStefano Zampini /* check */ 4266906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4267906d46d4SStefano Zampini Vec x,x_change; 4268906d46d4SStefano Zampini PetscReal error; 4269906d46d4SStefano Zampini 42705e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 4271906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 42725e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 4273e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4274e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4275d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 427688428137SStefano Zampini if (!pcbddc->change_interior) { 427788428137SStefano Zampini const PetscScalar *x,*y,*v; 427888428137SStefano Zampini PetscReal lerror = 0.; 427988428137SStefano Zampini PetscInt i; 428088428137SStefano Zampini 428188428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 428288428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 428388428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 428488428137SStefano Zampini for (i=0;i<local_size;i++) 428588428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 428688428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 428788428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 428888428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 428988428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 429088428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 429188428137SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on I: %1.6e\n",error);CHKERRQ(ierr); 429288428137SStefano Zampini } 4293e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4294e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4295906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4296906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4297906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4298906d46d4SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change on N: %1.6e\n",error);CHKERRQ(ierr); 4299906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4300906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4301906d46d4SStefano Zampini } 4302906d46d4SStefano Zampini 430322d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 43049b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 430522d5777bSStefano Zampini if (isseqaij) { 4306a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4307a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 4308aa0d41d4SStefano Zampini } else { 4309a00504b5SStefano Zampini Mat work_mat; 43101cf9b237SStefano Zampini 4311a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4312aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4313a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 43141d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 4315aa0d41d4SStefano Zampini } 43163301b35fSStefano Zampini if (matis->A->symmetric_set) { 43173301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 4318e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 43193301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 4320e496cd5dSStefano Zampini #endif 43213301b35fSStefano Zampini } 4322d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 4323aa0d41d4SStefano Zampini PetscFunctionReturn(0); 4324aa0d41d4SStefano Zampini } 4325aa0d41d4SStefano Zampini 4326aa0d41d4SStefano Zampini #undef __FUNCT__ 4327a64d13efSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalScatters" 43288ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 4329a64d13efSStefano Zampini { 4330a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4331a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4332d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 433353892102SStefano Zampini PetscInt *idx_R_local=NULL; 43343a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 43353a50541eSStefano Zampini PetscInt vbs,bs; 43366816873aSStefano Zampini PetscBT bitmask=NULL; 4337a64d13efSStefano Zampini PetscErrorCode ierr; 4338a64d13efSStefano Zampini 4339a64d13efSStefano Zampini PetscFunctionBegin; 4340b23d619eSStefano Zampini /* 4341b23d619eSStefano Zampini No need to setup local scatters if 4342b23d619eSStefano Zampini - primal space is unchanged 4343b23d619eSStefano Zampini AND 4344b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 4345b23d619eSStefano Zampini AND 4346b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 4347b23d619eSStefano Zampini */ 4348b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 4349f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 4350f4ddd8eeSStefano Zampini } 4351f4ddd8eeSStefano Zampini /* destroy old objects */ 4352f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 4353f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 4354f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 4355a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 4356b371cd4fSStefano Zampini n_B = pcis->n_B; 4357b371cd4fSStefano Zampini n_D = pcis->n - n_B; 4358b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 43593a50541eSStefano Zampini 4360a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 43616816873aSStefano Zampini 436253892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 4363b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4364854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 4365a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 4366a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 43670e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 4368a64d13efSStefano Zampini } 4369a64d13efSStefano Zampini 4370a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 43714641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 43726816873aSStefano Zampini idx_R_local[n_R++] = i; 4373a64d13efSStefano Zampini } 4374a64d13efSStefano Zampini } 4375df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 4376df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 43776816873aSStefano Zampini 4378df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4379df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 43806816873aSStefano Zampini } 43813a50541eSStefano Zampini 43823a50541eSStefano Zampini /* Block code */ 43833a50541eSStefano Zampini vbs = 1; 43843a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 43853a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 43863a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 43873a50541eSStefano Zampini PetscInt *vary; 4388b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4389785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 43903a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 4391d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 4392d3df7717SStefano Zampini /* it is ok to check this way since local_primal_ref_node are always sorted by local numbering and idx_R_local is obtained as a complement */ 43930e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 4394d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 43953a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 43963a50541eSStefano Zampini is_blocked = PETSC_FALSE; 43973a50541eSStefano Zampini break; 43983a50541eSStefano Zampini } 43993a50541eSStefano Zampini } 4400d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 4401d3df7717SStefano Zampini } else { 4402d3df7717SStefano Zampini /* Verify directly the R set */ 4403d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 4404d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 4405d3df7717SStefano Zampini for (j=1; j<bs; j++) { 4406d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 4407d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 4408d3df7717SStefano Zampini break; 4409d3df7717SStefano Zampini } 4410d3df7717SStefano Zampini } 4411d3df7717SStefano Zampini } 4412d3df7717SStefano Zampini } 44133a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 44143a50541eSStefano Zampini vbs = bs; 44153a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 44163a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 44173a50541eSStefano Zampini } 44183a50541eSStefano Zampini } 44193a50541eSStefano Zampini } 44203a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 4421b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4422df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 442353892102SStefano Zampini 4424df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4425df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 442653892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 4427df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 442853892102SStefano Zampini } else { 44293a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 443053892102SStefano Zampini } 4431a64d13efSStefano Zampini 4432a64d13efSStefano Zampini /* print some info if requested */ 4433a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 4434a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4435a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 44361575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4437a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 4438a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 44394f1b2e48SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"r_size = %d, v_size = %d, constraints = %d, local_primal_size = %d\n",n_R,n_vertices,pcbddc->local_primal_size-n_vertices-pcbddc->benign_n,pcbddc->local_primal_size);CHKERRQ(ierr); 4440a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4441a64d13efSStefano Zampini } 4442a64d13efSStefano Zampini 4443a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 4444b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 44456816873aSStefano Zampini IS is_aux1,is_aux2; 44466816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 44476816873aSStefano Zampini 44483a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4449854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 4450854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 4451a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 44524641a718SStefano Zampini for (i=0; i<n_D; i++) { 44534641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 44544641a718SStefano Zampini } 4455a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4456a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 44574641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 44584641a718SStefano Zampini aux_array1[j++] = i; 4459a64d13efSStefano Zampini } 4460a64d13efSStefano Zampini } 4461a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4462a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4463a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 44644641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 44654641a718SStefano Zampini aux_array2[j++] = i; 4466a64d13efSStefano Zampini } 4467a64d13efSStefano Zampini } 4468a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4469a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 4470a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 4471a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4472a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 4473a64d13efSStefano Zampini 44748eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4475785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 4476a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 44774641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 44784641a718SStefano Zampini aux_array1[j++] = i; 4479a64d13efSStefano Zampini } 4480a64d13efSStefano Zampini } 4481a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4482a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 4483a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4484a64d13efSStefano Zampini } 44854641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 44863a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4487d62866d3SStefano Zampini } else { 4488df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 44896816873aSStefano Zampini IS tis; 44906816873aSStefano Zampini PetscInt schur_size; 44916816873aSStefano Zampini 4492df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 44936816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 4494df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 44956816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 44966816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 44976816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 44986816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 44996816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 4500d62866d3SStefano Zampini } 4501d62866d3SStefano Zampini } 4502a64d13efSStefano Zampini PetscFunctionReturn(0); 4503a64d13efSStefano Zampini } 4504a64d13efSStefano Zampini 4505304d26faSStefano Zampini 4506304d26faSStefano Zampini #undef __FUNCT__ 4507304d26faSStefano Zampini #define __FUNCT__ "PCBDDCSetUpLocalSolvers" 4508684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 4509304d26faSStefano Zampini { 4510304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4511304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4512304d26faSStefano Zampini PC pc_temp; 4513304d26faSStefano Zampini Mat A_RR; 4514f4ddd8eeSStefano Zampini MatReuse reuse; 4515304d26faSStefano Zampini PetscScalar m_one = -1.0; 4516304d26faSStefano Zampini PetscReal value; 451704708bb6SStefano Zampini PetscInt n_D,n_R; 4518c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 4519304d26faSStefano Zampini PetscErrorCode ierr; 4520e604994aSStefano Zampini /* prefixes stuff */ 4521312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 4522e604994aSStefano Zampini size_t len; 4523304d26faSStefano Zampini 4524304d26faSStefano Zampini PetscFunctionBegin; 4525304d26faSStefano Zampini 4526e604994aSStefano Zampini /* compute prefixes */ 4527e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 4528e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 4529e604994aSStefano Zampini if (!pcbddc->current_level) { 4530e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4531e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4532e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4533e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4534e604994aSStefano Zampini } else { 4535e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4536312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4537e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4538e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 4539312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4540312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 454134d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 454234d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4543e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4544e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4545e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 4546e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 4547e604994aSStefano Zampini } 4548e604994aSStefano Zampini 4549304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 4550684f6988SStefano Zampini if (dirichlet) { 4551d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4552450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 45539a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 4554450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 4555a3df083aSStefano Zampini Mat A_IIn; 4556a3df083aSStefano Zampini 4557a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 4558a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 4559a3df083aSStefano Zampini pcis->A_II = A_IIn; 4560a3df083aSStefano Zampini } 4561450f8f5eSStefano Zampini } 45623301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 45633301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 4564964fefecSStefano Zampini } 4565ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 4566964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 4567304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 4568304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 4569304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 4570304d26faSStefano Zampini /* default */ 4571304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 4572e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 45739577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 4574304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 45759577ea80SStefano Zampini if (issbaij) { 45769577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 45779577ea80SStefano Zampini } else { 4578304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 45799577ea80SStefano Zampini } 4580304d26faSStefano Zampini /* Allow user's customization */ 4581304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 4582304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4583304d26faSStefano Zampini } 4584d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 4585b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4586df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4587d62866d3SStefano Zampini 4588df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 4589d5574798SStefano Zampini } 4590304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4591304d26faSStefano Zampini if (!n_D) { 4592304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 4593304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4594304d26faSStefano Zampini } 4595304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 4596304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 4597304d26faSStefano Zampini /* set ksp_D into pcis data */ 4598304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 4599304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 4600304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 4601684f6988SStefano Zampini } 4602304d26faSStefano Zampini 4603304d26faSStefano Zampini /* NEUMANN PROBLEM */ 4604684f6988SStefano Zampini A_RR = 0; 4605684f6988SStefano Zampini if (neumann) { 4606d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 460704708bb6SStefano Zampini PetscInt ibs,mbs; 460804708bb6SStefano Zampini PetscBool issbaij; 460904708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4610f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 46118ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 4612f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 4613f4ddd8eeSStefano Zampini PetscInt nn_R; 461481d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 4615f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4616f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 4617f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 4618f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 4619f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4620f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4621f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 4622727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 4623f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4624f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4625f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 4626f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 4627f4ddd8eeSStefano Zampini } 4628f4ddd8eeSStefano Zampini } 4629f4ddd8eeSStefano Zampini /* last check */ 4630d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 4631f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4632f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4633f4ddd8eeSStefano Zampini } 4634f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 4635f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4636f4ddd8eeSStefano Zampini } 4637a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 4638af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 4639af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 464004708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 464104708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 464204708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 464304708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 464404708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 4645af732b37SStefano Zampini } else { 4646511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 46476816873aSStefano Zampini } 464804708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 464904708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 465004708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 465104708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 465204708bb6SStefano Zampini } else { 4653511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 465404708bb6SStefano Zampini } 465504708bb6SStefano Zampini } 4656a00504b5SStefano Zampini /* extract A_RR */ 4657b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4658a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4659a00504b5SStefano Zampini 4660a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 466116e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4662a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 466316e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 466416e386b8SStefano Zampini } else { 4665a00504b5SStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 4666a00504b5SStefano Zampini } 4667a00504b5SStefano Zampini } else { 4668a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4669a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 4670a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4671a00504b5SStefano Zampini } 4672a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 4673f4ddd8eeSStefano Zampini ierr = MatGetSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 467416e386b8SStefano Zampini } 46753301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 46763301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 46776816873aSStefano Zampini } 4678f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 4679304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 4680304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 4681304d26faSStefano Zampini /* default */ 4682304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 4683e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 4684304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 46859577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 46869577ea80SStefano Zampini if (issbaij) { 46879577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 46889577ea80SStefano Zampini } else { 4689304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 46909577ea80SStefano Zampini } 4691304d26faSStefano Zampini /* Allow user's customization */ 4692304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 4693304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4694304d26faSStefano Zampini } 4695304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4696304d26faSStefano Zampini if (!n_R) { 4697304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 4698304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4699304d26faSStefano Zampini } 47005cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 4701df4d28bfSStefano Zampini /* Reuse solver if it is present */ 4702b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4703df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4704d62866d3SStefano Zampini 4705df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 4706d62866d3SStefano Zampini } 4707304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 4708304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 4709684f6988SStefano Zampini } 4710304d26faSStefano Zampini 4711684f6988SStefano Zampini if (pcbddc->dbg_flag) { 4712684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 47131575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4714684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4715684f6988SStefano Zampini } 4716c7017625SStefano Zampini 4717c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 4718c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 4719c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 4720c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 4721c7017625SStefano Zampini } 4722c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 4723c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 4724c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 4725c7017625SStefano Zampini } 4726c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 4727c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 4728c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 4729c7017625SStefano Zampini } 4730c7017625SStefano Zampini 4731c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 4732c7017625SStefano Zampini if (pcbddc->dbg_flag) { 4733684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 47340fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 47350fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 47360fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 47370fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 47380fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 4739e604994aSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d infinity error for Dirichlet solve (%s) = % 1.14e \n",PetscGlobalRank,((PetscObject)(pcbddc->ksp_D))->prefix,value);CHKERRQ(ierr); 4740c7017625SStefano Zampini if (check_corr[0]) { 4741c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 4742c7017625SStefano Zampini } 4743304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4744304d26faSStefano Zampini } 4745684f6988SStefano Zampini if (neumann) { /* Neumann */ 47460fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 47470fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 47480fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 47490fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 47500fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 4751e604994aSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d infinity error for Neumann solve (%s) = % 1.14e\n",PetscGlobalRank,((PetscObject)(pcbddc->ksp_R))->prefix,value);CHKERRQ(ierr); 4752c7017625SStefano Zampini if (check_corr[1]) { 4753c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 4754c7017625SStefano Zampini } 4755304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4756304d26faSStefano Zampini } 4757684f6988SStefano Zampini } 47585cbda25cSStefano Zampini /* free Neumann problem's matrix */ 47595cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4760304d26faSStefano Zampini PetscFunctionReturn(0); 4761304d26faSStefano Zampini } 4762304d26faSStefano Zampini 4763304d26faSStefano Zampini #undef __FUNCT__ 4764ba15a52eSStefano Zampini #define __FUNCT__ "PCBDDCSolveSubstructureCorrection" 476580677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 4766674ae819SStefano Zampini { 4767674ae819SStefano Zampini PetscErrorCode ierr; 4768674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4769be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4770b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 4771674ae819SStefano Zampini 4772674ae819SStefano Zampini PetscFunctionBegin; 4773b334f244SStefano Zampini if (!reuse_solver) { 477480677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 477520c7b377SStefano Zampini } 477680677318SStefano Zampini if (!pcbddc->switch_static) { 477780677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 477880677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 477980677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 478020c7b377SStefano Zampini } 4781b334f244SStefano Zampini if (!reuse_solver) { 478280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 478380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 478420c7b377SStefano Zampini } else { 4785df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4786be83ff47SStefano Zampini 4787df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4788df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 478920c7b377SStefano Zampini } 4790be83ff47SStefano Zampini } else { 479180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 479280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 479380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 479480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 479580677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 479680677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 479780677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 479880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 479980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4800674ae819SStefano Zampini } 4801674ae819SStefano Zampini } 4802b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 480380677318SStefano Zampini if (applytranspose) { 480480677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 480580677318SStefano Zampini } else { 480680677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 480780677318SStefano Zampini } 4808be83ff47SStefano Zampini } else { 4809df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4810be83ff47SStefano Zampini 4811be83ff47SStefano Zampini if (applytranspose) { 4812df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4813be83ff47SStefano Zampini } else { 4814df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 4815be83ff47SStefano Zampini } 4816be83ff47SStefano Zampini } 481780677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 481880677318SStefano Zampini if (!pcbddc->switch_static) { 4819b334f244SStefano Zampini if (!reuse_solver) { 482080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 482180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4822be83ff47SStefano Zampini } else { 4823df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4824be83ff47SStefano Zampini 4825df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4826df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4827be83ff47SStefano Zampini } 482880677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 482980677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 483080677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 483180677318SStefano Zampini } 483280677318SStefano Zampini } else { 483380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 483480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 483580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 483680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 483780677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 483880677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 483980677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 484080677318SStefano Zampini } 484180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 484280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 484380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 484480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4845674ae819SStefano Zampini } 4846674ae819SStefano Zampini PetscFunctionReturn(0); 4847674ae819SStefano Zampini } 4848674ae819SStefano Zampini 4849dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 4850674ae819SStefano Zampini #undef __FUNCT__ 4851674ae819SStefano Zampini #define __FUNCT__ "PCBDDCApplyInterfacePreconditioner" 4852dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 4853674ae819SStefano Zampini { 4854674ae819SStefano Zampini PetscErrorCode ierr; 4855674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4856674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 4857674ae819SStefano Zampini const PetscScalar zero = 0.0; 4858674ae819SStefano Zampini 4859674ae819SStefano Zampini PetscFunctionBegin; 4860dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 48614fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4862dc359a40SStefano Zampini if (applytranspose) { 4863674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 48648eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 4865dc359a40SStefano Zampini } else { 4866674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 4867674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 486815aaf578SStefano Zampini } 48694fee134fSStefano Zampini } else { 48704fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 48714fee134fSStefano Zampini } 4872efc2fbd9SStefano Zampini 4873efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 48744f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4875efc2fbd9SStefano Zampini PetscScalar *array; 48764f1b2e48SStefano Zampini PetscInt j; 4877efc2fbd9SStefano Zampini 4878efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 48794f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 4880efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4881efc2fbd9SStefano Zampini } 4882efc2fbd9SStefano Zampini 488312edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 488412edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 488512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 488612edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 488712edc857SStefano Zampini 48889f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 488912edc857SStefano Zampini if (pcbddc->coarse_ksp) { 489051694757SStefano Zampini Mat coarse_mat; 4891964fefecSStefano Zampini Vec rhs,sol; 489251694757SStefano Zampini MatNullSpace nullsp; 489327b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 4894964fefecSStefano Zampini 489527b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 489627b6a85dSStefano Zampini PC coarse_pc; 489727b6a85dSStefano Zampini 489827b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 489927b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 490027b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 490127b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 490227b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 490327b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 49043bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 490527b6a85dSStefano Zampini } 490627b6a85dSStefano Zampini } 4907964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 4908964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 490951694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 491051694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 491151694757SStefano Zampini if (nullsp) { 491251694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 491351694757SStefano Zampini } 491412edc857SStefano Zampini if (applytranspose) { 49159a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 4916964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 49172701bc32SStefano Zampini } else { 49181f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 49192701bc32SStefano Zampini PC coarse_pc; 49202701bc32SStefano Zampini 49212701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 49222701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 49233e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 49242701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 492512edc857SStefano Zampini } else { 4926964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 492712edc857SStefano Zampini } 49282701bc32SStefano Zampini } 49291d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 493027b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 493127b6a85dSStefano Zampini PC coarse_pc; 493227b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 493327b6a85dSStefano Zampini 493427b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 493527b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 493627b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 49373bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 493827b6a85dSStefano Zampini } 493951694757SStefano Zampini if (nullsp) { 494051694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 494151694757SStefano Zampini } 494212edc857SStefano Zampini } 4943674ae819SStefano Zampini 4944674ae819SStefano Zampini /* Local solution on R nodes */ 49454fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 494680677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 49479f00e9b4SStefano Zampini } 49489f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 49499f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 495012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4951674ae819SStefano Zampini 49524fee134fSStefano Zampini /* Sum contributions from the two levels */ 49534fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 4954dc359a40SStefano Zampini if (applytranspose) { 4955dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 4956dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4957dc359a40SStefano Zampini } else { 4958674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 49598eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 4960dc359a40SStefano Zampini } 4961efc2fbd9SStefano Zampini /* store p0 */ 49624f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4963efc2fbd9SStefano Zampini PetscScalar *array; 49644f1b2e48SStefano Zampini PetscInt j; 4965efc2fbd9SStefano Zampini 4966efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 49674f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 4968efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 4969efc2fbd9SStefano Zampini } 49704fee134fSStefano Zampini } else { /* expand the coarse solution */ 49714fee134fSStefano Zampini if (applytranspose) { 49724fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 49734fee134fSStefano Zampini } else { 49744fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 49754fee134fSStefano Zampini } 49764fee134fSStefano Zampini } 4977674ae819SStefano Zampini PetscFunctionReturn(0); 4978674ae819SStefano Zampini } 4979674ae819SStefano Zampini 4980674ae819SStefano Zampini #undef __FUNCT__ 4981674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataBegin" 498212edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 4983674ae819SStefano Zampini { 4984674ae819SStefano Zampini PetscErrorCode ierr; 4985674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 498658da7f69SStefano Zampini PetscScalar *array; 498712edc857SStefano Zampini Vec from,to; 4988674ae819SStefano Zampini 4989674ae819SStefano Zampini PetscFunctionBegin; 499012edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 499112edc857SStefano Zampini from = pcbddc->coarse_vec; 499212edc857SStefano Zampini to = pcbddc->vec1_P; 499312edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 499412edc857SStefano Zampini Vec tvec; 499558da7f69SStefano Zampini 499658da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 499758da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 499812edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 499958da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 500058da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 500158da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 500212edc857SStefano Zampini } 500312edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 500412edc857SStefano Zampini from = pcbddc->vec1_P; 500512edc857SStefano Zampini to = pcbddc->coarse_vec; 500612edc857SStefano Zampini } 500712edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 5008674ae819SStefano Zampini PetscFunctionReturn(0); 5009674ae819SStefano Zampini } 5010674ae819SStefano Zampini 5011674ae819SStefano Zampini #undef __FUNCT__ 5012674ae819SStefano Zampini #define __FUNCT__ "PCBDDCScatterCoarseDataEnd" 501312edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 5014674ae819SStefano Zampini { 5015674ae819SStefano Zampini PetscErrorCode ierr; 5016674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 501758da7f69SStefano Zampini PetscScalar *array; 501812edc857SStefano Zampini Vec from,to; 5019674ae819SStefano Zampini 5020674ae819SStefano Zampini PetscFunctionBegin; 502112edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 502212edc857SStefano Zampini from = pcbddc->coarse_vec; 502312edc857SStefano Zampini to = pcbddc->vec1_P; 502412edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 502512edc857SStefano Zampini from = pcbddc->vec1_P; 502612edc857SStefano Zampini to = pcbddc->coarse_vec; 502712edc857SStefano Zampini } 502812edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 502912edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 503012edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 503112edc857SStefano Zampini Vec tvec; 503258da7f69SStefano Zampini 503312edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 503458da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 503558da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 503658da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 503758da7f69SStefano Zampini } 503858da7f69SStefano Zampini } else { 503958da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 504058da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 504112edc857SStefano Zampini } 504212edc857SStefano Zampini } 5043674ae819SStefano Zampini PetscFunctionReturn(0); 5044674ae819SStefano Zampini } 5045674ae819SStefano Zampini 5046984c4197SStefano Zampini /* uncomment for testing purposes */ 5047984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 5048674ae819SStefano Zampini #undef __FUNCT__ 5049674ae819SStefano Zampini #define __FUNCT__ "PCBDDCConstraintsSetUp" 5050674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 5051674ae819SStefano Zampini { 5052674ae819SStefano Zampini PetscErrorCode ierr; 5053674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5054674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5055674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5056984c4197SStefano Zampini /* one and zero */ 5057984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 5058984c4197SStefano Zampini /* space to store constraints and their local indices */ 50599162d606SStefano Zampini PetscScalar *constraints_data; 50609162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 50619162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 50629162d606SStefano Zampini PetscInt *constraints_n; 5063984c4197SStefano Zampini /* iterators */ 5064b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 5065984c4197SStefano Zampini /* BLAS integers */ 5066e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 5067e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 5068c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 5069727cdba6SStefano Zampini /* reuse */ 50700e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 50710e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 5072984c4197SStefano Zampini /* change of basis */ 5073b3d85658SStefano Zampini PetscBool qr_needed; 50749162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 5075984c4197SStefano Zampini /* auxiliary stuff */ 507664efe560SStefano Zampini PetscInt *nnz,*is_indices; 50778a0068c3SStefano Zampini PetscInt ncc; 5078984c4197SStefano Zampini /* some quantities */ 507945a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 5080a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 5081984c4197SStefano Zampini 5082674ae819SStefano Zampini PetscFunctionBegin; 50838e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 50848e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 50858e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 508616909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 5087088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 5088088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 50890e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 50900e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 50910e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 50920e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 50930e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 5094088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5095cf5a6209SStefano Zampini 5096cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 50979162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 5098cf5a6209SStefano Zampini MatNullSpace nearnullsp; 5099cf5a6209SStefano Zampini const Vec *nearnullvecs; 5100cf5a6209SStefano Zampini Vec *localnearnullsp; 5101cf5a6209SStefano Zampini PetscScalar *array; 5102cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 5103cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 5104674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 5105b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 5106674ae819SStefano Zampini PetscScalar *work; 5107674ae819SStefano Zampini PetscReal *singular_vals; 5108674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5109674ae819SStefano Zampini PetscReal *rwork; 5110674ae819SStefano Zampini #endif 5111674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5112674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 5113674ae819SStefano Zampini #else 5114964fefecSStefano Zampini PetscBLASInt dummy_int=1; 5115964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 5116674ae819SStefano Zampini #endif 5117674ae819SStefano Zampini 5118674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 5119d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 5120e4d548c7SStefano Zampini /* print some info */ 51215c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 5122e4d548c7SStefano Zampini PetscInt nv; 5123e4d548c7SStefano Zampini 5124c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5125e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 5126e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5127e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5128e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 5129e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 5130e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 5131e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5132e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5133e4d548c7SStefano Zampini } 5134e4d548c7SStefano Zampini 5135d06fc5fdSStefano Zampini /* free unneeded index sets */ 5136d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 5137d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 5138674ae819SStefano Zampini } 5139d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 5140d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5141d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5142d06fc5fdSStefano Zampini } 5143d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5144d06fc5fdSStefano Zampini n_ISForEdges = 0; 5145d06fc5fdSStefano Zampini } 5146d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 5147d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5148d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5149d06fc5fdSStefano Zampini } 5150d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5151d06fc5fdSStefano Zampini n_ISForFaces = 0; 5152d06fc5fdSStefano Zampini } 515370022509SStefano Zampini 5154674ae819SStefano Zampini /* check if near null space is attached to global mat */ 5155674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 5156674ae819SStefano Zampini if (nearnullsp) { 5157674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 5158f4ddd8eeSStefano Zampini /* remove any stored info */ 5159f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 5160f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5161f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 5162f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 5163f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 5164473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5165f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 5166f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 5167f4ddd8eeSStefano Zampini } 5168984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 5169984c4197SStefano Zampini nnsp_size = 0; 5170674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 5171674ae819SStefano Zampini } 5172984c4197SStefano Zampini /* get max number of constraints on a single cc */ 5173984c4197SStefano Zampini max_constraints = nnsp_size; 5174984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 5175984c4197SStefano Zampini 5176674ae819SStefano Zampini /* 5177674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 51789162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 51799162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 51809162d606SStefano Zampini There can be multiple constraints per connected component 5181674ae819SStefano Zampini */ 5182674ae819SStefano Zampini n_vertices = 0; 5183674ae819SStefano Zampini if (ISForVertices) { 5184674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 5185674ae819SStefano Zampini } 51869162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 51879162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 51889162d606SStefano Zampini 51899162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 51909162d606SStefano Zampini total_counts *= max_constraints; 5191674ae819SStefano Zampini total_counts += n_vertices; 51924641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 51939162d606SStefano Zampini 5194674ae819SStefano Zampini total_counts = 0; 5195674ae819SStefano Zampini max_size_of_constraint = 0; 5196674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 51979162d606SStefano Zampini IS used_is; 5198674ae819SStefano Zampini if (i<n_ISForEdges) { 51999162d606SStefano Zampini used_is = ISForEdges[i]; 5200674ae819SStefano Zampini } else { 52019162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 5202674ae819SStefano Zampini } 52039162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 5204674ae819SStefano Zampini total_counts += j; 5205674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 5206674ae819SStefano Zampini } 52079162d606SStefano Zampini ierr = PetscMalloc3(total_counts*max_constraints+n_vertices,&constraints_data,total_counts+n_vertices,&constraints_idxs,total_counts+n_vertices,&constraints_idxs_B);CHKERRQ(ierr); 52089162d606SStefano Zampini 5209984c4197SStefano Zampini /* get local part of global near null space vectors */ 5210785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 5211984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5212984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 5213e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5214e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5215984c4197SStefano Zampini } 5216674ae819SStefano Zampini 5217242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 5218242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 5219a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 5220242a89d7SStefano Zampini 5221984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 5222a773dcb8SStefano Zampini if (!skip_lapack) { 5223674ae819SStefano Zampini PetscScalar temp_work; 5224911cabfeSStefano Zampini 5225674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5226984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 5227785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 5228785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 5229785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 5230674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5231785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 5232674ae819SStefano Zampini #endif 5233674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5234c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 5235c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 5236674ae819SStefano Zampini lwork = -1; 5237674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5238674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5239c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 5240674ae819SStefano Zampini #else 5241c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 5242674ae819SStefano Zampini #endif 5243674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5244984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 5245674ae819SStefano Zampini #else /* on missing GESVD */ 5246674ae819SStefano Zampini /* SVD */ 5247674ae819SStefano Zampini PetscInt max_n,min_n; 5248674ae819SStefano Zampini max_n = max_size_of_constraint; 5249984c4197SStefano Zampini min_n = max_constraints; 5250984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 5251674ae819SStefano Zampini min_n = max_size_of_constraint; 5252984c4197SStefano Zampini max_n = max_constraints; 5253674ae819SStefano Zampini } 5254785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 5255674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5256785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 5257674ae819SStefano Zampini #endif 5258674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5259674ae819SStefano Zampini lwork = -1; 5260e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 5261e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 5262b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 5263674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5264674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 52659162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&constraints_data[0],&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,&lierr)); 5266674ae819SStefano Zampini #else 52679162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,&constraints_data[0],&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,&temp_work,&lwork,rwork,&lierr)); 5268674ae819SStefano Zampini #endif 5269674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5270984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 5271984c4197SStefano Zampini #endif /* on missing GESVD */ 5272674ae819SStefano Zampini /* Allocate optimal workspace */ 5273674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 5274854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 5275674ae819SStefano Zampini } 5276674ae819SStefano Zampini /* Now we can loop on constraining sets */ 5277674ae819SStefano Zampini total_counts = 0; 52789162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 52799162d606SStefano Zampini constraints_data_ptr[0] = 0; 5280674ae819SStefano Zampini /* vertices */ 52819162d606SStefano Zampini if (n_vertices) { 5282674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 52839162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 5284674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 52859162d606SStefano Zampini constraints_n[total_counts] = 1; 52869162d606SStefano Zampini constraints_data[total_counts] = 1.0; 52879162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 52889162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 5289674ae819SStefano Zampini total_counts++; 5290674ae819SStefano Zampini } 5291674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5292674ae819SStefano Zampini n_vertices = total_counts; 5293674ae819SStefano Zampini } 5294984c4197SStefano Zampini 5295674ae819SStefano Zampini /* edges and faces */ 52969162d606SStefano Zampini total_counts_cc = total_counts; 5297911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 52989162d606SStefano Zampini IS used_is; 52999162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 53009162d606SStefano Zampini 5301911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 53029162d606SStefano Zampini used_is = ISForEdges[ncc]; 5303984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 5304674ae819SStefano Zampini } else { 53059162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 5306984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 5307674ae819SStefano Zampini } 5308674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 53099162d606SStefano Zampini 53109162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 53119162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5312984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 5313984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 5314674ae819SStefano Zampini if (nnsp_has_cnst) { 53155b08dc53SStefano Zampini PetscScalar quad_value; 53169162d606SStefano Zampini 53179162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 53189162d606SStefano Zampini idxs_copied = PETSC_TRUE; 53199162d606SStefano Zampini 5320a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 5321674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 5322a773dcb8SStefano Zampini } else { 5323a773dcb8SStefano Zampini quad_value = 1.0; 5324a773dcb8SStefano Zampini } 5325674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 53269162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 5327674ae819SStefano Zampini } 53289162d606SStefano Zampini temp_constraints++; 5329674ae819SStefano Zampini total_counts++; 5330674ae819SStefano Zampini } 5331674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 5332984c4197SStefano Zampini PetscReal real_value; 53339162d606SStefano Zampini PetscScalar *ptr_to_data; 53349162d606SStefano Zampini 5335984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 53369162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 5337674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 53389162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 5339674ae819SStefano Zampini } 5340984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 5341984c4197SStefano Zampini /* check if array is null on the connected component */ 5342e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 53439162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 53445b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 5345674ae819SStefano Zampini temp_constraints++; 5346674ae819SStefano Zampini total_counts++; 53479162d606SStefano Zampini if (!idxs_copied) { 53489162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 53499162d606SStefano Zampini idxs_copied = PETSC_TRUE; 5350674ae819SStefano Zampini } 5351674ae819SStefano Zampini } 53529162d606SStefano Zampini } 53539162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 535445a1bb75SStefano Zampini valid_constraints = temp_constraints; 5355eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 5356a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 53579162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 53589162d606SStefano Zampini 53599162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5360a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 53619162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 5362a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 53639162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 5364a773dcb8SStefano Zampini } else { /* perform SVD */ 5365984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 53669162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5367674ae819SStefano Zampini 5368674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5369984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 5370984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 5371984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 5372984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 5373984c4197SStefano Zampini from that computed using LAPACKgesvd 5374984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 5375984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 5376984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 5377674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 5378e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5379984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5380674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 5381674ae819SStefano Zampini for (k=0;k<j+1;k++) { 53829162d606SStefano Zampini PetscStackCallBLAS("BLASdot",correlation_mat[j*temp_constraints+k] = BLASdot_(&Blas_N,ptr_to_data+k*size_of_constraint,&Blas_one,ptr_to_data+j*size_of_constraint,&Blas_one)); 5383674ae819SStefano Zampini } 5384674ae819SStefano Zampini } 5385e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 5386e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5387e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 5388674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5389c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 5390674ae819SStefano Zampini #else 5391c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 5392674ae819SStefano Zampini #endif 5393674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5394984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 5395984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 5396674ae819SStefano Zampini j = 0; 5397984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 5398674ae819SStefano Zampini total_counts = total_counts-j; 539945a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 5400e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 5401c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5402c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5403c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 5404c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5405c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 5406c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5407674ae819SStefano Zampini if (j<temp_constraints) { 5408984c4197SStefano Zampini PetscInt ii; 5409984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 5410674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 54119162d606SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,ptr_to_data,&Blas_LDA,correlation_mat,&Blas_LDB,&zero,temp_basis,&Blas_LDC)); 5412674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5413984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 5414674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 54159162d606SStefano Zampini ptr_to_data[k*size_of_constraint+ii] = singular_vals[temp_constraints-1-k]*temp_basis[(temp_constraints-1-k)*size_of_constraint+ii]; 5416674ae819SStefano Zampini } 5417674ae819SStefano Zampini } 5418674ae819SStefano Zampini } 5419674ae819SStefano Zampini #else /* on missing GESVD */ 5420e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5421e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5422b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5423674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5424674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 54259162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,ptr_to_data,&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,&lierr)); 5426674ae819SStefano Zampini #else 54279162d606SStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("O","N",&Blas_M,&Blas_N,ptr_to_data,&Blas_LDA,singular_vals,&dummy_scalar,&dummy_int,&dummy_scalar,&dummy_int,work,&lwork,rwork,&lierr)); 5428674ae819SStefano Zampini #endif 5429984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 5430674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5431984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 5432e310c8b4SStefano Zampini k = temp_constraints; 5433e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 5434674ae819SStefano Zampini j = 0; 5435e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 543645a1bb75SStefano Zampini valid_constraints = k-j; 5437911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 5438984c4197SStefano Zampini #endif /* on missing GESVD */ 5439674ae819SStefano Zampini } 5440a773dcb8SStefano Zampini } 54419162d606SStefano Zampini /* update pointers information */ 54429162d606SStefano Zampini if (valid_constraints) { 54439162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 54449162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 54459162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 54469162d606SStefano Zampini /* set change_of_basis flag */ 544745a1bb75SStefano Zampini if (boolforchange) { 5448b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 54499162d606SStefano Zampini } 5450b3d85658SStefano Zampini total_counts_cc++; 545145a1bb75SStefano Zampini } 545245a1bb75SStefano Zampini } 5453984c4197SStefano Zampini /* free workspace */ 54548f1c130eSStefano Zampini if (!skip_lapack) { 5455984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 5456984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5457984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 5458984c4197SStefano Zampini #endif 5459984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 5460984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5461984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 5462984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 5463984c4197SStefano Zampini #endif 5464984c4197SStefano Zampini } 5465984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5466984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 5467984c4197SStefano Zampini } 5468984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 5469cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 5470cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5471cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5472cf5a6209SStefano Zampini } 5473cf5a6209SStefano Zampini if (n_ISForFaces) { 5474cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5475cf5a6209SStefano Zampini } 5476cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5477cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5478cf5a6209SStefano Zampini } 5479cf5a6209SStefano Zampini if (n_ISForEdges) { 5480cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5481cf5a6209SStefano Zampini } 5482cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 548308122e43SStefano Zampini } else { 548408122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5485984c4197SStefano Zampini 548608122e43SStefano Zampini total_counts = 0; 548708122e43SStefano Zampini n_vertices = 0; 5488d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 5489d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 549008122e43SStefano Zampini } 549108122e43SStefano Zampini max_constraints = 0; 54929162d606SStefano Zampini total_counts_cc = 0; 549308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 549408122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 54959162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 549608122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 549708122e43SStefano Zampini } 54989162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 54999162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 55009162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 55019162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 550274d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 55039162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 55049162d606SStefano Zampini total_counts_cc = 0; 55059162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 55069162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 55079162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 550808122e43SStefano Zampini } 550908122e43SStefano Zampini } 55109162d606SStefano Zampini #if 0 55119162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 55129162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 55139162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 55149162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 55159162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 55169162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 55179162d606SStefano Zampini } 55189162d606SStefano Zampini printf("\n"); 55199162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 55209162d606SStefano Zampini } 55211b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 55228bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 55231b968477SStefano Zampini } 55241b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 55258bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] sub %d, edge %d, n %d\n",PetscGlobalRank,i,(PetscBool)PetscBTLookup(sub_schurs->is_edge,i),pcbddc->adaptive_constraints_n[i+n_vertices]); 55261b968477SStefano Zampini } 552708122e43SStefano Zampini #endif 552808122e43SStefano Zampini 55298bec7fa6SStefano Zampini max_size_of_constraint = 0; 55309162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) max_size_of_constraint = PetscMax(max_size_of_constraint,constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]); 55319162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 553208122e43SStefano Zampini /* Change of basis */ 5533b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 553408122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 553508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 553608122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 5537b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 553808122e43SStefano Zampini } 553908122e43SStefano Zampini } 554008122e43SStefano Zampini } 554108122e43SStefano Zampini } 5542984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 55434f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 554408122e43SStefano Zampini 55459162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 55469162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 5547*eee23b56SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for constraints indices %D != %D\n",constraints_idxs_ptr[total_counts_cc],i); 5548674ae819SStefano Zampini 5549674ae819SStefano Zampini /* Create constraint matrix */ 5550674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 555116f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 5552984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 5553984c4197SStefano Zampini 5554984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 5555a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 5556a717540cSStefano Zampini qr_needed = PETSC_FALSE; 555774d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 5558984c4197SStefano Zampini total_primal_vertices=0; 5559b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 55609162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 55619162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 556272b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 55639162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 5564b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 556564efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 55669162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 55679162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 5568a717540cSStefano Zampini } 5569b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 557091af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 5571a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 5572a717540cSStefano Zampini qr_needed = PETSC_TRUE; 5573a717540cSStefano Zampini } 5574fa434743SStefano Zampini } else { 5575b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 5576fa434743SStefano Zampini } 5577a717540cSStefano Zampini } 5578b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 5579b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 5580674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 558170022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 55824f1b2e48SStefano Zampini ierr = PetscMalloc2(pcbddc->local_primal_size_cc+pcbddc->benign_n,&pcbddc->local_primal_ref_node,pcbddc->local_primal_size_cc+pcbddc->benign_n,&pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 55830e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 55840e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 5585984c4197SStefano Zampini 5586984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 558774d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 5588785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 5589984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 559074d5cdf7SStefano Zampini 5591984c4197SStefano Zampini j = total_primal_vertices; 559274d5cdf7SStefano Zampini total_counts = total_primal_vertices; 5593b3d85658SStefano Zampini cum = total_primal_vertices; 55949162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 55954641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 5596b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 5597b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 5598b3d85658SStefano Zampini cum++; 55999162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 560074d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 560174d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 560274d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 560374d5cdf7SStefano Zampini } 56049162d606SStefano Zampini j += constraints_n[i]; 5605674ae819SStefano Zampini } 5606674ae819SStefano Zampini } 5607674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 5608674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 5609088faed8SStefano Zampini 5610674ae819SStefano Zampini /* set values in constraint matrix */ 5611984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 56120e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5613674ae819SStefano Zampini } 5614984c4197SStefano Zampini total_counts = total_primal_vertices; 56159162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 56164641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 56179162d606SStefano Zampini PetscInt *cols; 56189162d606SStefano Zampini 56199162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 56209162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 56219162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 56229162d606SStefano Zampini PetscInt row = total_counts+k; 56239162d606SStefano Zampini PetscScalar *vals; 56249162d606SStefano Zampini 56259162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 56269162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 56279162d606SStefano Zampini } 56289162d606SStefano Zampini total_counts += constraints_n[i]; 5629674ae819SStefano Zampini } 5630674ae819SStefano Zampini } 5631674ae819SStefano Zampini /* assembling */ 5632674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5633674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5634088faed8SStefano Zampini 5635984c4197SStefano Zampini /* 56366a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5637984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 5638f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 5639984c4197SStefano Zampini */ 5640674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 5641674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 5642026de310SStefano Zampini /* dual and primal dofs on a single cc */ 5643984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 5644984c4197SStefano Zampini /* working stuff for GEQRF */ 564581d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 5646984c4197SStefano Zampini PetscBLASInt lqr_work; 5647984c4197SStefano Zampini /* working stuff for UNGQR */ 5648984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 5649984c4197SStefano Zampini PetscBLASInt lgqr_work; 5650984c4197SStefano Zampini /* working stuff for TRTRS */ 5651984c4197SStefano Zampini PetscScalar *trs_rhs; 56523f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 5653984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 5654984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 5655984c4197SStefano Zampini PetscScalar *start_vals; 5656984c4197SStefano Zampini /* working stuff for values insertion */ 56574641a718SStefano Zampini PetscBT is_primal; 565864efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 5659906d46d4SStefano Zampini /* matrix sizes */ 5660906d46d4SStefano Zampini PetscInt global_size,local_size; 5661906d46d4SStefano Zampini /* temporary change of basis */ 5662906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 5663cf5a6209SStefano Zampini /* extra space for debugging */ 5664cf5a6209SStefano Zampini PetscScalar *dbg_work; 5665984c4197SStefano Zampini 5666906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 5667906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 566816f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 5669bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 5670906d46d4SStefano Zampini /* nonzeros for local mat */ 5671bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 56721dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5673bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 56741dd7afcfSStefano Zampini } else { 56751dd7afcfSStefano Zampini const PetscInt *ii; 56761dd7afcfSStefano Zampini PetscInt n; 56771dd7afcfSStefano Zampini PetscBool flg_row; 56781dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 56791dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 56801dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 56811dd7afcfSStefano Zampini } 56829162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 5683a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 56849162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 5685a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 56869162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 5687a717540cSStefano Zampini } else { 56889162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 56899162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 5690a717540cSStefano Zampini } 5691a717540cSStefano Zampini } 5692a717540cSStefano Zampini } 5693906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 5694bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 56951dd7afcfSStefano Zampini /* Set interior change in the matrix */ 56961dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5697bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 5698906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 5699a717540cSStefano Zampini } 57001dd7afcfSStefano Zampini } else { 57011dd7afcfSStefano Zampini const PetscInt *ii,*jj; 57021dd7afcfSStefano Zampini PetscScalar *aa; 57031dd7afcfSStefano Zampini PetscInt n; 57041dd7afcfSStefano Zampini PetscBool flg_row; 57051dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 57061dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 57071dd7afcfSStefano Zampini for (i=0;i<n;i++) { 57081dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 57091dd7afcfSStefano Zampini } 57101dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 57111dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 57121dd7afcfSStefano Zampini } 5713a717540cSStefano Zampini 5714a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5715a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5716a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5717a717540cSStefano Zampini } 5718a717540cSStefano Zampini 5719a717540cSStefano Zampini 5720a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 5721a717540cSStefano Zampini /* 5722a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 5723a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 5724a717540cSStefano Zampini 5725a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 5726a717540cSStefano Zampini 5727a6b551f4SStefano Zampini - Using the following block transformation if there is only a primal dof on the cc (and -pc_bddc_use_qr_single is not specified) 5728a6b551f4SStefano Zampini 5729a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 5730a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 5731a717540cSStefano Zampini | ... | 5732a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 5733a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 5734a717540cSStefano Zampini 5735a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 5736a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 5737a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 5738a6b551f4SStefano Zampini 5739a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 5740a717540cSStefano Zampini */ 5741a717540cSStefano Zampini if (qr_needed) { 5742984c4197SStefano Zampini /* space to store Q */ 5743854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 57444e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 57454e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 5746984c4197SStefano Zampini /* first we issue queries for optimal work */ 57473f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 57483f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 57493f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5750984c4197SStefano Zampini lqr_work = -1; 57513f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 5752984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 5753984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 5754785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 5755984c4197SStefano Zampini lgqr_work = -1; 57563f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 57573f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 57583f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 57593f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 57603f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 57613f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 5762984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 5763984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 5764785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 5765984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 5766785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 5767a717540cSStefano Zampini /* allocating workspace for check */ 5768a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5769cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 5770a717540cSStefano Zampini } 5771a717540cSStefano Zampini } 5772984c4197SStefano Zampini /* array to store whether a node is primal or not */ 57734641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 5774473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 57750e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 5776*eee23b56SStefano Zampini if (i != total_primal_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D\n",total_primal_vertices,i); 577739e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 577839e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 577939e2fb2aSStefano Zampini } 578039e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 5781984c4197SStefano Zampini 5782a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 57839162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 57849162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 57854641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 5786984c4197SStefano Zampini /* get constraint info */ 57879162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 5788984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 5789984c4197SStefano Zampini 5790984c4197SStefano Zampini if (pcbddc->dbg_flag) { 57919162d606SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraints %d: %d need a change of basis (size %d)\n",total_counts,primal_dofs,size_of_constraint);CHKERRQ(ierr); 5792674ae819SStefano Zampini } 5793984c4197SStefano Zampini 5794fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 5795a717540cSStefano Zampini 5796a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 5797a717540cSStefano Zampini if (pcbddc->dbg_flag) { 57989162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5799a717540cSStefano Zampini } 5800984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 58019162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5802984c4197SStefano Zampini 5803984c4197SStefano Zampini /* compute QR decomposition of constraints */ 58043f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 58053f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 58063f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5807674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 58083f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 5809984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 5810674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5811984c4197SStefano Zampini 5812984c4197SStefano Zampini /* explictly compute R^-T */ 5813984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 5814984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 58153f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 58163f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 58173f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 58183f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 5819984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 58203f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 5821984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 5822984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5823984c4197SStefano Zampini 5824a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 58253f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 58263f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 58273f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 58283f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5829984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 58303f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 5831984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 5832984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5833984c4197SStefano Zampini 5834984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 5835984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 5836984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 58373f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 58383f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 58393f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 58403f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 58413f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 58423f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5843984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 58449162d606SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("N","N",&Blas_M,&Blas_N,&Blas_K,&one,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&zero,constraints_data+constraints_data_ptr[total_counts],&Blas_LDC)); 5845984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 58469162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 5847984c4197SStefano Zampini 5848984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 58499162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 5850984c4197SStefano Zampini /* insert cols for primal dofs */ 5851984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 5852984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 58539162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5854906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5855984c4197SStefano Zampini } 5856984c4197SStefano Zampini /* insert cols for dual dofs */ 5857984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 58589162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 5859984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 58609162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5861906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 5862984c4197SStefano Zampini j++; 5863674ae819SStefano Zampini } 5864674ae819SStefano Zampini } 5865984c4197SStefano Zampini 5866984c4197SStefano Zampini /* check change of basis */ 5867984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5868984c4197SStefano Zampini PetscInt ii,jj; 5869984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 5870c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 5871c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5872c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 5873c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5874c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 5875c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 5876984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5877cf5a6209SStefano Zampini PetscStackCallBLAS("BLASgemm",BLASgemm_("T","N",&Blas_M,&Blas_N,&Blas_K,&one,dbg_work,&Blas_LDA,qr_basis,&Blas_LDB,&zero,&dbg_work[size_of_constraint*primal_dofs],&Blas_LDC)); 5878984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5879984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5880984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5881cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 5882cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) valid_qr = PETSC_FALSE; 5883674ae819SStefano Zampini } 5884674ae819SStefano Zampini } 5885984c4197SStefano Zampini if (!valid_qr) { 588622d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 5887984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 5888984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 5889cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 5890cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not orthogonal to constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 5891674ae819SStefano Zampini } 5892cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 5893cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not unitary w.r.t constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 5894984c4197SStefano Zampini } 5895984c4197SStefano Zampini } 5896984c4197SStefano Zampini } 5897674ae819SStefano Zampini } else { 589822d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 5899674ae819SStefano Zampini } 5900674ae819SStefano Zampini } 5901a717540cSStefano Zampini } else { /* simple transformation block */ 5902a717540cSStefano Zampini PetscInt row,col; 5903a6b551f4SStefano Zampini PetscScalar val,norm; 5904a6b551f4SStefano Zampini 5905a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 59069162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,constraints_data+constraints_data_ptr[total_counts],&Blas_one,constraints_data+constraints_data_ptr[total_counts],&Blas_one)); 5907a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 59089162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 59099162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 5910bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 59119162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 5912906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 59139162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 5914a717540cSStefano Zampini } else { 5915a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 59169162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 5917a717540cSStefano Zampini if (row != col) { 59189162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 5919a717540cSStefano Zampini } else { 59209162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 5921a717540cSStefano Zampini } 5922906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 5923a717540cSStefano Zampini } 5924a717540cSStefano Zampini } 5925a717540cSStefano Zampini } 592698a51de6SStefano Zampini if (pcbddc->dbg_flag) { 592722d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 5928a717540cSStefano Zampini } 5929674ae819SStefano Zampini } 5930984c4197SStefano Zampini } else { 5931984c4197SStefano Zampini if (pcbddc->dbg_flag) { 59329162d606SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Constraint %d does not need a change of basis (size %d)\n",total_counts,size_of_constraint);CHKERRQ(ierr); 5933674ae819SStefano Zampini } 5934674ae819SStefano Zampini } 5935674ae819SStefano Zampini } 5936a717540cSStefano Zampini 5937a717540cSStefano Zampini /* free workspace */ 5938a717540cSStefano Zampini if (qr_needed) { 5939984c4197SStefano Zampini if (pcbddc->dbg_flag) { 5940cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 5941984c4197SStefano Zampini } 5942984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 5943984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 5944984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 5945984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 5946984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 5947674ae819SStefano Zampini } 5948a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 5949906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5950906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5951906d46d4SStefano Zampini 5952906d46d4SStefano Zampini /* assembling of global change of variable */ 595388c03ad3SStefano Zampini if (!pcbddc->fake_change) { 5954bbb9e6c6SStefano Zampini Mat tmat; 595516f15bc4SStefano Zampini PetscInt bs; 595616f15bc4SStefano Zampini 5957906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 5958906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 5959bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 5960bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 5961bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5962bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 596316f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 596416f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 5965906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 5966bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 5967bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 5968bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 5969bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 5970bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 5971e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5972e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5973bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 5974bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 597588c03ad3SStefano Zampini 5976906d46d4SStefano Zampini /* check */ 5977906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 5978906d46d4SStefano Zampini PetscReal error; 5979906d46d4SStefano Zampini Vec x,x_change; 5980906d46d4SStefano Zampini 5981906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 5982906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 5983906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 5984906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 5985e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5986e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5987bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 5988e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5989e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5990906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 5991906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 5992906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 5993906d46d4SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5994bbb9e6c6SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Error global vs local change: %1.6e\n",error);CHKERRQ(ierr); 5995906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 5996906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 5997906d46d4SStefano Zampini } 5998b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 5999b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 6000b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6001bf3a8328SStefano Zampini 60029a962809SStefano Zampini if (pcbddc->use_change_of_basis && pcbddc->adaptive_userdefined) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Cannot mix automatic change of basis, adaptive selection and user-defined constraints");CHKERRQ(ierr); 6003b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 6004ac632422SStefano Zampini Mat S_new,tmat; 6005bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 6006bbb9e6c6SStefano Zampini 6007bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 60086816873aSStefano Zampini ierr = MatGetSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 6009bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6010bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 6011bf3a8328SStefano Zampini IS is_V; 6012b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 6013b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 6014b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 6015b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 6016b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 6017bf3a8328SStefano Zampini } 6018bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 6019ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6020b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 6021ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6022bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6023bf3a8328SStefano Zampini const PetscScalar *array; 6024bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 6025bf3a8328SStefano Zampini PetscInt i,n_V; 6026bf3a8328SStefano Zampini 6027b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6028b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 6029b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6030b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6031b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 6032b087196eSStefano Zampini for (i=0;i<n_V;i++) { 6033b087196eSStefano Zampini PetscScalar val; 6034b087196eSStefano Zampini PetscInt idx; 6035b087196eSStefano Zampini 6036b087196eSStefano Zampini idx = idxs_V[i]; 6037b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 6038b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 6039b087196eSStefano Zampini } 6040b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6041b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6042bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 6043bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6044bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6045bf3a8328SStefano Zampini } 6046ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 6047ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6048ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 6049ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6050b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 6051ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6052bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6053b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6054bf3a8328SStefano Zampini } 6055ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 6056ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6057ac632422SStefano Zampini } 6058b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 605988c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6060b96c3477SStefano Zampini } 6061c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 6062b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 6063c9db6a07SStefano Zampini PetscInt i; 6064c9db6a07SStefano Zampini 6065c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 6066c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 6067c9db6a07SStefano Zampini } 6068c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 6069c9db6a07SStefano Zampini } 6070b96c3477SStefano Zampini } 607116909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 607216909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 607316909a7fSStefano Zampini } else { 6074906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 607516909a7fSStefano Zampini } 60761dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 607727b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 607872b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 607972b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 608072b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 608172b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 608272b8c272SStefano Zampini } 60831dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 608427b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 6085b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 6086b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 6087906d46d4SStefano Zampini } else { 60881dd7afcfSStefano Zampini Mat benign_global = NULL; 608927b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 60901dd7afcfSStefano Zampini Mat tmat; 60911dd7afcfSStefano Zampini 60921dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 60931dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 60941dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 60951dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 60961dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 60971dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 60981dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 60991dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 61001dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 61011dd7afcfSStefano Zampini if (pcbddc->benign_change) { 61021dd7afcfSStefano Zampini Mat M; 61031dd7afcfSStefano Zampini 61041dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 61051dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 61061dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 61071dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 6108906d46d4SStefano Zampini } else { 61091dd7afcfSStefano Zampini Mat eye; 61101dd7afcfSStefano Zampini PetscScalar *array; 61111dd7afcfSStefano Zampini 61121dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 61131dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 61141dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 61151dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 6116906d46d4SStefano Zampini } 61171dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 61181dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 61191dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 61201dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 61211dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 61221dd7afcfSStefano Zampini } 61231dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 61241dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 61251dd7afcfSStefano Zampini } 61261dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 61271dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 61281dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 612927b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 61301dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 61311dd7afcfSStefano Zampini } 61321dd7afcfSStefano Zampini } 613316909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 613416909a7fSStefano Zampini IS is_global; 613516909a7fSStefano Zampini const PetscInt *gidxs; 613616909a7fSStefano Zampini 613716909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 613816909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 613916909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 614016909a7fSStefano Zampini ierr = MatGetSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 614116909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 614216909a7fSStefano Zampini } 61431dd7afcfSStefano Zampini } 61441dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 61451dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 6146b9b85e73SStefano Zampini } 6147a717540cSStefano Zampini 614872b8c272SStefano Zampini if (!pcbddc->fake_change) { 61494f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 61504f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 61514f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 61524f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 6153019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 6154019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 6155019a44ceSStefano Zampini pcbddc->local_primal_size++; 6156019a44ceSStefano Zampini } 6157019a44ceSStefano Zampini 6158019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 6159727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 6160727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 61619f47a83aSStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_node,olocal_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 6162c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 61630e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 61649f47a83aSStefano Zampini ierr = PetscMemcmp(pcbddc->local_primal_ref_mult,olocal_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt),&pcbddc->new_primal_space_local);CHKERRQ(ierr); 6165727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 6166727cdba6SStefano Zampini } 61670e6343abSStefano Zampini } 6168727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 6169b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 617072b8c272SStefano Zampini } 617172b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 6172727cdba6SStefano Zampini 6173a717540cSStefano Zampini /* flush dbg viewer */ 6174b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 6175b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6176b8ffe317SStefano Zampini } 6177a717540cSStefano Zampini 6178e310c8b4SStefano Zampini /* free workspace */ 6179a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 61804641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 618108122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 61829162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 61839162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 618408122e43SStefano Zampini } else { 61859162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 61869162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 61879162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 618808122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 618908122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 61909162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 61919162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 619208122e43SStefano Zampini } 6193674ae819SStefano Zampini PetscFunctionReturn(0); 6194674ae819SStefano Zampini } 6195674ae819SStefano Zampini 6196674ae819SStefano Zampini #undef __FUNCT__ 6197674ae819SStefano Zampini #define __FUNCT__ "PCBDDCAnalyzeInterface" 6198674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 6199674ae819SStefano Zampini { 620071582508SStefano Zampini ISLocalToGlobalMapping map; 6201674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6202674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 620314f95afaSStefano Zampini PetscInt ierr,i,N; 6204674ae819SStefano Zampini 6205674ae819SStefano Zampini PetscFunctionBegin; 62068af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 6207b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 62088e61c736SStefano Zampini /* Reset previously computed graph */ 62098e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 6210674ae819SStefano Zampini /* Init local Graph struct */ 62117fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 621271582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 6213be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 6214674ae819SStefano Zampini 6215575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 62169a962809SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid size of local CSR graph! Found %d, expected %d\n",pcbddc->mat_graph->nvtxs_csr,pcbddc->mat_graph->nvtxs); 62179577ea80SStefano Zampini 6218674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 6219d4d8cf7bSStefano Zampini if ( (!pcbddc->mat_graph->xadj || !pcbddc->mat_graph->adjncy) && pcbddc->use_local_adj) { 62204d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 62214d379d7bSStefano Zampini PetscInt nvtxs; 6222e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 6223674ae819SStefano Zampini 62242fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 62252fffb893SStefano Zampini if (flg_row) { 62264d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 6227b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 62282fffb893SStefano Zampini } 62292fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 6230674ae819SStefano Zampini } 62319b28b941SStefano Zampini if (pcbddc->dbg_flag) { 62329b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6233674ae819SStefano Zampini } 6234674ae819SStefano Zampini 6235674ae819SStefano Zampini /* Setup of Graph */ 62364b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 623714f95afaSStefano Zampini ierr = PCBDDCGraphSetUp(pcbddc->mat_graph,pcbddc->vertex_size,pcbddc->NeumannBoundariesLocal,pcbddc->DirichletBoundariesLocal,pcbddc->n_ISForDofsLocal,pcbddc->ISForDofsLocal,pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 6238674ae819SStefano Zampini 62394f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 62404f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 62414f1b2e48SStefano Zampini PetscInt *local_subs; 62424f1b2e48SStefano Zampini 62434f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 62444f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 62454f1b2e48SStefano Zampini const PetscInt *idxs; 62464f1b2e48SStefano Zampini PetscInt nl,j; 62474f1b2e48SStefano Zampini 62484f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 62494f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 625071582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 62514f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 62524f1b2e48SStefano Zampini } 62534f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 62544f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 62554f1b2e48SStefano Zampini } 62568af8fcf9SStefano Zampini } 62574f1b2e48SStefano Zampini 6258cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 6259674ae819SStefano Zampini /* Graph's connected components analysis */ 6260674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 626171582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 62628af8fcf9SStefano Zampini } 6263674ae819SStefano Zampini PetscFunctionReturn(0); 6264674ae819SStefano Zampini } 6265674ae819SStefano Zampini 62669a7d3425SStefano Zampini #undef __FUNCT__ 62679a7d3425SStefano Zampini #define __FUNCT__ "PCBDDCOrthonormalizeVecs" 62689a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 62699a7d3425SStefano Zampini { 62709a7d3425SStefano Zampini PetscInt i,j; 62719a7d3425SStefano Zampini PetscScalar *alphas; 62729a7d3425SStefano Zampini PetscErrorCode ierr; 62739a7d3425SStefano Zampini 62749a7d3425SStefano Zampini PetscFunctionBegin; 6275785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 62769a7d3425SStefano Zampini for (i=0;i<n;i++) { 62779a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 6278669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 6279669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 6280669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 62819a7d3425SStefano Zampini } 62829a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 62839a7d3425SStefano Zampini PetscFunctionReturn(0); 62849a7d3425SStefano Zampini } 62859a7d3425SStefano Zampini 6286e7931f94SStefano Zampini #undef __FUNCT__ 628770cf5478SStefano Zampini #define __FUNCT__ "MatISGetSubassemblingPattern" 628857de7509SStefano Zampini PetscErrorCode MatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 6289e7931f94SStefano Zampini { 629057de7509SStefano Zampini Mat A; 6291e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 6292e7931f94SStefano Zampini PetscMPIInt size,rank,color; 629352e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 629452e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 629527b6a85dSStefano Zampini PetscInt im_active,active_procs,n,i,j,local_size,threshold = 2; 629657de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 629727b6a85dSStefano Zampini PetscInt xadj_count, *count; 629827b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 629927b6a85dSStefano Zampini PetscSubcomm psubcomm; 630027b6a85dSStefano Zampini MPI_Comm subcomm; 630152e5ac9dSStefano Zampini PetscErrorCode ierr; 6302a57a6d2fSStefano Zampini 6303e7931f94SStefano Zampini PetscFunctionBegin; 630457de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 630557de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 630657de7509SStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 630757de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 630857de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 630957de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 631057de7509SStefano Zampini 631157de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 631257de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 631357de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 631457de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 631557de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 631657de7509SStefano Zampini im_active = !!(n); 631757de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 631857de7509SStefano Zampini void_procs = size - active_procs; 631957de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 632057de7509SStefano Zampini if (void_procs) { 632157de7509SStefano Zampini PetscInt ncand; 632257de7509SStefano Zampini 632357de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 632457de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 632557de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 632657de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 632757de7509SStefano Zampini if (!procs_candidates[i]) { 632857de7509SStefano Zampini procs_candidates[ncand++] = i; 632957de7509SStefano Zampini } 633057de7509SStefano Zampini } 633157de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 633257de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 633357de7509SStefano Zampini } 633457de7509SStefano Zampini 633514f0bfb9SStefano Zampini /* number of subdomains requested greater than active processes -> just shift the matrix 633614f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 633714f0bfb9SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1) { 633814f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 633914f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 634014f0bfb9SStefano Zampini else dest = rank; 634157de7509SStefano Zampini if (im_active) { 634257de7509SStefano Zampini issize = 1; 634357de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 634414f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 634557de7509SStefano Zampini } else { 634614f0bfb9SStefano Zampini isidx = dest; 634757de7509SStefano Zampini } 634857de7509SStefano Zampini } else { 634957de7509SStefano Zampini issize = 0; 635057de7509SStefano Zampini isidx = -1; 635157de7509SStefano Zampini } 635257de7509SStefano Zampini *n_subdomains = active_procs; 635357de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 6354daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 635557de7509SStefano Zampini PetscFunctionReturn(0); 635657de7509SStefano Zampini } 6357c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 6358c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 635927b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 6360e7931f94SStefano Zampini 6361e7931f94SStefano Zampini /* Get info on mapping */ 63623bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&local_size);CHKERRQ(ierr); 63633bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6364e7931f94SStefano Zampini 6365e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 6366785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 6367e7931f94SStefano Zampini xadj[0] = 0; 6368e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 6369785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 6370785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 637127b6a85dSStefano Zampini ierr = PetscCalloc1(local_size,&count);CHKERRQ(ierr); 637227b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 637327b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 637427b6a85dSStefano Zampini count[shared[i][j]] += 1; 6375e7931f94SStefano Zampini 637627b6a85dSStefano Zampini xadj_count = 0; 63772b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 637827b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 637927b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 6380d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 6381d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 6382d023bfaeSStefano Zampini xadj_count++; 638327b6a85dSStefano Zampini break; 638427b6a85dSStefano Zampini } 6385e7931f94SStefano Zampini } 6386e7931f94SStefano Zampini } 6387d023bfaeSStefano Zampini xadj[1] = xadj_count; 638827b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 63893bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6390e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 6391e7931f94SStefano Zampini 63923837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 6393e7931f94SStefano Zampini 639427b6a85dSStefano Zampini /* Restrict work on active processes only */ 639527b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 639627b6a85dSStefano Zampini if (void_procs) { 639727b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 639827b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 639927b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 640027b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 640127b6a85dSStefano Zampini } else { 640227b6a85dSStefano Zampini psubcomm = NULL; 640327b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 640427b6a85dSStefano Zampini } 640527b6a85dSStefano Zampini 640627b6a85dSStefano Zampini v_wgt = NULL; 640727b6a85dSStefano Zampini if (!color) { 6408e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 6409e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 6410e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6411c8587f34SStefano Zampini } else { 641252e5ac9dSStefano Zampini Mat subdomain_adj; 641352e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 641452e5ac9dSStefano Zampini MatPartitioning partitioner; 641527b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 641652e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 641757de7509SStefano Zampini PetscMPIInt size; 6418b0c7d250SStefano Zampini PetscBool aggregate; 6419b0c7d250SStefano Zampini 642027b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 642127b6a85dSStefano Zampini if (void_procs) { 642227b6a85dSStefano Zampini PetscInt prank = rank; 6423785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 642427b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 6425e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 6426e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 6427c8587f34SStefano Zampini } 6428e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 642927b6a85dSStefano Zampini } else { 643027b6a85dSStefano Zampini oldranks = NULL; 643127b6a85dSStefano Zampini } 6432b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 643327b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 6434b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 6435b0c7d250SStefano Zampini PetscMPIInt nrank; 6436b0c7d250SStefano Zampini PetscScalar *vals; 6437b0c7d250SStefano Zampini 643827b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 6439b0c7d250SStefano Zampini lrows = 0; 6440b0c7d250SStefano Zampini if (nrank<redprocs) { 6441b0c7d250SStefano Zampini lrows = size/redprocs; 6442b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 6443b0c7d250SStefano Zampini } 644427b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 6445b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 6446b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6447b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6448b0c7d250SStefano Zampini row = nrank; 6449b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 6450b0c7d250SStefano Zampini cols = adjncy; 6451b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 6452b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 6453b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 6454b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6455b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 645652e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 645752e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 645852e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6459b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 646027b6a85dSStefano Zampini if (use_vwgt) { 646127b6a85dSStefano Zampini Vec v; 646227b6a85dSStefano Zampini const PetscScalar *array; 646327b6a85dSStefano Zampini PetscInt nl; 646427b6a85dSStefano Zampini 646527b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 646627b6a85dSStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)local_size,INSERT_VALUES);CHKERRQ(ierr); 646727b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 646827b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 646927b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 647027b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 647127b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 647222db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 647327b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 647427b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 647527b6a85dSStefano Zampini } 6476b0c7d250SStefano Zampini } else { 647727b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 647827b6a85dSStefano Zampini if (use_vwgt) { 647927b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 648027b6a85dSStefano Zampini v_wgt[0] = local_size; 648127b6a85dSStefano Zampini } 6482b0c7d250SStefano Zampini } 648322b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 6484e7931f94SStefano Zampini 6485e7931f94SStefano Zampini /* Partition */ 648627b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 6487e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 648827b6a85dSStefano Zampini if (v_wgt) { 6489e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 6490c8587f34SStefano Zampini } 649157de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 649257de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 6493e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 6494e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 649522b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 6496e7931f94SStefano Zampini 649752e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 64986583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 649952e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 650052e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 650157de7509SStefano Zampini if (!aggregate) { 650257de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 650327b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 650427b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 650527b6a85dSStefano Zampini #endif 650657de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 650727b6a85dSStefano Zampini } else if (oldranks) { 6508b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 650927b6a85dSStefano Zampini } else { 651027b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 651157de7509SStefano Zampini } 651228143c3dSStefano Zampini } else { 6513b0c7d250SStefano Zampini PetscInt idxs[1]; 6514b0c7d250SStefano Zampini PetscMPIInt tag; 6515b0c7d250SStefano Zampini MPI_Request *reqs; 6516b0c7d250SStefano Zampini 6517b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 6518b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 6519b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 652027b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 652128143c3dSStefano Zampini } 652227b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 6523b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6524b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 652557de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 652627b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 652727b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 652827b6a85dSStefano Zampini #endif 652957de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 653027b6a85dSStefano Zampini } else if (oldranks) { 6531b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 653227b6a85dSStefano Zampini } else { 653327b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 6534e7931f94SStefano Zampini } 653557de7509SStefano Zampini } 653652e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6537e7931f94SStefano Zampini /* clean up */ 6538e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 653952e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 6540e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 6541e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 6542e7931f94SStefano Zampini } 654327b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 654457de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 6545e7931f94SStefano Zampini 6546e7931f94SStefano Zampini /* assemble parallel IS for sends */ 6547e7931f94SStefano Zampini i = 1; 654827b6a85dSStefano Zampini if (!color) i=0; 654957de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 6550e7931f94SStefano Zampini PetscFunctionReturn(0); 6551e7931f94SStefano Zampini } 6552e7931f94SStefano Zampini 6553e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 6554e7931f94SStefano Zampini 6555e7931f94SStefano Zampini #undef __FUNCT__ 65561e0482f5SStefano Zampini #define __FUNCT__ "PCBDDCMatISSubassemble" 65571e0482f5SStefano Zampini PetscErrorCode PCBDDCMatISSubassemble(Mat mat, IS is_sends, PetscInt n_subdomains, PetscBool restrict_comm, PetscBool restrict_full, PetscBool reuse, Mat *mat_n, PetscInt nis, IS isarray[], PetscInt nvecs, Vec nnsp_vec[]) 6558e7931f94SStefano Zampini { 655970cf5478SStefano Zampini Mat local_mat; 6560e7931f94SStefano Zampini IS is_sends_internal; 65619d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 65621ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 65639d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 6564e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 6565e7931f94SStefano Zampini PetscInt* l2gmap_indices; 6566e7931f94SStefano Zampini const PetscInt* is_indices; 6567e7931f94SStefano Zampini MatType new_local_type; 6568e7931f94SStefano Zampini /* buffers */ 6569e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 657028143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 65719d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 6572e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 65731ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 6574e7931f94SStefano Zampini /* MPI */ 657528143c3dSStefano Zampini MPI_Comm comm,comm_n; 657628143c3dSStefano Zampini PetscSubcomm subcomm; 6577e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 657828143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 657928143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 65801ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 65811ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 65821ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 6583e7931f94SStefano Zampini PetscErrorCode ierr; 6584e7931f94SStefano Zampini 6585e7931f94SStefano Zampini PetscFunctionBegin; 658657de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6587e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 658828143c3dSStefano Zampini if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",__FUNCT__); 658957de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 659057de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 659157de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 659257de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 659357de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 65941ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 65951ae86dd6SStefano Zampini if (nvecs) { 65961ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 65971ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 65981ae86dd6SStefano Zampini } 659957de7509SStefano Zampini /* further checks */ 6600e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6601e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 6602e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 6603e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 6604e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 660557de7509SStefano Zampini if (reuse && *mat_n) { 660670cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 660757de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 660870cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 660928143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 661070cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 661170cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 661270cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 661370cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 661470cf5478SStefano Zampini } 6615e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 6616e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 661757de7509SStefano Zampini 6618e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 6619e7931f94SStefano Zampini if (!is_sends) { 662028143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 662157de7509SStefano Zampini ierr = MatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 6622c8587f34SStefano Zampini } else { 6623e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 6624e7931f94SStefano Zampini is_sends_internal = is_sends; 6625c8587f34SStefano Zampini } 6626e7931f94SStefano Zampini 6627e7931f94SStefano Zampini /* get comm */ 6628a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 6629e7931f94SStefano Zampini 6630e7931f94SStefano Zampini /* compute number of sends */ 6631e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 6632e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 6633e7931f94SStefano Zampini 6634e7931f94SStefano Zampini /* compute number of receives */ 6635e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 6636785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 6637e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 6638e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6639e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 6640e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 6641e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 6642e7931f94SStefano Zampini 664328143c3dSStefano Zampini /* restrict comm if requested */ 664428143c3dSStefano Zampini subcomm = 0; 664528143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 664628143c3dSStefano Zampini if (restrict_comm) { 6647779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 6648779c1cceSStefano Zampini 664928143c3dSStefano Zampini color = 0; 665053a05cb3SStefano Zampini if (restrict_full) { 665153a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 665253a05cb3SStefano Zampini } else { 665353a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 665453a05cb3SStefano Zampini } 6655b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 665628143c3dSStefano Zampini subcommsize = commsize - subcommsize; 665728143c3dSStefano Zampini /* check if reuse has been requested */ 665857de7509SStefano Zampini if (reuse) { 665928143c3dSStefano Zampini if (*mat_n) { 666028143c3dSStefano Zampini PetscMPIInt subcommsize2; 666128143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 666228143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 666328143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 666428143c3dSStefano Zampini } else { 666528143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 666628143c3dSStefano Zampini } 666728143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 6668779c1cceSStefano Zampini PetscMPIInt rank; 6669779c1cceSStefano Zampini 6670779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 667128143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 667228143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 667328143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 6674306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 667528143c3dSStefano Zampini } 667628143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 667728143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 667828143c3dSStefano Zampini } else { 667928143c3dSStefano Zampini comm_n = comm; 668028143c3dSStefano Zampini } 668128143c3dSStefano Zampini 6682e7931f94SStefano Zampini /* prepare send/receive buffers */ 6683785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 6684e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 6685785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 6686e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 668728143c3dSStefano Zampini if (nis) { 6688854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 668928143c3dSStefano Zampini } 6690e7931f94SStefano Zampini 669128143c3dSStefano Zampini /* Get data from local matrices */ 66926c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 6693e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 6694e7931f94SStefano Zampini /* 6695e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 6696e7931f94SStefano Zampini send_buffer_idxs should contain: 6697e7931f94SStefano Zampini - MatType_PRIVATE type 6698e7931f94SStefano Zampini - PetscInt size_of_l2gmap 6699e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 6700e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 6701e7931f94SStefano Zampini */ 67026c4ed002SBarry Smith else { 6703e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 67043bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 6705854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 6706e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 6707e7931f94SStefano Zampini send_buffer_idxs[1] = i; 67083bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6709e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 67103bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6711e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 6712e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6713e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 6714e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 6715c8587f34SStefano Zampini } 6716c8587f34SStefano Zampini } 6717e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 671828143c3dSStefano Zampini /* additional is (if any) */ 671928143c3dSStefano Zampini if (nis) { 672028143c3dSStefano Zampini PetscMPIInt psum; 672128143c3dSStefano Zampini PetscInt j; 672228143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 672328143c3dSStefano Zampini PetscInt plen; 672428143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 672528143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 672628143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 672728143c3dSStefano Zampini } 6728854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 672928143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 673028143c3dSStefano Zampini PetscInt plen; 673128143c3dSStefano Zampini const PetscInt *is_array_idxs; 673228143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 673328143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 673428143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 673528143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 673628143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 673728143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 673828143c3dSStefano Zampini } 673928143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 674028143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 674128143c3dSStefano Zampini } 674228143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 674328143c3dSStefano Zampini } 674428143c3dSStefano Zampini 6745e7931f94SStefano Zampini buf_size_idxs = 0; 6746e7931f94SStefano Zampini buf_size_vals = 0; 674728143c3dSStefano Zampini buf_size_idxs_is = 0; 67481ae86dd6SStefano Zampini buf_size_vecs = 0; 6749e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6750e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 6751e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 675228143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 67531ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 6754e7931f94SStefano Zampini } 6755785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 6756785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 675795ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 67581ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 6759e7931f94SStefano Zampini 6760e7931f94SStefano Zampini /* get new tags for clean communications */ 6761e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 6762e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 676328143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 67641ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 6765e7931f94SStefano Zampini 6766e7931f94SStefano Zampini /* allocate for requests */ 6767785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 6768785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 676995ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 67701ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 6771785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 6772785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 677395ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 67741ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 6775e7931f94SStefano Zampini 6776e7931f94SStefano Zampini /* communications */ 6777e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6778e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 677928143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 67801ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 6781e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6782e7931f94SStefano Zampini source_dest = onodes[i]; 6783e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 6784e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 6785e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6786e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 678728143c3dSStefano Zampini if (nis) { 678857de7509SStefano Zampini source_dest = onodes_is[i]; 678928143c3dSStefano Zampini ierr = MPI_Irecv(ptr_idxs_is,olengths_idxs_is[i],MPIU_INT,source_dest,tag_idxs_is,comm,&recv_req_idxs_is[i]);CHKERRQ(ierr); 679028143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 679128143c3dSStefano Zampini } 67921ae86dd6SStefano Zampini if (nvecs) { 67931ae86dd6SStefano Zampini source_dest = onodes[i]; 67941ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 67951ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 67961ae86dd6SStefano Zampini } 6797e7931f94SStefano Zampini } 6798e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6799e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 6800e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 6801e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 680228143c3dSStefano Zampini if (nis) { 680328143c3dSStefano Zampini ierr = MPI_Isend(send_buffer_idxs_is,ilengths_idxs_is[source_dest],MPIU_INT,source_dest,tag_idxs_is,comm,&send_req_idxs_is[i]);CHKERRQ(ierr); 680428143c3dSStefano Zampini } 68051ae86dd6SStefano Zampini if (nvecs) { 68061ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 68071ae86dd6SStefano Zampini ierr = MPI_Isend(send_buffer_vecs,ilengths_idxs[source_dest]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&send_req_vecs[i]);CHKERRQ(ierr); 68081ae86dd6SStefano Zampini } 6809e7931f94SStefano Zampini } 6810e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6811e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 6812e7931f94SStefano Zampini 6813e7931f94SStefano Zampini /* assemble new l2g map */ 6814e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6815e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 68169d30be91SStefano Zampini new_local_rows = 0; 6817e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 68189d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6819e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6820e7931f94SStefano Zampini } 68219d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 6822e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 68239d30be91SStefano Zampini new_local_rows = 0; 6824e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 68259d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 68269d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 6827e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6828e7931f94SStefano Zampini } 68299d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 68309d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 6831e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 6832e7931f94SStefano Zampini 6833e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 6834e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 6835e7931f94SStefano Zampini /* it also assumes that if the block size is set, than it is the same among all local matrices (see checks at the beginning of the function) */ 6836e7931f94SStefano Zampini if (n_recvs) { 683728143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 6838e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6839e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6840e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 6841e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 6842e7931f94SStefano Zampini break; 6843e7931f94SStefano Zampini } 6844e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6845e7931f94SStefano Zampini } 6846e7931f94SStefano Zampini switch (new_local_type_private) { 684728143c3dSStefano Zampini case MATDENSE_PRIVATE: 684828143c3dSStefano Zampini if (n_recvs>1) { /* subassembling of dense matrices does not give a dense matrix! */ 6849e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6850e7931f94SStefano Zampini bs = 1; 685128143c3dSStefano Zampini } else { /* if I receive only 1 dense matrix */ 685228143c3dSStefano Zampini new_local_type = MATSEQDENSE; 685328143c3dSStefano Zampini bs = 1; 685428143c3dSStefano Zampini } 6855e7931f94SStefano Zampini break; 6856e7931f94SStefano Zampini case MATAIJ_PRIVATE: 6857e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 6858e7931f94SStefano Zampini bs = 1; 6859e7931f94SStefano Zampini break; 6860e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 6861e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 6862e7931f94SStefano Zampini break; 6863e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 6864e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 6865e7931f94SStefano Zampini break; 6866e7931f94SStefano Zampini default: 68679d30be91SStefano Zampini SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,__FUNCT__); 6868e7931f94SStefano Zampini break; 6869e7931f94SStefano Zampini } 687028143c3dSStefano Zampini } else { /* by default, new_local_type is seqdense */ 687128143c3dSStefano Zampini new_local_type = MATSEQDENSE; 687228143c3dSStefano Zampini bs = 1; 6873e7931f94SStefano Zampini } 6874e7931f94SStefano Zampini 687570cf5478SStefano Zampini /* create MATIS object if needed */ 687657de7509SStefano Zampini if (!reuse) { 6877e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 6878e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 687970cf5478SStefano Zampini } else { 688070cf5478SStefano Zampini /* it also destroys the local matrices */ 688157de7509SStefano Zampini if (*mat_n) { 688270cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 688357de7509SStefano Zampini } else { /* this is a fake object */ 688457de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 688557de7509SStefano Zampini } 688670cf5478SStefano Zampini } 688770cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 6888e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 68899d30be91SStefano Zampini 68909d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 68919d30be91SStefano Zampini 68929d30be91SStefano Zampini /* Global to local map of received indices */ 68939d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 68949d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 68959d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 68969d30be91SStefano Zampini 68979d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 68989d30be91SStefano Zampini buf_size_idxs = 0; 68999d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 69009d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 69019d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 69029d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 69039d30be91SStefano Zampini } 69049d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 69059d30be91SStefano Zampini 69069d30be91SStefano Zampini /* set preallocation */ 69079d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 69089d30be91SStefano Zampini if (!newisdense) { 69099d30be91SStefano Zampini PetscInt *new_local_nnz=0; 69109d30be91SStefano Zampini 69119d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 69129d30be91SStefano Zampini if (n_recvs) { 69139d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 69149d30be91SStefano Zampini } 69159d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 69169d30be91SStefano Zampini PetscInt j; 69179d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 69189d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 69199d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 69209d30be91SStefano Zampini } 69219d30be91SStefano Zampini } else { 69229d30be91SStefano Zampini /* TODO */ 69239d30be91SStefano Zampini } 69249d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 69259d30be91SStefano Zampini } 69269d30be91SStefano Zampini if (new_local_nnz) { 69279d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 69289d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 69299d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 69309d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 69319d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 69329d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 69339d30be91SStefano Zampini } else { 69349d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 69359d30be91SStefano Zampini } 69369d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 69379d30be91SStefano Zampini } else { 69389d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 69399d30be91SStefano Zampini } 6940e7931f94SStefano Zampini 6941e7931f94SStefano Zampini /* set values */ 6942e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 69439d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 6944e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6945e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 6946e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 69479d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 6948e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6949e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 6950e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 695128143c3dSStefano Zampini } else { 695228143c3dSStefano Zampini /* TODO */ 6953e7931f94SStefano Zampini } 6954e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6955e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 6956e7931f94SStefano Zampini } 6957e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6958e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 695970cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 696070cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 69619d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 6962e7931f94SStefano Zampini 6963dfd14d43SStefano Zampini #if 0 696428143c3dSStefano Zampini if (!restrict_comm) { /* check */ 6965e7931f94SStefano Zampini Vec lvec,rvec; 6966e7931f94SStefano Zampini PetscReal infty_error; 6967e7931f94SStefano Zampini 69682a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 6969e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 6970e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 6971e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 697270cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 6973e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 6974e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 6975e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 6976e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 6977e7931f94SStefano Zampini } 697828143c3dSStefano Zampini #endif 6979e7931f94SStefano Zampini 698028143c3dSStefano Zampini /* assemble new additional is (if any) */ 698128143c3dSStefano Zampini if (nis) { 698228143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 698328143c3dSStefano Zampini 698428143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6985854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 698628143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 698728143c3dSStefano Zampini psum = 0; 698828143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 698928143c3dSStefano Zampini for (j=0;j<nis;j++) { 699028143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 699128143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 699228143c3dSStefano Zampini psum += plen; 699328143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 699428143c3dSStefano Zampini } 699528143c3dSStefano Zampini } 6996854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 6997854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 699828143c3dSStefano Zampini for (i=1;i<nis;i++) { 699928143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 700028143c3dSStefano Zampini } 700128143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 700228143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 700328143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 700428143c3dSStefano Zampini for (j=0;j<nis;j++) { 700528143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 700628143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 700728143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 700828143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 700928143c3dSStefano Zampini } 701028143c3dSStefano Zampini } 701128143c3dSStefano Zampini for (i=0;i<nis;i++) { 701228143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 701328143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 701428143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 701528143c3dSStefano Zampini } 701628143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 701728143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 701828143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 701928143c3dSStefano Zampini } 7020e7931f94SStefano Zampini /* free workspace */ 702128143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 7022e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7023e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 7024e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7025e7931f94SStefano Zampini if (isdense) { 7026e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7027e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 7028e7931f94SStefano Zampini } else { 7029e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 7030e7931f94SStefano Zampini } 703128143c3dSStefano Zampini if (nis) { 703228143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 703328143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 703428143c3dSStefano Zampini } 70351ae86dd6SStefano Zampini 70361ae86dd6SStefano Zampini if (nvecs) { 70371ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 70381ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 70391ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 70401ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 70411ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 70421ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 70431ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 70441ae86dd6SStefano Zampini /* set values */ 70451ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 70461ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 70471ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 70481ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 70491ae86dd6SStefano Zampini PetscInt j; 70501ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 70511ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 70521ae86dd6SStefano Zampini } 70531ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 70541ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 70551ae86dd6SStefano Zampini } 70561ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 70571ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 70581ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 70591ae86dd6SStefano Zampini } 70601ae86dd6SStefano Zampini 70611ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 70621ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 7063e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 7064e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 70651ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 706628143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 7067e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 7068e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 70691ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 707028143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 7071e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 7072e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 7073e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 7074e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 7075e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 707628143c3dSStefano Zampini if (nis) { 707728143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 707828143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 707928143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 708028143c3dSStefano Zampini } 708128143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 708228143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 708328143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 708428143c3dSStefano Zampini for (i=0;i<nis;i++) { 708528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 708628143c3dSStefano Zampini } 70871ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 70881ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 70891ae86dd6SStefano Zampini } 709053a05cb3SStefano Zampini *mat_n = NULL; 709128143c3dSStefano Zampini } 7092e7931f94SStefano Zampini PetscFunctionReturn(0); 7093e7931f94SStefano Zampini } 7094a57a6d2fSStefano Zampini 709512edc857SStefano Zampini /* temporary hack into ksp private data structure */ 7096af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 709712edc857SStefano Zampini 7098c8587f34SStefano Zampini #undef __FUNCT__ 7099c8587f34SStefano Zampini #define __FUNCT__ "PCBDDCSetUpCoarseSolver" 7100c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 7101c8587f34SStefano Zampini { 7102c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7103c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 710420a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 71051ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 71061e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 71079881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 710820a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 71096e683305SStefano Zampini IS coarse_is,*isarray; 71106e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 711130368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 7112f9eb5b7dSStefano Zampini PC pc_temp; 7113c8587f34SStefano Zampini PCType coarse_pc_type; 7114c8587f34SStefano Zampini KSPType coarse_ksp_type; 7115f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 71164f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 71171e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 711868457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 711922bc73bbSStefano Zampini PetscScalar *array; 712057de7509SStefano Zampini MatReuse coarse_mat_reuse; 712157de7509SStefano Zampini PetscBool restr, full_restr, have_void; 71229881197aSStefano Zampini PetscErrorCode ierr; 7123fdc09c96SStefano Zampini 7124c8587f34SStefano Zampini PetscFunctionBegin; 7125c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 712668457ee5SStefano Zampini if (pcbddc->new_primal_space || pcbddc->coarse_size == -1) { /* a new primal space is present or it is the first initialization, so recompute global numbering */ 7127fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 71285a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 7129fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 7130f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 7131f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 7132f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 7133fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 713451bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 713551bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 7136dc4bcba2SStefano Zampini PC pc; 7137dc4bcba2SStefano Zampini PetscBool isbddc; 7138dc4bcba2SStefano Zampini 7139dc4bcba2SStefano Zampini /* temporary workaround since PCBDDC does not have a reset method so far */ 7140dc4bcba2SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc);CHKERRQ(ierr); 7141dc4bcba2SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc,PCBDDC,&isbddc);CHKERRQ(ierr); 7142dc4bcba2SStefano Zampini if (isbddc) { 714363c961adSStefano Zampini ierr = KSPDestroy(&pcbddc->coarse_ksp);CHKERRQ(ierr); 714463c961adSStefano Zampini } else { 7145727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 714663c961adSStefano Zampini } 7147fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7148fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 7149fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7150f4ddd8eeSStefano Zampini } 7151fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 7152fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7153f4ddd8eeSStefano Zampini } 715470cf5478SStefano Zampini /* reset any subassembling information */ 715557de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 715670cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 715757de7509SStefano Zampini } 71586e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 7159fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7160f4ddd8eeSStefano Zampini } 716157de7509SStefano Zampini /* assemble coarse matrix */ 716257de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 716357de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 716457de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 716557de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 716618a45a71SStefano Zampini } else { 716757de7509SStefano Zampini coarse_mat = NULL; 716857de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 71696e683305SStefano Zampini } 7170e7931f94SStefano Zampini 7171abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 7172abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 7173abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 7174abbbba34SStefano Zampini 7175abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 717622bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 717722bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 717822bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 717922bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 7180e176bc59SStefano Zampini ierr = MatCreateIS(PetscObjectComm((PetscObject)pc),1,PETSC_DECIDE,PETSC_DECIDE,pcbddc->coarse_size,pcbddc->coarse_size,coarse_islg,NULL,&t_coarse_mat_is);CHKERRQ(ierr); 71816e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 71826e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 71836e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7184abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 7185abbbba34SStefano Zampini 718657de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 718757de7509SStefano Zampini im_active = !!(pcis->n); 718857de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 718957de7509SStefano Zampini 719014f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 719157de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 719257de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 719357de7509SStefano Zampini coarse_mat_is = NULL; 719457de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 719557de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 71961ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 719757de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 719857de7509SStefano Zampini if (multilevel_requested) { 719957de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 720057de7509SStefano Zampini restr = PETSC_FALSE; 720157de7509SStefano Zampini full_restr = PETSC_FALSE; 720257de7509SStefano Zampini } else { 720357de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 720457de7509SStefano Zampini restr = PETSC_TRUE; 720557de7509SStefano Zampini full_restr = PETSC_TRUE; 720657de7509SStefano Zampini } 72074b2aedd3SStefano Zampini if (!pcbddc->coarse_size) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 720857de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 720957de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 7210a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 721137eada30SStefano Zampini ierr = MatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7212a198735bSStefano Zampini } else { 7213a198735bSStefano Zampini PetscMPIInt size,rank; 7214a198735bSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 7215a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 7216a198735bSStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 7217a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 7218a198735bSStefano Zampini } 721957de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 722057de7509SStefano Zampini PetscInt psum; 722157de7509SStefano Zampini PetscMPIInt size; 722257de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 722357de7509SStefano Zampini else psum = 0; 722457de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 722557de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 722657de7509SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 722757de7509SStefano Zampini } 722857de7509SStefano Zampini /* determine if we can go multilevel */ 722957de7509SStefano Zampini if (multilevel_requested) { 723057de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 723157de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 723257de7509SStefano Zampini } 723357de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 723457de7509SStefano Zampini 7235e4d548c7SStefano Zampini /* dump subassembling pattern */ 7236e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 7237e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 7238e4d548c7SStefano Zampini } 7239e4d548c7SStefano Zampini 72406e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 72411e0482f5SStefano Zampini nedcfield = -1; 72421e0482f5SStefano Zampini if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal)) { /* protects from unneded computations */ 72436e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 72446e683305SStefano Zampini const PetscInt *idxs; 72456e683305SStefano Zampini ISLocalToGlobalMapping tmap; 72466e683305SStefano Zampini 72476e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 72480be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 72496e683305SStefano Zampini /* allocate space for temporary storage */ 7250854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 7251854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 72526e683305SStefano Zampini /* allocate for IS array */ 72536e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 72541e0482f5SStefano Zampini if (pcbddc->nedclocal) { 72551e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 72561e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 72571e0482f5SStefano Zampini } else { 72581e0482f5SStefano Zampini nedcfield = 0; 72591e0482f5SStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%d)",nisdofs); 72601e0482f5SStefano Zampini nisdofs = 1; 72611e0482f5SStefano Zampini } 72621e0482f5SStefano Zampini } 72636e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 726427b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 726530368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 7266854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 72676e683305SStefano Zampini /* dofs splitting */ 72686e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 72696e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 72701e0482f5SStefano Zampini if (nedcfield != i) { 72716e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 72726e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 72736e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 72746e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 72751e0482f5SStefano Zampini } else { 72761e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 72771e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 72781e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 7279*eee23b56SStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping coarse nedelec field! %d != %d\n",tsize,nout); 72801e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 72811e0482f5SStefano Zampini } 72826e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 728330368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 72846e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 72856e683305SStefano Zampini } 72866e683305SStefano Zampini /* neumann boundaries */ 72876e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 72886e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 72896e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 72906e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 72916e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 72926e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 72936e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 729430368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 72956e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 72966e683305SStefano Zampini } 72976e683305SStefano Zampini /* free memory */ 72986e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 72996e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 73006e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 73016e683305SStefano Zampini } else { 73026e683305SStefano Zampini nis = 0; 73036e683305SStefano Zampini nisdofs = 0; 73046e683305SStefano Zampini nisneu = 0; 730530368db7SStefano Zampini nisvert = 0; 73066e683305SStefano Zampini isarray = NULL; 73076e683305SStefano Zampini } 73086e683305SStefano Zampini /* destroy no longer needed map */ 73096e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 73106e683305SStefano Zampini 731157de7509SStefano Zampini /* subassemble */ 731257de7509SStefano Zampini if (multilevel_allowed) { 73131ae86dd6SStefano Zampini Vec vp[1]; 73141ae86dd6SStefano Zampini PetscInt nvecs = 0; 731557de7509SStefano Zampini PetscBool reuse,reuser; 73161ae86dd6SStefano Zampini 731757de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 731857de7509SStefano Zampini else reuse = PETSC_FALSE; 731957de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 73201ae86dd6SStefano Zampini vp[0] = NULL; 73211ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 73221ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 73231ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 73241ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 73251ae86dd6SStefano Zampini nvecs = 1; 73261ae86dd6SStefano Zampini 73271ae86dd6SStefano Zampini if (pcbddc->divudotp) { 7328a198735bSStefano Zampini Mat B,loc_divudotp; 73291ae86dd6SStefano Zampini Vec v,p; 73301ae86dd6SStefano Zampini IS dummy; 73311ae86dd6SStefano Zampini PetscInt np; 73321ae86dd6SStefano Zampini 7333a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 7334a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 73351ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 7336a198735bSStefano Zampini ierr = MatGetSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 73371ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 73381ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 73391ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 73401ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 73411ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 73421ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 73431ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 73441ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 73451ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 73461ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 73471ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 73481ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 734974e2c79eSStefano Zampini } 73501ae86dd6SStefano Zampini } 73511ae86dd6SStefano Zampini if (reuser) { 73521e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 735374e2c79eSStefano Zampini } else { 73541e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,nis,isarray,nvecs,vp);CHKERRQ(ierr); 73551ae86dd6SStefano Zampini } 73561ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 73571ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 73581ae86dd6SStefano Zampini PetscInt nl; 73591ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 73601ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 73611ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 73621ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 73631ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 73641ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 73651ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 73661ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 7367a198735bSStefano Zampini } else { 7368a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 73691ae86dd6SStefano Zampini } 73701ae86dd6SStefano Zampini } else { 73711e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_FALSE,&coarse_mat_is,0,NULL,0,NULL);CHKERRQ(ierr); 73726e683305SStefano Zampini } 737357de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 737457de7509SStefano Zampini PetscMPIInt size; 7375f913dca9SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size);CHKERRQ(ierr); 737657de7509SStefano Zampini if (!multilevel_allowed) { 737757de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 73786e683305SStefano Zampini } else { 737957de7509SStefano Zampini Mat A; 7380779c1cceSStefano Zampini 738157de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 738257de7509SStefano Zampini if (coarse_mat_is) { 738357de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 738457de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 738557de7509SStefano Zampini coarse_mat = coarse_mat_is; 738657de7509SStefano Zampini } 738757de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 738857de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 738957de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 7390779c1cceSStefano Zampini } 7391779c1cceSStefano Zampini } 739257de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 739357de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 73946e683305SStefano Zampini 73956e683305SStefano Zampini /* create local to global scatters for coarse problem */ 739668457ee5SStefano Zampini if (compute_vecs) { 73976e683305SStefano Zampini PetscInt lrows; 73986e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 739957de7509SStefano Zampini if (coarse_mat) { 740057de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 74016e683305SStefano Zampini } else { 74026e683305SStefano Zampini lrows = 0; 74036e683305SStefano Zampini } 74046e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 74056e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 74066e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 74076e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 74086e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 74096e683305SStefano Zampini } 74106e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 7411c8587f34SStefano Zampini 7412f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 7413f9eb5b7dSStefano Zampini if (multilevel_allowed) { 7414f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 7415f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 7416f9eb5b7dSStefano Zampini } else { 7417f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 7418f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 7419c8587f34SStefano Zampini } 7420c8587f34SStefano Zampini 74216e683305SStefano Zampini /* print some info if requested */ 74226e683305SStefano Zampini if (pcbddc->dbg_flag) { 74236e683305SStefano Zampini if (!multilevel_allowed) { 74246e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 74256e683305SStefano Zampini if (multilevel_requested) { 74266e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Not enough active processes on level %d (active processes %d, coarsening ratio %d)\n",pcbddc->current_level,active_procs,pcbddc->coarsening_ratio);CHKERRQ(ierr); 74276e683305SStefano Zampini } else if (pcbddc->max_levels) { 74286e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 74296e683305SStefano Zampini } 74306e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 74316e683305SStefano Zampini } 74326e683305SStefano Zampini } 74336e683305SStefano Zampini 74341e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 74351e0482f5SStefano Zampini coarseG = NULL; 74361e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 74371e0482f5SStefano Zampini MPI_Comm ccomm; 74381e0482f5SStefano Zampini if (coarse_mat) { 74391e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 74401e0482f5SStefano Zampini } else { 74411e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 74421e0482f5SStefano Zampini } 74431e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 74441e0482f5SStefano Zampini } 74451e0482f5SStefano Zampini 7446f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 744757de7509SStefano Zampini if (coarse_mat) { 74486a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 74496e683305SStefano Zampini if (pcbddc->dbg_flag) { 745057de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 74516e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 74526e683305SStefano Zampini } 7453f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 7454312be037SStefano Zampini char prefix[256],str_level[16]; 7455e604994aSStefano Zampini size_t len; 74561e0482f5SStefano Zampini 745757de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 7458422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 7459c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 7460f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 746157de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7462c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 74636e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 7464c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 74651e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 7466c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7467e604994aSStefano Zampini /* prefix */ 7468e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 7469e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 7470e604994aSStefano Zampini if (!pcbddc->current_level) { 7471e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 7472e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 7473c8587f34SStefano Zampini } else { 7474e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 7475312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 7476312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 747734d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 7478312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 7479e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 7480e604994aSStefano Zampini } 7481e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 74823e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 74833e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 74843e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 74853e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 7486f9eb5b7dSStefano Zampini /* allow user customization */ 7487f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 74883e3c6dadSStefano Zampini } 74893e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 749051bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 74913e3c6dadSStefano Zampini if (nisdofs) { 74923e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 74933e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 74943e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 74953e3c6dadSStefano Zampini } 74963e3c6dadSStefano Zampini } 74973e3c6dadSStefano Zampini if (nisneu) { 74983e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 74993e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 7500312be037SStefano Zampini } 750130368db7SStefano Zampini if (nisvert) { 750230368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 750330368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 750430368db7SStefano Zampini } 75051e0482f5SStefano Zampini if (coarseG) { 75061e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 75071e0482f5SStefano Zampini } 7508f9eb5b7dSStefano Zampini 7509f9eb5b7dSStefano Zampini /* get some info after set from options */ 7510f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 7511f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 75124f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 75136e683305SStefano Zampini if (isbddc && !multilevel_allowed) { /* multilevel can only be requested via pc_bddc_set_levels */ 7514f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7515f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 7516f9eb5b7dSStefano Zampini } 751739f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 75184f3a063dSStefano Zampini if (isredundant) { 75194f3a063dSStefano Zampini KSP inner_ksp; 75204f3a063dSStefano Zampini PC inner_pc; 75214f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 75224f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 75234f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 75244f3a063dSStefano Zampini } 7525f9eb5b7dSStefano Zampini 752657de7509SStefano Zampini /* parameters which miss an API */ 752757de7509SStefano Zampini if (isbddc) { 7528720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 7529720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 753057de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 753127b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 753227b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 7533a198735bSStefano Zampini Mat coarsedivudotp_is; 7534a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 7535a198735bSStefano Zampini IS row,col; 7536a198735bSStefano Zampini const PetscInt *gidxs; 7537a198735bSStefano Zampini PetscInt n,st,M,N; 7538a198735bSStefano Zampini 7539a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 7540a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 7541a198735bSStefano Zampini st = st-n; 7542a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 7543a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 7544a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 7545a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7546a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 7547a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7548a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 7549a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 7550a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 7551a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 7552a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 7553a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 7554a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 7555a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 7556a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 7557a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 7558a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7559a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7560a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 7561a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 75628ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 7563a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 7564720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 756559e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 7566720d30f9SStefano Zampini } 7567d4d8cf7bSStefano Zampini } 75689881197aSStefano Zampini 75693301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 75705a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 75713301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 75723301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 75733301b35fSStefano Zampini } 75743301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 75753301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 75763301b35fSStefano Zampini } 75773301b35fSStefano Zampini if (pc->pmat->spd_set) { 75783301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 75793301b35fSStefano Zampini } 758027b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 758127b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 758227b6a85dSStefano Zampini } 75836e683305SStefano Zampini /* set operators */ 75845f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 75856e683305SStefano Zampini if (pcbddc->dbg_flag) { 75866e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 75876e683305SStefano Zampini } 75886e683305SStefano Zampini } 75891e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 75906e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 7591b1ecc7b1SStefano Zampini #if 0 7592b9b85e73SStefano Zampini { 7593b9b85e73SStefano Zampini PetscViewer viewer; 7594b9b85e73SStefano Zampini char filename[256]; 7595b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 7596b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 75976a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 7598b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 7599f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 7600b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 7601b9b85e73SStefano Zampini } 7602b9b85e73SStefano Zampini #endif 7603f9eb5b7dSStefano Zampini 760498a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 760598a51de6SStefano Zampini Vec crhs,csol; 760604708bb6SStefano Zampini 7607f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 7608f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 7609f347579bSStefano Zampini if (!csol) { 76102a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 7611f9eb5b7dSStefano Zampini } 7612f347579bSStefano Zampini if (!crhs) { 76132a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 7614f347579bSStefano Zampini } 7615b0f5fe93SStefano Zampini } 76161ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 7617b0f5fe93SStefano Zampini 7618b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 7619b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 7620b0f5fe93SStefano Zampini 7621b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 76224f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 76234f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 76244f1b2e48SStefano Zampini } 7625b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 7626b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 7627b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7628b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7629b0f5fe93SStefano Zampini if (coarse_mat) { 7630b0f5fe93SStefano Zampini Vec nullv; 7631b0f5fe93SStefano Zampini PetscScalar *array,*array2; 7632b0f5fe93SStefano Zampini PetscInt nl; 7633b0f5fe93SStefano Zampini 7634b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 7635b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 7636b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7637b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 7638b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 7639b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 7640b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7641b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 7642b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 7643b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 7644b0f5fe93SStefano Zampini } 7645b0f5fe93SStefano Zampini } 7646b0f5fe93SStefano Zampini 7647b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 7648b0f5fe93SStefano Zampini PetscBool ispreonly; 7649b0f5fe93SStefano Zampini 7650b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7651b0f5fe93SStefano Zampini PetscBool isnull; 7652b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 7653bef83e63SStefano Zampini if (isnull) { 7654b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 7655b0f5fe93SStefano Zampini } 7656bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 7657b0f5fe93SStefano Zampini } 7658b0f5fe93SStefano Zampini /* setup coarse ksp */ 7659b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 7660cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 7661cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 76626e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 7663c8587f34SStefano Zampini KSP check_ksp; 76642b510759SStefano Zampini KSPType check_ksp_type; 7665c8587f34SStefano Zampini PC check_pc; 76666e683305SStefano Zampini Vec check_vec,coarse_vec; 76676a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 76682b510759SStefano Zampini PetscInt its; 76696e683305SStefano Zampini PetscBool compute_eigs; 76706e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 76716e683305SStefano Zampini PetscInt neigs; 76728e185a42SStefano Zampini const char *prefix; 7673c8587f34SStefano Zampini 76742b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 76756e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 7676422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 767723ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7678f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 7679e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 7680e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 7681e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 76822b510759SStefano Zampini if (ispreonly) { 76832b510759SStefano Zampini check_ksp_type = KSPPREONLY; 76846e683305SStefano Zampini compute_eigs = PETSC_FALSE; 76852b510759SStefano Zampini } else { 7686cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 76876e683305SStefano Zampini compute_eigs = PETSC_TRUE; 7688c8587f34SStefano Zampini } 7689c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 76906e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 76916e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 76926e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 7693a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 7694a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 7695a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 7696a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 7697c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 7698c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 7699c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 7700c8587f34SStefano Zampini /* create random vec */ 77012701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 7702c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 77036e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 7704c8587f34SStefano Zampini /* solve coarse problem */ 77056e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 7706cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 77076e683305SStefano Zampini if (compute_eigs) { 7708854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 7709854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 77106e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 77111ae86dd6SStefano Zampini if (neigs) { 77126e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 77136e683305SStefano Zampini lambda_min = eigs_r[0]; 77146e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 77152701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 77162701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 7717cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 7718cbcc2c2aSStefano Zampini } 7719c8587f34SStefano Zampini } 7720c8587f34SStefano Zampini } 77211ae86dd6SStefano Zampini } 7722cbcc2c2aSStefano Zampini 7723c8587f34SStefano Zampini /* check coarse problem residual error */ 77246e683305SStefano Zampini if (pcbddc->dbg_flag) { 77256e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 77266e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 77276e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 7728c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 77296e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 77306e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 7731779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 77326e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 77336e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 77346e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 77356e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 7736b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7737b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 7738b0f5fe93SStefano Zampini } 77396e683305SStefano Zampini if (compute_eigs) { 77406e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 7741b03ebc13SStefano Zampini KSPConvergedReason reason; 7742deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 7743c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 7744b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 77456e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 7746b03ebc13SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem eigenvalues (estimated with %d iterations of %s, conv reason %d): %1.6e %1.6e (%1.6e %1.6e)\n",its,check_ksp_type,reason,lambda_min,lambda_max,lambda_min_s,lambda_max_s);CHKERRQ(ierr); 77476e683305SStefano Zampini for (i=0;i<neigs;i++) { 77486e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 7749c8587f34SStefano Zampini } 77506e683305SStefano Zampini } 77516e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 77526e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 77536e683305SStefano Zampini } 7754e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 77552701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 7756c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 77576e683305SStefano Zampini if (compute_eigs) { 77586e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 77596e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 7760c8587f34SStefano Zampini } 77616e683305SStefano Zampini } 77626e683305SStefano Zampini } 7763bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 7764cbcc2c2aSStefano Zampini /* print additional info */ 7765cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 77666e683305SStefano Zampini /* waits until all processes reaches this point */ 77676e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 7768cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 7769cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7770cbcc2c2aSStefano Zampini } 7771cbcc2c2aSStefano Zampini 77722b510759SStefano Zampini /* free memory */ 7773fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 7774c8587f34SStefano Zampini PetscFunctionReturn(0); 7775c8587f34SStefano Zampini } 7776674ae819SStefano Zampini 7777f34684f1SStefano Zampini #undef __FUNCT__ 7778f34684f1SStefano Zampini #define __FUNCT__ "PCBDDCComputePrimalNumbering" 7779f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 7780f34684f1SStefano Zampini { 7781f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7782f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 7783f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 7784dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 7785dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 778673be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 7787dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 7788f34684f1SStefano Zampini PetscErrorCode ierr; 7789f34684f1SStefano Zampini 7790f34684f1SStefano Zampini PetscFunctionBegin; 7791f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 77926c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 7793dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 77943bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 7795dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7796dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 77976583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 7798dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 7799dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 7800dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 78016c4ed002SBarry Smith if (local_size != pcbddc->local_primal_size) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Invalid number of local primal indices computed %D != %D",local_size,pcbddc->local_primal_size); 7802dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 7803dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7804dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 7805dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 7806dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 7807f34684f1SStefano Zampini 7808f34684f1SStefano Zampini /* check numbering */ 7809f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 7810019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 7811dc456d91SStefano Zampini PetscInt i; 7812b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 7813f34684f1SStefano Zampini 7814f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7815f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 7816f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 78171575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7818019a44ceSStefano Zampini /* counter */ 7819019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7820019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 7821019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7822019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7823019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7824019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7825f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 7826f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 7827727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 7828f34684f1SStefano Zampini } 7829f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 7830f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 7831f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7832e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7833e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7834e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7835e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7836f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7837019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7838f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7839019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 78402c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 784175c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 7842b9b85e73SStefano Zampini set_error = PETSC_TRUE; 78432c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 78442c66d082SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d: local index %d (gid %d) owned by %d processes instead of %d!\n",PetscGlobalRank,i,gi,owned,neigh);CHKERRQ(ierr); 7845f34684f1SStefano Zampini } 7846f34684f1SStefano Zampini } 7847019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 7848b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 7849f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7850f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 7851f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 7852f34684f1SStefano Zampini } 7853f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 7854f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 7855e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7856e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 7857f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 7858f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 7859b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 7860ca8b9ea9SStefano Zampini PetscInt *gidxs; 7861ca8b9ea9SStefano Zampini 7862ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 78633bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 7864f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 7865f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7866f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 7867f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 78684bc2dc4bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_primal_indices[%d]=%d (%d,%d)\n",i,local_primal_indices[i],pcbddc->primal_indices_local_idxs[i],gidxs[i]);CHKERRQ(ierr); 7869f34684f1SStefano Zampini } 7870f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7871ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 7872f34684f1SStefano Zampini } 7873f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 78741575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 7875302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 7876f34684f1SStefano Zampini } 78778bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 7878f34684f1SStefano Zampini /* get back data */ 7879f34684f1SStefano Zampini *coarse_size_n = coarse_size; 7880f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 7881674ae819SStefano Zampini PetscFunctionReturn(0); 7882674ae819SStefano Zampini } 7883674ae819SStefano Zampini 7884e456f2a8SStefano Zampini #undef __FUNCT__ 7885e456f2a8SStefano Zampini #define __FUNCT__ "PCBDDCGlobalToLocal" 7886a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 7887e456f2a8SStefano Zampini { 7888e456f2a8SStefano Zampini IS localis_t; 7889a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 7890e456f2a8SStefano Zampini PetscScalar *vals; 7891e456f2a8SStefano Zampini PetscErrorCode ierr; 7892e456f2a8SStefano Zampini 7893e456f2a8SStefano Zampini PetscFunctionBegin; 7894a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 7895e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 7896854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 7897e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 7898e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7899a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 7900a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 79011035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 7902a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 79031035eff8SStefano Zampini } 7904a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 7905e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 7906e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 7907a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 7908a7dc3881SStefano Zampini /* now compute set in local ordering */ 7909a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7910a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7911a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7912a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 7913a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7914ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7915e456f2a8SStefano Zampini lsize++; 7916e456f2a8SStefano Zampini } 7917e456f2a8SStefano Zampini } 7918854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 7919a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 7920ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 7921e456f2a8SStefano Zampini idxs[lsize++] = i; 7922e456f2a8SStefano Zampini } 7923e456f2a8SStefano Zampini } 7924a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 7925a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 7926e456f2a8SStefano Zampini *localis = localis_t; 7927e456f2a8SStefano Zampini PetscFunctionReturn(0); 7928e456f2a8SStefano Zampini } 7929906d46d4SStefano Zampini 7930b96c3477SStefano Zampini #undef __FUNCT__ 7931b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCSetUpSubSchurs" 793208122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 7933b96c3477SStefano Zampini { 7934a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 7935b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 7936b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 7937a64f4aa4SStefano Zampini Mat S_j; 7938b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 7939b96c3477SStefano Zampini PetscBool free_used_adj; 7940b96c3477SStefano Zampini PetscErrorCode ierr; 7941b96c3477SStefano Zampini 7942b96c3477SStefano Zampini PetscFunctionBegin; 7943b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 7944b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 794508122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 7946b96c3477SStefano Zampini used_xadj = NULL; 7947b96c3477SStefano Zampini used_adjncy = NULL; 7948b96c3477SStefano Zampini } else { 794908122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 795008122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 795108122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 795208122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 7953b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 7954b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 7955b96c3477SStefano Zampini } else { 79562fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 7957b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 7958b96c3477SStefano Zampini PetscInt nvtxs; 7959b96c3477SStefano Zampini 79602fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 79612fffb893SStefano Zampini if (flg_row) { 7962b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 7963b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 7964b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 7965b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 79662fffb893SStefano Zampini } else { 79672fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 79682fffb893SStefano Zampini used_xadj = NULL; 79692fffb893SStefano Zampini used_adjncy = NULL; 79702fffb893SStefano Zampini } 79712fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 7972b96c3477SStefano Zampini } 7973b96c3477SStefano Zampini } 7974d5574798SStefano Zampini 7975d5574798SStefano Zampini /* setup sub_schurs data */ 7976a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 7977df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 7978df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 7979a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 798091af6908SStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,NULL,S_j,PETSC_FALSE,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,NULL,pcbddc->adaptive_selection,PETSC_FALSE,PETSC_FALSE,0,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 7981a64f4aa4SStefano Zampini } else { 79826816873aSStefano Zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 79834d7f8f00SStefano Zampini PetscBool isseqaij,need_change = PETSC_FALSE; 7984a3df083aSStefano Zampini PetscInt benign_n; 798572b8c272SStefano Zampini Mat change = NULL; 79869d54b7f4SStefano Zampini Vec scaling = NULL; 798772b8c272SStefano Zampini IS change_primal = NULL; 7988a3df083aSStefano Zampini 79895feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 79905feab87aSStefano Zampini PetscInt n_vertices; 79915feab87aSStefano Zampini 79925feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 79932034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 79945feab87aSStefano Zampini } 799504708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 799604708bb6SStefano Zampini if (!isseqaij) { 799704708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 799804708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 799904708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 800004708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 800104708bb6SStefano Zampini } else { 8002511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 800304708bb6SStefano Zampini } 800404708bb6SStefano Zampini } 8005a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 8006a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 8007ca92afb2SStefano Zampini } else { 8008a3df083aSStefano Zampini benign_n = 0; 8009ca92afb2SStefano Zampini } 8010b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 8011b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 8012b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 801372b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 801422db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 8015b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 801622db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 8017b7ab4a40SStefano Zampini } 8018b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 8019b7ab4a40SStefano Zampini We need to compute the change of basis according to the quadrature weights attached to pmat via MatSetNearNullSpace, and this could not be done (at the moment) without some hacking */ 8020b7ab4a40SStefano Zampini if (need_change) { 802188c03ad3SStefano Zampini PC_IS *pcisf; 802288c03ad3SStefano Zampini PC_BDDC *pcbddcf; 802388c03ad3SStefano Zampini PC pcf; 802488c03ad3SStefano Zampini 8025e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 802688c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 802788c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 802888c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 802988c03ad3SStefano Zampini /* hacks */ 803088c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 803172b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 803272b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 803372b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 803472b8c272SStefano Zampini pcisf->n = pcis->n; 803572b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 803688c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 803788c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 803888c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 803988c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 804088c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 804188c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 804272b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 804388c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 804488c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 804572b8c272SStefano Zampini /* store information on primal vertices and change of basis (in local numbering) */ 804672b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 804772b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 804872b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 804972b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 805088c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 805172b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 805288c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 805388c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 805488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 805588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 805688c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 805788c03ad3SStefano Zampini pcf->ops->destroy = NULL; 805888c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 805988c03ad3SStefano Zampini } 80609d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 806191af6908SStefano Zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,pcbddc->local_mat,S_j,pcbddc->sub_schurs_exact_schur,used_xadj,used_adjncy,pcbddc->sub_schurs_layers,scaling,pcbddc->adaptive_selection,reuse_solvers,pcbddc->benign_saddle_point,benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_zerodiag_subs,change,change_primal);CHKERRQ(ierr); 806272b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 806372b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 8064ca92afb2SStefano Zampini } 8065d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8066b96c3477SStefano Zampini 8067b96c3477SStefano Zampini /* free adjacency */ 8068b96c3477SStefano Zampini if (free_used_adj) { 8069b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 8070b96c3477SStefano Zampini } 8071b96c3477SStefano Zampini PetscFunctionReturn(0); 8072b96c3477SStefano Zampini } 8073b96c3477SStefano Zampini 8074b96c3477SStefano Zampini #undef __FUNCT__ 8075b96c3477SStefano Zampini #define __FUNCT__ "PCBDDCInitSubSchurs" 807608122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 8077b96c3477SStefano Zampini { 8078b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8079b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8080b96c3477SStefano Zampini PCBDDCGraph graph; 8081b96c3477SStefano Zampini PetscErrorCode ierr; 8082b96c3477SStefano Zampini 8083b96c3477SStefano Zampini PetscFunctionBegin; 8084b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 808508122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 80863301b35fSStefano Zampini IS verticesIS,verticescomm; 80873301b35fSStefano Zampini PetscInt vsize,*idxs; 8088b96c3477SStefano Zampini 8089b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 80903301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 80913301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 80923301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 80933301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 8094c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 8095b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 8096be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 8097441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 80983301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 8099b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 8100b96c3477SStefano Zampini } else { 8101b96c3477SStefano Zampini graph = pcbddc->mat_graph; 8102b96c3477SStefano Zampini } 8103e4d548c7SStefano Zampini /* print some info */ 81045c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 8105e4d548c7SStefano Zampini IS vertices; 8106e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 8107c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 8108e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8109e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 8110e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8111e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 8112e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 8113e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 8114e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 8115e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8116e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8117c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8118e4d548c7SStefano Zampini } 8119b96c3477SStefano Zampini 8120b96c3477SStefano Zampini /* sub_schurs init */ 8121b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 8122b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 8123b334f244SStefano Zampini } 81248b6046baSStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap,pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 8125a64f4aa4SStefano Zampini 8126b96c3477SStefano Zampini /* free graph struct */ 812708122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 8128b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 8129b96c3477SStefano Zampini } 8130b96c3477SStefano Zampini PetscFunctionReturn(0); 8131b96c3477SStefano Zampini } 8132fa34dd3eSStefano Zampini 8133fa34dd3eSStefano Zampini #undef __FUNCT__ 8134fa34dd3eSStefano Zampini #define __FUNCT__ "PCBDDCCheckOperator" 8135fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 8136fa34dd3eSStefano Zampini { 8137fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8138fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8139fa34dd3eSStefano Zampini PetscErrorCode ierr; 8140fa34dd3eSStefano Zampini 8141fa34dd3eSStefano Zampini PetscFunctionBegin; 8142fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 8143fa34dd3eSStefano Zampini IS zerodiag = NULL; 81444f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 8145fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 81464f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 814775c01103SStefano Zampini PetscReal norm; 8148fa34dd3eSStefano Zampini PetscInt i; 8149fa34dd3eSStefano Zampini 8150fa34dd3eSStefano Zampini /* B0 and B0_B */ 8151fa34dd3eSStefano Zampini if (zerodiag) { 8152fa34dd3eSStefano Zampini IS dummy; 8153fa34dd3eSStefano Zampini 81544f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 81554f1b2e48SStefano Zampini ierr = MatGetSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 8156fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 8157fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 8158fa34dd3eSStefano Zampini } 8159fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 8160fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 8161fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 8162fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8163fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8164fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8165fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8166fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 8167fa34dd3eSStefano Zampini /* S_j */ 8168fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8169fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 8170fa34dd3eSStefano Zampini 8171fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 8172fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 8173fa34dd3eSStefano Zampini /* continuous in primal space */ 8174fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 8175fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8176fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8177fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 81784f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 81794f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 8180fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8181fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8182fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8183fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8184fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8185fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8186fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 8187fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 8188fa34dd3eSStefano Zampini 8189fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 8190fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 8191fa34dd3eSStefano Zampini /* local with Schur */ 8192fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 8193fa34dd3eSStefano Zampini if (zerodiag) { 8194fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 81954f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 8196fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8197fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 8198fa34dd3eSStefano Zampini } 8199fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 8200fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8201fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8202fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8203fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8204fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 8205fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8206fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8207fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 8208fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8209fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8210fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8211fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8212fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8213fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 8214fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 8215fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8216fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8217fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8218fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8219fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8220fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8221fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 8222fa34dd3eSStefano Zampini if (zerodiag) { 8223fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 8224fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 82254f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 8226fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8227fa34dd3eSStefano Zampini } 8228fa34dd3eSStefano Zampini /* BDDC */ 8229fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 8230fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 8231fa34dd3eSStefano Zampini 8232fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 8233fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 8234fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 8235fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 82364f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 82374f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 8238fa34dd3eSStefano Zampini } 82394f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 8240fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 8241fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 8242fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 8243fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8244fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 8245fa34dd3eSStefano Zampini } 8246fa34dd3eSStefano Zampini PetscFunctionReturn(0); 8247fa34dd3eSStefano Zampini } 82481e0482f5SStefano Zampini 82491e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 82501e0482f5SStefano Zampini #undef __FUNCT__ 82511e0482f5SStefano Zampini #define __FUNCT__ "MatMPIAIJRestrict" 82521e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 82531e0482f5SStefano Zampini { 82541e0482f5SStefano Zampini Mat At; 82551e0482f5SStefano Zampini IS rows; 82561e0482f5SStefano Zampini PetscInt rst,ren; 82571e0482f5SStefano Zampini PetscErrorCode ierr; 82581e0482f5SStefano Zampini PetscLayout rmap; 82591e0482f5SStefano Zampini 82601e0482f5SStefano Zampini PetscFunctionBegin; 82611e0482f5SStefano Zampini rst = ren = 0; 82621e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 82631e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 82641e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 82651e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 82661e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 82671e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 82681e0482f5SStefano Zampini } 8269e07686f2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),ren-rst,rst,1,&rows);CHKERRQ(ierr); 82701e0482f5SStefano Zampini ierr = MatGetSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 82711e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 82721e0482f5SStefano Zampini 82731e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 82741e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 82751e0482f5SStefano Zampini IS from,to; 82761e0482f5SStefano Zampini Vec gvec; 82771e0482f5SStefano Zampini PetscInt lsize; 82781e0482f5SStefano Zampini 82791e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 82801e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 82811e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 82821e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 82831e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 82841e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 82851e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 82861e0482f5SStefano Zampini ierr = MPI_Comm_size(ccomm,&b->size);CHKERRQ(ierr); 82871e0482f5SStefano Zampini ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRQ(ierr); 82881e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 82891e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 82901e0482f5SStefano Zampini b->A = a->A; 82911e0482f5SStefano Zampini b->B = a->B; 82921e0482f5SStefano Zampini 82931e0482f5SStefano Zampini b->donotstash = a->donotstash; 82941e0482f5SStefano Zampini b->roworiented = a->roworiented; 82951e0482f5SStefano Zampini b->rowindices = 0; 82961e0482f5SStefano Zampini b->rowvalues = 0; 82971e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 82981e0482f5SStefano Zampini 82991e0482f5SStefano Zampini (*B)->rmap = rmap; 83001e0482f5SStefano Zampini (*B)->factortype = A->factortype; 83011e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 83021e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 83031e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 83041e0482f5SStefano Zampini 83051e0482f5SStefano Zampini if (a->colmap) { 83061e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 83071e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 83081e0482f5SStefano Zampini #else 83091e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 83101e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 83111e0482f5SStefano Zampini ierr = PetscMemcpy(b->colmap,a->colmap,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 83121e0482f5SStefano Zampini #endif 83131e0482f5SStefano Zampini } else b->colmap = 0; 83141e0482f5SStefano Zampini if (a->garray) { 83151e0482f5SStefano Zampini PetscInt len; 83161e0482f5SStefano Zampini len = a->B->cmap->n; 83171e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 83181e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 83191e0482f5SStefano Zampini if (len) { ierr = PetscMemcpy(b->garray,a->garray,len*sizeof(PetscInt));CHKERRQ(ierr); } 83201e0482f5SStefano Zampini } else b->garray = 0; 83211e0482f5SStefano Zampini 83221e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 83231e0482f5SStefano Zampini b->lvec = a->lvec; 83241e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 83251e0482f5SStefano Zampini 83261e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 83271e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 83281e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 83291e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 83301e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 83311e0482f5SStefano Zampini ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 83321e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 83331e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 83341e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 83351e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 83361e0482f5SStefano Zampini } 83371e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 83381e0482f5SStefano Zampini PetscFunctionReturn(0); 83391e0482f5SStefano Zampini } 8340