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> 4*21ef3d20SStefano Zampini #include <petscdm.h> 5674ae819SStefano Zampini #include <petscblaslapack.h> 6daf8a457SStefano Zampini #include <petsc/private/sfimpl.h> 7674ae819SStefano Zampini 81e0482f5SStefano Zampini static PetscErrorCode MatMPIAIJRestrict(Mat,MPI_Comm,Mat*); 91e0482f5SStefano Zampini 10f498cd09SStefano Zampini /* if range is true, it returns B s.t. span{B} = range(A) 11f498cd09SStefano Zampini if range is false, it returns B s.t. range(B) _|_ range(A) */ 12f498cd09SStefano Zampini PetscErrorCode MatDenseOrthogonalRangeOrComplement(Mat A, PetscBool range, 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"); 24614dbb09SStefano Zampini #else 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 */ 62f498cd09SStefano Zampini if (!range) { 63a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,nr-i,NULL,B);CHKERRQ(ierr); 64a13144ffSStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 65a13144ffSStefano Zampini ierr = PetscMemcpy(data,U+nr*i,(nr-i)*nr*sizeof(PetscScalar));CHKERRQ(ierr); 66f498cd09SStefano Zampini } else { 67f498cd09SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,i,NULL,B);CHKERRQ(ierr); 68f498cd09SStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 69f498cd09SStefano Zampini ierr = PetscMemcpy(data,U,i*nr*sizeof(PetscScalar));CHKERRQ(ierr); 70f498cd09SStefano Zampini } 71a13144ffSStefano Zampini ierr = MatDenseRestoreArray(*B,&data);CHKERRQ(ierr); 72a13144ffSStefano Zampini ierr = PetscFree(U);CHKERRQ(ierr); 73614dbb09SStefano Zampini #endif 74614dbb09SStefano Zampini #else /* PETSC_USE_COMPLEX */ 75a13144ffSStefano Zampini PetscFunctionBegin; 76a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for complexes"); 77a13144ffSStefano Zampini #endif 78a13144ffSStefano Zampini PetscFunctionReturn(0); 79a13144ffSStefano Zampini } 80a13144ffSStefano Zampini 811e0482f5SStefano Zampini /* TODO REMOVE */ 821e0482f5SStefano Zampini #if defined(PRINT_GDET) 831e0482f5SStefano Zampini static int inc = 0; 841e0482f5SStefano Zampini static int lev = 0; 851e0482f5SStefano Zampini #endif 861e0482f5SStefano Zampini 871e0482f5SStefano Zampini PetscErrorCode PCBDDCComputeNedelecChangeEdge(Mat lG, IS edge, IS extrow, IS extcol, IS corners, Mat* Gins, Mat* GKins, PetscScalar cvals[2], PetscScalar *work, PetscReal *rwork) 88a13144ffSStefano Zampini { 89a13144ffSStefano Zampini PetscErrorCode ierr; 90a13144ffSStefano Zampini Mat GE,GEd; 91a13144ffSStefano Zampini PetscInt rsize,csize,esize; 92a13144ffSStefano Zampini PetscScalar *ptr; 93a13144ffSStefano Zampini 94a13144ffSStefano Zampini PetscFunctionBegin; 95a13144ffSStefano Zampini ierr = ISGetSize(edge,&esize);CHKERRQ(ierr); 96c3c0e390SStefano Zampini if (!esize) PetscFunctionReturn(0); 97a13144ffSStefano Zampini ierr = ISGetSize(extrow,&rsize);CHKERRQ(ierr); 98a13144ffSStefano Zampini ierr = ISGetSize(extcol,&csize);CHKERRQ(ierr); 99a13144ffSStefano Zampini 100a13144ffSStefano Zampini /* gradients */ 101a13144ffSStefano Zampini ptr = work + 5*esize; 1027dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,extrow,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 103a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,rsize,csize,ptr,Gins);CHKERRQ(ierr); 104a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,Gins);CHKERRQ(ierr); 105a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 106a13144ffSStefano Zampini 107a13144ffSStefano Zampini /* constants */ 108a13144ffSStefano Zampini ptr += rsize*csize; 109a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,esize,csize,ptr,&GEd);CHKERRQ(ierr); 1107dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,edge,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 111a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,&GEd);CHKERRQ(ierr); 112a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 113f498cd09SStefano Zampini ierr = MatDenseOrthogonalRangeOrComplement(GEd,PETSC_FALSE,5*esize,work,rwork,GKins);CHKERRQ(ierr); 114a13144ffSStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1151e0482f5SStefano Zampini 1161e0482f5SStefano Zampini if (corners) { 1171e0482f5SStefano Zampini Mat GEc; 1181e0482f5SStefano Zampini PetscScalar *vals,v; 1191e0482f5SStefano Zampini 1207dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,edge,corners,MAT_INITIAL_MATRIX,&GEc);CHKERRQ(ierr); 1211e0482f5SStefano Zampini ierr = MatTransposeMatMult(GEc,*GKins,MAT_INITIAL_MATRIX,1.0,&GEd);CHKERRQ(ierr); 1221e0482f5SStefano Zampini ierr = MatDenseGetArray(GEd,&vals);CHKERRQ(ierr); 123637e8532SStefano Zampini /* v = PetscAbsScalar(vals[0]) */; 124637e8532SStefano Zampini v = 1.; 1251e0482f5SStefano Zampini cvals[0] = vals[0]/v; 1261e0482f5SStefano Zampini cvals[1] = vals[1]/v; 1271e0482f5SStefano Zampini ierr = MatDenseRestoreArray(GEd,&vals);CHKERRQ(ierr); 1281e0482f5SStefano Zampini ierr = MatScale(*GKins,1./v);CHKERRQ(ierr); 1291e0482f5SStefano Zampini #if defined(PRINT_GDET) 1301e0482f5SStefano Zampini { 1311e0482f5SStefano Zampini PetscViewer viewer; 1321e0482f5SStefano Zampini char filename[256]; 1331e0482f5SStefano Zampini sprintf(filename,"Gdet_l%d_r%d_cc%d.m",lev,PetscGlobalRank,inc++); 1341e0482f5SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1351e0482f5SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1361e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEc,"GEc");CHKERRQ(ierr); 1371e0482f5SStefano Zampini ierr = MatView(GEc,viewer);CHKERRQ(ierr); 1381e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)(*GKins),"GK");CHKERRQ(ierr); 1391e0482f5SStefano Zampini ierr = MatView(*GKins,viewer);CHKERRQ(ierr); 1401e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEd,"Gproj");CHKERRQ(ierr); 1411e0482f5SStefano Zampini ierr = MatView(GEd,viewer);CHKERRQ(ierr); 1421e0482f5SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1431e0482f5SStefano Zampini } 1441e0482f5SStefano Zampini #endif 1451e0482f5SStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1461e0482f5SStefano Zampini ierr = MatDestroy(&GEc);CHKERRQ(ierr); 1471e0482f5SStefano Zampini } 1481e0482f5SStefano Zampini 149a13144ffSStefano Zampini PetscFunctionReturn(0); 150a13144ffSStefano Zampini } 151a13144ffSStefano Zampini 152a13144ffSStefano Zampini PetscErrorCode PCBDDCNedelecSupport(PC pc) 153a13144ffSStefano Zampini { 154a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 155a13144ffSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1560569b399SStefano Zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGe,lGinit; 157eee23b56SStefano Zampini Vec tvec; 158a13144ffSStefano Zampini PetscSF sfv; 1591e0482f5SStefano Zampini ISLocalToGlobalMapping el2g,vl2g,fl2g,al2g; 160a13144ffSStefano Zampini MPI_Comm comm; 161c2151214SStefano Zampini IS lned,primals,allprimals,nedfieldlocal; 162c2151214SStefano Zampini IS *eedges,*extrows,*extcols,*alleedges; 1637d871cd7SStefano Zampini PetscBT btv,bte,btvc,btb,btbd,btvcand,btvi,btee,bter; 164a13144ffSStefano Zampini PetscScalar *vals,*work; 165a13144ffSStefano Zampini PetscReal *rwork; 166a13144ffSStefano Zampini const PetscInt *idxs,*ii,*jj,*iit,*jjt; 1671e0482f5SStefano Zampini PetscInt ne,nv,Lv,order,n,field; 168a13144ffSStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 169eee23b56SStefano Zampini PetscInt i,j,extmem,cum,maxsize,nee; 170b03ebc13SStefano Zampini PetscInt *extrow,*extrowcum,*marks,*vmarks,*gidxs; 171a13144ffSStefano Zampini PetscInt *sfvleaves,*sfvroots; 172b03ebc13SStefano Zampini PetscInt *corners,*cedges; 173637e8532SStefano Zampini PetscInt *ecount,**eneighs,*vcount,**vneighs; 174b03ebc13SStefano Zampini #if defined(PETSC_USE_DEBUG) 175b03ebc13SStefano Zampini PetscInt *emarks; 176b03ebc13SStefano Zampini #endif 177213b8bfaSStefano Zampini PetscBool print,eerr,done,lrc[2],conforming,global,singular,setprimal; 178a13144ffSStefano Zampini PetscErrorCode ierr; 179a13144ffSStefano Zampini 180a13144ffSStefano Zampini PetscFunctionBegin; 181213b8bfaSStefano Zampini /* If the discrete gradient is defined for a subset of dofs and global is true, 182213b8bfaSStefano Zampini it assumes G is given in global ordering for all the dofs. 183213b8bfaSStefano Zampini Otherwise, the ordering is global for the Nedelec field */ 184213b8bfaSStefano Zampini order = pcbddc->nedorder; 185213b8bfaSStefano Zampini conforming = pcbddc->conforming; 186213b8bfaSStefano Zampini field = pcbddc->nedfield; 187213b8bfaSStefano Zampini global = pcbddc->nedglobal; 188213b8bfaSStefano Zampini setprimal = PETSC_FALSE; 189a13144ffSStefano Zampini print = PETSC_FALSE; 190213b8bfaSStefano Zampini singular = PETSC_FALSE; 191a13144ffSStefano Zampini 192213b8bfaSStefano Zampini /* Command line customization */ 193213b8bfaSStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC Nedelec options","PC");CHKERRQ(ierr); 194213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_field_primal","All edge dofs set as primals: Toselli's algorithm C",NULL,setprimal,&setprimal,NULL);CHKERRQ(ierr); 195213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_singular","Infer nullspace from discrete gradient",NULL,singular,&singular,NULL);CHKERRQ(ierr); 196213b8bfaSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_nedelec_order","Test variable order code (to be removed)",NULL,order,&order,NULL);CHKERRQ(ierr); 197213b8bfaSStefano Zampini /* print debug info TODO: to be removed */ 198213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_print","Print debug info",NULL,print,&print,NULL);CHKERRQ(ierr); 199213b8bfaSStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 200213b8bfaSStefano Zampini 201213b8bfaSStefano Zampini /* Return if there are no edges in the decomposition and the problem is not singular */ 2021e0482f5SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&al2g,NULL);CHKERRQ(ierr); 2031e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(al2g,&n);CHKERRQ(ierr); 204213b8bfaSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 205213b8bfaSStefano Zampini if (!singular) { 206a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 207a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 208c2151214SStefano Zampini for (i=0;i<n;i++) { 209a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 210a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 211a13144ffSStefano Zampini break; 212a13144ffSStefano Zampini } 213a13144ffSStefano Zampini } 214a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 215a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 216a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 217213b8bfaSStefano Zampini } 218a13144ffSStefano Zampini 219213b8bfaSStefano Zampini /* Get Nedelec field */ 220213b8bfaSStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 221c2151214SStefano 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); 222213b8bfaSStefano Zampini if (pcbddc->n_ISForDofsLocal && field >= 0) { 223c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[field]);CHKERRQ(ierr); 224c2151214SStefano Zampini nedfieldlocal = pcbddc->ISForDofsLocal[field]; 225c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 226213b8bfaSStefano Zampini } else if (!pcbddc->n_ISForDofsLocal && field != PETSC_DECIDE) { 227213b8bfaSStefano Zampini ne = n; 228213b8bfaSStefano Zampini nedfieldlocal = NULL; 229213b8bfaSStefano Zampini global = PETSC_TRUE; 230213b8bfaSStefano Zampini } else if (field == PETSC_DECIDE) { 231213b8bfaSStefano Zampini PetscInt rst,ren,*idx; 232213b8bfaSStefano Zampini 233213b8bfaSStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 234213b8bfaSStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 235213b8bfaSStefano Zampini ierr = MatGetOwnershipRange(pcbddc->discretegradient,&rst,&ren);CHKERRQ(ierr); 236213b8bfaSStefano Zampini for (i=rst;i<ren;i++) { 237213b8bfaSStefano Zampini PetscInt nc; 238213b8bfaSStefano Zampini 239213b8bfaSStefano Zampini ierr = MatGetRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 240213b8bfaSStefano Zampini if (nc > 1) matis->sf_rootdata[i-rst] = 1; 241213b8bfaSStefano Zampini ierr = MatRestoreRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 242213b8bfaSStefano Zampini } 243213b8bfaSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 244213b8bfaSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 245213b8bfaSStefano Zampini ierr = PetscMalloc1(n,&idx);CHKERRQ(ierr); 246213b8bfaSStefano Zampini for (i=0,ne=0;i<n;i++) if (matis->sf_leafdata[i]) idx[ne++] = i; 247213b8bfaSStefano Zampini ierr = ISCreateGeneral(comm,ne,idx,PETSC_OWN_POINTER,&nedfieldlocal);CHKERRQ(ierr); 248213b8bfaSStefano Zampini } else { 249213b8bfaSStefano Zampini SETERRQ(comm,PETSC_ERR_USER,"When multiple fields are present, the Nedelec field has to be specified"); 250213b8bfaSStefano Zampini } 251213b8bfaSStefano Zampini 252213b8bfaSStefano Zampini /* Sanity checks */ 253213b8bfaSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 254213b8bfaSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 255213b8bfaSStefano 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); 256213b8bfaSStefano Zampini 257213b8bfaSStefano Zampini /* Just set primal dofs and return */ 2581e0482f5SStefano Zampini if (setprimal) { 259eee23b56SStefano Zampini IS enedfieldlocal; 260eee23b56SStefano Zampini PetscInt *eidxs; 261eee23b56SStefano Zampini 262eee23b56SStefano Zampini ierr = PetscMalloc1(ne,&eidxs);CHKERRQ(ierr); 263eee23b56SStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 264213b8bfaSStefano Zampini if (nedfieldlocal) { 265213b8bfaSStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 266eee23b56SStefano Zampini for (i=0,cum=0;i<ne;i++) { 267eee23b56SStefano Zampini if (PetscRealPart(vals[idxs[i]]) > 2.) { 268eee23b56SStefano Zampini eidxs[cum++] = idxs[i]; 269eee23b56SStefano Zampini } 270eee23b56SStefano Zampini } 271eee23b56SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 272213b8bfaSStefano Zampini } else { 273213b8bfaSStefano Zampini for (i=0,cum=0;i<ne;i++) { 274213b8bfaSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 275213b8bfaSStefano Zampini eidxs[cum++] = i; 276213b8bfaSStefano Zampini } 277213b8bfaSStefano Zampini } 278213b8bfaSStefano Zampini } 279213b8bfaSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 280eee23b56SStefano Zampini ierr = ISCreateGeneral(comm,cum,eidxs,PETSC_COPY_VALUES,&enedfieldlocal);CHKERRQ(ierr); 281eee23b56SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,enedfieldlocal);CHKERRQ(ierr); 282eee23b56SStefano Zampini ierr = PetscFree(eidxs);CHKERRQ(ierr); 2831e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 284eee23b56SStefano Zampini ierr = ISDestroy(&enedfieldlocal);CHKERRQ(ierr); 2851e0482f5SStefano Zampini PetscFunctionReturn(0); 2861e0482f5SStefano Zampini } 287a13144ffSStefano Zampini 288213b8bfaSStefano Zampini /* Compute some l2g maps */ 289213b8bfaSStefano Zampini if (nedfieldlocal) { 290c2151214SStefano Zampini IS is; 291c2151214SStefano Zampini 292c2151214SStefano Zampini /* need to map from the local Nedelec field to local numbering */ 293c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nedfieldlocal,&fl2g);CHKERRQ(ierr); 2941e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering for the whole dofs*/ 2951e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(al2g,nedfieldlocal,&is);CHKERRQ(ierr); 2961e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&al2g);CHKERRQ(ierr); 2971e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering (for Nedelec only) */ 2981e0482f5SStefano Zampini if (global) { 2991e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3001e0482f5SStefano Zampini el2g = al2g; 3011e0482f5SStefano Zampini } else { 3021e0482f5SStefano Zampini IS gis; 3031e0482f5SStefano Zampini 3041e0482f5SStefano Zampini ierr = ISRenumber(is,NULL,NULL,&gis);CHKERRQ(ierr); 3051e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gis,&el2g);CHKERRQ(ierr); 3061e0482f5SStefano Zampini ierr = ISDestroy(&gis);CHKERRQ(ierr); 3071e0482f5SStefano Zampini } 308c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 309c2151214SStefano Zampini } else { 3101e0482f5SStefano Zampini /* restore default */ 3111e0482f5SStefano Zampini pcbddc->nedfield = -1; 3121e0482f5SStefano Zampini /* one ref for the destruction of al2g, one for el2g */ 3131e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3141e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3151e0482f5SStefano Zampini el2g = al2g; 316c2151214SStefano Zampini fl2g = NULL; 317c2151214SStefano Zampini } 318a13144ffSStefano Zampini 319213b8bfaSStefano Zampini /* Start communication to drop connections for interior edges (for cc analysis only) */ 320c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 321c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 322c2151214SStefano Zampini if (nedfieldlocal) { 323c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 324c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 325c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 326c2151214SStefano Zampini } else { 327c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 328c2151214SStefano Zampini } 329c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 330c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 331213b8bfaSStefano Zampini 332213b8bfaSStefano Zampini if (!singular) { /* drop connections with interior edges to avoid unneeded communications and memory movements */ 333213b8bfaSStefano Zampini ierr = MatDuplicate(pcbddc->discretegradient,MAT_COPY_VALUES,&G);CHKERRQ(ierr); 334213b8bfaSStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 3351e0482f5SStefano Zampini if (global) { 3361e0482f5SStefano Zampini PetscInt rst; 3371e0482f5SStefano Zampini 338c2151214SStefano Zampini ierr = MatGetOwnershipRange(G,&rst,NULL);CHKERRQ(ierr); 339c2151214SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 340c2151214SStefano Zampini if (matis->sf_rootdata[i] < 2) { 341c2151214SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 342c2151214SStefano Zampini } 343c2151214SStefano Zampini } 344a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 345c2151214SStefano Zampini ierr = MatZeroRows(G,cum,matis->sf_rootdata,0.,NULL,NULL);CHKERRQ(ierr); 3461e0482f5SStefano Zampini } else { 3471e0482f5SStefano Zampini PetscInt *tbz; 3481e0482f5SStefano Zampini 3491e0482f5SStefano Zampini ierr = PetscMalloc1(ne,&tbz);CHKERRQ(ierr); 3501e0482f5SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3511e0482f5SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3521e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3531e0482f5SStefano Zampini for (i=0,cum=0;i<ne;i++) 3541e0482f5SStefano Zampini if (matis->sf_leafdata[idxs[i]] == 1) 3551e0482f5SStefano Zampini tbz[cum++] = i; 3561e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3571e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApply(el2g,cum,tbz,tbz);CHKERRQ(ierr); 3581e0482f5SStefano Zampini ierr = MatZeroRows(G,cum,tbz,0.,NULL,NULL);CHKERRQ(ierr); 3591e0482f5SStefano Zampini ierr = PetscFree(tbz);CHKERRQ(ierr); 3601e0482f5SStefano Zampini } 361213b8bfaSStefano Zampini } else { /* we need the entire G to infer the nullspace */ 362213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->discretegradient);CHKERRQ(ierr); 363213b8bfaSStefano Zampini G = pcbddc->discretegradient; 364213b8bfaSStefano Zampini } 365a13144ffSStefano Zampini 366a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 367a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 368a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 3697dae84e0SHong Zhang ierr = MatCreateSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 370a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 371a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 372a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 373a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 374a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 375a13144ffSStefano Zampini 376213b8bfaSStefano Zampini /* SF for nodal dofs communications */ 377c2151214SStefano Zampini ierr = MatGetLocalSize(G,NULL,&Lv);CHKERRQ(ierr); 378a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 379a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 380a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 381a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 382a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 383a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 384a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 385213b8bfaSStefano Zampini i = singular ? 2 : 1; 386213b8bfaSStefano Zampini ierr = PetscMalloc2(i*nv,&sfvleaves,i*Lv,&sfvroots);CHKERRQ(ierr); 387a13144ffSStefano Zampini 3881e0482f5SStefano Zampini /* Destroy temporary G created in MATIS format and modified G */ 389213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 390a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 391213b8bfaSStefano Zampini ierr = MatDestroy(&G);CHKERRQ(ierr); 392a13144ffSStefano Zampini 393213b8bfaSStefano Zampini if (print) { 394213b8bfaSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 395213b8bfaSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 396213b8bfaSStefano Zampini } 397213b8bfaSStefano Zampini 398213b8bfaSStefano Zampini /* Save lG for values insertion in change of basis */ 3990569b399SStefano Zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGinit);CHKERRQ(ierr); 4000569b399SStefano Zampini 401a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 4024e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 4034e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 404a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 405a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 406a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 4077d871cd7SStefano Zampini ierr = PetscBTCreate(ne,&btbd);CHKERRQ(ierr); 408c2151214SStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 409a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 410a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 411a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 412c2151214SStefano Zampini IS is; 413c2151214SStefano Zampini 414c2151214SStefano Zampini if (fl2g) { 415c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->DirichletBoundariesLocal,&is);CHKERRQ(ierr); 416c2151214SStefano Zampini } else { 417c2151214SStefano Zampini is = pcbddc->DirichletBoundariesLocal; 418c2151214SStefano Zampini } 419c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 420c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 421a13144ffSStefano Zampini for (i=0;i<cum;i++) { 422a13144ffSStefano Zampini if (idxs[i] >= 0) { 423a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 4247d871cd7SStefano Zampini ierr = PetscBTSet(btbd,idxs[i]);CHKERRQ(ierr); 425a13144ffSStefano Zampini } 426a13144ffSStefano Zampini } 427c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 428c2151214SStefano Zampini if (fl2g) { 429c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 430c2151214SStefano Zampini } 431a13144ffSStefano Zampini } 432a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 433c2151214SStefano Zampini IS is; 434c2151214SStefano Zampini 435c2151214SStefano Zampini if (fl2g) { 436c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->NeumannBoundariesLocal,&is);CHKERRQ(ierr); 437c2151214SStefano Zampini } else { 438c2151214SStefano Zampini is = pcbddc->NeumannBoundariesLocal; 439c2151214SStefano Zampini } 440c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 441c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 442a13144ffSStefano Zampini for (i=0;i<cum;i++) { 443a13144ffSStefano Zampini if (idxs[i] >= 0) { 444a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 445a13144ffSStefano Zampini } 446a13144ffSStefano Zampini } 447c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 448c2151214SStefano Zampini if (fl2g) { 449c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 450a13144ffSStefano Zampini } 451c2151214SStefano Zampini } 452c2151214SStefano Zampini 453213b8bfaSStefano Zampini /* Count neighs per dof */ 454637e8532SStefano Zampini ierr = PetscCalloc1(ne,&ecount);CHKERRQ(ierr); 455637e8532SStefano Zampini ierr = PetscMalloc1(ne,&eneighs);CHKERRQ(ierr); 456637e8532SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 457637e8532SStefano Zampini for (i=1,cum=0;i<n_neigh;i++) { 458637e8532SStefano Zampini cum += n_shared[i]; 459637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 460637e8532SStefano Zampini ecount[shared[i][j]]++; 461637e8532SStefano Zampini } 462637e8532SStefano Zampini } 463637e8532SStefano Zampini if (ne) { 464637e8532SStefano Zampini ierr = PetscMalloc1(cum,&eneighs[0]);CHKERRQ(ierr); 465637e8532SStefano Zampini } 466637e8532SStefano Zampini for (i=1;i<ne;i++) eneighs[i] = eneighs[i-1] + ecount[i-1]; 467637e8532SStefano Zampini ierr = PetscMemzero(ecount,ne*sizeof(PetscInt));CHKERRQ(ierr); 468637e8532SStefano Zampini for (i=1;i<n_neigh;i++) { 469637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 470637e8532SStefano Zampini PetscInt k = shared[i][j]; 471637e8532SStefano Zampini eneighs[k][ecount[k]] = neigh[i]; 472637e8532SStefano Zampini ecount[k]++; 473637e8532SStefano Zampini } 474637e8532SStefano Zampini } 475637e8532SStefano Zampini for (i=0;i<ne;i++) { 476637e8532SStefano Zampini ierr = PetscSortRemoveDupsInt(&ecount[i],eneighs[i]);CHKERRQ(ierr); 477637e8532SStefano Zampini } 478637e8532SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 479637e8532SStefano Zampini ierr = PetscCalloc1(nv,&vcount);CHKERRQ(ierr); 480637e8532SStefano Zampini ierr = PetscMalloc1(nv,&vneighs);CHKERRQ(ierr); 481637e8532SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 482637e8532SStefano Zampini for (i=1,cum=0;i<n_neigh;i++) { 483637e8532SStefano Zampini cum += n_shared[i]; 484637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 485637e8532SStefano Zampini vcount[shared[i][j]]++; 486637e8532SStefano Zampini } 487637e8532SStefano Zampini } 488637e8532SStefano Zampini if (nv) { 489637e8532SStefano Zampini ierr = PetscMalloc1(cum,&vneighs[0]);CHKERRQ(ierr); 490637e8532SStefano Zampini } 491637e8532SStefano Zampini for (i=1;i<nv;i++) vneighs[i] = vneighs[i-1] + vcount[i-1]; 492637e8532SStefano Zampini ierr = PetscMemzero(vcount,nv*sizeof(PetscInt));CHKERRQ(ierr); 493637e8532SStefano Zampini for (i=1;i<n_neigh;i++) { 494637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 495637e8532SStefano Zampini PetscInt k = shared[i][j]; 496637e8532SStefano Zampini vneighs[k][vcount[k]] = neigh[i]; 497637e8532SStefano Zampini vcount[k]++; 498637e8532SStefano Zampini } 499637e8532SStefano Zampini } 500637e8532SStefano Zampini for (i=0;i<nv;i++) { 501637e8532SStefano Zampini ierr = PetscSortRemoveDupsInt(&vcount[i],vneighs[i]);CHKERRQ(ierr); 502637e8532SStefano Zampini } 503637e8532SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 504637e8532SStefano Zampini 5057d871cd7SStefano Zampini /* need to remove coarse faces' dofs and coarse edges' dirichlet dofs 5067d871cd7SStefano Zampini for proper detection of coarse edges' endpoints */ 50762b0c6f7SStefano Zampini ierr = PetscBTCreate(ne,&btee);CHKERRQ(ierr); 50862b0c6f7SStefano Zampini for (i=0;i<ne;i++) { 5097d871cd7SStefano Zampini if ((ecount[i] > 1 && !PetscBTLookup(btbd,i)) || (ecount[i] == 1 && PetscBTLookup(btb,i))) { 51062b0c6f7SStefano Zampini ierr = PetscBTSet(btee,i);CHKERRQ(ierr); 51162b0c6f7SStefano Zampini } 51262b0c6f7SStefano Zampini } 513637e8532SStefano Zampini ierr = PetscMalloc1(ne,&marks);CHKERRQ(ierr); 51462b0c6f7SStefano Zampini if (!conforming) { 51562b0c6f7SStefano Zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 51662b0c6f7SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 51762b0c6f7SStefano Zampini } 5184e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 519dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 52062b0c6f7SStefano Zampini cum = 0; 521a13144ffSStefano Zampini for (i=0;i<ne;i++) { 522dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 52362b0c6f7SStefano Zampini if (!PetscBTLookup(btee,i)) { 524a13144ffSStefano Zampini marks[cum++] = i; 525dec27d64SStefano Zampini continue; 526dec27d64SStefano Zampini } 527dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 52862b0c6f7SStefano Zampini if (!conforming) { 52962b0c6f7SStefano Zampini if (ii[i+1]-ii[i] != order + 1) { /* every row of G on the coarse edge should list order+1 nodal dofs */ 530a13144ffSStefano Zampini marks[cum++] = i; 531a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 532a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 533a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 534a13144ffSStefano Zampini } 53562b0c6f7SStefano Zampini } else { 53662b0c6f7SStefano Zampini /* every edge dofs should be connected trough a certain number of nodal dofs 53762b0c6f7SStefano Zampini to other edge dofs belonging to coarse edges 53862b0c6f7SStefano Zampini - at most 2 endpoints 53962b0c6f7SStefano Zampini - order-1 interior nodal dofs 54062b0c6f7SStefano Zampini - no undefined nodal dofs (nconn < order) 54162b0c6f7SStefano Zampini */ 54262b0c6f7SStefano Zampini PetscInt ends = 0,ints = 0, undef = 0; 54362b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 54462b0c6f7SStefano Zampini PetscInt v = jj[j],k; 54562b0c6f7SStefano Zampini PetscInt nconn = iit[v+1]-iit[v]; 54662b0c6f7SStefano Zampini for (k=iit[v];k<iit[v+1];k++) if (!PetscBTLookup(btee,jjt[k])) nconn--; 54762b0c6f7SStefano Zampini if (nconn > order) ends++; 54862b0c6f7SStefano Zampini else if (nconn == order) ints++; 54962b0c6f7SStefano Zampini else undef++; 55062b0c6f7SStefano Zampini } 55162b0c6f7SStefano Zampini if (undef || ends > 2 || ints != order -1) { 55262b0c6f7SStefano Zampini marks[cum++] = i; 55362b0c6f7SStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 55462b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 55562b0c6f7SStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 55662b0c6f7SStefano Zampini } 55762b0c6f7SStefano Zampini } 55862b0c6f7SStefano Zampini } 559a13144ffSStefano Zampini } 560dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 561dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 562dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 563dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 564a13144ffSStefano Zampini } 565dec27d64SStefano Zampini } 56662b0c6f7SStefano Zampini ierr = PetscBTDestroy(&btee);CHKERRQ(ierr); 567dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 5684e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 56962b0c6f7SStefano Zampini if (!conforming) { 57062b0c6f7SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 57162b0c6f7SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 57262b0c6f7SStefano Zampini } 5734e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 574637e8532SStefano Zampini 575b03ebc13SStefano Zampini /* identify splitpoints and corner candidates */ 5764e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 577a13144ffSStefano Zampini if (print) { 5784e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 5794e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 5804e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 581a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 582a13144ffSStefano Zampini } 583a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 584dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 585a13144ffSStefano Zampini for (i=0;i<nv;i++) { 586637e8532SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i], vc = vcount[i]; 5877d871cd7SStefano Zampini PetscBool sneighs = PETSC_TRUE, bdir = PETSC_FALSE; 588b03ebc13SStefano Zampini if (!order) { /* variable order */ 589dec27d64SStefano Zampini PetscReal vorder = 0.; 590dec27d64SStefano Zampini 591dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 592dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 593dec27d64SStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%d)",vorder,test); 594dec27d64SStefano Zampini ord = 1; 595dec27d64SStefano Zampini } 596a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 597dec27d64SStefano 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); 598a13144ffSStefano Zampini #endif 599637e8532SStefano Zampini for (j=ii[i];j<ii[i+1] && sneighs;j++) { 6007d871cd7SStefano Zampini if (PetscBTLookup(btbd,jj[j])) { 6017d871cd7SStefano Zampini bdir = PETSC_TRUE; 6027d871cd7SStefano Zampini break; 6037d871cd7SStefano Zampini } 604637e8532SStefano Zampini if (vc != ecount[jj[j]]) { 605637e8532SStefano Zampini sneighs = PETSC_FALSE; 606637e8532SStefano Zampini } else { 607637e8532SStefano Zampini PetscInt k,*vn = vneighs[i], *en = eneighs[jj[j]]; 608637e8532SStefano Zampini for (k=0;k<vc;k++) { 609637e8532SStefano Zampini if (vn[k] != en[k]) { 610637e8532SStefano Zampini sneighs = PETSC_FALSE; 611637e8532SStefano Zampini break; 612637e8532SStefano Zampini } 613637e8532SStefano Zampini } 614637e8532SStefano Zampini } 615637e8532SStefano Zampini } 6167d871cd7SStefano Zampini if (!sneighs || test >= 3*ord || bdir) { /* splitpoints */ 6177d871cd7SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %d (%d %d %d)\n",i,!sneighs,test >= 3*ord,bdir); 618a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 619dec27d64SStefano Zampini } else if (test == ord) { 620b03ebc13SStefano Zampini if (order == 1 || (!order && ii[i+1]-ii[i] == 1)) { 621a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %d\n",i); 622a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 623a13144ffSStefano Zampini } else { 624a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %d\n",i); 625a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 626a13144ffSStefano Zampini } 627a13144ffSStefano Zampini } 628a13144ffSStefano Zampini } 629637e8532SStefano Zampini ierr = PetscFree(ecount);CHKERRQ(ierr); 630637e8532SStefano Zampini ierr = PetscFree(vcount);CHKERRQ(ierr); 631637e8532SStefano Zampini if (ne) { 632637e8532SStefano Zampini ierr = PetscFree(eneighs[0]);CHKERRQ(ierr); 633637e8532SStefano Zampini } 634637e8532SStefano Zampini if (nv) { 635637e8532SStefano Zampini ierr = PetscFree(vneighs[0]);CHKERRQ(ierr); 636637e8532SStefano Zampini } 637637e8532SStefano Zampini ierr = PetscFree(eneighs);CHKERRQ(ierr); 638637e8532SStefano Zampini ierr = PetscFree(vneighs);CHKERRQ(ierr); 6397d871cd7SStefano Zampini ierr = PetscBTDestroy(&btbd);CHKERRQ(ierr); 640b03ebc13SStefano Zampini 641b03ebc13SStefano Zampini /* a candidate is valid if it is connected to another candidate via a non-primal edge dof */ 642b03ebc13SStefano Zampini if (order != 1) { 643b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"INSPECTING CANDIDATES\n"); 644b03ebc13SStefano Zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 645b03ebc13SStefano Zampini for (i=0;i<nv;i++) { 646b03ebc13SStefano Zampini if (PetscBTLookup(btvcand,i)) { 647b03ebc13SStefano Zampini PetscBool found = PETSC_FALSE; 648b03ebc13SStefano Zampini for (j=ii[i];j<ii[i+1] && !found;j++) { 649b03ebc13SStefano Zampini PetscInt k,e = jj[j]; 650b03ebc13SStefano Zampini if (PetscBTLookup(bte,e)) continue; 651b03ebc13SStefano Zampini for (k=iit[e];k<iit[e+1];k++) { 652b03ebc13SStefano Zampini PetscInt v = jjt[k]; 653b03ebc13SStefano Zampini if (v != i && PetscBTLookup(btvcand,v)) { 654b03ebc13SStefano Zampini found = PETSC_TRUE; 655b03ebc13SStefano Zampini break; 656b03ebc13SStefano Zampini } 657b03ebc13SStefano Zampini } 658b03ebc13SStefano Zampini } 659b03ebc13SStefano Zampini if (!found) { 660b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d CLEARED\n",i); 661b03ebc13SStefano Zampini ierr = PetscBTClear(btvcand,i);CHKERRQ(ierr); 662b03ebc13SStefano Zampini } else { 663b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d ACCEPTED\n",i); 664b03ebc13SStefano Zampini } 665b03ebc13SStefano Zampini } 666b03ebc13SStefano Zampini } 667b03ebc13SStefano Zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 668b03ebc13SStefano Zampini } 669dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 670a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 671b03ebc13SStefano Zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 672a13144ffSStefano Zampini 673a13144ffSStefano Zampini /* Get the local G^T explicitly */ 6740569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 675a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 6764e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 677a13144ffSStefano Zampini 6784e64d54eSstefano_zampini /* Mark interior nodal dofs */ 679a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 6804e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 681a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 682a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 6834e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 684a13144ffSStefano Zampini } 685a13144ffSStefano Zampini } 686a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 687a13144ffSStefano Zampini 688a13144ffSStefano Zampini /* communicate corners and splitpoints */ 689a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 690a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 691a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 692a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 693a13144ffSStefano Zampini 694a13144ffSStefano Zampini if (print) { 695a13144ffSStefano Zampini IS tbz; 696a13144ffSStefano Zampini 697a13144ffSStefano Zampini cum = 0; 698a13144ffSStefano Zampini for (i=0;i<nv;i++) 699a13144ffSStefano Zampini if (sfvleaves[i]) 700a13144ffSStefano Zampini vmarks[cum++] = i; 701a13144ffSStefano Zampini 702a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 703a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 704a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 705a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 706a13144ffSStefano Zampini } 707a13144ffSStefano Zampini 708a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 709a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 710a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 711a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 712a13144ffSStefano Zampini 7134e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 7144e64d54eSstefano_zampini and interior nodal dofs */ 715a13144ffSStefano Zampini cum = 0; 716a13144ffSStefano Zampini for (i=0;i<nv;i++) { 717a13144ffSStefano Zampini if (sfvleaves[i]) { 718a13144ffSStefano Zampini vmarks[cum++] = i; 719a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 720a13144ffSStefano Zampini } 7214e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 722a13144ffSStefano Zampini } 7234e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 724a13144ffSStefano Zampini if (print) { 725a13144ffSStefano Zampini IS tbz; 726a13144ffSStefano Zampini 727a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 7284e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 729a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 730a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 731a13144ffSStefano Zampini } 732a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 733a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 734a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 735a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 736a13144ffSStefano Zampini 737a13144ffSStefano Zampini /* Recompute G */ 738a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 739a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 740a13144ffSStefano Zampini if (print) { 741a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 742a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 743a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 744a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 745a13144ffSStefano Zampini } 746a13144ffSStefano Zampini 747a13144ffSStefano Zampini /* Get primal dofs (if any) */ 748a13144ffSStefano Zampini cum = 0; 749a13144ffSStefano Zampini for (i=0;i<ne;i++) { 750a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 751a13144ffSStefano Zampini } 752c2151214SStefano Zampini if (fl2g) { 753c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 754c2151214SStefano Zampini } 755a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 756a13144ffSStefano Zampini if (print) { 757a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 758a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 759a13144ffSStefano Zampini } 760a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 761c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 762a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 763a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 764a13144ffSStefano Zampini 765a13144ffSStefano Zampini /* Compute edge connectivity */ 766a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 767a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 768a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 769c2151214SStefano Zampini if (fl2g) { 770c2151214SStefano Zampini PetscBT btf; 771c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 772c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 773c2151214SStefano Zampini 774c2151214SStefano Zampini /* create CSR for all local dofs */ 775c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 776c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 777c2151214SStefano 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); 778c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 779c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 780c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 781c2151214SStefano Zampini rest = PETSC_TRUE; 782c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 783c2151214SStefano Zampini } else { 784c2151214SStefano Zampini free = PETSC_TRUE; 785c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 786c2151214SStefano Zampini iiu[0] = 0; 787c2151214SStefano Zampini for (i=0;i<n;i++) { 788c2151214SStefano Zampini iiu[i+1] = i+1; 789c2151214SStefano Zampini jju[i] = -1; 790d904f53bSStefano Zampini } 791c2151214SStefano Zampini } 792c2151214SStefano Zampini 793c2151214SStefano Zampini /* import sizes of CSR */ 794c2151214SStefano Zampini iia[0] = 0; 795c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 796c2151214SStefano Zampini 797c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 798c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 799c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 800c2151214SStefano Zampini for (i=0;i<ne;i++) { 801c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 802c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 803c2151214SStefano Zampini } 804c2151214SStefano Zampini 805c2151214SStefano Zampini /* iia in CSR */ 806c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 807c2151214SStefano Zampini 808c2151214SStefano Zampini /* jja in CSR */ 809c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 810c2151214SStefano Zampini for (i=0;i<n;i++) 811c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 812c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 813c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 814c2151214SStefano Zampini 815c2151214SStefano Zampini /* map edge dofs connectivity */ 8161e0482f5SStefano Zampini if (jj) { 817c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 818c2151214SStefano Zampini for (i=0;i<ne;i++) { 819c2151214SStefano Zampini PetscInt e = idxs[i]; 820c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 821c2151214SStefano Zampini } 8221e0482f5SStefano Zampini } 823c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 824c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 825c2151214SStefano Zampini if (rest) { 826c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 827c2151214SStefano Zampini } 828c2151214SStefano Zampini if (free) { 829c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 830c2151214SStefano Zampini } 831c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 832c2151214SStefano Zampini } else { 833c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 834c2151214SStefano Zampini } 835c2151214SStefano Zampini 836a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 837a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 838213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 839a13144ffSStefano Zampini 840a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 841c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 842a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 843a13144ffSStefano Zampini 844c2151214SStefano Zampini if (fl2g) { 845c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 846c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 847c2151214SStefano Zampini for (i=0;i<nee;i++) { 848c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 849c2151214SStefano Zampini } 850c2151214SStefano Zampini } else { 851c2151214SStefano Zampini eedges = alleedges; 852c2151214SStefano Zampini primals = allprimals; 853c2151214SStefano Zampini } 854c2151214SStefano Zampini 855a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 856a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 857c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 858c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 859c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 860c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 861c2151214SStefano Zampini if (print) { 862c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 863c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 864c2151214SStefano Zampini } 865c2151214SStefano Zampini 866c2151214SStefano Zampini maxsize = 0; 867a13144ffSStefano Zampini for (i=0;i<nee;i++) { 868a13144ffSStefano Zampini PetscInt size,mark = i+1; 869a13144ffSStefano Zampini 870a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 871a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 872a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 873a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 874a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 875a13144ffSStefano Zampini } 876a13144ffSStefano Zampini 877a13144ffSStefano Zampini /* Find coarse edge endpoints */ 878a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 879a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 880a13144ffSStefano Zampini for (i=0;i<nee;i++) { 881a13144ffSStefano Zampini PetscInt mark = i+1,size; 882a13144ffSStefano Zampini 883a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8841e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8851e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 886a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 887a13144ffSStefano Zampini if (print) { 888a13144ffSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %d\n",i); 889a13144ffSStefano Zampini ISView(eedges[i],NULL); 890a13144ffSStefano Zampini } 891a13144ffSStefano Zampini for (j=0;j<size;j++) { 892a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 893a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %d\n",ee); 894a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 895a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %d\n",jj[k]); 896a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 897a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %d\n",jj[k]); 898a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 899a13144ffSStefano Zampini PetscInt k2; 900a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 901a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 902c2151214SStefano 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])); 903c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 904c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 905c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 906a13144ffSStefano Zampini corner = PETSC_TRUE; 907a13144ffSStefano Zampini break; 908a13144ffSStefano Zampini } 909a13144ffSStefano Zampini } 910a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 911a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %d\n",jj[k]); 912a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 913a13144ffSStefano Zampini } else { 914a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 915a13144ffSStefano Zampini } 916a13144ffSStefano Zampini } 917a13144ffSStefano Zampini } 918a13144ffSStefano Zampini } 919a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 920a13144ffSStefano Zampini } 921a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 922a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 923c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 924a13144ffSStefano Zampini 925a13144ffSStefano Zampini /* Reset marked primal dofs */ 926a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 927a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 928a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 929a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 930a13144ffSStefano Zampini 9310569b399SStefano Zampini /* Now use the initial lG */ 9320569b399SStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 9330569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 9340569b399SStefano Zampini lG = lGinit; 9350569b399SStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 9360569b399SStefano Zampini 937a13144ffSStefano Zampini /* Compute extended cols indices */ 938b03ebc13SStefano Zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 939b03ebc13SStefano Zampini ierr = PetscBTCreate(nee,&bter);CHKERRQ(ierr); 940a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 941a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 942a13144ffSStefano Zampini i *= maxsize; 943b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 944a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 945a13144ffSStefano Zampini eerr = PETSC_FALSE; 946a13144ffSStefano Zampini for (i=0;i<nee;i++) { 947b03ebc13SStefano Zampini PetscInt size,found = 0; 948a13144ffSStefano Zampini 949a13144ffSStefano Zampini cum = 0; 950a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 9511e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 9521e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 953a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 954b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 955a13144ffSStefano Zampini for (j=0;j<size;j++) { 956a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 957b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 958b03ebc13SStefano Zampini PetscInt vv = jj[k]; 959b03ebc13SStefano Zampini if (!PetscBTLookup(btv,vv)) extrow[cum++] = vv; 960b03ebc13SStefano Zampini else if (!PetscBTLookupSet(btvc,vv)) found++; 961b03ebc13SStefano Zampini } 962a13144ffSStefano Zampini } 963a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 964a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 965a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 966a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 967a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 968a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 969a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 970b03ebc13SStefano Zampini if (cum != size -1 || found != 2) { 971b03ebc13SStefano Zampini ierr = PetscBTSet(bter,i);CHKERRQ(ierr); 972a13144ffSStefano Zampini if (print) { 973a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 974a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 975a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 976a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 977a13144ffSStefano Zampini } 978a13144ffSStefano Zampini eerr = PETSC_TRUE; 979a13144ffSStefano Zampini } 980a13144ffSStefano Zampini } 9814e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 982a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 983a13144ffSStefano Zampini if (done) { 984a13144ffSStefano Zampini PetscInt *newprimals; 985a13144ffSStefano Zampini 986a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 987a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 988a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 989a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 990a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 9910569b399SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 992b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"DOING SECOND PASS (eerr %d)\n",eerr); 993a13144ffSStefano Zampini for (i=0;i<nee;i++) { 994b03ebc13SStefano Zampini PetscBool has_candidates = PETSC_FALSE; 995b03ebc13SStefano Zampini if (PetscBTLookup(bter,i)) { 996a13144ffSStefano Zampini PetscInt size,mark = i+1; 997a13144ffSStefano Zampini 998a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 999a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1000c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 1001a13144ffSStefano Zampini for (j=0;j<size;j++) { 1002a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 1003b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"Inspecting edge dof %d [%d %d)\n",ee,ii[ee],ii[ee+1]); 1004a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 1005a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 1006a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 1007a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 1008b03ebc13SStefano Zampini has_candidates = PETSC_TRUE; 1009b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Candidate set to vertex %d\n",vv); 1010a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 1011a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 1012a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 1013a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 1014a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 1015b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected edge dof set to primal %d\n",ee2); 1016a13144ffSStefano Zampini newprimals[cum++] = ee2; 1017a13144ffSStefano Zampini /* finally set the new corners */ 1018a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 1019b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected nodal dof set to vertex %d\n",jj[k3]); 1020a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 1021a13144ffSStefano Zampini } 1022a13144ffSStefano Zampini } 1023a13144ffSStefano Zampini } 1024b03ebc13SStefano Zampini } else { 1025b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Not a candidate vertex %d\n",jj[k]); 1026a13144ffSStefano Zampini } 1027a13144ffSStefano Zampini } 1028a13144ffSStefano Zampini } 1029b03ebc13SStefano Zampini if (!has_candidates) { /* circular edge */ 1030b03ebc13SStefano Zampini PetscInt k, ee = idxs[0],*tmarks; 1031b03ebc13SStefano Zampini 1032b03ebc13SStefano Zampini ierr = PetscCalloc1(ne,&tmarks);CHKERRQ(ierr); 1033b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Circular edge %d\n",i); 1034b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 1035b03ebc13SStefano Zampini PetscInt k2; 1036b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Set to corner %d\n",jj[k]); 1037b03ebc13SStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 1038b03ebc13SStefano Zampini for (k2=iit[jj[k]];k2<iit[jj[k]+1];k2++) tmarks[jjt[k2]]++; 1039b03ebc13SStefano Zampini } 1040b03ebc13SStefano Zampini for (j=0;j<size;j++) { 1041b03ebc13SStefano Zampini if (tmarks[idxs[j]] > 1) { 1042b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Edge dof set to primal %d\n",idxs[j]); 1043b03ebc13SStefano Zampini newprimals[cum++] = idxs[j]; 1044b03ebc13SStefano Zampini } 1045b03ebc13SStefano Zampini } 1046b03ebc13SStefano Zampini ierr = PetscFree(tmarks);CHKERRQ(ierr); 1047b03ebc13SStefano Zampini } 1048a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1049a13144ffSStefano Zampini } 1050a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 1051a13144ffSStefano Zampini } 1052b03ebc13SStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 10530569b399SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 1054a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 1055c2151214SStefano Zampini if (fl2g) { 1056c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 1057c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1058c2151214SStefano Zampini for (i=0;i<nee;i++) { 1059c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1060c2151214SStefano Zampini } 1061c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1062c2151214SStefano Zampini } 1063c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1064a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 1065a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 1066a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 1067a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1068a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 1069213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 1070c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1071c2151214SStefano Zampini if (fl2g) { 1072c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 1073c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 1074c2151214SStefano Zampini for (i=0;i<nee;i++) { 1075c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 1076c2151214SStefano Zampini } 1077c2151214SStefano Zampini } else { 1078c2151214SStefano Zampini eedges = alleedges; 1079c2151214SStefano Zampini primals = allprimals; 1080c2151214SStefano Zampini } 1081b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 1082a13144ffSStefano Zampini 1083a13144ffSStefano Zampini /* Mark again */ 1084a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 1085a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1086a13144ffSStefano Zampini PetscInt size,mark = i+1; 1087a13144ffSStefano Zampini 1088a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 1089a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1090a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 1091a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1092a13144ffSStefano Zampini } 1093a13144ffSStefano Zampini if (print) { 1094a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 1095a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 1096a13144ffSStefano Zampini } 1097a13144ffSStefano Zampini 1098a13144ffSStefano Zampini /* Recompute extended cols */ 1099a13144ffSStefano Zampini eerr = PETSC_FALSE; 1100a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1101a13144ffSStefano Zampini PetscInt size; 1102a13144ffSStefano Zampini 1103a13144ffSStefano Zampini cum = 0; 1104a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 11051e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 11061e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 1107a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1108a13144ffSStefano Zampini for (j=0;j<size;j++) { 1109a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 11101e0482f5SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 1111a13144ffSStefano Zampini } 1112a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1113a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 1114a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 1115a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 1116a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 1117a13144ffSStefano Zampini if (cum != size -1) { 1118a13144ffSStefano Zampini if (print) { 1119a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 1120a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 1121a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 1122a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 1123a13144ffSStefano Zampini } 1124a13144ffSStefano Zampini eerr = PETSC_TRUE; 1125a13144ffSStefano Zampini } 1126a13144ffSStefano Zampini } 1127a13144ffSStefano Zampini } 1128a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1129a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 1130b03ebc13SStefano Zampini ierr = PetscBTDestroy(&bter);CHKERRQ(ierr); 11317d871cd7SStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 1132a13144ffSStefano Zampini /* an error should not occur at this point */ 1133a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 1134a13144ffSStefano Zampini 11354e64d54eSstefano_zampini /* Check the number of endpoints */ 11360569b399SStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1137b03ebc13SStefano Zampini ierr = PetscMalloc1(2*nee,&corners);CHKERRQ(ierr); 1138b03ebc13SStefano Zampini ierr = PetscMalloc1(nee,&cedges);CHKERRQ(ierr); 11394e64d54eSstefano_zampini for (i=0;i<nee;i++) { 1140b03ebc13SStefano Zampini PetscInt size, found = 0, gc[2]; 11414e64d54eSstefano_zampini 1142b03ebc13SStefano Zampini /* init with defaults */ 1143b03ebc13SStefano Zampini cedges[i] = corners[i*2] = corners[i*2+1] = -1; 11444e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 11451e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 11461e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 11474e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1148b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 11494e64d54eSstefano_zampini for (j=0;j<size;j++) { 11504e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 11514e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 11524e64d54eSstefano_zampini PetscInt vv = jj[k]; 11534e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 1154b03ebc13SStefano Zampini if (found == 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found more then two corners for edge %d\n",i); 1155b03ebc13SStefano Zampini corners[i*2+found++] = vv; 11564e64d54eSstefano_zampini } 11574e64d54eSstefano_zampini } 11584e64d54eSstefano_zampini } 1159b03ebc13SStefano Zampini if (found != 2) { 1160b03ebc13SStefano Zampini PetscInt e; 1161b03ebc13SStefano Zampini if (fl2g) { 1162b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,1,idxs,&e);CHKERRQ(ierr); 1163b03ebc13SStefano Zampini } else { 1164b03ebc13SStefano Zampini e = idxs[0]; 1165b03ebc13SStefano Zampini } 1166b03ebc13SStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %d corners for edge %d (astart %d, estart %d)\n",found,i,e,idxs[0]); 1167b03ebc13SStefano Zampini } 1168eee23b56SStefano Zampini 1169eee23b56SStefano Zampini /* get primal dof index on this coarse edge */ 1170b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,2,corners+2*i,gc);CHKERRQ(ierr); 1171b03ebc13SStefano Zampini if (gc[0] > gc[1]) { 1172b03ebc13SStefano Zampini PetscInt swap = corners[2*i]; 1173b03ebc13SStefano Zampini corners[2*i] = corners[2*i+1]; 1174b03ebc13SStefano Zampini corners[2*i+1] = swap; 1175b03ebc13SStefano Zampini } 1176eee23b56SStefano Zampini cedges[i] = idxs[size-1]; 11774e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1178b03ebc13SStefano 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]); 11794e64d54eSstefano_zampini } 11800569b399SStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 11814e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 11824e64d54eSstefano_zampini 1183a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 1184a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 1185a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 1186a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 1187a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1188a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1189a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 1190a13144ffSStefano Zampini 1191a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1192a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 1193a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 1194a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 1195a13144ffSStefano Zampini if (emax < emarks[j]) { 1196a13144ffSStefano Zampini emax = emarks[j]; 1197a13144ffSStefano Zampini eemax = j; 1198a13144ffSStefano Zampini } 1199a13144ffSStefano Zampini } 1200a13144ffSStefano Zampini /* not relevant for edges */ 1201a13144ffSStefano Zampini if (!eemax) continue; 1202a13144ffSStefano Zampini 1203a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 1204a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 1205c2151214SStefano 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]); 1206a13144ffSStefano Zampini } 1207a13144ffSStefano Zampini } 1208a13144ffSStefano Zampini } 1209a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 1210a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1211a13144ffSStefano Zampini #endif 1212a13144ffSStefano Zampini 1213a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 1214a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1215a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 1216a13144ffSStefano Zampini extmem *= maxsize; 1217a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 1218a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 1219a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 1220a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1221a13144ffSStefano Zampini PetscInt mark = 0,size,start; 1222213b8bfaSStefano Zampini 1223a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1224a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 1225a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 1226a13144ffSStefano Zampini mark = marks[jj[j]]; 1227a13144ffSStefano Zampini 1228a13144ffSStefano Zampini /* not relevant */ 1229a13144ffSStefano Zampini if (!mark) continue; 1230a13144ffSStefano Zampini 1231a13144ffSStefano Zampini /* import extended row */ 1232a13144ffSStefano Zampini mark--; 1233a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 1234a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 1235a13144ffSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %d > %d",extrowcum[mark] + size,extmem); 1236a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 1237a13144ffSStefano Zampini extrowcum[mark] += size; 1238a13144ffSStefano Zampini } 1239a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1240213b8bfaSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 1241213b8bfaSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 1242213b8bfaSStefano Zampini 1243213b8bfaSStefano Zampini /* Compress extrows */ 1244a13144ffSStefano Zampini cum = 0; 1245a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1246a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 1247a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 1248a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 1249a13144ffSStefano Zampini cum = PetscMax(cum,size); 1250a13144ffSStefano Zampini } 1251a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 1252a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 1253a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 1254a13144ffSStefano Zampini 1255a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 1256a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 1257a13144ffSStefano Zampini 1258a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 1259a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1260c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 1261c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 1262a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 1263a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 1264a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 12651e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(T,al2g,al2g);CHKERRQ(ierr); 1266a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 1267a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1268213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&al2g);CHKERRQ(ierr); 1269a13144ffSStefano Zampini 1270a13144ffSStefano Zampini /* Defaults to identity */ 1271c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 1272a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 1273a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 1274a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 1275a13144ffSStefano Zampini 12761e0482f5SStefano Zampini /* Create discrete gradient for the coarser level if needed */ 12771e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 12781e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 12791e0482f5SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 12801e0482f5SStefano Zampini ISLocalToGlobalMapping cel2g,cvl2g; 12811e0482f5SStefano Zampini IS wis,gwis; 12821e0482f5SStefano Zampini PetscInt cnv,cne; 12831e0482f5SStefano Zampini 12841e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,nee,cedges,PETSC_COPY_VALUES,&wis);CHKERRQ(ierr); 12851e0482f5SStefano Zampini if (fl2g) { 12861e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(fl2g,wis,&pcbddc->nedclocal);CHKERRQ(ierr); 12871e0482f5SStefano Zampini } else { 12881e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)wis);CHKERRQ(ierr); 12891e0482f5SStefano Zampini pcbddc->nedclocal = wis; 12901e0482f5SStefano Zampini } 12911e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,wis,&gwis);CHKERRQ(ierr); 12921e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12931e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cne,&wis);CHKERRQ(ierr); 12941e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cel2g);CHKERRQ(ierr); 12951e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12961e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 12971e0482f5SStefano Zampini 12981e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,2*nee,corners,PETSC_USE_POINTER,&wis);CHKERRQ(ierr); 12991e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(vl2g,wis,&gwis);CHKERRQ(ierr); 13001e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 13011e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cnv,&wis);CHKERRQ(ierr); 13021e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cvl2g);CHKERRQ(ierr); 13031e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 13041e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 13051e0482f5SStefano Zampini 13061e0482f5SStefano Zampini ierr = MatCreate(comm,&pcbddc->nedcG);CHKERRQ(ierr); 13071e0482f5SStefano Zampini ierr = MatSetSizes(pcbddc->nedcG,PETSC_DECIDE,PETSC_DECIDE,cne,cnv);CHKERRQ(ierr); 13081e0482f5SStefano Zampini ierr = MatSetType(pcbddc->nedcG,MATAIJ);CHKERRQ(ierr); 13091e0482f5SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->nedcG,2,NULL);CHKERRQ(ierr); 13101e0482f5SStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->nedcG,2,NULL,2,NULL);CHKERRQ(ierr); 13111e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->nedcG,cel2g,cvl2g);CHKERRQ(ierr); 13121e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cel2g);CHKERRQ(ierr); 13131e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cvl2g);CHKERRQ(ierr); 13141e0482f5SStefano Zampini } 1315213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 13161e0482f5SStefano Zampini 13171e0482f5SStefano Zampini #if defined(PRINT_GDET) 13181e0482f5SStefano Zampini inc = 0; 13191e0482f5SStefano Zampini lev = pcbddc->current_level; 13201e0482f5SStefano Zampini #endif 1321213b8bfaSStefano Zampini 1322213b8bfaSStefano Zampini /* Insert values in the change of basis matrix */ 1323a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1324a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 13251e0482f5SStefano Zampini IS cornersis = NULL; 13261e0482f5SStefano Zampini PetscScalar cvals[2]; 1327a13144ffSStefano Zampini 13281e0482f5SStefano Zampini if (pcbddc->nedcG) { 13291e0482f5SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,2,corners+2*i,PETSC_USE_POINTER,&cornersis);CHKERRQ(ierr); 13301e0482f5SStefano Zampini } 13311e0482f5SStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],cornersis,&Gins,&GKins,cvals,work,rwork);CHKERRQ(ierr); 1332a13144ffSStefano Zampini if (Gins && GKins) { 1333a13144ffSStefano Zampini PetscScalar *data; 1334a13144ffSStefano Zampini const PetscInt *rows,*cols; 1335a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 1336a13144ffSStefano Zampini 1337a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 1338a13144ffSStefano Zampini /* H1 */ 1339a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 1340a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 1341a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 1342a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 1343a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 1344a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 1345a13144ffSStefano Zampini /* complement */ 1346a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 13471e0482f5SStefano Zampini if (!ncc) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Constant function has not been generated for coarse edge %d",i); 1348213b8bfaSStefano Zampini if (ncc + nch != nrc) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"The sum of the number of columns of GKins %d and Gins %d does not match %d for coarse edge %d",ncc,nch,nrc,i); 1349213b8bfaSStefano Zampini if (ncc != 1 && pcbddc->nedcG) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot generate the coarse discrete gradient for coarse edge %d with ncc %d",i,ncc); 1350a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 1351a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 1352a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 13531e0482f5SStefano Zampini 13541e0482f5SStefano Zampini /* coarse discrete gradient */ 13551e0482f5SStefano Zampini if (pcbddc->nedcG) { 13561e0482f5SStefano Zampini PetscInt cols[2]; 13571e0482f5SStefano Zampini 13581e0482f5SStefano Zampini cols[0] = 2*i; 13591e0482f5SStefano Zampini cols[1] = 2*i+1; 13601e0482f5SStefano Zampini ierr = MatSetValuesLocal(pcbddc->nedcG,1,&i,2,cols,cvals,INSERT_VALUES);CHKERRQ(ierr); 13611e0482f5SStefano Zampini } 1362a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 1363a13144ffSStefano Zampini } 1364a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 1365a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 13661e0482f5SStefano Zampini ierr = ISDestroy(&cornersis);CHKERRQ(ierr); 1367a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 1368a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 1369a13144ffSStefano Zampini } 1370213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 1371a13144ffSStefano Zampini 1372a13144ffSStefano Zampini /* Start assembling */ 1373a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13741e0482f5SStefano Zampini if (pcbddc->nedcG) { 13751e0482f5SStefano Zampini ierr = MatAssemblyBegin(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13761e0482f5SStefano Zampini } 1377a13144ffSStefano Zampini 1378a13144ffSStefano Zampini /* Free */ 1379c2151214SStefano Zampini if (fl2g) { 1380c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1381c2151214SStefano Zampini for (i=0;i<nee;i++) { 1382c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1383c2151214SStefano Zampini } 1384c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1385c2151214SStefano Zampini } 1386eee23b56SStefano Zampini 1387eee23b56SStefano Zampini /* hack mat_graph with primal dofs on the coarse edges */ 1388eee23b56SStefano Zampini { 1389eee23b56SStefano Zampini PCBDDCGraph graph = pcbddc->mat_graph; 1390eee23b56SStefano Zampini PetscInt *oqueue = graph->queue; 1391eee23b56SStefano Zampini PetscInt *ocptr = graph->cptr; 1392eee23b56SStefano Zampini PetscInt ncc,*idxs; 1393eee23b56SStefano Zampini 1394eee23b56SStefano Zampini /* find first primal edge */ 1395eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1396eee23b56SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1397eee23b56SStefano Zampini } else { 1398eee23b56SStefano Zampini if (fl2g) { 1399eee23b56SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,nee,cedges,cedges);CHKERRQ(ierr); 1400eee23b56SStefano Zampini } 1401eee23b56SStefano Zampini idxs = cedges; 1402eee23b56SStefano Zampini } 1403eee23b56SStefano Zampini cum = 0; 1404eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1405eee23b56SStefano Zampini 1406eee23b56SStefano Zampini /* adapt connected components */ 1407eee23b56SStefano Zampini ierr = PetscMalloc2(graph->nvtxs+1,&graph->cptr,ocptr[graph->ncc],&graph->queue);CHKERRQ(ierr); 1408eee23b56SStefano Zampini graph->cptr[0] = 0; 1409eee23b56SStefano Zampini for (i=0,ncc=0;i<graph->ncc;i++) { 1410eee23b56SStefano Zampini PetscInt lc = ocptr[i+1]-ocptr[i]; 1411eee23b56SStefano Zampini if (cum != nee && oqueue[ocptr[i+1]-1] == cedges[cum]) { /* this cc has a primal dof */ 1412eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc]+1; 1413eee23b56SStefano Zampini graph->queue[graph->cptr[ncc]] = cedges[cum]; 1414eee23b56SStefano Zampini ncc++; 1415eee23b56SStefano Zampini lc--; 1416eee23b56SStefano Zampini cum++; 1417eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1418eee23b56SStefano Zampini } 1419eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc] + lc; 1420eee23b56SStefano Zampini for (j=0;j<lc;j++) graph->queue[graph->cptr[ncc]+j] = oqueue[ocptr[i]+j]; 1421eee23b56SStefano Zampini ncc++; 1422eee23b56SStefano Zampini } 1423eee23b56SStefano Zampini graph->ncc = ncc; 1424eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1425eee23b56SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1426eee23b56SStefano Zampini } 1427eee23b56SStefano Zampini ierr = PetscFree2(ocptr,oqueue);CHKERRQ(ierr); 1428eee23b56SStefano Zampini } 1429213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 1430c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1431c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1432213b8bfaSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1433eee23b56SStefano Zampini 1434c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1435a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 1436a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 1437b03ebc13SStefano Zampini ierr = PetscFree(corners);CHKERRQ(ierr); 1438b03ebc13SStefano Zampini ierr = PetscFree(cedges);CHKERRQ(ierr); 1439a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 1440a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 1441a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 1442a13144ffSStefano Zampini 1443a13144ffSStefano Zampini /* Complete assembling */ 1444a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14451e0482f5SStefano Zampini if (pcbddc->nedcG) { 14461e0482f5SStefano Zampini ierr = MatAssemblyEnd(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14471e0482f5SStefano Zampini #if 0 14481e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->nedcG,"coarse_G");CHKERRQ(ierr); 14491e0482f5SStefano Zampini ierr = MatView(pcbddc->nedcG,NULL);CHKERRQ(ierr); 14501e0482f5SStefano Zampini #endif 14511e0482f5SStefano Zampini } 1452a13144ffSStefano Zampini 1453a13144ffSStefano Zampini /* set change of basis */ 1454213b8bfaSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,singular);CHKERRQ(ierr); 1455a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1456a13144ffSStefano Zampini 1457a13144ffSStefano Zampini PetscFunctionReturn(0); 1458a13144ffSStefano Zampini } 1459a13144ffSStefano Zampini 1460d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1461d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1462d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1463d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1464d8203eabSStefano Zampini { 1465d8203eabSStefano Zampini PetscErrorCode ierr; 1466d8203eabSStefano Zampini PetscInt i; 1467d8203eabSStefano Zampini 1468d8203eabSStefano Zampini PetscFunctionBegin; 1469d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1470d8203eabSStefano Zampini PetscInt first,last; 1471d8203eabSStefano Zampini 1472d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 147386fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1474d8203eabSStefano Zampini if (i>=first && i < last) { 1475d8203eabSStefano Zampini PetscScalar *data; 1476d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1477d8203eabSStefano Zampini if (!has_const) { 1478d8203eabSStefano Zampini data[i-first] = 1.; 1479d8203eabSStefano Zampini } else { 148086fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 148186fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1482d8203eabSStefano Zampini } 1483d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1484d8203eabSStefano Zampini } 1485d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1486d8203eabSStefano Zampini } 1487d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1488d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1489d8203eabSStefano Zampini PetscInt first,last; 1490ddc40e2cSstefano_zampini ierr = VecLockPop(quad_vecs[i]);CHKERRQ(ierr); 1491d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1492d8203eabSStefano Zampini if (i>=first && i < last) { 1493d8203eabSStefano Zampini PetscScalar *data; 1494d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1495d8203eabSStefano Zampini if (!has_const) { 1496d8203eabSStefano Zampini data[i-first] = 0.; 1497d8203eabSStefano Zampini } else { 149886fa73c5SStefano Zampini data[2*i-first] = 0.; 149986fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1500d8203eabSStefano Zampini } 1501d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1502d8203eabSStefano Zampini } 1503d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1504ddc40e2cSstefano_zampini ierr = VecLockPush(quad_vecs[i]);CHKERRQ(ierr); 1505d8203eabSStefano Zampini } 1506d8203eabSStefano Zampini PetscFunctionReturn(0); 1507d8203eabSStefano Zampini } 1508d8203eabSStefano Zampini 15098ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1510669cc0f4SStefano Zampini { 1511a198735bSStefano Zampini Mat loc_divudotp; 1512fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 15138ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1514669cc0f4SStefano Zampini IS *faces,*edges; 1515669cc0f4SStefano Zampini PetscScalar *vals; 1516669cc0f4SStefano Zampini const PetscScalar *array; 1517669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 15181ae86dd6SStefano Zampini PetscMPIInt rank; 1519a198735bSStefano Zampini PetscErrorCode ierr; 1520669cc0f4SStefano Zampini 1521669cc0f4SStefano Zampini PetscFunctionBegin; 1522669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1523669cc0f4SStefano Zampini if (graph->twodim) { 1524669cc0f4SStefano Zampini lmaxneighs = 2; 1525669cc0f4SStefano Zampini } else { 1526669cc0f4SStefano Zampini lmaxneighs = 1; 1527669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1528669cc0f4SStefano Zampini const PetscInt *idxs; 1529669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1530669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 1531669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1532669cc0f4SStefano Zampini } 1533669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 1534669cc0f4SStefano Zampini } 1535669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 1536669cc0f4SStefano Zampini maxsize = 0; 1537669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1538669cc0f4SStefano Zampini PetscInt nn; 1539669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1540669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1541669cc0f4SStefano Zampini } 1542669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1543669cc0f4SStefano Zampini PetscInt nn; 1544669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1545669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1546669cc0f4SStefano Zampini } 1547669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1548669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1549669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 15508ae0ca82SStefano Zampini if (!transpose) { 15518ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 15528ae0ca82SStefano Zampini } else { 15538ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 15548ae0ca82SStefano Zampini } 1555669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 15561ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1557d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1558669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1559ddc40e2cSstefano_zampini ierr = VecLockPop(quad_vecs[i]);CHKERRQ(ierr); 15608ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 1561669cc0f4SStefano Zampini } 1562d8203eabSStefano Zampini 1563669cc0f4SStefano Zampini /* compute local quad vec */ 1564a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 15658ae0ca82SStefano Zampini if (!transpose) { 1566a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 15678ae0ca82SStefano Zampini } else { 15688ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 15698ae0ca82SStefano Zampini } 1570669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 15718ae0ca82SStefano Zampini if (!transpose) { 1572a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 15738ae0ca82SStefano Zampini } else { 15748ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 15758ae0ca82SStefano Zampini } 1576fa23a32eSStefano Zampini if (vl2l) { 1577fa23a32eSStefano Zampini ierr = VecGetSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1578fa23a32eSStefano Zampini } else { 1579fa23a32eSStefano Zampini vins = v; 1580fa23a32eSStefano Zampini } 1581fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1582669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 15839a962809SStefano Zampini 15841ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 15851ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1586669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1587669cc0f4SStefano Zampini const PetscInt *idxs; 1588669cc0f4SStefano Zampini PetscInt idx,nn,j; 1589669cc0f4SStefano Zampini 1590669cc0f4SStefano Zampini ierr = ISGetIndices(faces[i],&idxs);CHKERRQ(ierr); 1591669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1592669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 15931ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1594669cc0f4SStefano Zampini idx = -(idx+1); 1595669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1596669cc0f4SStefano Zampini ierr = ISRestoreIndices(faces[i],&idxs);CHKERRQ(ierr); 1597669cc0f4SStefano Zampini } 1598669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1599669cc0f4SStefano Zampini const PetscInt *idxs; 1600669cc0f4SStefano Zampini PetscInt idx,nn,j; 1601669cc0f4SStefano Zampini 1602669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1603669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1604669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 16051ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1606669cc0f4SStefano Zampini idx = -(idx+1); 1607669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1608669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1609669cc0f4SStefano Zampini } 1610c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1611fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1612fa23a32eSStefano Zampini if (vl2l) { 1613fa23a32eSStefano Zampini ierr = VecRestoreSubVector(v,vl2l,&vins);CHKERRQ(ierr); 1614fa23a32eSStefano Zampini } 1615669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1616669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1617669cc0f4SStefano Zampini 1618669cc0f4SStefano Zampini /* assemble near null space */ 1619669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1620669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1621669cc0f4SStefano Zampini } 1622669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1623669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 1624ddc40e2cSstefano_zampini ierr = VecLockPush(quad_vecs[i]);CHKERRQ(ierr); 1625669cc0f4SStefano Zampini } 1626669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1627669cc0f4SStefano Zampini PetscFunctionReturn(0); 1628669cc0f4SStefano Zampini } 1629669cc0f4SStefano Zampini 1630669cc0f4SStefano Zampini 16311f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 16321f4df5f7SStefano Zampini { 16331f4df5f7SStefano Zampini PetscErrorCode ierr; 16341f4df5f7SStefano Zampini Vec local,global; 16351f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16361f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1637ef24a9ddSStefano Zampini PetscBool monolithic = PETSC_FALSE; 16381f4df5f7SStefano Zampini 16391f4df5f7SStefano Zampini PetscFunctionBegin; 16401f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 1641*21ef3d20SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 16421f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 16431f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 16441f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 16451f4df5f7SStefano Zampini PetscInt i; 16461f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16471f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 16481f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16491f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 16501f4df5f7SStefano Zampini } 16511f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 16521f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 16531f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 16541f4df5f7SStefano Zampini } 16551f4df5f7SStefano Zampini } else { 1656*21ef3d20SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present */ 1657*21ef3d20SStefano Zampini DM dm; 1658*21ef3d20SStefano Zampini 1659*21ef3d20SStefano Zampini ierr = PCGetDM(pc, &dm);CHKERRQ(ierr); 1660*21ef3d20SStefano Zampini if (!dm) { 1661*21ef3d20SStefano Zampini ierr = MatGetDM(pc->pmat, &dm);CHKERRQ(ierr); 1662*21ef3d20SStefano Zampini } 1663*21ef3d20SStefano Zampini if (dm) { 1664*21ef3d20SStefano Zampini IS *fields; 1665*21ef3d20SStefano Zampini PetscInt nf,i; 1666*21ef3d20SStefano Zampini ierr = DMCreateFieldDecomposition(dm,&nf,NULL,&fields,NULL);CHKERRQ(ierr); 1667*21ef3d20SStefano Zampini ierr = PetscMalloc1(nf,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 1668*21ef3d20SStefano Zampini for (i=0;i<nf;i++) { 1669*21ef3d20SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,fields[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 1670*21ef3d20SStefano Zampini ierr = ISDestroy(&fields[i]);CHKERRQ(ierr); 1671*21ef3d20SStefano Zampini } 1672*21ef3d20SStefano Zampini ierr = PetscFree(fields);CHKERRQ(ierr); 1673*21ef3d20SStefano Zampini pcbddc->n_ISForDofsLocal = nf; 1674*21ef3d20SStefano Zampini } else { /* See if MATIS has fields attached by the conversion from MatNest */ 1675*21ef3d20SStefano Zampini PetscContainer c; 1676*21ef3d20SStefano Zampini 1677*21ef3d20SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc->pmat,"_convert_nest_lfields",(PetscObject*)&c);CHKERRQ(ierr); 1678*21ef3d20SStefano Zampini if (c) { 1679*21ef3d20SStefano Zampini MatISLocalFields lf; 1680*21ef3d20SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&lf);CHKERRQ(ierr); 1681*21ef3d20SStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,lf->nr,lf->rf);CHKERRQ(ierr); 1682*21ef3d20SStefano Zampini } else { /* fallback, create the default fields if bs > 1 */ 16831f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1684986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 1685*21ef3d20SStefano Zampini if (i > 1) { 1686986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 16871f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16881f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16891f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16901f4df5f7SStefano Zampini } 16911f4df5f7SStefano Zampini } 1692*21ef3d20SStefano Zampini } 1693*21ef3d20SStefano Zampini } 16947a0e7b2cSstefano_zampini } else { 16957a0e7b2cSstefano_zampini PetscInt i; 16967a0e7b2cSstefano_zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16977a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16987a0e7b2cSstefano_zampini } 16991f4df5f7SStefano Zampini } 1700986cdee1SStefano Zampini } 17011f4df5f7SStefano Zampini 17021f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 17031f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 17047a0e7b2cSstefano_zampini } else if (pcbddc->DirichletBoundariesLocal) { 17057a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 17061f4df5f7SStefano Zampini } 17071f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 17081f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 17097a0e7b2cSstefano_zampini } else if (pcbddc->NeumannBoundariesLocal) { 17107a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 17111f4df5f7SStefano Zampini } 17121f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 17131f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 17141f4df5f7SStefano Zampini } 17151f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 17161f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 17177a0e7b2cSstefano_zampini 17187a0e7b2cSstefano_zampini PetscFunctionReturn(0); 17197a0e7b2cSstefano_zampini } 17207a0e7b2cSstefano_zampini 17217a0e7b2cSstefano_zampini PetscErrorCode PCBDDCConsistencyCheckIS(PC pc, MPI_Op mop, IS *is) 17227a0e7b2cSstefano_zampini { 17237a0e7b2cSstefano_zampini Mat_IS *matis = (Mat_IS*)(pc->pmat->data); 17247a0e7b2cSstefano_zampini PetscErrorCode ierr; 17257a0e7b2cSstefano_zampini IS nis; 17267a0e7b2cSstefano_zampini const PetscInt *idxs; 17277a0e7b2cSstefano_zampini PetscInt i,nd,n = matis->A->rmap->n,*nidxs,nnd; 17287a0e7b2cSstefano_zampini PetscBool *ld; 17297a0e7b2cSstefano_zampini 17307a0e7b2cSstefano_zampini PetscFunctionBegin; 17317a0e7b2cSstefano_zampini if (mop != MPI_LAND && mop != MPI_LOR) SETERRQ(PetscObjectComm((PetscObject)(pc)),PETSC_ERR_SUP,"Supported are MPI_LAND and MPI_LOR"); 17327a0e7b2cSstefano_zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 17337a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 17347a0e7b2cSstefano_zampini /* init rootdata with true */ 17357a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_rootdata; 17367a0e7b2cSstefano_zampini for (i=0;i<pc->pmat->rmap->n;i++) ld[i] = PETSC_TRUE; 17377a0e7b2cSstefano_zampini } else { 17387a0e7b2cSstefano_zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscBool));CHKERRQ(ierr); 17397a0e7b2cSstefano_zampini } 17407a0e7b2cSstefano_zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscBool));CHKERRQ(ierr); 17417a0e7b2cSstefano_zampini ierr = ISGetLocalSize(*is,&nd);CHKERRQ(ierr); 17427a0e7b2cSstefano_zampini ierr = ISGetIndices(*is,&idxs);CHKERRQ(ierr); 17437a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_leafdata; 17447a0e7b2cSstefano_zampini for (i=0;i<nd;i++) 17457a0e7b2cSstefano_zampini if (-1 < idxs[i] && idxs[i] < n) 17467a0e7b2cSstefano_zampini ld[idxs[i]] = PETSC_TRUE; 17477a0e7b2cSstefano_zampini ierr = ISRestoreIndices(*is,&idxs);CHKERRQ(ierr); 17487a0e7b2cSstefano_zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 17497a0e7b2cSstefano_zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 17507a0e7b2cSstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 17517a0e7b2cSstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 17527a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 17537a0e7b2cSstefano_zampini ierr = PetscMalloc1(nd,&nidxs);CHKERRQ(ierr); 17547a0e7b2cSstefano_zampini } else { 17557a0e7b2cSstefano_zampini ierr = PetscMalloc1(n,&nidxs);CHKERRQ(ierr); 17567a0e7b2cSstefano_zampini } 17577a0e7b2cSstefano_zampini for (i=0,nnd=0;i<n;i++) 17587a0e7b2cSstefano_zampini if (ld[i]) 17597a0e7b2cSstefano_zampini nidxs[nnd++] = i; 17607a0e7b2cSstefano_zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(*is)),nnd,nidxs,PETSC_OWN_POINTER,&nis);CHKERRQ(ierr); 17617a0e7b2cSstefano_zampini ierr = ISDestroy(is);CHKERRQ(ierr); 17627a0e7b2cSstefano_zampini *is = nis; 17631f4df5f7SStefano Zampini PetscFunctionReturn(0); 17641f4df5f7SStefano Zampini } 17651f4df5f7SStefano Zampini 17663e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 17673e589ea0SStefano Zampini { 17683e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 17693e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 17703e589ea0SStefano Zampini PetscErrorCode ierr; 17713e589ea0SStefano Zampini 17723e589ea0SStefano Zampini PetscFunctionBegin; 17733e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 17743e589ea0SStefano Zampini PetscFunctionReturn(0); 17753e589ea0SStefano Zampini } 17763e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 17773e589ea0SStefano Zampini Vec swap; 17783e589ea0SStefano Zampini 17793e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 17803e589ea0SStefano Zampini swap = pcbddc->work_change; 17813e589ea0SStefano Zampini pcbddc->work_change = r; 17823e589ea0SStefano Zampini r = swap; 17833e589ea0SStefano Zampini } 17843e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17853e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 17863e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 17873e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 17883e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17893e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 17903e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1791f913dca9SStefano Zampini pcbddc->work_change = r; 17923e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 17933e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 17943e589ea0SStefano Zampini } 17953e589ea0SStefano Zampini PetscFunctionReturn(0); 17963e589ea0SStefano Zampini } 17973e589ea0SStefano Zampini 1798a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1799a3df083aSStefano Zampini { 1800a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1801a3df083aSStefano Zampini PetscErrorCode ierr; 1802a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1803a3df083aSStefano Zampini 1804a3df083aSStefano Zampini PetscFunctionBegin; 1805a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1806a3df083aSStefano Zampini if (transpose) { 1807a3df083aSStefano Zampini apply_right = ctx->apply_left; 1808a3df083aSStefano Zampini apply_left = ctx->apply_right; 1809a3df083aSStefano Zampini } else { 1810a3df083aSStefano Zampini apply_right = ctx->apply_right; 1811a3df083aSStefano Zampini apply_left = ctx->apply_left; 1812a3df083aSStefano Zampini } 1813a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1814a3df083aSStefano Zampini if (apply_right) { 1815a3df083aSStefano Zampini const PetscScalar *ax; 1816a3df083aSStefano Zampini PetscInt nl,i; 1817a3df083aSStefano Zampini 1818a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1819a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1820a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1821a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1822a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1823a3df083aSStefano Zampini PetscScalar sum,val; 1824a3df083aSStefano Zampini const PetscInt *idxs; 1825a3df083aSStefano Zampini PetscInt nz,j; 1826a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1827a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1828a3df083aSStefano Zampini sum = 0.; 1829a3df083aSStefano Zampini if (ctx->apply_p0) { 1830a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1831a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1832a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1833a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1834a3df083aSStefano Zampini } 1835a3df083aSStefano Zampini } else { 1836a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1837a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1838a3df083aSStefano Zampini } 1839a3df083aSStefano Zampini } 1840a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1841a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1842a3df083aSStefano Zampini } 1843a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1844a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1845a3df083aSStefano Zampini } 1846a3df083aSStefano Zampini if (transpose) { 1847a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1848a3df083aSStefano Zampini } else { 1849a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1850a3df083aSStefano Zampini } 1851a3df083aSStefano Zampini if (reset_x) { 1852a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1853a3df083aSStefano Zampini } 1854a3df083aSStefano Zampini if (apply_left) { 1855a3df083aSStefano Zampini PetscScalar *ay; 1856a3df083aSStefano Zampini PetscInt i; 1857a3df083aSStefano Zampini 1858a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1859a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1860a3df083aSStefano Zampini PetscScalar sum,val; 1861a3df083aSStefano Zampini const PetscInt *idxs; 1862a3df083aSStefano Zampini PetscInt nz,j; 1863a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1864a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1865a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1866a3df083aSStefano Zampini if (ctx->apply_p0) { 1867a3df083aSStefano Zampini sum = 0.; 1868a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1869a3df083aSStefano Zampini sum += ay[idxs[j]]; 1870a3df083aSStefano Zampini ay[idxs[j]] += val; 1871a3df083aSStefano Zampini } 1872a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1873a3df083aSStefano Zampini } else { 1874a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1875a3df083aSStefano Zampini ay[idxs[j]] += val; 1876a3df083aSStefano Zampini } 1877a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1878a3df083aSStefano Zampini } 1879a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1880a3df083aSStefano Zampini } 1881a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1882a3df083aSStefano Zampini } 1883a3df083aSStefano Zampini PetscFunctionReturn(0); 1884a3df083aSStefano Zampini } 1885a3df083aSStefano Zampini 1886a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1887a3df083aSStefano Zampini { 1888a3df083aSStefano Zampini PetscErrorCode ierr; 1889a3df083aSStefano Zampini 1890a3df083aSStefano Zampini PetscFunctionBegin; 1891a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1892a3df083aSStefano Zampini PetscFunctionReturn(0); 1893a3df083aSStefano Zampini } 1894a3df083aSStefano Zampini 1895a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1896a3df083aSStefano Zampini { 1897a3df083aSStefano Zampini PetscErrorCode ierr; 1898a3df083aSStefano Zampini 1899a3df083aSStefano Zampini PetscFunctionBegin; 1900a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1901a3df083aSStefano Zampini PetscFunctionReturn(0); 1902a3df083aSStefano Zampini } 1903a3df083aSStefano Zampini 1904a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1905a3df083aSStefano Zampini { 1906a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1907a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1908a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1909a3df083aSStefano Zampini PetscErrorCode ierr; 1910a3df083aSStefano Zampini 1911a3df083aSStefano Zampini PetscFunctionBegin; 1912a3df083aSStefano Zampini if (!restore) { 19131dd7afcfSStefano Zampini Mat A_IB,A_BI; 1914a3df083aSStefano Zampini PetscScalar *work; 1915b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 1916a3df083aSStefano Zampini 19179a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 19189a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 1919a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 1920a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 1921a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1922a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 1923a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 1924a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 1925a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 1926a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 1927a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 1928a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 1929a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 1930a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 1931059032f7SStefano Zampini if (reuse) { 1932a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 19331dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 1934059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 1935059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 1936059032f7SStefano Zampini PetscInt i; 1937059032f7SStefano Zampini 1938059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 1939059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1940059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 1941059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1942059032f7SStefano Zampini } 1943059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 19441dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 1945059032f7SStefano Zampini } 1946a3df083aSStefano Zampini ctx->A = pcis->A_IB; 1947a3df083aSStefano Zampini ctx->work = work; 1948a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 1949a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1950a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 1951a3df083aSStefano Zampini pcis->A_IB = A_IB; 1952a3df083aSStefano Zampini 1953a3df083aSStefano Zampini /* A_BI as A_IB^T */ 1954a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 1955a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 1956a3df083aSStefano Zampini pcis->A_BI = A_BI; 1957a3df083aSStefano Zampini } else { 19581dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 19591dd7afcfSStefano Zampini PetscFunctionReturn(0); 19601dd7afcfSStefano Zampini } 1961a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 1962a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 1963a3df083aSStefano Zampini pcis->A_IB = ctx->A; 19641dd7afcfSStefano Zampini ctx->A = NULL; 19651dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 19661dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 19671dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 19681dd7afcfSStefano Zampini if (ctx->free) { 1969059032f7SStefano Zampini PetscInt i; 19701dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1971059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 1972059032f7SStefano Zampini } 1973059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 1974059032f7SStefano Zampini } 1975a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 1976a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 1977a3df083aSStefano Zampini } 1978a3df083aSStefano Zampini PetscFunctionReturn(0); 1979a3df083aSStefano Zampini } 1980a3df083aSStefano Zampini 1981a3df083aSStefano Zampini /* used just in bddc debug mode */ 1982a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 1983a3df083aSStefano Zampini { 1984a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1985a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1986a3df083aSStefano Zampini Mat An; 1987a3df083aSStefano Zampini PetscErrorCode ierr; 1988a3df083aSStefano Zampini 1989a3df083aSStefano Zampini PetscFunctionBegin; 1990a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 1991a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 1992a3df083aSStefano Zampini if (is1) { 19937dae84e0SHong Zhang ierr = MatCreateSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 1994a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 1995a3df083aSStefano Zampini } else { 1996a3df083aSStefano Zampini *B = An; 1997a3df083aSStefano Zampini } 1998a3df083aSStefano Zampini PetscFunctionReturn(0); 1999a3df083aSStefano Zampini } 2000a3df083aSStefano Zampini 20011cf9b237SStefano Zampini /* TODO: add reuse flag */ 20021cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 20031cf9b237SStefano Zampini { 20041cf9b237SStefano Zampini Mat Bt; 20051cf9b237SStefano Zampini PetscScalar *a,*bdata; 20061cf9b237SStefano Zampini const PetscInt *ii,*ij; 20071cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 20081cf9b237SStefano Zampini PetscBool flg_row; 20091cf9b237SStefano Zampini PetscErrorCode ierr; 20101cf9b237SStefano Zampini 20111cf9b237SStefano Zampini PetscFunctionBegin; 20121cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 20131cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 20141cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 20151cf9b237SStefano Zampini nnz = n; 20161cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 20171cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 20181cf9b237SStefano Zampini } 20191cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 20201cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 20211cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 20221cf9b237SStefano Zampini nnz = 0; 20231cf9b237SStefano Zampini bii[0] = 0; 20241cf9b237SStefano Zampini for (i=0;i<n;i++) { 20251cf9b237SStefano Zampini PetscInt j; 20261cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 20271cf9b237SStefano Zampini PetscScalar entry = a[j]; 20281cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 20291cf9b237SStefano Zampini bij[nnz] = ij[j]; 20301cf9b237SStefano Zampini bdata[nnz] = entry; 20311cf9b237SStefano Zampini nnz++; 20321cf9b237SStefano Zampini } 20331cf9b237SStefano Zampini } 20341cf9b237SStefano Zampini bii[i+1] = nnz; 20351cf9b237SStefano Zampini } 20361cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 20371cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 20381cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 20391cf9b237SStefano Zampini { 20401cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 20411cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 20421cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 20431cf9b237SStefano Zampini } 20441cf9b237SStefano Zampini *B = Bt; 20451cf9b237SStefano Zampini PetscFunctionReturn(0); 20461cf9b237SStefano Zampini } 20471cf9b237SStefano Zampini 20484f1b2e48SStefano Zampini PetscErrorCode MatDetectDisconnectedComponents(Mat A, PetscBool filter, PetscInt *ncc, IS* cc[]) 20494f1b2e48SStefano Zampini { 20504f1b2e48SStefano Zampini Mat B; 20514f1b2e48SStefano Zampini IS is_dummy,*cc_n; 20524f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 20534f1b2e48SStefano Zampini PCBDDCGraph graph; 20544f1b2e48SStefano Zampini PetscInt i,n; 20554f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 20564f1b2e48SStefano Zampini PetscInt *xadj_filtered,*adjncy_filtered; 20574f1b2e48SStefano Zampini PetscBool flg_row,isseqaij; 20584f1b2e48SStefano Zampini PetscErrorCode ierr; 20594f1b2e48SStefano Zampini 20604f1b2e48SStefano Zampini PetscFunctionBegin; 206163c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 206263c961adSStefano Zampini *ncc = 0; 206363c961adSStefano Zampini *cc = NULL; 206463c961adSStefano Zampini PetscFunctionReturn(0); 206563c961adSStefano Zampini } 20664f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 20674f1b2e48SStefano Zampini if (!isseqaij && filter) { 20681cf9b237SStefano Zampini PetscBool isseqdense; 20691cf9b237SStefano Zampini 20701cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 20711cf9b237SStefano Zampini if (!isseqdense) { 20724f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 20731cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 20741cf9b237SStefano Zampini PetscScalar *array; 20751cf9b237SStefano Zampini PetscReal chop=1.e-6; 20761cf9b237SStefano Zampini 20771cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 20781cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 20791cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 20801cf9b237SStefano Zampini for (i=0;i<n;i++) { 20811cf9b237SStefano Zampini PetscInt j; 20821cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 20831cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 20841cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 20851cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 20861cf9b237SStefano Zampini } 20871cf9b237SStefano Zampini } 20881cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 20899d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 20901cf9b237SStefano Zampini } 20914f1b2e48SStefano Zampini } else { 20924f1b2e48SStefano Zampini B = A; 20934f1b2e48SStefano Zampini } 20944f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 20954f1b2e48SStefano Zampini 20964f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 20974f1b2e48SStefano Zampini if (filter) { 20984f1b2e48SStefano Zampini PetscScalar *data; 20994f1b2e48SStefano Zampini PetscInt j,cum; 21004f1b2e48SStefano Zampini 21014f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 21024f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 21034f1b2e48SStefano Zampini cum = 0; 21044f1b2e48SStefano Zampini for (i=0;i<n;i++) { 21054f1b2e48SStefano Zampini PetscInt t; 21064f1b2e48SStefano Zampini 21074f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 21084f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 21094f1b2e48SStefano Zampini continue; 21104f1b2e48SStefano Zampini } 21114f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 21124f1b2e48SStefano Zampini } 21134f1b2e48SStefano Zampini t = xadj_filtered[i]; 21144f1b2e48SStefano Zampini xadj_filtered[i] = cum; 21154f1b2e48SStefano Zampini cum += t; 21164f1b2e48SStefano Zampini } 21174f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 21184f1b2e48SStefano Zampini } else { 21194f1b2e48SStefano Zampini xadj_filtered = NULL; 21204f1b2e48SStefano Zampini adjncy_filtered = NULL; 21214f1b2e48SStefano Zampini } 21224f1b2e48SStefano Zampini 21234f1b2e48SStefano Zampini /* compute local connected components using PCBDDCGraph */ 21244f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 21254f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 21264f1b2e48SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 21274f1b2e48SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 2128be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 21294f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 21304f1b2e48SStefano Zampini if (xadj_filtered) { 21314f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 21324f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 21334f1b2e48SStefano Zampini } else { 21344f1b2e48SStefano Zampini graph->xadj = xadj; 21354f1b2e48SStefano Zampini graph->adjncy = adjncy; 21364f1b2e48SStefano Zampini } 21374f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 21384f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 21394f1b2e48SStefano Zampini /* partial clean up */ 21404f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 21414f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 21421cf9b237SStefano Zampini if (A != B) { 21434f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 21444f1b2e48SStefano Zampini } 21454f1b2e48SStefano Zampini 21464f1b2e48SStefano Zampini /* get back data */ 21471cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 21481cf9b237SStefano Zampini if (cc) { 21494f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 21504f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 21514f1b2e48SStefano 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); 21524f1b2e48SStefano Zampini } 21534f1b2e48SStefano Zampini *cc = cc_n; 21541cf9b237SStefano Zampini } 21554f1b2e48SStefano Zampini /* clean up graph */ 21564f1b2e48SStefano Zampini graph->xadj = 0; 21574f1b2e48SStefano Zampini graph->adjncy = 0; 21584f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 21594f1b2e48SStefano Zampini PetscFunctionReturn(0); 21604f1b2e48SStefano Zampini } 21614f1b2e48SStefano Zampini 21625408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 21635408967cSStefano Zampini { 21645408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 21655408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2166dee84bffSStefano Zampini IS dirIS = NULL; 21674f1b2e48SStefano Zampini PetscInt i; 21685408967cSStefano Zampini PetscErrorCode ierr; 21695408967cSStefano Zampini 21705408967cSStefano Zampini PetscFunctionBegin; 2171dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 21725408967cSStefano Zampini if (zerodiag) { 21735408967cSStefano Zampini Mat A; 21745408967cSStefano Zampini Vec vec3_N; 21755408967cSStefano Zampini PetscScalar *vals; 21765408967cSStefano Zampini const PetscInt *idxs; 2177d12d3064SStefano Zampini PetscInt nz,*count; 21785408967cSStefano Zampini 21795408967cSStefano Zampini /* p0 */ 21805408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 21815408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 21825408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 21835408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 21844f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 21855408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 21865408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 21875408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 21885408967cSStefano Zampini /* v_I */ 21895408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 21905408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 21915408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 21925408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 21935408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 21945408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 21955408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 21965408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 21975408967cSStefano Zampini if (dirIS) { 21985408967cSStefano Zampini PetscInt n; 21995408967cSStefano Zampini 22005408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 22015408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 22025408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 22035408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 22045408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 22055408967cSStefano Zampini } 22065408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 22075408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 22085408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 22095408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2210669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 22115408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 22125408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 22139a962809SStefano 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])); 22145408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 22155408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2216d12d3064SStefano Zampini 2217d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 2218d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 2219d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2220d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 2221d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2222d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 22239a962809SStefano 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]); 2224d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2225d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 22265408967cSStefano Zampini } 2227dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 22285408967cSStefano Zampini 22295408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 22305408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 22314f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 22325408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 22334f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 22345408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2235f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2236f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 2237f2a566d8SStefano 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); 2238f2a566d8SStefano Zampini } 22395408967cSStefano Zampini PetscFunctionReturn(0); 22405408967cSStefano Zampini } 22415408967cSStefano Zampini 2242339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 2243339f8db1SStefano Zampini { 2244339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 22454edc6404Sstefano_zampini IS pressures,zerodiag,zerodiag_save,*zerodiag_subs; 2246b0f5fe93SStefano Zampini PetscInt nz,n; 22474edc6404Sstefano_zampini PetscInt *interior_dofs,n_interior_dofs,nneu; 22484edc6404Sstefano_zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag,checkb; 2249339f8db1SStefano Zampini PetscErrorCode ierr; 2250339f8db1SStefano Zampini 2251339f8db1SStefano Zampini PetscFunctionBegin; 22529f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 22539f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 2254a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 2255a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 2256a3df083aSStefano Zampini } 2257a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2258a3df083aSStefano Zampini pcbddc->benign_n = 0; 225928b8efb1Sstefano_zampini 226028b8efb1Sstefano_zampini /* if a local info on dofs is present, uses the last field for "pressures" (or fid by command line) 22614f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 22624f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 22634f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 22641ae86dd6SStefano Zampini since the local Schur complements are already SPD 22654f1b2e48SStefano Zampini */ 22664f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 22674f1b2e48SStefano Zampini have_null = PETSC_TRUE; 226840fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 22697fbe2174Sstefano_zampini IS iP = NULL; 22704f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 22714f1b2e48SStefano Zampini 227228b8efb1Sstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC benign options","PC");CHKERRQ(ierr); 227328b8efb1Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_pressure_field","Field id for pressures",NULL,p,&p,NULL);CHKERRQ(ierr); 227428b8efb1Sstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 227528b8efb1Sstefano_zampini if (p < 0 || p > pcbddc->n_ISForDofsLocal-1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Invalid field id for pressures %D",p); 22764f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 22774f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 22784f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 22794f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 2280ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 22817fbe2174Sstefano_zampini /* remove zeroed out pressures if we are setting up a BDDC solver for a saddle-point FETI-DP */ 22827fbe2174Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP",(PetscObject*)&iP);CHKERRQ(ierr); 22837fbe2174Sstefano_zampini if (iP) { 22847fbe2174Sstefano_zampini IS newpressures; 22857fbe2174Sstefano_zampini 22867fbe2174Sstefano_zampini ierr = ISDifference(pressures,iP,&newpressures);CHKERRQ(ierr); 22877fbe2174Sstefano_zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 22887fbe2174Sstefano_zampini pressures = newpressures; 22897fbe2174Sstefano_zampini } 229040fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 229140fa8d13SStefano Zampini if (!sorted) { 229240fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 229340fa8d13SStefano Zampini } 229440fa8d13SStefano Zampini } else { 229540fa8d13SStefano Zampini pressures = NULL; 229640fa8d13SStefano Zampini } 229797d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 229897d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 229927b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 230097d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 2301339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 2302339f8db1SStefano Zampini if (!sorted) { 2303339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 2304339f8db1SStefano Zampini } 23054edc6404Sstefano_zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 23064edc6404Sstefano_zampini zerodiag_save = zerodiag; 2307339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 23084f1b2e48SStefano Zampini if (!nz) { 23094f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 23104f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 231140fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 231240fa8d13SStefano Zampini } 23134f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 23144f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 23154f1b2e48SStefano Zampini zerodiag_subs = NULL; 23164f1b2e48SStefano Zampini pcbddc->benign_n = 0; 23171f4df5f7SStefano Zampini n_interior_dofs = 0; 23181f4df5f7SStefano Zampini interior_dofs = NULL; 23194edc6404Sstefano_zampini nneu = 0; 23204edc6404Sstefano_zampini if (pcbddc->NeumannBoundariesLocal) { 23214edc6404Sstefano_zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nneu);CHKERRQ(ierr); 23224edc6404Sstefano_zampini } 23233369cb78Sstefano_zampini checkb = (PetscBool)(!pcbddc->NeumannBoundariesLocal || pcbddc->current_level); 23244edc6404Sstefano_zampini if (checkb) { /* need to compute interior nodes */ 23251f4df5f7SStefano Zampini PetscInt n,i,j; 23261f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 23271f4df5f7SStefano Zampini PetscInt *iwork; 23281f4df5f7SStefano Zampini 23291f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 23301f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 23311f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 23321f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 233390648384SStefano Zampini for (i=1;i<n_neigh;i++) 23341f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 23351f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 23361f4df5f7SStefano Zampini for (i=0;i<n;i++) 23371f4df5f7SStefano Zampini if (!iwork[i]) 23381f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 23391f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 23401f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 23411f4df5f7SStefano Zampini } 23424f1b2e48SStefano Zampini if (has_null_pressures) { 23434f1b2e48SStefano Zampini IS *subs; 23444edc6404Sstefano_zampini PetscInt nsubs,i,j,nl; 23451f4df5f7SStefano Zampini const PetscInt *idxs; 23461f4df5f7SStefano Zampini PetscScalar *array; 23471f4df5f7SStefano Zampini Vec *work; 23481f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 23494f1b2e48SStefano Zampini 23504f1b2e48SStefano Zampini subs = pcbddc->local_subs; 23514f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 23521f4df5f7SStefano 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) */ 23534edc6404Sstefano_zampini if (checkb) { 23541f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 23551f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 23561f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 23571f4df5f7SStefano Zampini /* work[0] = 1_p */ 23581f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 23591f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 23601f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 23611f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 23621f4df5f7SStefano Zampini /* work[0] = 1_v */ 23631f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 23641f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 23651f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 23661f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 23671f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 23681f4df5f7SStefano Zampini } 23694f1b2e48SStefano Zampini if (nsubs > 1) { 23704f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 23714f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 23724f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 23734f1b2e48SStefano Zampini IS t_zerodiag_subs; 23744f1b2e48SStefano Zampini PetscInt nl; 23754f1b2e48SStefano Zampini 23764f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 23774f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 23784f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 23794f1b2e48SStefano Zampini if (nl) { 23804f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 23814f1b2e48SStefano Zampini 23824edc6404Sstefano_zampini if (checkb) { 23831f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 23841f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 23851f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 23861f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 23871f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 23881f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 23891f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 23901f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 23911f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 23921f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 23931f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 23941f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 23951f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 23961f4df5f7SStefano Zampini valid = PETSC_FALSE; 23971f4df5f7SStefano Zampini break; 23981f4df5f7SStefano Zampini } 23991f4df5f7SStefano Zampini } 24001f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 24011f4df5f7SStefano Zampini } 24026632bad2Sstefano_zampini if (valid && nneu) { 24036632bad2Sstefano_zampini const PetscInt *idxs; 24041f4df5f7SStefano Zampini PetscInt nzb; 24051f4df5f7SStefano Zampini 24066632bad2Sstefano_zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 24076632bad2Sstefano_zampini ierr = ISGlobalToLocalMappingApply(l2g,IS_GTOLM_DROP,nneu,idxs,&nzb,NULL);CHKERRQ(ierr); 24086632bad2Sstefano_zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 24091f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 24101f4df5f7SStefano Zampini } 24111f4df5f7SStefano Zampini if (valid && pressures) { 24124f1b2e48SStefano Zampini IS t_pressure_subs; 24134f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 24144f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 24154f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 24164f1b2e48SStefano Zampini } 24174f1b2e48SStefano Zampini if (valid) { 24184f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 24194f1b2e48SStefano Zampini pcbddc->benign_n++; 24204f1b2e48SStefano Zampini } else { 24214f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 24224f1b2e48SStefano Zampini } 24234f1b2e48SStefano Zampini } 24244f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 24254f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 24264f1b2e48SStefano Zampini } 24274f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 24284f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 24291f4df5f7SStefano Zampini 24306632bad2Sstefano_zampini if (nneu) valid = PETSC_FALSE; 24311f4df5f7SStefano Zampini if (valid && pressures) { 24324f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 24334f1b2e48SStefano Zampini } 24344edc6404Sstefano_zampini if (valid && checkb) { 24351f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 24361f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 24371f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 24381f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 24391f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 24401f4df5f7SStefano Zampini valid = PETSC_FALSE; 24411f4df5f7SStefano Zampini break; 24421f4df5f7SStefano Zampini } 24431f4df5f7SStefano Zampini } 24441f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 24451f4df5f7SStefano Zampini } 24464f1b2e48SStefano Zampini if (valid) { 24474f1b2e48SStefano Zampini pcbddc->benign_n = 1; 2448ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 24494f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 24504f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 24514f1b2e48SStefano Zampini } 24524f1b2e48SStefano Zampini } 24534edc6404Sstefano_zampini if (checkb) { 24541f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 24554f1b2e48SStefano Zampini } 24561f4df5f7SStefano Zampini } 24571f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 24584f1b2e48SStefano Zampini 24594f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2460b9b0e38cSStefano Zampini PetscInt n; 2461b9b0e38cSStefano Zampini 24624f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 24634f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2464b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 2465b9b0e38cSStefano Zampini if (n) { 24664f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 24674f1b2e48SStefano Zampini have_null = PETSC_FALSE; 24684f1b2e48SStefano Zampini } 2469b9b0e38cSStefano Zampini } 24704f1b2e48SStefano Zampini 24714f1b2e48SStefano Zampini /* final check for null pressures */ 24724f1b2e48SStefano Zampini if (zerodiag && pressures) { 24734f1b2e48SStefano Zampini PetscInt nz,np; 24744f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 24754f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 24764f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 24774f1b2e48SStefano Zampini } 24784f1b2e48SStefano Zampini 24794f1b2e48SStefano Zampini if (recompute_zerodiag) { 24804f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 24814f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 24824f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 24834f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 24844f1b2e48SStefano Zampini } else { 24854f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 24864f1b2e48SStefano Zampini 24874f1b2e48SStefano Zampini nzn = 0; 24884f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 24894f1b2e48SStefano Zampini PetscInt ns; 24904f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 24914f1b2e48SStefano Zampini nzn += ns; 24924f1b2e48SStefano Zampini } 24934f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 24944f1b2e48SStefano Zampini nzn = 0; 24954f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 24964f1b2e48SStefano Zampini PetscInt ns,*idxs; 24974f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 24984f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 24994f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 25004f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 25014f1b2e48SStefano Zampini nzn += ns; 25024f1b2e48SStefano Zampini } 25034f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 25044f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 25054f1b2e48SStefano Zampini } 25064f1b2e48SStefano Zampini have_null = PETSC_FALSE; 25074f1b2e48SStefano Zampini } 25084f1b2e48SStefano Zampini 2509669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2510a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2511a198735bSStefano Zampini Mat A,loc_divudotp; 2512a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2513a198735bSStefano Zampini IS row,col,isused = NULL; 2514a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2515a198735bSStefano Zampini 25161f4df5f7SStefano Zampini if (pressures) { 25171f4df5f7SStefano Zampini isused = pressures; 25181f4df5f7SStefano Zampini } else { 25194edc6404Sstefano_zampini isused = zerodiag_save; 25201f4df5f7SStefano Zampini } 2521a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2522669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 25231ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 25241ae86dd6SStefano 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"); 2525a198735bSStefano Zampini n_isused = 0; 2526a198735bSStefano Zampini if (isused) { 2527a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2528a198735bSStefano Zampini } 2529a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2530a198735bSStefano Zampini st = st-n_isused; 25311ae86dd6SStefano Zampini if (n) { 2532a198735bSStefano Zampini const PetscInt *gidxs; 2533a198735bSStefano Zampini 25347dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2535a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2536a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2537a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2538a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2539a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 25401ae86dd6SStefano Zampini } else { 2541a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2542a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2543a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2544a198735bSStefano Zampini } 2545a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2546a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2547a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2548a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2549a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2550a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2551a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2552a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2553a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2554a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2555a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2556a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2557a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2558a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 25591ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 25601ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 25611ae86dd6SStefano Zampini } 25624edc6404Sstefano_zampini ierr = ISDestroy(&zerodiag_save);CHKERRQ(ierr); 2563b3afcdbeSStefano Zampini 2564b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 25654f1b2e48SStefano Zampini if (has_null_pressures) { 25664f1b2e48SStefano Zampini IS zerodiagc; 25674f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 25684f1b2e48SStefano Zampini PetscInt i,s,*nnz; 25694f1b2e48SStefano Zampini 25704f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2571339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 2572339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 2573339f8db1SStefano Zampini /* local change of basis for pressures */ 2574339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 257597d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2576339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2577339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2578339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 25794f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 25804f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 25814f1b2e48SStefano Zampini PetscInt nzs,j; 25824f1b2e48SStefano Zampini 25834f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 25844f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 25854f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 25864f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 25874f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 25884f1b2e48SStefano Zampini } 2589339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2590339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2591339f8db1SStefano Zampini /* set identity on velocities */ 2592339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 2593339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 2594339f8db1SStefano Zampini } 25954f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 25964f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 25979f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 25984f1b2e48SStefano 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); 2599339f8db1SStefano Zampini /* set change on pressures */ 26004f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 26014f1b2e48SStefano Zampini PetscScalar *array; 26024f1b2e48SStefano Zampini PetscInt nzs; 26034f1b2e48SStefano Zampini 26044f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 26054f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 26064f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2607339f8db1SStefano Zampini PetscScalar vals[2]; 2608339f8db1SStefano Zampini PetscInt cols[2]; 2609339f8db1SStefano Zampini 2610339f8db1SStefano Zampini cols[0] = idxs[i]; 26114f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2612339f8db1SStefano Zampini vals[0] = 1.; 2613b0f5fe93SStefano Zampini vals[1] = 1.; 26144f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2615339f8db1SStefano Zampini } 26164f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 26174f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 26184f1b2e48SStefano Zampini array[nzs-1] = 1.; 26194f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 26204f1b2e48SStefano Zampini /* store local idxs for p0 */ 26214f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 26224f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2623339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 26244f1b2e48SStefano Zampini } 2625339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2626339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2627a3df083aSStefano Zampini /* project if needed */ 2628a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 26291dd7afcfSStefano Zampini Mat M; 26301dd7afcfSStefano Zampini 26311dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2632339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 26331dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 26341dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2635a3df083aSStefano Zampini } 26364f1b2e48SStefano Zampini /* store global idxs for p0 */ 26374f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2638339f8db1SStefano Zampini } 2639ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 26404f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 2641b0f5fe93SStefano Zampini 2642b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 2643b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 264427b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 264527b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2646339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2647339f8db1SStefano Zampini PetscFunctionReturn(0); 2648339f8db1SStefano Zampini } 2649339f8db1SStefano Zampini 2650015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2651efc2fbd9SStefano Zampini { 2652efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2653de9d7bd0SStefano Zampini PetscScalar *array; 2654efc2fbd9SStefano Zampini PetscErrorCode ierr; 2655efc2fbd9SStefano Zampini 2656efc2fbd9SStefano Zampini PetscFunctionBegin; 2657efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 2658efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 26594f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2660efc2fbd9SStefano Zampini } 2661de9d7bd0SStefano Zampini if (get) { 2662efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 26634f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 26644f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 2665efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 2666de9d7bd0SStefano Zampini } else { 2667de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 2668de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2669de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2670de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 2671efc2fbd9SStefano Zampini } 2672efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2673efc2fbd9SStefano Zampini } 2674efc2fbd9SStefano Zampini 2675c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 2676c263805aSStefano Zampini { 2677c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2678c263805aSStefano Zampini PetscErrorCode ierr; 2679c263805aSStefano Zampini 2680c263805aSStefano Zampini PetscFunctionBegin; 2681c263805aSStefano Zampini /* TODO: add error checking 2682c263805aSStefano Zampini - avoid nested pop (or push) calls. 2683c263805aSStefano Zampini - cannot push before pop. 26841c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2685c263805aSStefano Zampini */ 26864f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2687efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2688efc2fbd9SStefano Zampini } 2689c263805aSStefano Zampini if (pop) { 2690a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 26914f1b2e48SStefano Zampini IS is_p0; 26924f1b2e48SStefano Zampini MatReuse reuse; 2693c263805aSStefano Zampini 2694c263805aSStefano Zampini /* extract B_0 */ 26954f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 26964f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 26974f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 26984f1b2e48SStefano Zampini } 26994f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 27007dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2701c263805aSStefano Zampini /* remove rows and cols from local problem */ 2702c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 270397d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 27044f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 27054f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2706a3df083aSStefano Zampini } else { 2707a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2708a3df083aSStefano Zampini PetscScalar *vals; 2709a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2710a3df083aSStefano Zampini 2711a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2712a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2713a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 27140b5adadeSStefano Zampini PetscInt *nnz; 2715a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2716a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2717a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2718331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2719331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2720331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2721331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2722331e053bSStefano Zampini } 2723331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2724331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2725331e053bSStefano Zampini } 2726a3df083aSStefano Zampini 2727a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2728a3df083aSStefano Zampini PetscScalar *array; 2729a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2730a3df083aSStefano Zampini 2731a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2732a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2733a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2734a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2735a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2736a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2737a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2738a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2739a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2740a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2741a3df083aSStefano Zampini cum = 0; 2742a3df083aSStefano Zampini for (j=0;j<n;j++) { 274322db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2744a3df083aSStefano Zampini vals[cum] = array[j]; 2745a3df083aSStefano Zampini idxs_ins[cum] = j; 2746a3df083aSStefano Zampini cum++; 2747a3df083aSStefano Zampini } 2748a3df083aSStefano Zampini } 2749a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2750a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2751a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2752a3df083aSStefano Zampini } 2753a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2754a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2755a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2756a3df083aSStefano Zampini } 2757c263805aSStefano Zampini } else { /* push */ 2758a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 27594f1b2e48SStefano Zampini PetscInt i; 27604f1b2e48SStefano Zampini 27614f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 27624f1b2e48SStefano Zampini PetscScalar *B0_vals; 27634f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 27644f1b2e48SStefano Zampini 27654f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 27664f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 27677b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 27684f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 27694f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 27704f1b2e48SStefano Zampini } 2771c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2772c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2773a3df083aSStefano Zampini } else { 2774a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 2775a3df083aSStefano Zampini } 2776c263805aSStefano Zampini } 2777c263805aSStefano Zampini PetscFunctionReturn(0); 2778c263805aSStefano Zampini } 2779c263805aSStefano Zampini 278008122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 2781b1b3d7a2SStefano Zampini { 2782b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 278308122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 278408122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 278508122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 278608122e43SStefano Zampini PetscScalar *work,lwork; 278708122e43SStefano Zampini PetscScalar *St,*S,*eigv; 278808122e43SStefano Zampini PetscScalar *Sarray,*Starray; 278908122e43SStefano Zampini PetscReal *eigs,thresh; 27901b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 2791f6f667cfSStefano Zampini PetscBool allocated_S_St; 279208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 279308122e43SStefano Zampini PetscReal *rwork; 279408122e43SStefano Zampini #endif 2795b1b3d7a2SStefano Zampini PetscErrorCode ierr; 2796b1b3d7a2SStefano Zampini 2797b1b3d7a2SStefano Zampini PetscFunctionBegin; 2798b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 2799af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 2800d750e150Sstefano_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)\nRerun with -sub_schurs_hermitian 1 -sub_schurs_posdef 1 if the problem is SPD",sub_schurs->is_hermitian,sub_schurs->is_posdef); 280106a4e24aSStefano Zampini 2802fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2803fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 2804fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 2805fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 28061575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 2807fd14bc51SStefano Zampini } 2808fd14bc51SStefano Zampini 2809e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 2810e496cd5dSStefano 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); 2811e496cd5dSStefano Zampini } 2812e496cd5dSStefano Zampini 281308122e43SStefano Zampini /* max size of subsets */ 281408122e43SStefano Zampini mss = 0; 281508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 281608122e43SStefano Zampini PetscInt subset_size; 2817862806e4SStefano Zampini 281808122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 281908122e43SStefano Zampini mss = PetscMax(mss,subset_size); 282008122e43SStefano Zampini } 282108122e43SStefano Zampini 282208122e43SStefano Zampini /* min/max and threshold */ 282308122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 2824f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 282508122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 2826f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 2827f6f667cfSStefano Zampini if (nmin) { 2828f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 2829f6f667cfSStefano Zampini } 283008122e43SStefano Zampini 283108122e43SStefano Zampini /* allocate lapack workspace */ 283208122e43SStefano Zampini cum = cum2 = 0; 283308122e43SStefano Zampini maxneigs = 0; 283408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 283508122e43SStefano Zampini PetscInt n,subset_size; 2836f6f667cfSStefano Zampini 283708122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 283808122e43SStefano Zampini n = PetscMin(subset_size,nmax); 28399162d606SStefano Zampini cum += subset_size; 28409162d606SStefano Zampini cum2 += subset_size*n; 284108122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 284208122e43SStefano Zampini } 284308122e43SStefano Zampini if (mss) { 28449ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 284508122e43SStefano Zampini PetscBLASInt B_itype = 1; 284608122e43SStefano Zampini PetscBLASInt B_N = mss; 28474c6709b3SStefano Zampini PetscReal zero = 0.0; 28484c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 284908122e43SStefano Zampini 285008122e43SStefano Zampini B_lwork = -1; 285108122e43SStefano Zampini S = NULL; 285208122e43SStefano Zampini St = NULL; 2853a58a30b4SStefano Zampini eigs = NULL; 2854a58a30b4SStefano Zampini eigv = NULL; 2855a58a30b4SStefano Zampini B_iwork = NULL; 2856a58a30b4SStefano Zampini B_ifail = NULL; 2857d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 2858d1710679SStefano Zampini rwork = NULL; 2859d1710679SStefano Zampini #endif 28608bec7fa6SStefano Zampini thresh = 1.0; 286108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 286208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 286308122e43SStefano 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)); 286408122e43SStefano Zampini #else 286508122e43SStefano 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)); 286608122e43SStefano Zampini #endif 286708122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 286808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 286908122e43SStefano Zampini } else { 287008122e43SStefano Zampini /* TODO */ 287108122e43SStefano Zampini } 287208122e43SStefano Zampini } else { 287308122e43SStefano Zampini lwork = 0; 287408122e43SStefano Zampini } 287508122e43SStefano Zampini 287608122e43SStefano Zampini nv = 0; 2877d62866d3SStefano 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) */ 2878d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 287908122e43SStefano Zampini } 28804c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 2881f6f667cfSStefano Zampini if (allocated_S_St) { 2882f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 2883f6f667cfSStefano Zampini } 2884f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 288508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 288608122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 288708122e43SStefano Zampini #endif 28889162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 28899162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 28909162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 289108122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 28929162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 289308122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 289408122e43SStefano Zampini 289508122e43SStefano Zampini maxneigs = 0; 289672b8c272SStefano Zampini cum = cumarray = 0; 28979162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 28989162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 2899d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 290008122e43SStefano Zampini const PetscInt *idxs; 290108122e43SStefano Zampini 2902d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 290308122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 290408122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 290508122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 290608122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 29079162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 29089162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 290908122e43SStefano Zampini } 2910d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 291108122e43SStefano Zampini } 291208122e43SStefano Zampini 291308122e43SStefano Zampini if (mss) { /* multilevel */ 291408122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 291508122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 291608122e43SStefano Zampini } 291708122e43SStefano Zampini 2918ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 291908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 292008122e43SStefano Zampini const PetscInt *idxs; 29219d54b7f4SStefano Zampini PetscReal upper,lower; 2922862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 292308122e43SStefano Zampini PetscBLASInt B_N; 2924aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 292508122e43SStefano Zampini 29269d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 29279d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 29289d54b7f4SStefano Zampini lower = thresh; 29299d54b7f4SStefano Zampini } else { 29309d54b7f4SStefano Zampini upper = 1./thresh; 29319d54b7f4SStefano Zampini lower = 0.; 29329d54b7f4SStefano Zampini } 2933862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 2934ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 2935f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 2936f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 29379ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 2938aff50787SStefano Zampini PetscInt j,k; 2939aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 2940aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 2941aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 294208122e43SStefano Zampini } 294308122e43SStefano Zampini for (j=0;j<subset_size;j++) { 2944aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 2945aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 2946aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 2947aff50787SStefano Zampini } 294808122e43SStefano Zampini } 294908122e43SStefano Zampini } else { 295008122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 295108122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 295208122e43SStefano Zampini } 29538bec7fa6SStefano Zampini } else { 2954f6f667cfSStefano Zampini S = Sarray + cumarray; 2955f6f667cfSStefano Zampini St = Starray + cumarray; 29568bec7fa6SStefano Zampini } 2957aff50787SStefano Zampini /* see if we can save some work */ 2958b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 2959aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 2960aff50787SStefano Zampini } 2961aff50787SStefano Zampini 2962b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 2963aff50787SStefano Zampini B_neigs = 0; 2964aff50787SStefano Zampini } else { 29659ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 296608122e43SStefano Zampini PetscBLASInt B_itype = 1; 2967f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 29684c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 29699552c7c7SStefano Zampini PetscInt nmin_s; 2970b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 297108122e43SStefano Zampini 2972fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 2973eee23b56SStefano 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]]); 2974fd14bc51SStefano Zampini } 2975d16cbb6bSStefano Zampini 2976b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 2977b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 2978b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 2979b7ab4a40SStefano Zampini } 2980b7ab4a40SStefano Zampini 298108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 2982b7ab4a40SStefano Zampini if (compute_range) { 2983d16cbb6bSStefano Zampini 2984d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 298508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 29869d54b7f4SStefano 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)); 298708122e43SStefano Zampini #else 29889d54b7f4SStefano 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)); 298908122e43SStefano Zampini #endif 2990b7ab4a40SStefano Zampini } else if (!same_data) { 2991d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 2992d16cbb6bSStefano Zampini B_IL = 1; 2993d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 29949d54b7f4SStefano 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)); 2995d16cbb6bSStefano Zampini #else 29969d54b7f4SStefano 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)); 2997d16cbb6bSStefano Zampini #endif 2998b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 2999b7ab4a40SStefano Zampini PetscInt k; 3000b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 3001b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 3002b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 3003b7ab4a40SStefano Zampini nmin = nmax; 3004b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 3005b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 3006b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 3007b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 3008b7ab4a40SStefano Zampini } 3009d16cbb6bSStefano Zampini } 301008122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 301108122e43SStefano Zampini if (B_ierr) { 30126c4ed002SBarry 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); 30136c4ed002SBarry 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); 30146c4ed002SBarry 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); 301508122e43SStefano Zampini } 301608122e43SStefano Zampini 301708122e43SStefano Zampini if (B_neigs > nmax) { 3018fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3019fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 3020fd14bc51SStefano Zampini } 30219d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 302208122e43SStefano Zampini B_neigs = nmax; 302308122e43SStefano Zampini } 302408122e43SStefano Zampini 30259552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 30269552c7c7SStefano Zampini if (B_neigs < nmin_s) { 302708122e43SStefano Zampini PetscBLASInt B_neigs2; 302808122e43SStefano Zampini 30299d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3030f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 30319d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 30329d54b7f4SStefano Zampini } else { 30339d54b7f4SStefano Zampini B_IL = B_neigs + 1; 30349d54b7f4SStefano Zampini B_IU = nmin_s; 30359d54b7f4SStefano Zampini } 3036fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3037fd14bc51SStefano 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); 3038fd14bc51SStefano Zampini } 30399ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 30401ae86dd6SStefano Zampini PetscInt j,k; 304108122e43SStefano Zampini for (j=0;j<subset_size;j++) { 30421ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 30431ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 30441ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 304508122e43SStefano Zampini } 304608122e43SStefano Zampini } 304708122e43SStefano Zampini } else { 304808122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 304908122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 305008122e43SStefano Zampini } 305108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 305208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 30539d54b7f4SStefano 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)); 305408122e43SStefano Zampini #else 30559d54b7f4SStefano 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)); 305608122e43SStefano Zampini #endif 305708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 305808122e43SStefano Zampini B_neigs += B_neigs2; 305908122e43SStefano Zampini } 306008122e43SStefano Zampini if (B_ierr) { 30616c4ed002SBarry 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); 30626c4ed002SBarry 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); 30636c4ed002SBarry 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); 306408122e43SStefano Zampini } 3065fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3066ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 306708122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 306808122e43SStefano Zampini if (eigs[j] == 0.0) { 3069ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 307008122e43SStefano Zampini } else { 30719d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3072ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 30739d54b7f4SStefano Zampini } else { 30749d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 30759d54b7f4SStefano Zampini } 3076fd14bc51SStefano Zampini } 307708122e43SStefano Zampini } 307808122e43SStefano Zampini } 307908122e43SStefano Zampini } else { 308008122e43SStefano Zampini /* TODO */ 308108122e43SStefano Zampini } 3082aff50787SStefano Zampini } 30836c3e6151SStefano Zampini /* change the basis back to the original one */ 30846c3e6151SStefano Zampini if (sub_schurs->change) { 308572b8c272SStefano Zampini Mat change,phi,phit; 30866c3e6151SStefano Zampini 30876c3e6151SStefano Zampini if (pcbddc->dbg_flag > 1) { 30886c3e6151SStefano Zampini PetscInt ii; 30896c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 30906c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 30916c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 3092684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3093684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 3094684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 3095684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3096684229deSStefano Zampini #else 30976c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 3098684229deSStefano Zampini #endif 30996c3e6151SStefano Zampini } 31006c3e6151SStefano Zampini } 31016c3e6151SStefano Zampini } 310272b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 31036c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 310472b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 31056c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 31066c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 31076c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 31086c3e6151SStefano Zampini } 31098bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 31108bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 31119162d606SStefano Zampini if (B_neigs) { 31129162d606SStefano 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); 3113fd14bc51SStefano Zampini 3114fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 31159552c7c7SStefano Zampini PetscInt ii; 31169552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 3117ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 31189552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 3119ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3120ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3121ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3122ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3123ac47001eSStefano Zampini #else 3124ac47001eSStefano 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); 3125ac47001eSStefano Zampini #endif 31269552c7c7SStefano Zampini } 31279552c7c7SStefano Zampini } 3128fd14bc51SStefano Zampini } 31299162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 31309162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 31319162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 31329162d606SStefano Zampini cum++; 313308122e43SStefano Zampini } 313408122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 313508122e43SStefano Zampini /* shift for next computation */ 313608122e43SStefano Zampini cumarray += subset_size*subset_size; 313708122e43SStefano Zampini } 3138fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3139fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3140fd14bc51SStefano Zampini } 314108122e43SStefano Zampini 314208122e43SStefano Zampini if (mss) { 314308122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 314408122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 3145f6f667cfSStefano Zampini /* destroy matrices (junk) */ 3146f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 3147f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 314808122e43SStefano Zampini } 3149f6f667cfSStefano Zampini if (allocated_S_St) { 3150f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 3151f6f667cfSStefano Zampini } 3152f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 315308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 315408122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 315508122e43SStefano Zampini #endif 315608122e43SStefano Zampini if (pcbddc->dbg_flag) { 31571b968477SStefano Zampini PetscInt maxneigs_r; 3158b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 31599b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 316008122e43SStefano Zampini } 316108122e43SStefano Zampini PetscFunctionReturn(0); 316208122e43SStefano Zampini } 3163b1b3d7a2SStefano Zampini 3164c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 3165c8587f34SStefano Zampini { 31668629588bSStefano Zampini PetscScalar *coarse_submat_vals; 3167c8587f34SStefano Zampini PetscErrorCode ierr; 3168c8587f34SStefano Zampini 3169c8587f34SStefano Zampini PetscFunctionBegin; 3170f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 31715e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3172c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3173c8587f34SStefano Zampini 3174684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 31750fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3176684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3177c8587f34SStefano Zampini 31788629588bSStefano Zampini /* 31798629588bSStefano Zampini Setup local correction and local part of coarse basis. 31808629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 31818629588bSStefano Zampini */ 318247f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 31838629588bSStefano Zampini 31848629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 31858629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 31868629588bSStefano Zampini 31878629588bSStefano Zampini /* free */ 31888629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3189c8587f34SStefano Zampini PetscFunctionReturn(0); 3190c8587f34SStefano Zampini } 3191c8587f34SStefano Zampini 3192674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3193674ae819SStefano Zampini { 3194674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3195674ae819SStefano Zampini PetscErrorCode ierr; 3196674ae819SStefano Zampini 3197674ae819SStefano Zampini PetscFunctionBegin; 3198674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 319930368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3200674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3201785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3202674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3203f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3204f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3205785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 320663602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 320763602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3208674ae819SStefano Zampini PetscFunctionReturn(0); 3209674ae819SStefano Zampini } 3210674ae819SStefano Zampini 3211674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3212674ae819SStefano Zampini { 3213674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 32144f1b2e48SStefano Zampini PetscInt i; 3215674ae819SStefano Zampini PetscErrorCode ierr; 3216674ae819SStefano Zampini 3217674ae819SStefano Zampini PetscFunctionBegin; 32181e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 32191e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3220a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3221b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3222674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 322316909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 32241dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3225674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3226669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3227fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 32289326c5c6Sstefano_zampini ierr = PCBDDCGraphDestroy(&pcbddc->mat_graph);CHKERRQ(ierr); 32294f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 32304f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 32314f1b2e48SStefano Zampini } 3232e68a0315Sstefano_zampini pcbddc->n_local_subs = 0; 32334f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3234e68a0315Sstefano_zampini ierr = PCBDDCSubSchursDestroy(&pcbddc->sub_schurs);CHKERRQ(ierr); 3235c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 32368af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 3237674ae819SStefano Zampini PetscFunctionReturn(0); 3238674ae819SStefano Zampini } 3239674ae819SStefano Zampini 3240674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3241674ae819SStefano Zampini { 3242674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3243674ae819SStefano Zampini PetscErrorCode ierr; 3244674ae819SStefano Zampini 3245674ae819SStefano Zampini PetscFunctionBegin; 3246674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 324758da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3248ca92afb2SStefano Zampini PetscScalar *array; 324906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 325006656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 325158da7f69SStefano Zampini } 3252674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3253674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 325415aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 325515aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3256674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3257674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3258674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 325906656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3260674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3261674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 32628ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3263674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3264674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3265674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 32669326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_D);CHKERRQ(ierr); 32679326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 32689326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3269f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3270727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 32710e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3272f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 327370cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 327481d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 32750369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 32761dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 32774f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 32788b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3279ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3280ca92afb2SStefano Zampini PetscInt i; 3281ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3282ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3283ca92afb2SStefano Zampini } 3284ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3285ca92afb2SStefano Zampini } 32864f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3287674ae819SStefano Zampini PetscFunctionReturn(0); 3288674ae819SStefano Zampini } 3289674ae819SStefano Zampini 3290f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 32916bfb1811SStefano Zampini { 32926bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 32936bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 32946bfb1811SStefano Zampini VecType impVecType; 32954f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 32966bfb1811SStefano Zampini PetscErrorCode ierr; 32976bfb1811SStefano Zampini 32986bfb1811SStefano Zampini PetscFunctionBegin; 32994f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3300b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 33016bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3302e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3303e7b262bdSStefano Zampini /* R nodes */ 3304e7b262bdSStefano Zampini old_size = -1; 3305e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3306e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3307e7b262bdSStefano Zampini } 3308e7b262bdSStefano Zampini if (n_R != old_size) { 3309e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3310e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 33116bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 33126bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 33136bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 33146bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3315e7b262bdSStefano Zampini } 3316e7b262bdSStefano Zampini /* local primal dofs */ 3317e7b262bdSStefano Zampini old_size = -1; 3318e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3319e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3320e7b262bdSStefano Zampini } 3321e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3322e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 332383b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3324e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 33256bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3326e7b262bdSStefano Zampini } 3327e7b262bdSStefano Zampini /* local explicit constraints */ 3328e7b262bdSStefano Zampini old_size = -1; 3329e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3330e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3331e7b262bdSStefano Zampini } 3332e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3333e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 333483b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 333583b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 333683b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 333783b7ccabSStefano Zampini } 33386bfb1811SStefano Zampini PetscFunctionReturn(0); 33396bfb1811SStefano Zampini } 33406bfb1811SStefano Zampini 334147f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 334288ebb749SStefano Zampini { 334325084f0cSStefano Zampini PetscErrorCode ierr; 334425084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 334588ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 334688ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3347d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 334825084f0cSStefano Zampini /* submatrices of local problem */ 334980677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 335006656605SStefano Zampini /* submatrices of local coarse problem */ 335106656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 335225084f0cSStefano Zampini /* working matrices */ 335306656605SStefano Zampini Mat C_CR; 335425084f0cSStefano Zampini /* additional working stuff */ 335506656605SStefano Zampini PC pc_R; 3356c58f9fdbSStefano Zampini Mat F,Brhs = NULL; 33575cbda25cSStefano Zampini Vec dummy_vec; 3358c58f9fdbSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction,sparserhs; 335925084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 336006656605SStefano Zampini PetscScalar *work; 336106656605SStefano Zampini PetscInt *idx_V_B; 3362ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 336306656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 3364ffd830a3SStefano Zampini 336525084f0cSStefano Zampini /* some shortcuts to scalars */ 336606656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 336788ebb749SStefano Zampini 336888ebb749SStefano Zampini PetscFunctionBegin; 33699a962809SStefano 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"); 3370ffd830a3SStefano Zampini 3371ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3372b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 33734f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3374b371cd4fSStefano Zampini n_B = pcis->n_B; 3375b371cd4fSStefano Zampini n_D = pcis->n - n_B; 337688ebb749SStefano Zampini n_R = pcis->n - n_vertices; 337788ebb749SStefano Zampini 337888ebb749SStefano Zampini /* vertices in boundary numbering */ 3379785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 33800e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 33816c4ed002SBarry 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); 338288ebb749SStefano Zampini 338306656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3384019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 338506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 338606656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 338706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 338806656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 338906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 339006656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 339106656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 339206656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 339306656605SStefano Zampini 339406656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 339506656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 339606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 339706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 339806656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 3399ffd830a3SStefano Zampini lda_rhs = n_R; 3400a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 340106656605SStefano Zampini if (isLU || isILU || isCHOL) { 340206656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 3403b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 3404df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3405d62866d3SStefano Zampini MatFactorType type; 3406d62866d3SStefano Zampini 3407df4d28bfSStefano Zampini F = reuse_solver->F; 34086816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 3409d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 3410ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 341122db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 341206656605SStefano Zampini } else { 341306656605SStefano Zampini F = NULL; 341406656605SStefano Zampini } 341506656605SStefano Zampini 3416c58f9fdbSStefano Zampini /* determine if we can use a sparse right-hand side */ 3417c58f9fdbSStefano Zampini sparserhs = PETSC_FALSE; 3418c58f9fdbSStefano Zampini if (F) { 3419c58f9fdbSStefano Zampini const MatSolverPackage solver; 3420c58f9fdbSStefano Zampini 3421c58f9fdbSStefano Zampini ierr = MatFactorGetSolverPackage(F,&solver);CHKERRQ(ierr); 3422c58f9fdbSStefano Zampini ierr = PetscStrcmp(solver,MATSOLVERMUMPS,&sparserhs);CHKERRQ(ierr); 3423c58f9fdbSStefano Zampini } 3424c58f9fdbSStefano Zampini 3425ffd830a3SStefano Zampini /* allocate workspace */ 3426ffd830a3SStefano Zampini n = 0; 3427ffd830a3SStefano Zampini if (n_constraints) { 3428ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3429ffd830a3SStefano Zampini } 3430ffd830a3SStefano Zampini if (n_vertices) { 3431ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3432ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3433ffd830a3SStefano Zampini } 34342a3a6641Sstefano_zampini if (!pcbddc->symmetric_primal) { 34352a3a6641Sstefano_zampini n = PetscMax(2*lda_rhs*pcbddc->local_primal_size,n); 34362a3a6641Sstefano_zampini } 3437ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3438ffd830a3SStefano Zampini 34395cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 34405cbda25cSStefano Zampini dummy_vec = NULL; 34415cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 34425cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 34435cbda25cSStefano Zampini } 34445cbda25cSStefano Zampini 344588ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 344688ebb749SStefano Zampini if (n_constraints) { 344772b8c272SStefano Zampini Mat M1,M2,M3,C_B; 344806656605SStefano Zampini IS is_aux; 344980677318SStefano Zampini PetscScalar *array,*array2; 345006656605SStefano Zampini 3451f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 345280677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 345388ebb749SStefano Zampini 345425084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 345525084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 34567dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 34577dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 345888ebb749SStefano Zampini 345980677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 346080677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 3461c58f9fdbSStefano Zampini if (!sparserhs) { 3462ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 346388ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 346406656605SStefano Zampini const PetscScalar *row_cmat_values; 346506656605SStefano Zampini const PetscInt *row_cmat_indices; 346606656605SStefano Zampini PetscInt size_of_constraint,j; 346788ebb749SStefano Zampini 346806656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 346906656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 3470ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 347106656605SStefano Zampini } 347206656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 347306656605SStefano Zampini } 3474c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&Brhs);CHKERRQ(ierr); 3475c58f9fdbSStefano Zampini } else { 3476c58f9fdbSStefano Zampini Mat tC_CR; 3477c58f9fdbSStefano Zampini 3478c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3479c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 3480c58f9fdbSStefano Zampini PetscScalar *aa; 3481c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 3482c58f9fdbSStefano Zampini PetscBool done; 3483c58f9fdbSStefano Zampini 3484c58f9fdbSStefano Zampini ierr = MatGetRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 3485c58f9fdbSStefano Zampini if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed");CHKERRQ(ierr); 3486c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(C_CR,&aa);CHKERRQ(ierr); 3487c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_constraints,lda_rhs,ii,jj,aa,&tC_CR);CHKERRQ(ierr); 3488c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 3489c58f9fdbSStefano Zampini if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed");CHKERRQ(ierr); 3490c58f9fdbSStefano Zampini } else { 3491c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)C_CR);CHKERRQ(ierr); 3492c58f9fdbSStefano Zampini tC_CR = C_CR; 3493c58f9fdbSStefano Zampini } 3494c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tC_CR,&Brhs);CHKERRQ(ierr); 3495c58f9fdbSStefano Zampini ierr = MatDestroy(&tC_CR);CHKERRQ(ierr); 3496c58f9fdbSStefano Zampini } 3497ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 349806656605SStefano Zampini if (F) { 3499a3df083aSStefano Zampini if (need_benign_correction) { 3500df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3501a3df083aSStefano Zampini 350272b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 350372b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 3504a3df083aSStefano Zampini } 3505c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,local_auxmat2_R);CHKERRQ(ierr); 3506a3df083aSStefano Zampini if (need_benign_correction) { 3507a3df083aSStefano Zampini PetscScalar *marr; 3508df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3509a3df083aSStefano Zampini 3510a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 35115cbda25cSStefano Zampini if (lda_rhs != n_R) { 35125cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 35135cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 35145cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 35155cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 35165cbda25cSStefano Zampini } 35175cbda25cSStefano Zampini } else { 3518a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 3519a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 35205cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3521a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3522a3df083aSStefano Zampini } 35235cbda25cSStefano Zampini } 3524a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 3525a3df083aSStefano Zampini } 352606656605SStefano Zampini } else { 352780677318SStefano Zampini PetscScalar *marr; 352880677318SStefano Zampini 352980677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 353006656605SStefano Zampini for (i=0;i<n_constraints;i++) { 3531ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3532ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 353306656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 353406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 353506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 353606656605SStefano Zampini } 353780677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 353806656605SStefano Zampini } 3539c58f9fdbSStefano Zampini if (sparserhs) { 3540c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3541c58f9fdbSStefano Zampini } 3542c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 354380677318SStefano Zampini if (!pcbddc->switch_static) { 354480677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 354580677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 354680677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 354780677318SStefano Zampini for (i=0;i<n_constraints;i++) { 3548ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 354980677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 355080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 355180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 355280677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 355380677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 355480677318SStefano Zampini } 355580677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 355680677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 355772b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 355880677318SStefano Zampini } else { 3559ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3560ffd830a3SStefano Zampini IS dummy; 3561ffd830a3SStefano Zampini 3562ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 35637dae84e0SHong Zhang ierr = MatCreateSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 3564ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 3565ffd830a3SStefano Zampini } else { 356680677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 356780677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 3568ffd830a3SStefano Zampini } 356925084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 357080677318SStefano Zampini } 357180677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 357280677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 357380677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 357406656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M1);CHKERRQ(ierr); 357506656605SStefano Zampini ierr = MatDuplicate(M3,MAT_DO_NOT_COPY_VALUES,&M2);CHKERRQ(ierr); 357680677318SStefano Zampini if (isCHOL) { 357780677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 357880677318SStefano Zampini } else { 357925084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 358080677318SStefano Zampini } 358180677318SStefano Zampini ierr = VecSet(pcbddc->vec1_C,one);CHKERRQ(ierr); 358206656605SStefano Zampini ierr = MatDiagonalSet(M2,pcbddc->vec1_C,INSERT_VALUES);CHKERRQ(ierr); 358325084f0cSStefano Zampini ierr = MatMatSolve(M3,M2,M1);CHKERRQ(ierr); 358425084f0cSStefano Zampini ierr = MatDestroy(&M2);CHKERRQ(ierr); 358525084f0cSStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 358680677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 358772b8c272SStefano Zampini ierr = MatMatMult(M1,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 358872b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 358906656605SStefano Zampini ierr = MatCopy(M1,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 359006656605SStefano Zampini ierr = MatDestroy(&M1);CHKERRQ(ierr); 3591f4ddd8eeSStefano Zampini } 3592fc227af8SStefano Zampini 3593fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 359488ebb749SStefano Zampini if (n_vertices) { 359506656605SStefano Zampini IS is_aux; 3596c58f9fdbSStefano Zampini PetscBool isseqaij; 35973a50541eSStefano Zampini 3598b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 35996816873aSStefano Zampini IS tis; 36006816873aSStefano Zampini 36016816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 36026816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 36036816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 36046816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 36056816873aSStefano Zampini } else { 36063a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 36076816873aSStefano Zampini } 36087dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 36097dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 3610c58f9fdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 3611c58f9fdbSStefano Zampini if (!isseqaij) { /* MatMatMult(A_VR,A_RRmA_RV) below will raise an error */ 3612c58f9fdbSStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 3613c58f9fdbSStefano Zampini } 36147dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 361525084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 361688ebb749SStefano Zampini } 361788ebb749SStefano Zampini 361888ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 3619f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 362006656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 362106656605SStefano Zampini if (pcbddc->coarse_phi_D) { 362206656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 362306656605SStefano Zampini } 3624f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 362506656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 362606656605SStefano Zampini PetscScalar *marray; 362706656605SStefano Zampini 362806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 362906656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 3630f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3631f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3632f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3633f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3634f4ddd8eeSStefano Zampini } 3635f4ddd8eeSStefano Zampini } 363606656605SStefano Zampini 3637f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 3638a6e023c1Sstefano_zampini PetscScalar *marr; 363988ebb749SStefano Zampini 3640a6e023c1Sstefano_zampini /* memory size */ 364106656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 3642a6e023c1Sstefano_zampini if (pcbddc->switch_static || pcbddc->dbg_flag) n += n_D*pcbddc->local_primal_size; 3643a6e023c1Sstefano_zampini if (!pcbddc->symmetric_primal) n *= 2; 3644a6e023c1Sstefano_zampini ierr = PetscCalloc1(n,&marr);CHKERRQ(ierr); 3645a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3646a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 36478eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3648a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3649a6e023c1Sstefano_zampini marr += n_D*pcbddc->local_primal_size; 365088ebb749SStefano Zampini } 36513301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 3652a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3653a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 36548eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3655a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 365688ebb749SStefano Zampini } 365788ebb749SStefano Zampini } else { 3658c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 3659c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 36601b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3661c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 3662c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 3663c0553b1fSStefano Zampini } 366488ebb749SStefano Zampini } 366506656605SStefano Zampini } 3666019a44ceSStefano Zampini 366706656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 36684f1b2e48SStefano Zampini p0_lidx_I = NULL; 36694f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 3670d12edf2fSStefano Zampini const PetscInt *idxs; 3671d12edf2fSStefano Zampini 3672d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 36734f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 36744f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 36754f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 36764f1b2e48SStefano Zampini } 3677d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 3678d12edf2fSStefano Zampini } 3679d16cbb6bSStefano Zampini 368006656605SStefano Zampini /* vertices */ 368106656605SStefano Zampini if (n_vertices) { 3682c58f9fdbSStefano Zampini PetscBool restoreavr = PETSC_FALSE; 368316f15bc4SStefano Zampini 3684af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 368504708bb6SStefano Zampini 368616f15bc4SStefano Zampini if (n_R) { 368714393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 368806656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 368916f15bc4SStefano Zampini PetscScalar *x,*y; 369006656605SStefano Zampini 369121eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 369214393ed6SStefano Zampini if (need_benign_correction) { 369314393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 369414393ed6SStefano Zampini IS is_p0; 369514393ed6SStefano Zampini PetscInt *idxs_p0,n; 369614393ed6SStefano Zampini 369714393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 369814393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 369914393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 3700af25d912SStefano 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); 370114393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 370214393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 37037dae84e0SHong Zhang ierr = MatCreateSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 370414393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 370514393ed6SStefano Zampini } 370614393ed6SStefano Zampini 3707c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3708c58f9fdbSStefano Zampini if (!sparserhs || need_benign_correction) { 3709ffd830a3SStefano Zampini if (lda_rhs == n_R) { 3710af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3711ffd830a3SStefano Zampini } else { 3712ca92afb2SStefano Zampini PetscScalar *av,*array; 3713ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 3714ca92afb2SStefano Zampini PetscInt n; 3715ca92afb2SStefano Zampini PetscBool flg_row; 3716ffd830a3SStefano Zampini 3717ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 3718ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 37199d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3720ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3721ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 3722ca92afb2SStefano Zampini for (i=0;i<n;i++) { 3723ca92afb2SStefano Zampini PetscInt j; 3724ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 3725ffd830a3SStefano Zampini } 3726ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3727ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3728ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 3729ffd830a3SStefano Zampini } 3730a3df083aSStefano Zampini if (need_benign_correction) { 3731df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3732a3df083aSStefano Zampini PetscScalar *marr; 3733a3df083aSStefano Zampini 3734a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 373514393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 373614393ed6SStefano Zampini 373714393ed6SStefano Zampini | 0 0 0 | (V) 373814393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 373914393ed6SStefano Zampini | 0 0 -1 | (p0) 374014393ed6SStefano Zampini 374114393ed6SStefano Zampini */ 3742df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 374314393ed6SStefano Zampini const PetscScalar *vals; 374414393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 374514393ed6SStefano Zampini PetscInt n,j,nz; 374614393ed6SStefano Zampini 3747df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3748df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 374914393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 375014393ed6SStefano Zampini for (j=0;j<n;j++) { 375114393ed6SStefano Zampini PetscScalar val = vals[j]; 375214393ed6SStefano Zampini PetscInt k,col = idxs[j]; 375314393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 375414393ed6SStefano Zampini } 375514393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3756df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 375714393ed6SStefano Zampini } 375872b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 375972b8c272SStefano Zampini } 3760c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RV);CHKERRQ(ierr); 3761c58f9fdbSStefano Zampini Brhs = A_RV; 3762c58f9fdbSStefano Zampini } else { 3763c58f9fdbSStefano Zampini Mat tA_RVT,A_RVT; 3764c58f9fdbSStefano Zampini 3765c58f9fdbSStefano Zampini if (!pcbddc->symmetric_primal) { 3766c58f9fdbSStefano Zampini ierr = MatTranspose(A_RV,MAT_INITIAL_MATRIX,&A_RVT);CHKERRQ(ierr); 3767c58f9fdbSStefano Zampini } else { 3768c58f9fdbSStefano Zampini restoreavr = PETSC_TRUE; 3769c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 3770c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_VR);CHKERRQ(ierr); 3771c58f9fdbSStefano Zampini A_RVT = A_VR; 3772c58f9fdbSStefano Zampini } 3773c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 3774c58f9fdbSStefano Zampini PetscScalar *aa; 3775c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 3776c58f9fdbSStefano Zampini PetscBool done; 3777c58f9fdbSStefano Zampini 3778c58f9fdbSStefano Zampini ierr = MatGetRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 3779c58f9fdbSStefano Zampini if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed");CHKERRQ(ierr); 3780c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(A_RVT,&aa);CHKERRQ(ierr); 3781c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_vertices,lda_rhs,ii,jj,aa,&tA_RVT);CHKERRQ(ierr); 3782c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 3783c58f9fdbSStefano Zampini if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed");CHKERRQ(ierr); 3784c58f9fdbSStefano Zampini } else { 3785c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RVT);CHKERRQ(ierr); 3786c58f9fdbSStefano Zampini tA_RVT = A_RVT; 3787c58f9fdbSStefano Zampini } 3788c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tA_RVT,&Brhs);CHKERRQ(ierr); 3789c58f9fdbSStefano Zampini ierr = MatDestroy(&tA_RVT);CHKERRQ(ierr); 3790c58f9fdbSStefano Zampini ierr = MatDestroy(&A_RVT);CHKERRQ(ierr); 3791c58f9fdbSStefano Zampini } 379272b8c272SStefano Zampini if (F) { 379314393ed6SStefano Zampini /* need to correct the rhs */ 379472b8c272SStefano Zampini if (need_benign_correction) { 379572b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 379672b8c272SStefano Zampini PetscScalar *marr; 379772b8c272SStefano Zampini 3798c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&marr);CHKERRQ(ierr); 37995cbda25cSStefano Zampini if (lda_rhs != n_R) { 38005cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 38015cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 38025cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 38035cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 38045cbda25cSStefano Zampini } 38055cbda25cSStefano Zampini } else { 3806a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3807a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 38085cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3809a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3810a3df083aSStefano Zampini } 38115cbda25cSStefano Zampini } 3812c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&marr);CHKERRQ(ierr); 3813a3df083aSStefano Zampini } 3814c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,A_RRmA_RV);CHKERRQ(ierr); 3815c58f9fdbSStefano Zampini if (restoreavr) { 3816c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 3817c58f9fdbSStefano Zampini } 381814393ed6SStefano Zampini /* need to correct the solution */ 3819a3df083aSStefano Zampini if (need_benign_correction) { 3820df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3821a3df083aSStefano Zampini PetscScalar *marr; 3822a3df083aSStefano Zampini 3823a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 38245cbda25cSStefano Zampini if (lda_rhs != n_R) { 38255cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 38265cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 38275cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 38285cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 38295cbda25cSStefano Zampini } 38305cbda25cSStefano Zampini } else { 3831a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 3832a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 38335cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3834a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3835a3df083aSStefano Zampini } 38365cbda25cSStefano Zampini } 3837a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 3838a3df083aSStefano Zampini } 383906656605SStefano Zampini } else { 3840c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&y);CHKERRQ(ierr); 384106656605SStefano Zampini for (i=0;i<n_vertices;i++) { 3842ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 3843ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 384406656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 384506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 384606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 384706656605SStefano Zampini } 3848c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&y);CHKERRQ(ierr); 384906656605SStefano Zampini } 385080677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3851c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 3852ffd830a3SStefano Zampini /* S_VV and S_CV */ 385306656605SStefano Zampini if (n_constraints) { 385406656605SStefano Zampini Mat B; 385580677318SStefano Zampini 3856ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 385780677318SStefano Zampini for (i=0;i<n_vertices;i++) { 3858ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3859ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 386080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 386180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 386280677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 386380677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 386480677318SStefano Zampini } 3865ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 386680677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 386780677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 3868ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 386980677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 387006656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 3871ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 3872ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 387306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 387406656605SStefano Zampini } 3875ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3876ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 3877ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3878ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 3879ffd830a3SStefano Zampini } 388006656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 388114393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 388214393ed6SStefano Zampini if (need_benign_correction) { 3883df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 388414393ed6SStefano Zampini PetscScalar *marr,*sums; 388514393ed6SStefano Zampini 388614393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 3887f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 3888df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 388914393ed6SStefano Zampini const PetscScalar *vals; 389014393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 389114393ed6SStefano Zampini PetscInt n,j,nz; 389214393ed6SStefano Zampini 3893df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3894df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 389514393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 389614393ed6SStefano Zampini PetscInt k; 389714393ed6SStefano Zampini sums[j] = 0.; 389814393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 389914393ed6SStefano Zampini } 390014393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 390114393ed6SStefano Zampini for (j=0;j<n;j++) { 390214393ed6SStefano Zampini PetscScalar val = vals[j]; 390314393ed6SStefano Zampini PetscInt k; 390414393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 390514393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 390614393ed6SStefano Zampini } 390714393ed6SStefano Zampini } 390814393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3909df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 391014393ed6SStefano Zampini } 391114393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 3912f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 391314393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 391414393ed6SStefano Zampini } 391580677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 391606656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 391706656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 391806656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 391906656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 392006656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 392106656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 392206656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3923d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 3924019a44ceSStefano Zampini } else { 3925d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 3926d16cbb6bSStefano Zampini } 392721eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 3928d16cbb6bSStefano Zampini 392906656605SStefano Zampini /* coarse basis functions */ 393006656605SStefano Zampini for (i=0;i<n_vertices;i++) { 393116f15bc4SStefano Zampini PetscScalar *y; 393216f15bc4SStefano Zampini 3933ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 393406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 393506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 393606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 393706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 393806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 393906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 394006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 394106656605SStefano Zampini 394206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 39434f1b2e48SStefano Zampini PetscInt j; 39444f1b2e48SStefano Zampini 394506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 394606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 394706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 394806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 394906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 39504f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 395106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 395206656605SStefano Zampini } 395306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 395406656605SStefano Zampini } 395504708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 395604708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 395706656605SStefano Zampini } 39585cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 395906656605SStefano Zampini 396006656605SStefano Zampini if (n_constraints) { 396106656605SStefano Zampini Mat B; 396206656605SStefano Zampini 3963ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 396406656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 396580677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 396606656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 396706656605SStefano Zampini if (n_vertices) { 396880677318SStefano Zampini if (isCHOL) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 396980677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 397080677318SStefano Zampini } else { 397180677318SStefano Zampini Mat S_VCt; 397280677318SStefano Zampini 3973ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3974ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 397572b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 3976ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 3977ffd830a3SStefano Zampini } 397880677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 397980677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 398080677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 398180677318SStefano Zampini } 398206656605SStefano Zampini } 398306656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 398406656605SStefano Zampini /* coarse basis functions */ 398506656605SStefano Zampini for (i=0;i<n_constraints;i++) { 398606656605SStefano Zampini PetscScalar *y; 398706656605SStefano Zampini 3988ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 398906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 399006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 399106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 399206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 399306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 399406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 399506656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 39964f1b2e48SStefano Zampini PetscInt j; 39974f1b2e48SStefano Zampini 399806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 399906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 400006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 400106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 400206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 40034f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 400406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 400506656605SStefano Zampini } 400606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 400706656605SStefano Zampini } 400806656605SStefano Zampini } 400980677318SStefano Zampini if (n_constraints) { 401080677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 401180677318SStefano Zampini } 40124f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 401372b8c272SStefano Zampini 401472b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 401572b8c272SStefano Zampini if (pcbddc->benign_n) { 401672b8c272SStefano Zampini Mat B0_B,B0_BPHI; 401772b8c272SStefano Zampini IS is_dummy; 401872b8c272SStefano Zampini PetscScalar *data; 401972b8c272SStefano Zampini PetscInt j; 402072b8c272SStefano Zampini 402172b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 40227dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 402372b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 402472b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 402586c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 402672b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 402772b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 402872b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 402972b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 403072b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 403172b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 403272b8c272SStefano Zampini } 403372b8c272SStefano Zampini } 403472b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 403572b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 403672b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 403772b8c272SStefano Zampini } 4038019a44ceSStefano Zampini 403906656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 40403301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4041ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 4042ffd830a3SStefano Zampini PetscScalar *marray; 404306656605SStefano Zampini 404406656605SStefano Zampini if (n_constraints) { 4045ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 404606656605SStefano Zampini 4047abc8f43dSstefano_zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 404806656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 4049ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 405016f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 405106656605SStefano Zampini if (n_vertices) { 4052ffd830a3SStefano Zampini Mat S_VCT; 405306656605SStefano Zampini 405406656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 4055ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 405616f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 405706656605SStefano Zampini } 4058ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 40595b782168SStefano Zampini } else { 40605b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 406106656605SStefano Zampini } 406216f15bc4SStefano Zampini if (n_vertices && n_R) { 4063ffd830a3SStefano Zampini PetscScalar *av,*marray; 4064ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 4065ffd830a3SStefano Zampini PetscInt n; 4066ffd830a3SStefano Zampini PetscBool flg_row; 406706656605SStefano Zampini 4068ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 4069af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4070ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4071ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 4072ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4073ffd830a3SStefano Zampini for (i=0;i<n;i++) { 4074ffd830a3SStefano Zampini PetscInt j; 4075ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 4076ffd830a3SStefano Zampini } 4077ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4078ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4079ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 408006656605SStefano Zampini } 408106656605SStefano Zampini 4082ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 4083abc8f43dSstefano_zampini if (n_vertices) { 4084ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4085ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 4086ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 4087ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 408806656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 408906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 409006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 409106656605SStefano Zampini } 4092ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4093abc8f43dSstefano_zampini } 40945b782168SStefano Zampini if (B_C) { 4095ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 4096ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 4097ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 4098ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 4099ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4100ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4101ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 410206656605SStefano Zampini } 4103ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 41045b782168SStefano Zampini } 410506656605SStefano Zampini /* coarse basis functions */ 410606656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 410706656605SStefano Zampini PetscScalar *y; 410806656605SStefano Zampini 4109ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 411006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 411106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 411206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 411306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 411406656605SStefano Zampini if (i<n_vertices) { 411506656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 411606656605SStefano Zampini } 411706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 411806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 411906656605SStefano Zampini 412006656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 412106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 412206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 412306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 412406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 412506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 412606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 412706656605SStefano Zampini } 412806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 412906656605SStefano Zampini } 4130ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 4131ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 413206656605SStefano Zampini } 4133a6e023c1Sstefano_zampini 4134d62866d3SStefano Zampini /* free memory */ 413588ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 413606656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 413706656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 413806656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 413906656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 4140d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4141d62866d3SStefano Zampini if (n_vertices) { 4142d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 4143d62866d3SStefano Zampini } 4144d62866d3SStefano Zampini if (n_constraints) { 4145d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 4146d62866d3SStefano Zampini } 414788ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 414888ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 414988ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 4150d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 415188ebb749SStefano Zampini Mat coarse_sub_mat; 415225084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 415388ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 415488ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 415588ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 41568bec7fa6SStefano Zampini Mat C_B,CPHI; 41578bec7fa6SStefano Zampini IS is_dummy; 41588bec7fa6SStefano Zampini Vec mones; 415988ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 416088ebb749SStefano Zampini PetscReal real_value; 416188ebb749SStefano Zampini 4162a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 4163a3df083aSStefano Zampini Mat A; 4164a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 41657dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 41667dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 41677dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 41687dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4169a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 4170a3df083aSStefano Zampini } else { 417188ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 417288ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 417388ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 417488ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4175a3df083aSStefano Zampini } 417688ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 417788ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 4178ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 417988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 418088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 418188ebb749SStefano Zampini } 418288ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 418388ebb749SStefano Zampini 418425084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 41853301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 418625084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4187ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 418888ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 418988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 419088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 419188ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 419288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 419388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 419488ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 419588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 419688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 419788ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 419888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 419988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 420088ebb749SStefano Zampini } else { 420188ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 420288ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 420388ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 420488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 420588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 420688ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 420788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 420888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 420988ebb749SStefano Zampini } 421088ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 421188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 421288ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 4213511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 42144f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4215fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 4216d12edf2fSStefano Zampini PetscScalar *data,*data2; 42174f1b2e48SStefano Zampini PetscInt j; 4218d12edf2fSStefano Zampini 42194f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 42207dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 4221d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 422286c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 4223d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 4224d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 42254f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 42264f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 4227d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 42284f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 42294f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 42304f1b2e48SStefano Zampini } 4231d12edf2fSStefano Zampini } 4232d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 4233d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 4234d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4235d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4236d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4237d12edf2fSStefano Zampini } 4238d12edf2fSStefano Zampini #if 0 4239d12edf2fSStefano Zampini { 4240d12edf2fSStefano Zampini PetscViewer viewer; 4241d12edf2fSStefano Zampini char filename[256]; 4242ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4243d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4244d12edf2fSStefano Zampini ierr = PetscViewerSetFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4245ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4246ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4247ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4248d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 424972b8c272SStefano Zampini if (save_change) { 425072b8c272SStefano Zampini Mat phi_B; 425172b8c272SStefano Zampini ierr = MatMatMult(save_change,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&phi_B);CHKERRQ(ierr); 425272b8c272SStefano Zampini ierr = PetscObjectSetName((PetscObject)phi_B,"phi_B");CHKERRQ(ierr); 425372b8c272SStefano Zampini ierr = MatView(phi_B,viewer);CHKERRQ(ierr); 425472b8c272SStefano Zampini ierr = MatDestroy(&phi_B);CHKERRQ(ierr); 425572b8c272SStefano Zampini } else { 4256ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4257ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 425872b8c272SStefano Zampini } 4259ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4260ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4261ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4262ffd830a3SStefano Zampini } 4263ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4264ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4265ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4266ffd830a3SStefano Zampini } 426772b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4268ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4269ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4270ffd830a3SStefano Zampini } 4271d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4272d12edf2fSStefano Zampini } 4273d12edf2fSStefano Zampini #endif 427481d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 42758bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 42761575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 427706656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 42788bec7fa6SStefano Zampini 42798bec7fa6SStefano Zampini /* check constraints */ 4280a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 42817dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 42824f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 42838bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4284a00504b5SStefano Zampini } else { 4285a00504b5SStefano Zampini PetscScalar *data; 4286a00504b5SStefano Zampini Mat tmat; 4287a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4288a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4289a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4290a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4291a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4292a00504b5SStefano Zampini } 42938bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 42948bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 42958bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 42968bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4297bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4298ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4299bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4300bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4301bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4302bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4303bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 430488ebb749SStefano Zampini } 43058bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 43068bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 43078bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 43088bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 430925084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 431088ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 431188ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 431288ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 431388ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 431488ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 431588ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 431688ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 431788ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 431888ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 431988ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4320ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 432188ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 432288ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 432388ebb749SStefano Zampini } 432488ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 432588ebb749SStefano Zampini } 43268629588bSStefano Zampini /* get back data */ 43278629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 432888ebb749SStefano Zampini PetscFunctionReturn(0); 432988ebb749SStefano Zampini } 433088ebb749SStefano Zampini 43317dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4332aa0d41d4SStefano Zampini { 4333d65f70fdSStefano Zampini Mat *work_mat; 4334d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4335d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4336c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4337aa0d41d4SStefano Zampini PetscErrorCode ierr; 4338aa0d41d4SStefano Zampini 4339aa0d41d4SStefano Zampini PetscFunctionBegin; 4340d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4341d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4342d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4343d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4344aa0d41d4SStefano Zampini 4345d65f70fdSStefano Zampini if (!rsorted) { 4346906d46d4SStefano Zampini const PetscInt *idxs; 4347906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4348aa0d41d4SStefano Zampini 4349d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4350d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4351d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4352d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4353aa0d41d4SStefano Zampini } 4354d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4355d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4356d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4357d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4358aa0d41d4SStefano Zampini } 4359d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4360d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4361d65f70fdSStefano Zampini } else { 4362d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4363d65f70fdSStefano Zampini isrow_s = isrow; 4364aa0d41d4SStefano Zampini } 4365906d46d4SStefano Zampini 4366d65f70fdSStefano Zampini if (!csorted) { 4367d65f70fdSStefano Zampini if (isrow == iscol) { 4368d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4369d65f70fdSStefano Zampini iscol_s = isrow_s; 4370d65f70fdSStefano Zampini } else { 4371d65f70fdSStefano Zampini const PetscInt *idxs; 4372d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4373906d46d4SStefano Zampini 4374d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4375d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4376d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4377d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4378d65f70fdSStefano Zampini } 4379d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 4380d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 4381d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4382d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 4383d65f70fdSStefano Zampini } 4384d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 4385d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 4386d65f70fdSStefano Zampini } 4387d65f70fdSStefano Zampini } else { 4388d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 4389d65f70fdSStefano Zampini iscol_s = iscol; 4390d65f70fdSStefano Zampini } 4391d65f70fdSStefano Zampini 43927dae84e0SHong Zhang ierr = MatCreateSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4393d65f70fdSStefano Zampini 4394d65f70fdSStefano Zampini if (!rsorted || !csorted) { 4395906d46d4SStefano Zampini Mat new_mat; 4396d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 4397906d46d4SStefano Zampini 4398d65f70fdSStefano Zampini if (!rsorted) { 4399d65f70fdSStefano Zampini PetscInt *idxs_r,i; 4400d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 4401d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4402d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 4403906d46d4SStefano Zampini } 4404d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 4405d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 4406d65f70fdSStefano Zampini } else { 4407d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 4408906d46d4SStefano Zampini } 4409d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 4410d65f70fdSStefano Zampini 4411d65f70fdSStefano Zampini if (!csorted) { 4412d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 4413d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 4414d65f70fdSStefano Zampini is_perm_c = is_perm_r; 4415d65f70fdSStefano Zampini } else { 4416d65f70fdSStefano Zampini PetscInt *idxs_c,i; 4417f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 4418d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 4419d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4420d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 4421d65f70fdSStefano Zampini } 4422d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 4423d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 4424d65f70fdSStefano Zampini } 4425d65f70fdSStefano Zampini } else { 4426d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 4427d65f70fdSStefano Zampini } 4428d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 4429d65f70fdSStefano Zampini 4430d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 4431d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 4432d65f70fdSStefano Zampini work_mat[0] = new_mat; 4433d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 4434d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 4435d65f70fdSStefano Zampini } 4436d65f70fdSStefano Zampini 4437d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 4438d65f70fdSStefano Zampini *B = work_mat[0]; 4439d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 4440d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 4441d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 4442d65f70fdSStefano Zampini PetscFunctionReturn(0); 4443d65f70fdSStefano Zampini } 4444d65f70fdSStefano Zampini 44455e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 4446aa0d41d4SStefano Zampini { 4447aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 44485e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4449022d8d2bSstefano_zampini Mat new_mat,lA; 44505e8657edSStefano Zampini IS is_local,is_global; 4451d65f70fdSStefano Zampini PetscInt local_size; 4452d65f70fdSStefano Zampini PetscBool isseqaij; 4453aa0d41d4SStefano Zampini PetscErrorCode ierr; 4454aa0d41d4SStefano Zampini 4455aa0d41d4SStefano Zampini PetscFunctionBegin; 4456aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 44575e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 44585e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 4459b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 4460aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 44617dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 4462aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 4463906d46d4SStefano Zampini 4464906d46d4SStefano Zampini /* check */ 4465906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4466906d46d4SStefano Zampini Vec x,x_change; 4467906d46d4SStefano Zampini PetscReal error; 4468906d46d4SStefano Zampini 44695e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 4470906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 44715e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 4472e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4473e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4474d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 447588428137SStefano Zampini if (!pcbddc->change_interior) { 447688428137SStefano Zampini const PetscScalar *x,*y,*v; 447788428137SStefano Zampini PetscReal lerror = 0.; 447888428137SStefano Zampini PetscInt i; 447988428137SStefano Zampini 448088428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 448188428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 448288428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 448388428137SStefano Zampini for (i=0;i<local_size;i++) 448488428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 448588428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 448688428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 448788428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 448888428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 448988428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4490637e8532SStefano Zampini if (error > PETSC_SMALL) { 4491637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4492637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on I: %1.6e\n",error); 4493637e8532SStefano Zampini } else { 4494637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on I: %1.6e\n",error); 4495637e8532SStefano Zampini } 4496637e8532SStefano Zampini } 449788428137SStefano Zampini } 4498e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4499e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4500906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4501906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4502637e8532SStefano Zampini if (error > PETSC_SMALL) { 4503637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4504637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 4505637e8532SStefano Zampini } else { 4506637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on N: %1.6e\n",error); 4507637e8532SStefano Zampini } 4508637e8532SStefano Zampini } 4509906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4510906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4511906d46d4SStefano Zampini } 4512906d46d4SStefano Zampini 4513022d8d2bSstefano_zampini /* lA is present if we are setting up an inner BDDC for a saddle point FETI-DP */ 4514022d8d2bSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 4515022d8d2bSstefano_zampini 451622d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 45179b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 451822d5777bSStefano Zampini if (isseqaij) { 4519a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4520a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 4521022d8d2bSstefano_zampini if (lA) { 4522022d8d2bSstefano_zampini Mat work; 4523022d8d2bSstefano_zampini ierr = MatPtAP(lA,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4524022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4525022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4526022d8d2bSstefano_zampini } 4527aa0d41d4SStefano Zampini } else { 4528a00504b5SStefano Zampini Mat work_mat; 45291cf9b237SStefano Zampini 4530a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4531aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4532a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 45331d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 4534022d8d2bSstefano_zampini if (lA) { 4535022d8d2bSstefano_zampini Mat work; 4536022d8d2bSstefano_zampini ierr = MatConvert(lA,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4537022d8d2bSstefano_zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4538022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4539022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4540022d8d2bSstefano_zampini } 4541aa0d41d4SStefano Zampini } 45423301b35fSStefano Zampini if (matis->A->symmetric_set) { 45433301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 4544e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 45453301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 4546e496cd5dSStefano Zampini #endif 45473301b35fSStefano Zampini } 4548d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 4549aa0d41d4SStefano Zampini PetscFunctionReturn(0); 4550aa0d41d4SStefano Zampini } 4551aa0d41d4SStefano Zampini 45528ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 4553a64d13efSStefano Zampini { 4554a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4555a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4556d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 455753892102SStefano Zampini PetscInt *idx_R_local=NULL; 45583a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 45593a50541eSStefano Zampini PetscInt vbs,bs; 45606816873aSStefano Zampini PetscBT bitmask=NULL; 4561a64d13efSStefano Zampini PetscErrorCode ierr; 4562a64d13efSStefano Zampini 4563a64d13efSStefano Zampini PetscFunctionBegin; 4564b23d619eSStefano Zampini /* 4565b23d619eSStefano Zampini No need to setup local scatters if 4566b23d619eSStefano Zampini - primal space is unchanged 4567b23d619eSStefano Zampini AND 4568b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 4569b23d619eSStefano Zampini AND 4570b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 4571b23d619eSStefano Zampini */ 4572b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 4573f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 4574f4ddd8eeSStefano Zampini } 4575f4ddd8eeSStefano Zampini /* destroy old objects */ 4576f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 4577f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 4578f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 4579a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 4580b371cd4fSStefano Zampini n_B = pcis->n_B; 4581b371cd4fSStefano Zampini n_D = pcis->n - n_B; 4582b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 45833a50541eSStefano Zampini 4584a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 45856816873aSStefano Zampini 458653892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 4587b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4588854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 4589a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 4590a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 45910e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 4592a64d13efSStefano Zampini } 4593a64d13efSStefano Zampini 4594a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 45954641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 45966816873aSStefano Zampini idx_R_local[n_R++] = i; 4597a64d13efSStefano Zampini } 4598a64d13efSStefano Zampini } 4599df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 4600df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 46016816873aSStefano Zampini 4602df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4603df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 46046816873aSStefano Zampini } 46053a50541eSStefano Zampini 46063a50541eSStefano Zampini /* Block code */ 46073a50541eSStefano Zampini vbs = 1; 46083a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 46093a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 46103a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 46113a50541eSStefano Zampini PetscInt *vary; 4612b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4613785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 46143a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 4615d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 4616d3df7717SStefano 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 */ 46170e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 4618d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 46193a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 46203a50541eSStefano Zampini is_blocked = PETSC_FALSE; 46213a50541eSStefano Zampini break; 46223a50541eSStefano Zampini } 46233a50541eSStefano Zampini } 4624d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 4625d3df7717SStefano Zampini } else { 4626d3df7717SStefano Zampini /* Verify directly the R set */ 4627d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 4628d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 4629d3df7717SStefano Zampini for (j=1; j<bs; j++) { 4630d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 4631d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 4632d3df7717SStefano Zampini break; 4633d3df7717SStefano Zampini } 4634d3df7717SStefano Zampini } 4635d3df7717SStefano Zampini } 4636d3df7717SStefano Zampini } 46373a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 46383a50541eSStefano Zampini vbs = bs; 46393a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 46403a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 46413a50541eSStefano Zampini } 46423a50541eSStefano Zampini } 46433a50541eSStefano Zampini } 46443a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 4645b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4646df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 464753892102SStefano Zampini 4648df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4649df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 465053892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 4651df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 465253892102SStefano Zampini } else { 46533a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 465453892102SStefano Zampini } 4655a64d13efSStefano Zampini 4656a64d13efSStefano Zampini /* print some info if requested */ 4657a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 4658a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4659a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 46601575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4661a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 4662a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 46634f1b2e48SStefano 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); 4664a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4665a64d13efSStefano Zampini } 4666a64d13efSStefano Zampini 4667a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 4668b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 46696816873aSStefano Zampini IS is_aux1,is_aux2; 46706816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 46716816873aSStefano Zampini 46723a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4673854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 4674854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 4675a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 46764641a718SStefano Zampini for (i=0; i<n_D; i++) { 46774641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 46784641a718SStefano Zampini } 4679a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4680a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 46814641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 46824641a718SStefano Zampini aux_array1[j++] = i; 4683a64d13efSStefano Zampini } 4684a64d13efSStefano Zampini } 4685a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4686a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4687a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 46884641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 46894641a718SStefano Zampini aux_array2[j++] = i; 4690a64d13efSStefano Zampini } 4691a64d13efSStefano Zampini } 4692a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4693a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 4694a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 4695a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4696a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 4697a64d13efSStefano Zampini 46988eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4699785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 4700a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 47014641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 47024641a718SStefano Zampini aux_array1[j++] = i; 4703a64d13efSStefano Zampini } 4704a64d13efSStefano Zampini } 4705a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4706a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 4707a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4708a64d13efSStefano Zampini } 47094641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 47103a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4711d62866d3SStefano Zampini } else { 4712df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 47136816873aSStefano Zampini IS tis; 47146816873aSStefano Zampini PetscInt schur_size; 47156816873aSStefano Zampini 4716df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 47176816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 4718df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 47196816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 47206816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 47216816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 47226816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 47236816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 4724d62866d3SStefano Zampini } 4725d62866d3SStefano Zampini } 4726a64d13efSStefano Zampini PetscFunctionReturn(0); 4727a64d13efSStefano Zampini } 4728a64d13efSStefano Zampini 4729304d26faSStefano Zampini 4730684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 4731304d26faSStefano Zampini { 4732304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4733304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4734304d26faSStefano Zampini PC pc_temp; 4735304d26faSStefano Zampini Mat A_RR; 4736f4ddd8eeSStefano Zampini MatReuse reuse; 4737304d26faSStefano Zampini PetscScalar m_one = -1.0; 4738304d26faSStefano Zampini PetscReal value; 473904708bb6SStefano Zampini PetscInt n_D,n_R; 4740c7017625SStefano Zampini PetscBool check_corr[2],issbaij; 4741304d26faSStefano Zampini PetscErrorCode ierr; 4742e604994aSStefano Zampini /* prefixes stuff */ 4743312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 4744e604994aSStefano Zampini size_t len; 4745304d26faSStefano Zampini 4746304d26faSStefano Zampini PetscFunctionBegin; 4747304d26faSStefano Zampini 4748e604994aSStefano Zampini /* compute prefixes */ 4749e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 4750e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 4751e604994aSStefano Zampini if (!pcbddc->current_level) { 4752e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4753e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4754e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4755e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4756e604994aSStefano Zampini } else { 4757e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 4758312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 4759e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4760e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 4761312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4762312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 476334d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 476434d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4765e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4766e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4767e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 4768e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 4769e604994aSStefano Zampini } 4770e604994aSStefano Zampini 4771304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 4772684f6988SStefano Zampini if (dirichlet) { 4773d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4774450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 47759a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 4776450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 4777a3df083aSStefano Zampini Mat A_IIn; 4778a3df083aSStefano Zampini 4779a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 4780a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 4781a3df083aSStefano Zampini pcis->A_II = A_IIn; 4782a3df083aSStefano Zampini } 4783450f8f5eSStefano Zampini } 47843301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 47853301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 4786964fefecSStefano Zampini } 4787ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 4788964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 4789304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 4790304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 4791304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 4792304d26faSStefano Zampini /* default */ 4793304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 4794e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 47959577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 4796304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 47979577ea80SStefano Zampini if (issbaij) { 47989577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 47999577ea80SStefano Zampini } else { 4800304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 48019577ea80SStefano Zampini } 4802304d26faSStefano Zampini /* Allow user's customization */ 4803304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 4804304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4805304d26faSStefano Zampini } 4806d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 4807b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4808df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4809d62866d3SStefano Zampini 4810df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 4811d5574798SStefano Zampini } 4812304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4813304d26faSStefano Zampini if (!n_D) { 4814304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 4815304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4816304d26faSStefano Zampini } 4817304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 4818304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 4819304d26faSStefano Zampini /* set ksp_D into pcis data */ 4820304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 4821304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 4822304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 4823684f6988SStefano Zampini } 4824304d26faSStefano Zampini 4825304d26faSStefano Zampini /* NEUMANN PROBLEM */ 4826684f6988SStefano Zampini A_RR = 0; 4827684f6988SStefano Zampini if (neumann) { 4828d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 482904708bb6SStefano Zampini PetscInt ibs,mbs; 483004708bb6SStefano Zampini PetscBool issbaij; 483104708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 4832f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 48338ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 4834f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 4835f4ddd8eeSStefano Zampini PetscInt nn_R; 483681d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 4837f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4838f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 4839f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 4840f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 4841f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4842f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4843f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 4844727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 4845f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4846f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4847f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 4848f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 4849f4ddd8eeSStefano Zampini } 4850f4ddd8eeSStefano Zampini } 4851f4ddd8eeSStefano Zampini /* last check */ 4852d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 4853f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4854f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4855f4ddd8eeSStefano Zampini } 4856f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 4857f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 4858f4ddd8eeSStefano Zampini } 4859a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 4860af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 4861af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 486204708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 486304708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 486404708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 486504708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 486604708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 4867af732b37SStefano Zampini } else { 4868511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 48696816873aSStefano Zampini } 487004708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 487104708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 487204708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 487304708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 487404708bb6SStefano Zampini } else { 4875511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 487604708bb6SStefano Zampini } 487704708bb6SStefano Zampini } 4878a00504b5SStefano Zampini /* extract A_RR */ 4879b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4880a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4881a00504b5SStefano Zampini 4882a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 488316e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4884a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 488516e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 488616e386b8SStefano Zampini } else { 48877dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 4888a00504b5SStefano Zampini } 4889a00504b5SStefano Zampini } else { 4890a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4891a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 4892a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 4893a00504b5SStefano Zampini } 4894a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 48957dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 489616e386b8SStefano Zampini } 48973301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 48983301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 48996816873aSStefano Zampini } 4900f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 4901304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 4902304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 4903304d26faSStefano Zampini /* default */ 4904304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 4905e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 4906304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 49079577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 49089577ea80SStefano Zampini if (issbaij) { 49099577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 49109577ea80SStefano Zampini } else { 4911304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 49129577ea80SStefano Zampini } 4913304d26faSStefano Zampini /* Allow user's customization */ 4914304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 4915304d26faSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 4916304d26faSStefano Zampini } 4917304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 4918304d26faSStefano Zampini if (!n_R) { 4919304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 4920304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 4921304d26faSStefano Zampini } 49225cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 4923df4d28bfSStefano Zampini /* Reuse solver if it is present */ 4924111315fdSstefano_zampini if (sub_schurs && sub_schurs->reuse_solver && sub_schurs->A == pcbddc->local_mat) { 4925df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4926d62866d3SStefano Zampini 4927df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 4928d62866d3SStefano Zampini } 4929304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 4930304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 4931684f6988SStefano Zampini } 4932304d26faSStefano Zampini 4933684f6988SStefano Zampini if (pcbddc->dbg_flag) { 4934684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 49351575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4936684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4937684f6988SStefano Zampini } 4938c7017625SStefano Zampini 4939c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 4940c7017625SStefano Zampini check_corr[0] = check_corr[1] = PETSC_FALSE; 4941c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 4942c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 4943c7017625SStefano Zampini } 4944c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 4945c7017625SStefano Zampini check_corr[0] = PETSC_TRUE; 4946c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 4947c7017625SStefano Zampini } 4948c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 4949c7017625SStefano Zampini check_corr[1] = PETSC_TRUE; 4950c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 4951c7017625SStefano Zampini } 4952c7017625SStefano Zampini 4953c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 4954c7017625SStefano Zampini if (pcbddc->dbg_flag) { 4955684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 49560fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 49570fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 49580fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 49590fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 49600fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 4961e604994aSStefano 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); 4962c7017625SStefano Zampini if (check_corr[0]) { 4963c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 4964c7017625SStefano Zampini } 4965304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4966304d26faSStefano Zampini } 4967684f6988SStefano Zampini if (neumann) { /* Neumann */ 49680fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 49690fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 49700fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 49710fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 49720fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 4973e604994aSStefano 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); 4974c7017625SStefano Zampini if (check_corr[1]) { 4975c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 4976c7017625SStefano Zampini } 4977304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4978304d26faSStefano Zampini } 4979684f6988SStefano Zampini } 49805cbda25cSStefano Zampini /* free Neumann problem's matrix */ 49815cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 4982304d26faSStefano Zampini PetscFunctionReturn(0); 4983304d26faSStefano Zampini } 4984304d26faSStefano Zampini 498580677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 4986674ae819SStefano Zampini { 4987674ae819SStefano Zampini PetscErrorCode ierr; 4988674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 4989be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4990b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 4991674ae819SStefano Zampini 4992674ae819SStefano Zampini PetscFunctionBegin; 4993b334f244SStefano Zampini if (!reuse_solver) { 499480677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 499520c7b377SStefano Zampini } 499680677318SStefano Zampini if (!pcbddc->switch_static) { 499780677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 499880677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 499980677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 500020c7b377SStefano Zampini } 5001b334f244SStefano Zampini if (!reuse_solver) { 500280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 500380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 500420c7b377SStefano Zampini } else { 5005df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5006be83ff47SStefano Zampini 5007df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5008df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 500920c7b377SStefano Zampini } 5010be83ff47SStefano Zampini } else { 501180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 501280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 501380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 501480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 501580677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 501680677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 501780677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 501880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 501980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5020674ae819SStefano Zampini } 5021674ae819SStefano Zampini } 5022b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 502380677318SStefano Zampini if (applytranspose) { 502480677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 502580677318SStefano Zampini } else { 502680677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 502780677318SStefano Zampini } 5028be83ff47SStefano Zampini } else { 5029df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5030be83ff47SStefano Zampini 5031be83ff47SStefano Zampini if (applytranspose) { 5032df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5033be83ff47SStefano Zampini } else { 5034df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5035be83ff47SStefano Zampini } 5036be83ff47SStefano Zampini } 503780677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 503880677318SStefano Zampini if (!pcbddc->switch_static) { 5039b334f244SStefano Zampini if (!reuse_solver) { 504080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 504180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5042be83ff47SStefano Zampini } else { 5043df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5044be83ff47SStefano Zampini 5045df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5046df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5047be83ff47SStefano Zampini } 504880677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 504980677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 505080677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 505180677318SStefano Zampini } 505280677318SStefano Zampini } else { 505380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 505480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 505580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 505680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 505780677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 505880677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 505980677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 506080677318SStefano Zampini } 506180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 506280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 506380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 506480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5065674ae819SStefano Zampini } 5066674ae819SStefano Zampini PetscFunctionReturn(0); 5067674ae819SStefano Zampini } 5068674ae819SStefano Zampini 5069dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 5070dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 5071674ae819SStefano Zampini { 5072674ae819SStefano Zampini PetscErrorCode ierr; 5073674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5074674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 5075674ae819SStefano Zampini const PetscScalar zero = 0.0; 5076674ae819SStefano Zampini 5077674ae819SStefano Zampini PetscFunctionBegin; 5078dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 50794fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5080dc359a40SStefano Zampini if (applytranspose) { 5081674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 50828eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 5083dc359a40SStefano Zampini } else { 5084674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 5085674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 508615aaf578SStefano Zampini } 50874fee134fSStefano Zampini } else { 50884fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 50894fee134fSStefano Zampini } 5090efc2fbd9SStefano Zampini 5091efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 50924f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5093efc2fbd9SStefano Zampini PetscScalar *array; 50944f1b2e48SStefano Zampini PetscInt j; 5095efc2fbd9SStefano Zampini 5096efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 50974f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 5098efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5099efc2fbd9SStefano Zampini } 5100efc2fbd9SStefano Zampini 510112edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 510212edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 510312edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 510412edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 510512edc857SStefano Zampini 51069f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 510712edc857SStefano Zampini if (pcbddc->coarse_ksp) { 510851694757SStefano Zampini Mat coarse_mat; 5109964fefecSStefano Zampini Vec rhs,sol; 511051694757SStefano Zampini MatNullSpace nullsp; 511127b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 5112964fefecSStefano Zampini 511327b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 511427b6a85dSStefano Zampini PC coarse_pc; 511527b6a85dSStefano Zampini 511627b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 511727b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 511827b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 511927b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 512027b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 512127b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 51223bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 512327b6a85dSStefano Zampini } 512427b6a85dSStefano Zampini } 5125964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 5126964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 512751694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 512851694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 512951694757SStefano Zampini if (nullsp) { 513051694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 513151694757SStefano Zampini } 513212edc857SStefano Zampini if (applytranspose) { 51339a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 5134964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 51352701bc32SStefano Zampini } else { 51361f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 51372701bc32SStefano Zampini PC coarse_pc; 51382701bc32SStefano Zampini 51392701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 51402701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 51413e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 51422701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 514312edc857SStefano Zampini } else { 5144964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 514512edc857SStefano Zampini } 51462701bc32SStefano Zampini } 51471d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 514827b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 514927b6a85dSStefano Zampini PC coarse_pc; 515027b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 515127b6a85dSStefano Zampini 515227b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 515327b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 515427b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 51553bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 515627b6a85dSStefano Zampini } 515751694757SStefano Zampini if (nullsp) { 515851694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 515951694757SStefano Zampini } 516012edc857SStefano Zampini } 5161674ae819SStefano Zampini 5162674ae819SStefano Zampini /* Local solution on R nodes */ 51634fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 516480677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 51659f00e9b4SStefano Zampini } 51669f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 51679f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 516812edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5169674ae819SStefano Zampini 51704fee134fSStefano Zampini /* Sum contributions from the two levels */ 51714fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5172dc359a40SStefano Zampini if (applytranspose) { 5173dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5174dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5175dc359a40SStefano Zampini } else { 5176674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 51778eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5178dc359a40SStefano Zampini } 5179efc2fbd9SStefano Zampini /* store p0 */ 51804f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5181efc2fbd9SStefano Zampini PetscScalar *array; 51824f1b2e48SStefano Zampini PetscInt j; 5183efc2fbd9SStefano Zampini 5184efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 51854f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 5186efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5187efc2fbd9SStefano Zampini } 51884fee134fSStefano Zampini } else { /* expand the coarse solution */ 51894fee134fSStefano Zampini if (applytranspose) { 51904fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 51914fee134fSStefano Zampini } else { 51924fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 51934fee134fSStefano Zampini } 51944fee134fSStefano Zampini } 5195674ae819SStefano Zampini PetscFunctionReturn(0); 5196674ae819SStefano Zampini } 5197674ae819SStefano Zampini 519812edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 5199674ae819SStefano Zampini { 5200674ae819SStefano Zampini PetscErrorCode ierr; 5201674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 520258da7f69SStefano Zampini PetscScalar *array; 520312edc857SStefano Zampini Vec from,to; 5204674ae819SStefano Zampini 5205674ae819SStefano Zampini PetscFunctionBegin; 520612edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 520712edc857SStefano Zampini from = pcbddc->coarse_vec; 520812edc857SStefano Zampini to = pcbddc->vec1_P; 520912edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 521012edc857SStefano Zampini Vec tvec; 521158da7f69SStefano Zampini 521258da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 521358da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 521412edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 521558da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 521658da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 521758da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 521812edc857SStefano Zampini } 521912edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 522012edc857SStefano Zampini from = pcbddc->vec1_P; 522112edc857SStefano Zampini to = pcbddc->coarse_vec; 522212edc857SStefano Zampini } 522312edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 5224674ae819SStefano Zampini PetscFunctionReturn(0); 5225674ae819SStefano Zampini } 5226674ae819SStefano Zampini 522712edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 5228674ae819SStefano Zampini { 5229674ae819SStefano Zampini PetscErrorCode ierr; 5230674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 523158da7f69SStefano Zampini PetscScalar *array; 523212edc857SStefano Zampini Vec from,to; 5233674ae819SStefano Zampini 5234674ae819SStefano Zampini PetscFunctionBegin; 523512edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 523612edc857SStefano Zampini from = pcbddc->coarse_vec; 523712edc857SStefano Zampini to = pcbddc->vec1_P; 523812edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 523912edc857SStefano Zampini from = pcbddc->vec1_P; 524012edc857SStefano Zampini to = pcbddc->coarse_vec; 524112edc857SStefano Zampini } 524212edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 524312edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 524412edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 524512edc857SStefano Zampini Vec tvec; 524658da7f69SStefano Zampini 524712edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 524858da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 524958da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 525058da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 525158da7f69SStefano Zampini } 525258da7f69SStefano Zampini } else { 525358da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 525458da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 525512edc857SStefano Zampini } 525612edc857SStefano Zampini } 5257674ae819SStefano Zampini PetscFunctionReturn(0); 5258674ae819SStefano Zampini } 5259674ae819SStefano Zampini 5260984c4197SStefano Zampini /* uncomment for testing purposes */ 5261984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 5262674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 5263674ae819SStefano Zampini { 5264674ae819SStefano Zampini PetscErrorCode ierr; 5265674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5266674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5267674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5268984c4197SStefano Zampini /* one and zero */ 5269984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 5270984c4197SStefano Zampini /* space to store constraints and their local indices */ 52719162d606SStefano Zampini PetscScalar *constraints_data; 52729162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 52739162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 52749162d606SStefano Zampini PetscInt *constraints_n; 5275984c4197SStefano Zampini /* iterators */ 5276b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 5277984c4197SStefano Zampini /* BLAS integers */ 5278e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 5279e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 5280c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 5281727cdba6SStefano Zampini /* reuse */ 52820e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 52830e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 5284984c4197SStefano Zampini /* change of basis */ 5285b3d85658SStefano Zampini PetscBool qr_needed; 52869162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 5287984c4197SStefano Zampini /* auxiliary stuff */ 528864efe560SStefano Zampini PetscInt *nnz,*is_indices; 52898a0068c3SStefano Zampini PetscInt ncc; 5290984c4197SStefano Zampini /* some quantities */ 529145a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 5292a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 5293984c4197SStefano Zampini 5294674ae819SStefano Zampini PetscFunctionBegin; 52958e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 52968e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 52978e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 529816909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 5299088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 5300088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 53010e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 53020e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 53030e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 53040e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 53050e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 5306088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5307cf5a6209SStefano Zampini 5308cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 53099162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 5310cf5a6209SStefano Zampini MatNullSpace nearnullsp; 5311cf5a6209SStefano Zampini const Vec *nearnullvecs; 5312cf5a6209SStefano Zampini Vec *localnearnullsp; 5313cf5a6209SStefano Zampini PetscScalar *array; 5314cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 5315cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 5316674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 5317b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 5318674ae819SStefano Zampini PetscScalar *work; 5319674ae819SStefano Zampini PetscReal *singular_vals; 5320674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5321674ae819SStefano Zampini PetscReal *rwork; 5322674ae819SStefano Zampini #endif 5323674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5324674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 5325674ae819SStefano Zampini #else 5326964fefecSStefano Zampini PetscBLASInt dummy_int=1; 5327964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 5328674ae819SStefano Zampini #endif 5329674ae819SStefano Zampini 5330674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 5331d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 5332e4d548c7SStefano Zampini /* print some info */ 53335c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 5334e4d548c7SStefano Zampini PetscInt nv; 5335e4d548c7SStefano Zampini 5336c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5337e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 5338e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5339e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5340e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 5341e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 5342e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 5343e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5344e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5345e4d548c7SStefano Zampini } 5346e4d548c7SStefano Zampini 5347d06fc5fdSStefano Zampini /* free unneeded index sets */ 5348d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 5349d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 5350674ae819SStefano Zampini } 5351d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 5352d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5353d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5354d06fc5fdSStefano Zampini } 5355d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5356d06fc5fdSStefano Zampini n_ISForEdges = 0; 5357d06fc5fdSStefano Zampini } 5358d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 5359d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5360d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5361d06fc5fdSStefano Zampini } 5362d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5363d06fc5fdSStefano Zampini n_ISForFaces = 0; 5364d06fc5fdSStefano Zampini } 536570022509SStefano Zampini 5366674ae819SStefano Zampini /* check if near null space is attached to global mat */ 5367674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 5368674ae819SStefano Zampini if (nearnullsp) { 5369674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 5370f4ddd8eeSStefano Zampini /* remove any stored info */ 5371f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 5372f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5373f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 5374f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 5375f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 5376473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5377f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 5378f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 5379f4ddd8eeSStefano Zampini } 5380984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 5381984c4197SStefano Zampini nnsp_size = 0; 5382674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 5383674ae819SStefano Zampini } 5384984c4197SStefano Zampini /* get max number of constraints on a single cc */ 5385984c4197SStefano Zampini max_constraints = nnsp_size; 5386984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 5387984c4197SStefano Zampini 5388674ae819SStefano Zampini /* 5389674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 53909162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 53919162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 53929162d606SStefano Zampini There can be multiple constraints per connected component 5393674ae819SStefano Zampini */ 5394674ae819SStefano Zampini n_vertices = 0; 5395674ae819SStefano Zampini if (ISForVertices) { 5396674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 5397674ae819SStefano Zampini } 53989162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 53999162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 54009162d606SStefano Zampini 54019162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 54029162d606SStefano Zampini total_counts *= max_constraints; 5403674ae819SStefano Zampini total_counts += n_vertices; 54044641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 54059162d606SStefano Zampini 5406674ae819SStefano Zampini total_counts = 0; 5407674ae819SStefano Zampini max_size_of_constraint = 0; 5408674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 54099162d606SStefano Zampini IS used_is; 5410674ae819SStefano Zampini if (i<n_ISForEdges) { 54119162d606SStefano Zampini used_is = ISForEdges[i]; 5412674ae819SStefano Zampini } else { 54139162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 5414674ae819SStefano Zampini } 54159162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 5416674ae819SStefano Zampini total_counts += j; 5417674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 5418674ae819SStefano Zampini } 54199162d606SStefano 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); 54209162d606SStefano Zampini 5421984c4197SStefano Zampini /* get local part of global near null space vectors */ 5422785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 5423984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5424984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 5425e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5426e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5427984c4197SStefano Zampini } 5428674ae819SStefano Zampini 5429242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 5430242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 5431a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 5432242a89d7SStefano Zampini 5433984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 5434a773dcb8SStefano Zampini if (!skip_lapack) { 5435674ae819SStefano Zampini PetscScalar temp_work; 5436911cabfeSStefano Zampini 5437674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5438984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 5439785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 5440785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 5441785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 5442674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5443785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 5444674ae819SStefano Zampini #endif 5445674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5446c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 5447c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 5448674ae819SStefano Zampini lwork = -1; 5449674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5450674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5451c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 5452674ae819SStefano Zampini #else 5453c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 5454674ae819SStefano Zampini #endif 5455674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5456984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 5457674ae819SStefano Zampini #else /* on missing GESVD */ 5458674ae819SStefano Zampini /* SVD */ 5459674ae819SStefano Zampini PetscInt max_n,min_n; 5460674ae819SStefano Zampini max_n = max_size_of_constraint; 5461984c4197SStefano Zampini min_n = max_constraints; 5462984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 5463674ae819SStefano Zampini min_n = max_size_of_constraint; 5464984c4197SStefano Zampini max_n = max_constraints; 5465674ae819SStefano Zampini } 5466785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 5467674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5468785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 5469674ae819SStefano Zampini #endif 5470674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5471674ae819SStefano Zampini lwork = -1; 5472e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 5473e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 5474b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 5475674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5476674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 54779162d606SStefano 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)); 5478674ae819SStefano Zampini #else 54799162d606SStefano 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)); 5480674ae819SStefano Zampini #endif 5481674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5482984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 5483984c4197SStefano Zampini #endif /* on missing GESVD */ 5484674ae819SStefano Zampini /* Allocate optimal workspace */ 5485674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 5486854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 5487674ae819SStefano Zampini } 5488674ae819SStefano Zampini /* Now we can loop on constraining sets */ 5489674ae819SStefano Zampini total_counts = 0; 54909162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 54919162d606SStefano Zampini constraints_data_ptr[0] = 0; 5492674ae819SStefano Zampini /* vertices */ 54939162d606SStefano Zampini if (n_vertices) { 5494674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 54959162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 5496674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 54979162d606SStefano Zampini constraints_n[total_counts] = 1; 54989162d606SStefano Zampini constraints_data[total_counts] = 1.0; 54999162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 55009162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 5501674ae819SStefano Zampini total_counts++; 5502674ae819SStefano Zampini } 5503674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5504674ae819SStefano Zampini n_vertices = total_counts; 5505674ae819SStefano Zampini } 5506984c4197SStefano Zampini 5507674ae819SStefano Zampini /* edges and faces */ 55089162d606SStefano Zampini total_counts_cc = total_counts; 5509911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 55109162d606SStefano Zampini IS used_is; 55119162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 55129162d606SStefano Zampini 5513911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 55149162d606SStefano Zampini used_is = ISForEdges[ncc]; 5515984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 5516674ae819SStefano Zampini } else { 55179162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 5518984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 5519674ae819SStefano Zampini } 5520674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 55219162d606SStefano Zampini 55229162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 55239162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5524984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 5525984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 5526674ae819SStefano Zampini if (nnsp_has_cnst) { 55275b08dc53SStefano Zampini PetscScalar quad_value; 55289162d606SStefano Zampini 55299162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 55309162d606SStefano Zampini idxs_copied = PETSC_TRUE; 55319162d606SStefano Zampini 5532a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 5533674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 5534a773dcb8SStefano Zampini } else { 5535a773dcb8SStefano Zampini quad_value = 1.0; 5536a773dcb8SStefano Zampini } 5537674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 55389162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 5539674ae819SStefano Zampini } 55409162d606SStefano Zampini temp_constraints++; 5541674ae819SStefano Zampini total_counts++; 5542674ae819SStefano Zampini } 5543674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 5544984c4197SStefano Zampini PetscReal real_value; 55459162d606SStefano Zampini PetscScalar *ptr_to_data; 55469162d606SStefano Zampini 5547984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 55489162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 5549674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 55509162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 5551674ae819SStefano Zampini } 5552984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 5553984c4197SStefano Zampini /* check if array is null on the connected component */ 5554e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 55559162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 55565b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 5557674ae819SStefano Zampini temp_constraints++; 5558674ae819SStefano Zampini total_counts++; 55599162d606SStefano Zampini if (!idxs_copied) { 55609162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 55619162d606SStefano Zampini idxs_copied = PETSC_TRUE; 5562674ae819SStefano Zampini } 5563674ae819SStefano Zampini } 55649162d606SStefano Zampini } 55659162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 556645a1bb75SStefano Zampini valid_constraints = temp_constraints; 5567eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 5568a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 55699162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 55709162d606SStefano Zampini 55719162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5572a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 55739162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 5574a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 55759162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 5576a773dcb8SStefano Zampini } else { /* perform SVD */ 5577984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 55789162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5579674ae819SStefano Zampini 5580674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5581984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 5582984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 5583984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 5584984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 5585984c4197SStefano Zampini from that computed using LAPACKgesvd 5586984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 5587984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 5588984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 5589674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 5590e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5591984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5592674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 5593674ae819SStefano Zampini for (k=0;k<j+1;k++) { 55949162d606SStefano 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)); 5595674ae819SStefano Zampini } 5596674ae819SStefano Zampini } 5597e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 5598e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5599e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 5600674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5601c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 5602674ae819SStefano Zampini #else 5603c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 5604674ae819SStefano Zampini #endif 5605674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5606984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 5607984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 5608674ae819SStefano Zampini j = 0; 5609984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 5610674ae819SStefano Zampini total_counts = total_counts-j; 561145a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 5612e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 5613c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5614c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5615c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 5616c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5617c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 5618c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5619674ae819SStefano Zampini if (j<temp_constraints) { 5620984c4197SStefano Zampini PetscInt ii; 5621984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 5622674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 56239162d606SStefano 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)); 5624674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5625984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 5626674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 56279162d606SStefano 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]; 5628674ae819SStefano Zampini } 5629674ae819SStefano Zampini } 5630674ae819SStefano Zampini } 5631674ae819SStefano Zampini #else /* on missing GESVD */ 5632e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5633e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5634b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5635674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5636674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 56379162d606SStefano 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)); 5638674ae819SStefano Zampini #else 56399162d606SStefano 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)); 5640674ae819SStefano Zampini #endif 5641984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 5642674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5643984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 5644e310c8b4SStefano Zampini k = temp_constraints; 5645e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 5646674ae819SStefano Zampini j = 0; 5647e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 564845a1bb75SStefano Zampini valid_constraints = k-j; 5649911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 5650984c4197SStefano Zampini #endif /* on missing GESVD */ 5651674ae819SStefano Zampini } 5652a773dcb8SStefano Zampini } 56539162d606SStefano Zampini /* update pointers information */ 56549162d606SStefano Zampini if (valid_constraints) { 56559162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 56569162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 56579162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 56589162d606SStefano Zampini /* set change_of_basis flag */ 565945a1bb75SStefano Zampini if (boolforchange) { 5660b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 56619162d606SStefano Zampini } 5662b3d85658SStefano Zampini total_counts_cc++; 566345a1bb75SStefano Zampini } 566445a1bb75SStefano Zampini } 5665984c4197SStefano Zampini /* free workspace */ 56668f1c130eSStefano Zampini if (!skip_lapack) { 5667984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 5668984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5669984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 5670984c4197SStefano Zampini #endif 5671984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 5672984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5673984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 5674984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 5675984c4197SStefano Zampini #endif 5676984c4197SStefano Zampini } 5677984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5678984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 5679984c4197SStefano Zampini } 5680984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 5681cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 5682cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5683cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5684cf5a6209SStefano Zampini } 5685cf5a6209SStefano Zampini if (n_ISForFaces) { 5686cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5687cf5a6209SStefano Zampini } 5688cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5689cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5690cf5a6209SStefano Zampini } 5691cf5a6209SStefano Zampini if (n_ISForEdges) { 5692cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5693cf5a6209SStefano Zampini } 5694cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 569508122e43SStefano Zampini } else { 569608122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5697984c4197SStefano Zampini 569808122e43SStefano Zampini total_counts = 0; 569908122e43SStefano Zampini n_vertices = 0; 5700d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 5701d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 570208122e43SStefano Zampini } 570308122e43SStefano Zampini max_constraints = 0; 57049162d606SStefano Zampini total_counts_cc = 0; 570508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 570608122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 57079162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 570808122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 570908122e43SStefano Zampini } 57109162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 57119162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 57129162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 57139162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 571474d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 57159162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 57169162d606SStefano Zampini total_counts_cc = 0; 57179162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 57189162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 57199162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 572008122e43SStefano Zampini } 572108122e43SStefano Zampini } 57229162d606SStefano Zampini #if 0 57239162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 57249162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 57259162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 57269162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 57279162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 57289162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 57299162d606SStefano Zampini } 57309162d606SStefano Zampini printf("\n"); 57319162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 57329162d606SStefano Zampini } 57331b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 57348bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 57351b968477SStefano Zampini } 57361b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 57378bec7fa6SStefano 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]); 57381b968477SStefano Zampini } 573908122e43SStefano Zampini #endif 574008122e43SStefano Zampini 57418bec7fa6SStefano Zampini max_size_of_constraint = 0; 57429162d606SStefano 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]); 57439162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 574408122e43SStefano Zampini /* Change of basis */ 5745b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 574608122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 574708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 574808122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 5749b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 575008122e43SStefano Zampini } 575108122e43SStefano Zampini } 575208122e43SStefano Zampini } 575308122e43SStefano Zampini } 5754984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 57554f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 575608122e43SStefano Zampini 57579162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 57589162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 5759eee23b56SStefano 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); 5760674ae819SStefano Zampini 5761674ae819SStefano Zampini /* Create constraint matrix */ 5762674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 576316f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 5764984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 5765984c4197SStefano Zampini 5766984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 5767a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 5768a717540cSStefano Zampini qr_needed = PETSC_FALSE; 576974d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 5770984c4197SStefano Zampini total_primal_vertices=0; 5771b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 57729162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 57739162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 577472b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 57759162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 5776b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 577764efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 57789162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 57799162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 5780a717540cSStefano Zampini } 5781b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 578291af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 5783a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 5784a717540cSStefano Zampini qr_needed = PETSC_TRUE; 5785a717540cSStefano Zampini } 5786fa434743SStefano Zampini } else { 5787b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 5788fa434743SStefano Zampini } 5789a717540cSStefano Zampini } 5790b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 5791b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 5792674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 579370022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 57944f1b2e48SStefano 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); 57950e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 57960e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 5797984c4197SStefano Zampini 5798984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 579974d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 5800785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 5801984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 580274d5cdf7SStefano Zampini 5803984c4197SStefano Zampini j = total_primal_vertices; 580474d5cdf7SStefano Zampini total_counts = total_primal_vertices; 5805b3d85658SStefano Zampini cum = total_primal_vertices; 58069162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 58074641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 5808b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 5809b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 5810b3d85658SStefano Zampini cum++; 58119162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 581274d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 581374d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 581474d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 581574d5cdf7SStefano Zampini } 58169162d606SStefano Zampini j += constraints_n[i]; 5817674ae819SStefano Zampini } 5818674ae819SStefano Zampini } 5819674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 5820674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 5821088faed8SStefano Zampini 5822674ae819SStefano Zampini /* set values in constraint matrix */ 5823984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 58240e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 5825674ae819SStefano Zampini } 5826984c4197SStefano Zampini total_counts = total_primal_vertices; 58279162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 58284641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 58299162d606SStefano Zampini PetscInt *cols; 58309162d606SStefano Zampini 58319162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 58329162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 58339162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 58349162d606SStefano Zampini PetscInt row = total_counts+k; 58359162d606SStefano Zampini PetscScalar *vals; 58369162d606SStefano Zampini 58379162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 58389162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 58399162d606SStefano Zampini } 58409162d606SStefano Zampini total_counts += constraints_n[i]; 5841674ae819SStefano Zampini } 5842674ae819SStefano Zampini } 5843674ae819SStefano Zampini /* assembling */ 5844674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5845674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 5846088faed8SStefano Zampini 5847984c4197SStefano Zampini /* 58486a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 5849984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 5850f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 5851984c4197SStefano Zampini */ 5852674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 5853674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 5854026de310SStefano Zampini /* dual and primal dofs on a single cc */ 5855984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 5856984c4197SStefano Zampini /* working stuff for GEQRF */ 585781d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 5858984c4197SStefano Zampini PetscBLASInt lqr_work; 5859984c4197SStefano Zampini /* working stuff for UNGQR */ 5860984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 5861984c4197SStefano Zampini PetscBLASInt lgqr_work; 5862984c4197SStefano Zampini /* working stuff for TRTRS */ 5863984c4197SStefano Zampini PetscScalar *trs_rhs; 58643f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 5865984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 5866984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 5867984c4197SStefano Zampini PetscScalar *start_vals; 5868984c4197SStefano Zampini /* working stuff for values insertion */ 58694641a718SStefano Zampini PetscBT is_primal; 587064efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 5871906d46d4SStefano Zampini /* matrix sizes */ 5872906d46d4SStefano Zampini PetscInt global_size,local_size; 5873906d46d4SStefano Zampini /* temporary change of basis */ 5874906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 5875cf5a6209SStefano Zampini /* extra space for debugging */ 5876cf5a6209SStefano Zampini PetscScalar *dbg_work; 5877984c4197SStefano Zampini 5878906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 5879906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 588016f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 5881bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 5882906d46d4SStefano Zampini /* nonzeros for local mat */ 5883bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 58841dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5885bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 58861dd7afcfSStefano Zampini } else { 58871dd7afcfSStefano Zampini const PetscInt *ii; 58881dd7afcfSStefano Zampini PetscInt n; 58891dd7afcfSStefano Zampini PetscBool flg_row; 58901dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 58911dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 58921dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 58931dd7afcfSStefano Zampini } 58949162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 5895a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 58969162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 5897a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 58989162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 5899a717540cSStefano Zampini } else { 59009162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 59019162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 5902a717540cSStefano Zampini } 5903a717540cSStefano Zampini } 5904a717540cSStefano Zampini } 5905906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 5906bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 59071dd7afcfSStefano Zampini /* Set interior change in the matrix */ 59081dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 5909bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 5910906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 5911a717540cSStefano Zampini } 59121dd7afcfSStefano Zampini } else { 59131dd7afcfSStefano Zampini const PetscInt *ii,*jj; 59141dd7afcfSStefano Zampini PetscScalar *aa; 59151dd7afcfSStefano Zampini PetscInt n; 59161dd7afcfSStefano Zampini PetscBool flg_row; 59171dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 59181dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 59191dd7afcfSStefano Zampini for (i=0;i<n;i++) { 59201dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 59211dd7afcfSStefano Zampini } 59221dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 59231dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 59241dd7afcfSStefano Zampini } 5925a717540cSStefano Zampini 5926a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5927a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5928a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 5929a717540cSStefano Zampini } 5930a717540cSStefano Zampini 5931a717540cSStefano Zampini 5932a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 5933a717540cSStefano Zampini /* 5934a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 5935a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 5936a717540cSStefano Zampini 5937a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 5938a717540cSStefano Zampini 5939a6b551f4SStefano 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) 5940a6b551f4SStefano Zampini 5941a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 5942a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 5943a717540cSStefano Zampini | ... | 5944a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 5945a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 5946a717540cSStefano Zampini 5947a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 5948a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 5949a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 5950a6b551f4SStefano Zampini 5951a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 5952a717540cSStefano Zampini */ 5953a717540cSStefano Zampini if (qr_needed) { 5954984c4197SStefano Zampini /* space to store Q */ 5955854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 59564e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 59574e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 5958984c4197SStefano Zampini /* first we issue queries for optimal work */ 59593f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 59603f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 59613f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5962984c4197SStefano Zampini lqr_work = -1; 59633f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 5964984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 5965984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 5966785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 5967984c4197SStefano Zampini lgqr_work = -1; 59683f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 59693f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 59703f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 59713f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 59723f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 59733f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 5974984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to UNGQR Lapack routine %d",(int)lierr); 5975984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 5976785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 5977984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 5978785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 5979a717540cSStefano Zampini /* allocating workspace for check */ 5980a717540cSStefano Zampini if (pcbddc->dbg_flag) { 5981cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 5982a717540cSStefano Zampini } 5983a717540cSStefano Zampini } 5984984c4197SStefano Zampini /* array to store whether a node is primal or not */ 59854641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 5986473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 59870e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 5988eee23b56SStefano 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); 598939e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 599039e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 599139e2fb2aSStefano Zampini } 599239e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 5993984c4197SStefano Zampini 5994a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 59959162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 59969162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 59974641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 5998984c4197SStefano Zampini /* get constraint info */ 59999162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 6000984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 6001984c4197SStefano Zampini 6002984c4197SStefano Zampini if (pcbddc->dbg_flag) { 60039162d606SStefano 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); 6004674ae819SStefano Zampini } 6005984c4197SStefano Zampini 6006fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 6007a717540cSStefano Zampini 6008a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 6009a717540cSStefano Zampini if (pcbddc->dbg_flag) { 60109162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6011a717540cSStefano Zampini } 6012984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 60139162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6014984c4197SStefano Zampini 6015984c4197SStefano Zampini /* compute QR decomposition of constraints */ 60163f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 60173f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 60183f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6019674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 60203f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 6021984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 6022674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6023984c4197SStefano Zampini 6024984c4197SStefano Zampini /* explictly compute R^-T */ 6025984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 6026984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 60273f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 60283f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 60293f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 60303f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 6031984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 60323f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 6033984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 6034984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6035984c4197SStefano Zampini 6036a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 60373f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 60383f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 60393f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 60403f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6041984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 60423f08241aSStefano Zampini PetscStackCallBLAS("LAPACKungqr",LAPACKungqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 6043984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in UNGQR Lapack routine %d",(int)lierr); 6044984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6045984c4197SStefano Zampini 6046984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 6047984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 6048984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 60493f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 60503f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 60513f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 60523f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 60533f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 60543f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6055984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 60569162d606SStefano 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)); 6057984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 60589162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6059984c4197SStefano Zampini 6060984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 60619162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 6062984c4197SStefano Zampini /* insert cols for primal dofs */ 6063984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 6064984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 60659162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6066906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6067984c4197SStefano Zampini } 6068984c4197SStefano Zampini /* insert cols for dual dofs */ 6069984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 60709162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 6071984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 60729162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6073906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6074984c4197SStefano Zampini j++; 6075674ae819SStefano Zampini } 6076674ae819SStefano Zampini } 6077984c4197SStefano Zampini 6078984c4197SStefano Zampini /* check change of basis */ 6079984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6080984c4197SStefano Zampini PetscInt ii,jj; 6081984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 6082c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 6083c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6084c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 6085c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6086c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 6087c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 6088984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6089cf5a6209SStefano 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)); 6090984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6091984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6092984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6093cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 6094cf5a6209SStefano 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; 6095674ae819SStefano Zampini } 6096674ae819SStefano Zampini } 6097984c4197SStefano Zampini if (!valid_qr) { 609822d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 6099984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6100984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6101cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 6102cf5a6209SStefano 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])); 6103674ae819SStefano Zampini } 6104cf5a6209SStefano Zampini if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-1.0) > 1.e-12) { 6105cf5a6209SStefano 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])); 6106984c4197SStefano Zampini } 6107984c4197SStefano Zampini } 6108984c4197SStefano Zampini } 6109674ae819SStefano Zampini } else { 611022d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 6111674ae819SStefano Zampini } 6112674ae819SStefano Zampini } 6113a717540cSStefano Zampini } else { /* simple transformation block */ 6114a717540cSStefano Zampini PetscInt row,col; 6115a6b551f4SStefano Zampini PetscScalar val,norm; 6116a6b551f4SStefano Zampini 6117a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 61189162d606SStefano 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)); 6119a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 61209162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 61219162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6122bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 61239162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 6124906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 61259162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 6126a717540cSStefano Zampini } else { 6127a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 61289162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6129a717540cSStefano Zampini if (row != col) { 61309162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 6131a717540cSStefano Zampini } else { 61329162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 6133a717540cSStefano Zampini } 6134906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 6135a717540cSStefano Zampini } 6136a717540cSStefano Zampini } 6137a717540cSStefano Zampini } 613898a51de6SStefano Zampini if (pcbddc->dbg_flag) { 613922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 6140a717540cSStefano Zampini } 6141674ae819SStefano Zampini } 6142984c4197SStefano Zampini } else { 6143984c4197SStefano Zampini if (pcbddc->dbg_flag) { 61449162d606SStefano 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); 6145674ae819SStefano Zampini } 6146674ae819SStefano Zampini } 6147674ae819SStefano Zampini } 6148a717540cSStefano Zampini 6149a717540cSStefano Zampini /* free workspace */ 6150a717540cSStefano Zampini if (qr_needed) { 6151984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6152cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 6153984c4197SStefano Zampini } 6154984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 6155984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 6156984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 6157984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 6158984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 6159674ae819SStefano Zampini } 6160a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 6161906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6162906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6163906d46d4SStefano Zampini 6164906d46d4SStefano Zampini /* assembling of global change of variable */ 616588c03ad3SStefano Zampini if (!pcbddc->fake_change) { 6166bbb9e6c6SStefano Zampini Mat tmat; 616716f15bc4SStefano Zampini PetscInt bs; 616816f15bc4SStefano Zampini 6169906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 6170906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 6171bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 6172bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 6173bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6174bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 617516f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 617616f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 6177906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 6178bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 6179bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6180bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6181bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6182bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6183e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6184e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6185bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 6186bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 618788c03ad3SStefano Zampini 6188906d46d4SStefano Zampini /* check */ 6189906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 6190906d46d4SStefano Zampini PetscReal error; 6191906d46d4SStefano Zampini Vec x,x_change; 6192906d46d4SStefano Zampini 6193906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 6194906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 6195906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 6196906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 6197e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6198e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6199bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 6200e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6201e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6202906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 6203906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 6204906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 6205637e8532SStefano Zampini if (error > PETSC_SMALL) { 6206637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 6207637e8532SStefano Zampini } 6208906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 6209906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 6210906d46d4SStefano Zampini } 6211b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 6212b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 6213b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6214bf3a8328SStefano Zampini 62159a962809SStefano 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); 6216b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 6217ac632422SStefano Zampini Mat S_new,tmat; 6218bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 6219bbb9e6c6SStefano Zampini 6220bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 62217dae84e0SHong Zhang ierr = MatCreateSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 6222bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6223bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 6224bf3a8328SStefano Zampini IS is_V; 6225b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 6226b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 6227b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 6228b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 6229b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 6230bf3a8328SStefano Zampini } 6231bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 6232ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6233b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 6234ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6235bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6236bf3a8328SStefano Zampini const PetscScalar *array; 6237bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 6238bf3a8328SStefano Zampini PetscInt i,n_V; 6239bf3a8328SStefano Zampini 6240b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6241b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 6242b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6243b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6244b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 6245b087196eSStefano Zampini for (i=0;i<n_V;i++) { 6246b087196eSStefano Zampini PetscScalar val; 6247b087196eSStefano Zampini PetscInt idx; 6248b087196eSStefano Zampini 6249b087196eSStefano Zampini idx = idxs_V[i]; 6250b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 6251b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 6252b087196eSStefano Zampini } 6253b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6254b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6255bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 6256bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6257bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6258bf3a8328SStefano Zampini } 6259ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 6260ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6261ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 6262ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6263b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 6264ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6265bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6266b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6267bf3a8328SStefano Zampini } 6268ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 6269ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6270ac632422SStefano Zampini } 6271b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 627288c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6273b96c3477SStefano Zampini } 6274c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 6275b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 6276c9db6a07SStefano Zampini PetscInt i; 6277c9db6a07SStefano Zampini 6278c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 6279c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 6280c9db6a07SStefano Zampini } 6281c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 6282c9db6a07SStefano Zampini } 6283b96c3477SStefano Zampini } 628416909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 628516909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 628616909a7fSStefano Zampini } else { 6287906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 628816909a7fSStefano Zampini } 62891dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 629027b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 629172b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 629272b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 629372b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 629472b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 629572b8c272SStefano Zampini } 62961dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 629727b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 6298b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 6299b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 6300906d46d4SStefano Zampini } else { 63011dd7afcfSStefano Zampini Mat benign_global = NULL; 630227b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 63031dd7afcfSStefano Zampini Mat tmat; 63041dd7afcfSStefano Zampini 63051dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 63061dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 63071dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 63081dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 63091dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 63101dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 63111dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 63121dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 63131dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 63141dd7afcfSStefano Zampini if (pcbddc->benign_change) { 63151dd7afcfSStefano Zampini Mat M; 63161dd7afcfSStefano Zampini 63171dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 63181dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 63191dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 63201dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 6321906d46d4SStefano Zampini } else { 63221dd7afcfSStefano Zampini Mat eye; 63231dd7afcfSStefano Zampini PetscScalar *array; 63241dd7afcfSStefano Zampini 63251dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 63261dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 63271dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 63281dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 6329906d46d4SStefano Zampini } 63301dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 63311dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 63321dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 63331dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 63341dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 63351dd7afcfSStefano Zampini } 63361dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 63371dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 63381dd7afcfSStefano Zampini } 63391dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 63401dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 63411dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 634227b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 63431dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 63441dd7afcfSStefano Zampini } 63451dd7afcfSStefano Zampini } 634616909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 634716909a7fSStefano Zampini IS is_global; 634816909a7fSStefano Zampini const PetscInt *gidxs; 634916909a7fSStefano Zampini 635016909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 635116909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 635216909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 63537dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 635416909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 635516909a7fSStefano Zampini } 63561dd7afcfSStefano Zampini } 63571dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 63581dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 6359b9b85e73SStefano Zampini } 6360a717540cSStefano Zampini 636172b8c272SStefano Zampini if (!pcbddc->fake_change) { 63624f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 63634f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 63644f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 63654f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 6366019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 6367019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 6368019a44ceSStefano Zampini pcbddc->local_primal_size++; 6369019a44ceSStefano Zampini } 6370019a44ceSStefano Zampini 6371019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 6372727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 6373727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 63749f47a83aSStefano 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); 6375c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 63760e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 63779f47a83aSStefano 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); 6378727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 6379727cdba6SStefano Zampini } 63800e6343abSStefano Zampini } 6381727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 6382b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 638372b8c272SStefano Zampini } 638472b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 6385727cdba6SStefano Zampini 6386a717540cSStefano Zampini /* flush dbg viewer */ 6387b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 6388b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6389b8ffe317SStefano Zampini } 6390a717540cSStefano Zampini 6391e310c8b4SStefano Zampini /* free workspace */ 6392a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 63934641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 639408122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 63959162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 63969162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 639708122e43SStefano Zampini } else { 63989162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 63999162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 64009162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 640108122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 640208122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 64039162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 64049162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 640508122e43SStefano Zampini } 6406674ae819SStefano Zampini PetscFunctionReturn(0); 6407674ae819SStefano Zampini } 6408674ae819SStefano Zampini 6409674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 6410674ae819SStefano Zampini { 641171582508SStefano Zampini ISLocalToGlobalMapping map; 6412674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6413674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 641466da6bd7Sstefano_zampini PetscInt i,N; 641566da6bd7Sstefano_zampini PetscBool rcsr = PETSC_FALSE; 641666da6bd7Sstefano_zampini PetscErrorCode ierr; 6417674ae819SStefano Zampini 6418674ae819SStefano Zampini PetscFunctionBegin; 64198af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 6420b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 64218e61c736SStefano Zampini /* Reset previously computed graph */ 64228e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 6423674ae819SStefano Zampini /* Init local Graph struct */ 64247fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 642571582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 6426be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 6427674ae819SStefano Zampini 64287a0e7b2cSstefano_zampini if (pcbddc->user_primal_vertices_local && !pcbddc->user_primal_vertices) { 64297a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 64307a0e7b2cSstefano_zampini } 6431575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 64329a962809SStefano 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); 64339577ea80SStefano Zampini 6434674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 643566da6bd7Sstefano_zampini if (!pcbddc->mat_graph->xadj && pcbddc->use_local_adj) { 64364d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 64374d379d7bSStefano Zampini PetscInt nvtxs; 6438e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 6439674ae819SStefano Zampini 64402fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 64412fffb893SStefano Zampini if (flg_row) { 64424d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 6443b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 64442fffb893SStefano Zampini } 64452fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 644666da6bd7Sstefano_zampini rcsr = PETSC_TRUE; 6447674ae819SStefano Zampini } 64489b28b941SStefano Zampini if (pcbddc->dbg_flag) { 64499b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6450674ae819SStefano Zampini } 6451674ae819SStefano Zampini 6452674ae819SStefano Zampini /* Setup of Graph */ 64534b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 645414f95afaSStefano 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); 6455674ae819SStefano Zampini 64564f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 64574f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 64584f1b2e48SStefano Zampini PetscInt *local_subs; 64594f1b2e48SStefano Zampini 64604f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 64614f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 64624f1b2e48SStefano Zampini const PetscInt *idxs; 64634f1b2e48SStefano Zampini PetscInt nl,j; 64644f1b2e48SStefano Zampini 64654f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 64664f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 646771582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 64684f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 64694f1b2e48SStefano Zampini } 64704f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 64714f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 64724f1b2e48SStefano Zampini } 64738af8fcf9SStefano Zampini } 64744f1b2e48SStefano Zampini 6475cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 6476674ae819SStefano Zampini /* Graph's connected components analysis */ 6477674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 647871582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 64798af8fcf9SStefano Zampini } 648066da6bd7Sstefano_zampini if (rcsr) pcbddc->mat_graph->nvtxs_csr = 0; 6481674ae819SStefano Zampini PetscFunctionReturn(0); 6482674ae819SStefano Zampini } 6483674ae819SStefano Zampini 64849a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 64859a7d3425SStefano Zampini { 64869a7d3425SStefano Zampini PetscInt i,j; 64879a7d3425SStefano Zampini PetscScalar *alphas; 64889a7d3425SStefano Zampini PetscErrorCode ierr; 64899a7d3425SStefano Zampini 64909a7d3425SStefano Zampini PetscFunctionBegin; 6491785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 64929a7d3425SStefano Zampini for (i=0;i<n;i++) { 64939a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 6494669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 6495669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 6496669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 64979a7d3425SStefano Zampini } 64989a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 64999a7d3425SStefano Zampini PetscFunctionReturn(0); 65009a7d3425SStefano Zampini } 65019a7d3425SStefano Zampini 6502bb360cb4SStefano Zampini PetscErrorCode PCBDDCMatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 6503e7931f94SStefano Zampini { 650457de7509SStefano Zampini Mat A; 6505e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 6506e7931f94SStefano Zampini PetscMPIInt size,rank,color; 650752e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 650852e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 6509bb360cb4SStefano Zampini PetscInt im_active,active_procs,N,n,i,j,threshold = 2; 651057de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 651127b6a85dSStefano Zampini PetscInt xadj_count,*count; 651227b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 651327b6a85dSStefano Zampini PetscSubcomm psubcomm; 651427b6a85dSStefano Zampini MPI_Comm subcomm; 651552e5ac9dSStefano Zampini PetscErrorCode ierr; 6516a57a6d2fSStefano Zampini 6517e7931f94SStefano Zampini PetscFunctionBegin; 651857de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 651957de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 6520fbfcfee5SBarry Smith if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",PETSC_FUNCTION_NAME); 652157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 652257de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 652357de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 652457de7509SStefano Zampini 652557de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 652657de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 652757de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 652857de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 652957de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 6530bb360cb4SStefano Zampini im_active = !!n; 653157de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 653257de7509SStefano Zampini void_procs = size - active_procs; 653357de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 653457de7509SStefano Zampini if (void_procs) { 653557de7509SStefano Zampini PetscInt ncand; 653657de7509SStefano Zampini 653757de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 653857de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 653957de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 654057de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 654157de7509SStefano Zampini if (!procs_candidates[i]) { 654257de7509SStefano Zampini procs_candidates[ncand++] = i; 654357de7509SStefano Zampini } 654457de7509SStefano Zampini } 654557de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 654657de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 654757de7509SStefano Zampini } 654857de7509SStefano Zampini 6549bb360cb4SStefano Zampini /* number of subdomains requested greater than active processes or matrix size -> just shift the matrix 655014f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 6551bb360cb4SStefano Zampini ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 6552bb360cb4SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1 || N <= *n_subdomains) { 655314f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 655414f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 655514f0bfb9SStefano Zampini else dest = rank; 655657de7509SStefano Zampini if (im_active) { 655757de7509SStefano Zampini issize = 1; 655857de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 655914f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 656057de7509SStefano Zampini } else { 656114f0bfb9SStefano Zampini isidx = dest; 656257de7509SStefano Zampini } 656357de7509SStefano Zampini } else { 656457de7509SStefano Zampini issize = 0; 656557de7509SStefano Zampini isidx = -1; 656657de7509SStefano Zampini } 6567bb360cb4SStefano Zampini if (*n_subdomains != 1) *n_subdomains = active_procs; 656857de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 6569daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 657057de7509SStefano Zampini PetscFunctionReturn(0); 657157de7509SStefano Zampini } 6572c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 6573c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 657427b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 6575e7931f94SStefano Zampini 6576e7931f94SStefano Zampini /* Get info on mapping */ 65773bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6578e7931f94SStefano Zampini 6579e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 6580785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 6581e7931f94SStefano Zampini xadj[0] = 0; 6582e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 6583785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 6584785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 6585bb360cb4SStefano Zampini ierr = PetscCalloc1(n,&count);CHKERRQ(ierr); 658627b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 658727b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 658827b6a85dSStefano Zampini count[shared[i][j]] += 1; 6589e7931f94SStefano Zampini 659027b6a85dSStefano Zampini xadj_count = 0; 65912b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 659227b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 659327b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 6594d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 6595d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 6596d023bfaeSStefano Zampini xadj_count++; 659727b6a85dSStefano Zampini break; 659827b6a85dSStefano Zampini } 6599e7931f94SStefano Zampini } 6600e7931f94SStefano Zampini } 6601d023bfaeSStefano Zampini xadj[1] = xadj_count; 660227b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 66033bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6604e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 6605e7931f94SStefano Zampini 66063837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 6607e7931f94SStefano Zampini 660827b6a85dSStefano Zampini /* Restrict work on active processes only */ 660927b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 661027b6a85dSStefano Zampini if (void_procs) { 661127b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 661227b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 661327b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 661427b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 661527b6a85dSStefano Zampini } else { 661627b6a85dSStefano Zampini psubcomm = NULL; 661727b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 661827b6a85dSStefano Zampini } 661927b6a85dSStefano Zampini 662027b6a85dSStefano Zampini v_wgt = NULL; 662127b6a85dSStefano Zampini if (!color) { 6622e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 6623e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 6624e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6625c8587f34SStefano Zampini } else { 662652e5ac9dSStefano Zampini Mat subdomain_adj; 662752e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 662852e5ac9dSStefano Zampini MatPartitioning partitioner; 662927b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 663052e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 663157de7509SStefano Zampini PetscMPIInt size; 6632b0c7d250SStefano Zampini PetscBool aggregate; 6633b0c7d250SStefano Zampini 663427b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 663527b6a85dSStefano Zampini if (void_procs) { 663627b6a85dSStefano Zampini PetscInt prank = rank; 6637785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 663827b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 6639e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 6640e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 6641c8587f34SStefano Zampini } 6642e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 664327b6a85dSStefano Zampini } else { 664427b6a85dSStefano Zampini oldranks = NULL; 664527b6a85dSStefano Zampini } 6646b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 664727b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 6648b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 6649b0c7d250SStefano Zampini PetscMPIInt nrank; 6650b0c7d250SStefano Zampini PetscScalar *vals; 6651b0c7d250SStefano Zampini 665227b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 6653b0c7d250SStefano Zampini lrows = 0; 6654b0c7d250SStefano Zampini if (nrank<redprocs) { 6655b0c7d250SStefano Zampini lrows = size/redprocs; 6656b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 6657b0c7d250SStefano Zampini } 665827b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 6659b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 6660b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6661b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6662b0c7d250SStefano Zampini row = nrank; 6663b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 6664b0c7d250SStefano Zampini cols = adjncy; 6665b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 6666b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 6667b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 6668b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6669b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 667052e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 667152e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 667252e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6673b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 667427b6a85dSStefano Zampini if (use_vwgt) { 667527b6a85dSStefano Zampini Vec v; 667627b6a85dSStefano Zampini const PetscScalar *array; 667727b6a85dSStefano Zampini PetscInt nl; 667827b6a85dSStefano Zampini 667927b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 6680bb360cb4SStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)n,INSERT_VALUES);CHKERRQ(ierr); 668127b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 668227b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 668327b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 668427b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 668527b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 668622db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 668727b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 668827b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 668927b6a85dSStefano Zampini } 6690b0c7d250SStefano Zampini } else { 669127b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 669227b6a85dSStefano Zampini if (use_vwgt) { 669327b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 6694bb360cb4SStefano Zampini v_wgt[0] = n; 669527b6a85dSStefano Zampini } 6696b0c7d250SStefano Zampini } 669722b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 6698e7931f94SStefano Zampini 6699e7931f94SStefano Zampini /* Partition */ 670027b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 6701e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 670227b6a85dSStefano Zampini if (v_wgt) { 6703e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 6704c8587f34SStefano Zampini } 670557de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 670657de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 6707e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 6708e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 670922b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 6710e7931f94SStefano Zampini 671152e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 67126583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 671352e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 671452e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 671557de7509SStefano Zampini if (!aggregate) { 671657de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 671727b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 671827b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 671927b6a85dSStefano Zampini #endif 672057de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 672127b6a85dSStefano Zampini } else if (oldranks) { 6722b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 672327b6a85dSStefano Zampini } else { 672427b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 672557de7509SStefano Zampini } 672628143c3dSStefano Zampini } else { 6727b0c7d250SStefano Zampini PetscInt idxs[1]; 6728b0c7d250SStefano Zampini PetscMPIInt tag; 6729b0c7d250SStefano Zampini MPI_Request *reqs; 6730b0c7d250SStefano Zampini 6731b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 6732b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 6733b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 673427b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 673528143c3dSStefano Zampini } 673627b6a85dSStefano Zampini ierr = MPI_Recv(idxs,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 6737b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6738b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 673957de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 674027b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 674127b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 674227b6a85dSStefano Zampini #endif 674357de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[idxs[0]]]; 674427b6a85dSStefano Zampini } else if (oldranks) { 6745b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[idxs[0]]; 674627b6a85dSStefano Zampini } else { 674727b6a85dSStefano Zampini ranks_send_to_idx[0] = idxs[0]; 6748e7931f94SStefano Zampini } 674957de7509SStefano Zampini } 675052e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6751e7931f94SStefano Zampini /* clean up */ 6752e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 675352e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 6754e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 6755e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 6756e7931f94SStefano Zampini } 675727b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 675857de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 6759e7931f94SStefano Zampini 6760e7931f94SStefano Zampini /* assemble parallel IS for sends */ 6761e7931f94SStefano Zampini i = 1; 676227b6a85dSStefano Zampini if (!color) i=0; 676357de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 6764e7931f94SStefano Zampini PetscFunctionReturn(0); 6765e7931f94SStefano Zampini } 6766e7931f94SStefano Zampini 6767e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 6768e7931f94SStefano Zampini 67691e0482f5SStefano 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[]) 6770e7931f94SStefano Zampini { 677170cf5478SStefano Zampini Mat local_mat; 6772e7931f94SStefano Zampini IS is_sends_internal; 67739d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 67741ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 67759d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 6776e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 6777e7931f94SStefano Zampini PetscInt* l2gmap_indices; 6778e7931f94SStefano Zampini const PetscInt* is_indices; 6779e7931f94SStefano Zampini MatType new_local_type; 6780e7931f94SStefano Zampini /* buffers */ 6781e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 678228143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 67839d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 6784e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 67851ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 6786e7931f94SStefano Zampini /* MPI */ 678728143c3dSStefano Zampini MPI_Comm comm,comm_n; 678828143c3dSStefano Zampini PetscSubcomm subcomm; 6789e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 679028143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 679128143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 67921ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 67931ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 67941ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 6795e7931f94SStefano Zampini PetscErrorCode ierr; 6796e7931f94SStefano Zampini 6797e7931f94SStefano Zampini PetscFunctionBegin; 679857de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 6799e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 6800fbfcfee5SBarry Smith if (!ismatis) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot use %s on a matrix object which is not of type MATIS",PETSC_FUNCTION_NAME); 680157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 680257de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 680357de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 680457de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 680557de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 68061ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 68071ae86dd6SStefano Zampini if (nvecs) { 68081ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 68091ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 68101ae86dd6SStefano Zampini } 681157de7509SStefano Zampini /* further checks */ 6812e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 6813e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 6814e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 6815e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 6816e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 681757de7509SStefano Zampini if (reuse && *mat_n) { 681870cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 681957de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 682070cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 682128143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 682270cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 682370cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 682470cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 682570cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 682670cf5478SStefano Zampini } 6827e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 6828e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 682957de7509SStefano Zampini 6830e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 6831e7931f94SStefano Zampini if (!is_sends) { 683228143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 6833bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 6834c8587f34SStefano Zampini } else { 6835e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 6836e7931f94SStefano Zampini is_sends_internal = is_sends; 6837c8587f34SStefano Zampini } 6838e7931f94SStefano Zampini 6839e7931f94SStefano Zampini /* get comm */ 6840a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 6841e7931f94SStefano Zampini 6842e7931f94SStefano Zampini /* compute number of sends */ 6843e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 6844e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 6845e7931f94SStefano Zampini 6846e7931f94SStefano Zampini /* compute number of receives */ 6847e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 6848785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 6849e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 6850e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 6851e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 6852e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 6853e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 6854e7931f94SStefano Zampini 685528143c3dSStefano Zampini /* restrict comm if requested */ 685628143c3dSStefano Zampini subcomm = 0; 685728143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 685828143c3dSStefano Zampini if (restrict_comm) { 6859779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 6860779c1cceSStefano Zampini 686128143c3dSStefano Zampini color = 0; 686253a05cb3SStefano Zampini if (restrict_full) { 686353a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 686453a05cb3SStefano Zampini } else { 686553a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 686653a05cb3SStefano Zampini } 6867b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 686828143c3dSStefano Zampini subcommsize = commsize - subcommsize; 686928143c3dSStefano Zampini /* check if reuse has been requested */ 687057de7509SStefano Zampini if (reuse) { 687128143c3dSStefano Zampini if (*mat_n) { 687228143c3dSStefano Zampini PetscMPIInt subcommsize2; 687328143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 687428143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 687528143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 687628143c3dSStefano Zampini } else { 687728143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 687828143c3dSStefano Zampini } 687928143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 6880779c1cceSStefano Zampini PetscMPIInt rank; 6881779c1cceSStefano Zampini 6882779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 688328143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 688428143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 688528143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 6886306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 688728143c3dSStefano Zampini } 688828143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 688928143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 689028143c3dSStefano Zampini } else { 689128143c3dSStefano Zampini comm_n = comm; 689228143c3dSStefano Zampini } 689328143c3dSStefano Zampini 6894e7931f94SStefano Zampini /* prepare send/receive buffers */ 6895785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 6896e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 6897785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 6898e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 689928143c3dSStefano Zampini if (nis) { 6900854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 690128143c3dSStefano Zampini } 6902e7931f94SStefano Zampini 690328143c3dSStefano Zampini /* Get data from local matrices */ 69046c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 6905e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 6906e7931f94SStefano Zampini /* 6907e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 6908e7931f94SStefano Zampini send_buffer_idxs should contain: 6909e7931f94SStefano Zampini - MatType_PRIVATE type 6910e7931f94SStefano Zampini - PetscInt size_of_l2gmap 6911e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 6912e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 6913e7931f94SStefano Zampini */ 69146c4ed002SBarry Smith else { 6915e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 69163bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 6917854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 6918e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 6919e7931f94SStefano Zampini send_buffer_idxs[1] = i; 69203bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6921e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 69223bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 6923e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 6924e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 6925e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 6926e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 6927c8587f34SStefano Zampini } 6928c8587f34SStefano Zampini } 6929e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 693028143c3dSStefano Zampini /* additional is (if any) */ 693128143c3dSStefano Zampini if (nis) { 693228143c3dSStefano Zampini PetscMPIInt psum; 693328143c3dSStefano Zampini PetscInt j; 693428143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 693528143c3dSStefano Zampini PetscInt plen; 693628143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 693728143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 693828143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 693928143c3dSStefano Zampini } 6940854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 694128143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 694228143c3dSStefano Zampini PetscInt plen; 694328143c3dSStefano Zampini const PetscInt *is_array_idxs; 694428143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 694528143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 694628143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 694728143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 694828143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 694928143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 695028143c3dSStefano Zampini } 695128143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 695228143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 695328143c3dSStefano Zampini } 695428143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 695528143c3dSStefano Zampini } 69563b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 695728143c3dSStefano Zampini 6958e7931f94SStefano Zampini buf_size_idxs = 0; 6959e7931f94SStefano Zampini buf_size_vals = 0; 696028143c3dSStefano Zampini buf_size_idxs_is = 0; 69611ae86dd6SStefano Zampini buf_size_vecs = 0; 6962e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6963e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 6964e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 696528143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 69661ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 6967e7931f94SStefano Zampini } 6968785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 6969785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 697095ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 69711ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 6972e7931f94SStefano Zampini 6973e7931f94SStefano Zampini /* get new tags for clean communications */ 6974e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 6975e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 697628143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 69771ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 6978e7931f94SStefano Zampini 6979e7931f94SStefano Zampini /* allocate for requests */ 6980785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 6981785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 698295ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 69831ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 6984785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 6985785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 698695ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 69871ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 6988e7931f94SStefano Zampini 6989e7931f94SStefano Zampini /* communications */ 6990e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 6991e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 699228143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 69931ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 6994e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 6995e7931f94SStefano Zampini source_dest = onodes[i]; 6996e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 6997e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 6998e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 6999e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 700028143c3dSStefano Zampini if (nis) { 700157de7509SStefano Zampini source_dest = onodes_is[i]; 700228143c3dSStefano 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); 700328143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 700428143c3dSStefano Zampini } 70051ae86dd6SStefano Zampini if (nvecs) { 70061ae86dd6SStefano Zampini source_dest = onodes[i]; 70071ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 70081ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 70091ae86dd6SStefano Zampini } 7010e7931f94SStefano Zampini } 7011e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7012e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 7013e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 7014e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 701528143c3dSStefano Zampini if (nis) { 701628143c3dSStefano 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); 701728143c3dSStefano Zampini } 70181ae86dd6SStefano Zampini if (nvecs) { 70191ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 70201ae86dd6SStefano 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); 70211ae86dd6SStefano Zampini } 7022e7931f94SStefano Zampini } 7023e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7024e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 7025e7931f94SStefano Zampini 7026e7931f94SStefano Zampini /* assemble new l2g map */ 7027e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7028e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 70299d30be91SStefano Zampini new_local_rows = 0; 7030e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 70319d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7032e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7033e7931f94SStefano Zampini } 70349d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 7035e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 70369d30be91SStefano Zampini new_local_rows = 0; 7037e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 70389d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 70399d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7040e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7041e7931f94SStefano Zampini } 70429d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 70439d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 7044e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 7045e7931f94SStefano Zampini 7046e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 7047e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 7048e7931f94SStefano 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) */ 7049e7931f94SStefano Zampini if (n_recvs) { 705028143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 7051e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7052e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7053e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 7054e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 7055e7931f94SStefano Zampini break; 7056e7931f94SStefano Zampini } 7057e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7058e7931f94SStefano Zampini } 7059e7931f94SStefano Zampini switch (new_local_type_private) { 706028143c3dSStefano Zampini case MATDENSE_PRIVATE: 7061e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7062e7931f94SStefano Zampini bs = 1; 7063e7931f94SStefano Zampini break; 7064e7931f94SStefano Zampini case MATAIJ_PRIVATE: 7065e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7066e7931f94SStefano Zampini bs = 1; 7067e7931f94SStefano Zampini break; 7068e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 7069e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 7070e7931f94SStefano Zampini break; 7071e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 7072e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 7073e7931f94SStefano Zampini break; 7074e7931f94SStefano Zampini default: 7075fbfcfee5SBarry Smith SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,PETSC_FUNCTION_NAME); 7076e7931f94SStefano Zampini break; 7077e7931f94SStefano Zampini } 7078ed8ed4edSstefano_zampini } else { /* by default, new_local_type is seqaij */ 7079ed8ed4edSstefano_zampini new_local_type = MATSEQAIJ; 708028143c3dSStefano Zampini bs = 1; 7081e7931f94SStefano Zampini } 7082e7931f94SStefano Zampini 708370cf5478SStefano Zampini /* create MATIS object if needed */ 708457de7509SStefano Zampini if (!reuse) { 7085e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 7086e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 708770cf5478SStefano Zampini } else { 708870cf5478SStefano Zampini /* it also destroys the local matrices */ 708957de7509SStefano Zampini if (*mat_n) { 709070cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 709157de7509SStefano Zampini } else { /* this is a fake object */ 709257de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 709357de7509SStefano Zampini } 709470cf5478SStefano Zampini } 709570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 7096e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 70979d30be91SStefano Zampini 70989d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 70999d30be91SStefano Zampini 71009d30be91SStefano Zampini /* Global to local map of received indices */ 71019d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 71029d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 71039d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 71049d30be91SStefano Zampini 71059d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 71069d30be91SStefano Zampini buf_size_idxs = 0; 71079d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 71089d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 71099d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 71109d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 71119d30be91SStefano Zampini } 71129d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 71139d30be91SStefano Zampini 71149d30be91SStefano Zampini /* set preallocation */ 71159d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 71169d30be91SStefano Zampini if (!newisdense) { 71179d30be91SStefano Zampini PetscInt *new_local_nnz=0; 71189d30be91SStefano Zampini 71199d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 71209d30be91SStefano Zampini if (n_recvs) { 71219d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 71229d30be91SStefano Zampini } 71239d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 71249d30be91SStefano Zampini PetscInt j; 71259d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 71269d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 71279d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 71289d30be91SStefano Zampini } 71299d30be91SStefano Zampini } else { 71309d30be91SStefano Zampini /* TODO */ 71319d30be91SStefano Zampini } 71329d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 71339d30be91SStefano Zampini } 71349d30be91SStefano Zampini if (new_local_nnz) { 71359d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 71369d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 71379d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 71389d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 71399d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 71409d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 71419d30be91SStefano Zampini } else { 71429d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 71439d30be91SStefano Zampini } 71449d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 71459d30be91SStefano Zampini } else { 71469d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 71479d30be91SStefano Zampini } 7148e7931f94SStefano Zampini 7149e7931f94SStefano Zampini /* set values */ 7150e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 71519d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 7152e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7153e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 7154e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 71559d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 7156e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7157e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7158e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 715928143c3dSStefano Zampini } else { 716028143c3dSStefano Zampini /* TODO */ 7161e7931f94SStefano Zampini } 7162e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7163e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 7164e7931f94SStefano Zampini } 7165e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7166e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 71673b3b1effSJed Brown ierr = MatISRestoreLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 716870cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 716970cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 71709d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 7171e7931f94SStefano Zampini 7172dfd14d43SStefano Zampini #if 0 717328143c3dSStefano Zampini if (!restrict_comm) { /* check */ 7174e7931f94SStefano Zampini Vec lvec,rvec; 7175e7931f94SStefano Zampini PetscReal infty_error; 7176e7931f94SStefano Zampini 71772a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 7178e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 7179e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 7180e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 718170cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 7182e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 7183e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 7184e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 7185e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 7186e7931f94SStefano Zampini } 718728143c3dSStefano Zampini #endif 7188e7931f94SStefano Zampini 718928143c3dSStefano Zampini /* assemble new additional is (if any) */ 719028143c3dSStefano Zampini if (nis) { 719128143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 719228143c3dSStefano Zampini 719328143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7194854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 719528143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 719628143c3dSStefano Zampini psum = 0; 719728143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 719828143c3dSStefano Zampini for (j=0;j<nis;j++) { 719928143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 720028143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 720128143c3dSStefano Zampini psum += plen; 720228143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 720328143c3dSStefano Zampini } 720428143c3dSStefano Zampini } 7205854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 7206854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 720728143c3dSStefano Zampini for (i=1;i<nis;i++) { 720828143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 720928143c3dSStefano Zampini } 721028143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 721128143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 721228143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 721328143c3dSStefano Zampini for (j=0;j<nis;j++) { 721428143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 721528143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 721628143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 721728143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 721828143c3dSStefano Zampini } 721928143c3dSStefano Zampini } 722028143c3dSStefano Zampini for (i=0;i<nis;i++) { 722128143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 722228143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 722328143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 722428143c3dSStefano Zampini } 722528143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 722628143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 722728143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 722828143c3dSStefano Zampini } 7229e7931f94SStefano Zampini /* free workspace */ 723028143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 7231e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7232e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 7233e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7234e7931f94SStefano Zampini if (isdense) { 7235e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7236e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 72373b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 7238e7931f94SStefano Zampini } else { 7239e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 7240e7931f94SStefano Zampini } 724128143c3dSStefano Zampini if (nis) { 724228143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 724328143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 724428143c3dSStefano Zampini } 72451ae86dd6SStefano Zampini 72461ae86dd6SStefano Zampini if (nvecs) { 72471ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 72481ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 72491ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 72501ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 72511ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 72521ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 72531ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 72541ae86dd6SStefano Zampini /* set values */ 72551ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 72561ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 72571ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 72581ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 72591ae86dd6SStefano Zampini PetscInt j; 72601ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 72611ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 72621ae86dd6SStefano Zampini } 72631ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 72641ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 72651ae86dd6SStefano Zampini } 72661ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 72671ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 72681ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 72691ae86dd6SStefano Zampini } 72701ae86dd6SStefano Zampini 72711ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 72721ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 7273e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 7274e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 72751ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 727628143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 7277e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 7278e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 72791ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 728028143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 7281e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 7282e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 7283e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 7284e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 7285e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 728628143c3dSStefano Zampini if (nis) { 728728143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 728828143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 728928143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 729028143c3dSStefano Zampini } 729128143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 729228143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 729328143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 729428143c3dSStefano Zampini for (i=0;i<nis;i++) { 729528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 729628143c3dSStefano Zampini } 72971ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 72981ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 72991ae86dd6SStefano Zampini } 730053a05cb3SStefano Zampini *mat_n = NULL; 730128143c3dSStefano Zampini } 7302e7931f94SStefano Zampini PetscFunctionReturn(0); 7303e7931f94SStefano Zampini } 7304a57a6d2fSStefano Zampini 730512edc857SStefano Zampini /* temporary hack into ksp private data structure */ 7306af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 730712edc857SStefano Zampini 7308c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 7309c8587f34SStefano Zampini { 7310c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7311c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 731220a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 73131ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 73141e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 73159881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 731620a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 73176e683305SStefano Zampini IS coarse_is,*isarray; 73186e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 731930368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 7320f9eb5b7dSStefano Zampini PC pc_temp; 7321c8587f34SStefano Zampini PCType coarse_pc_type; 7322c8587f34SStefano Zampini KSPType coarse_ksp_type; 7323f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 73244f3a063dSStefano Zampini PetscBool isredundant,isbddc,isnn,coarse_reuse; 73251e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 732668457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 732722bc73bbSStefano Zampini PetscScalar *array; 732857de7509SStefano Zampini MatReuse coarse_mat_reuse; 732957de7509SStefano Zampini PetscBool restr, full_restr, have_void; 73307de4f681Sstefano_zampini PetscMPIInt commsize; 73319881197aSStefano Zampini PetscErrorCode ierr; 7332fdc09c96SStefano Zampini 7333c8587f34SStefano Zampini PetscFunctionBegin; 7334c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 733568457ee5SStefano 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 */ 7336fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 73375a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 73387de4f681Sstefano_zampini 73397de4f681Sstefano_zampini pcbddc->new_primal_space = PETSC_TRUE; 7340fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 7341f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 7342f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 7343f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 7344fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 734551bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 734651bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 7347727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 7348fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7349fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 7350fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7351f4ddd8eeSStefano Zampini } 7352fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 7353fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7354f4ddd8eeSStefano Zampini } 735570cf5478SStefano Zampini /* reset any subassembling information */ 735657de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 735770cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 735857de7509SStefano Zampini } 73596e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 7360fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7361f4ddd8eeSStefano Zampini } 736257de7509SStefano Zampini /* assemble coarse matrix */ 736357de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 736457de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 736557de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 736657de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 736718a45a71SStefano Zampini } else { 736857de7509SStefano Zampini coarse_mat = NULL; 736957de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 73706e683305SStefano Zampini } 7371e7931f94SStefano Zampini 7372abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 7373abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 7374abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 7375abbbba34SStefano Zampini 7376abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 737722bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 737822bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 737922bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 738022bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 7381e176bc59SStefano 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); 73826e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 73836e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 73846e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7385abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 7386abbbba34SStefano Zampini 738757de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 738857de7509SStefano Zampini im_active = !!(pcis->n); 738957de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 739057de7509SStefano Zampini 739114f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 739257de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 739357de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 73947de4f681Sstefano_zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&commsize);CHKERRQ(ierr); 739557de7509SStefano Zampini coarse_mat_is = NULL; 739657de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 739757de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 73981ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 739957de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 740057de7509SStefano Zampini if (multilevel_requested) { 740157de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 740257de7509SStefano Zampini restr = PETSC_FALSE; 740357de7509SStefano Zampini full_restr = PETSC_FALSE; 740457de7509SStefano Zampini } else { 740557de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 740657de7509SStefano Zampini restr = PETSC_TRUE; 740757de7509SStefano Zampini full_restr = PETSC_TRUE; 740857de7509SStefano Zampini } 74097de4f681Sstefano_zampini if (!pcbddc->coarse_size || commsize == 1) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 741057de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 741157de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 7412a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 7413bb360cb4SStefano Zampini if (multilevel_requested) { 7414bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7415bb360cb4SStefano Zampini } else { 7416bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7417bb360cb4SStefano Zampini } 7418a198735bSStefano Zampini } else { 74197de4f681Sstefano_zampini PetscMPIInt rank; 7420a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 74217de4f681Sstefano_zampini have_void = (active_procs == (PetscInt)commsize) ? PETSC_FALSE : PETSC_TRUE; 7422a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 7423a198735bSStefano Zampini } 742457de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 742557de7509SStefano Zampini PetscInt psum; 742657de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 742757de7509SStefano Zampini else psum = 0; 742857de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 74297de4f681Sstefano_zampini if (ncoarse < commsize) have_void = PETSC_TRUE; 743057de7509SStefano Zampini } 743157de7509SStefano Zampini /* determine if we can go multilevel */ 743257de7509SStefano Zampini if (multilevel_requested) { 743357de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 743457de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 743557de7509SStefano Zampini } 743657de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 743757de7509SStefano Zampini 7438e4d548c7SStefano Zampini /* dump subassembling pattern */ 7439e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 7440e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 7441e4d548c7SStefano Zampini } 7442e4d548c7SStefano Zampini 74436e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 74441e0482f5SStefano Zampini nedcfield = -1; 74451e0482f5SStefano Zampini if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal)) { /* protects from unneded computations */ 74466e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 74476e683305SStefano Zampini const PetscInt *idxs; 74486e683305SStefano Zampini ISLocalToGlobalMapping tmap; 74496e683305SStefano Zampini 74506e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 74510be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 74526e683305SStefano Zampini /* allocate space for temporary storage */ 7453854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 7454854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 74556e683305SStefano Zampini /* allocate for IS array */ 74566e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 74571e0482f5SStefano Zampini if (pcbddc->nedclocal) { 74581e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 74591e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 74601e0482f5SStefano Zampini } else { 74611e0482f5SStefano Zampini nedcfield = 0; 74621e0482f5SStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%d)",nisdofs); 74631e0482f5SStefano Zampini nisdofs = 1; 74641e0482f5SStefano Zampini } 74651e0482f5SStefano Zampini } 74666e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 746727b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 746830368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 7469854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 74706e683305SStefano Zampini /* dofs splitting */ 74716e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 74726e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 74731e0482f5SStefano Zampini if (nedcfield != i) { 74746e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 74756e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 74766e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 74776e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 74781e0482f5SStefano Zampini } else { 74791e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 74801e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 74811e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 7482eee23b56SStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping coarse nedelec field! %d != %d\n",tsize,nout); 74831e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 74841e0482f5SStefano Zampini } 74856e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 748630368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 74876e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 74886e683305SStefano Zampini } 74896e683305SStefano Zampini /* neumann boundaries */ 74906e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 74916e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 74926e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 74936e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 74946e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 74956e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 74966e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 749730368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 74986e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 74996e683305SStefano Zampini } 75006e683305SStefano Zampini /* free memory */ 75016e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 75026e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 75036e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 75046e683305SStefano Zampini } else { 75056e683305SStefano Zampini nis = 0; 75066e683305SStefano Zampini nisdofs = 0; 75076e683305SStefano Zampini nisneu = 0; 750830368db7SStefano Zampini nisvert = 0; 75096e683305SStefano Zampini isarray = NULL; 75106e683305SStefano Zampini } 75116e683305SStefano Zampini /* destroy no longer needed map */ 75126e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 75136e683305SStefano Zampini 751457de7509SStefano Zampini /* subassemble */ 751557de7509SStefano Zampini if (multilevel_allowed) { 75161ae86dd6SStefano Zampini Vec vp[1]; 75171ae86dd6SStefano Zampini PetscInt nvecs = 0; 751857de7509SStefano Zampini PetscBool reuse,reuser; 75191ae86dd6SStefano Zampini 752057de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 752157de7509SStefano Zampini else reuse = PETSC_FALSE; 752257de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 75231ae86dd6SStefano Zampini vp[0] = NULL; 75241ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 75251ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 75261ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 75271ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 75281ae86dd6SStefano Zampini nvecs = 1; 75291ae86dd6SStefano Zampini 75301ae86dd6SStefano Zampini if (pcbddc->divudotp) { 7531a198735bSStefano Zampini Mat B,loc_divudotp; 75321ae86dd6SStefano Zampini Vec v,p; 75331ae86dd6SStefano Zampini IS dummy; 75341ae86dd6SStefano Zampini PetscInt np; 75351ae86dd6SStefano Zampini 7536a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 7537a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 75381ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 75397dae84e0SHong Zhang ierr = MatCreateSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 75401ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 75411ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 75421ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 75431ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 75441ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 75451ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 75461ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 75471ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 75481ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 75491ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 75501ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 75511ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 755274e2c79eSStefano Zampini } 75531ae86dd6SStefano Zampini } 75541ae86dd6SStefano Zampini if (reuser) { 75551e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 755674e2c79eSStefano Zampini } else { 75571e0482f5SStefano 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); 75581ae86dd6SStefano Zampini } 75591ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 75601ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 75611ae86dd6SStefano Zampini PetscInt nl; 75621ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 75631ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 75641ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 75651ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 75661ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 75671ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 75681ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 75691ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 7570a198735bSStefano Zampini } else { 7571a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 75721ae86dd6SStefano Zampini } 75731ae86dd6SStefano Zampini } else { 75741e0482f5SStefano 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); 75756e683305SStefano Zampini } 757657de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 757757de7509SStefano Zampini PetscMPIInt size; 7578f913dca9SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size);CHKERRQ(ierr); 757957de7509SStefano Zampini if (!multilevel_allowed) { 758057de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 75816e683305SStefano Zampini } else { 758257de7509SStefano Zampini Mat A; 7583779c1cceSStefano Zampini 758457de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 758557de7509SStefano Zampini if (coarse_mat_is) { 758657de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 758757de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 758857de7509SStefano Zampini coarse_mat = coarse_mat_is; 758957de7509SStefano Zampini } 759057de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 759157de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 759257de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 7593779c1cceSStefano Zampini } 7594779c1cceSStefano Zampini } 759557de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 759657de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 75976e683305SStefano Zampini 75986e683305SStefano Zampini /* create local to global scatters for coarse problem */ 759968457ee5SStefano Zampini if (compute_vecs) { 76006e683305SStefano Zampini PetscInt lrows; 76016e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 760257de7509SStefano Zampini if (coarse_mat) { 760357de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 76046e683305SStefano Zampini } else { 76056e683305SStefano Zampini lrows = 0; 76066e683305SStefano Zampini } 76076e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 76086e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 76096e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 76106e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 76116e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 76126e683305SStefano Zampini } 76136e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 7614c8587f34SStefano Zampini 7615f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 7616f9eb5b7dSStefano Zampini if (multilevel_allowed) { 7617f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 7618f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 7619f9eb5b7dSStefano Zampini } else { 7620f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 7621f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 7622c8587f34SStefano Zampini } 7623c8587f34SStefano Zampini 76246e683305SStefano Zampini /* print some info if requested */ 76256e683305SStefano Zampini if (pcbddc->dbg_flag) { 76266e683305SStefano Zampini if (!multilevel_allowed) { 76276e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 76286e683305SStefano Zampini if (multilevel_requested) { 76296e683305SStefano 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); 76306e683305SStefano Zampini } else if (pcbddc->max_levels) { 76316e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 76326e683305SStefano Zampini } 76336e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 76346e683305SStefano Zampini } 76356e683305SStefano Zampini } 76366e683305SStefano Zampini 76371e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 76381e0482f5SStefano Zampini coarseG = NULL; 76391e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 76401e0482f5SStefano Zampini MPI_Comm ccomm; 76411e0482f5SStefano Zampini if (coarse_mat) { 76421e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 76431e0482f5SStefano Zampini } else { 76441e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 76451e0482f5SStefano Zampini } 76461e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 76471e0482f5SStefano Zampini } 76481e0482f5SStefano Zampini 7649f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 765057de7509SStefano Zampini if (coarse_mat) { 76516a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 76526e683305SStefano Zampini if (pcbddc->dbg_flag) { 765357de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 76546e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 76556e683305SStefano Zampini } 7656f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 7657312be037SStefano Zampini char prefix[256],str_level[16]; 7658e604994aSStefano Zampini size_t len; 76591e0482f5SStefano Zampini 766057de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 7661422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 7662c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 7663f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 766457de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7665c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 76666e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 7667c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 76681e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 7669c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7670e604994aSStefano Zampini /* prefix */ 7671e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 7672e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 7673e604994aSStefano Zampini if (!pcbddc->current_level) { 7674e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 7675e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 7676c8587f34SStefano Zampini } else { 7677e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 7678312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 7679312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 768034d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 7681312be037SStefano Zampini sprintf(str_level,"l%d_",(int)(pcbddc->current_level)); 7682e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 7683e604994aSStefano Zampini } 7684e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 76853e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 76863e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 76873e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 76883e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 7689f9eb5b7dSStefano Zampini /* allow user customization */ 7690f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 76913e3c6dadSStefano Zampini } 76923e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 769351bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 76943e3c6dadSStefano Zampini if (nisdofs) { 76953e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 76963e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 76973e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 76983e3c6dadSStefano Zampini } 76993e3c6dadSStefano Zampini } 77003e3c6dadSStefano Zampini if (nisneu) { 77013e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 77023e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 7703312be037SStefano Zampini } 770430368db7SStefano Zampini if (nisvert) { 770530368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 770630368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 770730368db7SStefano Zampini } 77081e0482f5SStefano Zampini if (coarseG) { 77091e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 77101e0482f5SStefano Zampini } 7711f9eb5b7dSStefano Zampini 7712f9eb5b7dSStefano Zampini /* get some info after set from options */ 7713f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 7714f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 77154f3a063dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 7716b76f3995Sstefano_zampini /* multilevel can only be requested via -pc_bddc_levels or PCBDDCSetLevels */ 7717b76f3995Sstefano_zampini if (isbddc && !multilevel_allowed) { 7718f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7719f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 7720f9eb5b7dSStefano Zampini } 7721b76f3995Sstefano_zampini /* multilevel cannot be done with coarse PCs different from BDDC or NN */ 7722b76f3995Sstefano_zampini if (multilevel_requested && !isbddc && !isnn) { 7723b76f3995Sstefano_zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 7724b76f3995Sstefano_zampini isbddc = PETSC_TRUE; 7725b76f3995Sstefano_zampini isnn = PETSC_FALSE; 7726b76f3995Sstefano_zampini } 772739f0f02cSStefano Zampini ierr = PCFactorSetReuseFill(pc_temp,PETSC_TRUE);CHKERRQ(ierr); 77284f3a063dSStefano Zampini if (isredundant) { 77294f3a063dSStefano Zampini KSP inner_ksp; 77304f3a063dSStefano Zampini PC inner_pc; 77319326c5c6Sstefano_zampini 77324f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 77334f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 77344f3a063dSStefano Zampini ierr = PCFactorSetReuseFill(inner_pc,PETSC_TRUE);CHKERRQ(ierr); 77354f3a063dSStefano Zampini } 7736f9eb5b7dSStefano Zampini 773757de7509SStefano Zampini /* parameters which miss an API */ 773857de7509SStefano Zampini if (isbddc) { 7739720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 7740720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 774157de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 774227b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 774327b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 7744a198735bSStefano Zampini Mat coarsedivudotp_is; 7745a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 7746a198735bSStefano Zampini IS row,col; 7747a198735bSStefano Zampini const PetscInt *gidxs; 7748a198735bSStefano Zampini PetscInt n,st,M,N; 7749a198735bSStefano Zampini 7750a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 7751a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 7752a198735bSStefano Zampini st = st-n; 7753a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 7754a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 7755a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 7756a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7757a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 7758a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7759a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 7760a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 7761a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 7762a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 7763a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 7764a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 7765a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 7766a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 7767a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 7768a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 7769a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7770a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7771a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 7772a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 77738ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 7774a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 7775720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 777659e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 7777720d30f9SStefano Zampini } 7778d4d8cf7bSStefano Zampini } 77799881197aSStefano Zampini 77803301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 77815a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 77823301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 77833301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 77843301b35fSStefano Zampini } 77853301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 77863301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 77873301b35fSStefano Zampini } 77883301b35fSStefano Zampini if (pc->pmat->spd_set) { 77893301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 77903301b35fSStefano Zampini } 779127b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 779227b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 779327b6a85dSStefano Zampini } 77946e683305SStefano Zampini /* set operators */ 77955f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 77966e683305SStefano Zampini if (pcbddc->dbg_flag) { 77976e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 77986e683305SStefano Zampini } 77996e683305SStefano Zampini } 78001e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 78016e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 7802b1ecc7b1SStefano Zampini #if 0 7803b9b85e73SStefano Zampini { 7804b9b85e73SStefano Zampini PetscViewer viewer; 7805b9b85e73SStefano Zampini char filename[256]; 7806b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 7807b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 78086a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 7809b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 7810f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 7811b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 7812b9b85e73SStefano Zampini } 7813b9b85e73SStefano Zampini #endif 7814f9eb5b7dSStefano Zampini 781598a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 781698a51de6SStefano Zampini Vec crhs,csol; 781704708bb6SStefano Zampini 7818f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 7819f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 7820f347579bSStefano Zampini if (!csol) { 78212a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 7822f9eb5b7dSStefano Zampini } 7823f347579bSStefano Zampini if (!crhs) { 78242a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 7825f347579bSStefano Zampini } 7826b0f5fe93SStefano Zampini } 78271ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 7828b0f5fe93SStefano Zampini 7829b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 7830b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 7831b0f5fe93SStefano Zampini 7832b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 78334f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 78344f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 78354f1b2e48SStefano Zampini } 7836b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 7837b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 7838b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7839b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 7840b0f5fe93SStefano Zampini if (coarse_mat) { 7841b0f5fe93SStefano Zampini Vec nullv; 7842b0f5fe93SStefano Zampini PetscScalar *array,*array2; 7843b0f5fe93SStefano Zampini PetscInt nl; 7844b0f5fe93SStefano Zampini 7845b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 7846b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 7847b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7848b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 7849b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 7850b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 7851b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 7852b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 7853b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 7854b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 7855b0f5fe93SStefano Zampini } 7856b0f5fe93SStefano Zampini } 7857b0f5fe93SStefano Zampini 7858b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 7859b0f5fe93SStefano Zampini PetscBool ispreonly; 7860b0f5fe93SStefano Zampini 7861b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7862b0f5fe93SStefano Zampini PetscBool isnull; 7863b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 7864bef83e63SStefano Zampini if (isnull) { 7865b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 7866b0f5fe93SStefano Zampini } 7867bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 7868b0f5fe93SStefano Zampini } 7869b0f5fe93SStefano Zampini /* setup coarse ksp */ 7870b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 7871cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 7872cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 78736e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 7874c8587f34SStefano Zampini KSP check_ksp; 78752b510759SStefano Zampini KSPType check_ksp_type; 7876c8587f34SStefano Zampini PC check_pc; 78776e683305SStefano Zampini Vec check_vec,coarse_vec; 78786a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 78792b510759SStefano Zampini PetscInt its; 78806e683305SStefano Zampini PetscBool compute_eigs; 78816e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 78826e683305SStefano Zampini PetscInt neigs; 78838e185a42SStefano Zampini const char *prefix; 7884c8587f34SStefano Zampini 78852b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 78866e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 7887422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 788823ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7889f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 7890e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 7891e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 7892e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 78932b510759SStefano Zampini if (ispreonly) { 78942b510759SStefano Zampini check_ksp_type = KSPPREONLY; 78956e683305SStefano Zampini compute_eigs = PETSC_FALSE; 78962b510759SStefano Zampini } else { 7897cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 78986e683305SStefano Zampini compute_eigs = PETSC_TRUE; 7899c8587f34SStefano Zampini } 7900c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 79016e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 79026e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 79036e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 7904a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 7905a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 7906a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 7907a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 7908c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 7909c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 7910c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 7911c8587f34SStefano Zampini /* create random vec */ 79122701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 7913c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 79146e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 7915c8587f34SStefano Zampini /* solve coarse problem */ 79166e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 7917cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 79186e683305SStefano Zampini if (compute_eigs) { 7919854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 7920854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 79216e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 79221ae86dd6SStefano Zampini if (neigs) { 79236e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 79246e683305SStefano Zampini lambda_min = eigs_r[0]; 79256e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 79262701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 79272701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 7928cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 7929cbcc2c2aSStefano Zampini } 7930c8587f34SStefano Zampini } 7931c8587f34SStefano Zampini } 79321ae86dd6SStefano Zampini } 7933cbcc2c2aSStefano Zampini 7934c8587f34SStefano Zampini /* check coarse problem residual error */ 79356e683305SStefano Zampini if (pcbddc->dbg_flag) { 79366e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 79376e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 79386e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 7939c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 79406e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 79416e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 7942779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 79436e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 79446e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 79456e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 79466e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 7947b0f5fe93SStefano Zampini if (CoarseNullSpace) { 7948b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 7949b0f5fe93SStefano Zampini } 79506e683305SStefano Zampini if (compute_eigs) { 79516e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 7952b03ebc13SStefano Zampini KSPConvergedReason reason; 7953deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 7954c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 7955b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 79566e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 7957b03ebc13SStefano 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); 79586e683305SStefano Zampini for (i=0;i<neigs;i++) { 79596e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 7960c8587f34SStefano Zampini } 79616e683305SStefano Zampini } 79626e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 79636e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 79646e683305SStefano Zampini } 7965e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 79662701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 7967c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 79686e683305SStefano Zampini if (compute_eigs) { 79696e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 79706e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 7971c8587f34SStefano Zampini } 79726e683305SStefano Zampini } 79736e683305SStefano Zampini } 7974bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 7975cbcc2c2aSStefano Zampini /* print additional info */ 7976cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 79776e683305SStefano Zampini /* waits until all processes reaches this point */ 79786e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 7979cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 7980cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 7981cbcc2c2aSStefano Zampini } 7982cbcc2c2aSStefano Zampini 79832b510759SStefano Zampini /* free memory */ 7984fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 7985c8587f34SStefano Zampini PetscFunctionReturn(0); 7986c8587f34SStefano Zampini } 7987674ae819SStefano Zampini 7988f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 7989f34684f1SStefano Zampini { 7990f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 7991f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 7992f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 7993dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 7994dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 799573be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 7996dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 7997f34684f1SStefano Zampini PetscErrorCode ierr; 7998f34684f1SStefano Zampini 7999f34684f1SStefano Zampini PetscFunctionBegin; 8000f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 80016c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 8002dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 80033bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 8004dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8005dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 80066583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 8007dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 8008dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 8009dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 80106c4ed002SBarry 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); 8011dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 8012dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8013dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 8014dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8015dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8016f34684f1SStefano Zampini 8017f34684f1SStefano Zampini /* check numbering */ 8018f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 8019019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 8020dc456d91SStefano Zampini PetscInt i; 8021b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 8022f34684f1SStefano Zampini 8023f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8024f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8025f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 80261575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8027019a44ceSStefano Zampini /* counter */ 8028019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8029019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 8030019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8031019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8032019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8033019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8034f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 8035f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 8036727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 8037f34684f1SStefano Zampini } 8038f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8039f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8040f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8041e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8042e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8043e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8044e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8045f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8046019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8047f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8048019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 80492c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 805075c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 8051b9b85e73SStefano Zampini set_error = PETSC_TRUE; 80522c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 80532c66d082SStefano 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); 8054f34684f1SStefano Zampini } 8055f34684f1SStefano Zampini } 8056019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8057b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8058f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8059f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8060f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 8061f34684f1SStefano Zampini } 8062f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8063f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8064e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8065e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8066f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 8067f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 8068b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 8069ca8b9ea9SStefano Zampini PetscInt *gidxs; 8070ca8b9ea9SStefano Zampini 8071ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 80723bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 8073f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 8074f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8075f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 8076f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 80774bc2dc4bSStefano 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); 8078f34684f1SStefano Zampini } 8079f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8080ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 8081f34684f1SStefano Zampini } 8082f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 80831575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8084302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 8085f34684f1SStefano Zampini } 80868bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 8087f34684f1SStefano Zampini /* get back data */ 8088f34684f1SStefano Zampini *coarse_size_n = coarse_size; 8089f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 8090674ae819SStefano Zampini PetscFunctionReturn(0); 8091674ae819SStefano Zampini } 8092674ae819SStefano Zampini 8093a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 8094e456f2a8SStefano Zampini { 8095e456f2a8SStefano Zampini IS localis_t; 8096a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 8097e456f2a8SStefano Zampini PetscScalar *vals; 8098e456f2a8SStefano Zampini PetscErrorCode ierr; 8099e456f2a8SStefano Zampini 8100e456f2a8SStefano Zampini PetscFunctionBegin; 8101a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 8102e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 8103854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 8104e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 8105e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8106a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 8107a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 81081035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 8109a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 81101035eff8SStefano Zampini } 8111a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 8112e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8113e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 8114a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 8115a7dc3881SStefano Zampini /* now compute set in local ordering */ 8116a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8117a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8118a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8119a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 8120a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8121ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8122e456f2a8SStefano Zampini lsize++; 8123e456f2a8SStefano Zampini } 8124e456f2a8SStefano Zampini } 8125854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 8126a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8127ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8128e456f2a8SStefano Zampini idxs[lsize++] = i; 8129e456f2a8SStefano Zampini } 8130e456f2a8SStefano Zampini } 8131a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8132a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 8133e456f2a8SStefano Zampini *localis = localis_t; 8134e456f2a8SStefano Zampini PetscFunctionReturn(0); 8135e456f2a8SStefano Zampini } 8136906d46d4SStefano Zampini 813708122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 8138b96c3477SStefano Zampini { 8139a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8140b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8141b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 8142a64f4aa4SStefano Zampini Mat S_j; 8143b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 8144b96c3477SStefano Zampini PetscBool free_used_adj; 8145b96c3477SStefano Zampini PetscErrorCode ierr; 8146b96c3477SStefano Zampini 8147b96c3477SStefano Zampini PetscFunctionBegin; 8148b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 8149b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 815008122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 8151b96c3477SStefano Zampini used_xadj = NULL; 8152b96c3477SStefano Zampini used_adjncy = NULL; 8153b96c3477SStefano Zampini } else { 815408122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 815508122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 815608122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 815708122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 8158b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 8159b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 8160b96c3477SStefano Zampini } else { 81612fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 8162b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 8163b96c3477SStefano Zampini PetscInt nvtxs; 8164b96c3477SStefano Zampini 81652fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 81662fffb893SStefano Zampini if (flg_row) { 8167b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 8168b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 8169b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 8170b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 81712fffb893SStefano Zampini } else { 81722fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 81732fffb893SStefano Zampini used_xadj = NULL; 81742fffb893SStefano Zampini used_adjncy = NULL; 81752fffb893SStefano Zampini } 81762fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 8177b96c3477SStefano Zampini } 8178b96c3477SStefano Zampini } 8179d5574798SStefano Zampini 8180d5574798SStefano Zampini /* setup sub_schurs data */ 8181a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8182df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 8183df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 8184a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 818591af6908SStefano 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); 8186a64f4aa4SStefano Zampini } else { 818772b8c272SStefano Zampini Mat change = NULL; 81889d54b7f4SStefano Zampini Vec scaling = NULL; 8189111315fdSstefano_zampini IS change_primal = NULL, iP; 8190111315fdSstefano_zampini PetscInt benign_n; 8191111315fdSstefano_zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 8192111315fdSstefano_zampini PetscBool isseqaij,need_change = PETSC_FALSE; 8193111315fdSstefano_zampini PetscBool discrete_harmonic = PETSC_FALSE; 8194a3df083aSStefano Zampini 81955feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 81965feab87aSStefano Zampini PetscInt n_vertices; 81975feab87aSStefano Zampini 81985feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 81992034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 82005feab87aSStefano Zampini } 820104708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 820204708bb6SStefano Zampini if (!isseqaij) { 820304708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 820404708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 820504708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 820604708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 820704708bb6SStefano Zampini } else { 8208511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 820904708bb6SStefano Zampini } 821004708bb6SStefano Zampini } 8211a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 8212a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 8213ca92afb2SStefano Zampini } else { 8214a3df083aSStefano Zampini benign_n = 0; 8215ca92afb2SStefano Zampini } 8216b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 8217b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 8218b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 821972b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 822022db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 8221b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 822222db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 8223b7ab4a40SStefano Zampini } 8224b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 8225b7ab4a40SStefano 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 */ 8226b7ab4a40SStefano Zampini if (need_change) { 822788c03ad3SStefano Zampini PC_IS *pcisf; 822888c03ad3SStefano Zampini PC_BDDC *pcbddcf; 822988c03ad3SStefano Zampini PC pcf; 823088c03ad3SStefano Zampini 8231e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 823288c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 823388c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 823488c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 8235b9be95fcSstefano_zampini 823688c03ad3SStefano Zampini /* hacks */ 823788c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 823872b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 823972b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 824072b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 824172b8c272SStefano Zampini pcisf->n = pcis->n; 824272b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 824388c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 824488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 824588c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 824688c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 824788c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 824888c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 824972b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 825088c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 8251b9be95fcSstefano_zampini 8252b9be95fcSstefano_zampini /* setup constraints so that we can get information on primal vertices and change of basis (in local numbering) */ 825388c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 825472b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 825572b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 825672b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 825772b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 8258b9be95fcSstefano_zampini 825988c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 826072b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 826188c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 826288c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 826388c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 826488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 826588c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 826688c03ad3SStefano Zampini pcf->ops->destroy = NULL; 8267b9be95fcSstefano_zampini pcf->ops->reset = NULL; 826888c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 826988c03ad3SStefano Zampini } 82709d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 8271111315fdSstefano_zampini 8272111315fdSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 8273111315fdSstefano_zampini if (iP) { 8274111315fdSstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)iP),sub_schurs->prefix,"BDDC sub_schurs options","PC");CHKERRQ(ierr); 8275111315fdSstefano_zampini ierr = PetscOptionsBool("-sub_schurs_discrete_harmonic",NULL,NULL,discrete_harmonic,&discrete_harmonic,NULL);CHKERRQ(ierr); 8276111315fdSstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 8277111315fdSstefano_zampini } 8278111315fdSstefano_zampini if (discrete_harmonic) { 8279111315fdSstefano_zampini Mat A; 8280111315fdSstefano_zampini ierr = MatDuplicate(pcbddc->local_mat,MAT_COPY_VALUES,&A);CHKERRQ(ierr); 8281111315fdSstefano_zampini ierr = MatZeroRowsColumnsIS(A,iP,1.0,NULL,NULL);CHKERRQ(ierr); 8282111315fdSstefano_zampini ierr = PetscObjectCompose((PetscObject)A,"__KSPFETIDP_iP",(PetscObject)iP);CHKERRQ(ierr); 8283111315fdSstefano_zampini ierr = PCBDDCSubSchursSetUp(sub_schurs,A,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); 8284111315fdSstefano_zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 8285111315fdSstefano_zampini } else { 828691af6908SStefano 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); 8287111315fdSstefano_zampini } 828872b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 828972b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 8290ca92afb2SStefano Zampini } 8291d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8292b96c3477SStefano Zampini 8293b96c3477SStefano Zampini /* free adjacency */ 8294b96c3477SStefano Zampini if (free_used_adj) { 8295b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 8296b96c3477SStefano Zampini } 8297b96c3477SStefano Zampini PetscFunctionReturn(0); 8298b96c3477SStefano Zampini } 8299b96c3477SStefano Zampini 830008122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 8301b96c3477SStefano Zampini { 8302b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8303b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8304b96c3477SStefano Zampini PCBDDCGraph graph; 8305b96c3477SStefano Zampini PetscErrorCode ierr; 8306b96c3477SStefano Zampini 8307b96c3477SStefano Zampini PetscFunctionBegin; 8308b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 830908122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 83103301b35fSStefano Zampini IS verticesIS,verticescomm; 83113301b35fSStefano Zampini PetscInt vsize,*idxs; 8312b96c3477SStefano Zampini 8313b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 83143301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 83153301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 83163301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 83173301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 8318c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 8319b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 8320be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 8321441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 83223301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 8323b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 8324b96c3477SStefano Zampini } else { 8325b96c3477SStefano Zampini graph = pcbddc->mat_graph; 8326b96c3477SStefano Zampini } 8327e4d548c7SStefano Zampini /* print some info */ 83285c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 8329e4d548c7SStefano Zampini IS vertices; 8330e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 8331c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 8332e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8333e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 8334e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8335e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 8336e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 8337e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 8338e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 8339e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8340e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8341c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8342e4d548c7SStefano Zampini } 8343b96c3477SStefano Zampini 8344b96c3477SStefano Zampini /* sub_schurs init */ 8345b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 8346b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 8347b334f244SStefano Zampini } 83488b6046baSStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap,pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 8349e62b6521Sstefano_zampini pcbddc->sub_schurs->prefix = ((PetscObject)pc)->prefix; 8350a64f4aa4SStefano Zampini 8351b96c3477SStefano Zampini /* free graph struct */ 835208122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 8353b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 8354b96c3477SStefano Zampini } 8355b96c3477SStefano Zampini PetscFunctionReturn(0); 8356b96c3477SStefano Zampini } 8357fa34dd3eSStefano Zampini 8358fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 8359fa34dd3eSStefano Zampini { 8360fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8361fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8362fa34dd3eSStefano Zampini PetscErrorCode ierr; 8363fa34dd3eSStefano Zampini 8364fa34dd3eSStefano Zampini PetscFunctionBegin; 8365fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 8366fa34dd3eSStefano Zampini IS zerodiag = NULL; 83674f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 8368fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 83694f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 837075c01103SStefano Zampini PetscReal norm; 8371fa34dd3eSStefano Zampini PetscInt i; 8372fa34dd3eSStefano Zampini 8373fa34dd3eSStefano Zampini /* B0 and B0_B */ 8374fa34dd3eSStefano Zampini if (zerodiag) { 8375fa34dd3eSStefano Zampini IS dummy; 8376fa34dd3eSStefano Zampini 83774f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 83787dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 8379fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 8380fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 8381fa34dd3eSStefano Zampini } 8382fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 8383fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 8384fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 8385fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8386fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8387fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8388fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8389fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 8390fa34dd3eSStefano Zampini /* S_j */ 8391fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8392fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 8393fa34dd3eSStefano Zampini 8394fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 8395fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 8396fa34dd3eSStefano Zampini /* continuous in primal space */ 8397fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 8398fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8399fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8400fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 84014f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 84024f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 8403fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8404fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8405fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8406fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8407fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8408fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8409fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 8410fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 8411fa34dd3eSStefano Zampini 8412fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 8413fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 8414fa34dd3eSStefano Zampini /* local with Schur */ 8415fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 8416fa34dd3eSStefano Zampini if (zerodiag) { 8417fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 84184f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 8419fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8420fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 8421fa34dd3eSStefano Zampini } 8422fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 8423fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8424fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8425fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8426fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8427fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 8428fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8429fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8430fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 8431fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8432fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8433fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8434fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8435fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8436fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 8437fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 8438fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8439fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8440fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8441fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8442fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8443fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8444fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 8445fa34dd3eSStefano Zampini if (zerodiag) { 8446fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 8447fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 84484f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 8449fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8450fa34dd3eSStefano Zampini } 8451fa34dd3eSStefano Zampini /* BDDC */ 8452fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 8453fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 8454fa34dd3eSStefano Zampini 8455fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 8456fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 8457fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 8458fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 84594f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 84604f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 8461fa34dd3eSStefano Zampini } 84624f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 8463fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 8464fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 8465fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 8466fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8467fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 8468fa34dd3eSStefano Zampini } 8469fa34dd3eSStefano Zampini PetscFunctionReturn(0); 8470fa34dd3eSStefano Zampini } 84711e0482f5SStefano Zampini 84721e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 84731e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 84741e0482f5SStefano Zampini { 84751e0482f5SStefano Zampini Mat At; 84761e0482f5SStefano Zampini IS rows; 84771e0482f5SStefano Zampini PetscInt rst,ren; 84781e0482f5SStefano Zampini PetscErrorCode ierr; 84791e0482f5SStefano Zampini PetscLayout rmap; 84801e0482f5SStefano Zampini 84811e0482f5SStefano Zampini PetscFunctionBegin; 84821e0482f5SStefano Zampini rst = ren = 0; 84831e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 84841e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 84851e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 84861e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 84871e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 84881e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 84891e0482f5SStefano Zampini } 8490e07686f2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),ren-rst,rst,1,&rows);CHKERRQ(ierr); 84917dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 84921e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 84931e0482f5SStefano Zampini 84941e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 84951e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 84961e0482f5SStefano Zampini IS from,to; 84971e0482f5SStefano Zampini Vec gvec; 84981e0482f5SStefano Zampini PetscInt lsize; 84991e0482f5SStefano Zampini 85001e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 85011e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 85021e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 85031e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 85041e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 85051e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 85061e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 85071e0482f5SStefano Zampini ierr = MPI_Comm_size(ccomm,&b->size);CHKERRQ(ierr); 85081e0482f5SStefano Zampini ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRQ(ierr); 85091e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 85101e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 85111e0482f5SStefano Zampini b->A = a->A; 85121e0482f5SStefano Zampini b->B = a->B; 85131e0482f5SStefano Zampini 85141e0482f5SStefano Zampini b->donotstash = a->donotstash; 85151e0482f5SStefano Zampini b->roworiented = a->roworiented; 85161e0482f5SStefano Zampini b->rowindices = 0; 85171e0482f5SStefano Zampini b->rowvalues = 0; 85181e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 85191e0482f5SStefano Zampini 85201e0482f5SStefano Zampini (*B)->rmap = rmap; 85211e0482f5SStefano Zampini (*B)->factortype = A->factortype; 85221e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 85231e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 85241e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 85251e0482f5SStefano Zampini 85261e0482f5SStefano Zampini if (a->colmap) { 85271e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 85281e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 85291e0482f5SStefano Zampini #else 85301e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 85311e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 85321e0482f5SStefano Zampini ierr = PetscMemcpy(b->colmap,a->colmap,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 85331e0482f5SStefano Zampini #endif 85341e0482f5SStefano Zampini } else b->colmap = 0; 85351e0482f5SStefano Zampini if (a->garray) { 85361e0482f5SStefano Zampini PetscInt len; 85371e0482f5SStefano Zampini len = a->B->cmap->n; 85381e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 85391e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 85401e0482f5SStefano Zampini if (len) { ierr = PetscMemcpy(b->garray,a->garray,len*sizeof(PetscInt));CHKERRQ(ierr); } 85411e0482f5SStefano Zampini } else b->garray = 0; 85421e0482f5SStefano Zampini 85431e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 85441e0482f5SStefano Zampini b->lvec = a->lvec; 85451e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 85461e0482f5SStefano Zampini 85471e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 85481e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 85491e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 85501e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 85511e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 85521e0482f5SStefano Zampini ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 85531e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 85541e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 85551e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 85561e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 85571e0482f5SStefano Zampini } 85581e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 85591e0482f5SStefano Zampini PetscFunctionReturn(0); 85601e0482f5SStefano Zampini } 8561