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> 4837cedc9SStefano Zampini #include <../src/mat/impls/dense/seq/dense.h> 5c80a6c00SStefano Zampini #include <petscdmplex.h> 6674ae819SStefano Zampini #include <petscblaslapack.h> 7daf8a457SStefano Zampini #include <petsc/private/sfimpl.h> 8c80a6c00SStefano Zampini #include <petsc/private/dmpleximpl.h> 97620a527SStefano Zampini #include <petscdmda.h> 10674ae819SStefano Zampini 111e0482f5SStefano Zampini static PetscErrorCode MatMPIAIJRestrict(Mat,MPI_Comm,Mat*); 121e0482f5SStefano Zampini 13f498cd09SStefano Zampini /* if range is true, it returns B s.t. span{B} = range(A) 14f498cd09SStefano Zampini if range is false, it returns B s.t. range(B) _|_ range(A) */ 15f498cd09SStefano Zampini PetscErrorCode MatDenseOrthogonalRangeOrComplement(Mat A, PetscBool range, PetscInt lw, PetscScalar *work, PetscReal *rwork, Mat *B) 16a13144ffSStefano Zampini { 17a13144ffSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 18a13144ffSStefano Zampini PetscScalar *uwork,*data,*U, ds = 0.; 19a13144ffSStefano Zampini PetscReal *sing; 20a13144ffSStefano Zampini PetscBLASInt bM,bN,lwork,lierr,di = 1; 21a13144ffSStefano Zampini PetscInt ulw,i,nr,nc,n; 22a13144ffSStefano Zampini PetscErrorCode ierr; 23a13144ffSStefano Zampini 24a13144ffSStefano Zampini PetscFunctionBegin; 25a13144ffSStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 26a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"LAPACK _GESVD not available"); 27614dbb09SStefano Zampini #else 28a13144ffSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 29a13144ffSStefano Zampini if (!nr || !nc) PetscFunctionReturn(0); 30a13144ffSStefano Zampini 31a13144ffSStefano Zampini /* workspace */ 32a13144ffSStefano Zampini if (!work) { 33a13144ffSStefano Zampini ulw = PetscMax(PetscMax(1,5*PetscMin(nr,nc)),3*PetscMin(nr,nc)+PetscMax(nr,nc)); 34f913dca9SStefano Zampini ierr = PetscMalloc1(ulw,&uwork);CHKERRQ(ierr); 35a13144ffSStefano Zampini } else { 36a13144ffSStefano Zampini ulw = lw; 37a13144ffSStefano Zampini uwork = work; 38a13144ffSStefano Zampini } 39a13144ffSStefano Zampini n = PetscMin(nr,nc); 40a13144ffSStefano Zampini if (!rwork) { 41a13144ffSStefano Zampini ierr = PetscMalloc1(n,&sing);CHKERRQ(ierr); 42a13144ffSStefano Zampini } else { 43a13144ffSStefano Zampini sing = rwork; 44a13144ffSStefano Zampini } 45a13144ffSStefano Zampini 46a13144ffSStefano Zampini /* SVD */ 47a13144ffSStefano Zampini ierr = PetscMalloc1(nr*nr,&U);CHKERRQ(ierr); 48a13144ffSStefano Zampini ierr = PetscBLASIntCast(nr,&bM);CHKERRQ(ierr); 49a13144ffSStefano Zampini ierr = PetscBLASIntCast(nc,&bN);CHKERRQ(ierr); 50a13144ffSStefano Zampini ierr = PetscBLASIntCast(ulw,&lwork);CHKERRQ(ierr); 51a13144ffSStefano Zampini ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); 52a13144ffSStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 53a13144ffSStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("A","N",&bM,&bN,data,&bM,sing,U,&bM,&ds,&di,uwork,&lwork,&lierr)); 54a13144ffSStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 55a13144ffSStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 56a13144ffSStefano Zampini ierr = MatDenseRestoreArray(A,&data);CHKERRQ(ierr); 57a13144ffSStefano Zampini for (i=0;i<n;i++) if (sing[i] < PETSC_SMALL) break; 58a13144ffSStefano Zampini if (!rwork) { 59a13144ffSStefano Zampini ierr = PetscFree(sing);CHKERRQ(ierr); 60a13144ffSStefano Zampini } 61a13144ffSStefano Zampini if (!work) { 62a13144ffSStefano Zampini ierr = PetscFree(uwork);CHKERRQ(ierr); 63a13144ffSStefano Zampini } 64a13144ffSStefano Zampini /* create B */ 65f498cd09SStefano Zampini if (!range) { 66a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,nr-i,NULL,B);CHKERRQ(ierr); 67a13144ffSStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 68a13144ffSStefano Zampini ierr = PetscMemcpy(data,U+nr*i,(nr-i)*nr*sizeof(PetscScalar));CHKERRQ(ierr); 69f498cd09SStefano Zampini } else { 70f498cd09SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,i,NULL,B);CHKERRQ(ierr); 71f498cd09SStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 72f498cd09SStefano Zampini ierr = PetscMemcpy(data,U,i*nr*sizeof(PetscScalar));CHKERRQ(ierr); 73f498cd09SStefano Zampini } 74a13144ffSStefano Zampini ierr = MatDenseRestoreArray(*B,&data);CHKERRQ(ierr); 75a13144ffSStefano Zampini ierr = PetscFree(U);CHKERRQ(ierr); 76614dbb09SStefano Zampini #endif 77614dbb09SStefano Zampini #else /* PETSC_USE_COMPLEX */ 78a13144ffSStefano Zampini PetscFunctionBegin; 79a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for complexes"); 80a13144ffSStefano Zampini #endif 81a13144ffSStefano Zampini PetscFunctionReturn(0); 82a13144ffSStefano Zampini } 83a13144ffSStefano Zampini 841e0482f5SStefano Zampini /* TODO REMOVE */ 851e0482f5SStefano Zampini #if defined(PRINT_GDET) 861e0482f5SStefano Zampini static int inc = 0; 871e0482f5SStefano Zampini static int lev = 0; 881e0482f5SStefano Zampini #endif 891e0482f5SStefano Zampini 901e0482f5SStefano Zampini PetscErrorCode PCBDDCComputeNedelecChangeEdge(Mat lG, IS edge, IS extrow, IS extcol, IS corners, Mat* Gins, Mat* GKins, PetscScalar cvals[2], PetscScalar *work, PetscReal *rwork) 91a13144ffSStefano Zampini { 92a13144ffSStefano Zampini PetscErrorCode ierr; 93a13144ffSStefano Zampini Mat GE,GEd; 94a13144ffSStefano Zampini PetscInt rsize,csize,esize; 95a13144ffSStefano Zampini PetscScalar *ptr; 96a13144ffSStefano Zampini 97a13144ffSStefano Zampini PetscFunctionBegin; 98a13144ffSStefano Zampini ierr = ISGetSize(edge,&esize);CHKERRQ(ierr); 99c3c0e390SStefano Zampini if (!esize) PetscFunctionReturn(0); 100a13144ffSStefano Zampini ierr = ISGetSize(extrow,&rsize);CHKERRQ(ierr); 101a13144ffSStefano Zampini ierr = ISGetSize(extcol,&csize);CHKERRQ(ierr); 102a13144ffSStefano Zampini 103a13144ffSStefano Zampini /* gradients */ 104a13144ffSStefano Zampini ptr = work + 5*esize; 1057dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,extrow,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 106a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,rsize,csize,ptr,Gins);CHKERRQ(ierr); 107a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,Gins);CHKERRQ(ierr); 108a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 109a13144ffSStefano Zampini 110a13144ffSStefano Zampini /* constants */ 111a13144ffSStefano Zampini ptr += rsize*csize; 112a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,esize,csize,ptr,&GEd);CHKERRQ(ierr); 1137dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,edge,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 114a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,&GEd);CHKERRQ(ierr); 115a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 116f498cd09SStefano Zampini ierr = MatDenseOrthogonalRangeOrComplement(GEd,PETSC_FALSE,5*esize,work,rwork,GKins);CHKERRQ(ierr); 117a13144ffSStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1181e0482f5SStefano Zampini 1191e0482f5SStefano Zampini if (corners) { 1201e0482f5SStefano Zampini Mat GEc; 1211e0482f5SStefano Zampini PetscScalar *vals,v; 1221e0482f5SStefano Zampini 1237dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,edge,corners,MAT_INITIAL_MATRIX,&GEc);CHKERRQ(ierr); 1241e0482f5SStefano Zampini ierr = MatTransposeMatMult(GEc,*GKins,MAT_INITIAL_MATRIX,1.0,&GEd);CHKERRQ(ierr); 1251e0482f5SStefano Zampini ierr = MatDenseGetArray(GEd,&vals);CHKERRQ(ierr); 126637e8532SStefano Zampini /* v = PetscAbsScalar(vals[0]) */; 127637e8532SStefano Zampini v = 1.; 1281e0482f5SStefano Zampini cvals[0] = vals[0]/v; 1291e0482f5SStefano Zampini cvals[1] = vals[1]/v; 1301e0482f5SStefano Zampini ierr = MatDenseRestoreArray(GEd,&vals);CHKERRQ(ierr); 1311e0482f5SStefano Zampini ierr = MatScale(*GKins,1./v);CHKERRQ(ierr); 1321e0482f5SStefano Zampini #if defined(PRINT_GDET) 1331e0482f5SStefano Zampini { 1341e0482f5SStefano Zampini PetscViewer viewer; 1351e0482f5SStefano Zampini char filename[256]; 1361e0482f5SStefano Zampini sprintf(filename,"Gdet_l%d_r%d_cc%d.m",lev,PetscGlobalRank,inc++); 1371e0482f5SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1381e0482f5SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1391e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEc,"GEc");CHKERRQ(ierr); 1401e0482f5SStefano Zampini ierr = MatView(GEc,viewer);CHKERRQ(ierr); 1411e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)(*GKins),"GK");CHKERRQ(ierr); 1421e0482f5SStefano Zampini ierr = MatView(*GKins,viewer);CHKERRQ(ierr); 1431e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEd,"Gproj");CHKERRQ(ierr); 1441e0482f5SStefano Zampini ierr = MatView(GEd,viewer);CHKERRQ(ierr); 1451e0482f5SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1461e0482f5SStefano Zampini } 1471e0482f5SStefano Zampini #endif 1481e0482f5SStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1491e0482f5SStefano Zampini ierr = MatDestroy(&GEc);CHKERRQ(ierr); 1501e0482f5SStefano Zampini } 1511e0482f5SStefano Zampini 152a13144ffSStefano Zampini PetscFunctionReturn(0); 153a13144ffSStefano Zampini } 154a13144ffSStefano Zampini 155a13144ffSStefano Zampini PetscErrorCode PCBDDCNedelecSupport(PC pc) 156a13144ffSStefano Zampini { 157a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 158a13144ffSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1590569b399SStefano Zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGe,lGinit; 160eee23b56SStefano Zampini Vec tvec; 161a13144ffSStefano Zampini PetscSF sfv; 1621e0482f5SStefano Zampini ISLocalToGlobalMapping el2g,vl2g,fl2g,al2g; 163a13144ffSStefano Zampini MPI_Comm comm; 164c2151214SStefano Zampini IS lned,primals,allprimals,nedfieldlocal; 165c2151214SStefano Zampini IS *eedges,*extrows,*extcols,*alleedges; 1667d871cd7SStefano Zampini PetscBT btv,bte,btvc,btb,btbd,btvcand,btvi,btee,bter; 167a13144ffSStefano Zampini PetscScalar *vals,*work; 168a13144ffSStefano Zampini PetscReal *rwork; 169a13144ffSStefano Zampini const PetscInt *idxs,*ii,*jj,*iit,*jjt; 1701e0482f5SStefano Zampini PetscInt ne,nv,Lv,order,n,field; 171a13144ffSStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 172eee23b56SStefano Zampini PetscInt i,j,extmem,cum,maxsize,nee; 173b03ebc13SStefano Zampini PetscInt *extrow,*extrowcum,*marks,*vmarks,*gidxs; 174a13144ffSStefano Zampini PetscInt *sfvleaves,*sfvroots; 175b03ebc13SStefano Zampini PetscInt *corners,*cedges; 176637e8532SStefano Zampini PetscInt *ecount,**eneighs,*vcount,**vneighs; 177b03ebc13SStefano Zampini #if defined(PETSC_USE_DEBUG) 178b03ebc13SStefano Zampini PetscInt *emarks; 179b03ebc13SStefano Zampini #endif 180213b8bfaSStefano Zampini PetscBool print,eerr,done,lrc[2],conforming,global,singular,setprimal; 181a13144ffSStefano Zampini PetscErrorCode ierr; 182a13144ffSStefano Zampini 183a13144ffSStefano Zampini PetscFunctionBegin; 184213b8bfaSStefano Zampini /* If the discrete gradient is defined for a subset of dofs and global is true, 185213b8bfaSStefano Zampini it assumes G is given in global ordering for all the dofs. 186213b8bfaSStefano Zampini Otherwise, the ordering is global for the Nedelec field */ 187213b8bfaSStefano Zampini order = pcbddc->nedorder; 188213b8bfaSStefano Zampini conforming = pcbddc->conforming; 189213b8bfaSStefano Zampini field = pcbddc->nedfield; 190213b8bfaSStefano Zampini global = pcbddc->nedglobal; 191213b8bfaSStefano Zampini setprimal = PETSC_FALSE; 192a13144ffSStefano Zampini print = PETSC_FALSE; 193213b8bfaSStefano Zampini singular = PETSC_FALSE; 194a13144ffSStefano Zampini 195213b8bfaSStefano Zampini /* Command line customization */ 196213b8bfaSStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC Nedelec options","PC");CHKERRQ(ierr); 197213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_field_primal","All edge dofs set as primals: Toselli's algorithm C",NULL,setprimal,&setprimal,NULL);CHKERRQ(ierr); 198213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_singular","Infer nullspace from discrete gradient",NULL,singular,&singular,NULL);CHKERRQ(ierr); 199213b8bfaSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_nedelec_order","Test variable order code (to be removed)",NULL,order,&order,NULL);CHKERRQ(ierr); 200213b8bfaSStefano Zampini /* print debug info TODO: to be removed */ 201213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_print","Print debug info",NULL,print,&print,NULL);CHKERRQ(ierr); 202213b8bfaSStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 203213b8bfaSStefano Zampini 204213b8bfaSStefano Zampini /* Return if there are no edges in the decomposition and the problem is not singular */ 2051e0482f5SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&al2g,NULL);CHKERRQ(ierr); 2061e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(al2g,&n);CHKERRQ(ierr); 207213b8bfaSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 208213b8bfaSStefano Zampini if (!singular) { 209a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 210a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 211c2151214SStefano Zampini for (i=0;i<n;i++) { 212a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 213a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 214a13144ffSStefano Zampini break; 215a13144ffSStefano Zampini } 216a13144ffSStefano Zampini } 217a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 218a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 219a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 220213b8bfaSStefano Zampini } 221a13144ffSStefano Zampini 222213b8bfaSStefano Zampini /* Get Nedelec field */ 223213b8bfaSStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 2246080607fSStefano 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); 225213b8bfaSStefano Zampini if (pcbddc->n_ISForDofsLocal && field >= 0) { 226c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[field]);CHKERRQ(ierr); 227c2151214SStefano Zampini nedfieldlocal = pcbddc->ISForDofsLocal[field]; 228c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 229213b8bfaSStefano Zampini } else if (!pcbddc->n_ISForDofsLocal && field != PETSC_DECIDE) { 230213b8bfaSStefano Zampini ne = n; 231213b8bfaSStefano Zampini nedfieldlocal = NULL; 232213b8bfaSStefano Zampini global = PETSC_TRUE; 233213b8bfaSStefano Zampini } else if (field == PETSC_DECIDE) { 234213b8bfaSStefano Zampini PetscInt rst,ren,*idx; 235213b8bfaSStefano Zampini 236213b8bfaSStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 237213b8bfaSStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 238213b8bfaSStefano Zampini ierr = MatGetOwnershipRange(pcbddc->discretegradient,&rst,&ren);CHKERRQ(ierr); 239213b8bfaSStefano Zampini for (i=rst;i<ren;i++) { 240213b8bfaSStefano Zampini PetscInt nc; 241213b8bfaSStefano Zampini 242213b8bfaSStefano Zampini ierr = MatGetRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 243213b8bfaSStefano Zampini if (nc > 1) matis->sf_rootdata[i-rst] = 1; 244213b8bfaSStefano Zampini ierr = MatRestoreRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 245213b8bfaSStefano Zampini } 246213b8bfaSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 247213b8bfaSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 248213b8bfaSStefano Zampini ierr = PetscMalloc1(n,&idx);CHKERRQ(ierr); 249213b8bfaSStefano Zampini for (i=0,ne=0;i<n;i++) if (matis->sf_leafdata[i]) idx[ne++] = i; 250213b8bfaSStefano Zampini ierr = ISCreateGeneral(comm,ne,idx,PETSC_OWN_POINTER,&nedfieldlocal);CHKERRQ(ierr); 251213b8bfaSStefano Zampini } else { 252213b8bfaSStefano Zampini SETERRQ(comm,PETSC_ERR_USER,"When multiple fields are present, the Nedelec field has to be specified"); 253213b8bfaSStefano Zampini } 254213b8bfaSStefano Zampini 255213b8bfaSStefano Zampini /* Sanity checks */ 256213b8bfaSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 257213b8bfaSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 2586080607fSStefano 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); 259213b8bfaSStefano Zampini 260213b8bfaSStefano Zampini /* Just set primal dofs and return */ 2611e0482f5SStefano Zampini if (setprimal) { 262eee23b56SStefano Zampini IS enedfieldlocal; 263eee23b56SStefano Zampini PetscInt *eidxs; 264eee23b56SStefano Zampini 265eee23b56SStefano Zampini ierr = PetscMalloc1(ne,&eidxs);CHKERRQ(ierr); 266eee23b56SStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 267213b8bfaSStefano Zampini if (nedfieldlocal) { 268213b8bfaSStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 269eee23b56SStefano Zampini for (i=0,cum=0;i<ne;i++) { 270eee23b56SStefano Zampini if (PetscRealPart(vals[idxs[i]]) > 2.) { 271eee23b56SStefano Zampini eidxs[cum++] = idxs[i]; 272eee23b56SStefano Zampini } 273eee23b56SStefano Zampini } 274eee23b56SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 275213b8bfaSStefano Zampini } else { 276213b8bfaSStefano Zampini for (i=0,cum=0;i<ne;i++) { 277213b8bfaSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 278213b8bfaSStefano Zampini eidxs[cum++] = i; 279213b8bfaSStefano Zampini } 280213b8bfaSStefano Zampini } 281213b8bfaSStefano Zampini } 282213b8bfaSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 283eee23b56SStefano Zampini ierr = ISCreateGeneral(comm,cum,eidxs,PETSC_COPY_VALUES,&enedfieldlocal);CHKERRQ(ierr); 284eee23b56SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,enedfieldlocal);CHKERRQ(ierr); 285eee23b56SStefano Zampini ierr = PetscFree(eidxs);CHKERRQ(ierr); 2861e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 287eee23b56SStefano Zampini ierr = ISDestroy(&enedfieldlocal);CHKERRQ(ierr); 2881e0482f5SStefano Zampini PetscFunctionReturn(0); 2891e0482f5SStefano Zampini } 290a13144ffSStefano Zampini 291213b8bfaSStefano Zampini /* Compute some l2g maps */ 292213b8bfaSStefano Zampini if (nedfieldlocal) { 293c2151214SStefano Zampini IS is; 294c2151214SStefano Zampini 295c2151214SStefano Zampini /* need to map from the local Nedelec field to local numbering */ 296c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nedfieldlocal,&fl2g);CHKERRQ(ierr); 2971e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering for the whole dofs*/ 2981e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(al2g,nedfieldlocal,&is);CHKERRQ(ierr); 2991e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&al2g);CHKERRQ(ierr); 3001e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering (for Nedelec only) */ 3011e0482f5SStefano Zampini if (global) { 3021e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3031e0482f5SStefano Zampini el2g = al2g; 3041e0482f5SStefano Zampini } else { 3051e0482f5SStefano Zampini IS gis; 3061e0482f5SStefano Zampini 3071e0482f5SStefano Zampini ierr = ISRenumber(is,NULL,NULL,&gis);CHKERRQ(ierr); 3081e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gis,&el2g);CHKERRQ(ierr); 3091e0482f5SStefano Zampini ierr = ISDestroy(&gis);CHKERRQ(ierr); 3101e0482f5SStefano Zampini } 311c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 312c2151214SStefano Zampini } else { 3131e0482f5SStefano Zampini /* restore default */ 3141e0482f5SStefano Zampini pcbddc->nedfield = -1; 3151e0482f5SStefano Zampini /* one ref for the destruction of al2g, one for el2g */ 3161e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3171e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3181e0482f5SStefano Zampini el2g = al2g; 319c2151214SStefano Zampini fl2g = NULL; 320c2151214SStefano Zampini } 321a13144ffSStefano Zampini 322213b8bfaSStefano Zampini /* Start communication to drop connections for interior edges (for cc analysis only) */ 323c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 324c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 325c2151214SStefano Zampini if (nedfieldlocal) { 326c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 327c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 328c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 329c2151214SStefano Zampini } else { 330c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 331c2151214SStefano Zampini } 332c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 333c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 334213b8bfaSStefano Zampini 335213b8bfaSStefano Zampini if (!singular) { /* drop connections with interior edges to avoid unneeded communications and memory movements */ 336213b8bfaSStefano Zampini ierr = MatDuplicate(pcbddc->discretegradient,MAT_COPY_VALUES,&G);CHKERRQ(ierr); 337213b8bfaSStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 3381e0482f5SStefano Zampini if (global) { 3391e0482f5SStefano Zampini PetscInt rst; 3401e0482f5SStefano Zampini 341c2151214SStefano Zampini ierr = MatGetOwnershipRange(G,&rst,NULL);CHKERRQ(ierr); 342c2151214SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 343c2151214SStefano Zampini if (matis->sf_rootdata[i] < 2) { 344c2151214SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 345c2151214SStefano Zampini } 346c2151214SStefano Zampini } 347a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 348c2151214SStefano Zampini ierr = MatZeroRows(G,cum,matis->sf_rootdata,0.,NULL,NULL);CHKERRQ(ierr); 3491e0482f5SStefano Zampini } else { 3501e0482f5SStefano Zampini PetscInt *tbz; 3511e0482f5SStefano Zampini 3521e0482f5SStefano Zampini ierr = PetscMalloc1(ne,&tbz);CHKERRQ(ierr); 3531e0482f5SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3541e0482f5SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3551e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3561e0482f5SStefano Zampini for (i=0,cum=0;i<ne;i++) 3571e0482f5SStefano Zampini if (matis->sf_leafdata[idxs[i]] == 1) 3581e0482f5SStefano Zampini tbz[cum++] = i; 3591e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3601e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApply(el2g,cum,tbz,tbz);CHKERRQ(ierr); 3611e0482f5SStefano Zampini ierr = MatZeroRows(G,cum,tbz,0.,NULL,NULL);CHKERRQ(ierr); 3621e0482f5SStefano Zampini ierr = PetscFree(tbz);CHKERRQ(ierr); 3631e0482f5SStefano Zampini } 364213b8bfaSStefano Zampini } else { /* we need the entire G to infer the nullspace */ 365213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->discretegradient);CHKERRQ(ierr); 366213b8bfaSStefano Zampini G = pcbddc->discretegradient; 367213b8bfaSStefano Zampini } 368a13144ffSStefano Zampini 369a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 370a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 371a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 3727dae84e0SHong Zhang ierr = MatCreateSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 373a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 374a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 375a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 376a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 377a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 378a13144ffSStefano Zampini 379213b8bfaSStefano Zampini /* SF for nodal dofs communications */ 380c2151214SStefano Zampini ierr = MatGetLocalSize(G,NULL,&Lv);CHKERRQ(ierr); 381a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 382a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 383a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 384a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 385a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 386a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 387a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 388213b8bfaSStefano Zampini i = singular ? 2 : 1; 389213b8bfaSStefano Zampini ierr = PetscMalloc2(i*nv,&sfvleaves,i*Lv,&sfvroots);CHKERRQ(ierr); 390a13144ffSStefano Zampini 3911e0482f5SStefano Zampini /* Destroy temporary G created in MATIS format and modified G */ 392213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 393a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 394213b8bfaSStefano Zampini ierr = MatDestroy(&G);CHKERRQ(ierr); 395a13144ffSStefano Zampini 396213b8bfaSStefano Zampini if (print) { 397213b8bfaSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 398213b8bfaSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 399213b8bfaSStefano Zampini } 400213b8bfaSStefano Zampini 401213b8bfaSStefano Zampini /* Save lG for values insertion in change of basis */ 4020569b399SStefano Zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGinit);CHKERRQ(ierr); 4030569b399SStefano Zampini 404a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 4054e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 4064e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 407a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 408a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 409a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 4107d871cd7SStefano Zampini ierr = PetscBTCreate(ne,&btbd);CHKERRQ(ierr); 411c2151214SStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 412a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 413a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 414a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 415c2151214SStefano Zampini IS is; 416c2151214SStefano Zampini 417c2151214SStefano Zampini if (fl2g) { 418c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->DirichletBoundariesLocal,&is);CHKERRQ(ierr); 419c2151214SStefano Zampini } else { 420c2151214SStefano Zampini is = pcbddc->DirichletBoundariesLocal; 421c2151214SStefano Zampini } 422c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 423c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 424a13144ffSStefano Zampini for (i=0;i<cum;i++) { 425a13144ffSStefano Zampini if (idxs[i] >= 0) { 426a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 4277d871cd7SStefano Zampini ierr = PetscBTSet(btbd,idxs[i]);CHKERRQ(ierr); 428a13144ffSStefano Zampini } 429a13144ffSStefano Zampini } 430c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 431c2151214SStefano Zampini if (fl2g) { 432c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 433c2151214SStefano Zampini } 434a13144ffSStefano Zampini } 435a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 436c2151214SStefano Zampini IS is; 437c2151214SStefano Zampini 438c2151214SStefano Zampini if (fl2g) { 439c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->NeumannBoundariesLocal,&is);CHKERRQ(ierr); 440c2151214SStefano Zampini } else { 441c2151214SStefano Zampini is = pcbddc->NeumannBoundariesLocal; 442c2151214SStefano Zampini } 443c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 444c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 445a13144ffSStefano Zampini for (i=0;i<cum;i++) { 446a13144ffSStefano Zampini if (idxs[i] >= 0) { 447a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 448a13144ffSStefano Zampini } 449a13144ffSStefano Zampini } 450c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 451c2151214SStefano Zampini if (fl2g) { 452c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 453a13144ffSStefano Zampini } 454c2151214SStefano Zampini } 455c2151214SStefano Zampini 456213b8bfaSStefano Zampini /* Count neighs per dof */ 457b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(el2g,NULL,&ecount,&eneighs);CHKERRQ(ierr); 458b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(vl2g,NULL,&vcount,&vneighs);CHKERRQ(ierr); 459637e8532SStefano Zampini 4607d871cd7SStefano Zampini /* need to remove coarse faces' dofs and coarse edges' dirichlet dofs 4617d871cd7SStefano Zampini for proper detection of coarse edges' endpoints */ 46262b0c6f7SStefano Zampini ierr = PetscBTCreate(ne,&btee);CHKERRQ(ierr); 46362b0c6f7SStefano Zampini for (i=0;i<ne;i++) { 464b63b1311SStefano Zampini if ((ecount[i] > 2 && !PetscBTLookup(btbd,i)) || (ecount[i] == 2 && PetscBTLookup(btb,i))) { 46562b0c6f7SStefano Zampini ierr = PetscBTSet(btee,i);CHKERRQ(ierr); 46662b0c6f7SStefano Zampini } 46762b0c6f7SStefano Zampini } 468637e8532SStefano Zampini ierr = PetscMalloc1(ne,&marks);CHKERRQ(ierr); 46962b0c6f7SStefano Zampini if (!conforming) { 47062b0c6f7SStefano Zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 47162b0c6f7SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 47262b0c6f7SStefano Zampini } 4734e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 474dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 47562b0c6f7SStefano Zampini cum = 0; 476a13144ffSStefano Zampini for (i=0;i<ne;i++) { 477dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 47862b0c6f7SStefano Zampini if (!PetscBTLookup(btee,i)) { 479a13144ffSStefano Zampini marks[cum++] = i; 480dec27d64SStefano Zampini continue; 481dec27d64SStefano Zampini } 482dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 48362b0c6f7SStefano Zampini if (!conforming) { 48462b0c6f7SStefano Zampini if (ii[i+1]-ii[i] != order + 1) { /* every row of G on the coarse edge should list order+1 nodal dofs */ 485a13144ffSStefano Zampini marks[cum++] = i; 486a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 487a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 488a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 489a13144ffSStefano Zampini } 49062b0c6f7SStefano Zampini } else { 49162b0c6f7SStefano Zampini /* every edge dofs should be connected trough a certain number of nodal dofs 49262b0c6f7SStefano Zampini to other edge dofs belonging to coarse edges 49362b0c6f7SStefano Zampini - at most 2 endpoints 49462b0c6f7SStefano Zampini - order-1 interior nodal dofs 49562b0c6f7SStefano Zampini - no undefined nodal dofs (nconn < order) 49662b0c6f7SStefano Zampini */ 49762b0c6f7SStefano Zampini PetscInt ends = 0,ints = 0, undef = 0; 49862b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 49962b0c6f7SStefano Zampini PetscInt v = jj[j],k; 50062b0c6f7SStefano Zampini PetscInt nconn = iit[v+1]-iit[v]; 50162b0c6f7SStefano Zampini for (k=iit[v];k<iit[v+1];k++) if (!PetscBTLookup(btee,jjt[k])) nconn--; 50262b0c6f7SStefano Zampini if (nconn > order) ends++; 50362b0c6f7SStefano Zampini else if (nconn == order) ints++; 50462b0c6f7SStefano Zampini else undef++; 50562b0c6f7SStefano Zampini } 50662b0c6f7SStefano Zampini if (undef || ends > 2 || ints != order -1) { 50762b0c6f7SStefano Zampini marks[cum++] = i; 50862b0c6f7SStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 50962b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 51062b0c6f7SStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 51162b0c6f7SStefano Zampini } 51262b0c6f7SStefano Zampini } 51362b0c6f7SStefano Zampini } 514a13144ffSStefano Zampini } 515dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 516dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 517dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 518dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 519a13144ffSStefano Zampini } 520dec27d64SStefano Zampini } 52162b0c6f7SStefano Zampini ierr = PetscBTDestroy(&btee);CHKERRQ(ierr); 522dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 5234e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 52462b0c6f7SStefano Zampini if (!conforming) { 52562b0c6f7SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 52662b0c6f7SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 52762b0c6f7SStefano Zampini } 5284e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 529637e8532SStefano Zampini 530b03ebc13SStefano Zampini /* identify splitpoints and corner candidates */ 5314e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 532a13144ffSStefano Zampini if (print) { 5334e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 5344e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 5354e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 536a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 537a13144ffSStefano Zampini } 538a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 539dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 540a13144ffSStefano Zampini for (i=0;i<nv;i++) { 541637e8532SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i], vc = vcount[i]; 5427d871cd7SStefano Zampini PetscBool sneighs = PETSC_TRUE, bdir = PETSC_FALSE; 543b03ebc13SStefano Zampini if (!order) { /* variable order */ 544dec27d64SStefano Zampini PetscReal vorder = 0.; 545dec27d64SStefano Zampini 546dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 547dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 5486080607fSStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%D)",vorder,test); 549dec27d64SStefano Zampini ord = 1; 550dec27d64SStefano Zampini } 551a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 5526080607fSStefano 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); 553a13144ffSStefano Zampini #endif 554637e8532SStefano Zampini for (j=ii[i];j<ii[i+1] && sneighs;j++) { 5557d871cd7SStefano Zampini if (PetscBTLookup(btbd,jj[j])) { 5567d871cd7SStefano Zampini bdir = PETSC_TRUE; 5577d871cd7SStefano Zampini break; 5587d871cd7SStefano Zampini } 559637e8532SStefano Zampini if (vc != ecount[jj[j]]) { 560637e8532SStefano Zampini sneighs = PETSC_FALSE; 561637e8532SStefano Zampini } else { 562637e8532SStefano Zampini PetscInt k,*vn = vneighs[i], *en = eneighs[jj[j]]; 563637e8532SStefano Zampini for (k=0;k<vc;k++) { 564637e8532SStefano Zampini if (vn[k] != en[k]) { 565637e8532SStefano Zampini sneighs = PETSC_FALSE; 566637e8532SStefano Zampini break; 567637e8532SStefano Zampini } 568637e8532SStefano Zampini } 569637e8532SStefano Zampini } 570637e8532SStefano Zampini } 5717d871cd7SStefano Zampini if (!sneighs || test >= 3*ord || bdir) { /* splitpoints */ 5726080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %D (%D %D %D)\n",i,!sneighs,test >= 3*ord,bdir); 573a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 574dec27d64SStefano Zampini } else if (test == ord) { 575b03ebc13SStefano Zampini if (order == 1 || (!order && ii[i+1]-ii[i] == 1)) { 5766080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %D\n",i); 577a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 578a13144ffSStefano Zampini } else { 5796080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %D\n",i); 580a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 581a13144ffSStefano Zampini } 582a13144ffSStefano Zampini } 583a13144ffSStefano Zampini } 584b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(el2g,NULL,&ecount,&eneighs);CHKERRQ(ierr); 585b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(vl2g,NULL,&vcount,&vneighs);CHKERRQ(ierr); 5867d871cd7SStefano Zampini ierr = PetscBTDestroy(&btbd);CHKERRQ(ierr); 587b03ebc13SStefano Zampini 588b03ebc13SStefano Zampini /* a candidate is valid if it is connected to another candidate via a non-primal edge dof */ 589b03ebc13SStefano Zampini if (order != 1) { 590b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"INSPECTING CANDIDATES\n"); 591b03ebc13SStefano Zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 592b03ebc13SStefano Zampini for (i=0;i<nv;i++) { 593b03ebc13SStefano Zampini if (PetscBTLookup(btvcand,i)) { 594b03ebc13SStefano Zampini PetscBool found = PETSC_FALSE; 595b03ebc13SStefano Zampini for (j=ii[i];j<ii[i+1] && !found;j++) { 596b03ebc13SStefano Zampini PetscInt k,e = jj[j]; 597b03ebc13SStefano Zampini if (PetscBTLookup(bte,e)) continue; 598b03ebc13SStefano Zampini for (k=iit[e];k<iit[e+1];k++) { 599b03ebc13SStefano Zampini PetscInt v = jjt[k]; 600b03ebc13SStefano Zampini if (v != i && PetscBTLookup(btvcand,v)) { 601b03ebc13SStefano Zampini found = PETSC_TRUE; 602b03ebc13SStefano Zampini break; 603b03ebc13SStefano Zampini } 604b03ebc13SStefano Zampini } 605b03ebc13SStefano Zampini } 606b03ebc13SStefano Zampini if (!found) { 6076080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %D CLEARED\n",i); 608b03ebc13SStefano Zampini ierr = PetscBTClear(btvcand,i);CHKERRQ(ierr); 609b03ebc13SStefano Zampini } else { 6106080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %D ACCEPTED\n",i); 611b03ebc13SStefano Zampini } 612b03ebc13SStefano Zampini } 613b03ebc13SStefano Zampini } 614b03ebc13SStefano Zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 615b03ebc13SStefano Zampini } 616dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 617a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 618b03ebc13SStefano Zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 619a13144ffSStefano Zampini 620a13144ffSStefano Zampini /* Get the local G^T explicitly */ 6210569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 622a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 6234e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 624a13144ffSStefano Zampini 6254e64d54eSstefano_zampini /* Mark interior nodal dofs */ 626a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 6274e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 628a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 629a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 6304e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 631a13144ffSStefano Zampini } 632a13144ffSStefano Zampini } 633a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 634a13144ffSStefano Zampini 635a13144ffSStefano Zampini /* communicate corners and splitpoints */ 636a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 637a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 638a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 639a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 640a13144ffSStefano Zampini 641a13144ffSStefano Zampini if (print) { 642a13144ffSStefano Zampini IS tbz; 643a13144ffSStefano Zampini 644a13144ffSStefano Zampini cum = 0; 645a13144ffSStefano Zampini for (i=0;i<nv;i++) 646a13144ffSStefano Zampini if (sfvleaves[i]) 647a13144ffSStefano Zampini vmarks[cum++] = i; 648a13144ffSStefano Zampini 649a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 650a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 651a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 652a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 653a13144ffSStefano Zampini } 654a13144ffSStefano Zampini 655a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 656a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 657a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 658a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 659a13144ffSStefano Zampini 6604e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 6614e64d54eSstefano_zampini and interior nodal dofs */ 662a13144ffSStefano Zampini cum = 0; 663a13144ffSStefano Zampini for (i=0;i<nv;i++) { 664a13144ffSStefano Zampini if (sfvleaves[i]) { 665a13144ffSStefano Zampini vmarks[cum++] = i; 666a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 667a13144ffSStefano Zampini } 6684e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 669a13144ffSStefano Zampini } 6704e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 671a13144ffSStefano Zampini if (print) { 672a13144ffSStefano Zampini IS tbz; 673a13144ffSStefano Zampini 674a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 6754e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 676a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 677a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 678a13144ffSStefano Zampini } 679a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 680a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 681a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 682a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 683a13144ffSStefano Zampini 684a13144ffSStefano Zampini /* Recompute G */ 685a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 686a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 687a13144ffSStefano Zampini if (print) { 688a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 689a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 690a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 691a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 692a13144ffSStefano Zampini } 693a13144ffSStefano Zampini 694a13144ffSStefano Zampini /* Get primal dofs (if any) */ 695a13144ffSStefano Zampini cum = 0; 696a13144ffSStefano Zampini for (i=0;i<ne;i++) { 697a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 698a13144ffSStefano Zampini } 699c2151214SStefano Zampini if (fl2g) { 700c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 701c2151214SStefano Zampini } 702a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 703a13144ffSStefano Zampini if (print) { 704a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 705a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 706a13144ffSStefano Zampini } 707a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 708c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 709a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 710a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 711a13144ffSStefano Zampini 712a13144ffSStefano Zampini /* Compute edge connectivity */ 713a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 714a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 715a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 716c2151214SStefano Zampini if (fl2g) { 717c2151214SStefano Zampini PetscBT btf; 718c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 719c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 720c2151214SStefano Zampini 721c2151214SStefano Zampini /* create CSR for all local dofs */ 722c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 723c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 7246080607fSStefano Zampini if (pcbddc->mat_graph->nvtxs_csr != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Invalid size of CSR graph %D. Should be %D",pcbddc->mat_graph->nvtxs_csr,n); 725c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 726c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 727c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 728c2151214SStefano Zampini rest = PETSC_TRUE; 729c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 730c2151214SStefano Zampini } else { 731c2151214SStefano Zampini free = PETSC_TRUE; 732c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 733c2151214SStefano Zampini iiu[0] = 0; 734c2151214SStefano Zampini for (i=0;i<n;i++) { 735c2151214SStefano Zampini iiu[i+1] = i+1; 736c2151214SStefano Zampini jju[i] = -1; 737d904f53bSStefano Zampini } 738c2151214SStefano Zampini } 739c2151214SStefano Zampini 740c2151214SStefano Zampini /* import sizes of CSR */ 741c2151214SStefano Zampini iia[0] = 0; 742c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 743c2151214SStefano Zampini 744c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 745c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 746c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 747c2151214SStefano Zampini for (i=0;i<ne;i++) { 748c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 749c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 750c2151214SStefano Zampini } 751c2151214SStefano Zampini 752c2151214SStefano Zampini /* iia in CSR */ 753c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 754c2151214SStefano Zampini 755c2151214SStefano Zampini /* jja in CSR */ 756c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 757c2151214SStefano Zampini for (i=0;i<n;i++) 758c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 759c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 760c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 761c2151214SStefano Zampini 762c2151214SStefano Zampini /* map edge dofs connectivity */ 7631e0482f5SStefano Zampini if (jj) { 764c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 765c2151214SStefano Zampini for (i=0;i<ne;i++) { 766c2151214SStefano Zampini PetscInt e = idxs[i]; 767c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 768c2151214SStefano Zampini } 7691e0482f5SStefano Zampini } 770c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 771c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 772c2151214SStefano Zampini if (rest) { 773c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 774c2151214SStefano Zampini } 775c2151214SStefano Zampini if (free) { 776c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 777c2151214SStefano Zampini } 778c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 779c2151214SStefano Zampini } else { 780c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 781c2151214SStefano Zampini } 782c2151214SStefano Zampini 783a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 784a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 785213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 786a13144ffSStefano Zampini 787a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 788c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 789a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 790a13144ffSStefano Zampini 791c2151214SStefano Zampini if (fl2g) { 792c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 793c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 794c2151214SStefano Zampini for (i=0;i<nee;i++) { 795c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 796c2151214SStefano Zampini } 797c2151214SStefano Zampini } else { 798c2151214SStefano Zampini eedges = alleedges; 799c2151214SStefano Zampini primals = allprimals; 800c2151214SStefano Zampini } 801c2151214SStefano Zampini 802a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 803a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 804c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 805c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 806c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 807c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 808c2151214SStefano Zampini if (print) { 809c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 810c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 811c2151214SStefano Zampini } 812c2151214SStefano Zampini 813c2151214SStefano Zampini maxsize = 0; 814a13144ffSStefano Zampini for (i=0;i<nee;i++) { 815a13144ffSStefano Zampini PetscInt size,mark = i+1; 816a13144ffSStefano Zampini 817a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 818a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 819a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 820a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 821a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 822a13144ffSStefano Zampini } 823a13144ffSStefano Zampini 824a13144ffSStefano Zampini /* Find coarse edge endpoints */ 825a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 826a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 827a13144ffSStefano Zampini for (i=0;i<nee;i++) { 828a13144ffSStefano Zampini PetscInt mark = i+1,size; 829a13144ffSStefano Zampini 830a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8311e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8326080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 833a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 834a13144ffSStefano Zampini if (print) { 8356080607fSStefano Zampini ierr = PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %D\n",i);CHKERRQ(ierr); 8366080607fSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 837a13144ffSStefano Zampini } 838a13144ffSStefano Zampini for (j=0;j<size;j++) { 839a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 8406080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %D\n",ee); 841a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 8426080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %D\n",jj[k]); 843a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 8446080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %D\n",jj[k]); 845a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 846a13144ffSStefano Zampini PetscInt k2; 847a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 848a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 8496080607fSStefano 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])); 850c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 851c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 852c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 853a13144ffSStefano Zampini corner = PETSC_TRUE; 854a13144ffSStefano Zampini break; 855a13144ffSStefano Zampini } 856a13144ffSStefano Zampini } 857a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 8586080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %D\n",jj[k]); 859a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 860a13144ffSStefano Zampini } else { 861a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 862a13144ffSStefano Zampini } 863a13144ffSStefano Zampini } 864a13144ffSStefano Zampini } 865a13144ffSStefano Zampini } 866a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 867a13144ffSStefano Zampini } 868a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 869a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 870c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 871a13144ffSStefano Zampini 872a13144ffSStefano Zampini /* Reset marked primal dofs */ 873a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 874a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 875a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 876a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 877a13144ffSStefano Zampini 8780569b399SStefano Zampini /* Now use the initial lG */ 8790569b399SStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 8800569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 8810569b399SStefano Zampini lG = lGinit; 8820569b399SStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 8830569b399SStefano Zampini 884a13144ffSStefano Zampini /* Compute extended cols indices */ 885b03ebc13SStefano Zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 886b03ebc13SStefano Zampini ierr = PetscBTCreate(nee,&bter);CHKERRQ(ierr); 887a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 888a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 889a13144ffSStefano Zampini i *= maxsize; 890b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 891a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 892a13144ffSStefano Zampini eerr = PETSC_FALSE; 893a13144ffSStefano Zampini for (i=0;i<nee;i++) { 894b03ebc13SStefano Zampini PetscInt size,found = 0; 895a13144ffSStefano Zampini 896a13144ffSStefano Zampini cum = 0; 897a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8981e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8996080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 900a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 901b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 902a13144ffSStefano Zampini for (j=0;j<size;j++) { 903a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 904b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 905b03ebc13SStefano Zampini PetscInt vv = jj[k]; 906b03ebc13SStefano Zampini if (!PetscBTLookup(btv,vv)) extrow[cum++] = vv; 907b03ebc13SStefano Zampini else if (!PetscBTLookupSet(btvc,vv)) found++; 908b03ebc13SStefano Zampini } 909a13144ffSStefano Zampini } 910a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 911a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 912a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 913a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 914a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 915a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 916a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 917b03ebc13SStefano Zampini if (cum != size -1 || found != 2) { 918b03ebc13SStefano Zampini ierr = PetscBTSet(bter,i);CHKERRQ(ierr); 919a13144ffSStefano Zampini if (print) { 920a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 921a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 922a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 923a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 924a13144ffSStefano Zampini } 925a13144ffSStefano Zampini eerr = PETSC_TRUE; 926a13144ffSStefano Zampini } 927a13144ffSStefano Zampini } 9284e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 929a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 930a13144ffSStefano Zampini if (done) { 931a13144ffSStefano Zampini PetscInt *newprimals; 932a13144ffSStefano Zampini 933a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 934a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 935a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 936a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 937a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 9380569b399SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 9396080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"DOING SECOND PASS (eerr %D)\n",eerr); 940a13144ffSStefano Zampini for (i=0;i<nee;i++) { 941b03ebc13SStefano Zampini PetscBool has_candidates = PETSC_FALSE; 942b03ebc13SStefano Zampini if (PetscBTLookup(bter,i)) { 943a13144ffSStefano Zampini PetscInt size,mark = i+1; 944a13144ffSStefano Zampini 945a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 946a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 947c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 948a13144ffSStefano Zampini for (j=0;j<size;j++) { 949a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 9506080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"Inspecting edge dof %D [%D %D)\n",ee,ii[ee],ii[ee+1]); 951a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 952a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 953a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 954a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 955b03ebc13SStefano Zampini has_candidates = PETSC_TRUE; 9566080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Candidate set to vertex %D\n",vv); 957a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 958a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 959a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 960a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 961a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 9626080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected edge dof set to primal %D\n",ee2); 963a13144ffSStefano Zampini newprimals[cum++] = ee2; 964a13144ffSStefano Zampini /* finally set the new corners */ 965a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 9666080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected nodal dof set to vertex %D\n",jj[k3]); 967a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 968a13144ffSStefano Zampini } 969a13144ffSStefano Zampini } 970a13144ffSStefano Zampini } 971b03ebc13SStefano Zampini } else { 9726080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Not a candidate vertex %D\n",jj[k]); 973a13144ffSStefano Zampini } 974a13144ffSStefano Zampini } 975a13144ffSStefano Zampini } 976b03ebc13SStefano Zampini if (!has_candidates) { /* circular edge */ 977b03ebc13SStefano Zampini PetscInt k, ee = idxs[0],*tmarks; 978b03ebc13SStefano Zampini 979b03ebc13SStefano Zampini ierr = PetscCalloc1(ne,&tmarks);CHKERRQ(ierr); 9806080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Circular edge %D\n",i); 981b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 982b03ebc13SStefano Zampini PetscInt k2; 9836080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Set to corner %D\n",jj[k]); 984b03ebc13SStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 985b03ebc13SStefano Zampini for (k2=iit[jj[k]];k2<iit[jj[k]+1];k2++) tmarks[jjt[k2]]++; 986b03ebc13SStefano Zampini } 987b03ebc13SStefano Zampini for (j=0;j<size;j++) { 988b03ebc13SStefano Zampini if (tmarks[idxs[j]] > 1) { 9896080607fSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Edge dof set to primal %D\n",idxs[j]); 990b03ebc13SStefano Zampini newprimals[cum++] = idxs[j]; 991b03ebc13SStefano Zampini } 992b03ebc13SStefano Zampini } 993b03ebc13SStefano Zampini ierr = PetscFree(tmarks);CHKERRQ(ierr); 994b03ebc13SStefano Zampini } 995a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 996a13144ffSStefano Zampini } 997a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 998a13144ffSStefano Zampini } 999b03ebc13SStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 10000569b399SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 1001a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 1002c2151214SStefano Zampini if (fl2g) { 1003c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 1004c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1005c2151214SStefano Zampini for (i=0;i<nee;i++) { 1006c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1007c2151214SStefano Zampini } 1008c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1009c2151214SStefano Zampini } 1010c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1011a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 1012a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 1013a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 1014a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1015a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 1016213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 1017c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1018c2151214SStefano Zampini if (fl2g) { 1019c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 1020c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 1021c2151214SStefano Zampini for (i=0;i<nee;i++) { 1022c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 1023c2151214SStefano Zampini } 1024c2151214SStefano Zampini } else { 1025c2151214SStefano Zampini eedges = alleedges; 1026c2151214SStefano Zampini primals = allprimals; 1027c2151214SStefano Zampini } 1028b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 1029a13144ffSStefano Zampini 1030a13144ffSStefano Zampini /* Mark again */ 1031a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 1032a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1033a13144ffSStefano Zampini PetscInt size,mark = i+1; 1034a13144ffSStefano Zampini 1035a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 1036a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1037a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 1038a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1039a13144ffSStefano Zampini } 1040a13144ffSStefano Zampini if (print) { 1041a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 1042a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 1043a13144ffSStefano Zampini } 1044a13144ffSStefano Zampini 1045a13144ffSStefano Zampini /* Recompute extended cols */ 1046a13144ffSStefano Zampini eerr = PETSC_FALSE; 1047a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1048a13144ffSStefano Zampini PetscInt size; 1049a13144ffSStefano Zampini 1050a13144ffSStefano Zampini cum = 0; 1051a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 10521e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 10536080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 1054a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1055a13144ffSStefano Zampini for (j=0;j<size;j++) { 1056a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 10571e0482f5SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 1058a13144ffSStefano Zampini } 1059a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1060a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 1061a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 1062a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 1063a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 1064a13144ffSStefano Zampini if (cum != size -1) { 1065a13144ffSStefano Zampini if (print) { 1066a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 1067a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 1068a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 1069a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 1070a13144ffSStefano Zampini } 1071a13144ffSStefano Zampini eerr = PETSC_TRUE; 1072a13144ffSStefano Zampini } 1073a13144ffSStefano Zampini } 1074a13144ffSStefano Zampini } 1075a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1076a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 1077b03ebc13SStefano Zampini ierr = PetscBTDestroy(&bter);CHKERRQ(ierr); 10787d871cd7SStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 1079a13144ffSStefano Zampini /* an error should not occur at this point */ 1080a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 1081a13144ffSStefano Zampini 10824e64d54eSstefano_zampini /* Check the number of endpoints */ 10830569b399SStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1084b03ebc13SStefano Zampini ierr = PetscMalloc1(2*nee,&corners);CHKERRQ(ierr); 1085b03ebc13SStefano Zampini ierr = PetscMalloc1(nee,&cedges);CHKERRQ(ierr); 10864e64d54eSstefano_zampini for (i=0;i<nee;i++) { 1087b03ebc13SStefano Zampini PetscInt size, found = 0, gc[2]; 10884e64d54eSstefano_zampini 1089b03ebc13SStefano Zampini /* init with defaults */ 1090b03ebc13SStefano Zampini cedges[i] = corners[i*2] = corners[i*2+1] = -1; 10914e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 10921e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 10936080607fSStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %D",i); 10944e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1095b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 10964e64d54eSstefano_zampini for (j=0;j<size;j++) { 10974e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 10984e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 10994e64d54eSstefano_zampini PetscInt vv = jj[k]; 11004e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 11016080607fSStefano Zampini if (found == 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found more then two corners for edge %D",i); 1102b03ebc13SStefano Zampini corners[i*2+found++] = vv; 11034e64d54eSstefano_zampini } 11044e64d54eSstefano_zampini } 11054e64d54eSstefano_zampini } 1106b03ebc13SStefano Zampini if (found != 2) { 1107b03ebc13SStefano Zampini PetscInt e; 1108b03ebc13SStefano Zampini if (fl2g) { 1109b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,1,idxs,&e);CHKERRQ(ierr); 1110b03ebc13SStefano Zampini } else { 1111b03ebc13SStefano Zampini e = idxs[0]; 1112b03ebc13SStefano Zampini } 11136080607fSStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %D corners for edge %D (astart %D, estart %D)",found,i,e,idxs[0]); 1114b03ebc13SStefano Zampini } 1115eee23b56SStefano Zampini 1116eee23b56SStefano Zampini /* get primal dof index on this coarse edge */ 1117b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,2,corners+2*i,gc);CHKERRQ(ierr); 1118b03ebc13SStefano Zampini if (gc[0] > gc[1]) { 1119b03ebc13SStefano Zampini PetscInt swap = corners[2*i]; 1120b03ebc13SStefano Zampini corners[2*i] = corners[2*i+1]; 1121b03ebc13SStefano Zampini corners[2*i+1] = swap; 1122b03ebc13SStefano Zampini } 1123eee23b56SStefano Zampini cedges[i] = idxs[size-1]; 11244e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 11256080607fSStefano 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]); 11264e64d54eSstefano_zampini } 11270569b399SStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 11284e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 11294e64d54eSstefano_zampini 1130a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 1131a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 1132a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 1133a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 1134a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1135a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1136a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 1137a13144ffSStefano Zampini 1138a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1139a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 1140a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 1141a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 1142a13144ffSStefano Zampini if (emax < emarks[j]) { 1143a13144ffSStefano Zampini emax = emarks[j]; 1144a13144ffSStefano Zampini eemax = j; 1145a13144ffSStefano Zampini } 1146a13144ffSStefano Zampini } 1147a13144ffSStefano Zampini /* not relevant for edges */ 1148a13144ffSStefano Zampini if (!eemax) continue; 1149a13144ffSStefano Zampini 1150a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 1151a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 11526080607fSStefano 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",marks[jj[j]]-1,eemax,i,jj[j]); 1153a13144ffSStefano Zampini } 1154a13144ffSStefano Zampini } 1155a13144ffSStefano Zampini } 1156a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 1157a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1158a13144ffSStefano Zampini #endif 1159a13144ffSStefano Zampini 1160a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 1161a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1162a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 1163a13144ffSStefano Zampini extmem *= maxsize; 1164a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 1165a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 1166a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 1167a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1168a13144ffSStefano Zampini PetscInt mark = 0,size,start; 1169213b8bfaSStefano Zampini 1170a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1171a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 1172a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 1173a13144ffSStefano Zampini mark = marks[jj[j]]; 1174a13144ffSStefano Zampini 1175a13144ffSStefano Zampini /* not relevant */ 1176a13144ffSStefano Zampini if (!mark) continue; 1177a13144ffSStefano Zampini 1178a13144ffSStefano Zampini /* import extended row */ 1179a13144ffSStefano Zampini mark--; 1180a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 1181a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 11826080607fSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %D > %D",extrowcum[mark] + size,extmem); 1183a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 1184a13144ffSStefano Zampini extrowcum[mark] += size; 1185a13144ffSStefano Zampini } 1186a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1187213b8bfaSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 1188213b8bfaSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 1189213b8bfaSStefano Zampini 1190213b8bfaSStefano Zampini /* Compress extrows */ 1191a13144ffSStefano Zampini cum = 0; 1192a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1193a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 1194a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 1195a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 1196a13144ffSStefano Zampini cum = PetscMax(cum,size); 1197a13144ffSStefano Zampini } 1198a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 1199a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 1200a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 1201a13144ffSStefano Zampini 1202a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 1203a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 1204a13144ffSStefano Zampini 1205a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 1206a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1207c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 1208c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 1209a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 1210a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 1211a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 12121e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(T,al2g,al2g);CHKERRQ(ierr); 1213a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 1214a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1215213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&al2g);CHKERRQ(ierr); 1216a13144ffSStefano Zampini 1217a13144ffSStefano Zampini /* Defaults to identity */ 1218c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 1219a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 1220a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 1221a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 1222a13144ffSStefano Zampini 12231e0482f5SStefano Zampini /* Create discrete gradient for the coarser level if needed */ 12241e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 12251e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 12261e0482f5SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 12271e0482f5SStefano Zampini ISLocalToGlobalMapping cel2g,cvl2g; 12281e0482f5SStefano Zampini IS wis,gwis; 12291e0482f5SStefano Zampini PetscInt cnv,cne; 12301e0482f5SStefano Zampini 12311e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,nee,cedges,PETSC_COPY_VALUES,&wis);CHKERRQ(ierr); 12321e0482f5SStefano Zampini if (fl2g) { 12331e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(fl2g,wis,&pcbddc->nedclocal);CHKERRQ(ierr); 12341e0482f5SStefano Zampini } else { 12351e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)wis);CHKERRQ(ierr); 12361e0482f5SStefano Zampini pcbddc->nedclocal = wis; 12371e0482f5SStefano Zampini } 12381e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,wis,&gwis);CHKERRQ(ierr); 12391e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12401e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cne,&wis);CHKERRQ(ierr); 12411e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cel2g);CHKERRQ(ierr); 12421e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12431e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 12441e0482f5SStefano Zampini 12451e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,2*nee,corners,PETSC_USE_POINTER,&wis);CHKERRQ(ierr); 12461e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(vl2g,wis,&gwis);CHKERRQ(ierr); 12471e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12481e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cnv,&wis);CHKERRQ(ierr); 12491e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cvl2g);CHKERRQ(ierr); 12501e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12511e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 12521e0482f5SStefano Zampini 12531e0482f5SStefano Zampini ierr = MatCreate(comm,&pcbddc->nedcG);CHKERRQ(ierr); 12541e0482f5SStefano Zampini ierr = MatSetSizes(pcbddc->nedcG,PETSC_DECIDE,PETSC_DECIDE,cne,cnv);CHKERRQ(ierr); 12551e0482f5SStefano Zampini ierr = MatSetType(pcbddc->nedcG,MATAIJ);CHKERRQ(ierr); 12561e0482f5SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->nedcG,2,NULL);CHKERRQ(ierr); 12571e0482f5SStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->nedcG,2,NULL,2,NULL);CHKERRQ(ierr); 12581e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->nedcG,cel2g,cvl2g);CHKERRQ(ierr); 12591e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cel2g);CHKERRQ(ierr); 12601e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cvl2g);CHKERRQ(ierr); 12611e0482f5SStefano Zampini } 1262213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 12631e0482f5SStefano Zampini 12641e0482f5SStefano Zampini #if defined(PRINT_GDET) 12651e0482f5SStefano Zampini inc = 0; 12661e0482f5SStefano Zampini lev = pcbddc->current_level; 12671e0482f5SStefano Zampini #endif 1268213b8bfaSStefano Zampini 1269213b8bfaSStefano Zampini /* Insert values in the change of basis matrix */ 1270a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1271a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 12721e0482f5SStefano Zampini IS cornersis = NULL; 12731e0482f5SStefano Zampini PetscScalar cvals[2]; 1274a13144ffSStefano Zampini 12751e0482f5SStefano Zampini if (pcbddc->nedcG) { 12761e0482f5SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,2,corners+2*i,PETSC_USE_POINTER,&cornersis);CHKERRQ(ierr); 12771e0482f5SStefano Zampini } 12781e0482f5SStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],cornersis,&Gins,&GKins,cvals,work,rwork);CHKERRQ(ierr); 1279a13144ffSStefano Zampini if (Gins && GKins) { 1280a13144ffSStefano Zampini PetscScalar *data; 1281a13144ffSStefano Zampini const PetscInt *rows,*cols; 1282a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 1283a13144ffSStefano Zampini 1284a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 1285a13144ffSStefano Zampini /* H1 */ 1286a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 1287a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 1288a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 1289a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 1290a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 1291a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 1292a13144ffSStefano Zampini /* complement */ 1293a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 12946080607fSStefano Zampini if (!ncc) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Constant function has not been generated for coarse edge %D",i); 12956080607fSStefano 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); 12966080607fSStefano 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); 1297a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 1298a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 1299a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 13001e0482f5SStefano Zampini 13011e0482f5SStefano Zampini /* coarse discrete gradient */ 13021e0482f5SStefano Zampini if (pcbddc->nedcG) { 13031e0482f5SStefano Zampini PetscInt cols[2]; 13041e0482f5SStefano Zampini 13051e0482f5SStefano Zampini cols[0] = 2*i; 13061e0482f5SStefano Zampini cols[1] = 2*i+1; 13071e0482f5SStefano Zampini ierr = MatSetValuesLocal(pcbddc->nedcG,1,&i,2,cols,cvals,INSERT_VALUES);CHKERRQ(ierr); 13081e0482f5SStefano Zampini } 1309a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 1310a13144ffSStefano Zampini } 1311a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 1312a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 13131e0482f5SStefano Zampini ierr = ISDestroy(&cornersis);CHKERRQ(ierr); 1314a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 1315a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 1316a13144ffSStefano Zampini } 1317213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 1318a13144ffSStefano Zampini 1319a13144ffSStefano Zampini /* Start assembling */ 1320a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13211e0482f5SStefano Zampini if (pcbddc->nedcG) { 13221e0482f5SStefano Zampini ierr = MatAssemblyBegin(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13231e0482f5SStefano Zampini } 1324a13144ffSStefano Zampini 1325a13144ffSStefano Zampini /* Free */ 1326c2151214SStefano Zampini if (fl2g) { 1327c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1328c2151214SStefano Zampini for (i=0;i<nee;i++) { 1329c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1330c2151214SStefano Zampini } 1331c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1332c2151214SStefano Zampini } 1333eee23b56SStefano Zampini 1334eee23b56SStefano Zampini /* hack mat_graph with primal dofs on the coarse edges */ 1335eee23b56SStefano Zampini { 1336eee23b56SStefano Zampini PCBDDCGraph graph = pcbddc->mat_graph; 1337eee23b56SStefano Zampini PetscInt *oqueue = graph->queue; 1338eee23b56SStefano Zampini PetscInt *ocptr = graph->cptr; 1339eee23b56SStefano Zampini PetscInt ncc,*idxs; 1340eee23b56SStefano Zampini 1341eee23b56SStefano Zampini /* find first primal edge */ 1342eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1343eee23b56SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1344eee23b56SStefano Zampini } else { 1345eee23b56SStefano Zampini if (fl2g) { 1346eee23b56SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,nee,cedges,cedges);CHKERRQ(ierr); 1347eee23b56SStefano Zampini } 1348eee23b56SStefano Zampini idxs = cedges; 1349eee23b56SStefano Zampini } 1350eee23b56SStefano Zampini cum = 0; 1351eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1352eee23b56SStefano Zampini 1353eee23b56SStefano Zampini /* adapt connected components */ 1354eee23b56SStefano Zampini ierr = PetscMalloc2(graph->nvtxs+1,&graph->cptr,ocptr[graph->ncc],&graph->queue);CHKERRQ(ierr); 1355eee23b56SStefano Zampini graph->cptr[0] = 0; 1356eee23b56SStefano Zampini for (i=0,ncc=0;i<graph->ncc;i++) { 1357eee23b56SStefano Zampini PetscInt lc = ocptr[i+1]-ocptr[i]; 1358eee23b56SStefano Zampini if (cum != nee && oqueue[ocptr[i+1]-1] == cedges[cum]) { /* this cc has a primal dof */ 1359eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc]+1; 1360eee23b56SStefano Zampini graph->queue[graph->cptr[ncc]] = cedges[cum]; 1361eee23b56SStefano Zampini ncc++; 1362eee23b56SStefano Zampini lc--; 1363eee23b56SStefano Zampini cum++; 1364eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1365eee23b56SStefano Zampini } 1366eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc] + lc; 1367eee23b56SStefano Zampini for (j=0;j<lc;j++) graph->queue[graph->cptr[ncc]+j] = oqueue[ocptr[i]+j]; 1368eee23b56SStefano Zampini ncc++; 1369eee23b56SStefano Zampini } 1370eee23b56SStefano Zampini graph->ncc = ncc; 1371eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1372eee23b56SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1373eee23b56SStefano Zampini } 1374eee23b56SStefano Zampini ierr = PetscFree2(ocptr,oqueue);CHKERRQ(ierr); 1375eee23b56SStefano Zampini } 1376213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 1377c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1378c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1379213b8bfaSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1380eee23b56SStefano Zampini 1381c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1382a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 1383a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 1384b03ebc13SStefano Zampini ierr = PetscFree(corners);CHKERRQ(ierr); 1385b03ebc13SStefano Zampini ierr = PetscFree(cedges);CHKERRQ(ierr); 1386a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 1387a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 1388a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 1389a13144ffSStefano Zampini 1390a13144ffSStefano Zampini /* Complete assembling */ 1391a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13921e0482f5SStefano Zampini if (pcbddc->nedcG) { 13931e0482f5SStefano Zampini ierr = MatAssemblyEnd(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13941e0482f5SStefano Zampini #if 0 13951e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->nedcG,"coarse_G");CHKERRQ(ierr); 13961e0482f5SStefano Zampini ierr = MatView(pcbddc->nedcG,NULL);CHKERRQ(ierr); 13971e0482f5SStefano Zampini #endif 13981e0482f5SStefano Zampini } 1399a13144ffSStefano Zampini 1400a13144ffSStefano Zampini /* set change of basis */ 1401213b8bfaSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,singular);CHKERRQ(ierr); 1402a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1403a13144ffSStefano Zampini 1404a13144ffSStefano Zampini PetscFunctionReturn(0); 1405a13144ffSStefano Zampini } 1406a13144ffSStefano Zampini 1407d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1408d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1409d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1410d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1411d8203eabSStefano Zampini { 1412d8203eabSStefano Zampini PetscErrorCode ierr; 1413d8203eabSStefano Zampini PetscInt i; 1414d8203eabSStefano Zampini 1415d8203eabSStefano Zampini PetscFunctionBegin; 1416d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1417d8203eabSStefano Zampini PetscInt first,last; 1418d8203eabSStefano Zampini 1419d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 142086fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1421d8203eabSStefano Zampini if (i>=first && i < last) { 1422d8203eabSStefano Zampini PetscScalar *data; 1423d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1424d8203eabSStefano Zampini if (!has_const) { 1425d8203eabSStefano Zampini data[i-first] = 1.; 1426d8203eabSStefano Zampini } else { 142786fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 142886fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1429d8203eabSStefano Zampini } 1430d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1431d8203eabSStefano Zampini } 1432d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1433d8203eabSStefano Zampini } 1434d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1435d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1436d8203eabSStefano Zampini PetscInt first,last; 1437ddc40e2cSstefano_zampini ierr = VecLockPop(quad_vecs[i]);CHKERRQ(ierr); 1438d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1439d8203eabSStefano Zampini if (i>=first && i < last) { 1440d8203eabSStefano Zampini PetscScalar *data; 1441d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1442d8203eabSStefano Zampini if (!has_const) { 1443d8203eabSStefano Zampini data[i-first] = 0.; 1444d8203eabSStefano Zampini } else { 144586fa73c5SStefano Zampini data[2*i-first] = 0.; 144686fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1447d8203eabSStefano Zampini } 1448d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1449d8203eabSStefano Zampini } 1450d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1451ddc40e2cSstefano_zampini ierr = VecLockPush(quad_vecs[i]);CHKERRQ(ierr); 1452d8203eabSStefano Zampini } 1453d8203eabSStefano Zampini PetscFunctionReturn(0); 1454d8203eabSStefano Zampini } 1455d8203eabSStefano Zampini 14568ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1457669cc0f4SStefano Zampini { 1458a198735bSStefano Zampini Mat loc_divudotp; 1459fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 14608ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1461669cc0f4SStefano Zampini PetscScalar *vals; 1462669cc0f4SStefano Zampini const PetscScalar *array; 1463a040e873SStefano Zampini PetscInt i,maxneighs,maxsize; 1464a040e873SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 14651ae86dd6SStefano Zampini PetscMPIInt rank; 1466a198735bSStefano Zampini PetscErrorCode ierr; 1467669cc0f4SStefano Zampini 1468669cc0f4SStefano Zampini PetscFunctionBegin; 1469a040e873SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1470a040e873SStefano Zampini ierr = MPIU_Allreduce(&n_neigh,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 14718037d520SStefano Zampini if (!maxneighs) { 14728037d520SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 14738037d520SStefano Zampini *nnsp = NULL; 14748037d520SStefano Zampini PetscFunctionReturn(0); 1475669cc0f4SStefano Zampini } 1476669cc0f4SStefano Zampini maxsize = 0; 1477a040e873SStefano Zampini for (i=0;i<n_neigh;i++) maxsize = PetscMax(n_shared[i],maxsize); 1478669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1479669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1480669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 14818ae0ca82SStefano Zampini if (!transpose) { 14828ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 14838ae0ca82SStefano Zampini } else { 14848ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 14858ae0ca82SStefano Zampini } 1486669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 14871ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1488d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1489669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1490ddc40e2cSstefano_zampini ierr = VecLockPop(quad_vecs[i]);CHKERRQ(ierr); 14918ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 1492669cc0f4SStefano Zampini } 1493d8203eabSStefano Zampini 1494669cc0f4SStefano Zampini /* compute local quad vec */ 1495a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 14968ae0ca82SStefano Zampini if (!transpose) { 1497a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 14988ae0ca82SStefano Zampini } else { 14998ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 15008ae0ca82SStefano Zampini } 1501669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 15028ae0ca82SStefano Zampini if (!transpose) { 1503a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 15048ae0ca82SStefano Zampini } else { 15058ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 15068ae0ca82SStefano Zampini } 1507fa23a32eSStefano Zampini if (vl2l) { 1508187c917aSStefano Zampini Mat lA; 1509187c917aSStefano Zampini VecScatter sc; 1510187c917aSStefano Zampini 1511187c917aSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1512187c917aSStefano Zampini ierr = MatCreateVecs(lA,&vins,NULL);CHKERRQ(ierr); 1513187c917aSStefano Zampini ierr = VecScatterCreate(v,vl2l,vins,NULL,&sc);CHKERRQ(ierr); 1514187c917aSStefano Zampini ierr = VecScatterBegin(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1515187c917aSStefano Zampini ierr = VecScatterEnd(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1516187c917aSStefano Zampini ierr = VecScatterDestroy(&sc);CHKERRQ(ierr); 1517fa23a32eSStefano Zampini } else { 1518fa23a32eSStefano Zampini vins = v; 1519fa23a32eSStefano Zampini } 1520fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1521669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 15229a962809SStefano Zampini 15231ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 15241ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1525a040e873SStefano Zampini for (i=0;i<n_neigh;i++) { 1526669cc0f4SStefano Zampini const PetscInt *idxs; 1527669cc0f4SStefano Zampini PetscInt idx,nn,j; 1528669cc0f4SStefano Zampini 1529a040e873SStefano Zampini idxs = shared[i]; 1530a040e873SStefano Zampini nn = n_shared[i]; 1531669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 15321ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1533669cc0f4SStefano Zampini idx = -(idx+1); 1534669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1535669cc0f4SStefano Zampini } 1536a040e873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1537fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1538fa23a32eSStefano Zampini if (vl2l) { 1539187c917aSStefano Zampini ierr = VecDestroy(&vins);CHKERRQ(ierr); 1540fa23a32eSStefano Zampini } 1541669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1542669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1543669cc0f4SStefano Zampini 1544669cc0f4SStefano Zampini /* assemble near null space */ 1545669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1546669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1547669cc0f4SStefano Zampini } 1548669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1549669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 15503272d46bSStefano Zampini ierr = VecViewFromOptions(quad_vecs[i],NULL,"-pc_bddc_quad_vecs_view");CHKERRQ(ierr); 1551ddc40e2cSstefano_zampini ierr = VecLockPush(quad_vecs[i]);CHKERRQ(ierr); 1552669cc0f4SStefano Zampini } 1553669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1554669cc0f4SStefano Zampini PetscFunctionReturn(0); 1555669cc0f4SStefano Zampini } 1556669cc0f4SStefano Zampini 15577620a527SStefano Zampini PetscErrorCode PCBDDCAddPrimalVerticesLocalIS(PC pc, IS primalv) 15587620a527SStefano Zampini { 15597620a527SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15607620a527SStefano Zampini PetscErrorCode ierr; 15617620a527SStefano Zampini 15627620a527SStefano Zampini PetscFunctionBegin; 15637620a527SStefano Zampini if (primalv) { 15647620a527SStefano Zampini if (pcbddc->user_primal_vertices_local) { 15657620a527SStefano Zampini IS list[2], newp; 15667620a527SStefano Zampini 15677620a527SStefano Zampini list[0] = primalv; 15687620a527SStefano Zampini list[1] = pcbddc->user_primal_vertices_local; 15697620a527SStefano Zampini ierr = ISConcatenate(PetscObjectComm((PetscObject)pc),2,list,&newp);CHKERRQ(ierr); 15707620a527SStefano Zampini ierr = ISSortRemoveDups(newp);CHKERRQ(ierr); 15717620a527SStefano Zampini ierr = ISDestroy(&list[1]);CHKERRQ(ierr); 15727620a527SStefano Zampini pcbddc->user_primal_vertices_local = newp; 15737620a527SStefano Zampini } else { 15747620a527SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 15757620a527SStefano Zampini } 15767620a527SStefano Zampini } 15777620a527SStefano Zampini PetscFunctionReturn(0); 15787620a527SStefano Zampini } 1579669cc0f4SStefano Zampini 15801c7a958bSStefano Zampini static PetscErrorCode func_coords_private(PetscInt dim, PetscReal t, const PetscReal X[], PetscInt Nf, PetscScalar *out, void *ctx) 15811c7a958bSStefano Zampini { 15821c7a958bSStefano Zampini PetscInt f, *comp = (PetscInt *)ctx; 15831c7a958bSStefano Zampini 15841c7a958bSStefano Zampini PetscFunctionBegin; 15851c7a958bSStefano Zampini for (f=0;f<Nf;f++) out[f] = X[*comp]; 15861c7a958bSStefano Zampini PetscFunctionReturn(0); 15871c7a958bSStefano Zampini } 1588674ae819SStefano Zampini 15891f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 15901f4df5f7SStefano Zampini { 15911f4df5f7SStefano Zampini PetscErrorCode ierr; 15921f4df5f7SStefano Zampini Vec local,global; 15931f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15941f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 15955c5e10d6SStefano Zampini PetscBool monolithic = PETSC_FALSE; 15961f4df5f7SStefano Zampini 15971f4df5f7SStefano Zampini PetscFunctionBegin; 15985c5e10d6SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC topology options","PC");CHKERRQ(ierr); 15995c5e10d6SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_monolithic","Discard any information on dofs splitting",NULL,monolithic,&monolithic,NULL);CHKERRQ(ierr); 16005c5e10d6SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 16011f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 160221ef3d20SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 16031f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 16046a8fc67bSStefano Zampini if (monolithic) { /* just get block size to properly compute vertices */ 16056a8fc67bSStefano Zampini if (pcbddc->vertex_size == 1) { 16066a8fc67bSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->vertex_size);CHKERRQ(ierr); 16076a8fc67bSStefano Zampini } 16086a8fc67bSStefano Zampini goto boundary; 16096a8fc67bSStefano Zampini } 16105c5e10d6SStefano Zampini 16111f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 16121f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 16131f4df5f7SStefano Zampini PetscInt i; 16141f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16151f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 16161f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16171f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 16181f4df5f7SStefano Zampini } 16191f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 16201f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 16211f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 16221f4df5f7SStefano Zampini } 16231f4df5f7SStefano Zampini } else { 162421ef3d20SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present */ 162521ef3d20SStefano Zampini DM dm; 162621ef3d20SStefano Zampini 162721ef3d20SStefano Zampini ierr = PCGetDM(pc, &dm);CHKERRQ(ierr); 162821ef3d20SStefano Zampini if (!dm) { 162921ef3d20SStefano Zampini ierr = MatGetDM(pc->pmat, &dm);CHKERRQ(ierr); 163021ef3d20SStefano Zampini } 163121ef3d20SStefano Zampini if (dm) { 163221ef3d20SStefano Zampini IS *fields; 163321ef3d20SStefano Zampini PetscInt nf,i; 163421ef3d20SStefano Zampini ierr = DMCreateFieldDecomposition(dm,&nf,NULL,&fields,NULL);CHKERRQ(ierr); 163521ef3d20SStefano Zampini ierr = PetscMalloc1(nf,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 163621ef3d20SStefano Zampini for (i=0;i<nf;i++) { 163721ef3d20SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,fields[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 163821ef3d20SStefano Zampini ierr = ISDestroy(&fields[i]);CHKERRQ(ierr); 163921ef3d20SStefano Zampini } 164021ef3d20SStefano Zampini ierr = PetscFree(fields);CHKERRQ(ierr); 164121ef3d20SStefano Zampini pcbddc->n_ISForDofsLocal = nf; 164221ef3d20SStefano Zampini } else { /* See if MATIS has fields attached by the conversion from MatNest */ 164321ef3d20SStefano Zampini PetscContainer c; 164421ef3d20SStefano Zampini 164521ef3d20SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc->pmat,"_convert_nest_lfields",(PetscObject*)&c);CHKERRQ(ierr); 164621ef3d20SStefano Zampini if (c) { 164721ef3d20SStefano Zampini MatISLocalFields lf; 164821ef3d20SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&lf);CHKERRQ(ierr); 164921ef3d20SStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,lf->nr,lf->rf);CHKERRQ(ierr); 165021ef3d20SStefano Zampini } else { /* fallback, create the default fields if bs > 1 */ 16511f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1652986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 165321ef3d20SStefano Zampini if (i > 1) { 1654986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 16551f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16561f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16571f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16581f4df5f7SStefano Zampini } 16591f4df5f7SStefano Zampini } 166021ef3d20SStefano Zampini } 166121ef3d20SStefano Zampini } 16627a0e7b2cSstefano_zampini } else { 16637a0e7b2cSstefano_zampini PetscInt i; 16647a0e7b2cSstefano_zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16657a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16667a0e7b2cSstefano_zampini } 16671f4df5f7SStefano Zampini } 1668986cdee1SStefano Zampini } 16691f4df5f7SStefano Zampini 16705c5e10d6SStefano Zampini boundary: 16711f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 16721f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16737a0e7b2cSstefano_zampini } else if (pcbddc->DirichletBoundariesLocal) { 16747a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16751f4df5f7SStefano Zampini } 16761f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 16771f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16787a0e7b2cSstefano_zampini } else if (pcbddc->NeumannBoundariesLocal) { 16797a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16801f4df5f7SStefano Zampini } 16811f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 16821f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 16831f4df5f7SStefano Zampini } 16841f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 16851f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 16867620a527SStefano Zampini /* detect local disconnected subdomains if requested (use matis->A) */ 16877620a527SStefano Zampini if (pcbddc->detect_disconnected) { 16887620a527SStefano Zampini IS primalv = NULL; 16897620a527SStefano Zampini PetscInt i; 16908361f951SStefano Zampini PetscBool filter = pcbddc->detect_disconnected_filter; 16917a0e7b2cSstefano_zampini 16927620a527SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 16937620a527SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 16947620a527SStefano Zampini } 16957620a527SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 16968361f951SStefano Zampini ierr = PCBDDCDetectDisconnectedComponents(pc,filter,&pcbddc->n_local_subs,&pcbddc->local_subs,&primalv);CHKERRQ(ierr); 16977620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 16987620a527SStefano Zampini ierr = ISDestroy(&primalv);CHKERRQ(ierr); 16997620a527SStefano Zampini } 17007620a527SStefano Zampini /* early stage corner detection */ 17017620a527SStefano Zampini { 17027620a527SStefano Zampini DM dm; 17037620a527SStefano Zampini 17047620a527SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 17057620a527SStefano Zampini if (dm) { 17067620a527SStefano Zampini PetscBool isda; 17077620a527SStefano Zampini 17087620a527SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&isda);CHKERRQ(ierr); 17097620a527SStefano Zampini if (isda) { 17107620a527SStefano Zampini ISLocalToGlobalMapping l2l; 17117620a527SStefano Zampini IS corners; 17127620a527SStefano Zampini Mat lA; 17137620a527SStefano Zampini 1714d4a6ed37SStefano Zampini ierr = DMDAGetSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17157620a527SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17167620a527SStefano Zampini ierr = MatGetLocalToGlobalMapping(lA,&l2l,NULL);CHKERRQ(ierr); 17177620a527SStefano Zampini ierr = MatISRestoreLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 1718fa55603eSStefano Zampini if (l2l && corners) { 17197620a527SStefano Zampini const PetscInt *idx; 172072ed36d8SStefano Zampini PetscInt dof,bs,*idxout,n; 17217620a527SStefano Zampini 172272ed36d8SStefano Zampini ierr = DMDAGetInfo(dm,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&dof,NULL,NULL,NULL,NULL,NULL);CHKERRQ(ierr); 17237620a527SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(l2l,&bs);CHKERRQ(ierr); 17247620a527SStefano Zampini ierr = ISGetLocalSize(corners,&n);CHKERRQ(ierr); 17257620a527SStefano Zampini ierr = ISGetIndices(corners,&idx);CHKERRQ(ierr); 172672ed36d8SStefano Zampini if (bs == dof) { 17277620a527SStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 17287620a527SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(l2l,n,idx,idxout);CHKERRQ(ierr); 172972ed36d8SStefano Zampini } else { /* the original DMDA local-to-local map have been modified */ 173072ed36d8SStefano Zampini PetscInt i,d; 173172ed36d8SStefano Zampini 173272ed36d8SStefano Zampini ierr = PetscMalloc1(dof*n,&idxout);CHKERRQ(ierr); 173372ed36d8SStefano Zampini for (i=0;i<n;i++) for (d=0;d<dof;d++) idxout[dof*i+d] = dof*idx[i]+d; 173472ed36d8SStefano Zampini ierr = ISLocalToGlobalMappingApply(l2l,dof*n,idxout,idxout);CHKERRQ(ierr); 173572ed36d8SStefano Zampini 173672ed36d8SStefano Zampini bs = 1; 173772ed36d8SStefano Zampini n *= dof; 173872ed36d8SStefano Zampini } 17397620a527SStefano Zampini ierr = ISRestoreIndices(corners,&idx);CHKERRQ(ierr); 1740d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17417620a527SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)pc),bs,n,idxout,PETSC_OWN_POINTER,&corners);CHKERRQ(ierr); 17427620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,corners);CHKERRQ(ierr); 17437620a527SStefano Zampini ierr = ISDestroy(&corners);CHKERRQ(ierr); 17441c7a958bSStefano Zampini pcbddc->corner_selected = PETSC_TRUE; 1745fa55603eSStefano Zampini } else if (corners) { /* not from DMDA */ 1746d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17477620a527SStefano Zampini } 17487620a527SStefano Zampini } 17497620a527SStefano Zampini } 17507620a527SStefano Zampini } 17511c7a958bSStefano Zampini if (pcbddc->corner_selection && !pcbddc->mat_graph->cdim) { 17521c7a958bSStefano Zampini DM dm; 17531c7a958bSStefano Zampini 17541c7a958bSStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 17551c7a958bSStefano Zampini if (!dm) { 17561c7a958bSStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 17571c7a958bSStefano Zampini } 17581c7a958bSStefano Zampini if (dm) { 17591c7a958bSStefano Zampini Vec vcoords; 17601c7a958bSStefano Zampini PetscSection section; 17611c7a958bSStefano Zampini PetscReal *coords; 17621c7a958bSStefano Zampini PetscInt d,cdim,nl,nf,**ctxs; 17631c7a958bSStefano Zampini PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal *, PetscInt, PetscScalar *, void *); 17641c7a958bSStefano Zampini 17651c7a958bSStefano Zampini ierr = DMGetCoordinateDim(dm,&cdim);CHKERRQ(ierr); 1766e87a4003SBarry Smith ierr = DMGetSection(dm,§ion);CHKERRQ(ierr); 17671c7a958bSStefano Zampini ierr = PetscSectionGetNumFields(section,&nf);CHKERRQ(ierr); 17681c7a958bSStefano Zampini ierr = DMCreateGlobalVector(dm,&vcoords);CHKERRQ(ierr); 17691c7a958bSStefano Zampini ierr = VecGetLocalSize(vcoords,&nl);CHKERRQ(ierr); 17701c7a958bSStefano Zampini ierr = PetscMalloc1(nl*cdim,&coords);CHKERRQ(ierr); 17711c7a958bSStefano Zampini ierr = PetscMalloc2(nf,&funcs,nf,&ctxs);CHKERRQ(ierr); 17721c7a958bSStefano Zampini ierr = PetscMalloc1(nf,&ctxs[0]);CHKERRQ(ierr); 17731c7a958bSStefano Zampini for (d=0;d<nf;d++) funcs[d] = func_coords_private; 17741c7a958bSStefano Zampini for (d=1;d<nf;d++) ctxs[d] = ctxs[d-1] + 1; 17751c7a958bSStefano Zampini for (d=0;d<cdim;d++) { 17761c7a958bSStefano Zampini PetscInt i; 17771c7a958bSStefano Zampini const PetscScalar *v; 17781c7a958bSStefano Zampini 17791c7a958bSStefano Zampini for (i=0;i<nf;i++) ctxs[i][0] = d; 17801c7a958bSStefano Zampini ierr = DMProjectFunction(dm,0.0,funcs,(void**)ctxs,INSERT_VALUES,vcoords);CHKERRQ(ierr); 17811c7a958bSStefano Zampini ierr = VecGetArrayRead(vcoords,&v);CHKERRQ(ierr); 17821c7a958bSStefano Zampini for (i=0;i<nl;i++) coords[i*cdim+d] = PetscRealPart(v[i]); 17831c7a958bSStefano Zampini ierr = VecRestoreArrayRead(vcoords,&v);CHKERRQ(ierr); 17841c7a958bSStefano Zampini } 17851c7a958bSStefano Zampini ierr = VecDestroy(&vcoords);CHKERRQ(ierr); 17861c7a958bSStefano Zampini ierr = PCSetCoordinates(pc,cdim,nl,coords);CHKERRQ(ierr); 17871c7a958bSStefano Zampini ierr = PetscFree(coords);CHKERRQ(ierr); 17881c7a958bSStefano Zampini ierr = PetscFree(ctxs[0]);CHKERRQ(ierr); 17891c7a958bSStefano Zampini ierr = PetscFree2(funcs,ctxs);CHKERRQ(ierr); 17901c7a958bSStefano Zampini } 17911c7a958bSStefano Zampini } 17927a0e7b2cSstefano_zampini PetscFunctionReturn(0); 17937a0e7b2cSstefano_zampini } 17947a0e7b2cSstefano_zampini 17957a0e7b2cSstefano_zampini PetscErrorCode PCBDDCConsistencyCheckIS(PC pc, MPI_Op mop, IS *is) 17967a0e7b2cSstefano_zampini { 17977a0e7b2cSstefano_zampini Mat_IS *matis = (Mat_IS*)(pc->pmat->data); 17987a0e7b2cSstefano_zampini PetscErrorCode ierr; 17997a0e7b2cSstefano_zampini IS nis; 18007a0e7b2cSstefano_zampini const PetscInt *idxs; 18017a0e7b2cSstefano_zampini PetscInt i,nd,n = matis->A->rmap->n,*nidxs,nnd; 18027a0e7b2cSstefano_zampini PetscBool *ld; 18037a0e7b2cSstefano_zampini 18047a0e7b2cSstefano_zampini PetscFunctionBegin; 18057a0e7b2cSstefano_zampini if (mop != MPI_LAND && mop != MPI_LOR) SETERRQ(PetscObjectComm((PetscObject)(pc)),PETSC_ERR_SUP,"Supported are MPI_LAND and MPI_LOR"); 18067a0e7b2cSstefano_zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 18077a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18087a0e7b2cSstefano_zampini /* init rootdata with true */ 18097a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_rootdata; 18107a0e7b2cSstefano_zampini for (i=0;i<pc->pmat->rmap->n;i++) ld[i] = PETSC_TRUE; 18117a0e7b2cSstefano_zampini } else { 18127a0e7b2cSstefano_zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscBool));CHKERRQ(ierr); 18137a0e7b2cSstefano_zampini } 18147a0e7b2cSstefano_zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscBool));CHKERRQ(ierr); 18157a0e7b2cSstefano_zampini ierr = ISGetLocalSize(*is,&nd);CHKERRQ(ierr); 18167a0e7b2cSstefano_zampini ierr = ISGetIndices(*is,&idxs);CHKERRQ(ierr); 18177a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_leafdata; 18187a0e7b2cSstefano_zampini for (i=0;i<nd;i++) 18197a0e7b2cSstefano_zampini if (-1 < idxs[i] && idxs[i] < n) 18207a0e7b2cSstefano_zampini ld[idxs[i]] = PETSC_TRUE; 18217a0e7b2cSstefano_zampini ierr = ISRestoreIndices(*is,&idxs);CHKERRQ(ierr); 18227a0e7b2cSstefano_zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18237a0e7b2cSstefano_zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18247a0e7b2cSstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18257a0e7b2cSstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18267a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18277a0e7b2cSstefano_zampini ierr = PetscMalloc1(nd,&nidxs);CHKERRQ(ierr); 18287a0e7b2cSstefano_zampini } else { 18297a0e7b2cSstefano_zampini ierr = PetscMalloc1(n,&nidxs);CHKERRQ(ierr); 18307a0e7b2cSstefano_zampini } 18317a0e7b2cSstefano_zampini for (i=0,nnd=0;i<n;i++) 18327a0e7b2cSstefano_zampini if (ld[i]) 18337a0e7b2cSstefano_zampini nidxs[nnd++] = i; 18347a0e7b2cSstefano_zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(*is)),nnd,nidxs,PETSC_OWN_POINTER,&nis);CHKERRQ(ierr); 18357a0e7b2cSstefano_zampini ierr = ISDestroy(is);CHKERRQ(ierr); 18367a0e7b2cSstefano_zampini *is = nis; 18371f4df5f7SStefano Zampini PetscFunctionReturn(0); 18381f4df5f7SStefano Zampini } 18391f4df5f7SStefano Zampini 18403e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 18413e589ea0SStefano Zampini { 18423e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 18433e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 18443e589ea0SStefano Zampini PetscErrorCode ierr; 18453e589ea0SStefano Zampini 18463e589ea0SStefano Zampini PetscFunctionBegin; 18473e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 18483e589ea0SStefano Zampini PetscFunctionReturn(0); 18493e589ea0SStefano Zampini } 18503e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18513e589ea0SStefano Zampini Vec swap; 18523e589ea0SStefano Zampini 18533e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 18543e589ea0SStefano Zampini swap = pcbddc->work_change; 18553e589ea0SStefano Zampini pcbddc->work_change = r; 18563e589ea0SStefano Zampini r = swap; 18573e589ea0SStefano Zampini } 18583e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18593e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18603e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 18613e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 18623e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18633e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18643e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1865f913dca9SStefano Zampini pcbddc->work_change = r; 18663e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 18673e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 18683e589ea0SStefano Zampini } 18693e589ea0SStefano Zampini PetscFunctionReturn(0); 18703e589ea0SStefano Zampini } 18713e589ea0SStefano Zampini 1872a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1873a3df083aSStefano Zampini { 1874a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1875a3df083aSStefano Zampini PetscErrorCode ierr; 1876a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1877a3df083aSStefano Zampini 1878a3df083aSStefano Zampini PetscFunctionBegin; 1879a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1880a3df083aSStefano Zampini if (transpose) { 1881a3df083aSStefano Zampini apply_right = ctx->apply_left; 1882a3df083aSStefano Zampini apply_left = ctx->apply_right; 1883a3df083aSStefano Zampini } else { 1884a3df083aSStefano Zampini apply_right = ctx->apply_right; 1885a3df083aSStefano Zampini apply_left = ctx->apply_left; 1886a3df083aSStefano Zampini } 1887a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1888a3df083aSStefano Zampini if (apply_right) { 1889a3df083aSStefano Zampini const PetscScalar *ax; 1890a3df083aSStefano Zampini PetscInt nl,i; 1891a3df083aSStefano Zampini 1892a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1893a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1894a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1895a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1896a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1897a3df083aSStefano Zampini PetscScalar sum,val; 1898a3df083aSStefano Zampini const PetscInt *idxs; 1899a3df083aSStefano Zampini PetscInt nz,j; 1900a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1901a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1902a3df083aSStefano Zampini sum = 0.; 1903a3df083aSStefano Zampini if (ctx->apply_p0) { 1904a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1905a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1906a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1907a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1908a3df083aSStefano Zampini } 1909a3df083aSStefano Zampini } else { 1910a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1911a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1912a3df083aSStefano Zampini } 1913a3df083aSStefano Zampini } 1914a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1915a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1916a3df083aSStefano Zampini } 1917a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1918a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1919a3df083aSStefano Zampini } 1920a3df083aSStefano Zampini if (transpose) { 1921a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1922a3df083aSStefano Zampini } else { 1923a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1924a3df083aSStefano Zampini } 1925a3df083aSStefano Zampini if (reset_x) { 1926a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1927a3df083aSStefano Zampini } 1928a3df083aSStefano Zampini if (apply_left) { 1929a3df083aSStefano Zampini PetscScalar *ay; 1930a3df083aSStefano Zampini PetscInt i; 1931a3df083aSStefano Zampini 1932a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1933a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1934a3df083aSStefano Zampini PetscScalar sum,val; 1935a3df083aSStefano Zampini const PetscInt *idxs; 1936a3df083aSStefano Zampini PetscInt nz,j; 1937a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1938a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1939a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1940a3df083aSStefano Zampini if (ctx->apply_p0) { 1941a3df083aSStefano Zampini sum = 0.; 1942a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1943a3df083aSStefano Zampini sum += ay[idxs[j]]; 1944a3df083aSStefano Zampini ay[idxs[j]] += val; 1945a3df083aSStefano Zampini } 1946a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1947a3df083aSStefano Zampini } else { 1948a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1949a3df083aSStefano Zampini ay[idxs[j]] += val; 1950a3df083aSStefano Zampini } 1951a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1952a3df083aSStefano Zampini } 1953a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1954a3df083aSStefano Zampini } 1955a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1956a3df083aSStefano Zampini } 1957a3df083aSStefano Zampini PetscFunctionReturn(0); 1958a3df083aSStefano Zampini } 1959a3df083aSStefano Zampini 1960a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1961a3df083aSStefano Zampini { 1962a3df083aSStefano Zampini PetscErrorCode ierr; 1963a3df083aSStefano Zampini 1964a3df083aSStefano Zampini PetscFunctionBegin; 1965a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1966a3df083aSStefano Zampini PetscFunctionReturn(0); 1967a3df083aSStefano Zampini } 1968a3df083aSStefano Zampini 1969a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1970a3df083aSStefano Zampini { 1971a3df083aSStefano Zampini PetscErrorCode ierr; 1972a3df083aSStefano Zampini 1973a3df083aSStefano Zampini PetscFunctionBegin; 1974a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1975a3df083aSStefano Zampini PetscFunctionReturn(0); 1976a3df083aSStefano Zampini } 1977a3df083aSStefano Zampini 1978a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1979a3df083aSStefano Zampini { 1980a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1981a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1982a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1983a3df083aSStefano Zampini PetscErrorCode ierr; 1984a3df083aSStefano Zampini 1985a3df083aSStefano Zampini PetscFunctionBegin; 1986a3df083aSStefano Zampini if (!restore) { 19871dd7afcfSStefano Zampini Mat A_IB,A_BI; 1988a3df083aSStefano Zampini PetscScalar *work; 1989b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 1990a3df083aSStefano Zampini 19919a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 19929a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 1993a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 1994a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 1995a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1996a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 1997a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 1998a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 1999a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 2000a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 2001a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 2002a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 2003a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 2004a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 2005059032f7SStefano Zampini if (reuse) { 2006a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 20071dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 2008059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 2009059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 2010059032f7SStefano Zampini PetscInt i; 2011059032f7SStefano Zampini 2012059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 2013059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2014059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2015059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2016059032f7SStefano Zampini } 2017059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 20181dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 2019059032f7SStefano Zampini } 2020a3df083aSStefano Zampini ctx->A = pcis->A_IB; 2021a3df083aSStefano Zampini ctx->work = work; 2022a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 2023a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2024a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2025a3df083aSStefano Zampini pcis->A_IB = A_IB; 2026a3df083aSStefano Zampini 2027a3df083aSStefano Zampini /* A_BI as A_IB^T */ 2028a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 2029a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 2030a3df083aSStefano Zampini pcis->A_BI = A_BI; 2031a3df083aSStefano Zampini } else { 20321dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 20331dd7afcfSStefano Zampini PetscFunctionReturn(0); 20341dd7afcfSStefano Zampini } 2035a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 2036a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 2037a3df083aSStefano Zampini pcis->A_IB = ctx->A; 20381dd7afcfSStefano Zampini ctx->A = NULL; 20391dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 20401dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 20411dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 20421dd7afcfSStefano Zampini if (ctx->free) { 2043059032f7SStefano Zampini PetscInt i; 20441dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 2045059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2046059032f7SStefano Zampini } 2047059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2048059032f7SStefano Zampini } 2049a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 2050a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 2051a3df083aSStefano Zampini } 2052a3df083aSStefano Zampini PetscFunctionReturn(0); 2053a3df083aSStefano Zampini } 2054a3df083aSStefano Zampini 2055a3df083aSStefano Zampini /* used just in bddc debug mode */ 2056a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 2057a3df083aSStefano Zampini { 2058a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2059a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2060a3df083aSStefano Zampini Mat An; 2061a3df083aSStefano Zampini PetscErrorCode ierr; 2062a3df083aSStefano Zampini 2063a3df083aSStefano Zampini PetscFunctionBegin; 2064a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 2065a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 2066a3df083aSStefano Zampini if (is1) { 20677dae84e0SHong Zhang ierr = MatCreateSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 2068a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 2069a3df083aSStefano Zampini } else { 2070a3df083aSStefano Zampini *B = An; 2071a3df083aSStefano Zampini } 2072a3df083aSStefano Zampini PetscFunctionReturn(0); 2073a3df083aSStefano Zampini } 2074a3df083aSStefano Zampini 20751cf9b237SStefano Zampini /* TODO: add reuse flag */ 20761cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 20771cf9b237SStefano Zampini { 20781cf9b237SStefano Zampini Mat Bt; 20791cf9b237SStefano Zampini PetscScalar *a,*bdata; 20801cf9b237SStefano Zampini const PetscInt *ii,*ij; 20811cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 20821cf9b237SStefano Zampini PetscBool flg_row; 20831cf9b237SStefano Zampini PetscErrorCode ierr; 20841cf9b237SStefano Zampini 20851cf9b237SStefano Zampini PetscFunctionBegin; 20861cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 20871cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 20881cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 20891cf9b237SStefano Zampini nnz = n; 20901cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 20911cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 20921cf9b237SStefano Zampini } 20931cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 20941cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 20951cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 20961cf9b237SStefano Zampini nnz = 0; 20971cf9b237SStefano Zampini bii[0] = 0; 20981cf9b237SStefano Zampini for (i=0;i<n;i++) { 20991cf9b237SStefano Zampini PetscInt j; 21001cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 21011cf9b237SStefano Zampini PetscScalar entry = a[j]; 21023272d46bSStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || (n == m && ij[j] == i)) { 21031cf9b237SStefano Zampini bij[nnz] = ij[j]; 21041cf9b237SStefano Zampini bdata[nnz] = entry; 21051cf9b237SStefano Zampini nnz++; 21061cf9b237SStefano Zampini } 21071cf9b237SStefano Zampini } 21081cf9b237SStefano Zampini bii[i+1] = nnz; 21091cf9b237SStefano Zampini } 21101cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 21111cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 21121cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 21131cf9b237SStefano Zampini { 21141cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 21151cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 21161cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 21171cf9b237SStefano Zampini } 21183272d46bSStefano Zampini if (*B == A) { 21193272d46bSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 21203272d46bSStefano Zampini } 21211cf9b237SStefano Zampini *B = Bt; 21221cf9b237SStefano Zampini PetscFunctionReturn(0); 21231cf9b237SStefano Zampini } 21241cf9b237SStefano Zampini 21258361f951SStefano Zampini PetscErrorCode PCBDDCDetectDisconnectedComponents(PC pc, PetscBool filter, PetscInt *ncc, IS* cc[], IS* primalv) 21264f1b2e48SStefano Zampini { 2127c80a6c00SStefano Zampini Mat B = NULL; 2128c80a6c00SStefano Zampini DM dm; 21294f1b2e48SStefano Zampini IS is_dummy,*cc_n; 21304f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 21314f1b2e48SStefano Zampini PCBDDCGraph graph; 2132c80a6c00SStefano Zampini PetscInt *xadj_filtered = NULL,*adjncy_filtered = NULL; 21334f1b2e48SStefano Zampini PetscInt i,n; 21344f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 2135c80a6c00SStefano Zampini PetscBool isplex = PETSC_FALSE; 21364f1b2e48SStefano Zampini PetscErrorCode ierr; 21374f1b2e48SStefano Zampini 21384f1b2e48SStefano Zampini PetscFunctionBegin; 2139a2eca866SStefano Zampini if (ncc) *ncc = 0; 2140a2eca866SStefano Zampini if (cc) *cc = NULL; 2141a2eca866SStefano Zampini if (primalv) *primalv = NULL; 2142c80a6c00SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 2143c80a6c00SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 2144c80a6c00SStefano Zampini if (!dm) { 2145c80a6c00SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 2146c80a6c00SStefano Zampini } 2147c80a6c00SStefano Zampini if (dm) { 2148c80a6c00SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMPLEX,&isplex);CHKERRQ(ierr); 2149c80a6c00SStefano Zampini } 21508361f951SStefano Zampini if (filter) isplex = PETSC_FALSE; 21518361f951SStefano Zampini 2152c80a6c00SStefano Zampini if (isplex) { /* this code has been modified from plexpartition.c */ 2153c80a6c00SStefano Zampini PetscInt p, pStart, pEnd, a, adjSize, idx, size, nroots; 2154c80a6c00SStefano Zampini PetscInt *adj = NULL; 2155c80a6c00SStefano Zampini IS cellNumbering; 2156c80a6c00SStefano Zampini const PetscInt *cellNum; 2157c80a6c00SStefano Zampini PetscBool useCone, useClosure; 2158c80a6c00SStefano Zampini PetscSection section; 2159c80a6c00SStefano Zampini PetscSegBuffer adjBuffer; 2160c80a6c00SStefano Zampini PetscSF sfPoint; 2161c80a6c00SStefano Zampini PetscErrorCode ierr; 2162c80a6c00SStefano Zampini 2163c80a6c00SStefano Zampini PetscFunctionBegin; 2164c80a6c00SStefano Zampini ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 2165c80a6c00SStefano Zampini ierr = DMGetPointSF(dm, &sfPoint);CHKERRQ(ierr); 2166c80a6c00SStefano Zampini ierr = PetscSFGetGraph(sfPoint, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 2167c80a6c00SStefano Zampini /* Build adjacency graph via a section/segbuffer */ 2168c80a6c00SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), §ion);CHKERRQ(ierr); 2169c80a6c00SStefano Zampini ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 2170c80a6c00SStefano Zampini ierr = PetscSegBufferCreate(sizeof(PetscInt),1000,&adjBuffer);CHKERRQ(ierr); 2171c80a6c00SStefano Zampini /* Always use FVM adjacency to create partitioner graph */ 2172c80a6c00SStefano Zampini ierr = DMPlexGetAdjacencyUseCone(dm, &useCone);CHKERRQ(ierr); 2173c80a6c00SStefano Zampini ierr = DMPlexGetAdjacencyUseClosure(dm, &useClosure);CHKERRQ(ierr); 2174c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseCone(dm, PETSC_TRUE);CHKERRQ(ierr); 2175c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseClosure(dm, PETSC_FALSE);CHKERRQ(ierr); 2176956e2312SStefano Zampini ierr = DMPlexGetCellNumbering(dm, &cellNumbering);CHKERRQ(ierr); 2177c80a6c00SStefano Zampini ierr = ISGetIndices(cellNumbering, &cellNum);CHKERRQ(ierr); 2178c80a6c00SStefano Zampini for (n = 0, p = pStart; p < pEnd; p++) { 2179c80a6c00SStefano Zampini /* Skip non-owned cells in parallel (ParMetis expects no overlap) */ 2180c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2181c80a6c00SStefano Zampini adjSize = PETSC_DETERMINE; 2182c80a6c00SStefano Zampini ierr = DMPlexGetAdjacency(dm, p, &adjSize, &adj);CHKERRQ(ierr); 2183c80a6c00SStefano Zampini for (a = 0; a < adjSize; ++a) { 2184c80a6c00SStefano Zampini const PetscInt point = adj[a]; 21855cef3d0dSStefano Zampini if (pStart <= point && point < pEnd) { 2186c80a6c00SStefano Zampini PetscInt *PETSC_RESTRICT pBuf; 2187c80a6c00SStefano Zampini ierr = PetscSectionAddDof(section, p, 1);CHKERRQ(ierr); 2188c80a6c00SStefano Zampini ierr = PetscSegBufferGetInts(adjBuffer, 1, &pBuf);CHKERRQ(ierr); 2189c80a6c00SStefano Zampini *pBuf = point; 2190c80a6c00SStefano Zampini } 2191c80a6c00SStefano Zampini } 2192c80a6c00SStefano Zampini n++; 2193c80a6c00SStefano Zampini } 2194c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseCone(dm, useCone);CHKERRQ(ierr); 2195c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseClosure(dm, useClosure);CHKERRQ(ierr); 2196c80a6c00SStefano Zampini /* Derive CSR graph from section/segbuffer */ 2197c80a6c00SStefano Zampini ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 2198c80a6c00SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 2199c80a6c00SStefano Zampini ierr = PetscMalloc1(n+1, &xadj);CHKERRQ(ierr); 2200c80a6c00SStefano Zampini for (idx = 0, p = pStart; p < pEnd; p++) { 2201c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2202c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(section, p, &(xadj[idx++]));CHKERRQ(ierr); 2203c80a6c00SStefano Zampini } 2204c80a6c00SStefano Zampini xadj[n] = size; 2205c80a6c00SStefano Zampini ierr = PetscSegBufferExtractAlloc(adjBuffer, &adjncy);CHKERRQ(ierr); 2206c80a6c00SStefano Zampini /* Clean up */ 2207c80a6c00SStefano Zampini ierr = PetscSegBufferDestroy(&adjBuffer);CHKERRQ(ierr); 2208c80a6c00SStefano Zampini ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 2209c80a6c00SStefano Zampini ierr = PetscFree(adj);CHKERRQ(ierr); 2210c80a6c00SStefano Zampini graph->xadj = xadj; 2211c80a6c00SStefano Zampini graph->adjncy = adjncy; 2212c80a6c00SStefano Zampini } else { 2213c80a6c00SStefano Zampini Mat A; 22148361f951SStefano Zampini PetscBool isseqaij, flg_row; 2215c80a6c00SStefano Zampini 2216c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 221763c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 2218a2eca866SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 221963c961adSStefano Zampini PetscFunctionReturn(0); 222063c961adSStefano Zampini } 22214f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 22224f1b2e48SStefano Zampini if (!isseqaij && filter) { 22231cf9b237SStefano Zampini PetscBool isseqdense; 22241cf9b237SStefano Zampini 22251cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 22261cf9b237SStefano Zampini if (!isseqdense) { 22274f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 22281cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 22291cf9b237SStefano Zampini PetscScalar *array; 22301cf9b237SStefano Zampini PetscReal chop=1.e-6; 22311cf9b237SStefano Zampini 22321cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 22331cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 22341cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 22351cf9b237SStefano Zampini for (i=0;i<n;i++) { 22361cf9b237SStefano Zampini PetscInt j; 22371cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 22381cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 22391cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 22401cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 22411cf9b237SStefano Zampini } 22421cf9b237SStefano Zampini } 22431cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 22449d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 22451cf9b237SStefano Zampini } 22464f1b2e48SStefano Zampini } else { 2247c80a6c00SStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22484f1b2e48SStefano Zampini B = A; 22494f1b2e48SStefano Zampini } 22504f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 22514f1b2e48SStefano Zampini 22524f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 22534f1b2e48SStefano Zampini if (filter) { 22544f1b2e48SStefano Zampini PetscScalar *data; 22554f1b2e48SStefano Zampini PetscInt j,cum; 22564f1b2e48SStefano Zampini 22574f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 22584f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 22594f1b2e48SStefano Zampini cum = 0; 22604f1b2e48SStefano Zampini for (i=0;i<n;i++) { 22614f1b2e48SStefano Zampini PetscInt t; 22624f1b2e48SStefano Zampini 22634f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 22644f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 22654f1b2e48SStefano Zampini continue; 22664f1b2e48SStefano Zampini } 22674f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 22684f1b2e48SStefano Zampini } 22694f1b2e48SStefano Zampini t = xadj_filtered[i]; 22704f1b2e48SStefano Zampini xadj_filtered[i] = cum; 22714f1b2e48SStefano Zampini cum += t; 22724f1b2e48SStefano Zampini } 22734f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 22744f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 22754f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 22764f1b2e48SStefano Zampini } else { 22774f1b2e48SStefano Zampini graph->xadj = xadj; 22784f1b2e48SStefano Zampini graph->adjncy = adjncy; 22794f1b2e48SStefano Zampini } 2280c80a6c00SStefano Zampini } 2281c80a6c00SStefano Zampini /* compute local connected components using PCBDDCGraph */ 2282c80a6c00SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 2283c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 2284c80a6c00SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2285c80a6c00SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 2286c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 22874f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 22884f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 2289c80a6c00SStefano Zampini 22904f1b2e48SStefano Zampini /* partial clean up */ 22914f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 2292c80a6c00SStefano Zampini if (B) { 2293c80a6c00SStefano Zampini PetscBool flg_row; 22944f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 22954f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 22964f1b2e48SStefano Zampini } 2297c80a6c00SStefano Zampini if (isplex) { 2298c80a6c00SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 2299c80a6c00SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 2300c80a6c00SStefano Zampini } 23014f1b2e48SStefano Zampini 23024f1b2e48SStefano Zampini /* get back data */ 2303c80a6c00SStefano Zampini if (isplex) { 2304c80a6c00SStefano Zampini if (ncc) *ncc = graph->ncc; 2305c80a6c00SStefano Zampini if (cc || primalv) { 2306c80a6c00SStefano Zampini Mat A; 2307c80a6c00SStefano Zampini PetscBT btv,btvt; 2308c80a6c00SStefano Zampini PetscSection subSection; 2309c80a6c00SStefano Zampini PetscInt *ids,cum,cump,*cids,*pids; 2310c80a6c00SStefano Zampini 2311c80a6c00SStefano Zampini ierr = DMPlexGetSubdomainSection(dm,&subSection);CHKERRQ(ierr); 2312c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 2313c80a6c00SStefano Zampini ierr = PetscMalloc3(A->rmap->n,&ids,graph->ncc+1,&cids,A->rmap->n,&pids);CHKERRQ(ierr); 2314c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btv);CHKERRQ(ierr); 2315c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btvt);CHKERRQ(ierr); 2316c80a6c00SStefano Zampini 2317c80a6c00SStefano Zampini cids[0] = 0; 2318c80a6c00SStefano Zampini for (i = 0, cump = 0, cum = 0; i < graph->ncc; i++) { 2319c80a6c00SStefano Zampini PetscInt j; 2320c80a6c00SStefano Zampini 2321c80a6c00SStefano Zampini ierr = PetscBTMemzero(A->rmap->n,btvt);CHKERRQ(ierr); 2322c80a6c00SStefano Zampini for (j = graph->cptr[i]; j < graph->cptr[i+1]; j++) { 2323c80a6c00SStefano Zampini PetscInt k, size, *closure = NULL, cell = graph->queue[j]; 2324c80a6c00SStefano Zampini 2325c80a6c00SStefano Zampini ierr = DMPlexGetTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2326c80a6c00SStefano Zampini for (k = 0; k < 2*size; k += 2) { 2327c80a6c00SStefano Zampini PetscInt s, p = closure[k], off, dof, cdof; 2328c80a6c00SStefano Zampini 2329c80a6c00SStefano Zampini ierr = PetscSectionGetConstraintDof(subSection, p, &cdof);CHKERRQ(ierr); 2330c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(subSection,p,&off);CHKERRQ(ierr); 2331c80a6c00SStefano Zampini ierr = PetscSectionGetDof(subSection,p,&dof);CHKERRQ(ierr); 2332c80a6c00SStefano Zampini for (s = 0; s < dof-cdof; s++) { 2333c80a6c00SStefano Zampini if (PetscBTLookupSet(btvt,off+s)) continue; 2334c80a6c00SStefano Zampini if (!PetscBTLookup(btv,off+s)) { 2335c80a6c00SStefano Zampini ids[cum++] = off+s; 2336c80a6c00SStefano Zampini } else { /* cross-vertex */ 2337c80a6c00SStefano Zampini pids[cump++] = off+s; 2338c80a6c00SStefano Zampini } 2339c80a6c00SStefano Zampini } 2340c80a6c00SStefano Zampini } 2341c80a6c00SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2342c80a6c00SStefano Zampini } 2343c80a6c00SStefano Zampini cids[i+1] = cum; 2344c80a6c00SStefano Zampini /* mark dofs as already assigned */ 2345c80a6c00SStefano Zampini for (j = cids[i]; j < cids[i+1]; j++) { 2346c80a6c00SStefano Zampini ierr = PetscBTSet(btv,ids[j]);CHKERRQ(ierr); 2347c80a6c00SStefano Zampini } 2348c80a6c00SStefano Zampini } 2349c80a6c00SStefano Zampini if (cc) { 2350c80a6c00SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 2351c80a6c00SStefano Zampini for (i = 0; i < graph->ncc; i++) { 2352c80a6c00SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cids[i+1]-cids[i],ids+cids[i],PETSC_COPY_VALUES,&cc_n[i]);CHKERRQ(ierr); 2353c80a6c00SStefano Zampini } 2354c80a6c00SStefano Zampini *cc = cc_n; 2355c80a6c00SStefano Zampini } 2356c80a6c00SStefano Zampini if (primalv) { 2357c80a6c00SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),cump,pids,PETSC_COPY_VALUES,primalv);CHKERRQ(ierr); 2358c80a6c00SStefano Zampini } 2359c80a6c00SStefano Zampini ierr = PetscFree3(ids,cids,pids);CHKERRQ(ierr); 2360c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 2361c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btvt);CHKERRQ(ierr); 2362c80a6c00SStefano Zampini } 2363c80a6c00SStefano Zampini } else { 23641cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 23651cf9b237SStefano Zampini if (cc) { 23664f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 23674f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 23684f1b2e48SStefano 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); 23694f1b2e48SStefano Zampini } 23704f1b2e48SStefano Zampini *cc = cc_n; 23711cf9b237SStefano Zampini } 2372c80a6c00SStefano Zampini } 23734f1b2e48SStefano Zampini /* clean up graph */ 23744f1b2e48SStefano Zampini graph->xadj = 0; 23754f1b2e48SStefano Zampini graph->adjncy = 0; 23764f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 23774f1b2e48SStefano Zampini PetscFunctionReturn(0); 23784f1b2e48SStefano Zampini } 23794f1b2e48SStefano Zampini 23805408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 23815408967cSStefano Zampini { 23825408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 23835408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2384dee84bffSStefano Zampini IS dirIS = NULL; 23854f1b2e48SStefano Zampini PetscInt i; 23865408967cSStefano Zampini PetscErrorCode ierr; 23875408967cSStefano Zampini 23885408967cSStefano Zampini PetscFunctionBegin; 2389dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 23905408967cSStefano Zampini if (zerodiag) { 23915408967cSStefano Zampini Mat A; 23925408967cSStefano Zampini Vec vec3_N; 23935408967cSStefano Zampini PetscScalar *vals; 23945408967cSStefano Zampini const PetscInt *idxs; 2395d12d3064SStefano Zampini PetscInt nz,*count; 23965408967cSStefano Zampini 23975408967cSStefano Zampini /* p0 */ 23985408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 23995408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 24005408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 24015408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 24024f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 24035408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24045408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 24055408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 24065408967cSStefano Zampini /* v_I */ 24075408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 24085408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 24095408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24105408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 24115408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 24125408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 24135408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24145408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 24155408967cSStefano Zampini if (dirIS) { 24165408967cSStefano Zampini PetscInt n; 24175408967cSStefano Zampini 24185408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 24195408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 24205408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 24215408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24225408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 24235408967cSStefano Zampini } 24245408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 24255408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 24265408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 24275408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2428669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 24295408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 24305408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 24319a962809SStefano 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])); 24325408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 24335408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2434d12d3064SStefano Zampini 2435d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 2436d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 2437d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2438d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 2439d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2440d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 24416080607fSStefano 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]); 2442d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2443d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 24445408967cSStefano Zampini } 2445dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 24465408967cSStefano Zampini 24475408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 24485408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 24494f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 24505408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 24514f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 24525408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2453f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2454f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 24556080607fSStefano Zampini if (val != -PetscGlobalRank-i) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error testing PCBDDCBenignGetOrSetP0! Found %g at %D instead of %g",PetscRealPart(pcbddc->benign_p0[i]),i,-PetscGlobalRank-i); 2456f2a566d8SStefano Zampini } 24575408967cSStefano Zampini PetscFunctionReturn(0); 24585408967cSStefano Zampini } 24595408967cSStefano Zampini 2460339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 2461339f8db1SStefano Zampini { 2462339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 24634edc6404Sstefano_zampini IS pressures,zerodiag,zerodiag_save,*zerodiag_subs; 2464b0f5fe93SStefano Zampini PetscInt nz,n; 24654edc6404Sstefano_zampini PetscInt *interior_dofs,n_interior_dofs,nneu; 24664edc6404Sstefano_zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag,checkb; 2467339f8db1SStefano Zampini PetscErrorCode ierr; 2468339f8db1SStefano Zampini 2469339f8db1SStefano Zampini PetscFunctionBegin; 24709f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 24719f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 2472a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 2473a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 2474a3df083aSStefano Zampini } 2475a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2476a3df083aSStefano Zampini pcbddc->benign_n = 0; 247728b8efb1Sstefano_zampini 247828b8efb1Sstefano_zampini /* if a local info on dofs is present, uses the last field for "pressures" (or fid by command line) 24794f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 24804f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 24814f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 24821ae86dd6SStefano Zampini since the local Schur complements are already SPD 24834f1b2e48SStefano Zampini */ 24844f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 24854f1b2e48SStefano Zampini have_null = PETSC_TRUE; 248640fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 24877fbe2174Sstefano_zampini IS iP = NULL; 24884f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 24894f1b2e48SStefano Zampini 249028b8efb1Sstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC benign options","PC");CHKERRQ(ierr); 249128b8efb1Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_pressure_field","Field id for pressures",NULL,p,&p,NULL);CHKERRQ(ierr); 249228b8efb1Sstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 249328b8efb1Sstefano_zampini if (p < 0 || p > pcbddc->n_ISForDofsLocal-1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Invalid field id for pressures %D",p); 24944f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 24954f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 24964f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 24974f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 2498ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 24997fbe2174Sstefano_zampini /* remove zeroed out pressures if we are setting up a BDDC solver for a saddle-point FETI-DP */ 25007fbe2174Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP",(PetscObject*)&iP);CHKERRQ(ierr); 25017fbe2174Sstefano_zampini if (iP) { 25027fbe2174Sstefano_zampini IS newpressures; 25037fbe2174Sstefano_zampini 25047fbe2174Sstefano_zampini ierr = ISDifference(pressures,iP,&newpressures);CHKERRQ(ierr); 25057fbe2174Sstefano_zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 25067fbe2174Sstefano_zampini pressures = newpressures; 25077fbe2174Sstefano_zampini } 250840fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 250940fa8d13SStefano Zampini if (!sorted) { 251040fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 251140fa8d13SStefano Zampini } 251240fa8d13SStefano Zampini } else { 251340fa8d13SStefano Zampini pressures = NULL; 251440fa8d13SStefano Zampini } 251597d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 251697d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 251727b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 251897d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 2519339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 2520339f8db1SStefano Zampini if (!sorted) { 2521339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 2522339f8db1SStefano Zampini } 25234edc6404Sstefano_zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 25244edc6404Sstefano_zampini zerodiag_save = zerodiag; 2525339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 25264f1b2e48SStefano Zampini if (!nz) { 25274f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 25284f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 252940fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 253040fa8d13SStefano Zampini } 25314f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 25324f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 25334f1b2e48SStefano Zampini zerodiag_subs = NULL; 25344f1b2e48SStefano Zampini pcbddc->benign_n = 0; 25351f4df5f7SStefano Zampini n_interior_dofs = 0; 25361f4df5f7SStefano Zampini interior_dofs = NULL; 25374edc6404Sstefano_zampini nneu = 0; 25384edc6404Sstefano_zampini if (pcbddc->NeumannBoundariesLocal) { 25394edc6404Sstefano_zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nneu);CHKERRQ(ierr); 25404edc6404Sstefano_zampini } 25413369cb78Sstefano_zampini checkb = (PetscBool)(!pcbddc->NeumannBoundariesLocal || pcbddc->current_level); 25424edc6404Sstefano_zampini if (checkb) { /* need to compute interior nodes */ 25431f4df5f7SStefano Zampini PetscInt n,i,j; 25441f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 25451f4df5f7SStefano Zampini PetscInt *iwork; 25461f4df5f7SStefano Zampini 25471f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 25481f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 25491f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 25501f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 255190648384SStefano Zampini for (i=1;i<n_neigh;i++) 25521f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 25531f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 25541f4df5f7SStefano Zampini for (i=0;i<n;i++) 25551f4df5f7SStefano Zampini if (!iwork[i]) 25561f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 25571f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 25581f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 25591f4df5f7SStefano Zampini } 25604f1b2e48SStefano Zampini if (has_null_pressures) { 25614f1b2e48SStefano Zampini IS *subs; 25624edc6404Sstefano_zampini PetscInt nsubs,i,j,nl; 25631f4df5f7SStefano Zampini const PetscInt *idxs; 25641f4df5f7SStefano Zampini PetscScalar *array; 25651f4df5f7SStefano Zampini Vec *work; 25661f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 25674f1b2e48SStefano Zampini 25684f1b2e48SStefano Zampini subs = pcbddc->local_subs; 25694f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 25701f4df5f7SStefano 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) */ 25714edc6404Sstefano_zampini if (checkb) { 25721f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 25731f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 25741f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 25751f4df5f7SStefano Zampini /* work[0] = 1_p */ 25761f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 25771f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 25781f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 25791f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 25801f4df5f7SStefano Zampini /* work[0] = 1_v */ 25811f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 25821f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 25831f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 25841f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 25851f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 25861f4df5f7SStefano Zampini } 25874f1b2e48SStefano Zampini if (nsubs > 1) { 25884f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 25894f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 25904f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 25914f1b2e48SStefano Zampini IS t_zerodiag_subs; 25924f1b2e48SStefano Zampini PetscInt nl; 25934f1b2e48SStefano Zampini 25944f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 25954f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 25964f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 25974f1b2e48SStefano Zampini if (nl) { 25984f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 25994f1b2e48SStefano Zampini 26004edc6404Sstefano_zampini if (checkb) { 26011f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 26021f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 26031f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 26041f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 26051f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 26061f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 26071f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 26081f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 26091f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 26101f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 26111f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 26121f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 26131f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 26141f4df5f7SStefano Zampini valid = PETSC_FALSE; 26151f4df5f7SStefano Zampini break; 26161f4df5f7SStefano Zampini } 26171f4df5f7SStefano Zampini } 26181f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 26191f4df5f7SStefano Zampini } 26206632bad2Sstefano_zampini if (valid && nneu) { 26216632bad2Sstefano_zampini const PetscInt *idxs; 26221f4df5f7SStefano Zampini PetscInt nzb; 26231f4df5f7SStefano Zampini 26246632bad2Sstefano_zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 26256632bad2Sstefano_zampini ierr = ISGlobalToLocalMappingApply(l2g,IS_GTOLM_DROP,nneu,idxs,&nzb,NULL);CHKERRQ(ierr); 26266632bad2Sstefano_zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 26271f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 26281f4df5f7SStefano Zampini } 26291f4df5f7SStefano Zampini if (valid && pressures) { 26304f1b2e48SStefano Zampini IS t_pressure_subs; 26314f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 26324f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 26334f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 26344f1b2e48SStefano Zampini } 26354f1b2e48SStefano Zampini if (valid) { 26364f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 26374f1b2e48SStefano Zampini pcbddc->benign_n++; 26384f1b2e48SStefano Zampini } else { 26394f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 26404f1b2e48SStefano Zampini } 26414f1b2e48SStefano Zampini } 26424f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 26434f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 26444f1b2e48SStefano Zampini } 26454f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 26464f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 26471f4df5f7SStefano Zampini 26486632bad2Sstefano_zampini if (nneu) valid = PETSC_FALSE; 26491f4df5f7SStefano Zampini if (valid && pressures) { 26504f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 26514f1b2e48SStefano Zampini } 26524edc6404Sstefano_zampini if (valid && checkb) { 26531f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 26541f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 26551f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 26561f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 26571f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 26581f4df5f7SStefano Zampini valid = PETSC_FALSE; 26591f4df5f7SStefano Zampini break; 26601f4df5f7SStefano Zampini } 26611f4df5f7SStefano Zampini } 26621f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 26631f4df5f7SStefano Zampini } 26644f1b2e48SStefano Zampini if (valid) { 26654f1b2e48SStefano Zampini pcbddc->benign_n = 1; 2666ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 26674f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 26684f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 26694f1b2e48SStefano Zampini } 26704f1b2e48SStefano Zampini } 26714edc6404Sstefano_zampini if (checkb) { 26721f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 26734f1b2e48SStefano Zampini } 26741f4df5f7SStefano Zampini } 26751f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 26764f1b2e48SStefano Zampini 26774f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2678b9b0e38cSStefano Zampini PetscInt n; 2679b9b0e38cSStefano Zampini 26804f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 26814f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2682b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 2683b9b0e38cSStefano Zampini if (n) { 26844f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 26854f1b2e48SStefano Zampini have_null = PETSC_FALSE; 26864f1b2e48SStefano Zampini } 2687b9b0e38cSStefano Zampini } 26884f1b2e48SStefano Zampini 26894f1b2e48SStefano Zampini /* final check for null pressures */ 26904f1b2e48SStefano Zampini if (zerodiag && pressures) { 26914f1b2e48SStefano Zampini PetscInt nz,np; 26924f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 26934f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 26944f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 26954f1b2e48SStefano Zampini } 26964f1b2e48SStefano Zampini 26974f1b2e48SStefano Zampini if (recompute_zerodiag) { 26984f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 26994f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 27004f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 27014f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 27024f1b2e48SStefano Zampini } else { 27034f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 27044f1b2e48SStefano Zampini 27054f1b2e48SStefano Zampini nzn = 0; 27064f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 27074f1b2e48SStefano Zampini PetscInt ns; 27084f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 27094f1b2e48SStefano Zampini nzn += ns; 27104f1b2e48SStefano Zampini } 27114f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 27124f1b2e48SStefano Zampini nzn = 0; 27134f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 27144f1b2e48SStefano Zampini PetscInt ns,*idxs; 27154f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 27164f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 27174f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 27184f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 27194f1b2e48SStefano Zampini nzn += ns; 27204f1b2e48SStefano Zampini } 27214f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 27224f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 27234f1b2e48SStefano Zampini } 27244f1b2e48SStefano Zampini have_null = PETSC_FALSE; 27254f1b2e48SStefano Zampini } 27264f1b2e48SStefano Zampini 2727669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2728a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2729a198735bSStefano Zampini Mat A,loc_divudotp; 2730a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2731a198735bSStefano Zampini IS row,col,isused = NULL; 2732a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2733a198735bSStefano Zampini 27341f4df5f7SStefano Zampini if (pressures) { 27351f4df5f7SStefano Zampini isused = pressures; 27361f4df5f7SStefano Zampini } else { 27374edc6404Sstefano_zampini isused = zerodiag_save; 27381f4df5f7SStefano Zampini } 2739a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2740669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 27411ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 27421ae86dd6SStefano 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"); 2743a198735bSStefano Zampini n_isused = 0; 2744a198735bSStefano Zampini if (isused) { 2745a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2746a198735bSStefano Zampini } 2747a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2748a198735bSStefano Zampini st = st-n_isused; 27491ae86dd6SStefano Zampini if (n) { 2750a198735bSStefano Zampini const PetscInt *gidxs; 2751a198735bSStefano Zampini 27527dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2753a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2754a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2755a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2756a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2757a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 27581ae86dd6SStefano Zampini } else { 2759a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2760a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2761a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2762a198735bSStefano Zampini } 2763a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2764a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2765a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2766a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2767a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2768a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2769a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2770a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2771a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2772a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2773a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2774a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2775a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2776a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 27771ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27781ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27791ae86dd6SStefano Zampini } 27804edc6404Sstefano_zampini ierr = ISDestroy(&zerodiag_save);CHKERRQ(ierr); 2781b3afcdbeSStefano Zampini 2782b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 27834f1b2e48SStefano Zampini if (has_null_pressures) { 27844f1b2e48SStefano Zampini IS zerodiagc; 27854f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 27864f1b2e48SStefano Zampini PetscInt i,s,*nnz; 27874f1b2e48SStefano Zampini 27884f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2789339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 2790339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 2791339f8db1SStefano Zampini /* local change of basis for pressures */ 2792339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 279397d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2794339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2795339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2796339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 27974f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 27984f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 27994f1b2e48SStefano Zampini PetscInt nzs,j; 28004f1b2e48SStefano Zampini 28014f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 28024f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 28034f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 28044f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 28054f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 28064f1b2e48SStefano Zampini } 2807339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2808e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->benign_change,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 2809339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2810339f8db1SStefano Zampini /* set identity on velocities */ 2811339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 2812339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 2813339f8db1SStefano Zampini } 28144f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 28154f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 28169f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 28174f1b2e48SStefano 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); 2818339f8db1SStefano Zampini /* set change on pressures */ 28194f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 28204f1b2e48SStefano Zampini PetscScalar *array; 28214f1b2e48SStefano Zampini PetscInt nzs; 28224f1b2e48SStefano Zampini 28234f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 28244f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 28254f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2826339f8db1SStefano Zampini PetscScalar vals[2]; 2827339f8db1SStefano Zampini PetscInt cols[2]; 2828339f8db1SStefano Zampini 2829339f8db1SStefano Zampini cols[0] = idxs[i]; 28304f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2831339f8db1SStefano Zampini vals[0] = 1.; 2832b0f5fe93SStefano Zampini vals[1] = 1.; 28334f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2834339f8db1SStefano Zampini } 28354f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 28364f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 28374f1b2e48SStefano Zampini array[nzs-1] = 1.; 28384f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 28394f1b2e48SStefano Zampini /* store local idxs for p0 */ 28404f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 28414f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2842339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 28434f1b2e48SStefano Zampini } 2844339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2845339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2846a3df083aSStefano Zampini /* project if needed */ 2847a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 28481dd7afcfSStefano Zampini Mat M; 28491dd7afcfSStefano Zampini 28501dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2851339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 28521dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 28531dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2854a3df083aSStefano Zampini } 28554f1b2e48SStefano Zampini /* store global idxs for p0 */ 28564f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2857339f8db1SStefano Zampini } 2858ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 28594f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 2860b0f5fe93SStefano Zampini 2861b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 2862b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 286327b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 2864c69e9cc1SStefano Zampini have_null = (PetscBool)(!!pcbddc->benign_n); 286527b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2866339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2867339f8db1SStefano Zampini PetscFunctionReturn(0); 2868339f8db1SStefano Zampini } 2869339f8db1SStefano Zampini 2870015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2871efc2fbd9SStefano Zampini { 2872efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2873de9d7bd0SStefano Zampini PetscScalar *array; 2874efc2fbd9SStefano Zampini PetscErrorCode ierr; 2875efc2fbd9SStefano Zampini 2876efc2fbd9SStefano Zampini PetscFunctionBegin; 2877efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 2878efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 28794f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2880efc2fbd9SStefano Zampini } 2881de9d7bd0SStefano Zampini if (get) { 2882efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 28834f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 28844f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 2885efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 2886de9d7bd0SStefano Zampini } else { 2887de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 2888de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2889de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2890de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 2891efc2fbd9SStefano Zampini } 2892efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2893efc2fbd9SStefano Zampini } 2894efc2fbd9SStefano Zampini 2895c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 2896c263805aSStefano Zampini { 2897c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2898c263805aSStefano Zampini PetscErrorCode ierr; 2899c263805aSStefano Zampini 2900c263805aSStefano Zampini PetscFunctionBegin; 2901c263805aSStefano Zampini /* TODO: add error checking 2902c263805aSStefano Zampini - avoid nested pop (or push) calls. 2903c263805aSStefano Zampini - cannot push before pop. 29041c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2905c263805aSStefano Zampini */ 29064f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2907efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2908efc2fbd9SStefano Zampini } 2909c263805aSStefano Zampini if (pop) { 2910a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 29114f1b2e48SStefano Zampini IS is_p0; 29124f1b2e48SStefano Zampini MatReuse reuse; 2913c263805aSStefano Zampini 2914c263805aSStefano Zampini /* extract B_0 */ 29154f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 29164f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 29174f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 29184f1b2e48SStefano Zampini } 29194f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 29207dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2921c263805aSStefano Zampini /* remove rows and cols from local problem */ 2922c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 292397d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 29244f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 29254f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2926a3df083aSStefano Zampini } else { 2927a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2928a3df083aSStefano Zampini PetscScalar *vals; 2929a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2930a3df083aSStefano Zampini 2931a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2932a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2933a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 29340b5adadeSStefano Zampini PetscInt *nnz; 2935a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2936a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2937a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2938331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2939331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2940331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2941331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2942331e053bSStefano Zampini } 2943331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2944e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->benign_B0,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 2945331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2946331e053bSStefano Zampini } 2947a3df083aSStefano Zampini 2948a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2949a3df083aSStefano Zampini PetscScalar *array; 2950a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2951a3df083aSStefano Zampini 2952a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2953a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2954a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2955a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2956a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2957a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2958a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2959a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2960a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2961a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2962a3df083aSStefano Zampini cum = 0; 2963a3df083aSStefano Zampini for (j=0;j<n;j++) { 296422db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2965a3df083aSStefano Zampini vals[cum] = array[j]; 2966a3df083aSStefano Zampini idxs_ins[cum] = j; 2967a3df083aSStefano Zampini cum++; 2968a3df083aSStefano Zampini } 2969a3df083aSStefano Zampini } 2970a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2971a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2972a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2973a3df083aSStefano Zampini } 2974a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2975a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2976a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2977a3df083aSStefano Zampini } 2978c263805aSStefano Zampini } else { /* push */ 2979a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 29804f1b2e48SStefano Zampini PetscInt i; 29814f1b2e48SStefano Zampini 29824f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 29834f1b2e48SStefano Zampini PetscScalar *B0_vals; 29844f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 29854f1b2e48SStefano Zampini 29864f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 29874f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 29887b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 29894f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 29904f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 29914f1b2e48SStefano Zampini } 2992c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2993c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 29946080607fSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!"); 2995c263805aSStefano Zampini } 2996c263805aSStefano Zampini PetscFunctionReturn(0); 2997c263805aSStefano Zampini } 2998c263805aSStefano Zampini 299908122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 3000b1b3d7a2SStefano Zampini { 3001b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 300208122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 300308122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 300408122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 300508122e43SStefano Zampini PetscScalar *work,lwork; 300608122e43SStefano Zampini PetscScalar *St,*S,*eigv; 300708122e43SStefano Zampini PetscScalar *Sarray,*Starray; 3008bd2a564bSStefano Zampini PetscReal *eigs,thresh,lthresh,uthresh; 30091b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 3010f6f667cfSStefano Zampini PetscBool allocated_S_St; 301108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 301208122e43SStefano Zampini PetscReal *rwork; 301308122e43SStefano Zampini #endif 3014b1b3d7a2SStefano Zampini PetscErrorCode ierr; 3015b1b3d7a2SStefano Zampini 3016b1b3d7a2SStefano Zampini PetscFunctionBegin; 3017b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 3018af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 3019bd2a564bSStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_symmetric)) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adaptive selection not yet implemented for this matrix pencil (herm %d, symm %d, posdef %d)",sub_schurs->is_hermitian,sub_schurs->is_symmetric,sub_schurs->is_posdef); 302043371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_AdaptiveSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 302106a4e24aSStefano Zampini 3022fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3023fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3024fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3025fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 30261575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3027fd14bc51SStefano Zampini } 3028fd14bc51SStefano Zampini 3029e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 30306080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d cc %D (%d,%d).\n",PetscGlobalRank,sub_schurs->n_subs,sub_schurs->is_hermitian,sub_schurs->is_posdef);CHKERRQ(ierr); 3031e496cd5dSStefano Zampini } 3032e496cd5dSStefano Zampini 303308122e43SStefano Zampini /* max size of subsets */ 303408122e43SStefano Zampini mss = 0; 303508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 303608122e43SStefano Zampini PetscInt subset_size; 3037862806e4SStefano Zampini 303808122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 303908122e43SStefano Zampini mss = PetscMax(mss,subset_size); 304008122e43SStefano Zampini } 304108122e43SStefano Zampini 304208122e43SStefano Zampini /* min/max and threshold */ 304308122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 3044f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 304508122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 3046f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 3047bd2a564bSStefano Zampini if (nmin || !sub_schurs->is_posdef) { /* XXX */ 3048f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 3049f6f667cfSStefano Zampini } 305008122e43SStefano Zampini 305108122e43SStefano Zampini /* allocate lapack workspace */ 305208122e43SStefano Zampini cum = cum2 = 0; 305308122e43SStefano Zampini maxneigs = 0; 305408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 305508122e43SStefano Zampini PetscInt n,subset_size; 3056f6f667cfSStefano Zampini 305708122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 305808122e43SStefano Zampini n = PetscMin(subset_size,nmax); 30599162d606SStefano Zampini cum += subset_size; 30609162d606SStefano Zampini cum2 += subset_size*n; 306108122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 306208122e43SStefano Zampini } 306308122e43SStefano Zampini if (mss) { 3064bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 306508122e43SStefano Zampini PetscBLASInt B_itype = 1; 306608122e43SStefano Zampini PetscBLASInt B_N = mss; 30674c6709b3SStefano Zampini PetscReal zero = 0.0; 30684c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 306908122e43SStefano Zampini 307008122e43SStefano Zampini B_lwork = -1; 307108122e43SStefano Zampini S = NULL; 307208122e43SStefano Zampini St = NULL; 3073a58a30b4SStefano Zampini eigs = NULL; 3074a58a30b4SStefano Zampini eigv = NULL; 3075a58a30b4SStefano Zampini B_iwork = NULL; 3076a58a30b4SStefano Zampini B_ifail = NULL; 3077d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3078d1710679SStefano Zampini rwork = NULL; 3079d1710679SStefano Zampini #endif 30808bec7fa6SStefano Zampini thresh = 1.0; 308108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 308208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 308308122e43SStefano 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)); 308408122e43SStefano Zampini #else 308508122e43SStefano 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)); 308608122e43SStefano Zampini #endif 308708122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 308808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3089bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 309008122e43SStefano Zampini } else { 309108122e43SStefano Zampini lwork = 0; 309208122e43SStefano Zampini } 309308122e43SStefano Zampini 309408122e43SStefano Zampini nv = 0; 3095d62866d3SStefano 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) */ 3096d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 309708122e43SStefano Zampini } 30984c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 3099f6f667cfSStefano Zampini if (allocated_S_St) { 3100f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 3101f6f667cfSStefano Zampini } 3102f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 310308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 310408122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 310508122e43SStefano Zampini #endif 31069162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 31079162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 31089162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 310908122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 31109162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 311108122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 311208122e43SStefano Zampini 311308122e43SStefano Zampini maxneigs = 0; 311472b8c272SStefano Zampini cum = cumarray = 0; 31159162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 31169162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 3117d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 311808122e43SStefano Zampini const PetscInt *idxs; 311908122e43SStefano Zampini 3120d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 312108122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 312208122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 312308122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 312408122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 31259162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 31269162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 312708122e43SStefano Zampini } 3128d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 312908122e43SStefano Zampini } 313008122e43SStefano Zampini 313108122e43SStefano Zampini if (mss) { /* multilevel */ 313208122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 313308122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 313408122e43SStefano Zampini } 313508122e43SStefano Zampini 3136bd2a564bSStefano Zampini lthresh = pcbddc->adaptive_threshold[0]; 3137bd2a564bSStefano Zampini uthresh = pcbddc->adaptive_threshold[1]; 313808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 313908122e43SStefano Zampini const PetscInt *idxs; 31409d54b7f4SStefano Zampini PetscReal upper,lower; 3141862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 314208122e43SStefano Zampini PetscBLASInt B_N; 3143aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 3144bd2a564bSStefano Zampini PetscBool scal = PETSC_FALSE; 314508122e43SStefano Zampini 31469d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 31479d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 3148bd2a564bSStefano Zampini lower = uthresh; 31499d54b7f4SStefano Zampini } else { 3150bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented without deluxe scaling"); 3151bd2a564bSStefano Zampini upper = 1./uthresh; 31529d54b7f4SStefano Zampini lower = 0.; 31539d54b7f4SStefano Zampini } 3154862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 3155ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 3156f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 3157bd2a564bSStefano Zampini /* this is experimental: we assume the dofs have been properly grouped to have 3158bd2a564bSStefano Zampini the diagonal blocks Schur complements either positive or negative definite (true for Stokes) */ 3159bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) { 3160bd2a564bSStefano Zampini Mat T; 3161bd2a564bSStefano Zampini 3162bd2a564bSStefano Zampini for (j=0;j<subset_size;j++) { 3163bd2a564bSStefano Zampini if (PetscRealPart(*(Sarray+cumarray+j*(subset_size+1))) < 0.0) { 3164bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Sarray+cumarray,&T);CHKERRQ(ierr); 3165bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3166bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3167bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Starray+cumarray,&T);CHKERRQ(ierr); 3168bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3169bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3170bd2a564bSStefano Zampini if (sub_schurs->change_primal_sub) { 3171bd2a564bSStefano Zampini PetscInt nz,k; 3172bd2a564bSStefano Zampini const PetscInt *idxs; 3173bd2a564bSStefano Zampini 3174bd2a564bSStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nz);CHKERRQ(ierr); 3175bd2a564bSStefano Zampini ierr = ISGetIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3176bd2a564bSStefano Zampini for (k=0;k<nz;k++) { 3177bd2a564bSStefano Zampini *( Sarray + cumarray + idxs[k]*(subset_size+1)) *= -1.0; 3178bd2a564bSStefano Zampini *(Starray + cumarray + idxs[k]*(subset_size+1)) = 0.0; 3179bd2a564bSStefano Zampini } 3180bd2a564bSStefano Zampini ierr = ISRestoreIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3181bd2a564bSStefano Zampini } 3182bd2a564bSStefano Zampini scal = PETSC_TRUE; 3183bd2a564bSStefano Zampini break; 3184bd2a564bSStefano Zampini } 3185bd2a564bSStefano Zampini } 3186bd2a564bSStefano Zampini } 3187bd2a564bSStefano Zampini 3188f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 3189bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 3190aff50787SStefano Zampini PetscInt j,k; 3191aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 3192aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 3193aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 319408122e43SStefano Zampini } 319508122e43SStefano Zampini for (j=0;j<subset_size;j++) { 3196aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 3197aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 3198aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 3199aff50787SStefano Zampini } 320008122e43SStefano Zampini } 320108122e43SStefano Zampini } else { 320208122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 320308122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 320408122e43SStefano Zampini } 32058bec7fa6SStefano Zampini } else { 3206f6f667cfSStefano Zampini S = Sarray + cumarray; 3207f6f667cfSStefano Zampini St = Starray + cumarray; 32088bec7fa6SStefano Zampini } 3209aff50787SStefano Zampini /* see if we can save some work */ 3210b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 3211aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 3212aff50787SStefano Zampini } 3213aff50787SStefano Zampini 3214b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 3215aff50787SStefano Zampini B_neigs = 0; 3216aff50787SStefano Zampini } else { 3217bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 321808122e43SStefano Zampini PetscBLASInt B_itype = 1; 3219f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 32204c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 32219552c7c7SStefano Zampini PetscInt nmin_s; 3222bd2a564bSStefano Zampini PetscBool compute_range; 3223bd2a564bSStefano Zampini 32249036ceccSStefano Zampini B_neigs = 0; 3225bd2a564bSStefano Zampini compute_range = (PetscBool)!same_data; 3226bd2a564bSStefano Zampini if (nmin >= subset_size) compute_range = PETSC_FALSE; 322708122e43SStefano Zampini 3228fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 32299036ceccSStefano Zampini PetscInt nc = 0; 3230d16cbb6bSStefano Zampini 32319036ceccSStefano Zampini if (sub_schurs->change_primal_sub) { 32329036ceccSStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nc);CHKERRQ(ierr); 32339036ceccSStefano Zampini } 32346080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %D/%D size %D count %D fid %D (range %d) (change %D).\n",i,sub_schurs->n_subs,subset_size,pcbddc->mat_graph->count[idxs[0]]+1,pcbddc->mat_graph->which_dof[idxs[0]],compute_range,nc);CHKERRQ(ierr); 3235b7ab4a40SStefano Zampini } 3236b7ab4a40SStefano Zampini 323708122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3238b7ab4a40SStefano Zampini if (compute_range) { 3239d16cbb6bSStefano Zampini 3240d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 3241bd2a564bSStefano Zampini if (sub_schurs->is_posdef) { 324208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 32439d54b7f4SStefano 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)); 324408122e43SStefano Zampini #else 32459d54b7f4SStefano 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)); 324608122e43SStefano Zampini #endif 324743371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3248bd2a564bSStefano Zampini } else { /* no theory so far, but it works nicely */ 32499036ceccSStefano Zampini PetscInt recipe = 0,recipe_m = 1; 3250bd2a564bSStefano Zampini PetscReal bb[2]; 3251bd2a564bSStefano Zampini 3252bd2a564bSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe",&recipe,NULL);CHKERRQ(ierr); 3253bd2a564bSStefano Zampini switch (recipe) { 3254bd2a564bSStefano Zampini case 0: 3255bd2a564bSStefano Zampini if (scal) { bb[0] = PETSC_MIN_REAL; bb[1] = lthresh; } 3256bd2a564bSStefano Zampini else { bb[0] = uthresh; bb[1] = PETSC_MAX_REAL; } 3257bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3258bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 3259bd2a564bSStefano Zampini #else 3260bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 3261bd2a564bSStefano Zampini #endif 326243371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3263bd2a564bSStefano Zampini break; 3264bd2a564bSStefano Zampini case 1: 3265bd2a564bSStefano Zampini bb[0] = PETSC_MIN_REAL; bb[1] = lthresh*lthresh; 3266bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3267bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 3268bd2a564bSStefano Zampini #else 3269bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 3270bd2a564bSStefano Zampini #endif 327143371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3272bd2a564bSStefano Zampini if (!scal) { 32739036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 3274bd2a564bSStefano Zampini 3275aed7e7d0SStefano Zampini bb[0] = PetscMax(lthresh*lthresh,uthresh); bb[1] = PETSC_MAX_REAL; 3276bd2a564bSStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 3277bd2a564bSStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 3278bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3279bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 3280bd2a564bSStefano Zampini #else 3281bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 3282bd2a564bSStefano Zampini #endif 328343371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3284bd2a564bSStefano Zampini B_neigs += B_neigs2; 3285bd2a564bSStefano Zampini } 3286bd2a564bSStefano Zampini break; 32879036ceccSStefano Zampini case 2: 32889036ceccSStefano Zampini if (scal) { 32899036ceccSStefano Zampini bb[0] = PETSC_MIN_REAL; 32909036ceccSStefano Zampini bb[1] = 0; 32919036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 32929036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 32939036ceccSStefano Zampini #else 32949036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 32959036ceccSStefano Zampini #endif 329643371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 32979036ceccSStefano Zampini } else { 32989036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 32999036ceccSStefano Zampini PetscBool import = PETSC_FALSE; 33009036ceccSStefano Zampini 33019036ceccSStefano Zampini lthresh = PetscMax(lthresh,0.0); 33029036ceccSStefano Zampini if (lthresh > 0.0) { 33039036ceccSStefano Zampini bb[0] = PETSC_MIN_REAL; 33049036ceccSStefano Zampini bb[1] = lthresh*lthresh; 33059036ceccSStefano Zampini 33069036ceccSStefano Zampini import = PETSC_TRUE; 33079036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 33089036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 33099036ceccSStefano Zampini #else 33109036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 33119036ceccSStefano Zampini #endif 331243371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 33139036ceccSStefano Zampini } 33149036ceccSStefano Zampini bb[0] = PetscMax(lthresh*lthresh,uthresh); 33159036ceccSStefano Zampini bb[1] = PETSC_MAX_REAL; 33169036ceccSStefano Zampini if (import) { 33179036ceccSStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 33189036ceccSStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 33199036ceccSStefano Zampini } 33209036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 33219036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 33229036ceccSStefano Zampini #else 33239036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 33249036ceccSStefano Zampini #endif 332543371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 33269036ceccSStefano Zampini B_neigs += B_neigs2; 33279036ceccSStefano Zampini } 33289036ceccSStefano Zampini break; 33299036ceccSStefano Zampini case 3: 33309036ceccSStefano Zampini if (scal) { 33319036ceccSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe3_min_scal",&recipe_m,NULL);CHKERRQ(ierr); 33329036ceccSStefano Zampini } else { 33339036ceccSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe3_min",&recipe_m,NULL);CHKERRQ(ierr); 33349036ceccSStefano Zampini } 33359036ceccSStefano Zampini if (!scal) { 33369036ceccSStefano Zampini bb[0] = uthresh; 33379036ceccSStefano Zampini bb[1] = PETSC_MAX_REAL; 33389036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 33399036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 33409036ceccSStefano Zampini #else 33419036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 33429036ceccSStefano Zampini #endif 334343371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 33449036ceccSStefano Zampini } 33459036ceccSStefano Zampini if (recipe_m > 0 && B_N - B_neigs > 0) { 33469036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 33479036ceccSStefano Zampini 33489036ceccSStefano Zampini B_IL = 1; 33499036ceccSStefano Zampini ierr = PetscBLASIntCast(PetscMin(recipe_m,B_N - B_neigs),&B_IU);CHKERRQ(ierr); 33509036ceccSStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 33519036ceccSStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 33529036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 33539036ceccSStefano 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*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 33549036ceccSStefano Zampini #else 33559036ceccSStefano 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*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 33569036ceccSStefano Zampini #endif 335743371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 33589036ceccSStefano Zampini B_neigs += B_neigs2; 33599036ceccSStefano Zampini } 33609036ceccSStefano Zampini break; 336148cebe81SStefano Zampini case 4: 336248cebe81SStefano Zampini bb[0] = PETSC_MIN_REAL; bb[1] = lthresh; 336348cebe81SStefano Zampini #if defined(PETSC_USE_COMPLEX) 336448cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 336548cebe81SStefano Zampini #else 336648cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 336748cebe81SStefano Zampini #endif 336843371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 336948cebe81SStefano Zampini { 337048cebe81SStefano Zampini PetscBLASInt B_neigs2 = 0; 337148cebe81SStefano Zampini 337248cebe81SStefano Zampini bb[0] = PetscMax(lthresh+PETSC_SMALL,uthresh); bb[1] = PETSC_MAX_REAL; 337348cebe81SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 337448cebe81SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 337548cebe81SStefano Zampini #if defined(PETSC_USE_COMPLEX) 337648cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 337748cebe81SStefano Zampini #else 337848cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 337948cebe81SStefano Zampini #endif 338043371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 338148cebe81SStefano Zampini B_neigs += B_neigs2; 338248cebe81SStefano Zampini } 338348cebe81SStefano Zampini break; 338480db8efeSStefano Zampini case 5: /* same as before: first compute all eigenvalues, then filter */ 338580db8efeSStefano Zampini #if defined(PETSC_USE_COMPLEX) 338680db8efeSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","A","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 338780db8efeSStefano Zampini #else 338880db8efeSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","A","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 338980db8efeSStefano Zampini #endif 339043371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 339180db8efeSStefano Zampini { 339280db8efeSStefano Zampini PetscInt e,k,ne; 339380db8efeSStefano Zampini for (e=0,ne=0;e<B_neigs;e++) { 339480db8efeSStefano Zampini if (eigs[e] < lthresh || eigs[e] > uthresh) { 339580db8efeSStefano Zampini for (k=0;k<B_N;k++) S[ne*B_N+k] = eigv[e*B_N+k]; 339680db8efeSStefano Zampini eigs[ne] = eigs[e]; 339780db8efeSStefano Zampini ne++; 339880db8efeSStefano Zampini } 339980db8efeSStefano Zampini } 340080db8efeSStefano Zampini ierr = PetscMemcpy(eigv,S,B_N*ne*sizeof(PetscScalar));CHKERRQ(ierr); 340180db8efeSStefano Zampini B_neigs = ne; 340280db8efeSStefano Zampini } 340380db8efeSStefano Zampini break; 3404bd2a564bSStefano Zampini default: 3405bd2a564bSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Unknown recipe %D",recipe); 3406bd2a564bSStefano Zampini break; 3407bd2a564bSStefano Zampini } 3408bd2a564bSStefano Zampini } 3409bd2a564bSStefano Zampini } else if (!same_data) { /* this is just to see all the eigenvalues */ 3410d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 3411d16cbb6bSStefano Zampini B_IL = 1; 3412d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 34139d54b7f4SStefano 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)); 3414d16cbb6bSStefano Zampini #else 34159d54b7f4SStefano 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)); 3416d16cbb6bSStefano Zampini #endif 341743371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 3418b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 3419b7ab4a40SStefano Zampini PetscInt k; 3420b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 3421b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 3422b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 3423b7ab4a40SStefano Zampini nmin = nmax; 3424b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 3425b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 3426b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 3427b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 3428b7ab4a40SStefano Zampini } 3429d16cbb6bSStefano Zampini } 343008122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 343108122e43SStefano Zampini if (B_ierr) { 34326c4ed002SBarry 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); 34336c4ed002SBarry 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); 34346c4ed002SBarry 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); 343508122e43SStefano Zampini } 343608122e43SStefano Zampini 343708122e43SStefano Zampini if (B_neigs > nmax) { 3438fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 34396080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %D.\n",B_neigs,nmax);CHKERRQ(ierr); 3440fd14bc51SStefano Zampini } 3441bd2a564bSStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = scal ? 0 : B_neigs-nmax; 344208122e43SStefano Zampini B_neigs = nmax; 344308122e43SStefano Zampini } 344408122e43SStefano Zampini 34459552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 34469552c7c7SStefano Zampini if (B_neigs < nmin_s) { 34479036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 344808122e43SStefano Zampini 34499d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3450bd2a564bSStefano Zampini if (scal) { 3451bd2a564bSStefano Zampini B_IU = nmin_s; 3452bd2a564bSStefano Zampini B_IL = B_neigs + 1; 3453bd2a564bSStefano Zampini } else { 3454f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 34559d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 3456bd2a564bSStefano Zampini } 34579d54b7f4SStefano Zampini } else { 34589d54b7f4SStefano Zampini B_IL = B_neigs + 1; 34599d54b7f4SStefano Zampini B_IU = nmin_s; 34609d54b7f4SStefano Zampini } 3461fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 34626080607fSStefano Zampini ierr = 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);CHKERRQ(ierr); 3463fd14bc51SStefano Zampini } 3464bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 34651ae86dd6SStefano Zampini PetscInt j,k; 346608122e43SStefano Zampini for (j=0;j<subset_size;j++) { 34671ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 34681ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 34691ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 347008122e43SStefano Zampini } 347108122e43SStefano Zampini } 347208122e43SStefano Zampini } else { 347308122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 347408122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 347508122e43SStefano Zampini } 347608122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 347708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 34789d54b7f4SStefano 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)); 347908122e43SStefano Zampini #else 34809d54b7f4SStefano 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)); 348108122e43SStefano Zampini #endif 348243371fb9SStefano Zampini ierr = PetscLogFlops((4.0*subset_size*subset_size*subset_size)/3.0);CHKERRQ(ierr); 348308122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 348408122e43SStefano Zampini B_neigs += B_neigs2; 348508122e43SStefano Zampini } 348608122e43SStefano Zampini if (B_ierr) { 34876c4ed002SBarry 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); 34886c4ed002SBarry 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); 34896c4ed002SBarry 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); 349008122e43SStefano Zampini } 3491fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3492ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 349308122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 349408122e43SStefano Zampini if (eigs[j] == 0.0) { 3495ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 349608122e43SStefano Zampini } else { 34979d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3498ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 34999d54b7f4SStefano Zampini } else { 35009d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 35019d54b7f4SStefano Zampini } 3502fd14bc51SStefano Zampini } 350308122e43SStefano Zampini } 350408122e43SStefano Zampini } 3505bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 3506aff50787SStefano Zampini } 35076c3e6151SStefano Zampini /* change the basis back to the original one */ 35086c3e6151SStefano Zampini if (sub_schurs->change) { 350972b8c272SStefano Zampini Mat change,phi,phit; 35106c3e6151SStefano Zampini 351103dfb2d7SStefano Zampini if (pcbddc->dbg_flag > 2) { 35126c3e6151SStefano Zampini PetscInt ii; 35136c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 35146c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 35156c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 3516684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3517684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 3518684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 3519684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3520684229deSStefano Zampini #else 35216c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 3522684229deSStefano Zampini #endif 35236c3e6151SStefano Zampini } 35246c3e6151SStefano Zampini } 35256c3e6151SStefano Zampini } 352672b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 35276c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 352872b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 35296c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 35306c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 35316c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 35326c3e6151SStefano Zampini } 35338bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 35348bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 35359162d606SStefano Zampini if (B_neigs) { 35369162d606SStefano 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); 3537fd14bc51SStefano Zampini 3538fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 35399552c7c7SStefano Zampini PetscInt ii; 35409552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 3541ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 35429552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 3543ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3544ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3545ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3546ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3547ac47001eSStefano Zampini #else 3548ac47001eSStefano 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); 3549ac47001eSStefano Zampini #endif 35509552c7c7SStefano Zampini } 35519552c7c7SStefano Zampini } 3552fd14bc51SStefano Zampini } 35539162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 35549162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 35559162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 35569162d606SStefano Zampini cum++; 355708122e43SStefano Zampini } 355808122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 355908122e43SStefano Zampini /* shift for next computation */ 356008122e43SStefano Zampini cumarray += subset_size*subset_size; 356108122e43SStefano Zampini } 3562fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3563fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3564fd14bc51SStefano Zampini } 356508122e43SStefano Zampini 356608122e43SStefano Zampini if (mss) { 356708122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 356808122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 3569f6f667cfSStefano Zampini /* destroy matrices (junk) */ 3570f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 3571f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 357208122e43SStefano Zampini } 3573f6f667cfSStefano Zampini if (allocated_S_St) { 3574f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 3575f6f667cfSStefano Zampini } 3576f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 357708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 357808122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 357908122e43SStefano Zampini #endif 358008122e43SStefano Zampini if (pcbddc->dbg_flag) { 35811b968477SStefano Zampini PetscInt maxneigs_r; 3582b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 35836080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %D\n",maxneigs_r);CHKERRQ(ierr); 358408122e43SStefano Zampini } 358543371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_AdaptiveSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 358608122e43SStefano Zampini PetscFunctionReturn(0); 358708122e43SStefano Zampini } 3588b1b3d7a2SStefano Zampini 3589c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 3590c8587f34SStefano Zampini { 35918629588bSStefano Zampini PetscScalar *coarse_submat_vals; 3592c8587f34SStefano Zampini PetscErrorCode ierr; 3593c8587f34SStefano Zampini 3594c8587f34SStefano Zampini PetscFunctionBegin; 3595f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 35965e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3597c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3598c8587f34SStefano Zampini 3599684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 36000fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3601684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3602c8587f34SStefano Zampini 36038629588bSStefano Zampini /* 36048629588bSStefano Zampini Setup local correction and local part of coarse basis. 36058629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 36068629588bSStefano Zampini */ 360747f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 36088629588bSStefano Zampini 36098629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 36108629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 36118629588bSStefano Zampini 36128629588bSStefano Zampini /* free */ 36138629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3614c8587f34SStefano Zampini PetscFunctionReturn(0); 3615c8587f34SStefano Zampini } 3616c8587f34SStefano Zampini 3617674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3618674ae819SStefano Zampini { 3619674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3620674ae819SStefano Zampini PetscErrorCode ierr; 3621674ae819SStefano Zampini 3622674ae819SStefano Zampini PetscFunctionBegin; 3623674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 362430368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3625674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3626785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3627674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3628f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3629f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3630785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 363163602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 363263602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3633674ae819SStefano Zampini PetscFunctionReturn(0); 3634674ae819SStefano Zampini } 3635674ae819SStefano Zampini 3636674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3637674ae819SStefano Zampini { 3638674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 36394f1b2e48SStefano Zampini PetscInt i; 3640674ae819SStefano Zampini PetscErrorCode ierr; 3641674ae819SStefano Zampini 3642674ae819SStefano Zampini PetscFunctionBegin; 36431e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 36441e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3645a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3646b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3647674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 364816909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 36491dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3650674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3651669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3652fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 36539326c5c6Sstefano_zampini ierr = PCBDDCGraphDestroy(&pcbddc->mat_graph);CHKERRQ(ierr); 36544f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 36554f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 36564f1b2e48SStefano Zampini } 3657e68a0315Sstefano_zampini pcbddc->n_local_subs = 0; 36584f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3659e68a0315Sstefano_zampini ierr = PCBDDCSubSchursDestroy(&pcbddc->sub_schurs);CHKERRQ(ierr); 3660c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 36618af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 36621c7a958bSStefano Zampini pcbddc->corner_selected = PETSC_FALSE; 3663674ae819SStefano Zampini PetscFunctionReturn(0); 3664674ae819SStefano Zampini } 3665674ae819SStefano Zampini 3666674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3667674ae819SStefano Zampini { 3668674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3669674ae819SStefano Zampini PetscErrorCode ierr; 3670674ae819SStefano Zampini 3671674ae819SStefano Zampini PetscFunctionBegin; 3672674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 367358da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3674ca92afb2SStefano Zampini PetscScalar *array; 367506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 367606656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 367758da7f69SStefano Zampini } 3678674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3679674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 368015aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 368115aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3682674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3683674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3684674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 368506656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3686674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3687674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 36888ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3689674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3690674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3691674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 36929326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_D);CHKERRQ(ierr); 36939326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 36949326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3695f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3696727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 36970e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3698f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 369970cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 370081d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 37010369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 37021dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 37034f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 37048b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3705ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3706ca92afb2SStefano Zampini PetscInt i; 3707ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3708ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3709ca92afb2SStefano Zampini } 3710ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3711ca92afb2SStefano Zampini } 37124f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3713674ae819SStefano Zampini PetscFunctionReturn(0); 3714674ae819SStefano Zampini } 3715674ae819SStefano Zampini 3716f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 37176bfb1811SStefano Zampini { 37186bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 37196bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 37206bfb1811SStefano Zampini VecType impVecType; 37214f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 37226bfb1811SStefano Zampini PetscErrorCode ierr; 37236bfb1811SStefano Zampini 37246bfb1811SStefano Zampini PetscFunctionBegin; 37254f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3726b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 37276bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3728e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3729e7b262bdSStefano Zampini /* R nodes */ 3730e7b262bdSStefano Zampini old_size = -1; 3731e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3732e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3733e7b262bdSStefano Zampini } 3734e7b262bdSStefano Zampini if (n_R != old_size) { 3735e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3736e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 37376bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 37386bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 37396bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 37406bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3741e7b262bdSStefano Zampini } 3742e7b262bdSStefano Zampini /* local primal dofs */ 3743e7b262bdSStefano Zampini old_size = -1; 3744e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3745e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3746e7b262bdSStefano Zampini } 3747e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3748e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 374983b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3750e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 37516bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3752e7b262bdSStefano Zampini } 3753e7b262bdSStefano Zampini /* local explicit constraints */ 3754e7b262bdSStefano Zampini old_size = -1; 3755e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3756e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3757e7b262bdSStefano Zampini } 3758e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3759e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 376083b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 376183b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 376283b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 376383b7ccabSStefano Zampini } 37646bfb1811SStefano Zampini PetscFunctionReturn(0); 37656bfb1811SStefano Zampini } 37666bfb1811SStefano Zampini 376747f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 376888ebb749SStefano Zampini { 376925084f0cSStefano Zampini PetscErrorCode ierr; 377025084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 377188ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 377288ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3773d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 377425084f0cSStefano Zampini /* submatrices of local problem */ 377580677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 377606656605SStefano Zampini /* submatrices of local coarse problem */ 377706656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 377825084f0cSStefano Zampini /* working matrices */ 377906656605SStefano Zampini Mat C_CR; 378025084f0cSStefano Zampini /* additional working stuff */ 378106656605SStefano Zampini PC pc_R; 3782c58f9fdbSStefano Zampini Mat F,Brhs = NULL; 37835cbda25cSStefano Zampini Vec dummy_vec; 3784c58f9fdbSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction,sparserhs; 378525084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 378606656605SStefano Zampini PetscScalar *work; 378706656605SStefano Zampini PetscInt *idx_V_B; 3788ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 378906656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 3790ffd830a3SStefano Zampini 379125084f0cSStefano Zampini /* some shortcuts to scalars */ 379206656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 379388ebb749SStefano Zampini 379488ebb749SStefano Zampini PetscFunctionBegin; 37959a962809SStefano 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"); 379643371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CorrectionSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 3797ffd830a3SStefano Zampini 3798ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3799b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 38004f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3801b371cd4fSStefano Zampini n_B = pcis->n_B; 3802b371cd4fSStefano Zampini n_D = pcis->n - n_B; 380388ebb749SStefano Zampini n_R = pcis->n - n_vertices; 380488ebb749SStefano Zampini 380588ebb749SStefano Zampini /* vertices in boundary numbering */ 3806785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 38070e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 38086080607fSStefano Zampini if (i != n_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D",n_vertices,i); 380988ebb749SStefano Zampini 381006656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3811019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 381206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 381306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 381406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 381506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 381606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 381706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 381806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 381906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 382006656605SStefano Zampini 382106656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 382206656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 38232958b453SStefano Zampini ierr = PCSetUp(pc_R);CHKERRQ(ierr); 382406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 382506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 382606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 3827ffd830a3SStefano Zampini lda_rhs = n_R; 3828a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 382906656605SStefano Zampini if (isLU || isILU || isCHOL) { 383006656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 3831b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 3832df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3833d62866d3SStefano Zampini MatFactorType type; 3834d62866d3SStefano Zampini 3835df4d28bfSStefano Zampini F = reuse_solver->F; 38366816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 3837d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 3838ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 383922db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 384006656605SStefano Zampini } else { 384106656605SStefano Zampini F = NULL; 384206656605SStefano Zampini } 384306656605SStefano Zampini 3844c58f9fdbSStefano Zampini /* determine if we can use a sparse right-hand side */ 3845c58f9fdbSStefano Zampini sparserhs = PETSC_FALSE; 3846c58f9fdbSStefano Zampini if (F) { 3847ea799195SBarry Smith MatSolverType solver; 3848c58f9fdbSStefano Zampini 38493ca39a21SBarry Smith ierr = MatFactorGetSolverType(F,&solver);CHKERRQ(ierr); 3850c58f9fdbSStefano Zampini ierr = PetscStrcmp(solver,MATSOLVERMUMPS,&sparserhs);CHKERRQ(ierr); 3851c58f9fdbSStefano Zampini } 3852c58f9fdbSStefano Zampini 3853ffd830a3SStefano Zampini /* allocate workspace */ 3854ffd830a3SStefano Zampini n = 0; 3855ffd830a3SStefano Zampini if (n_constraints) { 3856ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3857ffd830a3SStefano Zampini } 3858ffd830a3SStefano Zampini if (n_vertices) { 3859ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3860ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3861ffd830a3SStefano Zampini } 38622a3a6641Sstefano_zampini if (!pcbddc->symmetric_primal) { 38632a3a6641Sstefano_zampini n = PetscMax(2*lda_rhs*pcbddc->local_primal_size,n); 38642a3a6641Sstefano_zampini } 3865ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3866ffd830a3SStefano Zampini 38675cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 38685cbda25cSStefano Zampini dummy_vec = NULL; 38695cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 38705cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 38715cbda25cSStefano Zampini } 38725cbda25cSStefano Zampini 387388ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 387488ebb749SStefano Zampini if (n_constraints) { 3875837cedc9SStefano Zampini Mat M3,C_B; 387606656605SStefano Zampini IS is_aux; 387780677318SStefano Zampini PetscScalar *array,*array2; 387806656605SStefano Zampini 3879f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 388080677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 388188ebb749SStefano Zampini 388225084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 388325084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 38847dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 38857dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 388688ebb749SStefano Zampini 388780677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 388880677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 3889c58f9fdbSStefano Zampini if (!sparserhs) { 3890ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 389188ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 389206656605SStefano Zampini const PetscScalar *row_cmat_values; 389306656605SStefano Zampini const PetscInt *row_cmat_indices; 389406656605SStefano Zampini PetscInt size_of_constraint,j; 389588ebb749SStefano Zampini 389606656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 389706656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 3898ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 389906656605SStefano Zampini } 390006656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 390106656605SStefano Zampini } 3902c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&Brhs);CHKERRQ(ierr); 3903c58f9fdbSStefano Zampini } else { 3904c58f9fdbSStefano Zampini Mat tC_CR; 3905c58f9fdbSStefano Zampini 3906c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3907c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 3908c58f9fdbSStefano Zampini PetscScalar *aa; 3909c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 3910c58f9fdbSStefano Zampini PetscBool done; 3911c58f9fdbSStefano Zampini 3912c58f9fdbSStefano Zampini ierr = MatGetRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 391313903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 3914c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(C_CR,&aa);CHKERRQ(ierr); 3915c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_constraints,lda_rhs,ii,jj,aa,&tC_CR);CHKERRQ(ierr); 3916c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 391713903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 3918c58f9fdbSStefano Zampini } else { 3919c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)C_CR);CHKERRQ(ierr); 3920c58f9fdbSStefano Zampini tC_CR = C_CR; 3921c58f9fdbSStefano Zampini } 3922c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tC_CR,&Brhs);CHKERRQ(ierr); 3923c58f9fdbSStefano Zampini ierr = MatDestroy(&tC_CR);CHKERRQ(ierr); 3924c58f9fdbSStefano Zampini } 3925ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 392606656605SStefano Zampini if (F) { 3927a3df083aSStefano Zampini if (need_benign_correction) { 3928df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3929a3df083aSStefano Zampini 393072b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 393172b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 3932a3df083aSStefano Zampini } 3933c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,local_auxmat2_R);CHKERRQ(ierr); 3934a3df083aSStefano Zampini if (need_benign_correction) { 3935a3df083aSStefano Zampini PetscScalar *marr; 3936df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3937a3df083aSStefano Zampini 3938a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 39395cbda25cSStefano Zampini if (lda_rhs != n_R) { 39405cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 39415cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 39425cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 39435cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 39445cbda25cSStefano Zampini } 39455cbda25cSStefano Zampini } else { 3946a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 3947a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 39485cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3949a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3950a3df083aSStefano Zampini } 39515cbda25cSStefano Zampini } 3952a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 3953a3df083aSStefano Zampini } 395406656605SStefano Zampini } else { 395580677318SStefano Zampini PetscScalar *marr; 395680677318SStefano Zampini 395780677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 395806656605SStefano Zampini for (i=0;i<n_constraints;i++) { 3959ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3960ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 396106656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 396206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 396306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 396406656605SStefano Zampini } 396580677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 396606656605SStefano Zampini } 3967c58f9fdbSStefano Zampini if (sparserhs) { 3968c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3969c58f9fdbSStefano Zampini } 3970c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 397180677318SStefano Zampini if (!pcbddc->switch_static) { 397280677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 397380677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 397480677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 397580677318SStefano Zampini for (i=0;i<n_constraints;i++) { 3976ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 397780677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 397880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 397980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 398080677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 398180677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 398280677318SStefano Zampini } 398380677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 398480677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 398572b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 398680677318SStefano Zampini } else { 3987ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3988ffd830a3SStefano Zampini IS dummy; 3989ffd830a3SStefano Zampini 3990ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 39917dae84e0SHong Zhang ierr = MatCreateSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 3992ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 3993ffd830a3SStefano Zampini } else { 399480677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 399580677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 3996ffd830a3SStefano Zampini } 399725084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 399880677318SStefano Zampini } 399980677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 400080677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 400180677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 400280677318SStefano Zampini if (isCHOL) { 400380677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 400480677318SStefano Zampini } else { 400525084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 400680677318SStefano Zampini } 4007837cedc9SStefano Zampini ierr = MatSeqDenseInvertFactors_Private(M3);CHKERRQ(ierr); 400880677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 4009837cedc9SStefano Zampini ierr = MatMatMult(M3,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 401072b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 4011837cedc9SStefano Zampini ierr = MatCopy(M3,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 4012837cedc9SStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 4013f4ddd8eeSStefano Zampini } 4014fc227af8SStefano Zampini 4015fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 401688ebb749SStefano Zampini if (n_vertices) { 401706656605SStefano Zampini IS is_aux; 4018c58f9fdbSStefano Zampini PetscBool isseqaij; 40193a50541eSStefano Zampini 4020b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 40216816873aSStefano Zampini IS tis; 40226816873aSStefano Zampini 40236816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 40246816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 40256816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 40266816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 40276816873aSStefano Zampini } else { 40283a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 40296816873aSStefano Zampini } 40307dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 40317dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 4032c58f9fdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 4033c58f9fdbSStefano Zampini if (!isseqaij) { /* MatMatMult(A_VR,A_RRmA_RV) below will raise an error */ 4034c58f9fdbSStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4035c58f9fdbSStefano Zampini } 40367dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 403725084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 403888ebb749SStefano Zampini } 403988ebb749SStefano Zampini 404088ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 4041f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 404206656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 404306656605SStefano Zampini if (pcbddc->coarse_phi_D) { 404406656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 404506656605SStefano Zampini } 4046f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 404706656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 404806656605SStefano Zampini PetscScalar *marray; 404906656605SStefano Zampini 405006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 405106656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 4052f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 4053f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 4054f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 4055f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 4056f4ddd8eeSStefano Zampini } 4057f4ddd8eeSStefano Zampini } 405806656605SStefano Zampini 4059f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 4060a6e023c1Sstefano_zampini PetscScalar *marr; 406188ebb749SStefano Zampini 4062a6e023c1Sstefano_zampini /* memory size */ 406306656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 4064a6e023c1Sstefano_zampini if (pcbddc->switch_static || pcbddc->dbg_flag) n += n_D*pcbddc->local_primal_size; 4065a6e023c1Sstefano_zampini if (!pcbddc->symmetric_primal) n *= 2; 4066a6e023c1Sstefano_zampini ierr = PetscCalloc1(n,&marr);CHKERRQ(ierr); 4067a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 4068a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 40698eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4070a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 4071a6e023c1Sstefano_zampini marr += n_D*pcbddc->local_primal_size; 407288ebb749SStefano Zampini } 40733301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4074a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 4075a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 40768eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4077a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 407888ebb749SStefano Zampini } 407988ebb749SStefano Zampini } else { 4080c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 4081c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 40821b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4083c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 4084c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 4085c0553b1fSStefano Zampini } 408688ebb749SStefano Zampini } 408706656605SStefano Zampini } 4088019a44ceSStefano Zampini 408906656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 40904f1b2e48SStefano Zampini p0_lidx_I = NULL; 40914f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 4092d12edf2fSStefano Zampini const PetscInt *idxs; 4093d12edf2fSStefano Zampini 4094d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 40954f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 40964f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 40974f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 40984f1b2e48SStefano Zampini } 4099d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 4100d12edf2fSStefano Zampini } 4101d16cbb6bSStefano Zampini 410206656605SStefano Zampini /* vertices */ 410306656605SStefano Zampini if (n_vertices) { 4104c58f9fdbSStefano Zampini PetscBool restoreavr = PETSC_FALSE; 410516f15bc4SStefano Zampini 4106af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 410704708bb6SStefano Zampini 410816f15bc4SStefano Zampini if (n_R) { 410914393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 411006656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 411116f15bc4SStefano Zampini PetscScalar *x,*y; 411206656605SStefano Zampini 411321eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 411414393ed6SStefano Zampini if (need_benign_correction) { 411514393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 411614393ed6SStefano Zampini IS is_p0; 411714393ed6SStefano Zampini PetscInt *idxs_p0,n; 411814393ed6SStefano Zampini 411914393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 412014393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 412114393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 41226080607fSStefano Zampini if (n != pcbddc->benign_n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in R numbering for benign p0! %D != %D",n,pcbddc->benign_n); 412314393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 412414393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 41257dae84e0SHong Zhang ierr = MatCreateSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 412614393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 412714393ed6SStefano Zampini } 412814393ed6SStefano Zampini 4129c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4130c58f9fdbSStefano Zampini if (!sparserhs || need_benign_correction) { 4131ffd830a3SStefano Zampini if (lda_rhs == n_R) { 4132af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 4133ffd830a3SStefano Zampini } else { 4134ca92afb2SStefano Zampini PetscScalar *av,*array; 4135ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 4136ca92afb2SStefano Zampini PetscInt n; 4137ca92afb2SStefano Zampini PetscBool flg_row; 4138ffd830a3SStefano Zampini 4139ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 4140ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 41419d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 4142ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4143ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 4144ca92afb2SStefano Zampini for (i=0;i<n;i++) { 4145ca92afb2SStefano Zampini PetscInt j; 4146ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 4147ffd830a3SStefano Zampini } 4148ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4149ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4150ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 4151ffd830a3SStefano Zampini } 4152a3df083aSStefano Zampini if (need_benign_correction) { 4153df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4154a3df083aSStefano Zampini PetscScalar *marr; 4155a3df083aSStefano Zampini 4156a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 415714393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 415814393ed6SStefano Zampini 415914393ed6SStefano Zampini | 0 0 0 | (V) 416014393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 416114393ed6SStefano Zampini | 0 0 -1 | (p0) 416214393ed6SStefano Zampini 416314393ed6SStefano Zampini */ 4164df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 416514393ed6SStefano Zampini const PetscScalar *vals; 416614393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 416714393ed6SStefano Zampini PetscInt n,j,nz; 416814393ed6SStefano Zampini 4169df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4170df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 417114393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 417214393ed6SStefano Zampini for (j=0;j<n;j++) { 417314393ed6SStefano Zampini PetscScalar val = vals[j]; 417414393ed6SStefano Zampini PetscInt k,col = idxs[j]; 417514393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 417614393ed6SStefano Zampini } 417714393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4178df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 417914393ed6SStefano Zampini } 418072b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 418172b8c272SStefano Zampini } 4182c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RV);CHKERRQ(ierr); 4183c58f9fdbSStefano Zampini Brhs = A_RV; 4184c58f9fdbSStefano Zampini } else { 4185c58f9fdbSStefano Zampini Mat tA_RVT,A_RVT; 4186c58f9fdbSStefano Zampini 4187c58f9fdbSStefano Zampini if (!pcbddc->symmetric_primal) { 4188fb6280fbSStefano Zampini /* A_RV already scaled by -1 */ 4189c58f9fdbSStefano Zampini ierr = MatTranspose(A_RV,MAT_INITIAL_MATRIX,&A_RVT);CHKERRQ(ierr); 4190c58f9fdbSStefano Zampini } else { 4191c58f9fdbSStefano Zampini restoreavr = PETSC_TRUE; 4192c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4193c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_VR);CHKERRQ(ierr); 4194c58f9fdbSStefano Zampini A_RVT = A_VR; 4195c58f9fdbSStefano Zampini } 4196c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 4197c58f9fdbSStefano Zampini PetscScalar *aa; 4198c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 4199c58f9fdbSStefano Zampini PetscBool done; 4200c58f9fdbSStefano Zampini 4201c58f9fdbSStefano Zampini ierr = MatGetRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 420213903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 4203c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(A_RVT,&aa);CHKERRQ(ierr); 4204c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_vertices,lda_rhs,ii,jj,aa,&tA_RVT);CHKERRQ(ierr); 4205c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 420613903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 4207c58f9fdbSStefano Zampini } else { 4208c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RVT);CHKERRQ(ierr); 4209c58f9fdbSStefano Zampini tA_RVT = A_RVT; 4210c58f9fdbSStefano Zampini } 4211c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tA_RVT,&Brhs);CHKERRQ(ierr); 4212c58f9fdbSStefano Zampini ierr = MatDestroy(&tA_RVT);CHKERRQ(ierr); 4213c58f9fdbSStefano Zampini ierr = MatDestroy(&A_RVT);CHKERRQ(ierr); 4214c58f9fdbSStefano Zampini } 421572b8c272SStefano Zampini if (F) { 421614393ed6SStefano Zampini /* need to correct the rhs */ 421772b8c272SStefano Zampini if (need_benign_correction) { 421872b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 421972b8c272SStefano Zampini PetscScalar *marr; 422072b8c272SStefano Zampini 4221c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&marr);CHKERRQ(ierr); 42225cbda25cSStefano Zampini if (lda_rhs != n_R) { 42235cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 42245cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 42255cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 42265cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 42275cbda25cSStefano Zampini } 42285cbda25cSStefano Zampini } else { 4229a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4230a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 42315cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 4232a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4233a3df083aSStefano Zampini } 42345cbda25cSStefano Zampini } 4235c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&marr);CHKERRQ(ierr); 4236a3df083aSStefano Zampini } 4237c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,A_RRmA_RV);CHKERRQ(ierr); 4238c58f9fdbSStefano Zampini if (restoreavr) { 4239c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4240c58f9fdbSStefano Zampini } 424114393ed6SStefano Zampini /* need to correct the solution */ 4242a3df083aSStefano Zampini if (need_benign_correction) { 4243df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4244a3df083aSStefano Zampini PetscScalar *marr; 4245a3df083aSStefano Zampini 4246a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 42475cbda25cSStefano Zampini if (lda_rhs != n_R) { 42485cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 42495cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 42505cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 42515cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 42525cbda25cSStefano Zampini } 42535cbda25cSStefano Zampini } else { 4254a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4255a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 42565cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 4257a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4258a3df083aSStefano Zampini } 42595cbda25cSStefano Zampini } 4260a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 4261a3df083aSStefano Zampini } 426206656605SStefano Zampini } else { 4263c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&y);CHKERRQ(ierr); 426406656605SStefano Zampini for (i=0;i<n_vertices;i++) { 4265ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 4266ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 426706656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 426806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 426906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 427006656605SStefano Zampini } 4271c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&y);CHKERRQ(ierr); 427206656605SStefano Zampini } 427380677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4274c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 4275ffd830a3SStefano Zampini /* S_VV and S_CV */ 427606656605SStefano Zampini if (n_constraints) { 427706656605SStefano Zampini Mat B; 427880677318SStefano Zampini 4279ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 428080677318SStefano Zampini for (i=0;i<n_vertices;i++) { 4281ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 4282ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 428380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 428480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 428580677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 428680677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 428780677318SStefano Zampini } 4288ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 428980677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 429080677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 4291ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 429280677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 429306656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 4294ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 4295ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 429606656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 429706656605SStefano Zampini } 4298ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4299ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 4300ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4301ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 4302ffd830a3SStefano Zampini } 430306656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 430414393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 430514393ed6SStefano Zampini if (need_benign_correction) { 4306df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 430714393ed6SStefano Zampini PetscScalar *marr,*sums; 430814393ed6SStefano Zampini 430914393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 4310f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 4311df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 431214393ed6SStefano Zampini const PetscScalar *vals; 431314393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 431414393ed6SStefano Zampini PetscInt n,j,nz; 431514393ed6SStefano Zampini 4316df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4317df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 431814393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 431914393ed6SStefano Zampini PetscInt k; 432014393ed6SStefano Zampini sums[j] = 0.; 432114393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 432214393ed6SStefano Zampini } 432314393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 432414393ed6SStefano Zampini for (j=0;j<n;j++) { 432514393ed6SStefano Zampini PetscScalar val = vals[j]; 432614393ed6SStefano Zampini PetscInt k; 432714393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 432814393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 432914393ed6SStefano Zampini } 433014393ed6SStefano Zampini } 433114393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4332df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 433314393ed6SStefano Zampini } 433414393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 4335f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 433614393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 433714393ed6SStefano Zampini } 433880677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 433906656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 434006656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 434106656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 434206656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 434306656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 434406656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 434506656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4346d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 4347019a44ceSStefano Zampini } else { 4348d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4349d16cbb6bSStefano Zampini } 435021eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 4351d16cbb6bSStefano Zampini 435206656605SStefano Zampini /* coarse basis functions */ 435306656605SStefano Zampini for (i=0;i<n_vertices;i++) { 435416f15bc4SStefano Zampini PetscScalar *y; 435516f15bc4SStefano Zampini 4356ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 435706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 435806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 435906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 436006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 436106656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 436206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 436306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 436406656605SStefano Zampini 436506656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 43664f1b2e48SStefano Zampini PetscInt j; 43674f1b2e48SStefano Zampini 436806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 436906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 437006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 437106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 437206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 43734f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 437406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 437506656605SStefano Zampini } 437606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 437706656605SStefano Zampini } 437804708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 437904708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 438006656605SStefano Zampini } 43815cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 438206656605SStefano Zampini 438306656605SStefano Zampini if (n_constraints) { 438406656605SStefano Zampini Mat B; 438506656605SStefano Zampini 4386ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 438706656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 438880677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 438906656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 439006656605SStefano Zampini if (n_vertices) { 439103dfb2d7SStefano Zampini if (isCHOL || need_benign_correction) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 439280677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 439380677318SStefano Zampini } else { 439480677318SStefano Zampini Mat S_VCt; 439580677318SStefano Zampini 4396ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4397ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 439872b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 4399ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 4400ffd830a3SStefano Zampini } 440180677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 440280677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 440380677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 440480677318SStefano Zampini } 440506656605SStefano Zampini } 440606656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 440706656605SStefano Zampini /* coarse basis functions */ 440806656605SStefano Zampini for (i=0;i<n_constraints;i++) { 440906656605SStefano Zampini PetscScalar *y; 441006656605SStefano Zampini 4411ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 441206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 441306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 441406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 441506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 441606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 441706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 441806656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 44194f1b2e48SStefano Zampini PetscInt j; 44204f1b2e48SStefano Zampini 442106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 442206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 442306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 442406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 442506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 44264f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 442706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 442806656605SStefano Zampini } 442906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 443006656605SStefano Zampini } 443106656605SStefano Zampini } 443280677318SStefano Zampini if (n_constraints) { 443380677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 443480677318SStefano Zampini } 44354f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 443672b8c272SStefano Zampini 443772b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 443872b8c272SStefano Zampini if (pcbddc->benign_n) { 443972b8c272SStefano Zampini Mat B0_B,B0_BPHI; 444072b8c272SStefano Zampini IS is_dummy; 444172b8c272SStefano Zampini PetscScalar *data; 444272b8c272SStefano Zampini PetscInt j; 444372b8c272SStefano Zampini 444472b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 44457dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 444672b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 444772b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 444886c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 444972b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 445072b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 445172b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 445272b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 445372b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 445472b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 445572b8c272SStefano Zampini } 445672b8c272SStefano Zampini } 445772b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 445872b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 445972b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 446072b8c272SStefano Zampini } 4461019a44ceSStefano Zampini 446206656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 44633301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4464ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 4465ffd830a3SStefano Zampini PetscScalar *marray; 446606656605SStefano Zampini 446706656605SStefano Zampini if (n_constraints) { 4468ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 446906656605SStefano Zampini 4470abc8f43dSstefano_zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 447106656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 4472ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 447316f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 447406656605SStefano Zampini if (n_vertices) { 4475ffd830a3SStefano Zampini Mat S_VCT; 447606656605SStefano Zampini 447706656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 4478ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 447916f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 448006656605SStefano Zampini } 4481ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 44825b782168SStefano Zampini } else { 44835b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 448406656605SStefano Zampini } 448516f15bc4SStefano Zampini if (n_vertices && n_R) { 4486ffd830a3SStefano Zampini PetscScalar *av,*marray; 4487ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 4488ffd830a3SStefano Zampini PetscInt n; 4489ffd830a3SStefano Zampini PetscBool flg_row; 449006656605SStefano Zampini 4491ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 4492af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4493ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4494ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 4495ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4496ffd830a3SStefano Zampini for (i=0;i<n;i++) { 4497ffd830a3SStefano Zampini PetscInt j; 4498ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 4499ffd830a3SStefano Zampini } 4500ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4501ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4502ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 450306656605SStefano Zampini } 450406656605SStefano Zampini 4505ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 4506abc8f43dSstefano_zampini if (n_vertices) { 4507ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4508ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 4509ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 4510ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 451106656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 451206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 451306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 451406656605SStefano Zampini } 4515ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4516abc8f43dSstefano_zampini } 45175b782168SStefano Zampini if (B_C) { 4518ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 4519ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 4520ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 4521ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 4522ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4523ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4524ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 452506656605SStefano Zampini } 4526ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 45275b782168SStefano Zampini } 452806656605SStefano Zampini /* coarse basis functions */ 452906656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 453006656605SStefano Zampini PetscScalar *y; 453106656605SStefano Zampini 4532ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 453306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 453406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 453506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 453606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 453706656605SStefano Zampini if (i<n_vertices) { 453806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 453906656605SStefano Zampini } 454006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 454106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 454206656605SStefano Zampini 454306656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 454406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 454506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 454606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 454706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 454806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 454906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 455006656605SStefano Zampini } 455106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 455206656605SStefano Zampini } 4553ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 4554ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 455506656605SStefano Zampini } 4556a6e023c1Sstefano_zampini 4557d62866d3SStefano Zampini /* free memory */ 455888ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 455906656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 456006656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 456106656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 456206656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 4563d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4564d62866d3SStefano Zampini if (n_vertices) { 4565d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 4566d62866d3SStefano Zampini } 4567d62866d3SStefano Zampini if (n_constraints) { 4568d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 4569d62866d3SStefano Zampini } 457088ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 457188ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 457288ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 4573d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 457488ebb749SStefano Zampini Mat coarse_sub_mat; 457525084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 457688ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 457788ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 457888ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 45798bec7fa6SStefano Zampini Mat C_B,CPHI; 45808bec7fa6SStefano Zampini IS is_dummy; 45818bec7fa6SStefano Zampini Vec mones; 458288ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 458388ebb749SStefano Zampini PetscReal real_value; 458488ebb749SStefano Zampini 4585a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 4586a3df083aSStefano Zampini Mat A; 4587a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 45887dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 45897dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 45907dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 45917dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4592a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 4593a3df083aSStefano Zampini } else { 459488ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 459588ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 459688ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 459788ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4598a3df083aSStefano Zampini } 459988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 460088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 4601ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 460288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 460388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 460488ebb749SStefano Zampini } 460588ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 460688ebb749SStefano Zampini 460725084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 46083301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 460925084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4610ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 461188ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 461288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 461388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 461488ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 461588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 461688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 461788ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 461888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 461988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 462088ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 462188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 462288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 462388ebb749SStefano Zampini } else { 462488ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 462588ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 462688ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 462788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 462888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 462988ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 463088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 463188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 463288ebb749SStefano Zampini } 463388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 463488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 463588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 4636511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 46374f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4638fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 4639d12edf2fSStefano Zampini PetscScalar *data,*data2; 46404f1b2e48SStefano Zampini PetscInt j; 4641d12edf2fSStefano Zampini 46424f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 46437dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 4644d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 464586c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 4646d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 4647d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 46484f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 46494f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 4650d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 46514f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 46524f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 46534f1b2e48SStefano Zampini } 4654d12edf2fSStefano Zampini } 4655d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 4656d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 4657d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4658d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4659d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4660d12edf2fSStefano Zampini } 4661d12edf2fSStefano Zampini #if 0 4662d12edf2fSStefano Zampini { 4663d12edf2fSStefano Zampini PetscViewer viewer; 4664d12edf2fSStefano Zampini char filename[256]; 4665ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4666d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4667a7414863SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4668ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4669ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4670ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4671d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 4672a7414863SStefano Zampini if (pcbddc->coarse_phi_B) { 4673ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4674ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 467572b8c272SStefano Zampini } 4676ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4677ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4678ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4679ffd830a3SStefano Zampini } 4680ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4681ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4682ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4683ffd830a3SStefano Zampini } 468472b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4685ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4686ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4687ffd830a3SStefano Zampini } 4688fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->local_mat,"A");CHKERRQ(ierr); 4689fb6280fbSStefano Zampini ierr = MatView(pcbddc->local_mat,viewer);CHKERRQ(ierr); 4690fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->ConstraintMatrix,"C");CHKERRQ(ierr); 4691fb6280fbSStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,viewer);CHKERRQ(ierr); 4692fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_I_local,"I");CHKERRQ(ierr); 4693fb6280fbSStefano Zampini ierr = ISView(pcis->is_I_local,viewer);CHKERRQ(ierr); 4694fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_B_local,"B");CHKERRQ(ierr); 4695fb6280fbSStefano Zampini ierr = ISView(pcis->is_B_local,viewer);CHKERRQ(ierr); 4696fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->is_R_local,"R");CHKERRQ(ierr); 4697fb6280fbSStefano Zampini ierr = ISView(pcbddc->is_R_local,viewer);CHKERRQ(ierr); 4698d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4699d12edf2fSStefano Zampini } 4700d12edf2fSStefano Zampini #endif 470181d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 47028bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 47031575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 470406656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 47058bec7fa6SStefano Zampini 47068bec7fa6SStefano Zampini /* check constraints */ 4707a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 47087dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 47094f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 47108bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4711a00504b5SStefano Zampini } else { 4712a00504b5SStefano Zampini PetscScalar *data; 4713a00504b5SStefano Zampini Mat tmat; 4714a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4715a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4716a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4717a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4718a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4719a00504b5SStefano Zampini } 47208bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 47218bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 47228bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 47238bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4724bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4725ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4726bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4727bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4728bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4729bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4730bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 473188ebb749SStefano Zampini } 47328bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 47338bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 47348bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 47358bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 473625084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 473788ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 473888ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 473988ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 474088ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 474188ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 474288ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 474388ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 474488ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 474588ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 474688ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4747ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 474888ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 474988ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 475088ebb749SStefano Zampini } 475188ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 475288ebb749SStefano Zampini } 47538629588bSStefano Zampini /* get back data */ 47548629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 475543371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CorrectionSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 475688ebb749SStefano Zampini PetscFunctionReturn(0); 475788ebb749SStefano Zampini } 475888ebb749SStefano Zampini 47597dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4760aa0d41d4SStefano Zampini { 4761d65f70fdSStefano Zampini Mat *work_mat; 4762d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4763d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4764c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4765aa0d41d4SStefano Zampini PetscErrorCode ierr; 4766aa0d41d4SStefano Zampini 4767aa0d41d4SStefano Zampini PetscFunctionBegin; 4768d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4769d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4770d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4771d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4772aa0d41d4SStefano Zampini 4773d65f70fdSStefano Zampini if (!rsorted) { 4774906d46d4SStefano Zampini const PetscInt *idxs; 4775906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4776aa0d41d4SStefano Zampini 4777d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4778d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4779d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4780d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4781aa0d41d4SStefano Zampini } 4782d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4783d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4784d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4785d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4786aa0d41d4SStefano Zampini } 4787d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4788d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4789d65f70fdSStefano Zampini } else { 4790d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4791d65f70fdSStefano Zampini isrow_s = isrow; 4792aa0d41d4SStefano Zampini } 4793906d46d4SStefano Zampini 4794d65f70fdSStefano Zampini if (!csorted) { 4795d65f70fdSStefano Zampini if (isrow == iscol) { 4796d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4797d65f70fdSStefano Zampini iscol_s = isrow_s; 4798d65f70fdSStefano Zampini } else { 4799d65f70fdSStefano Zampini const PetscInt *idxs; 4800d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4801906d46d4SStefano Zampini 4802d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4803d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4804d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4805d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4806d65f70fdSStefano Zampini } 4807d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 4808d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 4809d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4810d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 4811d65f70fdSStefano Zampini } 4812d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 4813d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 4814d65f70fdSStefano Zampini } 4815d65f70fdSStefano Zampini } else { 4816d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 4817d65f70fdSStefano Zampini iscol_s = iscol; 4818d65f70fdSStefano Zampini } 4819d65f70fdSStefano Zampini 48207dae84e0SHong Zhang ierr = MatCreateSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4821d65f70fdSStefano Zampini 4822d65f70fdSStefano Zampini if (!rsorted || !csorted) { 4823906d46d4SStefano Zampini Mat new_mat; 4824d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 4825906d46d4SStefano Zampini 4826d65f70fdSStefano Zampini if (!rsorted) { 4827d65f70fdSStefano Zampini PetscInt *idxs_r,i; 4828d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 4829d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4830d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 4831906d46d4SStefano Zampini } 4832d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 4833d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 4834d65f70fdSStefano Zampini } else { 4835d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 4836906d46d4SStefano Zampini } 4837d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 4838d65f70fdSStefano Zampini 4839d65f70fdSStefano Zampini if (!csorted) { 4840d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 4841d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 4842d65f70fdSStefano Zampini is_perm_c = is_perm_r; 4843d65f70fdSStefano Zampini } else { 4844d65f70fdSStefano Zampini PetscInt *idxs_c,i; 4845f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 4846d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 4847d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4848d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 4849d65f70fdSStefano Zampini } 4850d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 4851d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 4852d65f70fdSStefano Zampini } 4853d65f70fdSStefano Zampini } else { 4854d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 4855d65f70fdSStefano Zampini } 4856d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 4857d65f70fdSStefano Zampini 4858d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 4859d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 4860d65f70fdSStefano Zampini work_mat[0] = new_mat; 4861d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 4862d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 4863d65f70fdSStefano Zampini } 4864d65f70fdSStefano Zampini 4865d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 4866d65f70fdSStefano Zampini *B = work_mat[0]; 4867d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 4868d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 4869d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 4870d65f70fdSStefano Zampini PetscFunctionReturn(0); 4871d65f70fdSStefano Zampini } 4872d65f70fdSStefano Zampini 48735e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 4874aa0d41d4SStefano Zampini { 4875aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 48765e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4877022d8d2bSstefano_zampini Mat new_mat,lA; 48785e8657edSStefano Zampini IS is_local,is_global; 4879d65f70fdSStefano Zampini PetscInt local_size; 4880d65f70fdSStefano Zampini PetscBool isseqaij; 4881aa0d41d4SStefano Zampini PetscErrorCode ierr; 4882aa0d41d4SStefano Zampini 4883aa0d41d4SStefano Zampini PetscFunctionBegin; 4884aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 48855e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 48865e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 4887b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 4888aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 48897dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 4890aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 4891906d46d4SStefano Zampini 4892906d46d4SStefano Zampini /* check */ 4893906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4894906d46d4SStefano Zampini Vec x,x_change; 4895906d46d4SStefano Zampini PetscReal error; 4896906d46d4SStefano Zampini 48975e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 4898906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 48995e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 4900e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4901e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4902d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 490388428137SStefano Zampini if (!pcbddc->change_interior) { 490488428137SStefano Zampini const PetscScalar *x,*y,*v; 490588428137SStefano Zampini PetscReal lerror = 0.; 490688428137SStefano Zampini PetscInt i; 490788428137SStefano Zampini 490888428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 490988428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 491088428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 491188428137SStefano Zampini for (i=0;i<local_size;i++) 491288428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 491388428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 491488428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 491588428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 491688428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 491788428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4918637e8532SStefano Zampini if (error > PETSC_SMALL) { 4919637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 49206080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on I: %1.6e",error); 4921637e8532SStefano Zampini } else { 49226080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on I: %1.6e",error); 4923637e8532SStefano Zampini } 4924637e8532SStefano Zampini } 492588428137SStefano Zampini } 4926e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4927e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4928906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4929906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4930637e8532SStefano Zampini if (error > PETSC_SMALL) { 4931637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 49326080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e",error); 4933637e8532SStefano Zampini } else { 49346080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on N: %1.6e",error); 4935637e8532SStefano Zampini } 4936637e8532SStefano Zampini } 4937906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4938906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4939906d46d4SStefano Zampini } 4940906d46d4SStefano Zampini 4941022d8d2bSstefano_zampini /* lA is present if we are setting up an inner BDDC for a saddle point FETI-DP */ 4942022d8d2bSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 4943022d8d2bSstefano_zampini 494422d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 49459b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 494622d5777bSStefano Zampini if (isseqaij) { 4947a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4948a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 4949022d8d2bSstefano_zampini if (lA) { 4950022d8d2bSstefano_zampini Mat work; 4951022d8d2bSstefano_zampini ierr = MatPtAP(lA,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4952022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4953022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4954022d8d2bSstefano_zampini } 4955aa0d41d4SStefano Zampini } else { 4956a00504b5SStefano Zampini Mat work_mat; 49571cf9b237SStefano Zampini 4958a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4959aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4960a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 49611d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 4962022d8d2bSstefano_zampini if (lA) { 4963022d8d2bSstefano_zampini Mat work; 4964022d8d2bSstefano_zampini ierr = MatConvert(lA,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4965022d8d2bSstefano_zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4966022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4967022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4968022d8d2bSstefano_zampini } 4969aa0d41d4SStefano Zampini } 49703301b35fSStefano Zampini if (matis->A->symmetric_set) { 49713301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 4972e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 49733301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 4974e496cd5dSStefano Zampini #endif 49753301b35fSStefano Zampini } 4976d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 4977aa0d41d4SStefano Zampini PetscFunctionReturn(0); 4978aa0d41d4SStefano Zampini } 4979aa0d41d4SStefano Zampini 49808ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 4981a64d13efSStefano Zampini { 4982a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4983a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4984d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 498553892102SStefano Zampini PetscInt *idx_R_local=NULL; 49863a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 49873a50541eSStefano Zampini PetscInt vbs,bs; 49886816873aSStefano Zampini PetscBT bitmask=NULL; 4989a64d13efSStefano Zampini PetscErrorCode ierr; 4990a64d13efSStefano Zampini 4991a64d13efSStefano Zampini PetscFunctionBegin; 4992b23d619eSStefano Zampini /* 4993b23d619eSStefano Zampini No need to setup local scatters if 4994b23d619eSStefano Zampini - primal space is unchanged 4995b23d619eSStefano Zampini AND 4996b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 4997b23d619eSStefano Zampini AND 4998b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 4999b23d619eSStefano Zampini */ 5000b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 5001f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 5002f4ddd8eeSStefano Zampini } 5003f4ddd8eeSStefano Zampini /* destroy old objects */ 5004f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 5005f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 5006f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 5007a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 5008b371cd4fSStefano Zampini n_B = pcis->n_B; 5009b371cd4fSStefano Zampini n_D = pcis->n - n_B; 5010b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 50113a50541eSStefano Zampini 5012a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 50136816873aSStefano Zampini 501453892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 5015b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 5016854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 5017a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 5018a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 50190e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 5020a64d13efSStefano Zampini } 5021a64d13efSStefano Zampini 5022a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 50234641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 50246816873aSStefano Zampini idx_R_local[n_R++] = i; 5025a64d13efSStefano Zampini } 5026a64d13efSStefano Zampini } 5027df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 5028df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 50296816873aSStefano Zampini 5030df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5031df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 50326816873aSStefano Zampini } 50333a50541eSStefano Zampini 50343a50541eSStefano Zampini /* Block code */ 50353a50541eSStefano Zampini vbs = 1; 50363a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 50373a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 50383a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 50393a50541eSStefano Zampini PetscInt *vary; 5040b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 5041785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 50423a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 5043d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 5044d3df7717SStefano 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 */ 50450e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 5046d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 50473a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 50483a50541eSStefano Zampini is_blocked = PETSC_FALSE; 50493a50541eSStefano Zampini break; 50503a50541eSStefano Zampini } 50513a50541eSStefano Zampini } 5052d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 5053d3df7717SStefano Zampini } else { 5054d3df7717SStefano Zampini /* Verify directly the R set */ 5055d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 5056d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 5057d3df7717SStefano Zampini for (j=1; j<bs; j++) { 5058d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 5059d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 5060d3df7717SStefano Zampini break; 5061d3df7717SStefano Zampini } 5062d3df7717SStefano Zampini } 5063d3df7717SStefano Zampini } 5064d3df7717SStefano Zampini } 50653a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 50663a50541eSStefano Zampini vbs = bs; 50673a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 50683a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 50693a50541eSStefano Zampini } 50703a50541eSStefano Zampini } 50713a50541eSStefano Zampini } 50723a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 5073b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5074df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 507553892102SStefano Zampini 5076df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5077df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 507853892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 5079df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 508053892102SStefano Zampini } else { 50813a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 508253892102SStefano Zampini } 5083a64d13efSStefano Zampini 5084a64d13efSStefano Zampini /* print some info if requested */ 5085a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 5086a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5087a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50881575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5089a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 50906080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %D, dirichlet_size = %D, boundary_size = %D\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 50916080607fSStefano 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); 5092a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5093a64d13efSStefano Zampini } 5094a64d13efSStefano Zampini 5095a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 5096b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 50976816873aSStefano Zampini IS is_aux1,is_aux2; 50986816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 50996816873aSStefano Zampini 51003a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5101854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 5102854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 5103a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 51044641a718SStefano Zampini for (i=0; i<n_D; i++) { 51054641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 51064641a718SStefano Zampini } 5107a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5108a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 51094641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 51104641a718SStefano Zampini aux_array1[j++] = i; 5111a64d13efSStefano Zampini } 5112a64d13efSStefano Zampini } 5113a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 5114a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5115a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 51164641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 51174641a718SStefano Zampini aux_array2[j++] = i; 5118a64d13efSStefano Zampini } 5119a64d13efSStefano Zampini } 5120a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5121a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 5122a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 5123a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 5124a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 5125a64d13efSStefano Zampini 51268eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 5127785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 5128a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 51294641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 51304641a718SStefano Zampini aux_array1[j++] = i; 5131a64d13efSStefano Zampini } 5132a64d13efSStefano Zampini } 5133a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 5134a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 5135a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 5136a64d13efSStefano Zampini } 51374641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 51383a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5139d62866d3SStefano Zampini } else { 5140df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 51416816873aSStefano Zampini IS tis; 51426816873aSStefano Zampini PetscInt schur_size; 51436816873aSStefano Zampini 5144df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 51456816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 5146df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 51476816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 51486816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 51496816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 51506816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 51516816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 5152d62866d3SStefano Zampini } 5153d62866d3SStefano Zampini } 5154a64d13efSStefano Zampini PetscFunctionReturn(0); 5155a64d13efSStefano Zampini } 5156a64d13efSStefano Zampini 5157304d26faSStefano Zampini 5158684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 5159304d26faSStefano Zampini { 5160304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5161304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 5162304d26faSStefano Zampini PC pc_temp; 5163304d26faSStefano Zampini Mat A_RR; 5164f4ddd8eeSStefano Zampini MatReuse reuse; 5165304d26faSStefano Zampini PetscScalar m_one = -1.0; 5166304d26faSStefano Zampini PetscReal value; 516704708bb6SStefano Zampini PetscInt n_D,n_R; 516835529e7bSStefano Zampini PetscBool check_corr,issbaij; 5169304d26faSStefano Zampini PetscErrorCode ierr; 5170e604994aSStefano Zampini /* prefixes stuff */ 5171312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 5172e604994aSStefano Zampini size_t len; 5173304d26faSStefano Zampini 5174304d26faSStefano Zampini PetscFunctionBegin; 517543371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_LocalSolvers[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 5176e604994aSStefano Zampini /* compute prefixes */ 5177e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 5178e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 5179e604994aSStefano Zampini if (!pcbddc->current_level) { 5180a126751eSBarry Smith ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,sizeof(dir_prefix));CHKERRQ(ierr); 5181a126751eSBarry Smith ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,sizeof(neu_prefix));CHKERRQ(ierr); 5182a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,"pc_bddc_dirichlet_",sizeof(dir_prefix));CHKERRQ(ierr); 5183a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,"pc_bddc_neumann_",sizeof(neu_prefix));CHKERRQ(ierr); 5184e604994aSStefano Zampini } else { 518535529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 5186e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5187e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 5188312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5189312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 5190a126751eSBarry Smith /* Nonstandard use of PetscStrncpy() to only copy a portion of the input string */ 519134d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 519234d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5193a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,"pc_bddc_dirichlet_",sizeof(dir_prefix));CHKERRQ(ierr); 5194a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,"pc_bddc_neumann_",sizeof(neu_prefix));CHKERRQ(ierr); 5195a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,str_level,sizeof(dir_prefix));CHKERRQ(ierr); 5196a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,str_level,sizeof(neu_prefix));CHKERRQ(ierr); 5197e604994aSStefano Zampini } 5198e604994aSStefano Zampini 5199304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 5200684f6988SStefano Zampini if (dirichlet) { 5201d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5202450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 52036080607fSStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 5204450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 5205a3df083aSStefano Zampini Mat A_IIn; 5206a3df083aSStefano Zampini 5207a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 5208a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 5209a3df083aSStefano Zampini pcis->A_II = A_IIn; 5210a3df083aSStefano Zampini } 5211450f8f5eSStefano Zampini } 52123301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 52133301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 5214964fefecSStefano Zampini } 5215ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 5216964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 5217304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 5218cd18cfedSStefano Zampini void (*f)(void) = 0; 5219cd18cfedSStefano Zampini 5220304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 5221304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 5222304d26faSStefano Zampini /* default */ 5223304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 5224e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 52259577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 5226304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 52279577ea80SStefano Zampini if (issbaij) { 52289577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 52299577ea80SStefano Zampini } else { 5230304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 52319577ea80SStefano Zampini } 5232399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->ksp_D,pc->erroriffailure);CHKERRQ(ierr); 5233304d26faSStefano Zampini /* Allow user's customization */ 5234304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 5235cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 5236cd18cfedSStefano Zampini if (f && pcbddc->mat_graph->cloc) { 5237cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5238cd18cfedSStefano Zampini const PetscInt *idxs; 5239cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5240cd18cfedSStefano Zampini 5241cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcis->is_I_local,&nl);CHKERRQ(ierr); 5242cd18cfedSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5243cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5244cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5245cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5246cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5247cd18cfedSStefano Zampini } 5248cd18cfedSStefano Zampini } 5249cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5250cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5251cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5252cd18cfedSStefano Zampini } 5253304d26faSStefano Zampini } 52543007b4efSStefano Zampini ierr = MatSetOptionsPrefix(pcis->A_II,((PetscObject)pcbddc->ksp_D)->prefix);CHKERRQ(ierr); 5255d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 5256b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5257df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5258d62866d3SStefano Zampini 5259df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 5260d5574798SStefano Zampini } 5261304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5262304d26faSStefano Zampini if (!n_D) { 5263304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 5264304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5265304d26faSStefano Zampini } 5266304d26faSStefano Zampini /* set ksp_D into pcis data */ 5267304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 5268304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 5269304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 5270684f6988SStefano Zampini } 5271304d26faSStefano Zampini 5272304d26faSStefano Zampini /* NEUMANN PROBLEM */ 5273684f6988SStefano Zampini A_RR = 0; 5274684f6988SStefano Zampini if (neumann) { 5275d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 527604708bb6SStefano Zampini PetscInt ibs,mbs; 52770aa714b2SStefano Zampini PetscBool issbaij, reuse_neumann_solver; 527804708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 52790aa714b2SStefano Zampini 52800aa714b2SStefano Zampini reuse_neumann_solver = PETSC_FALSE; 52810aa714b2SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 52820aa714b2SStefano Zampini IS iP; 52830aa714b2SStefano Zampini 52840aa714b2SStefano Zampini reuse_neumann_solver = PETSC_TRUE; 52850aa714b2SStefano Zampini ierr = PetscObjectQuery((PetscObject)sub_schurs->A,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 52860aa714b2SStefano Zampini if (iP) reuse_neumann_solver = PETSC_FALSE; 52870aa714b2SStefano Zampini } 5288f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 52898ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 5290f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 5291f4ddd8eeSStefano Zampini PetscInt nn_R; 529281d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 5293f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5294f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 5295f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 5296f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 5297f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5298f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5299f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 5300727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 5301f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5302f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5303f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 5304f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 5305f4ddd8eeSStefano Zampini } 5306f4ddd8eeSStefano Zampini } 5307f4ddd8eeSStefano Zampini /* last check */ 5308d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 5309f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5310f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5311f4ddd8eeSStefano Zampini } 5312f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 5313f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5314f4ddd8eeSStefano Zampini } 5315a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 5316af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 5317af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 531804708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 531904708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 532004708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 532104708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 532204708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 5323af732b37SStefano Zampini } else { 5324511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 53256816873aSStefano Zampini } 532604708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 532704708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 532804708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 532904708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 533004708bb6SStefano Zampini } else { 5331511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 533204708bb6SStefano Zampini } 533304708bb6SStefano Zampini } 5334a00504b5SStefano Zampini /* extract A_RR */ 53350aa714b2SStefano Zampini if (reuse_neumann_solver) { 5336a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5337a00504b5SStefano Zampini 5338a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 533916e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5340a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 534116e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 534216e386b8SStefano Zampini } else { 53437dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 5344a00504b5SStefano Zampini } 5345a00504b5SStefano Zampini } else { 5346a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5347a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 5348a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5349a00504b5SStefano Zampini } 5350a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 53517dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 535216e386b8SStefano Zampini } 53533301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 53543301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 53556816873aSStefano Zampini } 5356f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 5357cd18cfedSStefano Zampini void (*f)(void) = 0; 5358cd18cfedSStefano Zampini 5359304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 5360304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 5361304d26faSStefano Zampini /* default */ 5362304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 5363e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 5364304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 53659577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 53669577ea80SStefano Zampini if (issbaij) { 53679577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 53689577ea80SStefano Zampini } else { 5369304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 53709577ea80SStefano Zampini } 5371399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->ksp_R,pc->erroriffailure);CHKERRQ(ierr); 5372304d26faSStefano Zampini /* Allow user's customization */ 5373304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 5374cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 5375cd18cfedSStefano Zampini if (f && pcbddc->mat_graph->cloc) { 5376cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5377cd18cfedSStefano Zampini const PetscInt *idxs; 5378cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5379cd18cfedSStefano Zampini 5380cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcbddc->is_R_local,&nl);CHKERRQ(ierr); 5381cd18cfedSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5382cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5383cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5384cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5385cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5386cd18cfedSStefano Zampini } 5387cd18cfedSStefano Zampini } 5388cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5389cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5390cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5391cd18cfedSStefano Zampini } 5392304d26faSStefano Zampini } 5393304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5394304d26faSStefano Zampini if (!n_R) { 5395304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 5396304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5397304d26faSStefano Zampini } 53983007b4efSStefano Zampini ierr = MatSetOptionsPrefix(A_RR,((PetscObject)pcbddc->ksp_R)->prefix);CHKERRQ(ierr); 53995cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 5400df4d28bfSStefano Zampini /* Reuse solver if it is present */ 54010aa714b2SStefano Zampini if (reuse_neumann_solver) { 5402df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5403d62866d3SStefano Zampini 5404df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 5405d62866d3SStefano Zampini } 5406684f6988SStefano Zampini } 5407304d26faSStefano Zampini 5408684f6988SStefano Zampini if (pcbddc->dbg_flag) { 5409684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 54101575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5411684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5412684f6988SStefano Zampini } 5413c7017625SStefano Zampini 5414c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 541535529e7bSStefano Zampini check_corr = PETSC_FALSE; 5416c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 5417c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 5418c7017625SStefano Zampini } 5419c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 542035529e7bSStefano Zampini check_corr = PETSC_TRUE; 5421c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 5422c7017625SStefano Zampini } 5423c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 542435529e7bSStefano Zampini check_corr = PETSC_TRUE; 5425c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 5426c7017625SStefano Zampini } 5427c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 5428c7017625SStefano Zampini if (pcbddc->dbg_flag) { 5429684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 54300fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 54310fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 54320fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 54330fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 54340fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 5435e604994aSStefano 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); 543635529e7bSStefano Zampini if (check_corr) { 5437c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 5438c7017625SStefano Zampini } 5439304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5440304d26faSStefano Zampini } 5441684f6988SStefano Zampini if (neumann) { /* Neumann */ 54420fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 54430fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 54440fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 54450fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 54460fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 5447e604994aSStefano 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); 544835529e7bSStefano Zampini if (check_corr) { 5449c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 5450c7017625SStefano Zampini } 5451304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5452304d26faSStefano Zampini } 5453684f6988SStefano Zampini } 54545cbda25cSStefano Zampini /* free Neumann problem's matrix */ 54555cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 545643371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_LocalSolvers[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 5457304d26faSStefano Zampini PetscFunctionReturn(0); 5458304d26faSStefano Zampini } 5459304d26faSStefano Zampini 546080677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 5461674ae819SStefano Zampini { 5462674ae819SStefano Zampini PetscErrorCode ierr; 5463674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5464be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5465b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 5466674ae819SStefano Zampini 5467674ae819SStefano Zampini PetscFunctionBegin; 5468b334f244SStefano Zampini if (!reuse_solver) { 546980677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 547020c7b377SStefano Zampini } 547180677318SStefano Zampini if (!pcbddc->switch_static) { 547280677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 547380677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 547480677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 547520c7b377SStefano Zampini } 5476b334f244SStefano Zampini if (!reuse_solver) { 547780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 547880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 547920c7b377SStefano Zampini } else { 5480df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5481be83ff47SStefano Zampini 5482df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5483df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 548420c7b377SStefano Zampini } 5485be83ff47SStefano Zampini } else { 548680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 548780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 548880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 548980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 549080677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 549180677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 549280677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 549380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 549480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5495674ae819SStefano Zampini } 5496674ae819SStefano Zampini } 5497b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 549880677318SStefano Zampini if (applytranspose) { 549980677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 550080677318SStefano Zampini } else { 550180677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 550280677318SStefano Zampini } 5503be83ff47SStefano Zampini } else { 5504df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5505be83ff47SStefano Zampini 5506be83ff47SStefano Zampini if (applytranspose) { 5507df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5508be83ff47SStefano Zampini } else { 5509df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5510be83ff47SStefano Zampini } 5511be83ff47SStefano Zampini } 551280677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 551380677318SStefano Zampini if (!pcbddc->switch_static) { 5514b334f244SStefano Zampini if (!reuse_solver) { 551580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 551680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5517be83ff47SStefano Zampini } else { 5518df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5519be83ff47SStefano Zampini 5520df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5521df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5522be83ff47SStefano Zampini } 552380677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 552480677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 552580677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 552680677318SStefano Zampini } 552780677318SStefano Zampini } else { 552880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 552980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 553080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 553180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 553280677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 553380677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 553480677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 553580677318SStefano Zampini } 553680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 553780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 553880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 553980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5540674ae819SStefano Zampini } 5541674ae819SStefano Zampini PetscFunctionReturn(0); 5542674ae819SStefano Zampini } 5543674ae819SStefano Zampini 5544dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 5545dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 5546674ae819SStefano Zampini { 5547674ae819SStefano Zampini PetscErrorCode ierr; 5548674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5549674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 5550674ae819SStefano Zampini const PetscScalar zero = 0.0; 5551674ae819SStefano Zampini 5552674ae819SStefano Zampini PetscFunctionBegin; 5553dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 55544fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5555dc359a40SStefano Zampini if (applytranspose) { 5556674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 55578eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 5558dc359a40SStefano Zampini } else { 5559674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 5560674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 556115aaf578SStefano Zampini } 55624fee134fSStefano Zampini } else { 55634fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 55644fee134fSStefano Zampini } 5565efc2fbd9SStefano Zampini 5566efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 55674f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5568efc2fbd9SStefano Zampini PetscScalar *array; 55694f1b2e48SStefano Zampini PetscInt j; 5570efc2fbd9SStefano Zampini 5571efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 55724f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 5573efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5574efc2fbd9SStefano Zampini } 5575efc2fbd9SStefano Zampini 557612edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 557712edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 557812edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 557912edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 558012edc857SStefano Zampini 55819f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 558212edc857SStefano Zampini if (pcbddc->coarse_ksp) { 558351694757SStefano Zampini Mat coarse_mat; 5584964fefecSStefano Zampini Vec rhs,sol; 558551694757SStefano Zampini MatNullSpace nullsp; 558627b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 5587964fefecSStefano Zampini 558827b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 558927b6a85dSStefano Zampini PC coarse_pc; 559027b6a85dSStefano Zampini 559127b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 559227b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 559327b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 559427b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 559527b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 559627b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 55973bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 559827b6a85dSStefano Zampini } 559927b6a85dSStefano Zampini } 5600964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 5601964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 560251694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 560312edc857SStefano Zampini if (applytranspose) { 56049a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 5605964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 56069bfcb8eaSStefano Zampini ierr = MatGetTransposeNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 56079bfcb8eaSStefano Zampini if (nullsp) { 56089bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 56099bfcb8eaSStefano Zampini } 56102701bc32SStefano Zampini } else { 56119bfcb8eaSStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 56121f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 56132701bc32SStefano Zampini PC coarse_pc; 56142701bc32SStefano Zampini 56159bfcb8eaSStefano Zampini if (nullsp) { 56169bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 56179bfcb8eaSStefano Zampini } 56182701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 56192701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 56203e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 56212701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 562212edc857SStefano Zampini } else { 5623964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 56249bfcb8eaSStefano Zampini if (nullsp) { 56259bfcb8eaSStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 56269bfcb8eaSStefano Zampini } 562712edc857SStefano Zampini } 56282701bc32SStefano Zampini } 56291d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 563027b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 563127b6a85dSStefano Zampini PC coarse_pc; 563227b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 563327b6a85dSStefano Zampini 563427b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 563527b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 563627b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 56373bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 563827b6a85dSStefano Zampini } 563912edc857SStefano Zampini } 5640674ae819SStefano Zampini 5641674ae819SStefano Zampini /* Local solution on R nodes */ 56424fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 564380677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 56449f00e9b4SStefano Zampini } 56459f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 56469f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 564712edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5648674ae819SStefano Zampini 56494fee134fSStefano Zampini /* Sum contributions from the two levels */ 56504fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5651dc359a40SStefano Zampini if (applytranspose) { 5652dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5653dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5654dc359a40SStefano Zampini } else { 5655674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 56568eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5657dc359a40SStefano Zampini } 5658efc2fbd9SStefano Zampini /* store p0 */ 56594f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5660efc2fbd9SStefano Zampini PetscScalar *array; 56614f1b2e48SStefano Zampini PetscInt j; 5662efc2fbd9SStefano Zampini 5663efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 56644f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 5665efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5666efc2fbd9SStefano Zampini } 56674fee134fSStefano Zampini } else { /* expand the coarse solution */ 56684fee134fSStefano Zampini if (applytranspose) { 56694fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 56704fee134fSStefano Zampini } else { 56714fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 56724fee134fSStefano Zampini } 56734fee134fSStefano Zampini } 5674674ae819SStefano Zampini PetscFunctionReturn(0); 5675674ae819SStefano Zampini } 5676674ae819SStefano Zampini 567712edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 5678674ae819SStefano Zampini { 5679674ae819SStefano Zampini PetscErrorCode ierr; 5680674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 568158da7f69SStefano Zampini PetscScalar *array; 568212edc857SStefano Zampini Vec from,to; 5683674ae819SStefano Zampini 5684674ae819SStefano Zampini PetscFunctionBegin; 568512edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 568612edc857SStefano Zampini from = pcbddc->coarse_vec; 568712edc857SStefano Zampini to = pcbddc->vec1_P; 568812edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 568912edc857SStefano Zampini Vec tvec; 569058da7f69SStefano Zampini 569158da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 569258da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 569312edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 569458da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 569558da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 569658da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 569712edc857SStefano Zampini } 569812edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 569912edc857SStefano Zampini from = pcbddc->vec1_P; 570012edc857SStefano Zampini to = pcbddc->coarse_vec; 570112edc857SStefano Zampini } 570212edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 5703674ae819SStefano Zampini PetscFunctionReturn(0); 5704674ae819SStefano Zampini } 5705674ae819SStefano Zampini 570612edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 5707674ae819SStefano Zampini { 5708674ae819SStefano Zampini PetscErrorCode ierr; 5709674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 571058da7f69SStefano Zampini PetscScalar *array; 571112edc857SStefano Zampini Vec from,to; 5712674ae819SStefano Zampini 5713674ae819SStefano Zampini PetscFunctionBegin; 571412edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 571512edc857SStefano Zampini from = pcbddc->coarse_vec; 571612edc857SStefano Zampini to = pcbddc->vec1_P; 571712edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 571812edc857SStefano Zampini from = pcbddc->vec1_P; 571912edc857SStefano Zampini to = pcbddc->coarse_vec; 572012edc857SStefano Zampini } 572112edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 572212edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 572312edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 572412edc857SStefano Zampini Vec tvec; 572558da7f69SStefano Zampini 572612edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 572758da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 572858da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 572958da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 573058da7f69SStefano Zampini } 573158da7f69SStefano Zampini } else { 573258da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 573358da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 573412edc857SStefano Zampini } 573512edc857SStefano Zampini } 5736674ae819SStefano Zampini PetscFunctionReturn(0); 5737674ae819SStefano Zampini } 5738674ae819SStefano Zampini 5739984c4197SStefano Zampini /* uncomment for testing purposes */ 5740984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 5741674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 5742674ae819SStefano Zampini { 5743674ae819SStefano Zampini PetscErrorCode ierr; 5744674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5745674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5746674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5747984c4197SStefano Zampini /* one and zero */ 5748984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 5749984c4197SStefano Zampini /* space to store constraints and their local indices */ 57509162d606SStefano Zampini PetscScalar *constraints_data; 57519162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 57529162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 57539162d606SStefano Zampini PetscInt *constraints_n; 5754984c4197SStefano Zampini /* iterators */ 5755b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 5756984c4197SStefano Zampini /* BLAS integers */ 5757e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 5758e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 5759c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 5760727cdba6SStefano Zampini /* reuse */ 57610e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 57620e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 5763984c4197SStefano Zampini /* change of basis */ 5764b3d85658SStefano Zampini PetscBool qr_needed; 57659162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 5766984c4197SStefano Zampini /* auxiliary stuff */ 576764efe560SStefano Zampini PetscInt *nnz,*is_indices; 57688a0068c3SStefano Zampini PetscInt ncc; 5769984c4197SStefano Zampini /* some quantities */ 577045a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 5771a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 577257715f18SStefano Zampini PetscReal tol; /* tolerance for retaining eigenmodes */ 5773984c4197SStefano Zampini 5774674ae819SStefano Zampini PetscFunctionBegin; 577557715f18SStefano Zampini tol = PetscSqrtReal(PETSC_SMALL); 57768e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 57778e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 57788e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 577916909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 5780088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 5781088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 57820e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 57830e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 57840e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 57850e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 57860e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 5787088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5788cf5a6209SStefano Zampini 5789cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 57909162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 5791cf5a6209SStefano Zampini MatNullSpace nearnullsp; 5792cf5a6209SStefano Zampini const Vec *nearnullvecs; 5793cf5a6209SStefano Zampini Vec *localnearnullsp; 5794cf5a6209SStefano Zampini PetscScalar *array; 5795cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 5796cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 5797674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 5798b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 5799674ae819SStefano Zampini PetscScalar *work; 5800674ae819SStefano Zampini PetscReal *singular_vals; 5801674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5802674ae819SStefano Zampini PetscReal *rwork; 5803674ae819SStefano Zampini #endif 5804674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5805674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 5806674ae819SStefano Zampini #else 5807964fefecSStefano Zampini PetscBLASInt dummy_int=1; 5808964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 5809674ae819SStefano Zampini #endif 5810674ae819SStefano Zampini 5811674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 5812d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 5813e4d548c7SStefano Zampini /* print some info */ 58145c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 5815e4d548c7SStefano Zampini PetscInt nv; 5816e4d548c7SStefano Zampini 5817c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5818e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 5819e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5820e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 58216080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%D)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 58226080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%D)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 58236080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%D)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 5824e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5825e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5826e4d548c7SStefano Zampini } 5827e4d548c7SStefano Zampini 5828d06fc5fdSStefano Zampini /* free unneeded index sets */ 5829d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 5830d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 5831674ae819SStefano Zampini } 5832d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 5833d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5834d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5835d06fc5fdSStefano Zampini } 5836d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5837d06fc5fdSStefano Zampini n_ISForEdges = 0; 5838d06fc5fdSStefano Zampini } 5839d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 5840d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5841d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5842d06fc5fdSStefano Zampini } 5843d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5844d06fc5fdSStefano Zampini n_ISForFaces = 0; 5845d06fc5fdSStefano Zampini } 584670022509SStefano Zampini 5847674ae819SStefano Zampini /* check if near null space is attached to global mat */ 5848674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 5849674ae819SStefano Zampini if (nearnullsp) { 5850674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 5851f4ddd8eeSStefano Zampini /* remove any stored info */ 5852f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 5853f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5854f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 5855f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 5856f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 5857473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5858f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 5859f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 5860f4ddd8eeSStefano Zampini } 5861984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 5862984c4197SStefano Zampini nnsp_size = 0; 5863674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 5864674ae819SStefano Zampini } 5865984c4197SStefano Zampini /* get max number of constraints on a single cc */ 5866984c4197SStefano Zampini max_constraints = nnsp_size; 5867984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 5868984c4197SStefano Zampini 5869674ae819SStefano Zampini /* 5870674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 58719162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 58729162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 58739162d606SStefano Zampini There can be multiple constraints per connected component 5874674ae819SStefano Zampini */ 5875674ae819SStefano Zampini n_vertices = 0; 5876674ae819SStefano Zampini if (ISForVertices) { 5877674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 5878674ae819SStefano Zampini } 58799162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 58809162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 58819162d606SStefano Zampini 58829162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 58839162d606SStefano Zampini total_counts *= max_constraints; 5884674ae819SStefano Zampini total_counts += n_vertices; 58854641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 58869162d606SStefano Zampini 5887674ae819SStefano Zampini total_counts = 0; 5888674ae819SStefano Zampini max_size_of_constraint = 0; 5889674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 58909162d606SStefano Zampini IS used_is; 5891674ae819SStefano Zampini if (i<n_ISForEdges) { 58929162d606SStefano Zampini used_is = ISForEdges[i]; 5893674ae819SStefano Zampini } else { 58949162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 5895674ae819SStefano Zampini } 58969162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 5897674ae819SStefano Zampini total_counts += j; 5898674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 5899674ae819SStefano Zampini } 59009162d606SStefano 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); 59019162d606SStefano Zampini 5902984c4197SStefano Zampini /* get local part of global near null space vectors */ 5903785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 5904984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5905984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 5906e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5907e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5908984c4197SStefano Zampini } 5909674ae819SStefano Zampini 5910242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 5911242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 5912a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 5913242a89d7SStefano Zampini 5914984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 5915a773dcb8SStefano Zampini if (!skip_lapack) { 5916674ae819SStefano Zampini PetscScalar temp_work; 5917911cabfeSStefano Zampini 5918674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5919984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 5920785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 5921785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 5922785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 5923674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5924785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 5925674ae819SStefano Zampini #endif 5926674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5927c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 5928c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 5929674ae819SStefano Zampini lwork = -1; 5930674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5931674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5932c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 5933674ae819SStefano Zampini #else 5934c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 5935674ae819SStefano Zampini #endif 5936674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5937984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 5938674ae819SStefano Zampini #else /* on missing GESVD */ 5939674ae819SStefano Zampini /* SVD */ 5940674ae819SStefano Zampini PetscInt max_n,min_n; 5941674ae819SStefano Zampini max_n = max_size_of_constraint; 5942984c4197SStefano Zampini min_n = max_constraints; 5943984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 5944674ae819SStefano Zampini min_n = max_size_of_constraint; 5945984c4197SStefano Zampini max_n = max_constraints; 5946674ae819SStefano Zampini } 5947785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 5948674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5949785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 5950674ae819SStefano Zampini #endif 5951674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5952674ae819SStefano Zampini lwork = -1; 5953e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 5954e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 5955b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 5956674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5957674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 59589162d606SStefano 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)); 5959674ae819SStefano Zampini #else 59609162d606SStefano 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)); 5961674ae819SStefano Zampini #endif 5962674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5963984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 5964984c4197SStefano Zampini #endif /* on missing GESVD */ 5965674ae819SStefano Zampini /* Allocate optimal workspace */ 5966674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 5967854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 5968674ae819SStefano Zampini } 5969674ae819SStefano Zampini /* Now we can loop on constraining sets */ 5970674ae819SStefano Zampini total_counts = 0; 59719162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 59729162d606SStefano Zampini constraints_data_ptr[0] = 0; 5973674ae819SStefano Zampini /* vertices */ 59749162d606SStefano Zampini if (n_vertices) { 5975674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 59769162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 5977674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 59789162d606SStefano Zampini constraints_n[total_counts] = 1; 59799162d606SStefano Zampini constraints_data[total_counts] = 1.0; 59809162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 59819162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 5982674ae819SStefano Zampini total_counts++; 5983674ae819SStefano Zampini } 5984674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5985674ae819SStefano Zampini n_vertices = total_counts; 5986674ae819SStefano Zampini } 5987984c4197SStefano Zampini 5988674ae819SStefano Zampini /* edges and faces */ 59899162d606SStefano Zampini total_counts_cc = total_counts; 5990911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 59919162d606SStefano Zampini IS used_is; 59929162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 59939162d606SStefano Zampini 5994911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 59959162d606SStefano Zampini used_is = ISForEdges[ncc]; 5996984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 5997674ae819SStefano Zampini } else { 59989162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 5999984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 6000674ae819SStefano Zampini } 6001674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 60029162d606SStefano Zampini 60039162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 60049162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6005984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 6006984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 6007674ae819SStefano Zampini if (nnsp_has_cnst) { 60085b08dc53SStefano Zampini PetscScalar quad_value; 60099162d606SStefano Zampini 60109162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 60119162d606SStefano Zampini idxs_copied = PETSC_TRUE; 60129162d606SStefano Zampini 6013a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 6014674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 6015a773dcb8SStefano Zampini } else { 6016a773dcb8SStefano Zampini quad_value = 1.0; 6017a773dcb8SStefano Zampini } 6018674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 60199162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 6020674ae819SStefano Zampini } 60219162d606SStefano Zampini temp_constraints++; 6022674ae819SStefano Zampini total_counts++; 6023674ae819SStefano Zampini } 6024674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 6025984c4197SStefano Zampini PetscReal real_value; 60269162d606SStefano Zampini PetscScalar *ptr_to_data; 60279162d606SStefano Zampini 6028984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 60299162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 6030674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 60319162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 6032674ae819SStefano Zampini } 6033984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 6034984c4197SStefano Zampini /* check if array is null on the connected component */ 6035e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 60369162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 603757715f18SStefano Zampini if (real_value > tol*size_of_constraint) { /* keep indices and values */ 6038674ae819SStefano Zampini temp_constraints++; 6039674ae819SStefano Zampini total_counts++; 60409162d606SStefano Zampini if (!idxs_copied) { 60419162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 60429162d606SStefano Zampini idxs_copied = PETSC_TRUE; 6043674ae819SStefano Zampini } 6044674ae819SStefano Zampini } 60459162d606SStefano Zampini } 60469162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 604745a1bb75SStefano Zampini valid_constraints = temp_constraints; 6048eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 6049a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 60509162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 60519162d606SStefano Zampini 60529162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 6053a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 60549162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 6055a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 60569162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 6057a773dcb8SStefano Zampini } else { /* perform SVD */ 60589162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 6059674ae819SStefano Zampini 6060674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 6061984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 6062984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 6063984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 6064984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 6065984c4197SStefano Zampini from that computed using LAPACKgesvd 6066984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 6067984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 6068984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 6069674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 6070e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6071984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6072674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 6073674ae819SStefano Zampini for (k=0;k<j+1;k++) { 60749162d606SStefano 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)); 6075674ae819SStefano Zampini } 6076674ae819SStefano Zampini } 6077e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 6078e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6079e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 6080674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 6081c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 6082674ae819SStefano Zampini #else 6083c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 6084674ae819SStefano Zampini #endif 6085674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6086984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 6087984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 6088674ae819SStefano Zampini j = 0; 6089984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 6090674ae819SStefano Zampini total_counts = total_counts-j; 609145a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 6092e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 6093c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 6094c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6095c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 6096c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6097c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 6098c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6099674ae819SStefano Zampini if (j<temp_constraints) { 6100984c4197SStefano Zampini PetscInt ii; 6101984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 6102674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 61039162d606SStefano 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)); 6104674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6105984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 6106674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 61079162d606SStefano 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]; 6108674ae819SStefano Zampini } 6109674ae819SStefano Zampini } 6110674ae819SStefano Zampini } 6111674ae819SStefano Zampini #else /* on missing GESVD */ 6112e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 6113e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6114b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6115674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6116674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 61179162d606SStefano 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)); 6118674ae819SStefano Zampini #else 61199162d606SStefano 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)); 6120674ae819SStefano Zampini #endif 6121984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 6122674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6123984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 6124e310c8b4SStefano Zampini k = temp_constraints; 6125e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 6126674ae819SStefano Zampini j = 0; 6127e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 612845a1bb75SStefano Zampini valid_constraints = k-j; 6129911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 6130984c4197SStefano Zampini #endif /* on missing GESVD */ 6131674ae819SStefano Zampini } 6132a773dcb8SStefano Zampini } 61339162d606SStefano Zampini /* update pointers information */ 61349162d606SStefano Zampini if (valid_constraints) { 61359162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 61369162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 61379162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 61389162d606SStefano Zampini /* set change_of_basis flag */ 613945a1bb75SStefano Zampini if (boolforchange) { 6140b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 61419162d606SStefano Zampini } 6142b3d85658SStefano Zampini total_counts_cc++; 614345a1bb75SStefano Zampini } 614445a1bb75SStefano Zampini } 6145984c4197SStefano Zampini /* free workspace */ 61468f1c130eSStefano Zampini if (!skip_lapack) { 6147984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 6148984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6149984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 6150984c4197SStefano Zampini #endif 6151984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 6152984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 6153984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 6154984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 6155984c4197SStefano Zampini #endif 6156984c4197SStefano Zampini } 6157984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 6158984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 6159984c4197SStefano Zampini } 6160984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 6161cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 6162cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 6163cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 6164cf5a6209SStefano Zampini } 6165cf5a6209SStefano Zampini if (n_ISForFaces) { 6166cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 6167cf5a6209SStefano Zampini } 6168cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 6169cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 6170cf5a6209SStefano Zampini } 6171cf5a6209SStefano Zampini if (n_ISForEdges) { 6172cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 6173cf5a6209SStefano Zampini } 6174cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 617508122e43SStefano Zampini } else { 617608122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 6177984c4197SStefano Zampini 617808122e43SStefano Zampini total_counts = 0; 617908122e43SStefano Zampini n_vertices = 0; 6180d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 6181d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 618208122e43SStefano Zampini } 618308122e43SStefano Zampini max_constraints = 0; 61849162d606SStefano Zampini total_counts_cc = 0; 618508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 618608122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 61879162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 618808122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 618908122e43SStefano Zampini } 61909162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 61919162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 61929162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 61939162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 619474d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 61959162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 61969162d606SStefano Zampini total_counts_cc = 0; 61979162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 61989162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 61999162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 620008122e43SStefano Zampini } 620108122e43SStefano Zampini } 620208122e43SStefano Zampini 62038bec7fa6SStefano Zampini max_size_of_constraint = 0; 62049162d606SStefano 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]); 62059162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 620608122e43SStefano Zampini /* Change of basis */ 6207b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 620808122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 620908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 621008122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 6211b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 621208122e43SStefano Zampini } 621308122e43SStefano Zampini } 621408122e43SStefano Zampini } 621508122e43SStefano Zampini } 6216984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 62174f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 621808122e43SStefano Zampini 62199162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 62209162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 62216080607fSStefano 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",constraints_idxs_ptr[total_counts_cc],i); 6222674ae819SStefano Zampini 6223674ae819SStefano Zampini /* Create constraint matrix */ 6224674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 622516f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 6226984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 6227984c4197SStefano Zampini 6228984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 6229a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 6230*5a52fde0SStefano Zampini qr_needed = pcbddc->use_qr_single; 623174d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 6232984c4197SStefano Zampini total_primal_vertices=0; 6233b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 62349162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 62359162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 623672b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 62379162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 6238b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 623964efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 62409162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 62419162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 6242a717540cSStefano Zampini } 6243b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 624491af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 6245a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 6246a717540cSStefano Zampini qr_needed = PETSC_TRUE; 6247a717540cSStefano Zampini } 6248fa434743SStefano Zampini } else { 6249b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 6250fa434743SStefano Zampini } 6251a717540cSStefano Zampini } 6252b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 6253b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 6254674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 625570022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 62564f1b2e48SStefano 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); 62570e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 62580e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 6259984c4197SStefano Zampini 6260984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 626174d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 6262785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 6263984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 626474d5cdf7SStefano Zampini 6265984c4197SStefano Zampini j = total_primal_vertices; 626674d5cdf7SStefano Zampini total_counts = total_primal_vertices; 6267b3d85658SStefano Zampini cum = total_primal_vertices; 62689162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 62694641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 6270b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 6271b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 6272b3d85658SStefano Zampini cum++; 62739162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 627474d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 627574d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 627674d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 627774d5cdf7SStefano Zampini } 62789162d606SStefano Zampini j += constraints_n[i]; 6279674ae819SStefano Zampini } 6280674ae819SStefano Zampini } 6281674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 6282e1b21442SStefano Zampini ierr = MatSetOption(pcbddc->ConstraintMatrix,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 6283674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 6284088faed8SStefano Zampini 6285674ae819SStefano Zampini /* set values in constraint matrix */ 6286984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 62870e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6288674ae819SStefano Zampini } 6289984c4197SStefano Zampini total_counts = total_primal_vertices; 62909162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 62914641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 62929162d606SStefano Zampini PetscInt *cols; 62939162d606SStefano Zampini 62949162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 62959162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 62969162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 62979162d606SStefano Zampini PetscInt row = total_counts+k; 62989162d606SStefano Zampini PetscScalar *vals; 62999162d606SStefano Zampini 63009162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 63019162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 63029162d606SStefano Zampini } 63039162d606SStefano Zampini total_counts += constraints_n[i]; 6304674ae819SStefano Zampini } 6305674ae819SStefano Zampini } 6306674ae819SStefano Zampini /* assembling */ 6307674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6308674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 63093272d46bSStefano Zampini ierr = MatViewFromOptions(pcbddc->ConstraintMatrix,NULL,"-pc_bddc_constraint_mat_view");CHKERRQ(ierr); 6310088faed8SStefano Zampini 6311674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 6312674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 6313026de310SStefano Zampini /* dual and primal dofs on a single cc */ 6314984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 6315984c4197SStefano Zampini /* working stuff for GEQRF */ 6316*5a52fde0SStefano Zampini PetscScalar *qr_basis = NULL,*qr_tau = NULL,*qr_work = NULL,lqr_work_t; 6317984c4197SStefano Zampini PetscBLASInt lqr_work; 6318984c4197SStefano Zampini /* working stuff for UNGQR */ 6319*5a52fde0SStefano Zampini PetscScalar *gqr_work = NULL,lgqr_work_t; 6320984c4197SStefano Zampini PetscBLASInt lgqr_work; 6321984c4197SStefano Zampini /* working stuff for TRTRS */ 6322*5a52fde0SStefano Zampini PetscScalar *trs_rhs = NULL; 63233f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 6324984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 6325984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 6326984c4197SStefano Zampini PetscScalar *start_vals; 6327984c4197SStefano Zampini /* working stuff for values insertion */ 63284641a718SStefano Zampini PetscBT is_primal; 632964efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 6330906d46d4SStefano Zampini /* matrix sizes */ 6331906d46d4SStefano Zampini PetscInt global_size,local_size; 6332906d46d4SStefano Zampini /* temporary change of basis */ 6333906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 6334cf5a6209SStefano Zampini /* extra space for debugging */ 6335*5a52fde0SStefano Zampini PetscScalar *dbg_work = NULL; 6336984c4197SStefano Zampini 6337906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 6338906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 633916f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 6340bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 6341906d46d4SStefano Zampini /* nonzeros for local mat */ 6342bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 63431dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6344bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 63451dd7afcfSStefano Zampini } else { 63461dd7afcfSStefano Zampini const PetscInt *ii; 63471dd7afcfSStefano Zampini PetscInt n; 63481dd7afcfSStefano Zampini PetscBool flg_row; 63491dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 63501dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 63511dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 63521dd7afcfSStefano Zampini } 63539162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 6354a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 63559162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 6356a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 63579162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 6358a717540cSStefano Zampini } else { 63599162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 63609162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 6361a717540cSStefano Zampini } 6362a717540cSStefano Zampini } 6363a717540cSStefano Zampini } 6364906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 6365e1b21442SStefano Zampini ierr = MatSetOption(localChangeOfBasisMatrix,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_TRUE);CHKERRQ(ierr); 6366bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 63671dd7afcfSStefano Zampini /* Set interior change in the matrix */ 63681dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6369bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 6370906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 6371a717540cSStefano Zampini } 63721dd7afcfSStefano Zampini } else { 63731dd7afcfSStefano Zampini const PetscInt *ii,*jj; 63741dd7afcfSStefano Zampini PetscScalar *aa; 63751dd7afcfSStefano Zampini PetscInt n; 63761dd7afcfSStefano Zampini PetscBool flg_row; 63771dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 63781dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 63791dd7afcfSStefano Zampini for (i=0;i<n;i++) { 63801dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 63811dd7afcfSStefano Zampini } 63821dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 63831dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 63841dd7afcfSStefano Zampini } 6385a717540cSStefano Zampini 6386a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6387a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6388a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6389a717540cSStefano Zampini } 6390a717540cSStefano Zampini 6391a717540cSStefano Zampini 6392a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 6393a717540cSStefano Zampini /* 6394a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 6395a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 6396a717540cSStefano Zampini 6397a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 6398a717540cSStefano Zampini 6399a6b551f4SStefano 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) 6400a6b551f4SStefano Zampini 6401a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 6402a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 6403a717540cSStefano Zampini | ... | 6404a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 6405a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 6406a717540cSStefano Zampini 6407a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 6408a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 6409a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 6410a6b551f4SStefano Zampini 6411a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 6412a717540cSStefano Zampini */ 6413*5a52fde0SStefano Zampini if (qr_needed && max_size_of_constraint) { 6414984c4197SStefano Zampini /* space to store Q */ 6415854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 64164e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 64174e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 6418984c4197SStefano Zampini /* first we issue queries for optimal work */ 64193f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 64203f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 64213f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6422984c4197SStefano Zampini lqr_work = -1; 64233f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 6424984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 6425984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 6426785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 6427984c4197SStefano Zampini lgqr_work = -1; 64283f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 64293f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 64303f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 64313f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 64323f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 6433c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 6434c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to ORGQR/UNGQR Lapack routine %d",(int)lierr); 6435984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 6436785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 6437984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 6438785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 6439a717540cSStefano Zampini /* allocating workspace for check */ 6440a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6441cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 6442a717540cSStefano Zampini } 6443a717540cSStefano Zampini } 6444984c4197SStefano Zampini /* array to store whether a node is primal or not */ 64454641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 6446473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 64470e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 64486080607fSStefano Zampini if (i != total_primal_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D",total_primal_vertices,i); 644939e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 645039e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 645139e2fb2aSStefano Zampini } 645239e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 6453984c4197SStefano Zampini 6454a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 64559162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 64569162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 64574641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 6458984c4197SStefano Zampini /* get constraint info */ 64599162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 6460984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 6461984c4197SStefano Zampini 6462984c4197SStefano Zampini if (pcbddc->dbg_flag) { 64636080607fSStefano 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); 6464674ae819SStefano Zampini } 6465984c4197SStefano Zampini 6466fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 6467a717540cSStefano Zampini 6468a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 6469a717540cSStefano Zampini if (pcbddc->dbg_flag) { 64709162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6471a717540cSStefano Zampini } 6472984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 64739162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6474984c4197SStefano Zampini 6475984c4197SStefano Zampini /* compute QR decomposition of constraints */ 64763f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 64773f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 64783f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6479674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 64803f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 6481984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 6482674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6483984c4197SStefano Zampini 6484984c4197SStefano Zampini /* explictly compute R^-T */ 6485984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 6486984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 64873f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 64883f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 64893f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 64903f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 6491984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 64923f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 6493984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 6494984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6495984c4197SStefano Zampini 6496a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 64973f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 64983f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 64993f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 65003f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6501984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6502c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 6503c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in ORGQR/UNGQR Lapack routine %d",(int)lierr); 6504984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6505984c4197SStefano Zampini 6506984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 6507984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 6508984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 65093f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 65103f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 65113f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 65123f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 65133f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 65143f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6515984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 65169162d606SStefano 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)); 6517984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 65189162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6519984c4197SStefano Zampini 6520984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 65219162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 6522984c4197SStefano Zampini /* insert cols for primal dofs */ 6523984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 6524984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 65259162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6526906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6527984c4197SStefano Zampini } 6528984c4197SStefano Zampini /* insert cols for dual dofs */ 6529984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 65309162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 6531984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 65329162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6533906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6534984c4197SStefano Zampini j++; 6535674ae819SStefano Zampini } 6536674ae819SStefano Zampini } 6537984c4197SStefano Zampini 6538984c4197SStefano Zampini /* check change of basis */ 6539984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6540984c4197SStefano Zampini PetscInt ii,jj; 6541984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 6542c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 6543c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6544c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 6545c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6546c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 6547c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 6548984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6549cf5a6209SStefano 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)); 6550984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6551984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6552984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6553cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 6554c068d9bbSLisandro Dalcin if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-(PetscReal)1) > 1.e-12) valid_qr = PETSC_FALSE; 6555674ae819SStefano Zampini } 6556674ae819SStefano Zampini } 6557984c4197SStefano Zampini if (!valid_qr) { 655822d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 6559984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6560984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6561cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 65626080607fSStefano Zampini ierr = 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]));CHKERRQ(ierr); 6563674ae819SStefano Zampini } 6564c068d9bbSLisandro Dalcin if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-(PetscReal)1) > 1.e-12) { 65656080607fSStefano Zampini ierr = 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]));CHKERRQ(ierr); 6566984c4197SStefano Zampini } 6567984c4197SStefano Zampini } 6568984c4197SStefano Zampini } 6569674ae819SStefano Zampini } else { 657022d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 6571674ae819SStefano Zampini } 6572674ae819SStefano Zampini } 6573a717540cSStefano Zampini } else { /* simple transformation block */ 6574a717540cSStefano Zampini PetscInt row,col; 6575a6b551f4SStefano Zampini PetscScalar val,norm; 6576a6b551f4SStefano Zampini 6577a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 65789162d606SStefano 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)); 6579a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 65809162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 65819162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6582bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 65839162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 6584906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 65859162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 6586a717540cSStefano Zampini } else { 6587a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 65889162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6589a717540cSStefano Zampini if (row != col) { 65909162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 6591a717540cSStefano Zampini } else { 65929162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 6593a717540cSStefano Zampini } 6594906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 6595a717540cSStefano Zampini } 6596a717540cSStefano Zampini } 6597a717540cSStefano Zampini } 659898a51de6SStefano Zampini if (pcbddc->dbg_flag) { 659922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 6600a717540cSStefano Zampini } 6601674ae819SStefano Zampini } 6602984c4197SStefano Zampini } else { 6603984c4197SStefano Zampini if (pcbddc->dbg_flag) { 66046080607fSStefano 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); 6605674ae819SStefano Zampini } 6606674ae819SStefano Zampini } 6607674ae819SStefano Zampini } 6608a717540cSStefano Zampini 6609a717540cSStefano Zampini /* free workspace */ 6610a717540cSStefano Zampini if (qr_needed) { 6611984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6612cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 6613984c4197SStefano Zampini } 6614984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 6615984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 6616984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 6617984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 6618984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 6619674ae819SStefano Zampini } 6620a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 6621906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6622906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6623906d46d4SStefano Zampini 6624906d46d4SStefano Zampini /* assembling of global change of variable */ 662588c03ad3SStefano Zampini if (!pcbddc->fake_change) { 6626bbb9e6c6SStefano Zampini Mat tmat; 662716f15bc4SStefano Zampini PetscInt bs; 662816f15bc4SStefano Zampini 6629906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 6630906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 6631bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 6632bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 6633487b449aSStefano Zampini ierr = MatAssemblyBegin(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6634487b449aSStefano Zampini ierr = MatAssemblyEnd(tmat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6635bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6636bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 663716f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 663816f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 6639906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 6640bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 6641487b449aSStefano Zampini ierr = MatConvert(tmat,MATAIJ,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6642bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6643bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6644bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6645e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6646e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6647bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 6648bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 664988c03ad3SStefano Zampini 6650906d46d4SStefano Zampini /* check */ 6651906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 6652906d46d4SStefano Zampini PetscReal error; 6653906d46d4SStefano Zampini Vec x,x_change; 6654906d46d4SStefano Zampini 6655906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 6656906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 6657906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 6658906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 6659e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6660e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6661bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 6662e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6663e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6664906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 6665906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 6666906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 6667637e8532SStefano Zampini if (error > PETSC_SMALL) { 66686080607fSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e",error); 6669637e8532SStefano Zampini } 6670906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 6671906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 6672906d46d4SStefano Zampini } 6673b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 6674b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 6675b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6676bf3a8328SStefano Zampini 667713903a91SSatish Balay 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"); 6678b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 6679ac632422SStefano Zampini Mat S_new,tmat; 6680bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 6681bbb9e6c6SStefano Zampini 6682bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 66837dae84e0SHong Zhang ierr = MatCreateSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 6684bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6685bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 6686bf3a8328SStefano Zampini IS is_V; 6687b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 6688b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 6689b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 6690b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 6691b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 6692bf3a8328SStefano Zampini } 6693bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 6694ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6695b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 6696ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6697bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6698bf3a8328SStefano Zampini const PetscScalar *array; 6699bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 6700bf3a8328SStefano Zampini PetscInt i,n_V; 6701bf3a8328SStefano Zampini 6702b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6703b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 6704b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6705b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6706b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 6707b087196eSStefano Zampini for (i=0;i<n_V;i++) { 6708b087196eSStefano Zampini PetscScalar val; 6709b087196eSStefano Zampini PetscInt idx; 6710b087196eSStefano Zampini 6711b087196eSStefano Zampini idx = idxs_V[i]; 6712b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 6713b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 6714b087196eSStefano Zampini } 6715b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6716b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6717bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 6718bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6719bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6720bf3a8328SStefano Zampini } 6721ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 6722ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6723ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 6724ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6725b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 6726ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6727bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6728b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6729bf3a8328SStefano Zampini } 6730ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 6731ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6732ac632422SStefano Zampini } 6733b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 673488c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6735b96c3477SStefano Zampini } 6736c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 6737b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 6738c9db6a07SStefano Zampini PetscInt i; 6739c9db6a07SStefano Zampini 6740c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 6741c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 6742c9db6a07SStefano Zampini } 6743c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 6744c9db6a07SStefano Zampini } 6745b96c3477SStefano Zampini } 674616909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 674716909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 674816909a7fSStefano Zampini } else { 6749906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 675016909a7fSStefano Zampini } 67511dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 675227b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 675372b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 675472b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 675572b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 675672b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 675772b8c272SStefano Zampini } 67581dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 675927b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 6760b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 6761b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 6762906d46d4SStefano Zampini } else { 67631dd7afcfSStefano Zampini Mat benign_global = NULL; 676427b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 67651dd7afcfSStefano Zampini Mat M; 67661dd7afcfSStefano Zampini 67679e9b7b1fSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 67689e9b7b1fSStefano Zampini ierr = VecCopy(matis->counter,pcis->vec1_N);CHKERRQ(ierr); 67699e9b7b1fSStefano Zampini ierr = VecReciprocal(pcis->vec1_N);CHKERRQ(ierr); 67709e9b7b1fSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&benign_global);CHKERRQ(ierr); 67719e9b7b1fSStefano Zampini if (pcbddc->benign_change) { 67721dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 67731dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 6774906d46d4SStefano Zampini } else { 67759e9b7b1fSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&M);CHKERRQ(ierr); 67769e9b7b1fSStefano Zampini ierr = MatDiagonalSet(M,pcis->vec1_N,INSERT_VALUES);CHKERRQ(ierr); 6777906d46d4SStefano Zampini } 67789e9b7b1fSStefano Zampini ierr = MatISSetLocalMat(benign_global,M);CHKERRQ(ierr); 67799e9b7b1fSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 67809e9b7b1fSStefano Zampini ierr = MatAssemblyBegin(benign_global,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 67819e9b7b1fSStefano Zampini ierr = MatAssemblyEnd(benign_global,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 67821dd7afcfSStefano Zampini } 67831dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 67841dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 67851dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 678627b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 67871dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 67881dd7afcfSStefano Zampini } 67891dd7afcfSStefano Zampini } 679016909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 679116909a7fSStefano Zampini IS is_global; 679216909a7fSStefano Zampini const PetscInt *gidxs; 679316909a7fSStefano Zampini 679416909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 679516909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 679616909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 67977dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 679816909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 679916909a7fSStefano Zampini } 68001dd7afcfSStefano Zampini } 68011dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 68021dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 6803b9b85e73SStefano Zampini } 6804a717540cSStefano Zampini 680572b8c272SStefano Zampini if (!pcbddc->fake_change) { 68064f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 68074f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 68084f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 68094f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 6810019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 6811019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 6812019a44ceSStefano Zampini pcbddc->local_primal_size++; 6813019a44ceSStefano Zampini } 6814019a44ceSStefano Zampini 6815019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 6816727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 6817727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 68189f47a83aSStefano 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); 6819c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 68200e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 68219f47a83aSStefano 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); 6822727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 6823727cdba6SStefano Zampini } 68240e6343abSStefano Zampini } 6825727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 6826b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 682772b8c272SStefano Zampini } 682872b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 6829727cdba6SStefano Zampini 6830a717540cSStefano Zampini /* flush dbg viewer */ 6831b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 6832b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6833b8ffe317SStefano Zampini } 6834a717540cSStefano Zampini 6835e310c8b4SStefano Zampini /* free workspace */ 6836a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 68374641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 683808122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 68399162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 68409162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 684108122e43SStefano Zampini } else { 68429162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 68439162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 68449162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 684508122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 684608122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 68479162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 68489162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 684908122e43SStefano Zampini } 6850674ae819SStefano Zampini PetscFunctionReturn(0); 6851674ae819SStefano Zampini } 685204a6f24aSStefano Zampini /* #undef PETSC_MISSING_LAPACK_GESVD */ 6853674ae819SStefano Zampini 6854674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 6855674ae819SStefano Zampini { 685671582508SStefano Zampini ISLocalToGlobalMapping map; 6857674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6858674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 685966da6bd7Sstefano_zampini PetscInt i,N; 686066da6bd7Sstefano_zampini PetscBool rcsr = PETSC_FALSE; 686166da6bd7Sstefano_zampini PetscErrorCode ierr; 6862674ae819SStefano Zampini 6863674ae819SStefano Zampini PetscFunctionBegin; 68648af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 6865b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 68668e61c736SStefano Zampini /* Reset previously computed graph */ 68678e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 6868674ae819SStefano Zampini /* Init local Graph struct */ 68697fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 687071582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 6871be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 6872674ae819SStefano Zampini 68737a0e7b2cSstefano_zampini if (pcbddc->user_primal_vertices_local && !pcbddc->user_primal_vertices) { 68747a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 68757a0e7b2cSstefano_zampini } 6876575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 68776080607fSStefano 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",pcbddc->mat_graph->nvtxs_csr,pcbddc->mat_graph->nvtxs); 68789577ea80SStefano Zampini 6879674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 688066da6bd7Sstefano_zampini if (!pcbddc->mat_graph->xadj && pcbddc->use_local_adj) { 68814d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 68824d379d7bSStefano Zampini PetscInt nvtxs; 6883e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 6884674ae819SStefano Zampini 68852fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 68862fffb893SStefano Zampini if (flg_row) { 68874d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 6888b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 68892fffb893SStefano Zampini } 68902fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 689166da6bd7Sstefano_zampini rcsr = PETSC_TRUE; 6892674ae819SStefano Zampini } 68939b28b941SStefano Zampini if (pcbddc->dbg_flag) { 68949b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6895674ae819SStefano Zampini } 6896674ae819SStefano Zampini 6897ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cdim && !pcbddc->mat_graph->cloc) { 6898ab8c8b98SStefano Zampini PetscReal *lcoords; 6899ab8c8b98SStefano Zampini PetscInt n; 6900ab8c8b98SStefano Zampini MPI_Datatype dimrealtype; 6901ab8c8b98SStefano Zampini 6902ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cnloc != pc->pmat->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Invalid number of local coordinates! Got %D, expected %D",pcbddc->mat_graph->cnloc,pc->pmat->rmap->n); 6903ab8c8b98SStefano Zampini ierr = MatGetLocalSize(matis->A,&n,NULL);CHKERRQ(ierr); 6904ab8c8b98SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 6905ab8c8b98SStefano Zampini ierr = PetscMalloc1(pcbddc->mat_graph->cdim*n,&lcoords);CHKERRQ(ierr); 6906ab8c8b98SStefano Zampini ierr = MPI_Type_contiguous(pcbddc->mat_graph->cdim,MPIU_REAL,&dimrealtype);CHKERRQ(ierr); 6907ab8c8b98SStefano Zampini ierr = MPI_Type_commit(&dimrealtype);CHKERRQ(ierr); 6908ab8c8b98SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 6909ab8c8b98SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 6910ab8c8b98SStefano Zampini ierr = MPI_Type_free(&dimrealtype);CHKERRQ(ierr); 6911ab8c8b98SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->coords);CHKERRQ(ierr); 6912ab8c8b98SStefano Zampini 6913ab8c8b98SStefano Zampini pcbddc->mat_graph->coords = lcoords; 6914ab8c8b98SStefano Zampini pcbddc->mat_graph->cloc = PETSC_TRUE; 6915ab8c8b98SStefano Zampini pcbddc->mat_graph->cnloc = n; 6916ab8c8b98SStefano Zampini } 6917ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cnloc && pcbddc->mat_graph->cnloc != pcbddc->mat_graph->nvtxs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Invalid number of local subdomain coordinates! Got %D, expected %D",pcbddc->mat_graph->cnloc,pcbddc->mat_graph->nvtxs); 69181c7a958bSStefano Zampini pcbddc->mat_graph->active_coords = (PetscBool)(pcbddc->corner_selection && !pcbddc->corner_selected); 6919ab8c8b98SStefano Zampini 6920674ae819SStefano Zampini /* Setup of Graph */ 69214b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 692214f95afaSStefano 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); 6923674ae819SStefano Zampini 69244f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 69254f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 69264f1b2e48SStefano Zampini PetscInt *local_subs; 69274f1b2e48SStefano Zampini 69284f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 69294f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 69304f1b2e48SStefano Zampini const PetscInt *idxs; 69314f1b2e48SStefano Zampini PetscInt nl,j; 69324f1b2e48SStefano Zampini 69334f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 69344f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 693571582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 69364f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 69374f1b2e48SStefano Zampini } 69384f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 69394f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 69404f1b2e48SStefano Zampini } 69418af8fcf9SStefano Zampini } 69424f1b2e48SStefano Zampini 6943cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 6944674ae819SStefano Zampini /* Graph's connected components analysis */ 6945674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 694671582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 69478af8fcf9SStefano Zampini } 694866da6bd7Sstefano_zampini if (rcsr) pcbddc->mat_graph->nvtxs_csr = 0; 6949674ae819SStefano Zampini PetscFunctionReturn(0); 6950674ae819SStefano Zampini } 6951674ae819SStefano Zampini 69529a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 69539a7d3425SStefano Zampini { 69549a7d3425SStefano Zampini PetscInt i,j; 69559a7d3425SStefano Zampini PetscScalar *alphas; 69569a7d3425SStefano Zampini PetscErrorCode ierr; 69579a7d3425SStefano Zampini 69589a7d3425SStefano Zampini PetscFunctionBegin; 69598c0031efSStefano Zampini if (!n) PetscFunctionReturn(0); 6960785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 69618c0031efSStefano Zampini ierr = VecNormalize(vecs[0],NULL);CHKERRQ(ierr); 69628c0031efSStefano Zampini for (i=1;i<n;i++) { 69638c0031efSStefano Zampini ierr = VecMDot(vecs[i],i,vecs,alphas);CHKERRQ(ierr); 69648c0031efSStefano Zampini for (j=0;j<i;j++) alphas[j] = PetscConj(-alphas[j]); 69658c0031efSStefano Zampini ierr = VecMAXPY(vecs[i],i,alphas,vecs);CHKERRQ(ierr); 69669a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 69679a7d3425SStefano Zampini } 69689a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 69699a7d3425SStefano Zampini PetscFunctionReturn(0); 69709a7d3425SStefano Zampini } 69719a7d3425SStefano Zampini 6972bb360cb4SStefano Zampini PetscErrorCode PCBDDCMatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 6973e7931f94SStefano Zampini { 697457de7509SStefano Zampini Mat A; 6975e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 6976e7931f94SStefano Zampini PetscMPIInt size,rank,color; 697752e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 697852e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 6979bb360cb4SStefano Zampini PetscInt im_active,active_procs,N,n,i,j,threshold = 2; 698057de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 698127b6a85dSStefano Zampini PetscInt xadj_count,*count; 698227b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 698327b6a85dSStefano Zampini PetscSubcomm psubcomm; 698427b6a85dSStefano Zampini MPI_Comm subcomm; 698552e5ac9dSStefano Zampini PetscErrorCode ierr; 6986a57a6d2fSStefano Zampini 6987e7931f94SStefano Zampini PetscFunctionBegin; 698857de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 698957de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 6990fbfcfee5SBarry 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); 699157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 699257de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 69936080607fSStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %D",*n_subdomains); 699457de7509SStefano Zampini 699557de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 699657de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 699757de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 699857de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 699957de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 7000bb360cb4SStefano Zampini im_active = !!n; 700157de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 700257de7509SStefano Zampini void_procs = size - active_procs; 700357de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 700457de7509SStefano Zampini if (void_procs) { 700557de7509SStefano Zampini PetscInt ncand; 700657de7509SStefano Zampini 700757de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 700857de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 700957de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 701057de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 701157de7509SStefano Zampini if (!procs_candidates[i]) { 701257de7509SStefano Zampini procs_candidates[ncand++] = i; 701357de7509SStefano Zampini } 701457de7509SStefano Zampini } 701557de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 701657de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 701757de7509SStefano Zampini } 701857de7509SStefano Zampini 7019bb360cb4SStefano Zampini /* number of subdomains requested greater than active processes or matrix size -> just shift the matrix 702014f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 7021bb360cb4SStefano Zampini ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 7022bb360cb4SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1 || N <= *n_subdomains) { 702314f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 702414f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 702514f0bfb9SStefano Zampini else dest = rank; 702657de7509SStefano Zampini if (im_active) { 702757de7509SStefano Zampini issize = 1; 702857de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 702914f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 703057de7509SStefano Zampini } else { 703114f0bfb9SStefano Zampini isidx = dest; 703257de7509SStefano Zampini } 703357de7509SStefano Zampini } else { 703457de7509SStefano Zampini issize = 0; 703557de7509SStefano Zampini isidx = -1; 703657de7509SStefano Zampini } 7037bb360cb4SStefano Zampini if (*n_subdomains != 1) *n_subdomains = active_procs; 703857de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 7039daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 704057de7509SStefano Zampini PetscFunctionReturn(0); 704157de7509SStefano Zampini } 7042c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 7043c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 704427b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 7045e7931f94SStefano Zampini 7046e7931f94SStefano Zampini /* Get info on mapping */ 70473bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 7048e7931f94SStefano Zampini 7049e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 7050785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 7051e7931f94SStefano Zampini xadj[0] = 0; 7052e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 7053785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 7054785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 7055bb360cb4SStefano Zampini ierr = PetscCalloc1(n,&count);CHKERRQ(ierr); 705627b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 705727b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 705827b6a85dSStefano Zampini count[shared[i][j]] += 1; 7059e7931f94SStefano Zampini 706027b6a85dSStefano Zampini xadj_count = 0; 70612b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 706227b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 706327b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 7064d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 7065d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 7066d023bfaeSStefano Zampini xadj_count++; 706727b6a85dSStefano Zampini break; 706827b6a85dSStefano Zampini } 7069e7931f94SStefano Zampini } 7070e7931f94SStefano Zampini } 7071d023bfaeSStefano Zampini xadj[1] = xadj_count; 707227b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 70733bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 7074e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 7075e7931f94SStefano Zampini 70763837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 7077e7931f94SStefano Zampini 707827b6a85dSStefano Zampini /* Restrict work on active processes only */ 707927b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 708027b6a85dSStefano Zampini if (void_procs) { 708127b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 708227b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 708327b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 708427b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 708527b6a85dSStefano Zampini } else { 708627b6a85dSStefano Zampini psubcomm = NULL; 708727b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 708827b6a85dSStefano Zampini } 708927b6a85dSStefano Zampini 709027b6a85dSStefano Zampini v_wgt = NULL; 709127b6a85dSStefano Zampini if (!color) { 7092e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 7093e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 7094e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 7095c8587f34SStefano Zampini } else { 709652e5ac9dSStefano Zampini Mat subdomain_adj; 709752e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 709852e5ac9dSStefano Zampini MatPartitioning partitioner; 709927b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 710052e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 710157de7509SStefano Zampini PetscMPIInt size; 7102b0c7d250SStefano Zampini PetscBool aggregate; 7103b0c7d250SStefano Zampini 710427b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 710527b6a85dSStefano Zampini if (void_procs) { 710627b6a85dSStefano Zampini PetscInt prank = rank; 7107785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 710827b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 7109e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 7110e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 7111c8587f34SStefano Zampini } 7112e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 711327b6a85dSStefano Zampini } else { 711427b6a85dSStefano Zampini oldranks = NULL; 711527b6a85dSStefano Zampini } 7116b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 711727b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 7118b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 7119b0c7d250SStefano Zampini PetscMPIInt nrank; 7120b0c7d250SStefano Zampini PetscScalar *vals; 7121b0c7d250SStefano Zampini 712227b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 7123b0c7d250SStefano Zampini lrows = 0; 7124b0c7d250SStefano Zampini if (nrank<redprocs) { 7125b0c7d250SStefano Zampini lrows = size/redprocs; 7126b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 7127b0c7d250SStefano Zampini } 712827b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 7129b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 7130b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7131b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7132b0c7d250SStefano Zampini row = nrank; 7133b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 7134b0c7d250SStefano Zampini cols = adjncy; 7135b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 7136b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 7137b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 7138b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7139b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 714052e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 714152e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 714252e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 7143b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 714427b6a85dSStefano Zampini if (use_vwgt) { 714527b6a85dSStefano Zampini Vec v; 714627b6a85dSStefano Zampini const PetscScalar *array; 714727b6a85dSStefano Zampini PetscInt nl; 714827b6a85dSStefano Zampini 714927b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 7150bb360cb4SStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)n,INSERT_VALUES);CHKERRQ(ierr); 715127b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 715227b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 715327b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 715427b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 715527b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 715622db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 715727b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 715827b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 715927b6a85dSStefano Zampini } 7160b0c7d250SStefano Zampini } else { 716127b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 716227b6a85dSStefano Zampini if (use_vwgt) { 716327b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 7164bb360cb4SStefano Zampini v_wgt[0] = n; 716527b6a85dSStefano Zampini } 7166b0c7d250SStefano Zampini } 716722b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 7168e7931f94SStefano Zampini 7169e7931f94SStefano Zampini /* Partition */ 717027b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 7171e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 717227b6a85dSStefano Zampini if (v_wgt) { 7173e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 7174c8587f34SStefano Zampini } 717557de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 717657de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 7177e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 7178e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 717922b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 7180e7931f94SStefano Zampini 718152e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 71826583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 718352e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 718452e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 718557de7509SStefano Zampini if (!aggregate) { 718657de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 718727b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 718827b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 718927b6a85dSStefano Zampini #endif 719057de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 719127b6a85dSStefano Zampini } else if (oldranks) { 7192b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 719327b6a85dSStefano Zampini } else { 719427b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 719557de7509SStefano Zampini } 719628143c3dSStefano Zampini } else { 71977fb8a5e4SKarl Rupp PetscInt idx = 0; 7198b0c7d250SStefano Zampini PetscMPIInt tag; 7199b0c7d250SStefano Zampini MPI_Request *reqs; 7200b0c7d250SStefano Zampini 7201b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 7202b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 7203b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 720427b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 720528143c3dSStefano Zampini } 72067fb8a5e4SKarl Rupp ierr = MPI_Recv(&idx,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 7207b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7208b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 720957de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 721027b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 721127b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 721227b6a85dSStefano Zampini #endif 72137fb8a5e4SKarl Rupp ranks_send_to_idx[0] = procs_candidates[oldranks[idx]]; 721427b6a85dSStefano Zampini } else if (oldranks) { 72157fb8a5e4SKarl Rupp ranks_send_to_idx[0] = oldranks[idx]; 721627b6a85dSStefano Zampini } else { 72177fb8a5e4SKarl Rupp ranks_send_to_idx[0] = idx; 7218e7931f94SStefano Zampini } 721957de7509SStefano Zampini } 722052e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 7221e7931f94SStefano Zampini /* clean up */ 7222e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 722352e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 7224e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 7225e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 7226e7931f94SStefano Zampini } 722727b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 722857de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 7229e7931f94SStefano Zampini 7230e7931f94SStefano Zampini /* assemble parallel IS for sends */ 7231e7931f94SStefano Zampini i = 1; 723227b6a85dSStefano Zampini if (!color) i=0; 723357de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 7234e7931f94SStefano Zampini PetscFunctionReturn(0); 7235e7931f94SStefano Zampini } 7236e7931f94SStefano Zampini 7237e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 7238e7931f94SStefano Zampini 72391e0482f5SStefano 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[]) 7240e7931f94SStefano Zampini { 724170cf5478SStefano Zampini Mat local_mat; 7242e7931f94SStefano Zampini IS is_sends_internal; 72439d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 72441ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 72459d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 7246e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 7247e7931f94SStefano Zampini PetscInt* l2gmap_indices; 7248e7931f94SStefano Zampini const PetscInt* is_indices; 7249e7931f94SStefano Zampini MatType new_local_type; 7250e7931f94SStefano Zampini /* buffers */ 7251e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 725228143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 72539d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 7254e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 72551ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 7256e7931f94SStefano Zampini /* MPI */ 725728143c3dSStefano Zampini MPI_Comm comm,comm_n; 725828143c3dSStefano Zampini PetscSubcomm subcomm; 7259e569e4e1SStefano Zampini PetscMPIInt n_sends,n_recvs,size; 726028143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 726128143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 72621ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 72631ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 72641ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 7265e7931f94SStefano Zampini PetscErrorCode ierr; 7266e7931f94SStefano Zampini 7267e7931f94SStefano Zampini PetscFunctionBegin; 726857de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7269e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 7270fbfcfee5SBarry 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); 727157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 727257de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 727357de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 727457de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 727557de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 72761ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 72771ae86dd6SStefano Zampini if (nvecs) { 72781ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 72791ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 72801ae86dd6SStefano Zampini } 728157de7509SStefano Zampini /* further checks */ 7282e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7283e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 7284e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 7285e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 7286e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 728757de7509SStefano Zampini if (reuse && *mat_n) { 728870cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 728957de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 729070cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 729128143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 729270cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 729370cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 729470cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 729570cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 729670cf5478SStefano Zampini } 7297e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 7298e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 729957de7509SStefano Zampini 7300e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 7301e7931f94SStefano Zampini if (!is_sends) { 730228143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 7303bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 7304c8587f34SStefano Zampini } else { 7305e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 7306e7931f94SStefano Zampini is_sends_internal = is_sends; 7307c8587f34SStefano Zampini } 7308e7931f94SStefano Zampini 7309e7931f94SStefano Zampini /* get comm */ 7310a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 7311e7931f94SStefano Zampini 7312e7931f94SStefano Zampini /* compute number of sends */ 7313e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 7314e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 7315e7931f94SStefano Zampini 7316e7931f94SStefano Zampini /* compute number of receives */ 7317e569e4e1SStefano Zampini ierr = MPI_Comm_size(comm,&size);CHKERRQ(ierr); 7318e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&iflags);CHKERRQ(ierr); 7319e569e4e1SStefano Zampini ierr = PetscMemzero(iflags,size*sizeof(*iflags));CHKERRQ(ierr); 7320e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7321e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 7322e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 7323e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 7324e7931f94SStefano Zampini 732528143c3dSStefano Zampini /* restrict comm if requested */ 732628143c3dSStefano Zampini subcomm = 0; 732728143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 732828143c3dSStefano Zampini if (restrict_comm) { 7329779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 7330779c1cceSStefano Zampini 733128143c3dSStefano Zampini color = 0; 733253a05cb3SStefano Zampini if (restrict_full) { 733353a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 733453a05cb3SStefano Zampini } else { 733553a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 733653a05cb3SStefano Zampini } 7337b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 7338e569e4e1SStefano Zampini subcommsize = size - subcommsize; 733928143c3dSStefano Zampini /* check if reuse has been requested */ 734057de7509SStefano Zampini if (reuse) { 734128143c3dSStefano Zampini if (*mat_n) { 734228143c3dSStefano Zampini PetscMPIInt subcommsize2; 734328143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 734428143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 734528143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 734628143c3dSStefano Zampini } else { 734728143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 734828143c3dSStefano Zampini } 734928143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 7350779c1cceSStefano Zampini PetscMPIInt rank; 7351779c1cceSStefano Zampini 7352779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 735328143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 735428143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 735528143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 7356306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 735728143c3dSStefano Zampini } 735828143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 735928143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 736028143c3dSStefano Zampini } else { 736128143c3dSStefano Zampini comm_n = comm; 736228143c3dSStefano Zampini } 736328143c3dSStefano Zampini 7364e7931f94SStefano Zampini /* prepare send/receive buffers */ 7365e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&ilengths_idxs);CHKERRQ(ierr); 7366e569e4e1SStefano Zampini ierr = PetscMemzero(ilengths_idxs,size*sizeof(*ilengths_idxs));CHKERRQ(ierr); 7367e569e4e1SStefano Zampini ierr = PetscMalloc1(size,&ilengths_vals);CHKERRQ(ierr); 7368e569e4e1SStefano Zampini ierr = PetscMemzero(ilengths_vals,size*sizeof(*ilengths_vals));CHKERRQ(ierr); 736928143c3dSStefano Zampini if (nis) { 7370e569e4e1SStefano Zampini ierr = PetscCalloc1(size,&ilengths_idxs_is);CHKERRQ(ierr); 737128143c3dSStefano Zampini } 7372e7931f94SStefano Zampini 737328143c3dSStefano Zampini /* Get data from local matrices */ 73746c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 7375e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 7376e7931f94SStefano Zampini /* 7377e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 7378e7931f94SStefano Zampini send_buffer_idxs should contain: 7379e7931f94SStefano Zampini - MatType_PRIVATE type 7380e7931f94SStefano Zampini - PetscInt size_of_l2gmap 7381e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 7382e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 7383e7931f94SStefano Zampini */ 73846c4ed002SBarry Smith else { 7385e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 73863bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 7387854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 7388e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 7389e7931f94SStefano Zampini send_buffer_idxs[1] = i; 73903bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7391e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 73923bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7393e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 7394e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7395e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 7396e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 7397c8587f34SStefano Zampini } 7398c8587f34SStefano Zampini } 7399e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 740028143c3dSStefano Zampini /* additional is (if any) */ 740128143c3dSStefano Zampini if (nis) { 740228143c3dSStefano Zampini PetscMPIInt psum; 740328143c3dSStefano Zampini PetscInt j; 740428143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 740528143c3dSStefano Zampini PetscInt plen; 740628143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 740728143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 740828143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 740928143c3dSStefano Zampini } 7410854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 741128143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 741228143c3dSStefano Zampini PetscInt plen; 741328143c3dSStefano Zampini const PetscInt *is_array_idxs; 741428143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 741528143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 741628143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 741728143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 741828143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 741928143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 742028143c3dSStefano Zampini } 742128143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 742228143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 742328143c3dSStefano Zampini } 742428143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 742528143c3dSStefano Zampini } 74263b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 742728143c3dSStefano Zampini 7428e7931f94SStefano Zampini buf_size_idxs = 0; 7429e7931f94SStefano Zampini buf_size_vals = 0; 743028143c3dSStefano Zampini buf_size_idxs_is = 0; 74311ae86dd6SStefano Zampini buf_size_vecs = 0; 7432e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7433e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 7434e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 743528143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 74361ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 7437e7931f94SStefano Zampini } 7438785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 7439785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 744095ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 74411ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 7442e7931f94SStefano Zampini 7443e7931f94SStefano Zampini /* get new tags for clean communications */ 7444e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 7445e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 744628143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 74471ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 7448e7931f94SStefano Zampini 7449e7931f94SStefano Zampini /* allocate for requests */ 7450785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 7451785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 745295ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 74531ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 7454785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 7455785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 745695ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 74571ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 7458e7931f94SStefano Zampini 7459e7931f94SStefano Zampini /* communications */ 7460e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7461e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 746228143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 74631ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 7464e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7465e7931f94SStefano Zampini source_dest = onodes[i]; 7466e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 7467e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 7468e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7469e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 747028143c3dSStefano Zampini if (nis) { 747157de7509SStefano Zampini source_dest = onodes_is[i]; 747228143c3dSStefano 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); 747328143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 747428143c3dSStefano Zampini } 74751ae86dd6SStefano Zampini if (nvecs) { 74761ae86dd6SStefano Zampini source_dest = onodes[i]; 74771ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 74781ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 74791ae86dd6SStefano Zampini } 7480e7931f94SStefano Zampini } 7481e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7482e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 7483e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 7484e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 748528143c3dSStefano Zampini if (nis) { 748628143c3dSStefano 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); 748728143c3dSStefano Zampini } 74881ae86dd6SStefano Zampini if (nvecs) { 74891ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 74901ae86dd6SStefano 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); 74911ae86dd6SStefano Zampini } 7492e7931f94SStefano Zampini } 7493e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7494e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 7495e7931f94SStefano Zampini 7496e7931f94SStefano Zampini /* assemble new l2g map */ 7497e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7498e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 74999d30be91SStefano Zampini new_local_rows = 0; 7500e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 75019d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7502e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7503e7931f94SStefano Zampini } 75049d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 7505e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 75069d30be91SStefano Zampini new_local_rows = 0; 7507e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 75089d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 75099d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7510e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7511e7931f94SStefano Zampini } 75129d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 75139d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 7514e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 7515e7931f94SStefano Zampini 7516e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 7517e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 7518e7931f94SStefano 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) */ 7519e7931f94SStefano Zampini if (n_recvs) { 752028143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 7521e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7522e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7523e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 7524e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 7525e7931f94SStefano Zampini break; 7526e7931f94SStefano Zampini } 7527e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7528e7931f94SStefano Zampini } 7529e7931f94SStefano Zampini switch (new_local_type_private) { 753028143c3dSStefano Zampini case MATDENSE_PRIVATE: 7531e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7532e7931f94SStefano Zampini bs = 1; 7533e7931f94SStefano Zampini break; 7534e7931f94SStefano Zampini case MATAIJ_PRIVATE: 7535e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7536e7931f94SStefano Zampini bs = 1; 7537e7931f94SStefano Zampini break; 7538e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 7539e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 7540e7931f94SStefano Zampini break; 7541e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 7542e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 7543e7931f94SStefano Zampini break; 7544e7931f94SStefano Zampini default: 7545fbfcfee5SBarry Smith SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,PETSC_FUNCTION_NAME); 7546e7931f94SStefano Zampini break; 7547e7931f94SStefano Zampini } 7548ed8ed4edSstefano_zampini } else { /* by default, new_local_type is seqaij */ 7549ed8ed4edSstefano_zampini new_local_type = MATSEQAIJ; 755028143c3dSStefano Zampini bs = 1; 7551e7931f94SStefano Zampini } 7552e7931f94SStefano Zampini 755370cf5478SStefano Zampini /* create MATIS object if needed */ 755457de7509SStefano Zampini if (!reuse) { 7555e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 7556e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 755770cf5478SStefano Zampini } else { 755870cf5478SStefano Zampini /* it also destroys the local matrices */ 755957de7509SStefano Zampini if (*mat_n) { 756070cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 756157de7509SStefano Zampini } else { /* this is a fake object */ 756257de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 756357de7509SStefano Zampini } 756470cf5478SStefano Zampini } 756570cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 7566e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 75679d30be91SStefano Zampini 75689d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 75699d30be91SStefano Zampini 75709d30be91SStefano Zampini /* Global to local map of received indices */ 75719d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 75729d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 75739d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 75749d30be91SStefano Zampini 75759d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 75769d30be91SStefano Zampini buf_size_idxs = 0; 75779d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 75789d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 75799d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 75809d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 75819d30be91SStefano Zampini } 75829d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 75839d30be91SStefano Zampini 75849d30be91SStefano Zampini /* set preallocation */ 75859d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 75869d30be91SStefano Zampini if (!newisdense) { 75879d30be91SStefano Zampini PetscInt *new_local_nnz=0; 75889d30be91SStefano Zampini 75899d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 75909d30be91SStefano Zampini if (n_recvs) { 75919d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 75929d30be91SStefano Zampini } 75939d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 75949d30be91SStefano Zampini PetscInt j; 75959d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 75969d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 75979d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 75989d30be91SStefano Zampini } 75999d30be91SStefano Zampini } else { 76009d30be91SStefano Zampini /* TODO */ 76019d30be91SStefano Zampini } 76029d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 76039d30be91SStefano Zampini } 76049d30be91SStefano Zampini if (new_local_nnz) { 76059d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 76069d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 76079d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 76089d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 76099d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 76109d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 76119d30be91SStefano Zampini } else { 76129d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 76139d30be91SStefano Zampini } 76149d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 76159d30be91SStefano Zampini } else { 76169d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 76179d30be91SStefano Zampini } 7618e7931f94SStefano Zampini 7619e7931f94SStefano Zampini /* set values */ 7620e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 76219d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 7622e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7623e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 7624e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 76259d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 7626e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7627e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7628e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 762928143c3dSStefano Zampini } else { 763028143c3dSStefano Zampini /* TODO */ 7631e7931f94SStefano Zampini } 7632e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7633e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 7634e7931f94SStefano Zampini } 7635e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7636e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 76373b3b1effSJed Brown ierr = MatISRestoreLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 763870cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 763970cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 76409d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 7641e7931f94SStefano Zampini 7642dfd14d43SStefano Zampini #if 0 764328143c3dSStefano Zampini if (!restrict_comm) { /* check */ 7644e7931f94SStefano Zampini Vec lvec,rvec; 7645e7931f94SStefano Zampini PetscReal infty_error; 7646e7931f94SStefano Zampini 76472a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 7648e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 7649e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 7650e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 765170cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 7652e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 7653e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 7654e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 7655e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 7656e7931f94SStefano Zampini } 765728143c3dSStefano Zampini #endif 7658e7931f94SStefano Zampini 765928143c3dSStefano Zampini /* assemble new additional is (if any) */ 766028143c3dSStefano Zampini if (nis) { 766128143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 766228143c3dSStefano Zampini 766328143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7664854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 766528143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 766628143c3dSStefano Zampini psum = 0; 766728143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 766828143c3dSStefano Zampini for (j=0;j<nis;j++) { 766928143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 767028143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 767128143c3dSStefano Zampini psum += plen; 767228143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 767328143c3dSStefano Zampini } 767428143c3dSStefano Zampini } 7675854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 7676854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 767728143c3dSStefano Zampini for (i=1;i<nis;i++) { 767828143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 767928143c3dSStefano Zampini } 768028143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 768128143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 768228143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 768328143c3dSStefano Zampini for (j=0;j<nis;j++) { 768428143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 768528143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 768628143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 768728143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 768828143c3dSStefano Zampini } 768928143c3dSStefano Zampini } 769028143c3dSStefano Zampini for (i=0;i<nis;i++) { 769128143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 769228143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 769328143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 769428143c3dSStefano Zampini } 769528143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 769628143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 769728143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 769828143c3dSStefano Zampini } 7699e7931f94SStefano Zampini /* free workspace */ 770028143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 7701e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7702e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 7703e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7704e7931f94SStefano Zampini if (isdense) { 7705e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7706e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 77073b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 7708e7931f94SStefano Zampini } else { 7709e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 7710e7931f94SStefano Zampini } 771128143c3dSStefano Zampini if (nis) { 771228143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 771328143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 771428143c3dSStefano Zampini } 77151ae86dd6SStefano Zampini 77161ae86dd6SStefano Zampini if (nvecs) { 77171ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 77181ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 77191ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 77201ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 77211ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 77221ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 77231ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 77241ae86dd6SStefano Zampini /* set values */ 77251ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 77261ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 77271ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 77281ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 77291ae86dd6SStefano Zampini PetscInt j; 77301ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 77311ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 77321ae86dd6SStefano Zampini } 77331ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 77341ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 77351ae86dd6SStefano Zampini } 77361ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 77371ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 77381ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 77391ae86dd6SStefano Zampini } 77401ae86dd6SStefano Zampini 77411ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 77421ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 7743e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 7744e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 77451ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 774628143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 7747e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 7748e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 77491ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 775028143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 7751e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 7752e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 7753e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 7754e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 7755e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 775628143c3dSStefano Zampini if (nis) { 775728143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 775828143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 775928143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 776028143c3dSStefano Zampini } 776128143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 776228143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 776328143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 776428143c3dSStefano Zampini for (i=0;i<nis;i++) { 776528143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 776628143c3dSStefano Zampini } 77671ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 77681ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 77691ae86dd6SStefano Zampini } 777053a05cb3SStefano Zampini *mat_n = NULL; 777128143c3dSStefano Zampini } 7772e7931f94SStefano Zampini PetscFunctionReturn(0); 7773e7931f94SStefano Zampini } 7774a57a6d2fSStefano Zampini 777512edc857SStefano Zampini /* temporary hack into ksp private data structure */ 7776af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 777712edc857SStefano Zampini 7778c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 7779c8587f34SStefano Zampini { 7780c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7781c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 778220a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 77831ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 77841e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 77859881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 778620a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 77876e683305SStefano Zampini IS coarse_is,*isarray; 77886e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 778930368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 7790e569e4e1SStefano Zampini PetscInt coarse_eqs_per_proc; 7791f9eb5b7dSStefano Zampini PC pc_temp; 7792c8587f34SStefano Zampini PCType coarse_pc_type; 7793c8587f34SStefano Zampini KSPType coarse_ksp_type; 7794f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 77957274672aSStefano Zampini PetscBool coarse_reuse; 77961e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 779768457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 779822bc73bbSStefano Zampini PetscScalar *array; 779957de7509SStefano Zampini MatReuse coarse_mat_reuse; 780057de7509SStefano Zampini PetscBool restr, full_restr, have_void; 7801e569e4e1SStefano Zampini PetscMPIInt size; 78029881197aSStefano Zampini PetscErrorCode ierr; 7803fdc09c96SStefano Zampini 7804c8587f34SStefano Zampini PetscFunctionBegin; 780543371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CoarseSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 7806c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 780768457ee5SStefano 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 */ 7808fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 78095a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 78107de4f681Sstefano_zampini 78117de4f681Sstefano_zampini pcbddc->new_primal_space = PETSC_TRUE; 7812fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 7813f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 7814f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 7815f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 7816fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 781751bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 781851bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 7819727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 7820fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7821fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 7822fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7823f4ddd8eeSStefano Zampini } 7824fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 7825fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7826f4ddd8eeSStefano Zampini } 782770cf5478SStefano Zampini /* reset any subassembling information */ 782857de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 782970cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 783057de7509SStefano Zampini } 78316e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 7832fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7833f4ddd8eeSStefano Zampini } 783457de7509SStefano Zampini /* assemble coarse matrix */ 783557de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 783657de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 783757de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 783857de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 783918a45a71SStefano Zampini } else { 784057de7509SStefano Zampini coarse_mat = NULL; 784157de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 78426e683305SStefano Zampini } 7843e7931f94SStefano Zampini 7844abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 7845abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 7846abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 7847abbbba34SStefano Zampini 7848abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 784922bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 785022bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 785122bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 785222bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 7853e176bc59SStefano 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); 78546e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 78556e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 78566e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7857abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 7858abbbba34SStefano Zampini 785957de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 786057de7509SStefano Zampini im_active = !!(pcis->n); 786157de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 786257de7509SStefano Zampini 786314f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 786457de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 786557de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 7866e569e4e1SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&size);CHKERRQ(ierr); 786757de7509SStefano Zampini coarse_mat_is = NULL; 786857de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 786957de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 7870e569e4e1SStefano Zampini coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 787157de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 7872e569e4e1SStefano Zampini if (pcbddc->coarse_size <= pcbddc->coarse_eqs_limit) multilevel_requested = PETSC_FALSE; 787357de7509SStefano Zampini if (multilevel_requested) { 787457de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 787557de7509SStefano Zampini restr = PETSC_FALSE; 787657de7509SStefano Zampini full_restr = PETSC_FALSE; 787757de7509SStefano Zampini } else { 7878e569e4e1SStefano Zampini ncoarse = pcbddc->coarse_size/coarse_eqs_per_proc + !!(pcbddc->coarse_size%coarse_eqs_per_proc); 787957de7509SStefano Zampini restr = PETSC_TRUE; 788057de7509SStefano Zampini full_restr = PETSC_TRUE; 788157de7509SStefano Zampini } 7882e569e4e1SStefano Zampini if (!pcbddc->coarse_size || size == 1) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 788357de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 788457de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 7885a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 7886bb360cb4SStefano Zampini if (multilevel_requested) { 7887bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7888bb360cb4SStefano Zampini } else { 7889bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7890bb360cb4SStefano Zampini } 7891a198735bSStefano Zampini } else { 78927de4f681Sstefano_zampini PetscMPIInt rank; 7893a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 7894e569e4e1SStefano Zampini have_void = (active_procs == (PetscInt)size) ? PETSC_FALSE : PETSC_TRUE; 7895a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 7896a198735bSStefano Zampini } 789757de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 789857de7509SStefano Zampini PetscInt psum; 789957de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 790057de7509SStefano Zampini else psum = 0; 790157de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 7902e569e4e1SStefano Zampini if (ncoarse < size) have_void = PETSC_TRUE; 790357de7509SStefano Zampini } 790457de7509SStefano Zampini /* determine if we can go multilevel */ 790557de7509SStefano Zampini if (multilevel_requested) { 790657de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 790757de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 790857de7509SStefano Zampini } 790957de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 791057de7509SStefano Zampini 7911e4d548c7SStefano Zampini /* dump subassembling pattern */ 7912e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 7913e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 7914e4d548c7SStefano Zampini } 7915e4d548c7SStefano Zampini 79166e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 79171e0482f5SStefano Zampini nedcfield = -1; 79181e0482f5SStefano Zampini if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal)) { /* protects from unneded computations */ 79196e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 79206e683305SStefano Zampini const PetscInt *idxs; 79216e683305SStefano Zampini ISLocalToGlobalMapping tmap; 79226e683305SStefano Zampini 79236e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 79240be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 79256e683305SStefano Zampini /* allocate space for temporary storage */ 7926854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 7927854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 79286e683305SStefano Zampini /* allocate for IS array */ 79296e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 79301e0482f5SStefano Zampini if (pcbddc->nedclocal) { 79311e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 79321e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 79331e0482f5SStefano Zampini } else { 79341e0482f5SStefano Zampini nedcfield = 0; 79356080607fSStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%D)",nisdofs); 79361e0482f5SStefano Zampini nisdofs = 1; 79371e0482f5SStefano Zampini } 79381e0482f5SStefano Zampini } 79396e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 794027b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 794130368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 7942854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 79436e683305SStefano Zampini /* dofs splitting */ 79446e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 79456e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 79461e0482f5SStefano Zampini if (nedcfield != i) { 79476e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 79486e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 79496e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 79506e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 79511e0482f5SStefano Zampini } else { 79521e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 79531e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 79541e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 79556080607fSStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping coarse nedelec field! %D != %D",tsize,nout); 79561e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 79571e0482f5SStefano Zampini } 79586e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 795930368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 79606e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 79616e683305SStefano Zampini } 79626e683305SStefano Zampini /* neumann boundaries */ 79636e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 79646e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 79656e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 79666e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 79676e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 79686e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 79696e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 797030368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 79716e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 79726e683305SStefano Zampini } 79736e683305SStefano Zampini /* free memory */ 79746e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 79756e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 79766e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 79776e683305SStefano Zampini } else { 79786e683305SStefano Zampini nis = 0; 79796e683305SStefano Zampini nisdofs = 0; 79806e683305SStefano Zampini nisneu = 0; 798130368db7SStefano Zampini nisvert = 0; 79826e683305SStefano Zampini isarray = NULL; 79836e683305SStefano Zampini } 79846e683305SStefano Zampini /* destroy no longer needed map */ 79856e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 79866e683305SStefano Zampini 798757de7509SStefano Zampini /* subassemble */ 798857de7509SStefano Zampini if (multilevel_allowed) { 79891ae86dd6SStefano Zampini Vec vp[1]; 79901ae86dd6SStefano Zampini PetscInt nvecs = 0; 799157de7509SStefano Zampini PetscBool reuse,reuser; 79921ae86dd6SStefano Zampini 799357de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 799457de7509SStefano Zampini else reuse = PETSC_FALSE; 799557de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 79961ae86dd6SStefano Zampini vp[0] = NULL; 79971ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 79981ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 79991ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 80001ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 80011ae86dd6SStefano Zampini nvecs = 1; 80021ae86dd6SStefano Zampini 80031ae86dd6SStefano Zampini if (pcbddc->divudotp) { 8004a198735bSStefano Zampini Mat B,loc_divudotp; 80051ae86dd6SStefano Zampini Vec v,p; 80061ae86dd6SStefano Zampini IS dummy; 80071ae86dd6SStefano Zampini PetscInt np; 80081ae86dd6SStefano Zampini 8009a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 8010a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 80111ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 80127dae84e0SHong Zhang ierr = MatCreateSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 80131ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 80141ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 80151ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 80161ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 80171ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 80181ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 80191ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 80201ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 80211ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 80221ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 80231ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 80241ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 802574e2c79eSStefano Zampini } 80261ae86dd6SStefano Zampini } 80271ae86dd6SStefano Zampini if (reuser) { 80281e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 802974e2c79eSStefano Zampini } else { 80301e0482f5SStefano 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); 80311ae86dd6SStefano Zampini } 80321ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 80331ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 80341ae86dd6SStefano Zampini PetscInt nl; 80351ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 80361ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 80371ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 80381ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 80391ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 80401ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 80411ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 80421ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 8043a198735bSStefano Zampini } else { 8044a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 80451ae86dd6SStefano Zampini } 80461ae86dd6SStefano Zampini } else { 80471e0482f5SStefano 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); 80486e683305SStefano Zampini } 804957de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 805057de7509SStefano Zampini PetscMPIInt size; 8051f913dca9SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size);CHKERRQ(ierr); 805257de7509SStefano Zampini if (!multilevel_allowed) { 8053487b449aSStefano Zampini ierr = MatConvert(coarse_mat_is,MATAIJ,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 80546e683305SStefano Zampini } else { 805557de7509SStefano Zampini Mat A; 8056779c1cceSStefano Zampini 805757de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 805857de7509SStefano Zampini if (coarse_mat_is) { 805957de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 806057de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 806157de7509SStefano Zampini coarse_mat = coarse_mat_is; 806257de7509SStefano Zampini } 806357de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 806457de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 806557de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 8066779c1cceSStefano Zampini } 8067779c1cceSStefano Zampini } 806857de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 806957de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 80706e683305SStefano Zampini 80716e683305SStefano Zampini /* create local to global scatters for coarse problem */ 807268457ee5SStefano Zampini if (compute_vecs) { 80736e683305SStefano Zampini PetscInt lrows; 80746e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 807557de7509SStefano Zampini if (coarse_mat) { 807657de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 80776e683305SStefano Zampini } else { 80786e683305SStefano Zampini lrows = 0; 80796e683305SStefano Zampini } 80806e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 80816e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 80826e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 80836e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 80846e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 80856e683305SStefano Zampini } 80866e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 8087c8587f34SStefano Zampini 8088f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 8089f9eb5b7dSStefano Zampini if (multilevel_allowed) { 8090f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 8091f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 8092f9eb5b7dSStefano Zampini } else { 8093f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 8094f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 8095c8587f34SStefano Zampini } 8096c8587f34SStefano Zampini 80976e683305SStefano Zampini /* print some info if requested */ 80986e683305SStefano Zampini if (pcbddc->dbg_flag) { 80996e683305SStefano Zampini if (!multilevel_allowed) { 81006e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 81016e683305SStefano Zampini if (multilevel_requested) { 81026080607fSStefano 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); 81036e683305SStefano Zampini } else if (pcbddc->max_levels) { 81046080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%D)\n",pcbddc->max_levels);CHKERRQ(ierr); 81056e683305SStefano Zampini } 81066e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 81076e683305SStefano Zampini } 81086e683305SStefano Zampini } 81096e683305SStefano Zampini 81101e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 81111e0482f5SStefano Zampini coarseG = NULL; 81121e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 81131e0482f5SStefano Zampini MPI_Comm ccomm; 81141e0482f5SStefano Zampini if (coarse_mat) { 81151e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 81161e0482f5SStefano Zampini } else { 81171e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 81181e0482f5SStefano Zampini } 81191e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 81201e0482f5SStefano Zampini } 81211e0482f5SStefano Zampini 8122f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 812357de7509SStefano Zampini if (coarse_mat) { 81247274672aSStefano Zampini PetscBool isredundant,isnn,isbddc; 81256a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 81267274672aSStefano Zampini 81276e683305SStefano Zampini if (pcbddc->dbg_flag) { 812857de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 81296e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 81306e683305SStefano Zampini } 8131f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 8132312be037SStefano Zampini char prefix[256],str_level[16]; 8133e604994aSStefano Zampini size_t len; 81341e0482f5SStefano Zampini 813557de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 8136422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 8137c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 8138f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 813957de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8140c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 81416e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 8142c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 81431e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 8144c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8145e604994aSStefano Zampini /* prefix */ 8146e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 8147e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 8148e604994aSStefano Zampini if (!pcbddc->current_level) { 8149a126751eSBarry Smith ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,sizeof(prefix));CHKERRQ(ierr); 8150a126751eSBarry Smith ierr = PetscStrlcat(prefix,"pc_bddc_coarse_",sizeof(prefix));CHKERRQ(ierr); 8151c8587f34SStefano Zampini } else { 8152e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 8153312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 8154312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 8155a126751eSBarry Smith /* Nonstandard use of PetscStrncpy() to copy only a portion of the string */ 815634d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 815735529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 8158a126751eSBarry Smith ierr = PetscStrlcat(prefix,str_level,sizeof(prefix));CHKERRQ(ierr); 8159e604994aSStefano Zampini } 8160e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 81613e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 81623e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 81633e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 81643e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 8165f9eb5b7dSStefano Zampini /* allow user customization */ 8166f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 8167e569e4e1SStefano Zampini /* get some info after set from options */ 8168e569e4e1SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 8169e569e4e1SStefano Zampini /* multilevel cannot be done with coarse PCs different from BDDC or NN */ 8170e569e4e1SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 8171e569e4e1SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 8172e569e4e1SStefano Zampini if (multilevel_allowed && !isbddc && !isnn) { 8173e569e4e1SStefano Zampini isbddc = PETSC_TRUE; 8174e569e4e1SStefano Zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 8175e569e4e1SStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 8176e569e4e1SStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 8177e569e4e1SStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 8178e569e4e1SStefano Zampini } 81793e3c6dadSStefano Zampini } 81803e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 818151bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 81823e3c6dadSStefano Zampini if (nisdofs) { 81833e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 81843e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 81853e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 81863e3c6dadSStefano Zampini } 81873e3c6dadSStefano Zampini } 81883e3c6dadSStefano Zampini if (nisneu) { 81893e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 81903e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 8191312be037SStefano Zampini } 819230368db7SStefano Zampini if (nisvert) { 819330368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 819430368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 819530368db7SStefano Zampini } 81961e0482f5SStefano Zampini if (coarseG) { 81971e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 81981e0482f5SStefano Zampini } 8199f9eb5b7dSStefano Zampini 8200f9eb5b7dSStefano Zampini /* get some info after set from options */ 8201f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 8202b76f3995Sstefano_zampini /* multilevel can only be requested via -pc_bddc_levels or PCBDDCSetLevels */ 8203b76f3995Sstefano_zampini if (isbddc && !multilevel_allowed) { 8204f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8205f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 8206f9eb5b7dSStefano Zampini } 8207b76f3995Sstefano_zampini /* multilevel cannot be done with coarse PCs different from BDDC or NN */ 82087274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 82097274672aSStefano Zampini if (multilevel_requested && multilevel_allowed && !isbddc && !isnn) { 8210b76f3995Sstefano_zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 8211b76f3995Sstefano_zampini isbddc = PETSC_TRUE; 8212b76f3995Sstefano_zampini } 82137274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 82144f3a063dSStefano Zampini if (isredundant) { 82154f3a063dSStefano Zampini KSP inner_ksp; 82164f3a063dSStefano Zampini PC inner_pc; 82179326c5c6Sstefano_zampini 82184f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 82194f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 82204f3a063dSStefano Zampini } 8221f9eb5b7dSStefano Zampini 822257de7509SStefano Zampini /* parameters which miss an API */ 82237274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 822457de7509SStefano Zampini if (isbddc) { 8225720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 82267274672aSStefano Zampini 8227720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 822857de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 8229e569e4e1SStefano Zampini pcbddc_coarse->coarse_eqs_limit = pcbddc->coarse_eqs_limit; 823027b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 823127b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 8232a198735bSStefano Zampini Mat coarsedivudotp_is; 8233a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 8234a198735bSStefano Zampini IS row,col; 8235a198735bSStefano Zampini const PetscInt *gidxs; 8236a198735bSStefano Zampini PetscInt n,st,M,N; 8237a198735bSStefano Zampini 8238a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 8239a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 8240a198735bSStefano Zampini st = st-n; 8241a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 8242a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 8243a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 8244a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8245a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 8246a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8247a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 8248a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 8249a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 8250a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 8251a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 8252a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 8253a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 8254a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 8255a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 8256a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 8257a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 8258a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 8259a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 8260a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 82618ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 8262a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 8263720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 8264bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[0] == 0.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 8265720d30f9SStefano Zampini } 8266d4d8cf7bSStefano Zampini } 82679881197aSStefano Zampini 82683301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 82695a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 82703301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 82713301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 82723301b35fSStefano Zampini } 82733301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 82743301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 82753301b35fSStefano Zampini } 82763301b35fSStefano Zampini if (pc->pmat->spd_set) { 82773301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 82783301b35fSStefano Zampini } 827927b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 828027b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 828127b6a85dSStefano Zampini } 82826e683305SStefano Zampini /* set operators */ 828304fe1396SStefano Zampini ierr = MatViewFromOptions(coarse_mat,(PetscObject)pc,"-pc_bddc_coarse_mat_view");CHKERRQ(ierr); 82843007b4efSStefano Zampini ierr = MatSetOptionsPrefix(coarse_mat,((PetscObject)pcbddc->coarse_ksp)->prefix);CHKERRQ(ierr); 82855f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 82866e683305SStefano Zampini if (pcbddc->dbg_flag) { 82876e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 82886e683305SStefano Zampini } 82896e683305SStefano Zampini } 82901e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 82916e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 8292b1ecc7b1SStefano Zampini #if 0 8293b9b85e73SStefano Zampini { 8294b9b85e73SStefano Zampini PetscViewer viewer; 8295b9b85e73SStefano Zampini char filename[256]; 8296b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 8297b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 82986a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 8299b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 8300f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 8301b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 8302b9b85e73SStefano Zampini } 8303b9b85e73SStefano Zampini #endif 8304f9eb5b7dSStefano Zampini 830598a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 830698a51de6SStefano Zampini Vec crhs,csol; 830704708bb6SStefano Zampini 8308f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 8309f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 8310f347579bSStefano Zampini if (!csol) { 83112a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 8312f9eb5b7dSStefano Zampini } 8313f347579bSStefano Zampini if (!crhs) { 83142a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 8315f347579bSStefano Zampini } 8316b0f5fe93SStefano Zampini } 83171ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 8318b0f5fe93SStefano Zampini 8319b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 8320b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 8321b0f5fe93SStefano Zampini 8322b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 83234f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 83244f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 83254f1b2e48SStefano Zampini } 8326b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 8327b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 8328b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8329b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8330b0f5fe93SStefano Zampini if (coarse_mat) { 8331b0f5fe93SStefano Zampini Vec nullv; 8332b0f5fe93SStefano Zampini PetscScalar *array,*array2; 8333b0f5fe93SStefano Zampini PetscInt nl; 8334b0f5fe93SStefano Zampini 8335b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 8336b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 8337b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8338b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 8339b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 8340b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 8341b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8342b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 8343b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 8344b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 8345b0f5fe93SStefano Zampini } 8346b0f5fe93SStefano Zampini } 834743371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CoarseSetUp[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8348b0f5fe93SStefano Zampini 834943371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_CoarseSolver[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8350b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 8351b0f5fe93SStefano Zampini PetscBool ispreonly; 8352b0f5fe93SStefano Zampini 8353b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8354b0f5fe93SStefano Zampini PetscBool isnull; 8355b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 8356bef83e63SStefano Zampini if (isnull) { 8357b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 8358b0f5fe93SStefano Zampini } 8359bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 8360b0f5fe93SStefano Zampini } 8361b0f5fe93SStefano Zampini /* setup coarse ksp */ 8362b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 8363cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 8364cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 83656e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 8366c8587f34SStefano Zampini KSP check_ksp; 83672b510759SStefano Zampini KSPType check_ksp_type; 8368c8587f34SStefano Zampini PC check_pc; 83696e683305SStefano Zampini Vec check_vec,coarse_vec; 83706a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 83712b510759SStefano Zampini PetscInt its; 83726e683305SStefano Zampini PetscBool compute_eigs; 83736e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 83746e683305SStefano Zampini PetscInt neigs; 83758e185a42SStefano Zampini const char *prefix; 8376c8587f34SStefano Zampini 83772b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 83786e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 837915579a77SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)check_ksp,(PetscObject)pcbddc->coarse_ksp,0);CHKERRQ(ierr); 8380399ffe99SStefano Zampini ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,PETSC_FALSE);CHKERRQ(ierr); 838123ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8382f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 8383e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 8384e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 8385e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 83862b510759SStefano Zampini if (ispreonly) { 83872b510759SStefano Zampini check_ksp_type = KSPPREONLY; 83886e683305SStefano Zampini compute_eigs = PETSC_FALSE; 83892b510759SStefano Zampini } else { 8390cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 83916e683305SStefano Zampini compute_eigs = PETSC_TRUE; 8392c8587f34SStefano Zampini } 8393c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 83946e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 83956e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 83966e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 8397a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 8398a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 8399a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 8400a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 8401c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 8402c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 8403c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 8404c8587f34SStefano Zampini /* create random vec */ 84052701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 8406c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 84076e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 8408c8587f34SStefano Zampini /* solve coarse problem */ 84096e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 8410cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 84116e683305SStefano Zampini if (compute_eigs) { 8412854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 8413854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 84146e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 84151ae86dd6SStefano Zampini if (neigs) { 84166e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 84176e683305SStefano Zampini lambda_min = eigs_r[0]; 84186e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 84192701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 84202701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 8421cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 8422cbcc2c2aSStefano Zampini } 8423c8587f34SStefano Zampini } 8424c8587f34SStefano Zampini } 84251ae86dd6SStefano Zampini } 8426cbcc2c2aSStefano Zampini 8427c8587f34SStefano Zampini /* check coarse problem residual error */ 84286e683305SStefano Zampini if (pcbddc->dbg_flag) { 84296e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 84306e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 84316e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 8432c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 84336e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 84346e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 8435779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 84366e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 84376e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 84386e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 84396e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 8440b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8441b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 8442b0f5fe93SStefano Zampini } 84436e683305SStefano Zampini if (compute_eigs) { 84446e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 8445b03ebc13SStefano Zampini KSPConvergedReason reason; 8446deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 8447c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 8448b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 84496e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 8450b03ebc13SStefano 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); 84516e683305SStefano Zampini for (i=0;i<neigs;i++) { 84526e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 8453c8587f34SStefano Zampini } 84546e683305SStefano Zampini } 84556e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 84566e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 84576e683305SStefano Zampini } 8458e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 84592701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 8460c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 84616e683305SStefano Zampini if (compute_eigs) { 84626e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 84636e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 8464c8587f34SStefano Zampini } 84656e683305SStefano Zampini } 84666e683305SStefano Zampini } 8467bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 8468cbcc2c2aSStefano Zampini /* print additional info */ 8469cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 84706e683305SStefano Zampini /* waits until all processes reaches this point */ 84716e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 84726080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %D\n",pcbddc->current_level);CHKERRQ(ierr); 8473cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8474cbcc2c2aSStefano Zampini } 8475cbcc2c2aSStefano Zampini 84762b510759SStefano Zampini /* free memory */ 8477fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 847843371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_CoarseSolver[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8479c8587f34SStefano Zampini PetscFunctionReturn(0); 8480c8587f34SStefano Zampini } 8481674ae819SStefano Zampini 8482f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 8483f34684f1SStefano Zampini { 8484f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 8485f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 8486f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 8487dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 8488dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 848973be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 8490dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 8491f34684f1SStefano Zampini PetscErrorCode ierr; 8492f34684f1SStefano Zampini 8493f34684f1SStefano Zampini PetscFunctionBegin; 8494f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 84956c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 8496dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 84973bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 8498dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8499dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 85006583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 8501dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 8502dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 8503dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 85046c4ed002SBarry 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); 8505dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 8506dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8507dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 8508dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8509dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8510f34684f1SStefano Zampini 8511f34684f1SStefano Zampini /* check numbering */ 8512f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 8513019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 8514dc456d91SStefano Zampini PetscInt i; 8515b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 8516f34684f1SStefano Zampini 8517f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8518f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8519f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 85201575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8521019a44ceSStefano Zampini /* counter */ 8522019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8523019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 8524019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8525019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8526019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8527019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8528f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 8529f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 8530727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 8531f34684f1SStefano Zampini } 8532f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8533f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8534f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8535e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8536e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8537e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8538e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8539f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8540019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8541f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8542019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 85432c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 854475c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 8545b9b85e73SStefano Zampini set_error = PETSC_TRUE; 85462c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 85476080607fSStefano 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); 8548f34684f1SStefano Zampini } 8549f34684f1SStefano Zampini } 8550019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8551b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8552f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8553f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8554f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 8555f34684f1SStefano Zampini } 8556f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8557f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8558e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8559e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8560f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 85616080607fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %D (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 8562b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 8563ca8b9ea9SStefano Zampini PetscInt *gidxs; 8564ca8b9ea9SStefano Zampini 8565ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 85663bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 8567f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 8568f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8569f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 8570f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 85716080607fSStefano 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); 8572f34684f1SStefano Zampini } 8573f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8574ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 8575f34684f1SStefano Zampini } 8576f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 85771575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8578302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 8579f34684f1SStefano Zampini } 85806080607fSStefano Zampini 8581f34684f1SStefano Zampini /* get back data */ 8582f34684f1SStefano Zampini *coarse_size_n = coarse_size; 8583f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 8584674ae819SStefano Zampini PetscFunctionReturn(0); 8585674ae819SStefano Zampini } 8586674ae819SStefano Zampini 8587a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 8588e456f2a8SStefano Zampini { 8589e456f2a8SStefano Zampini IS localis_t; 8590a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 8591e456f2a8SStefano Zampini PetscScalar *vals; 8592e456f2a8SStefano Zampini PetscErrorCode ierr; 8593e456f2a8SStefano Zampini 8594e456f2a8SStefano Zampini PetscFunctionBegin; 8595a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 8596e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 8597854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 8598e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 8599e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8600a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 8601a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 86021035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 86033151afb1SStefano Zampini ierr = VecSetOption(gwork,VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE);CHKERRQ(ierr); 8604a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 86051035eff8SStefano Zampini } 8606a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 8607e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8608e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 8609a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 8610a7dc3881SStefano Zampini /* now compute set in local ordering */ 8611a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8612a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8613a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8614a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 8615a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8616ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8617e456f2a8SStefano Zampini lsize++; 8618e456f2a8SStefano Zampini } 8619e456f2a8SStefano Zampini } 8620854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 8621a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8622ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8623e456f2a8SStefano Zampini idxs[lsize++] = i; 8624e456f2a8SStefano Zampini } 8625e456f2a8SStefano Zampini } 8626a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8627a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 8628e456f2a8SStefano Zampini *localis = localis_t; 8629e456f2a8SStefano Zampini PetscFunctionReturn(0); 8630e456f2a8SStefano Zampini } 8631906d46d4SStefano Zampini 863208122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 8633b96c3477SStefano Zampini { 8634a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8635b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8636b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 8637a64f4aa4SStefano Zampini Mat S_j; 8638b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 8639b96c3477SStefano Zampini PetscBool free_used_adj; 8640b96c3477SStefano Zampini PetscErrorCode ierr; 8641b96c3477SStefano Zampini 8642b96c3477SStefano Zampini PetscFunctionBegin; 864343371fb9SStefano Zampini ierr = PetscLogEventBegin(PC_BDDC_Schurs[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8644b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 8645b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 864608122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 8647b96c3477SStefano Zampini used_xadj = NULL; 8648b96c3477SStefano Zampini used_adjncy = NULL; 8649b96c3477SStefano Zampini } else { 865008122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 865108122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 865208122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 865308122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 8654b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 8655b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 8656b96c3477SStefano Zampini } else { 86572fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 8658b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 8659b96c3477SStefano Zampini PetscInt nvtxs; 8660b96c3477SStefano Zampini 86612fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 86622fffb893SStefano Zampini if (flg_row) { 8663b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 8664b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 8665b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 8666b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 86672fffb893SStefano Zampini } else { 86682fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 86692fffb893SStefano Zampini used_xadj = NULL; 86702fffb893SStefano Zampini used_adjncy = NULL; 86712fffb893SStefano Zampini } 86722fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 8673b96c3477SStefano Zampini } 8674b96c3477SStefano Zampini } 8675d5574798SStefano Zampini 8676d5574798SStefano Zampini /* setup sub_schurs data */ 8677a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8678df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 8679df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 8680a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 868191af6908SStefano 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); 8682a64f4aa4SStefano Zampini } else { 868372b8c272SStefano Zampini Mat change = NULL; 86849d54b7f4SStefano Zampini Vec scaling = NULL; 8685111315fdSstefano_zampini IS change_primal = NULL, iP; 8686111315fdSstefano_zampini PetscInt benign_n; 8687111315fdSstefano_zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 8688111315fdSstefano_zampini PetscBool isseqaij,need_change = PETSC_FALSE; 8689111315fdSstefano_zampini PetscBool discrete_harmonic = PETSC_FALSE; 8690a3df083aSStefano Zampini 86915feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 86925feab87aSStefano Zampini PetscInt n_vertices; 86935feab87aSStefano Zampini 86945feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 86952034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 86965feab87aSStefano Zampini } 869704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 869804708bb6SStefano Zampini if (!isseqaij) { 869904708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 870004708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 870104708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 870204708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 870304708bb6SStefano Zampini } else { 8704511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 870504708bb6SStefano Zampini } 870604708bb6SStefano Zampini } 8707a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 8708a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 8709ca92afb2SStefano Zampini } else { 8710a3df083aSStefano Zampini benign_n = 0; 8711ca92afb2SStefano Zampini } 8712b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 8713b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 8714b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 871572b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 871622db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 8717b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 871822db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 8719b7ab4a40SStefano Zampini } 8720b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 8721b7ab4a40SStefano 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 */ 8722b7ab4a40SStefano Zampini if (need_change) { 872388c03ad3SStefano Zampini PC_IS *pcisf; 872488c03ad3SStefano Zampini PC_BDDC *pcbddcf; 872588c03ad3SStefano Zampini PC pcf; 872688c03ad3SStefano Zampini 8727e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 872888c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 872988c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 873088c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 8731b9be95fcSstefano_zampini 873288c03ad3SStefano Zampini /* hacks */ 873388c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 873472b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 873572b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 873672b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 873772b8c272SStefano Zampini pcisf->n = pcis->n; 873872b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 873988c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 874088c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 874188c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 874288c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 874388c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 874488c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 874572b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 874688c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 8747b9be95fcSstefano_zampini 8748b9be95fcSstefano_zampini /* setup constraints so that we can get information on primal vertices and change of basis (in local numbering) */ 874988c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 875072b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 875172b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 875272b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 875372b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 8754b9be95fcSstefano_zampini 875588c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 875672b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 875788c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 875888c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 875988c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 876088c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 876188c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 876288c03ad3SStefano Zampini pcf->ops->destroy = NULL; 8763b9be95fcSstefano_zampini pcf->ops->reset = NULL; 876488c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 876588c03ad3SStefano Zampini } 87669d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 8767111315fdSstefano_zampini 8768111315fdSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 8769111315fdSstefano_zampini if (iP) { 8770111315fdSstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)iP),sub_schurs->prefix,"BDDC sub_schurs options","PC");CHKERRQ(ierr); 8771111315fdSstefano_zampini ierr = PetscOptionsBool("-sub_schurs_discrete_harmonic",NULL,NULL,discrete_harmonic,&discrete_harmonic,NULL);CHKERRQ(ierr); 8772111315fdSstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 8773111315fdSstefano_zampini } 8774111315fdSstefano_zampini if (discrete_harmonic) { 8775111315fdSstefano_zampini Mat A; 8776111315fdSstefano_zampini ierr = MatDuplicate(pcbddc->local_mat,MAT_COPY_VALUES,&A);CHKERRQ(ierr); 8777111315fdSstefano_zampini ierr = MatZeroRowsColumnsIS(A,iP,1.0,NULL,NULL);CHKERRQ(ierr); 8778111315fdSstefano_zampini ierr = PetscObjectCompose((PetscObject)A,"__KSPFETIDP_iP",(PetscObject)iP);CHKERRQ(ierr); 8779111315fdSstefano_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); 8780111315fdSstefano_zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 8781111315fdSstefano_zampini } else { 878291af6908SStefano 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); 8783111315fdSstefano_zampini } 878472b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 878572b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 8786ca92afb2SStefano Zampini } 8787d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8788b96c3477SStefano Zampini 8789b96c3477SStefano Zampini /* free adjacency */ 8790b96c3477SStefano Zampini if (free_used_adj) { 8791b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 8792b96c3477SStefano Zampini } 879343371fb9SStefano Zampini ierr = PetscLogEventEnd(PC_BDDC_Schurs[pcbddc->current_level],pc,0,0,0);CHKERRQ(ierr); 8794b96c3477SStefano Zampini PetscFunctionReturn(0); 8795b96c3477SStefano Zampini } 8796b96c3477SStefano Zampini 879708122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 8798b96c3477SStefano Zampini { 8799b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8800b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8801b96c3477SStefano Zampini PCBDDCGraph graph; 8802b96c3477SStefano Zampini PetscErrorCode ierr; 8803b96c3477SStefano Zampini 8804b96c3477SStefano Zampini PetscFunctionBegin; 8805b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 880608122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 88073301b35fSStefano Zampini IS verticesIS,verticescomm; 88083301b35fSStefano Zampini PetscInt vsize,*idxs; 8809b96c3477SStefano Zampini 8810b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 88113301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 88123301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 88133301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 88143301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 8815c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 8816b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 8817be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 8818441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 88193301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 8820b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 8821b96c3477SStefano Zampini } else { 8822b96c3477SStefano Zampini graph = pcbddc->mat_graph; 8823b96c3477SStefano Zampini } 8824e4d548c7SStefano Zampini /* print some info */ 88255c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 8826e4d548c7SStefano Zampini IS vertices; 8827e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 8828c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 8829e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8830e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 8831e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8832e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 88336080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%D)\n",PetscGlobalRank,(int)nv,pcbddc->use_vertices);CHKERRQ(ierr); 88346080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%D)\n",PetscGlobalRank,(int)nedges,pcbddc->use_edges);CHKERRQ(ierr); 88356080607fSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%D)\n",PetscGlobalRank,(int)nfaces,pcbddc->use_faces);CHKERRQ(ierr); 8836e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8837e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8838c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8839e4d548c7SStefano Zampini } 8840b96c3477SStefano Zampini 8841b96c3477SStefano Zampini /* sub_schurs init */ 8842b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 8843b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 8844b334f244SStefano Zampini } 884588113c35SStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,((PetscObject)pc)->prefix,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap,pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 8846a64f4aa4SStefano Zampini 8847b96c3477SStefano Zampini /* free graph struct */ 884808122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 8849b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 8850b96c3477SStefano Zampini } 8851b96c3477SStefano Zampini PetscFunctionReturn(0); 8852b96c3477SStefano Zampini } 8853fa34dd3eSStefano Zampini 8854fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 8855fa34dd3eSStefano Zampini { 8856fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8857fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8858fa34dd3eSStefano Zampini PetscErrorCode ierr; 8859fa34dd3eSStefano Zampini 8860fa34dd3eSStefano Zampini PetscFunctionBegin; 8861fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 8862fa34dd3eSStefano Zampini IS zerodiag = NULL; 88634f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 8864fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 88654f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 886675c01103SStefano Zampini PetscReal norm; 8867fa34dd3eSStefano Zampini PetscInt i; 8868fa34dd3eSStefano Zampini 8869fa34dd3eSStefano Zampini /* B0 and B0_B */ 8870fa34dd3eSStefano Zampini if (zerodiag) { 8871fa34dd3eSStefano Zampini IS dummy; 8872fa34dd3eSStefano Zampini 88734f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 88747dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 8875fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 8876fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 8877fa34dd3eSStefano Zampini } 8878fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 8879fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 8880fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 8881fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8882fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8883fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8884fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8885fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 8886fa34dd3eSStefano Zampini /* S_j */ 8887fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8888fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 8889fa34dd3eSStefano Zampini 8890fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 8891fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 8892fa34dd3eSStefano Zampini /* continuous in primal space */ 8893fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 8894fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8895fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8896fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 88974f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 88984f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 8899fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8900fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8901fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8902fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8903fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8904fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8905fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 8906fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 8907fa34dd3eSStefano Zampini 8908fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 8909fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 8910fa34dd3eSStefano Zampini /* local with Schur */ 8911fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 8912fa34dd3eSStefano Zampini if (zerodiag) { 8913fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 89144f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 8915fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8916fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 8917fa34dd3eSStefano Zampini } 8918fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 8919fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8920fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8921fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8922fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8923fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 8924fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8925fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8926fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 8927fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8928fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8929fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8930fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8931fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8932fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 8933fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 8934fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8935fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8936fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8937fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8938fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8939fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8940fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 8941fa34dd3eSStefano Zampini if (zerodiag) { 8942fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 8943fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 89444f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 8945fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8946fa34dd3eSStefano Zampini } 8947fa34dd3eSStefano Zampini /* BDDC */ 8948fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 8949fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 8950fa34dd3eSStefano Zampini 8951fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 8952fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 8953fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 89546080607fSStefano Zampini ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm);CHKERRQ(ierr); 89554f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 89566080607fSStefano Zampini ierr = PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%D] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i]));CHKERRQ(ierr); 8957fa34dd3eSStefano Zampini } 89584f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 8959fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 8960fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 8961fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 8962fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8963fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 8964fa34dd3eSStefano Zampini } 8965fa34dd3eSStefano Zampini PetscFunctionReturn(0); 8966fa34dd3eSStefano Zampini } 89671e0482f5SStefano Zampini 89681e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 89691e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 89701e0482f5SStefano Zampini { 89711e0482f5SStefano Zampini Mat At; 89721e0482f5SStefano Zampini IS rows; 89731e0482f5SStefano Zampini PetscInt rst,ren; 89741e0482f5SStefano Zampini PetscErrorCode ierr; 89751e0482f5SStefano Zampini PetscLayout rmap; 89761e0482f5SStefano Zampini 89771e0482f5SStefano Zampini PetscFunctionBegin; 89781e0482f5SStefano Zampini rst = ren = 0; 89791e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 89801e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 89811e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 89821e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 89831e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 89841e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 89851e0482f5SStefano Zampini } 8986e07686f2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),ren-rst,rst,1,&rows);CHKERRQ(ierr); 89877dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 89881e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 89891e0482f5SStefano Zampini 89901e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 89911e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 89921e0482f5SStefano Zampini IS from,to; 89931e0482f5SStefano Zampini Vec gvec; 89941e0482f5SStefano Zampini PetscInt lsize; 89951e0482f5SStefano Zampini 89961e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 89971e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 89981e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 89991e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 90001e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 90011e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 90021e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 90031e0482f5SStefano Zampini ierr = MPI_Comm_size(ccomm,&b->size);CHKERRQ(ierr); 90041e0482f5SStefano Zampini ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRQ(ierr); 90051e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 90061e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 90071e0482f5SStefano Zampini b->A = a->A; 90081e0482f5SStefano Zampini b->B = a->B; 90091e0482f5SStefano Zampini 90101e0482f5SStefano Zampini b->donotstash = a->donotstash; 90111e0482f5SStefano Zampini b->roworiented = a->roworiented; 90121e0482f5SStefano Zampini b->rowindices = 0; 90131e0482f5SStefano Zampini b->rowvalues = 0; 90141e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 90151e0482f5SStefano Zampini 90161e0482f5SStefano Zampini (*B)->rmap = rmap; 90171e0482f5SStefano Zampini (*B)->factortype = A->factortype; 90181e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 90191e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 90201e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 90211e0482f5SStefano Zampini 90221e0482f5SStefano Zampini if (a->colmap) { 90231e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 90241e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 90251e0482f5SStefano Zampini #else 90261e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 90271e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 90281e0482f5SStefano Zampini ierr = PetscMemcpy(b->colmap,a->colmap,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 90291e0482f5SStefano Zampini #endif 90301e0482f5SStefano Zampini } else b->colmap = 0; 90311e0482f5SStefano Zampini if (a->garray) { 90321e0482f5SStefano Zampini PetscInt len; 90331e0482f5SStefano Zampini len = a->B->cmap->n; 90341e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 90351e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 90361e0482f5SStefano Zampini if (len) { ierr = PetscMemcpy(b->garray,a->garray,len*sizeof(PetscInt));CHKERRQ(ierr); } 90371e0482f5SStefano Zampini } else b->garray = 0; 90381e0482f5SStefano Zampini 90391e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 90401e0482f5SStefano Zampini b->lvec = a->lvec; 90411e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 90421e0482f5SStefano Zampini 90431e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 90441e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 90451e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 90461e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 90471e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 90481e0482f5SStefano Zampini ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 90491e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 90501e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 90511e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 90521e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 90531e0482f5SStefano Zampini } 90541e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 90551e0482f5SStefano Zampini PetscFunctionReturn(0); 90561e0482f5SStefano Zampini } 9057