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); 224c2151214SStefano 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"); 258213b8bfaSStefano 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 */ 457637e8532SStefano Zampini ierr = PetscCalloc1(ne,&ecount);CHKERRQ(ierr); 458637e8532SStefano Zampini ierr = PetscMalloc1(ne,&eneighs);CHKERRQ(ierr); 459637e8532SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 460637e8532SStefano Zampini for (i=1,cum=0;i<n_neigh;i++) { 461637e8532SStefano Zampini cum += n_shared[i]; 462637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 463637e8532SStefano Zampini ecount[shared[i][j]]++; 464637e8532SStefano Zampini } 465637e8532SStefano Zampini } 466637e8532SStefano Zampini if (ne) { 467637e8532SStefano Zampini ierr = PetscMalloc1(cum,&eneighs[0]);CHKERRQ(ierr); 468637e8532SStefano Zampini } 469637e8532SStefano Zampini for (i=1;i<ne;i++) eneighs[i] = eneighs[i-1] + ecount[i-1]; 470637e8532SStefano Zampini ierr = PetscMemzero(ecount,ne*sizeof(PetscInt));CHKERRQ(ierr); 471637e8532SStefano Zampini for (i=1;i<n_neigh;i++) { 472637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 473637e8532SStefano Zampini PetscInt k = shared[i][j]; 474637e8532SStefano Zampini eneighs[k][ecount[k]] = neigh[i]; 475637e8532SStefano Zampini ecount[k]++; 476637e8532SStefano Zampini } 477637e8532SStefano Zampini } 478637e8532SStefano Zampini for (i=0;i<ne;i++) { 479637e8532SStefano Zampini ierr = PetscSortRemoveDupsInt(&ecount[i],eneighs[i]);CHKERRQ(ierr); 480637e8532SStefano Zampini } 481637e8532SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 482637e8532SStefano Zampini ierr = PetscCalloc1(nv,&vcount);CHKERRQ(ierr); 483637e8532SStefano Zampini ierr = PetscMalloc1(nv,&vneighs);CHKERRQ(ierr); 484637e8532SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 485637e8532SStefano Zampini for (i=1,cum=0;i<n_neigh;i++) { 486637e8532SStefano Zampini cum += n_shared[i]; 487637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 488637e8532SStefano Zampini vcount[shared[i][j]]++; 489637e8532SStefano Zampini } 490637e8532SStefano Zampini } 491637e8532SStefano Zampini if (nv) { 492637e8532SStefano Zampini ierr = PetscMalloc1(cum,&vneighs[0]);CHKERRQ(ierr); 493637e8532SStefano Zampini } 494637e8532SStefano Zampini for (i=1;i<nv;i++) vneighs[i] = vneighs[i-1] + vcount[i-1]; 495637e8532SStefano Zampini ierr = PetscMemzero(vcount,nv*sizeof(PetscInt));CHKERRQ(ierr); 496637e8532SStefano Zampini for (i=1;i<n_neigh;i++) { 497637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 498637e8532SStefano Zampini PetscInt k = shared[i][j]; 499637e8532SStefano Zampini vneighs[k][vcount[k]] = neigh[i]; 500637e8532SStefano Zampini vcount[k]++; 501637e8532SStefano Zampini } 502637e8532SStefano Zampini } 503637e8532SStefano Zampini for (i=0;i<nv;i++) { 504637e8532SStefano Zampini ierr = PetscSortRemoveDupsInt(&vcount[i],vneighs[i]);CHKERRQ(ierr); 505637e8532SStefano Zampini } 506637e8532SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 507637e8532SStefano Zampini 5087d871cd7SStefano Zampini /* need to remove coarse faces' dofs and coarse edges' dirichlet dofs 5097d871cd7SStefano Zampini for proper detection of coarse edges' endpoints */ 51062b0c6f7SStefano Zampini ierr = PetscBTCreate(ne,&btee);CHKERRQ(ierr); 51162b0c6f7SStefano Zampini for (i=0;i<ne;i++) { 5127d871cd7SStefano Zampini if ((ecount[i] > 1 && !PetscBTLookup(btbd,i)) || (ecount[i] == 1 && PetscBTLookup(btb,i))) { 51362b0c6f7SStefano Zampini ierr = PetscBTSet(btee,i);CHKERRQ(ierr); 51462b0c6f7SStefano Zampini } 51562b0c6f7SStefano Zampini } 516637e8532SStefano Zampini ierr = PetscMalloc1(ne,&marks);CHKERRQ(ierr); 51762b0c6f7SStefano Zampini if (!conforming) { 51862b0c6f7SStefano Zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 51962b0c6f7SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 52062b0c6f7SStefano Zampini } 5214e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 522dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 52362b0c6f7SStefano Zampini cum = 0; 524a13144ffSStefano Zampini for (i=0;i<ne;i++) { 525dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 52662b0c6f7SStefano Zampini if (!PetscBTLookup(btee,i)) { 527a13144ffSStefano Zampini marks[cum++] = i; 528dec27d64SStefano Zampini continue; 529dec27d64SStefano Zampini } 530dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 53162b0c6f7SStefano Zampini if (!conforming) { 53262b0c6f7SStefano Zampini if (ii[i+1]-ii[i] != order + 1) { /* every row of G on the coarse edge should list order+1 nodal dofs */ 533a13144ffSStefano Zampini marks[cum++] = i; 534a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 535a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 536a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 537a13144ffSStefano Zampini } 53862b0c6f7SStefano Zampini } else { 53962b0c6f7SStefano Zampini /* every edge dofs should be connected trough a certain number of nodal dofs 54062b0c6f7SStefano Zampini to other edge dofs belonging to coarse edges 54162b0c6f7SStefano Zampini - at most 2 endpoints 54262b0c6f7SStefano Zampini - order-1 interior nodal dofs 54362b0c6f7SStefano Zampini - no undefined nodal dofs (nconn < order) 54462b0c6f7SStefano Zampini */ 54562b0c6f7SStefano Zampini PetscInt ends = 0,ints = 0, undef = 0; 54662b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 54762b0c6f7SStefano Zampini PetscInt v = jj[j],k; 54862b0c6f7SStefano Zampini PetscInt nconn = iit[v+1]-iit[v]; 54962b0c6f7SStefano Zampini for (k=iit[v];k<iit[v+1];k++) if (!PetscBTLookup(btee,jjt[k])) nconn--; 55062b0c6f7SStefano Zampini if (nconn > order) ends++; 55162b0c6f7SStefano Zampini else if (nconn == order) ints++; 55262b0c6f7SStefano Zampini else undef++; 55362b0c6f7SStefano Zampini } 55462b0c6f7SStefano Zampini if (undef || ends > 2 || ints != order -1) { 55562b0c6f7SStefano Zampini marks[cum++] = i; 55662b0c6f7SStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 55762b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 55862b0c6f7SStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 55962b0c6f7SStefano Zampini } 56062b0c6f7SStefano Zampini } 56162b0c6f7SStefano Zampini } 562a13144ffSStefano Zampini } 563dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 564dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 565dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 566dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 567a13144ffSStefano Zampini } 568dec27d64SStefano Zampini } 56962b0c6f7SStefano Zampini ierr = PetscBTDestroy(&btee);CHKERRQ(ierr); 570dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 5714e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 57262b0c6f7SStefano Zampini if (!conforming) { 57362b0c6f7SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 57462b0c6f7SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 57562b0c6f7SStefano Zampini } 5764e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 577637e8532SStefano Zampini 578b03ebc13SStefano Zampini /* identify splitpoints and corner candidates */ 5794e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 580a13144ffSStefano Zampini if (print) { 5814e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 5824e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 5834e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 584a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 585a13144ffSStefano Zampini } 586a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 587dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 588a13144ffSStefano Zampini for (i=0;i<nv;i++) { 589637e8532SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i], vc = vcount[i]; 5907d871cd7SStefano Zampini PetscBool sneighs = PETSC_TRUE, bdir = PETSC_FALSE; 591b03ebc13SStefano Zampini if (!order) { /* variable order */ 592dec27d64SStefano Zampini PetscReal vorder = 0.; 593dec27d64SStefano Zampini 594dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 595dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 596dec27d64SStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%d)",vorder,test); 597dec27d64SStefano Zampini ord = 1; 598dec27d64SStefano Zampini } 599a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 600dec27d64SStefano 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); 601a13144ffSStefano Zampini #endif 602637e8532SStefano Zampini for (j=ii[i];j<ii[i+1] && sneighs;j++) { 6037d871cd7SStefano Zampini if (PetscBTLookup(btbd,jj[j])) { 6047d871cd7SStefano Zampini bdir = PETSC_TRUE; 6057d871cd7SStefano Zampini break; 6067d871cd7SStefano Zampini } 607637e8532SStefano Zampini if (vc != ecount[jj[j]]) { 608637e8532SStefano Zampini sneighs = PETSC_FALSE; 609637e8532SStefano Zampini } else { 610637e8532SStefano Zampini PetscInt k,*vn = vneighs[i], *en = eneighs[jj[j]]; 611637e8532SStefano Zampini for (k=0;k<vc;k++) { 612637e8532SStefano Zampini if (vn[k] != en[k]) { 613637e8532SStefano Zampini sneighs = PETSC_FALSE; 614637e8532SStefano Zampini break; 615637e8532SStefano Zampini } 616637e8532SStefano Zampini } 617637e8532SStefano Zampini } 618637e8532SStefano Zampini } 6197d871cd7SStefano Zampini if (!sneighs || test >= 3*ord || bdir) { /* splitpoints */ 6207d871cd7SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %d (%d %d %d)\n",i,!sneighs,test >= 3*ord,bdir); 621a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 622dec27d64SStefano Zampini } else if (test == ord) { 623b03ebc13SStefano Zampini if (order == 1 || (!order && ii[i+1]-ii[i] == 1)) { 624a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %d\n",i); 625a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 626a13144ffSStefano Zampini } else { 627a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %d\n",i); 628a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 629a13144ffSStefano Zampini } 630a13144ffSStefano Zampini } 631a13144ffSStefano Zampini } 632637e8532SStefano Zampini ierr = PetscFree(ecount);CHKERRQ(ierr); 633637e8532SStefano Zampini ierr = PetscFree(vcount);CHKERRQ(ierr); 634637e8532SStefano Zampini if (ne) { 635637e8532SStefano Zampini ierr = PetscFree(eneighs[0]);CHKERRQ(ierr); 636637e8532SStefano Zampini } 637637e8532SStefano Zampini if (nv) { 638637e8532SStefano Zampini ierr = PetscFree(vneighs[0]);CHKERRQ(ierr); 639637e8532SStefano Zampini } 640637e8532SStefano Zampini ierr = PetscFree(eneighs);CHKERRQ(ierr); 641637e8532SStefano Zampini ierr = PetscFree(vneighs);CHKERRQ(ierr); 6427d871cd7SStefano Zampini ierr = PetscBTDestroy(&btbd);CHKERRQ(ierr); 643b03ebc13SStefano Zampini 644b03ebc13SStefano Zampini /* a candidate is valid if it is connected to another candidate via a non-primal edge dof */ 645b03ebc13SStefano Zampini if (order != 1) { 646b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"INSPECTING CANDIDATES\n"); 647b03ebc13SStefano Zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 648b03ebc13SStefano Zampini for (i=0;i<nv;i++) { 649b03ebc13SStefano Zampini if (PetscBTLookup(btvcand,i)) { 650b03ebc13SStefano Zampini PetscBool found = PETSC_FALSE; 651b03ebc13SStefano Zampini for (j=ii[i];j<ii[i+1] && !found;j++) { 652b03ebc13SStefano Zampini PetscInt k,e = jj[j]; 653b03ebc13SStefano Zampini if (PetscBTLookup(bte,e)) continue; 654b03ebc13SStefano Zampini for (k=iit[e];k<iit[e+1];k++) { 655b03ebc13SStefano Zampini PetscInt v = jjt[k]; 656b03ebc13SStefano Zampini if (v != i && PetscBTLookup(btvcand,v)) { 657b03ebc13SStefano Zampini found = PETSC_TRUE; 658b03ebc13SStefano Zampini break; 659b03ebc13SStefano Zampini } 660b03ebc13SStefano Zampini } 661b03ebc13SStefano Zampini } 662b03ebc13SStefano Zampini if (!found) { 663b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d CLEARED\n",i); 664b03ebc13SStefano Zampini ierr = PetscBTClear(btvcand,i);CHKERRQ(ierr); 665b03ebc13SStefano Zampini } else { 666b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d ACCEPTED\n",i); 667b03ebc13SStefano Zampini } 668b03ebc13SStefano Zampini } 669b03ebc13SStefano Zampini } 670b03ebc13SStefano Zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 671b03ebc13SStefano Zampini } 672dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 673a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 674b03ebc13SStefano Zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 675a13144ffSStefano Zampini 676a13144ffSStefano Zampini /* Get the local G^T explicitly */ 6770569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 678a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 6794e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 680a13144ffSStefano Zampini 6814e64d54eSstefano_zampini /* Mark interior nodal dofs */ 682a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 6834e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 684a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 685a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 6864e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 687a13144ffSStefano Zampini } 688a13144ffSStefano Zampini } 689a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 690a13144ffSStefano Zampini 691a13144ffSStefano Zampini /* communicate corners and splitpoints */ 692a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 693a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 694a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 695a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 696a13144ffSStefano Zampini 697a13144ffSStefano Zampini if (print) { 698a13144ffSStefano Zampini IS tbz; 699a13144ffSStefano Zampini 700a13144ffSStefano Zampini cum = 0; 701a13144ffSStefano Zampini for (i=0;i<nv;i++) 702a13144ffSStefano Zampini if (sfvleaves[i]) 703a13144ffSStefano Zampini vmarks[cum++] = i; 704a13144ffSStefano Zampini 705a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 706a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 707a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 708a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 709a13144ffSStefano Zampini } 710a13144ffSStefano Zampini 711a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 712a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 713a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 714a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 715a13144ffSStefano Zampini 7164e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 7174e64d54eSstefano_zampini and interior nodal dofs */ 718a13144ffSStefano Zampini cum = 0; 719a13144ffSStefano Zampini for (i=0;i<nv;i++) { 720a13144ffSStefano Zampini if (sfvleaves[i]) { 721a13144ffSStefano Zampini vmarks[cum++] = i; 722a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 723a13144ffSStefano Zampini } 7244e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 725a13144ffSStefano Zampini } 7264e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 727a13144ffSStefano Zampini if (print) { 728a13144ffSStefano Zampini IS tbz; 729a13144ffSStefano Zampini 730a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 7314e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 732a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 733a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 734a13144ffSStefano Zampini } 735a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 736a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 737a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 738a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 739a13144ffSStefano Zampini 740a13144ffSStefano Zampini /* Recompute G */ 741a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 742a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 743a13144ffSStefano Zampini if (print) { 744a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 745a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 746a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 747a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 748a13144ffSStefano Zampini } 749a13144ffSStefano Zampini 750a13144ffSStefano Zampini /* Get primal dofs (if any) */ 751a13144ffSStefano Zampini cum = 0; 752a13144ffSStefano Zampini for (i=0;i<ne;i++) { 753a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 754a13144ffSStefano Zampini } 755c2151214SStefano Zampini if (fl2g) { 756c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 757c2151214SStefano Zampini } 758a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 759a13144ffSStefano Zampini if (print) { 760a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 761a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 762a13144ffSStefano Zampini } 763a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 764c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 765a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 766a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 767a13144ffSStefano Zampini 768a13144ffSStefano Zampini /* Compute edge connectivity */ 769a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 770a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 771a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 772c2151214SStefano Zampini if (fl2g) { 773c2151214SStefano Zampini PetscBT btf; 774c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 775c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 776c2151214SStefano Zampini 777c2151214SStefano Zampini /* create CSR for all local dofs */ 778c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 779c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 780c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Invalid size of CSR graph %d. Should be %d\n",pcbddc->mat_graph->nvtxs_csr,n); 781c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 782c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 783c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 784c2151214SStefano Zampini rest = PETSC_TRUE; 785c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 786c2151214SStefano Zampini } else { 787c2151214SStefano Zampini free = PETSC_TRUE; 788c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 789c2151214SStefano Zampini iiu[0] = 0; 790c2151214SStefano Zampini for (i=0;i<n;i++) { 791c2151214SStefano Zampini iiu[i+1] = i+1; 792c2151214SStefano Zampini jju[i] = -1; 793d904f53bSStefano Zampini } 794c2151214SStefano Zampini } 795c2151214SStefano Zampini 796c2151214SStefano Zampini /* import sizes of CSR */ 797c2151214SStefano Zampini iia[0] = 0; 798c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 799c2151214SStefano Zampini 800c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 801c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 802c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 803c2151214SStefano Zampini for (i=0;i<ne;i++) { 804c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 805c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 806c2151214SStefano Zampini } 807c2151214SStefano Zampini 808c2151214SStefano Zampini /* iia in CSR */ 809c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 810c2151214SStefano Zampini 811c2151214SStefano Zampini /* jja in CSR */ 812c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 813c2151214SStefano Zampini for (i=0;i<n;i++) 814c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 815c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 816c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 817c2151214SStefano Zampini 818c2151214SStefano Zampini /* map edge dofs connectivity */ 8191e0482f5SStefano Zampini if (jj) { 820c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 821c2151214SStefano Zampini for (i=0;i<ne;i++) { 822c2151214SStefano Zampini PetscInt e = idxs[i]; 823c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 824c2151214SStefano Zampini } 8251e0482f5SStefano Zampini } 826c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 827c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 828c2151214SStefano Zampini if (rest) { 829c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 830c2151214SStefano Zampini } 831c2151214SStefano Zampini if (free) { 832c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 833c2151214SStefano Zampini } 834c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 835c2151214SStefano Zampini } else { 836c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 837c2151214SStefano Zampini } 838c2151214SStefano Zampini 839a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 840a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 841213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 842a13144ffSStefano Zampini 843a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 844c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 845a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 846a13144ffSStefano Zampini 847c2151214SStefano Zampini if (fl2g) { 848c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 849c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 850c2151214SStefano Zampini for (i=0;i<nee;i++) { 851c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 852c2151214SStefano Zampini } 853c2151214SStefano Zampini } else { 854c2151214SStefano Zampini eedges = alleedges; 855c2151214SStefano Zampini primals = allprimals; 856c2151214SStefano Zampini } 857c2151214SStefano Zampini 858a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 859a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 860c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 861c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 862c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 863c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 864c2151214SStefano Zampini if (print) { 865c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 866c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 867c2151214SStefano Zampini } 868c2151214SStefano Zampini 869c2151214SStefano Zampini maxsize = 0; 870a13144ffSStefano Zampini for (i=0;i<nee;i++) { 871a13144ffSStefano Zampini PetscInt size,mark = i+1; 872a13144ffSStefano Zampini 873a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 874a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 875a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 876a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 877a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 878a13144ffSStefano Zampini } 879a13144ffSStefano Zampini 880a13144ffSStefano Zampini /* Find coarse edge endpoints */ 881a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 882a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 883a13144ffSStefano Zampini for (i=0;i<nee;i++) { 884a13144ffSStefano Zampini PetscInt mark = i+1,size; 885a13144ffSStefano Zampini 886a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8871e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8881e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 889a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 890a13144ffSStefano Zampini if (print) { 891a13144ffSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %d\n",i); 892a13144ffSStefano Zampini ISView(eedges[i],NULL); 893a13144ffSStefano Zampini } 894a13144ffSStefano Zampini for (j=0;j<size;j++) { 895a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 896a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %d\n",ee); 897a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 898a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %d\n",jj[k]); 899a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 900a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %d\n",jj[k]); 901a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 902a13144ffSStefano Zampini PetscInt k2; 903a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 904a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 905c2151214SStefano 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])); 906c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 907c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 908c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 909a13144ffSStefano Zampini corner = PETSC_TRUE; 910a13144ffSStefano Zampini break; 911a13144ffSStefano Zampini } 912a13144ffSStefano Zampini } 913a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 914a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %d\n",jj[k]); 915a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 916a13144ffSStefano Zampini } else { 917a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 918a13144ffSStefano Zampini } 919a13144ffSStefano Zampini } 920a13144ffSStefano Zampini } 921a13144ffSStefano Zampini } 922a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 923a13144ffSStefano Zampini } 924a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 925a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 926c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 927a13144ffSStefano Zampini 928a13144ffSStefano Zampini /* Reset marked primal dofs */ 929a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 930a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 931a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 932a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 933a13144ffSStefano Zampini 9340569b399SStefano Zampini /* Now use the initial lG */ 9350569b399SStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 9360569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 9370569b399SStefano Zampini lG = lGinit; 9380569b399SStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 9390569b399SStefano Zampini 940a13144ffSStefano Zampini /* Compute extended cols indices */ 941b03ebc13SStefano Zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 942b03ebc13SStefano Zampini ierr = PetscBTCreate(nee,&bter);CHKERRQ(ierr); 943a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 944a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 945a13144ffSStefano Zampini i *= maxsize; 946b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 947a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 948a13144ffSStefano Zampini eerr = PETSC_FALSE; 949a13144ffSStefano Zampini for (i=0;i<nee;i++) { 950b03ebc13SStefano Zampini PetscInt size,found = 0; 951a13144ffSStefano Zampini 952a13144ffSStefano Zampini cum = 0; 953a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 9541e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 9551e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 956a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 957b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 958a13144ffSStefano Zampini for (j=0;j<size;j++) { 959a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 960b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 961b03ebc13SStefano Zampini PetscInt vv = jj[k]; 962b03ebc13SStefano Zampini if (!PetscBTLookup(btv,vv)) extrow[cum++] = vv; 963b03ebc13SStefano Zampini else if (!PetscBTLookupSet(btvc,vv)) found++; 964b03ebc13SStefano Zampini } 965a13144ffSStefano Zampini } 966a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 967a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 968a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 969a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 970a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 971a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 972a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 973b03ebc13SStefano Zampini if (cum != size -1 || found != 2) { 974b03ebc13SStefano Zampini ierr = PetscBTSet(bter,i);CHKERRQ(ierr); 975a13144ffSStefano Zampini if (print) { 976a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 977a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 978a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 979a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 980a13144ffSStefano Zampini } 981a13144ffSStefano Zampini eerr = PETSC_TRUE; 982a13144ffSStefano Zampini } 983a13144ffSStefano Zampini } 9844e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 985a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 986a13144ffSStefano Zampini if (done) { 987a13144ffSStefano Zampini PetscInt *newprimals; 988a13144ffSStefano Zampini 989a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 990a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 991a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 992a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 993a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 9940569b399SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 995b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"DOING SECOND PASS (eerr %d)\n",eerr); 996a13144ffSStefano Zampini for (i=0;i<nee;i++) { 997b03ebc13SStefano Zampini PetscBool has_candidates = PETSC_FALSE; 998b03ebc13SStefano Zampini if (PetscBTLookup(bter,i)) { 999a13144ffSStefano Zampini PetscInt size,mark = i+1; 1000a13144ffSStefano Zampini 1001a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 1002a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1003c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 1004a13144ffSStefano Zampini for (j=0;j<size;j++) { 1005a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 1006b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"Inspecting edge dof %d [%d %d)\n",ee,ii[ee],ii[ee+1]); 1007a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 1008a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 1009a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 1010a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 1011b03ebc13SStefano Zampini has_candidates = PETSC_TRUE; 1012b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Candidate set to vertex %d\n",vv); 1013a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 1014a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 1015a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 1016a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 1017a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 1018b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected edge dof set to primal %d\n",ee2); 1019a13144ffSStefano Zampini newprimals[cum++] = ee2; 1020a13144ffSStefano Zampini /* finally set the new corners */ 1021a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 1022b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected nodal dof set to vertex %d\n",jj[k3]); 1023a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 1024a13144ffSStefano Zampini } 1025a13144ffSStefano Zampini } 1026a13144ffSStefano Zampini } 1027b03ebc13SStefano Zampini } else { 1028b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Not a candidate vertex %d\n",jj[k]); 1029a13144ffSStefano Zampini } 1030a13144ffSStefano Zampini } 1031a13144ffSStefano Zampini } 1032b03ebc13SStefano Zampini if (!has_candidates) { /* circular edge */ 1033b03ebc13SStefano Zampini PetscInt k, ee = idxs[0],*tmarks; 1034b03ebc13SStefano Zampini 1035b03ebc13SStefano Zampini ierr = PetscCalloc1(ne,&tmarks);CHKERRQ(ierr); 1036b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Circular edge %d\n",i); 1037b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 1038b03ebc13SStefano Zampini PetscInt k2; 1039b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Set to corner %d\n",jj[k]); 1040b03ebc13SStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 1041b03ebc13SStefano Zampini for (k2=iit[jj[k]];k2<iit[jj[k]+1];k2++) tmarks[jjt[k2]]++; 1042b03ebc13SStefano Zampini } 1043b03ebc13SStefano Zampini for (j=0;j<size;j++) { 1044b03ebc13SStefano Zampini if (tmarks[idxs[j]] > 1) { 1045b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Edge dof set to primal %d\n",idxs[j]); 1046b03ebc13SStefano Zampini newprimals[cum++] = idxs[j]; 1047b03ebc13SStefano Zampini } 1048b03ebc13SStefano Zampini } 1049b03ebc13SStefano Zampini ierr = PetscFree(tmarks);CHKERRQ(ierr); 1050b03ebc13SStefano Zampini } 1051a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1052a13144ffSStefano Zampini } 1053a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 1054a13144ffSStefano Zampini } 1055b03ebc13SStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 10560569b399SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 1057a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 1058c2151214SStefano Zampini if (fl2g) { 1059c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 1060c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1061c2151214SStefano Zampini for (i=0;i<nee;i++) { 1062c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1063c2151214SStefano Zampini } 1064c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1065c2151214SStefano Zampini } 1066c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1067a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 1068a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 1069a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 1070a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1071a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 1072213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 1073c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1074c2151214SStefano Zampini if (fl2g) { 1075c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 1076c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 1077c2151214SStefano Zampini for (i=0;i<nee;i++) { 1078c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 1079c2151214SStefano Zampini } 1080c2151214SStefano Zampini } else { 1081c2151214SStefano Zampini eedges = alleedges; 1082c2151214SStefano Zampini primals = allprimals; 1083c2151214SStefano Zampini } 1084b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 1085a13144ffSStefano Zampini 1086a13144ffSStefano Zampini /* Mark again */ 1087a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 1088a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1089a13144ffSStefano Zampini PetscInt size,mark = i+1; 1090a13144ffSStefano Zampini 1091a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 1092a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1093a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 1094a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1095a13144ffSStefano Zampini } 1096a13144ffSStefano Zampini if (print) { 1097a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 1098a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 1099a13144ffSStefano Zampini } 1100a13144ffSStefano Zampini 1101a13144ffSStefano Zampini /* Recompute extended cols */ 1102a13144ffSStefano Zampini eerr = PETSC_FALSE; 1103a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1104a13144ffSStefano Zampini PetscInt size; 1105a13144ffSStefano Zampini 1106a13144ffSStefano Zampini cum = 0; 1107a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 11081e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 11091e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 1110a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1111a13144ffSStefano Zampini for (j=0;j<size;j++) { 1112a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 11131e0482f5SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 1114a13144ffSStefano Zampini } 1115a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1116a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 1117a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 1118a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 1119a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 1120a13144ffSStefano Zampini if (cum != size -1) { 1121a13144ffSStefano Zampini if (print) { 1122a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 1123a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 1124a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 1125a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 1126a13144ffSStefano Zampini } 1127a13144ffSStefano Zampini eerr = PETSC_TRUE; 1128a13144ffSStefano Zampini } 1129a13144ffSStefano Zampini } 1130a13144ffSStefano Zampini } 1131a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1132a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 1133b03ebc13SStefano Zampini ierr = PetscBTDestroy(&bter);CHKERRQ(ierr); 11347d871cd7SStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 1135a13144ffSStefano Zampini /* an error should not occur at this point */ 1136a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 1137a13144ffSStefano Zampini 11384e64d54eSstefano_zampini /* Check the number of endpoints */ 11390569b399SStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1140b03ebc13SStefano Zampini ierr = PetscMalloc1(2*nee,&corners);CHKERRQ(ierr); 1141b03ebc13SStefano Zampini ierr = PetscMalloc1(nee,&cedges);CHKERRQ(ierr); 11424e64d54eSstefano_zampini for (i=0;i<nee;i++) { 1143b03ebc13SStefano Zampini PetscInt size, found = 0, gc[2]; 11444e64d54eSstefano_zampini 1145b03ebc13SStefano Zampini /* init with defaults */ 1146b03ebc13SStefano Zampini cedges[i] = corners[i*2] = corners[i*2+1] = -1; 11474e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 11481e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 11491e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 11504e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1151b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 11524e64d54eSstefano_zampini for (j=0;j<size;j++) { 11534e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 11544e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 11554e64d54eSstefano_zampini PetscInt vv = jj[k]; 11564e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 1157b03ebc13SStefano Zampini if (found == 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found more then two corners for edge %d\n",i); 1158b03ebc13SStefano Zampini corners[i*2+found++] = vv; 11594e64d54eSstefano_zampini } 11604e64d54eSstefano_zampini } 11614e64d54eSstefano_zampini } 1162b03ebc13SStefano Zampini if (found != 2) { 1163b03ebc13SStefano Zampini PetscInt e; 1164b03ebc13SStefano Zampini if (fl2g) { 1165b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,1,idxs,&e);CHKERRQ(ierr); 1166b03ebc13SStefano Zampini } else { 1167b03ebc13SStefano Zampini e = idxs[0]; 1168b03ebc13SStefano Zampini } 1169b03ebc13SStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %d corners for edge %d (astart %d, estart %d)\n",found,i,e,idxs[0]); 1170b03ebc13SStefano Zampini } 1171eee23b56SStefano Zampini 1172eee23b56SStefano Zampini /* get primal dof index on this coarse edge */ 1173b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,2,corners+2*i,gc);CHKERRQ(ierr); 1174b03ebc13SStefano Zampini if (gc[0] > gc[1]) { 1175b03ebc13SStefano Zampini PetscInt swap = corners[2*i]; 1176b03ebc13SStefano Zampini corners[2*i] = corners[2*i+1]; 1177b03ebc13SStefano Zampini corners[2*i+1] = swap; 1178b03ebc13SStefano Zampini } 1179eee23b56SStefano Zampini cedges[i] = idxs[size-1]; 11804e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1181b03ebc13SStefano 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]); 11824e64d54eSstefano_zampini } 11830569b399SStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 11844e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 11854e64d54eSstefano_zampini 1186a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 1187a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 1188a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 1189a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 1190a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1191a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1192a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 1193a13144ffSStefano Zampini 1194a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1195a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 1196a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 1197a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 1198a13144ffSStefano Zampini if (emax < emarks[j]) { 1199a13144ffSStefano Zampini emax = emarks[j]; 1200a13144ffSStefano Zampini eemax = j; 1201a13144ffSStefano Zampini } 1202a13144ffSStefano Zampini } 1203a13144ffSStefano Zampini /* not relevant for edges */ 1204a13144ffSStefano Zampini if (!eemax) continue; 1205a13144ffSStefano Zampini 1206a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 1207a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 1208c2151214SStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Found 2 coarse edges (id %d and %d) connected through the %d nodal dof at edge dof %d\n",marks[jj[j]]-1,eemax,i,jj[j]); 1209a13144ffSStefano Zampini } 1210a13144ffSStefano Zampini } 1211a13144ffSStefano Zampini } 1212a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 1213a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1214a13144ffSStefano Zampini #endif 1215a13144ffSStefano Zampini 1216a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 1217a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1218a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 1219a13144ffSStefano Zampini extmem *= maxsize; 1220a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 1221a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 1222a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 1223a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1224a13144ffSStefano Zampini PetscInt mark = 0,size,start; 1225213b8bfaSStefano Zampini 1226a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1227a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 1228a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 1229a13144ffSStefano Zampini mark = marks[jj[j]]; 1230a13144ffSStefano Zampini 1231a13144ffSStefano Zampini /* not relevant */ 1232a13144ffSStefano Zampini if (!mark) continue; 1233a13144ffSStefano Zampini 1234a13144ffSStefano Zampini /* import extended row */ 1235a13144ffSStefano Zampini mark--; 1236a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 1237a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 1238a13144ffSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %d > %d",extrowcum[mark] + size,extmem); 1239a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 1240a13144ffSStefano Zampini extrowcum[mark] += size; 1241a13144ffSStefano Zampini } 1242a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1243213b8bfaSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 1244213b8bfaSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 1245213b8bfaSStefano Zampini 1246213b8bfaSStefano Zampini /* Compress extrows */ 1247a13144ffSStefano Zampini cum = 0; 1248a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1249a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 1250a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 1251a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 1252a13144ffSStefano Zampini cum = PetscMax(cum,size); 1253a13144ffSStefano Zampini } 1254a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 1255a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 1256a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 1257a13144ffSStefano Zampini 1258a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 1259a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 1260a13144ffSStefano Zampini 1261a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 1262a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1263c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 1264c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 1265a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 1266a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 1267a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 12681e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(T,al2g,al2g);CHKERRQ(ierr); 1269a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 1270a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1271213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&al2g);CHKERRQ(ierr); 1272a13144ffSStefano Zampini 1273a13144ffSStefano Zampini /* Defaults to identity */ 1274c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 1275a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 1276a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 1277a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 1278a13144ffSStefano Zampini 12791e0482f5SStefano Zampini /* Create discrete gradient for the coarser level if needed */ 12801e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 12811e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 12821e0482f5SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 12831e0482f5SStefano Zampini ISLocalToGlobalMapping cel2g,cvl2g; 12841e0482f5SStefano Zampini IS wis,gwis; 12851e0482f5SStefano Zampini PetscInt cnv,cne; 12861e0482f5SStefano Zampini 12871e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,nee,cedges,PETSC_COPY_VALUES,&wis);CHKERRQ(ierr); 12881e0482f5SStefano Zampini if (fl2g) { 12891e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(fl2g,wis,&pcbddc->nedclocal);CHKERRQ(ierr); 12901e0482f5SStefano Zampini } else { 12911e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)wis);CHKERRQ(ierr); 12921e0482f5SStefano Zampini pcbddc->nedclocal = wis; 12931e0482f5SStefano Zampini } 12941e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,wis,&gwis);CHKERRQ(ierr); 12951e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12961e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cne,&wis);CHKERRQ(ierr); 12971e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cel2g);CHKERRQ(ierr); 12981e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12991e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 13001e0482f5SStefano Zampini 13011e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,2*nee,corners,PETSC_USE_POINTER,&wis);CHKERRQ(ierr); 13021e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(vl2g,wis,&gwis);CHKERRQ(ierr); 13031e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 13041e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cnv,&wis);CHKERRQ(ierr); 13051e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cvl2g);CHKERRQ(ierr); 13061e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 13071e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 13081e0482f5SStefano Zampini 13091e0482f5SStefano Zampini ierr = MatCreate(comm,&pcbddc->nedcG);CHKERRQ(ierr); 13101e0482f5SStefano Zampini ierr = MatSetSizes(pcbddc->nedcG,PETSC_DECIDE,PETSC_DECIDE,cne,cnv);CHKERRQ(ierr); 13111e0482f5SStefano Zampini ierr = MatSetType(pcbddc->nedcG,MATAIJ);CHKERRQ(ierr); 13121e0482f5SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->nedcG,2,NULL);CHKERRQ(ierr); 13131e0482f5SStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->nedcG,2,NULL,2,NULL);CHKERRQ(ierr); 13141e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->nedcG,cel2g,cvl2g);CHKERRQ(ierr); 13151e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cel2g);CHKERRQ(ierr); 13161e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cvl2g);CHKERRQ(ierr); 13171e0482f5SStefano Zampini } 1318213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 13191e0482f5SStefano Zampini 13201e0482f5SStefano Zampini #if defined(PRINT_GDET) 13211e0482f5SStefano Zampini inc = 0; 13221e0482f5SStefano Zampini lev = pcbddc->current_level; 13231e0482f5SStefano Zampini #endif 1324213b8bfaSStefano Zampini 1325213b8bfaSStefano Zampini /* Insert values in the change of basis matrix */ 1326a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1327a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 13281e0482f5SStefano Zampini IS cornersis = NULL; 13291e0482f5SStefano Zampini PetscScalar cvals[2]; 1330a13144ffSStefano Zampini 13311e0482f5SStefano Zampini if (pcbddc->nedcG) { 13321e0482f5SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,2,corners+2*i,PETSC_USE_POINTER,&cornersis);CHKERRQ(ierr); 13331e0482f5SStefano Zampini } 13341e0482f5SStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],cornersis,&Gins,&GKins,cvals,work,rwork);CHKERRQ(ierr); 1335a13144ffSStefano Zampini if (Gins && GKins) { 1336a13144ffSStefano Zampini PetscScalar *data; 1337a13144ffSStefano Zampini const PetscInt *rows,*cols; 1338a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 1339a13144ffSStefano Zampini 1340a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 1341a13144ffSStefano Zampini /* H1 */ 1342a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 1343a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 1344a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 1345a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 1346a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 1347a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 1348a13144ffSStefano Zampini /* complement */ 1349a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 13501e0482f5SStefano Zampini if (!ncc) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Constant function has not been generated for coarse edge %d",i); 1351213b8bfaSStefano 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); 1352213b8bfaSStefano 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); 1353a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 1354a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 1355a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 13561e0482f5SStefano Zampini 13571e0482f5SStefano Zampini /* coarse discrete gradient */ 13581e0482f5SStefano Zampini if (pcbddc->nedcG) { 13591e0482f5SStefano Zampini PetscInt cols[2]; 13601e0482f5SStefano Zampini 13611e0482f5SStefano Zampini cols[0] = 2*i; 13621e0482f5SStefano Zampini cols[1] = 2*i+1; 13631e0482f5SStefano Zampini ierr = MatSetValuesLocal(pcbddc->nedcG,1,&i,2,cols,cvals,INSERT_VALUES);CHKERRQ(ierr); 13641e0482f5SStefano Zampini } 1365a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 1366a13144ffSStefano Zampini } 1367a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 1368a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 13691e0482f5SStefano Zampini ierr = ISDestroy(&cornersis);CHKERRQ(ierr); 1370a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 1371a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 1372a13144ffSStefano Zampini } 1373213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 1374a13144ffSStefano Zampini 1375a13144ffSStefano Zampini /* Start assembling */ 1376a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13771e0482f5SStefano Zampini if (pcbddc->nedcG) { 13781e0482f5SStefano Zampini ierr = MatAssemblyBegin(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13791e0482f5SStefano Zampini } 1380a13144ffSStefano Zampini 1381a13144ffSStefano Zampini /* Free */ 1382c2151214SStefano Zampini if (fl2g) { 1383c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1384c2151214SStefano Zampini for (i=0;i<nee;i++) { 1385c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1386c2151214SStefano Zampini } 1387c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1388c2151214SStefano Zampini } 1389eee23b56SStefano Zampini 1390eee23b56SStefano Zampini /* hack mat_graph with primal dofs on the coarse edges */ 1391eee23b56SStefano Zampini { 1392eee23b56SStefano Zampini PCBDDCGraph graph = pcbddc->mat_graph; 1393eee23b56SStefano Zampini PetscInt *oqueue = graph->queue; 1394eee23b56SStefano Zampini PetscInt *ocptr = graph->cptr; 1395eee23b56SStefano Zampini PetscInt ncc,*idxs; 1396eee23b56SStefano Zampini 1397eee23b56SStefano Zampini /* find first primal edge */ 1398eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1399eee23b56SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1400eee23b56SStefano Zampini } else { 1401eee23b56SStefano Zampini if (fl2g) { 1402eee23b56SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,nee,cedges,cedges);CHKERRQ(ierr); 1403eee23b56SStefano Zampini } 1404eee23b56SStefano Zampini idxs = cedges; 1405eee23b56SStefano Zampini } 1406eee23b56SStefano Zampini cum = 0; 1407eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1408eee23b56SStefano Zampini 1409eee23b56SStefano Zampini /* adapt connected components */ 1410eee23b56SStefano Zampini ierr = PetscMalloc2(graph->nvtxs+1,&graph->cptr,ocptr[graph->ncc],&graph->queue);CHKERRQ(ierr); 1411eee23b56SStefano Zampini graph->cptr[0] = 0; 1412eee23b56SStefano Zampini for (i=0,ncc=0;i<graph->ncc;i++) { 1413eee23b56SStefano Zampini PetscInt lc = ocptr[i+1]-ocptr[i]; 1414eee23b56SStefano Zampini if (cum != nee && oqueue[ocptr[i+1]-1] == cedges[cum]) { /* this cc has a primal dof */ 1415eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc]+1; 1416eee23b56SStefano Zampini graph->queue[graph->cptr[ncc]] = cedges[cum]; 1417eee23b56SStefano Zampini ncc++; 1418eee23b56SStefano Zampini lc--; 1419eee23b56SStefano Zampini cum++; 1420eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1421eee23b56SStefano Zampini } 1422eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc] + lc; 1423eee23b56SStefano Zampini for (j=0;j<lc;j++) graph->queue[graph->cptr[ncc]+j] = oqueue[ocptr[i]+j]; 1424eee23b56SStefano Zampini ncc++; 1425eee23b56SStefano Zampini } 1426eee23b56SStefano Zampini graph->ncc = ncc; 1427eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1428eee23b56SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1429eee23b56SStefano Zampini } 1430eee23b56SStefano Zampini ierr = PetscFree2(ocptr,oqueue);CHKERRQ(ierr); 1431eee23b56SStefano Zampini } 1432213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 1433c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1434c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1435213b8bfaSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1436eee23b56SStefano Zampini 1437c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1438a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 1439a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 1440b03ebc13SStefano Zampini ierr = PetscFree(corners);CHKERRQ(ierr); 1441b03ebc13SStefano Zampini ierr = PetscFree(cedges);CHKERRQ(ierr); 1442a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 1443a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 1444a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 1445a13144ffSStefano Zampini 1446a13144ffSStefano Zampini /* Complete assembling */ 1447a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14481e0482f5SStefano Zampini if (pcbddc->nedcG) { 14491e0482f5SStefano Zampini ierr = MatAssemblyEnd(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14501e0482f5SStefano Zampini #if 0 14511e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->nedcG,"coarse_G");CHKERRQ(ierr); 14521e0482f5SStefano Zampini ierr = MatView(pcbddc->nedcG,NULL);CHKERRQ(ierr); 14531e0482f5SStefano Zampini #endif 14541e0482f5SStefano Zampini } 1455a13144ffSStefano Zampini 1456a13144ffSStefano Zampini /* set change of basis */ 1457213b8bfaSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,singular);CHKERRQ(ierr); 1458a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1459a13144ffSStefano Zampini 1460a13144ffSStefano Zampini PetscFunctionReturn(0); 1461a13144ffSStefano Zampini } 1462a13144ffSStefano Zampini 1463d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1464d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1465d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1466d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1467d8203eabSStefano Zampini { 1468d8203eabSStefano Zampini PetscErrorCode ierr; 1469d8203eabSStefano Zampini PetscInt i; 1470d8203eabSStefano Zampini 1471d8203eabSStefano Zampini PetscFunctionBegin; 1472d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1473d8203eabSStefano Zampini PetscInt first,last; 1474d8203eabSStefano Zampini 1475d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 147686fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1477d8203eabSStefano Zampini if (i>=first && i < last) { 1478d8203eabSStefano Zampini PetscScalar *data; 1479d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1480d8203eabSStefano Zampini if (!has_const) { 1481d8203eabSStefano Zampini data[i-first] = 1.; 1482d8203eabSStefano Zampini } else { 148386fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 148486fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1485d8203eabSStefano Zampini } 1486d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1487d8203eabSStefano Zampini } 1488d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1489d8203eabSStefano Zampini } 1490d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1491d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1492d8203eabSStefano Zampini PetscInt first,last; 1493ddc40e2cSstefano_zampini ierr = VecLockPop(quad_vecs[i]);CHKERRQ(ierr); 1494d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1495d8203eabSStefano Zampini if (i>=first && i < last) { 1496d8203eabSStefano Zampini PetscScalar *data; 1497d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1498d8203eabSStefano Zampini if (!has_const) { 1499d8203eabSStefano Zampini data[i-first] = 0.; 1500d8203eabSStefano Zampini } else { 150186fa73c5SStefano Zampini data[2*i-first] = 0.; 150286fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1503d8203eabSStefano Zampini } 1504d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1505d8203eabSStefano Zampini } 1506d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1507ddc40e2cSstefano_zampini ierr = VecLockPush(quad_vecs[i]);CHKERRQ(ierr); 1508d8203eabSStefano Zampini } 1509d8203eabSStefano Zampini PetscFunctionReturn(0); 1510d8203eabSStefano Zampini } 1511d8203eabSStefano Zampini 15128ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1513669cc0f4SStefano Zampini { 1514a198735bSStefano Zampini Mat loc_divudotp; 1515fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 15168ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1517669cc0f4SStefano Zampini PetscScalar *vals; 1518669cc0f4SStefano Zampini const PetscScalar *array; 1519*a040e873SStefano Zampini PetscInt i,maxneighs,maxsize; 1520*a040e873SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 15211ae86dd6SStefano Zampini PetscMPIInt rank; 1522a198735bSStefano Zampini PetscErrorCode ierr; 1523669cc0f4SStefano Zampini 1524669cc0f4SStefano Zampini PetscFunctionBegin; 1525*a040e873SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1526*a040e873SStefano Zampini ierr = MPIU_Allreduce(&n_neigh,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 1527669cc0f4SStefano Zampini maxsize = 0; 1528*a040e873SStefano Zampini for (i=0;i<n_neigh;i++) maxsize = PetscMax(n_shared[i],maxsize); 1529669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1530669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1531669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 15328ae0ca82SStefano Zampini if (!transpose) { 15338ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 15348ae0ca82SStefano Zampini } else { 15358ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 15368ae0ca82SStefano Zampini } 1537669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 15381ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1539d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1540669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1541ddc40e2cSstefano_zampini ierr = VecLockPop(quad_vecs[i]);CHKERRQ(ierr); 15428ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 1543669cc0f4SStefano Zampini } 1544d8203eabSStefano Zampini 1545669cc0f4SStefano Zampini /* compute local quad vec */ 1546a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 15478ae0ca82SStefano Zampini if (!transpose) { 1548a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 15498ae0ca82SStefano Zampini } else { 15508ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 15518ae0ca82SStefano Zampini } 1552669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 15538ae0ca82SStefano Zampini if (!transpose) { 1554a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 15558ae0ca82SStefano Zampini } else { 15568ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 15578ae0ca82SStefano Zampini } 1558fa23a32eSStefano Zampini if (vl2l) { 1559187c917aSStefano Zampini Mat lA; 1560187c917aSStefano Zampini VecScatter sc; 1561187c917aSStefano Zampini 1562187c917aSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1563187c917aSStefano Zampini ierr = MatCreateVecs(lA,&vins,NULL);CHKERRQ(ierr); 1564187c917aSStefano Zampini ierr = VecScatterCreate(v,vl2l,vins,NULL,&sc);CHKERRQ(ierr); 1565187c917aSStefano Zampini ierr = VecScatterBegin(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1566187c917aSStefano Zampini ierr = VecScatterEnd(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1567187c917aSStefano Zampini ierr = VecScatterDestroy(&sc);CHKERRQ(ierr); 1568fa23a32eSStefano Zampini } else { 1569fa23a32eSStefano Zampini vins = v; 1570fa23a32eSStefano Zampini } 1571fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1572669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 15739a962809SStefano Zampini 15741ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 15751ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1576*a040e873SStefano Zampini for (i=0;i<n_neigh;i++) { 1577669cc0f4SStefano Zampini const PetscInt *idxs; 1578669cc0f4SStefano Zampini PetscInt idx,nn,j; 1579669cc0f4SStefano Zampini 1580*a040e873SStefano Zampini idxs = shared[i]; 1581*a040e873SStefano Zampini nn = n_shared[i]; 1582669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 15831ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1584669cc0f4SStefano Zampini idx = -(idx+1); 1585669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1586669cc0f4SStefano Zampini } 1587*a040e873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1588fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1589fa23a32eSStefano Zampini if (vl2l) { 1590187c917aSStefano Zampini ierr = VecDestroy(&vins);CHKERRQ(ierr); 1591fa23a32eSStefano Zampini } 1592669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1593669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1594669cc0f4SStefano Zampini 1595669cc0f4SStefano Zampini /* assemble near null space */ 1596669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1597669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1598669cc0f4SStefano Zampini } 1599669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1600669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 1601ddc40e2cSstefano_zampini ierr = VecLockPush(quad_vecs[i]);CHKERRQ(ierr); 1602669cc0f4SStefano Zampini } 1603669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1604669cc0f4SStefano Zampini PetscFunctionReturn(0); 1605669cc0f4SStefano Zampini } 1606669cc0f4SStefano Zampini 16077620a527SStefano Zampini PetscErrorCode PCBDDCAddPrimalVerticesLocalIS(PC pc, IS primalv) 16087620a527SStefano Zampini { 16097620a527SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16107620a527SStefano Zampini PetscErrorCode ierr; 16117620a527SStefano Zampini 16127620a527SStefano Zampini PetscFunctionBegin; 16137620a527SStefano Zampini if (primalv) { 16147620a527SStefano Zampini if (pcbddc->user_primal_vertices_local) { 16157620a527SStefano Zampini IS list[2], newp; 16167620a527SStefano Zampini 16177620a527SStefano Zampini list[0] = primalv; 16187620a527SStefano Zampini list[1] = pcbddc->user_primal_vertices_local; 16197620a527SStefano Zampini ierr = ISConcatenate(PetscObjectComm((PetscObject)pc),2,list,&newp);CHKERRQ(ierr); 16207620a527SStefano Zampini ierr = ISSortRemoveDups(newp);CHKERRQ(ierr); 16217620a527SStefano Zampini ierr = ISDestroy(&list[1]);CHKERRQ(ierr); 16227620a527SStefano Zampini pcbddc->user_primal_vertices_local = newp; 16237620a527SStefano Zampini } else { 16247620a527SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 16257620a527SStefano Zampini } 16267620a527SStefano Zampini } 16277620a527SStefano Zampini PetscFunctionReturn(0); 16287620a527SStefano Zampini } 1629669cc0f4SStefano Zampini 16301f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 16311f4df5f7SStefano Zampini { 16321f4df5f7SStefano Zampini PetscErrorCode ierr; 16331f4df5f7SStefano Zampini Vec local,global; 16341f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16351f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 16365c5e10d6SStefano Zampini PetscBool monolithic = PETSC_FALSE; 16371f4df5f7SStefano Zampini 16381f4df5f7SStefano Zampini PetscFunctionBegin; 16395c5e10d6SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC topology options","PC");CHKERRQ(ierr); 16405c5e10d6SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_monolithic","Discard any information on dofs splitting",NULL,monolithic,&monolithic,NULL);CHKERRQ(ierr); 16415c5e10d6SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 16421f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 164321ef3d20SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 16441f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 16456a8fc67bSStefano Zampini if (monolithic) { /* just get block size to properly compute vertices */ 16466a8fc67bSStefano Zampini if (pcbddc->vertex_size == 1) { 16476a8fc67bSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->vertex_size);CHKERRQ(ierr); 16486a8fc67bSStefano Zampini } 16496a8fc67bSStefano Zampini goto boundary; 16506a8fc67bSStefano Zampini } 16515c5e10d6SStefano Zampini 16521f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 16531f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 16541f4df5f7SStefano Zampini PetscInt i; 16551f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16561f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 16571f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16581f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 16591f4df5f7SStefano Zampini } 16601f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 16611f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 16621f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 16631f4df5f7SStefano Zampini } 16641f4df5f7SStefano Zampini } else { 166521ef3d20SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present */ 166621ef3d20SStefano Zampini DM dm; 166721ef3d20SStefano Zampini 166821ef3d20SStefano Zampini ierr = PCGetDM(pc, &dm);CHKERRQ(ierr); 166921ef3d20SStefano Zampini if (!dm) { 167021ef3d20SStefano Zampini ierr = MatGetDM(pc->pmat, &dm);CHKERRQ(ierr); 167121ef3d20SStefano Zampini } 167221ef3d20SStefano Zampini if (dm) { 167321ef3d20SStefano Zampini IS *fields; 167421ef3d20SStefano Zampini PetscInt nf,i; 167521ef3d20SStefano Zampini ierr = DMCreateFieldDecomposition(dm,&nf,NULL,&fields,NULL);CHKERRQ(ierr); 167621ef3d20SStefano Zampini ierr = PetscMalloc1(nf,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 167721ef3d20SStefano Zampini for (i=0;i<nf;i++) { 167821ef3d20SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,fields[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 167921ef3d20SStefano Zampini ierr = ISDestroy(&fields[i]);CHKERRQ(ierr); 168021ef3d20SStefano Zampini } 168121ef3d20SStefano Zampini ierr = PetscFree(fields);CHKERRQ(ierr); 168221ef3d20SStefano Zampini pcbddc->n_ISForDofsLocal = nf; 168321ef3d20SStefano Zampini } else { /* See if MATIS has fields attached by the conversion from MatNest */ 168421ef3d20SStefano Zampini PetscContainer c; 168521ef3d20SStefano Zampini 168621ef3d20SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc->pmat,"_convert_nest_lfields",(PetscObject*)&c);CHKERRQ(ierr); 168721ef3d20SStefano Zampini if (c) { 168821ef3d20SStefano Zampini MatISLocalFields lf; 168921ef3d20SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&lf);CHKERRQ(ierr); 169021ef3d20SStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,lf->nr,lf->rf);CHKERRQ(ierr); 169121ef3d20SStefano Zampini } else { /* fallback, create the default fields if bs > 1 */ 16921f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1693986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 169421ef3d20SStefano Zampini if (i > 1) { 1695986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 16961f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16971f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16981f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16991f4df5f7SStefano Zampini } 17001f4df5f7SStefano Zampini } 170121ef3d20SStefano Zampini } 170221ef3d20SStefano Zampini } 17037a0e7b2cSstefano_zampini } else { 17047a0e7b2cSstefano_zampini PetscInt i; 17057a0e7b2cSstefano_zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 17067a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 17077a0e7b2cSstefano_zampini } 17081f4df5f7SStefano Zampini } 1709986cdee1SStefano Zampini } 17101f4df5f7SStefano Zampini 17115c5e10d6SStefano Zampini boundary: 17121f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 17131f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 17147a0e7b2cSstefano_zampini } else if (pcbddc->DirichletBoundariesLocal) { 17157a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 17161f4df5f7SStefano Zampini } 17171f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 17181f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 17197a0e7b2cSstefano_zampini } else if (pcbddc->NeumannBoundariesLocal) { 17207a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 17211f4df5f7SStefano Zampini } 17221f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 17231f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 17241f4df5f7SStefano Zampini } 17251f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 17261f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 17277620a527SStefano Zampini /* detect local disconnected subdomains if requested (use matis->A) */ 17287620a527SStefano Zampini if (pcbddc->detect_disconnected) { 17297620a527SStefano Zampini IS primalv = NULL; 17307620a527SStefano Zampini PetscInt i; 17317a0e7b2cSstefano_zampini 17327620a527SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 17337620a527SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 17347620a527SStefano Zampini } 17357620a527SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 17367620a527SStefano Zampini ierr = PCBDDCDetectDisconnectedComponents(pc,&pcbddc->n_local_subs,&pcbddc->local_subs,&primalv);CHKERRQ(ierr); 17377620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 17387620a527SStefano Zampini ierr = ISDestroy(&primalv);CHKERRQ(ierr); 17397620a527SStefano Zampini } 17407620a527SStefano Zampini /* early stage corner detection */ 17417620a527SStefano Zampini { 17427620a527SStefano Zampini DM dm; 17437620a527SStefano Zampini 17447620a527SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 17457620a527SStefano Zampini if (dm) { 17467620a527SStefano Zampini PetscBool isda; 17477620a527SStefano Zampini 17487620a527SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&isda);CHKERRQ(ierr); 17497620a527SStefano Zampini if (isda) { 17507620a527SStefano Zampini ISLocalToGlobalMapping l2l; 17517620a527SStefano Zampini IS corners; 17527620a527SStefano Zampini Mat lA; 17537620a527SStefano Zampini 1754d4a6ed37SStefano Zampini ierr = DMDAGetSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17557620a527SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17567620a527SStefano Zampini ierr = MatGetLocalToGlobalMapping(lA,&l2l,NULL);CHKERRQ(ierr); 17577620a527SStefano Zampini ierr = MatISRestoreLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17587620a527SStefano Zampini if (l2l) { 17597620a527SStefano Zampini const PetscInt *idx; 17607620a527SStefano Zampini PetscInt bs,*idxout,n; 17617620a527SStefano Zampini 17627620a527SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(l2l,&bs);CHKERRQ(ierr); 17637620a527SStefano Zampini ierr = ISGetLocalSize(corners,&n);CHKERRQ(ierr); 17647620a527SStefano Zampini ierr = ISGetIndices(corners,&idx);CHKERRQ(ierr); 17657620a527SStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 17667620a527SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(l2l,n,idx,idxout);CHKERRQ(ierr); 17677620a527SStefano Zampini ierr = ISRestoreIndices(corners,&idx);CHKERRQ(ierr); 1768d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17697620a527SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)pc),bs,n,idxout,PETSC_OWN_POINTER,&corners);CHKERRQ(ierr); 17707620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,corners);CHKERRQ(ierr); 17717620a527SStefano Zampini ierr = ISDestroy(&corners);CHKERRQ(ierr); 17727620a527SStefano Zampini } else { /* not from DMDA */ 1773d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17747620a527SStefano Zampini } 17757620a527SStefano Zampini } 17767620a527SStefano Zampini } 17777620a527SStefano Zampini } 17787a0e7b2cSstefano_zampini PetscFunctionReturn(0); 17797a0e7b2cSstefano_zampini } 17807a0e7b2cSstefano_zampini 17817a0e7b2cSstefano_zampini PetscErrorCode PCBDDCConsistencyCheckIS(PC pc, MPI_Op mop, IS *is) 17827a0e7b2cSstefano_zampini { 17837a0e7b2cSstefano_zampini Mat_IS *matis = (Mat_IS*)(pc->pmat->data); 17847a0e7b2cSstefano_zampini PetscErrorCode ierr; 17857a0e7b2cSstefano_zampini IS nis; 17867a0e7b2cSstefano_zampini const PetscInt *idxs; 17877a0e7b2cSstefano_zampini PetscInt i,nd,n = matis->A->rmap->n,*nidxs,nnd; 17887a0e7b2cSstefano_zampini PetscBool *ld; 17897a0e7b2cSstefano_zampini 17907a0e7b2cSstefano_zampini PetscFunctionBegin; 17917a0e7b2cSstefano_zampini if (mop != MPI_LAND && mop != MPI_LOR) SETERRQ(PetscObjectComm((PetscObject)(pc)),PETSC_ERR_SUP,"Supported are MPI_LAND and MPI_LOR"); 17927a0e7b2cSstefano_zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 17937a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 17947a0e7b2cSstefano_zampini /* init rootdata with true */ 17957a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_rootdata; 17967a0e7b2cSstefano_zampini for (i=0;i<pc->pmat->rmap->n;i++) ld[i] = PETSC_TRUE; 17977a0e7b2cSstefano_zampini } else { 17987a0e7b2cSstefano_zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscBool));CHKERRQ(ierr); 17997a0e7b2cSstefano_zampini } 18007a0e7b2cSstefano_zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscBool));CHKERRQ(ierr); 18017a0e7b2cSstefano_zampini ierr = ISGetLocalSize(*is,&nd);CHKERRQ(ierr); 18027a0e7b2cSstefano_zampini ierr = ISGetIndices(*is,&idxs);CHKERRQ(ierr); 18037a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_leafdata; 18047a0e7b2cSstefano_zampini for (i=0;i<nd;i++) 18057a0e7b2cSstefano_zampini if (-1 < idxs[i] && idxs[i] < n) 18067a0e7b2cSstefano_zampini ld[idxs[i]] = PETSC_TRUE; 18077a0e7b2cSstefano_zampini ierr = ISRestoreIndices(*is,&idxs);CHKERRQ(ierr); 18087a0e7b2cSstefano_zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18097a0e7b2cSstefano_zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18107a0e7b2cSstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18117a0e7b2cSstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18127a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18137a0e7b2cSstefano_zampini ierr = PetscMalloc1(nd,&nidxs);CHKERRQ(ierr); 18147a0e7b2cSstefano_zampini } else { 18157a0e7b2cSstefano_zampini ierr = PetscMalloc1(n,&nidxs);CHKERRQ(ierr); 18167a0e7b2cSstefano_zampini } 18177a0e7b2cSstefano_zampini for (i=0,nnd=0;i<n;i++) 18187a0e7b2cSstefano_zampini if (ld[i]) 18197a0e7b2cSstefano_zampini nidxs[nnd++] = i; 18207a0e7b2cSstefano_zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(*is)),nnd,nidxs,PETSC_OWN_POINTER,&nis);CHKERRQ(ierr); 18217a0e7b2cSstefano_zampini ierr = ISDestroy(is);CHKERRQ(ierr); 18227a0e7b2cSstefano_zampini *is = nis; 18231f4df5f7SStefano Zampini PetscFunctionReturn(0); 18241f4df5f7SStefano Zampini } 18251f4df5f7SStefano Zampini 18263e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 18273e589ea0SStefano Zampini { 18283e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 18293e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 18303e589ea0SStefano Zampini PetscErrorCode ierr; 18313e589ea0SStefano Zampini 18323e589ea0SStefano Zampini PetscFunctionBegin; 18333e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 18343e589ea0SStefano Zampini PetscFunctionReturn(0); 18353e589ea0SStefano Zampini } 18363e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18373e589ea0SStefano Zampini Vec swap; 18383e589ea0SStefano Zampini 18393e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 18403e589ea0SStefano Zampini swap = pcbddc->work_change; 18413e589ea0SStefano Zampini pcbddc->work_change = r; 18423e589ea0SStefano Zampini r = swap; 18433e589ea0SStefano Zampini } 18443e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18453e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18463e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 18473e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 18483e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18493e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18503e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1851f913dca9SStefano Zampini pcbddc->work_change = r; 18523e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 18533e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 18543e589ea0SStefano Zampini } 18553e589ea0SStefano Zampini PetscFunctionReturn(0); 18563e589ea0SStefano Zampini } 18573e589ea0SStefano Zampini 1858a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1859a3df083aSStefano Zampini { 1860a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1861a3df083aSStefano Zampini PetscErrorCode ierr; 1862a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1863a3df083aSStefano Zampini 1864a3df083aSStefano Zampini PetscFunctionBegin; 1865a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1866a3df083aSStefano Zampini if (transpose) { 1867a3df083aSStefano Zampini apply_right = ctx->apply_left; 1868a3df083aSStefano Zampini apply_left = ctx->apply_right; 1869a3df083aSStefano Zampini } else { 1870a3df083aSStefano Zampini apply_right = ctx->apply_right; 1871a3df083aSStefano Zampini apply_left = ctx->apply_left; 1872a3df083aSStefano Zampini } 1873a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1874a3df083aSStefano Zampini if (apply_right) { 1875a3df083aSStefano Zampini const PetscScalar *ax; 1876a3df083aSStefano Zampini PetscInt nl,i; 1877a3df083aSStefano Zampini 1878a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1879a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1880a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1881a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1882a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1883a3df083aSStefano Zampini PetscScalar sum,val; 1884a3df083aSStefano Zampini const PetscInt *idxs; 1885a3df083aSStefano Zampini PetscInt nz,j; 1886a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1887a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1888a3df083aSStefano Zampini sum = 0.; 1889a3df083aSStefano Zampini if (ctx->apply_p0) { 1890a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1891a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1892a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1893a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1894a3df083aSStefano Zampini } 1895a3df083aSStefano Zampini } else { 1896a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1897a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1898a3df083aSStefano Zampini } 1899a3df083aSStefano Zampini } 1900a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1901a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1902a3df083aSStefano Zampini } 1903a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1904a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1905a3df083aSStefano Zampini } 1906a3df083aSStefano Zampini if (transpose) { 1907a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1908a3df083aSStefano Zampini } else { 1909a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1910a3df083aSStefano Zampini } 1911a3df083aSStefano Zampini if (reset_x) { 1912a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1913a3df083aSStefano Zampini } 1914a3df083aSStefano Zampini if (apply_left) { 1915a3df083aSStefano Zampini PetscScalar *ay; 1916a3df083aSStefano Zampini PetscInt i; 1917a3df083aSStefano Zampini 1918a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1919a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1920a3df083aSStefano Zampini PetscScalar sum,val; 1921a3df083aSStefano Zampini const PetscInt *idxs; 1922a3df083aSStefano Zampini PetscInt nz,j; 1923a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1924a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1925a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1926a3df083aSStefano Zampini if (ctx->apply_p0) { 1927a3df083aSStefano Zampini sum = 0.; 1928a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1929a3df083aSStefano Zampini sum += ay[idxs[j]]; 1930a3df083aSStefano Zampini ay[idxs[j]] += val; 1931a3df083aSStefano Zampini } 1932a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1933a3df083aSStefano Zampini } else { 1934a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1935a3df083aSStefano Zampini ay[idxs[j]] += val; 1936a3df083aSStefano Zampini } 1937a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1938a3df083aSStefano Zampini } 1939a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1940a3df083aSStefano Zampini } 1941a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1942a3df083aSStefano Zampini } 1943a3df083aSStefano Zampini PetscFunctionReturn(0); 1944a3df083aSStefano Zampini } 1945a3df083aSStefano Zampini 1946a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1947a3df083aSStefano Zampini { 1948a3df083aSStefano Zampini PetscErrorCode ierr; 1949a3df083aSStefano Zampini 1950a3df083aSStefano Zampini PetscFunctionBegin; 1951a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1952a3df083aSStefano Zampini PetscFunctionReturn(0); 1953a3df083aSStefano Zampini } 1954a3df083aSStefano Zampini 1955a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1956a3df083aSStefano Zampini { 1957a3df083aSStefano Zampini PetscErrorCode ierr; 1958a3df083aSStefano Zampini 1959a3df083aSStefano Zampini PetscFunctionBegin; 1960a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1961a3df083aSStefano Zampini PetscFunctionReturn(0); 1962a3df083aSStefano Zampini } 1963a3df083aSStefano Zampini 1964a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1965a3df083aSStefano Zampini { 1966a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1967a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1968a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1969a3df083aSStefano Zampini PetscErrorCode ierr; 1970a3df083aSStefano Zampini 1971a3df083aSStefano Zampini PetscFunctionBegin; 1972a3df083aSStefano Zampini if (!restore) { 19731dd7afcfSStefano Zampini Mat A_IB,A_BI; 1974a3df083aSStefano Zampini PetscScalar *work; 1975b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 1976a3df083aSStefano Zampini 19779a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 19789a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 1979a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 1980a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 1981a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1982a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 1983a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 1984a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 1985a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 1986a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 1987a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 1988a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 1989a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 1990a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 1991059032f7SStefano Zampini if (reuse) { 1992a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 19931dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 1994059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 1995059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 1996059032f7SStefano Zampini PetscInt i; 1997059032f7SStefano Zampini 1998059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 1999059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2000059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2001059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2002059032f7SStefano Zampini } 2003059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 20041dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 2005059032f7SStefano Zampini } 2006a3df083aSStefano Zampini ctx->A = pcis->A_IB; 2007a3df083aSStefano Zampini ctx->work = work; 2008a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 2009a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2010a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2011a3df083aSStefano Zampini pcis->A_IB = A_IB; 2012a3df083aSStefano Zampini 2013a3df083aSStefano Zampini /* A_BI as A_IB^T */ 2014a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 2015a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 2016a3df083aSStefano Zampini pcis->A_BI = A_BI; 2017a3df083aSStefano Zampini } else { 20181dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 20191dd7afcfSStefano Zampini PetscFunctionReturn(0); 20201dd7afcfSStefano Zampini } 2021a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 2022a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 2023a3df083aSStefano Zampini pcis->A_IB = ctx->A; 20241dd7afcfSStefano Zampini ctx->A = NULL; 20251dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 20261dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 20271dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 20281dd7afcfSStefano Zampini if (ctx->free) { 2029059032f7SStefano Zampini PetscInt i; 20301dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 2031059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2032059032f7SStefano Zampini } 2033059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2034059032f7SStefano Zampini } 2035a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 2036a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 2037a3df083aSStefano Zampini } 2038a3df083aSStefano Zampini PetscFunctionReturn(0); 2039a3df083aSStefano Zampini } 2040a3df083aSStefano Zampini 2041a3df083aSStefano Zampini /* used just in bddc debug mode */ 2042a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 2043a3df083aSStefano Zampini { 2044a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2045a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2046a3df083aSStefano Zampini Mat An; 2047a3df083aSStefano Zampini PetscErrorCode ierr; 2048a3df083aSStefano Zampini 2049a3df083aSStefano Zampini PetscFunctionBegin; 2050a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 2051a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 2052a3df083aSStefano Zampini if (is1) { 20537dae84e0SHong Zhang ierr = MatCreateSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 2054a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 2055a3df083aSStefano Zampini } else { 2056a3df083aSStefano Zampini *B = An; 2057a3df083aSStefano Zampini } 2058a3df083aSStefano Zampini PetscFunctionReturn(0); 2059a3df083aSStefano Zampini } 2060a3df083aSStefano Zampini 20611cf9b237SStefano Zampini /* TODO: add reuse flag */ 20621cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 20631cf9b237SStefano Zampini { 20641cf9b237SStefano Zampini Mat Bt; 20651cf9b237SStefano Zampini PetscScalar *a,*bdata; 20661cf9b237SStefano Zampini const PetscInt *ii,*ij; 20671cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 20681cf9b237SStefano Zampini PetscBool flg_row; 20691cf9b237SStefano Zampini PetscErrorCode ierr; 20701cf9b237SStefano Zampini 20711cf9b237SStefano Zampini PetscFunctionBegin; 20721cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 20731cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 20741cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 20751cf9b237SStefano Zampini nnz = n; 20761cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 20771cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 20781cf9b237SStefano Zampini } 20791cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 20801cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 20811cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 20821cf9b237SStefano Zampini nnz = 0; 20831cf9b237SStefano Zampini bii[0] = 0; 20841cf9b237SStefano Zampini for (i=0;i<n;i++) { 20851cf9b237SStefano Zampini PetscInt j; 20861cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 20871cf9b237SStefano Zampini PetscScalar entry = a[j]; 20881cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 20891cf9b237SStefano Zampini bij[nnz] = ij[j]; 20901cf9b237SStefano Zampini bdata[nnz] = entry; 20911cf9b237SStefano Zampini nnz++; 20921cf9b237SStefano Zampini } 20931cf9b237SStefano Zampini } 20941cf9b237SStefano Zampini bii[i+1] = nnz; 20951cf9b237SStefano Zampini } 20961cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 20971cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 20981cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 20991cf9b237SStefano Zampini { 21001cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 21011cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 21021cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 21031cf9b237SStefano Zampini } 21041cf9b237SStefano Zampini *B = Bt; 21051cf9b237SStefano Zampini PetscFunctionReturn(0); 21061cf9b237SStefano Zampini } 21071cf9b237SStefano Zampini 2108c80a6c00SStefano Zampini PetscErrorCode PCBDDCDetectDisconnectedComponents(PC pc, PetscInt *ncc, IS* cc[], IS* primalv) 21094f1b2e48SStefano Zampini { 2110c80a6c00SStefano Zampini Mat B = NULL; 2111c80a6c00SStefano Zampini DM dm; 21124f1b2e48SStefano Zampini IS is_dummy,*cc_n; 21134f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 21144f1b2e48SStefano Zampini PCBDDCGraph graph; 2115c80a6c00SStefano Zampini PetscInt *xadj_filtered = NULL,*adjncy_filtered = NULL; 21164f1b2e48SStefano Zampini PetscInt i,n; 21174f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 2118c80a6c00SStefano Zampini PetscBool isplex = PETSC_FALSE; 21194f1b2e48SStefano Zampini PetscErrorCode ierr; 21204f1b2e48SStefano Zampini 21214f1b2e48SStefano Zampini PetscFunctionBegin; 2122a2eca866SStefano Zampini if (ncc) *ncc = 0; 2123a2eca866SStefano Zampini if (cc) *cc = NULL; 2124a2eca866SStefano Zampini if (primalv) *primalv = NULL; 2125c80a6c00SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 2126c80a6c00SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 2127c80a6c00SStefano Zampini if (!dm) { 2128c80a6c00SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 2129c80a6c00SStefano Zampini } 2130c80a6c00SStefano Zampini if (dm) { 2131c80a6c00SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMPLEX,&isplex);CHKERRQ(ierr); 2132c80a6c00SStefano Zampini } 2133c80a6c00SStefano Zampini if (isplex) { /* this code has been modified from plexpartition.c */ 2134c80a6c00SStefano Zampini PetscInt p, pStart, pEnd, a, adjSize, idx, size, nroots; 2135c80a6c00SStefano Zampini PetscInt *adj = NULL; 2136c80a6c00SStefano Zampini IS cellNumbering; 2137c80a6c00SStefano Zampini const PetscInt *cellNum; 2138c80a6c00SStefano Zampini PetscBool useCone, useClosure; 2139c80a6c00SStefano Zampini PetscSection section; 2140c80a6c00SStefano Zampini PetscSegBuffer adjBuffer; 2141c80a6c00SStefano Zampini PetscSF sfPoint; 2142c80a6c00SStefano Zampini PetscErrorCode ierr; 2143c80a6c00SStefano Zampini 2144c80a6c00SStefano Zampini PetscFunctionBegin; 2145c80a6c00SStefano Zampini ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 2146c80a6c00SStefano Zampini ierr = DMGetPointSF(dm, &sfPoint);CHKERRQ(ierr); 2147c80a6c00SStefano Zampini ierr = PetscSFGetGraph(sfPoint, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 2148c80a6c00SStefano Zampini /* Build adjacency graph via a section/segbuffer */ 2149c80a6c00SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), §ion);CHKERRQ(ierr); 2150c80a6c00SStefano Zampini ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 2151c80a6c00SStefano Zampini ierr = PetscSegBufferCreate(sizeof(PetscInt),1000,&adjBuffer);CHKERRQ(ierr); 2152c80a6c00SStefano Zampini /* Always use FVM adjacency to create partitioner graph */ 2153c80a6c00SStefano Zampini ierr = DMPlexGetAdjacencyUseCone(dm, &useCone);CHKERRQ(ierr); 2154c80a6c00SStefano Zampini ierr = DMPlexGetAdjacencyUseClosure(dm, &useClosure);CHKERRQ(ierr); 2155c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseCone(dm, PETSC_TRUE);CHKERRQ(ierr); 2156c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseClosure(dm, PETSC_FALSE);CHKERRQ(ierr); 2157956e2312SStefano Zampini ierr = DMPlexGetCellNumbering(dm, &cellNumbering);CHKERRQ(ierr); 2158c80a6c00SStefano Zampini ierr = ISGetIndices(cellNumbering, &cellNum);CHKERRQ(ierr); 2159c80a6c00SStefano Zampini for (n = 0, p = pStart; p < pEnd; p++) { 2160c80a6c00SStefano Zampini /* Skip non-owned cells in parallel (ParMetis expects no overlap) */ 2161c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2162c80a6c00SStefano Zampini adjSize = PETSC_DETERMINE; 2163c80a6c00SStefano Zampini ierr = DMPlexGetAdjacency(dm, p, &adjSize, &adj);CHKERRQ(ierr); 2164c80a6c00SStefano Zampini for (a = 0; a < adjSize; ++a) { 2165c80a6c00SStefano Zampini const PetscInt point = adj[a]; 21665cef3d0dSStefano Zampini if (pStart <= point && point < pEnd) { 2167c80a6c00SStefano Zampini PetscInt *PETSC_RESTRICT pBuf; 2168c80a6c00SStefano Zampini ierr = PetscSectionAddDof(section, p, 1);CHKERRQ(ierr); 2169c80a6c00SStefano Zampini ierr = PetscSegBufferGetInts(adjBuffer, 1, &pBuf);CHKERRQ(ierr); 2170c80a6c00SStefano Zampini *pBuf = point; 2171c80a6c00SStefano Zampini } 2172c80a6c00SStefano Zampini } 2173c80a6c00SStefano Zampini n++; 2174c80a6c00SStefano Zampini } 2175c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseCone(dm, useCone);CHKERRQ(ierr); 2176c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseClosure(dm, useClosure);CHKERRQ(ierr); 2177c80a6c00SStefano Zampini /* Derive CSR graph from section/segbuffer */ 2178c80a6c00SStefano Zampini ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 2179c80a6c00SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 2180c80a6c00SStefano Zampini ierr = PetscMalloc1(n+1, &xadj);CHKERRQ(ierr); 2181c80a6c00SStefano Zampini for (idx = 0, p = pStart; p < pEnd; p++) { 2182c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2183c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(section, p, &(xadj[idx++]));CHKERRQ(ierr); 2184c80a6c00SStefano Zampini } 2185c80a6c00SStefano Zampini xadj[n] = size; 2186c80a6c00SStefano Zampini ierr = PetscSegBufferExtractAlloc(adjBuffer, &adjncy);CHKERRQ(ierr); 2187c80a6c00SStefano Zampini /* Clean up */ 2188c80a6c00SStefano Zampini ierr = PetscSegBufferDestroy(&adjBuffer);CHKERRQ(ierr); 2189c80a6c00SStefano Zampini ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 2190c80a6c00SStefano Zampini ierr = PetscFree(adj);CHKERRQ(ierr); 2191c80a6c00SStefano Zampini graph->xadj = xadj; 2192c80a6c00SStefano Zampini graph->adjncy = adjncy; 2193c80a6c00SStefano Zampini } else { 2194c80a6c00SStefano Zampini Mat A; 2195c80a6c00SStefano Zampini PetscBool filter = PETSC_FALSE, isseqaij, flg_row; 2196c80a6c00SStefano Zampini 2197c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 219863c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 2199a2eca866SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 220063c961adSStefano Zampini PetscFunctionReturn(0); 220163c961adSStefano Zampini } 22024f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 22034f1b2e48SStefano Zampini if (!isseqaij && filter) { 22041cf9b237SStefano Zampini PetscBool isseqdense; 22051cf9b237SStefano Zampini 22061cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 22071cf9b237SStefano Zampini if (!isseqdense) { 22084f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 22091cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 22101cf9b237SStefano Zampini PetscScalar *array; 22111cf9b237SStefano Zampini PetscReal chop=1.e-6; 22121cf9b237SStefano Zampini 22131cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 22141cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 22151cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 22161cf9b237SStefano Zampini for (i=0;i<n;i++) { 22171cf9b237SStefano Zampini PetscInt j; 22181cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 22191cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 22201cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 22211cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 22221cf9b237SStefano Zampini } 22231cf9b237SStefano Zampini } 22241cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 22259d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 22261cf9b237SStefano Zampini } 22274f1b2e48SStefano Zampini } else { 2228c80a6c00SStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22294f1b2e48SStefano Zampini B = A; 22304f1b2e48SStefano Zampini } 22314f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 22324f1b2e48SStefano Zampini 22334f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 22344f1b2e48SStefano Zampini if (filter) { 22354f1b2e48SStefano Zampini PetscScalar *data; 22364f1b2e48SStefano Zampini PetscInt j,cum; 22374f1b2e48SStefano Zampini 22384f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 22394f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 22404f1b2e48SStefano Zampini cum = 0; 22414f1b2e48SStefano Zampini for (i=0;i<n;i++) { 22424f1b2e48SStefano Zampini PetscInt t; 22434f1b2e48SStefano Zampini 22444f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 22454f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 22464f1b2e48SStefano Zampini continue; 22474f1b2e48SStefano Zampini } 22484f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 22494f1b2e48SStefano Zampini } 22504f1b2e48SStefano Zampini t = xadj_filtered[i]; 22514f1b2e48SStefano Zampini xadj_filtered[i] = cum; 22524f1b2e48SStefano Zampini cum += t; 22534f1b2e48SStefano Zampini } 22544f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 22554f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 22564f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 22574f1b2e48SStefano Zampini } else { 22584f1b2e48SStefano Zampini graph->xadj = xadj; 22594f1b2e48SStefano Zampini graph->adjncy = adjncy; 22604f1b2e48SStefano Zampini } 2261c80a6c00SStefano Zampini } 2262c80a6c00SStefano Zampini /* compute local connected components using PCBDDCGraph */ 2263c80a6c00SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 2264c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 2265c80a6c00SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2266c80a6c00SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 2267c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 22684f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 22694f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 2270c80a6c00SStefano Zampini 22714f1b2e48SStefano Zampini /* partial clean up */ 22724f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 2273c80a6c00SStefano Zampini if (B) { 2274c80a6c00SStefano Zampini PetscBool flg_row; 22754f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 22764f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 22774f1b2e48SStefano Zampini } 2278c80a6c00SStefano Zampini if (isplex) { 2279c80a6c00SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 2280c80a6c00SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 2281c80a6c00SStefano Zampini } 22824f1b2e48SStefano Zampini 22834f1b2e48SStefano Zampini /* get back data */ 2284c80a6c00SStefano Zampini if (isplex) { 2285c80a6c00SStefano Zampini if (ncc) *ncc = graph->ncc; 2286c80a6c00SStefano Zampini if (cc || primalv) { 2287c80a6c00SStefano Zampini Mat A; 2288c80a6c00SStefano Zampini PetscBT btv,btvt; 2289c80a6c00SStefano Zampini PetscSection subSection; 2290c80a6c00SStefano Zampini PetscInt *ids,cum,cump,*cids,*pids; 2291c80a6c00SStefano Zampini 2292c80a6c00SStefano Zampini ierr = DMPlexGetSubdomainSection(dm,&subSection);CHKERRQ(ierr); 2293c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 2294c80a6c00SStefano Zampini ierr = PetscMalloc3(A->rmap->n,&ids,graph->ncc+1,&cids,A->rmap->n,&pids);CHKERRQ(ierr); 2295c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btv);CHKERRQ(ierr); 2296c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btvt);CHKERRQ(ierr); 2297c80a6c00SStefano Zampini 2298c80a6c00SStefano Zampini cids[0] = 0; 2299c80a6c00SStefano Zampini for (i = 0, cump = 0, cum = 0; i < graph->ncc; i++) { 2300c80a6c00SStefano Zampini PetscInt j; 2301c80a6c00SStefano Zampini 2302c80a6c00SStefano Zampini ierr = PetscBTMemzero(A->rmap->n,btvt);CHKERRQ(ierr); 2303c80a6c00SStefano Zampini for (j = graph->cptr[i]; j < graph->cptr[i+1]; j++) { 2304c80a6c00SStefano Zampini PetscInt k, size, *closure = NULL, cell = graph->queue[j]; 2305c80a6c00SStefano Zampini 2306c80a6c00SStefano Zampini ierr = DMPlexGetTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2307c80a6c00SStefano Zampini for (k = 0; k < 2*size; k += 2) { 2308c80a6c00SStefano Zampini PetscInt s, p = closure[k], off, dof, cdof; 2309c80a6c00SStefano Zampini 2310c80a6c00SStefano Zampini ierr = PetscSectionGetConstraintDof(subSection, p, &cdof);CHKERRQ(ierr); 2311c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(subSection,p,&off);CHKERRQ(ierr); 2312c80a6c00SStefano Zampini ierr = PetscSectionGetDof(subSection,p,&dof);CHKERRQ(ierr); 2313c80a6c00SStefano Zampini for (s = 0; s < dof-cdof; s++) { 2314c80a6c00SStefano Zampini if (PetscBTLookupSet(btvt,off+s)) continue; 2315c80a6c00SStefano Zampini if (!PetscBTLookup(btv,off+s)) { 2316c80a6c00SStefano Zampini ids[cum++] = off+s; 2317c80a6c00SStefano Zampini } else { /* cross-vertex */ 2318c80a6c00SStefano Zampini pids[cump++] = off+s; 2319c80a6c00SStefano Zampini } 2320c80a6c00SStefano Zampini } 2321c80a6c00SStefano Zampini } 2322c80a6c00SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2323c80a6c00SStefano Zampini } 2324c80a6c00SStefano Zampini cids[i+1] = cum; 2325c80a6c00SStefano Zampini /* mark dofs as already assigned */ 2326c80a6c00SStefano Zampini for (j = cids[i]; j < cids[i+1]; j++) { 2327c80a6c00SStefano Zampini ierr = PetscBTSet(btv,ids[j]);CHKERRQ(ierr); 2328c80a6c00SStefano Zampini } 2329c80a6c00SStefano Zampini } 2330c80a6c00SStefano Zampini if (cc) { 2331c80a6c00SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 2332c80a6c00SStefano Zampini for (i = 0; i < graph->ncc; i++) { 2333c80a6c00SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cids[i+1]-cids[i],ids+cids[i],PETSC_COPY_VALUES,&cc_n[i]);CHKERRQ(ierr); 2334c80a6c00SStefano Zampini } 2335c80a6c00SStefano Zampini *cc = cc_n; 2336c80a6c00SStefano Zampini } 2337c80a6c00SStefano Zampini if (primalv) { 2338c80a6c00SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),cump,pids,PETSC_COPY_VALUES,primalv);CHKERRQ(ierr); 2339c80a6c00SStefano Zampini } 2340c80a6c00SStefano Zampini ierr = PetscFree3(ids,cids,pids);CHKERRQ(ierr); 2341c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 2342c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btvt);CHKERRQ(ierr); 2343c80a6c00SStefano Zampini } 2344c80a6c00SStefano Zampini } else { 23451cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 23461cf9b237SStefano Zampini if (cc) { 23474f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 23484f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 23494f1b2e48SStefano 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); 23504f1b2e48SStefano Zampini } 23514f1b2e48SStefano Zampini *cc = cc_n; 23521cf9b237SStefano Zampini } 2353c80a6c00SStefano Zampini } 23544f1b2e48SStefano Zampini /* clean up graph */ 23554f1b2e48SStefano Zampini graph->xadj = 0; 23564f1b2e48SStefano Zampini graph->adjncy = 0; 23574f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 23584f1b2e48SStefano Zampini PetscFunctionReturn(0); 23594f1b2e48SStefano Zampini } 23604f1b2e48SStefano Zampini 23615408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 23625408967cSStefano Zampini { 23635408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 23645408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2365dee84bffSStefano Zampini IS dirIS = NULL; 23664f1b2e48SStefano Zampini PetscInt i; 23675408967cSStefano Zampini PetscErrorCode ierr; 23685408967cSStefano Zampini 23695408967cSStefano Zampini PetscFunctionBegin; 2370dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 23715408967cSStefano Zampini if (zerodiag) { 23725408967cSStefano Zampini Mat A; 23735408967cSStefano Zampini Vec vec3_N; 23745408967cSStefano Zampini PetscScalar *vals; 23755408967cSStefano Zampini const PetscInt *idxs; 2376d12d3064SStefano Zampini PetscInt nz,*count; 23775408967cSStefano Zampini 23785408967cSStefano Zampini /* p0 */ 23795408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 23805408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 23815408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 23825408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 23834f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 23845408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 23855408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 23865408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 23875408967cSStefano Zampini /* v_I */ 23885408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 23895408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 23905408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 23915408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 23925408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 23935408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 23945408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 23955408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 23965408967cSStefano Zampini if (dirIS) { 23975408967cSStefano Zampini PetscInt n; 23985408967cSStefano Zampini 23995408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 24005408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 24015408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 24025408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24035408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 24045408967cSStefano Zampini } 24055408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 24065408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 24075408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 24085408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2409669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 24105408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 24115408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 24129a962809SStefano 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])); 24135408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 24145408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2415d12d3064SStefano Zampini 2416d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 2417d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 2418d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2419d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 2420d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2421d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 24229a962809SStefano 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]); 2423d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2424d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 24255408967cSStefano Zampini } 2426dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 24275408967cSStefano Zampini 24285408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 24295408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 24304f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 24315408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 24324f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 24335408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2434f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2435f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 243613903a91SSatish Balay if (val != -PetscGlobalRank-i) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error testing PCBDDCBenignGetOrSetP0! Found %g at %d instead of %g\n",PetscRealPart(pcbddc->benign_p0[i]),i,-PetscGlobalRank-i); 2437f2a566d8SStefano Zampini } 24385408967cSStefano Zampini PetscFunctionReturn(0); 24395408967cSStefano Zampini } 24405408967cSStefano Zampini 2441339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 2442339f8db1SStefano Zampini { 2443339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 24444edc6404Sstefano_zampini IS pressures,zerodiag,zerodiag_save,*zerodiag_subs; 2445b0f5fe93SStefano Zampini PetscInt nz,n; 24464edc6404Sstefano_zampini PetscInt *interior_dofs,n_interior_dofs,nneu; 24474edc6404Sstefano_zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag,checkb; 2448339f8db1SStefano Zampini PetscErrorCode ierr; 2449339f8db1SStefano Zampini 2450339f8db1SStefano Zampini PetscFunctionBegin; 24519f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 24529f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 2453a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 2454a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 2455a3df083aSStefano Zampini } 2456a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2457a3df083aSStefano Zampini pcbddc->benign_n = 0; 245828b8efb1Sstefano_zampini 245928b8efb1Sstefano_zampini /* if a local info on dofs is present, uses the last field for "pressures" (or fid by command line) 24604f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 24614f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 24624f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 24631ae86dd6SStefano Zampini since the local Schur complements are already SPD 24644f1b2e48SStefano Zampini */ 24654f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 24664f1b2e48SStefano Zampini have_null = PETSC_TRUE; 246740fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 24687fbe2174Sstefano_zampini IS iP = NULL; 24694f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 24704f1b2e48SStefano Zampini 247128b8efb1Sstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC benign options","PC");CHKERRQ(ierr); 247228b8efb1Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_pressure_field","Field id for pressures",NULL,p,&p,NULL);CHKERRQ(ierr); 247328b8efb1Sstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 247428b8efb1Sstefano_zampini if (p < 0 || p > pcbddc->n_ISForDofsLocal-1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Invalid field id for pressures %D",p); 24754f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 24764f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 24774f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 24784f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 2479ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 24807fbe2174Sstefano_zampini /* remove zeroed out pressures if we are setting up a BDDC solver for a saddle-point FETI-DP */ 24817fbe2174Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP",(PetscObject*)&iP);CHKERRQ(ierr); 24827fbe2174Sstefano_zampini if (iP) { 24837fbe2174Sstefano_zampini IS newpressures; 24847fbe2174Sstefano_zampini 24857fbe2174Sstefano_zampini ierr = ISDifference(pressures,iP,&newpressures);CHKERRQ(ierr); 24867fbe2174Sstefano_zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 24877fbe2174Sstefano_zampini pressures = newpressures; 24887fbe2174Sstefano_zampini } 248940fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 249040fa8d13SStefano Zampini if (!sorted) { 249140fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 249240fa8d13SStefano Zampini } 249340fa8d13SStefano Zampini } else { 249440fa8d13SStefano Zampini pressures = NULL; 249540fa8d13SStefano Zampini } 249697d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 249797d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 249827b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 249997d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 2500339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 2501339f8db1SStefano Zampini if (!sorted) { 2502339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 2503339f8db1SStefano Zampini } 25044edc6404Sstefano_zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 25054edc6404Sstefano_zampini zerodiag_save = zerodiag; 2506339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 25074f1b2e48SStefano Zampini if (!nz) { 25084f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 25094f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 251040fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 251140fa8d13SStefano Zampini } 25124f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 25134f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 25144f1b2e48SStefano Zampini zerodiag_subs = NULL; 25154f1b2e48SStefano Zampini pcbddc->benign_n = 0; 25161f4df5f7SStefano Zampini n_interior_dofs = 0; 25171f4df5f7SStefano Zampini interior_dofs = NULL; 25184edc6404Sstefano_zampini nneu = 0; 25194edc6404Sstefano_zampini if (pcbddc->NeumannBoundariesLocal) { 25204edc6404Sstefano_zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nneu);CHKERRQ(ierr); 25214edc6404Sstefano_zampini } 25223369cb78Sstefano_zampini checkb = (PetscBool)(!pcbddc->NeumannBoundariesLocal || pcbddc->current_level); 25234edc6404Sstefano_zampini if (checkb) { /* need to compute interior nodes */ 25241f4df5f7SStefano Zampini PetscInt n,i,j; 25251f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 25261f4df5f7SStefano Zampini PetscInt *iwork; 25271f4df5f7SStefano Zampini 25281f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 25291f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 25301f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 25311f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 253290648384SStefano Zampini for (i=1;i<n_neigh;i++) 25331f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 25341f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 25351f4df5f7SStefano Zampini for (i=0;i<n;i++) 25361f4df5f7SStefano Zampini if (!iwork[i]) 25371f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 25381f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 25391f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 25401f4df5f7SStefano Zampini } 25414f1b2e48SStefano Zampini if (has_null_pressures) { 25424f1b2e48SStefano Zampini IS *subs; 25434edc6404Sstefano_zampini PetscInt nsubs,i,j,nl; 25441f4df5f7SStefano Zampini const PetscInt *idxs; 25451f4df5f7SStefano Zampini PetscScalar *array; 25461f4df5f7SStefano Zampini Vec *work; 25471f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 25484f1b2e48SStefano Zampini 25494f1b2e48SStefano Zampini subs = pcbddc->local_subs; 25504f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 25511f4df5f7SStefano 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) */ 25524edc6404Sstefano_zampini if (checkb) { 25531f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 25541f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 25551f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 25561f4df5f7SStefano Zampini /* work[0] = 1_p */ 25571f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 25581f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 25591f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 25601f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 25611f4df5f7SStefano Zampini /* work[0] = 1_v */ 25621f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 25631f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 25641f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 25651f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 25661f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 25671f4df5f7SStefano Zampini } 25684f1b2e48SStefano Zampini if (nsubs > 1) { 25694f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 25704f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 25714f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 25724f1b2e48SStefano Zampini IS t_zerodiag_subs; 25734f1b2e48SStefano Zampini PetscInt nl; 25744f1b2e48SStefano Zampini 25754f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 25764f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 25774f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 25784f1b2e48SStefano Zampini if (nl) { 25794f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 25804f1b2e48SStefano Zampini 25814edc6404Sstefano_zampini if (checkb) { 25821f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 25831f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 25841f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 25851f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 25861f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 25871f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 25881f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 25891f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 25901f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 25911f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 25921f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 25931f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 25941f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 25951f4df5f7SStefano Zampini valid = PETSC_FALSE; 25961f4df5f7SStefano Zampini break; 25971f4df5f7SStefano Zampini } 25981f4df5f7SStefano Zampini } 25991f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 26001f4df5f7SStefano Zampini } 26016632bad2Sstefano_zampini if (valid && nneu) { 26026632bad2Sstefano_zampini const PetscInt *idxs; 26031f4df5f7SStefano Zampini PetscInt nzb; 26041f4df5f7SStefano Zampini 26056632bad2Sstefano_zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 26066632bad2Sstefano_zampini ierr = ISGlobalToLocalMappingApply(l2g,IS_GTOLM_DROP,nneu,idxs,&nzb,NULL);CHKERRQ(ierr); 26076632bad2Sstefano_zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 26081f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 26091f4df5f7SStefano Zampini } 26101f4df5f7SStefano Zampini if (valid && pressures) { 26114f1b2e48SStefano Zampini IS t_pressure_subs; 26124f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 26134f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 26144f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 26154f1b2e48SStefano Zampini } 26164f1b2e48SStefano Zampini if (valid) { 26174f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 26184f1b2e48SStefano Zampini pcbddc->benign_n++; 26194f1b2e48SStefano Zampini } else { 26204f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 26214f1b2e48SStefano Zampini } 26224f1b2e48SStefano Zampini } 26234f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 26244f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 26254f1b2e48SStefano Zampini } 26264f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 26274f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 26281f4df5f7SStefano Zampini 26296632bad2Sstefano_zampini if (nneu) valid = PETSC_FALSE; 26301f4df5f7SStefano Zampini if (valid && pressures) { 26314f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 26324f1b2e48SStefano Zampini } 26334edc6404Sstefano_zampini if (valid && checkb) { 26341f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 26351f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 26361f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 26371f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 26381f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 26391f4df5f7SStefano Zampini valid = PETSC_FALSE; 26401f4df5f7SStefano Zampini break; 26411f4df5f7SStefano Zampini } 26421f4df5f7SStefano Zampini } 26431f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 26441f4df5f7SStefano Zampini } 26454f1b2e48SStefano Zampini if (valid) { 26464f1b2e48SStefano Zampini pcbddc->benign_n = 1; 2647ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 26484f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 26494f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 26504f1b2e48SStefano Zampini } 26514f1b2e48SStefano Zampini } 26524edc6404Sstefano_zampini if (checkb) { 26531f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 26544f1b2e48SStefano Zampini } 26551f4df5f7SStefano Zampini } 26561f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 26574f1b2e48SStefano Zampini 26584f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2659b9b0e38cSStefano Zampini PetscInt n; 2660b9b0e38cSStefano Zampini 26614f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 26624f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2663b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 2664b9b0e38cSStefano Zampini if (n) { 26654f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 26664f1b2e48SStefano Zampini have_null = PETSC_FALSE; 26674f1b2e48SStefano Zampini } 2668b9b0e38cSStefano Zampini } 26694f1b2e48SStefano Zampini 26704f1b2e48SStefano Zampini /* final check for null pressures */ 26714f1b2e48SStefano Zampini if (zerodiag && pressures) { 26724f1b2e48SStefano Zampini PetscInt nz,np; 26734f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 26744f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 26754f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 26764f1b2e48SStefano Zampini } 26774f1b2e48SStefano Zampini 26784f1b2e48SStefano Zampini if (recompute_zerodiag) { 26794f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 26804f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 26814f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 26824f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 26834f1b2e48SStefano Zampini } else { 26844f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 26854f1b2e48SStefano Zampini 26864f1b2e48SStefano Zampini nzn = 0; 26874f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 26884f1b2e48SStefano Zampini PetscInt ns; 26894f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 26904f1b2e48SStefano Zampini nzn += ns; 26914f1b2e48SStefano Zampini } 26924f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 26934f1b2e48SStefano Zampini nzn = 0; 26944f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 26954f1b2e48SStefano Zampini PetscInt ns,*idxs; 26964f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 26974f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 26984f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 26994f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 27004f1b2e48SStefano Zampini nzn += ns; 27014f1b2e48SStefano Zampini } 27024f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 27034f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 27044f1b2e48SStefano Zampini } 27054f1b2e48SStefano Zampini have_null = PETSC_FALSE; 27064f1b2e48SStefano Zampini } 27074f1b2e48SStefano Zampini 2708669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2709a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2710a198735bSStefano Zampini Mat A,loc_divudotp; 2711a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2712a198735bSStefano Zampini IS row,col,isused = NULL; 2713a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2714a198735bSStefano Zampini 27151f4df5f7SStefano Zampini if (pressures) { 27161f4df5f7SStefano Zampini isused = pressures; 27171f4df5f7SStefano Zampini } else { 27184edc6404Sstefano_zampini isused = zerodiag_save; 27191f4df5f7SStefano Zampini } 2720a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2721669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 27221ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 27231ae86dd6SStefano 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"); 2724a198735bSStefano Zampini n_isused = 0; 2725a198735bSStefano Zampini if (isused) { 2726a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2727a198735bSStefano Zampini } 2728a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2729a198735bSStefano Zampini st = st-n_isused; 27301ae86dd6SStefano Zampini if (n) { 2731a198735bSStefano Zampini const PetscInt *gidxs; 2732a198735bSStefano Zampini 27337dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2734a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2735a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2736a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2737a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2738a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 27391ae86dd6SStefano Zampini } else { 2740a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2741a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2742a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2743a198735bSStefano Zampini } 2744a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2745a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2746a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2747a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2748a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2749a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2750a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2751a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2752a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2753a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2754a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2755a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2756a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2757a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 27581ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27591ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27601ae86dd6SStefano Zampini } 27614edc6404Sstefano_zampini ierr = ISDestroy(&zerodiag_save);CHKERRQ(ierr); 2762b3afcdbeSStefano Zampini 2763b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 27644f1b2e48SStefano Zampini if (has_null_pressures) { 27654f1b2e48SStefano Zampini IS zerodiagc; 27664f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 27674f1b2e48SStefano Zampini PetscInt i,s,*nnz; 27684f1b2e48SStefano Zampini 27694f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2770339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 2771339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 2772339f8db1SStefano Zampini /* local change of basis for pressures */ 2773339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 277497d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2775339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2776339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2777339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 27784f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 27794f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 27804f1b2e48SStefano Zampini PetscInt nzs,j; 27814f1b2e48SStefano Zampini 27824f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 27834f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 27844f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 27854f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 27864f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 27874f1b2e48SStefano Zampini } 2788339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2789339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2790339f8db1SStefano Zampini /* set identity on velocities */ 2791339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 2792339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 2793339f8db1SStefano Zampini } 27944f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 27954f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 27969f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 27974f1b2e48SStefano 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); 2798339f8db1SStefano Zampini /* set change on pressures */ 27994f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 28004f1b2e48SStefano Zampini PetscScalar *array; 28014f1b2e48SStefano Zampini PetscInt nzs; 28024f1b2e48SStefano Zampini 28034f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 28044f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 28054f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2806339f8db1SStefano Zampini PetscScalar vals[2]; 2807339f8db1SStefano Zampini PetscInt cols[2]; 2808339f8db1SStefano Zampini 2809339f8db1SStefano Zampini cols[0] = idxs[i]; 28104f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2811339f8db1SStefano Zampini vals[0] = 1.; 2812b0f5fe93SStefano Zampini vals[1] = 1.; 28134f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2814339f8db1SStefano Zampini } 28154f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 28164f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 28174f1b2e48SStefano Zampini array[nzs-1] = 1.; 28184f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 28194f1b2e48SStefano Zampini /* store local idxs for p0 */ 28204f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 28214f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2822339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 28234f1b2e48SStefano Zampini } 2824339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2825339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2826a3df083aSStefano Zampini /* project if needed */ 2827a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 28281dd7afcfSStefano Zampini Mat M; 28291dd7afcfSStefano Zampini 28301dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2831339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 28321dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 28331dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2834a3df083aSStefano Zampini } 28354f1b2e48SStefano Zampini /* store global idxs for p0 */ 28364f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2837339f8db1SStefano Zampini } 2838ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 28394f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 2840b0f5fe93SStefano Zampini 2841b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 2842b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 284327b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 284427b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2845339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2846339f8db1SStefano Zampini PetscFunctionReturn(0); 2847339f8db1SStefano Zampini } 2848339f8db1SStefano Zampini 2849015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2850efc2fbd9SStefano Zampini { 2851efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2852de9d7bd0SStefano Zampini PetscScalar *array; 2853efc2fbd9SStefano Zampini PetscErrorCode ierr; 2854efc2fbd9SStefano Zampini 2855efc2fbd9SStefano Zampini PetscFunctionBegin; 2856efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 2857efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 28584f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2859efc2fbd9SStefano Zampini } 2860de9d7bd0SStefano Zampini if (get) { 2861efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 28624f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 28634f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 2864efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 2865de9d7bd0SStefano Zampini } else { 2866de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 2867de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2868de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2869de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 2870efc2fbd9SStefano Zampini } 2871efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2872efc2fbd9SStefano Zampini } 2873efc2fbd9SStefano Zampini 2874c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 2875c263805aSStefano Zampini { 2876c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2877c263805aSStefano Zampini PetscErrorCode ierr; 2878c263805aSStefano Zampini 2879c263805aSStefano Zampini PetscFunctionBegin; 2880c263805aSStefano Zampini /* TODO: add error checking 2881c263805aSStefano Zampini - avoid nested pop (or push) calls. 2882c263805aSStefano Zampini - cannot push before pop. 28831c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2884c263805aSStefano Zampini */ 28854f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2886efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2887efc2fbd9SStefano Zampini } 2888c263805aSStefano Zampini if (pop) { 2889a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 28904f1b2e48SStefano Zampini IS is_p0; 28914f1b2e48SStefano Zampini MatReuse reuse; 2892c263805aSStefano Zampini 2893c263805aSStefano Zampini /* extract B_0 */ 28944f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 28954f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 28964f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 28974f1b2e48SStefano Zampini } 28984f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 28997dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2900c263805aSStefano Zampini /* remove rows and cols from local problem */ 2901c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 290297d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 29034f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 29044f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2905a3df083aSStefano Zampini } else { 2906a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2907a3df083aSStefano Zampini PetscScalar *vals; 2908a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2909a3df083aSStefano Zampini 2910a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2911a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2912a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 29130b5adadeSStefano Zampini PetscInt *nnz; 2914a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2915a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2916a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2917331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2918331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2919331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2920331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2921331e053bSStefano Zampini } 2922331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2923331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2924331e053bSStefano Zampini } 2925a3df083aSStefano Zampini 2926a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2927a3df083aSStefano Zampini PetscScalar *array; 2928a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2929a3df083aSStefano Zampini 2930a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2931a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2932a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2933a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2934a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2935a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2936a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2937a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2938a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2939a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2940a3df083aSStefano Zampini cum = 0; 2941a3df083aSStefano Zampini for (j=0;j<n;j++) { 294222db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2943a3df083aSStefano Zampini vals[cum] = array[j]; 2944a3df083aSStefano Zampini idxs_ins[cum] = j; 2945a3df083aSStefano Zampini cum++; 2946a3df083aSStefano Zampini } 2947a3df083aSStefano Zampini } 2948a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2949a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2950a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2951a3df083aSStefano Zampini } 2952a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2953a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2954a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2955a3df083aSStefano Zampini } 2956c263805aSStefano Zampini } else { /* push */ 2957a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 29584f1b2e48SStefano Zampini PetscInt i; 29594f1b2e48SStefano Zampini 29604f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 29614f1b2e48SStefano Zampini PetscScalar *B0_vals; 29624f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 29634f1b2e48SStefano Zampini 29644f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 29654f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 29667b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 29674f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 29684f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 29694f1b2e48SStefano Zampini } 2970c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2971c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2972a3df083aSStefano Zampini } else { 2973a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 2974a3df083aSStefano Zampini } 2975c263805aSStefano Zampini } 2976c263805aSStefano Zampini PetscFunctionReturn(0); 2977c263805aSStefano Zampini } 2978c263805aSStefano Zampini 297908122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 2980b1b3d7a2SStefano Zampini { 2981b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 298208122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 298308122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 298408122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 298508122e43SStefano Zampini PetscScalar *work,lwork; 298608122e43SStefano Zampini PetscScalar *St,*S,*eigv; 298708122e43SStefano Zampini PetscScalar *Sarray,*Starray; 298808122e43SStefano Zampini PetscReal *eigs,thresh; 29891b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 2990f6f667cfSStefano Zampini PetscBool allocated_S_St; 299108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 299208122e43SStefano Zampini PetscReal *rwork; 299308122e43SStefano Zampini #endif 2994b1b3d7a2SStefano Zampini PetscErrorCode ierr; 2995b1b3d7a2SStefano Zampini 2996b1b3d7a2SStefano Zampini PetscFunctionBegin; 2997b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 2998af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 2999d750e150Sstefano_zampini if (sub_schurs->n_subs && (!sub_schurs->is_hermitian || !sub_schurs->is_posdef)) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adaptive selection not yet implemented for general matrix pencils (herm %d, posdef %d)\nRerun with -sub_schurs_hermitian 1 -sub_schurs_posdef 1 if the problem is SPD",sub_schurs->is_hermitian,sub_schurs->is_posdef); 300006a4e24aSStefano Zampini 3001fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3002fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3003fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3004fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 30051575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3006fd14bc51SStefano Zampini } 3007fd14bc51SStefano Zampini 3008e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 3009e496cd5dSStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d cc %d (%d,%d).\n",PetscGlobalRank,sub_schurs->n_subs,sub_schurs->is_hermitian,sub_schurs->is_posdef); 3010e496cd5dSStefano Zampini } 3011e496cd5dSStefano Zampini 301208122e43SStefano Zampini /* max size of subsets */ 301308122e43SStefano Zampini mss = 0; 301408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 301508122e43SStefano Zampini PetscInt subset_size; 3016862806e4SStefano Zampini 301708122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 301808122e43SStefano Zampini mss = PetscMax(mss,subset_size); 301908122e43SStefano Zampini } 302008122e43SStefano Zampini 302108122e43SStefano Zampini /* min/max and threshold */ 302208122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 3023f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 302408122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 3025f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 3026f6f667cfSStefano Zampini if (nmin) { 3027f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 3028f6f667cfSStefano Zampini } 302908122e43SStefano Zampini 303008122e43SStefano Zampini /* allocate lapack workspace */ 303108122e43SStefano Zampini cum = cum2 = 0; 303208122e43SStefano Zampini maxneigs = 0; 303308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 303408122e43SStefano Zampini PetscInt n,subset_size; 3035f6f667cfSStefano Zampini 303608122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 303708122e43SStefano Zampini n = PetscMin(subset_size,nmax); 30389162d606SStefano Zampini cum += subset_size; 30399162d606SStefano Zampini cum2 += subset_size*n; 304008122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 304108122e43SStefano Zampini } 304208122e43SStefano Zampini if (mss) { 30439ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 304408122e43SStefano Zampini PetscBLASInt B_itype = 1; 304508122e43SStefano Zampini PetscBLASInt B_N = mss; 30464c6709b3SStefano Zampini PetscReal zero = 0.0; 30474c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 304808122e43SStefano Zampini 304908122e43SStefano Zampini B_lwork = -1; 305008122e43SStefano Zampini S = NULL; 305108122e43SStefano Zampini St = NULL; 3052a58a30b4SStefano Zampini eigs = NULL; 3053a58a30b4SStefano Zampini eigv = NULL; 3054a58a30b4SStefano Zampini B_iwork = NULL; 3055a58a30b4SStefano Zampini B_ifail = NULL; 3056d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3057d1710679SStefano Zampini rwork = NULL; 3058d1710679SStefano Zampini #endif 30598bec7fa6SStefano Zampini thresh = 1.0; 306008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 306108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 306208122e43SStefano 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)); 306308122e43SStefano Zampini #else 306408122e43SStefano 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)); 306508122e43SStefano Zampini #endif 306608122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 306708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 306808122e43SStefano Zampini } else { 306908122e43SStefano Zampini /* TODO */ 307008122e43SStefano Zampini } 307108122e43SStefano Zampini } else { 307208122e43SStefano Zampini lwork = 0; 307308122e43SStefano Zampini } 307408122e43SStefano Zampini 307508122e43SStefano Zampini nv = 0; 3076d62866d3SStefano 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) */ 3077d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 307808122e43SStefano Zampini } 30794c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 3080f6f667cfSStefano Zampini if (allocated_S_St) { 3081f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 3082f6f667cfSStefano Zampini } 3083f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 308408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 308508122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 308608122e43SStefano Zampini #endif 30879162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 30889162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 30899162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 309008122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 30919162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 309208122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 309308122e43SStefano Zampini 309408122e43SStefano Zampini maxneigs = 0; 309572b8c272SStefano Zampini cum = cumarray = 0; 30969162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 30979162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 3098d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 309908122e43SStefano Zampini const PetscInt *idxs; 310008122e43SStefano Zampini 3101d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 310208122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 310308122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 310408122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 310508122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 31069162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 31079162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 310808122e43SStefano Zampini } 3109d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 311008122e43SStefano Zampini } 311108122e43SStefano Zampini 311208122e43SStefano Zampini if (mss) { /* multilevel */ 311308122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 311408122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 311508122e43SStefano Zampini } 311608122e43SStefano Zampini 3117ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 311808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 311908122e43SStefano Zampini const PetscInt *idxs; 31209d54b7f4SStefano Zampini PetscReal upper,lower; 3121862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 312208122e43SStefano Zampini PetscBLASInt B_N; 3123aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 312408122e43SStefano Zampini 31259d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 31269d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 31279d54b7f4SStefano Zampini lower = thresh; 31289d54b7f4SStefano Zampini } else { 31299d54b7f4SStefano Zampini upper = 1./thresh; 31309d54b7f4SStefano Zampini lower = 0.; 31319d54b7f4SStefano Zampini } 3132862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 3133ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 3134f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 3135f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 31369ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 3137aff50787SStefano Zampini PetscInt j,k; 3138aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 3139aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 3140aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 314108122e43SStefano Zampini } 314208122e43SStefano Zampini for (j=0;j<subset_size;j++) { 3143aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 3144aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 3145aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 3146aff50787SStefano Zampini } 314708122e43SStefano Zampini } 314808122e43SStefano Zampini } else { 314908122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 315008122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 315108122e43SStefano Zampini } 31528bec7fa6SStefano Zampini } else { 3153f6f667cfSStefano Zampini S = Sarray + cumarray; 3154f6f667cfSStefano Zampini St = Starray + cumarray; 31558bec7fa6SStefano Zampini } 3156aff50787SStefano Zampini /* see if we can save some work */ 3157b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 3158aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 3159aff50787SStefano Zampini } 3160aff50787SStefano Zampini 3161b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 3162aff50787SStefano Zampini B_neigs = 0; 3163aff50787SStefano Zampini } else { 31649ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 316508122e43SStefano Zampini PetscBLASInt B_itype = 1; 3166f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 31674c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 31689552c7c7SStefano Zampini PetscInt nmin_s; 3169b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 317008122e43SStefano Zampini 3171fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3172eee23b56SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %d/%d size %d count %d fid %d.\n",i,sub_schurs->n_subs,subset_size,pcbddc->mat_graph->count[idxs[0]]+1,pcbddc->mat_graph->which_dof[idxs[0]]); 3173fd14bc51SStefano Zampini } 3174d16cbb6bSStefano Zampini 3175b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 3176b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 3177b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 3178b7ab4a40SStefano Zampini } 3179b7ab4a40SStefano Zampini 318008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3181b7ab4a40SStefano Zampini if (compute_range) { 3182d16cbb6bSStefano Zampini 3183d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 318408122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 31859d54b7f4SStefano 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)); 318608122e43SStefano Zampini #else 31879d54b7f4SStefano 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)); 318808122e43SStefano Zampini #endif 3189b7ab4a40SStefano Zampini } else if (!same_data) { 3190d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 3191d16cbb6bSStefano Zampini B_IL = 1; 3192d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 31939d54b7f4SStefano 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)); 3194d16cbb6bSStefano Zampini #else 31959d54b7f4SStefano 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)); 3196d16cbb6bSStefano Zampini #endif 3197b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 3198b7ab4a40SStefano Zampini PetscInt k; 3199b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 3200b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 3201b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 3202b7ab4a40SStefano Zampini nmin = nmax; 3203b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 3204b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 3205b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 3206b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 3207b7ab4a40SStefano Zampini } 3208d16cbb6bSStefano Zampini } 320908122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 321008122e43SStefano Zampini if (B_ierr) { 32116c4ed002SBarry 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); 32126c4ed002SBarry 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); 32136c4ed002SBarry 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); 321408122e43SStefano Zampini } 321508122e43SStefano Zampini 321608122e43SStefano Zampini if (B_neigs > nmax) { 3217fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3218fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 3219fd14bc51SStefano Zampini } 32209d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 322108122e43SStefano Zampini B_neigs = nmax; 322208122e43SStefano Zampini } 322308122e43SStefano Zampini 32249552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 32259552c7c7SStefano Zampini if (B_neigs < nmin_s) { 322608122e43SStefano Zampini PetscBLASInt B_neigs2; 322708122e43SStefano Zampini 32289d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3229f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 32309d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 32319d54b7f4SStefano Zampini } else { 32329d54b7f4SStefano Zampini B_IL = B_neigs + 1; 32339d54b7f4SStefano Zampini B_IU = nmin_s; 32349d54b7f4SStefano Zampini } 3235fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3236fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, less than minimum required %d. Asking for %d to %d incl (fortran like)\n",B_neigs,nmin,B_IL,B_IU); 3237fd14bc51SStefano Zampini } 32389ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 32391ae86dd6SStefano Zampini PetscInt j,k; 324008122e43SStefano Zampini for (j=0;j<subset_size;j++) { 32411ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 32421ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 32431ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 324408122e43SStefano Zampini } 324508122e43SStefano Zampini } 324608122e43SStefano Zampini } else { 324708122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 324808122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 324908122e43SStefano Zampini } 325008122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 325108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 32529d54b7f4SStefano 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)); 325308122e43SStefano Zampini #else 32549d54b7f4SStefano 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)); 325508122e43SStefano Zampini #endif 325608122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 325708122e43SStefano Zampini B_neigs += B_neigs2; 325808122e43SStefano Zampini } 325908122e43SStefano Zampini if (B_ierr) { 32606c4ed002SBarry 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); 32616c4ed002SBarry 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); 32626c4ed002SBarry 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); 326308122e43SStefano Zampini } 3264fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3265ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 326608122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 326708122e43SStefano Zampini if (eigs[j] == 0.0) { 3268ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 326908122e43SStefano Zampini } else { 32709d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3271ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 32729d54b7f4SStefano Zampini } else { 32739d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 32749d54b7f4SStefano Zampini } 3275fd14bc51SStefano Zampini } 327608122e43SStefano Zampini } 327708122e43SStefano Zampini } 327808122e43SStefano Zampini } else { 327908122e43SStefano Zampini /* TODO */ 328008122e43SStefano Zampini } 3281aff50787SStefano Zampini } 32826c3e6151SStefano Zampini /* change the basis back to the original one */ 32836c3e6151SStefano Zampini if (sub_schurs->change) { 328472b8c272SStefano Zampini Mat change,phi,phit; 32856c3e6151SStefano Zampini 328603dfb2d7SStefano Zampini if (pcbddc->dbg_flag > 2) { 32876c3e6151SStefano Zampini PetscInt ii; 32886c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 32896c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 32906c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 3291684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3292684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 3293684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 3294684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3295684229deSStefano Zampini #else 32966c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 3297684229deSStefano Zampini #endif 32986c3e6151SStefano Zampini } 32996c3e6151SStefano Zampini } 33006c3e6151SStefano Zampini } 330172b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 33026c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 330372b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 33046c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 33056c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 33066c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 33076c3e6151SStefano Zampini } 33088bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 33098bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 33109162d606SStefano Zampini if (B_neigs) { 33119162d606SStefano 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); 3312fd14bc51SStefano Zampini 3313fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 33149552c7c7SStefano Zampini PetscInt ii; 33159552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 3316ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 33179552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 3318ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3319ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3320ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3321ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3322ac47001eSStefano Zampini #else 3323ac47001eSStefano 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); 3324ac47001eSStefano Zampini #endif 33259552c7c7SStefano Zampini } 33269552c7c7SStefano Zampini } 3327fd14bc51SStefano Zampini } 33289162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 33299162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 33309162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 33319162d606SStefano Zampini cum++; 333208122e43SStefano Zampini } 333308122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 333408122e43SStefano Zampini /* shift for next computation */ 333508122e43SStefano Zampini cumarray += subset_size*subset_size; 333608122e43SStefano Zampini } 3337fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3338fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3339fd14bc51SStefano Zampini } 334008122e43SStefano Zampini 334108122e43SStefano Zampini if (mss) { 334208122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 334308122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 3344f6f667cfSStefano Zampini /* destroy matrices (junk) */ 3345f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 3346f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 334708122e43SStefano Zampini } 3348f6f667cfSStefano Zampini if (allocated_S_St) { 3349f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 3350f6f667cfSStefano Zampini } 3351f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 335208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 335308122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 335408122e43SStefano Zampini #endif 335508122e43SStefano Zampini if (pcbddc->dbg_flag) { 33561b968477SStefano Zampini PetscInt maxneigs_r; 3357b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 33589b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 335908122e43SStefano Zampini } 336008122e43SStefano Zampini PetscFunctionReturn(0); 336108122e43SStefano Zampini } 3362b1b3d7a2SStefano Zampini 3363c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 3364c8587f34SStefano Zampini { 33658629588bSStefano Zampini PetscScalar *coarse_submat_vals; 3366c8587f34SStefano Zampini PetscErrorCode ierr; 3367c8587f34SStefano Zampini 3368c8587f34SStefano Zampini PetscFunctionBegin; 3369f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 33705e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3371c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3372c8587f34SStefano Zampini 3373684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 33740fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3375684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3376c8587f34SStefano Zampini 33778629588bSStefano Zampini /* 33788629588bSStefano Zampini Setup local correction and local part of coarse basis. 33798629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 33808629588bSStefano Zampini */ 338147f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 33828629588bSStefano Zampini 33838629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 33848629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 33858629588bSStefano Zampini 33868629588bSStefano Zampini /* free */ 33878629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3388c8587f34SStefano Zampini PetscFunctionReturn(0); 3389c8587f34SStefano Zampini } 3390c8587f34SStefano Zampini 3391674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3392674ae819SStefano Zampini { 3393674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3394674ae819SStefano Zampini PetscErrorCode ierr; 3395674ae819SStefano Zampini 3396674ae819SStefano Zampini PetscFunctionBegin; 3397674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 339830368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3399674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3400785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3401674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3402f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3403f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3404785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 340563602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 340663602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3407674ae819SStefano Zampini PetscFunctionReturn(0); 3408674ae819SStefano Zampini } 3409674ae819SStefano Zampini 3410674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3411674ae819SStefano Zampini { 3412674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 34134f1b2e48SStefano Zampini PetscInt i; 3414674ae819SStefano Zampini PetscErrorCode ierr; 3415674ae819SStefano Zampini 3416674ae819SStefano Zampini PetscFunctionBegin; 34171e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 34181e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3419a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3420b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3421674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 342216909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 34231dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3424674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3425669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3426fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 34279326c5c6Sstefano_zampini ierr = PCBDDCGraphDestroy(&pcbddc->mat_graph);CHKERRQ(ierr); 34284f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 34294f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 34304f1b2e48SStefano Zampini } 3431e68a0315Sstefano_zampini pcbddc->n_local_subs = 0; 34324f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3433e68a0315Sstefano_zampini ierr = PCBDDCSubSchursDestroy(&pcbddc->sub_schurs);CHKERRQ(ierr); 3434c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 34358af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 3436674ae819SStefano Zampini PetscFunctionReturn(0); 3437674ae819SStefano Zampini } 3438674ae819SStefano Zampini 3439674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3440674ae819SStefano Zampini { 3441674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3442674ae819SStefano Zampini PetscErrorCode ierr; 3443674ae819SStefano Zampini 3444674ae819SStefano Zampini PetscFunctionBegin; 3445674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 344658da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3447ca92afb2SStefano Zampini PetscScalar *array; 344806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 344906656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 345058da7f69SStefano Zampini } 3451674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3452674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 345315aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 345415aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3455674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3456674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3457674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 345806656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3459674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3460674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 34618ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3462674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3463674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3464674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 34659326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_D);CHKERRQ(ierr); 34669326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 34679326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3468f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3469727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 34700e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3471f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 347270cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 347381d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 34740369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 34751dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 34764f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 34778b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3478ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3479ca92afb2SStefano Zampini PetscInt i; 3480ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3481ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3482ca92afb2SStefano Zampini } 3483ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3484ca92afb2SStefano Zampini } 34854f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3486674ae819SStefano Zampini PetscFunctionReturn(0); 3487674ae819SStefano Zampini } 3488674ae819SStefano Zampini 3489f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 34906bfb1811SStefano Zampini { 34916bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 34926bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 34936bfb1811SStefano Zampini VecType impVecType; 34944f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 34956bfb1811SStefano Zampini PetscErrorCode ierr; 34966bfb1811SStefano Zampini 34976bfb1811SStefano Zampini PetscFunctionBegin; 34984f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3499b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 35006bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3501e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3502e7b262bdSStefano Zampini /* R nodes */ 3503e7b262bdSStefano Zampini old_size = -1; 3504e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3505e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3506e7b262bdSStefano Zampini } 3507e7b262bdSStefano Zampini if (n_R != old_size) { 3508e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3509e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 35106bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 35116bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 35126bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 35136bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3514e7b262bdSStefano Zampini } 3515e7b262bdSStefano Zampini /* local primal dofs */ 3516e7b262bdSStefano Zampini old_size = -1; 3517e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3518e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3519e7b262bdSStefano Zampini } 3520e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3521e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 352283b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3523e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 35246bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3525e7b262bdSStefano Zampini } 3526e7b262bdSStefano Zampini /* local explicit constraints */ 3527e7b262bdSStefano Zampini old_size = -1; 3528e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3529e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3530e7b262bdSStefano Zampini } 3531e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3532e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 353383b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 353483b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 353583b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 353683b7ccabSStefano Zampini } 35376bfb1811SStefano Zampini PetscFunctionReturn(0); 35386bfb1811SStefano Zampini } 35396bfb1811SStefano Zampini 354047f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 354188ebb749SStefano Zampini { 354225084f0cSStefano Zampini PetscErrorCode ierr; 354325084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 354488ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 354588ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3546d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 354725084f0cSStefano Zampini /* submatrices of local problem */ 354880677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 354906656605SStefano Zampini /* submatrices of local coarse problem */ 355006656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 355125084f0cSStefano Zampini /* working matrices */ 355206656605SStefano Zampini Mat C_CR; 355325084f0cSStefano Zampini /* additional working stuff */ 355406656605SStefano Zampini PC pc_R; 3555c58f9fdbSStefano Zampini Mat F,Brhs = NULL; 35565cbda25cSStefano Zampini Vec dummy_vec; 3557c58f9fdbSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction,sparserhs; 355825084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 355906656605SStefano Zampini PetscScalar *work; 356006656605SStefano Zampini PetscInt *idx_V_B; 3561ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 356206656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 3563ffd830a3SStefano Zampini 356425084f0cSStefano Zampini /* some shortcuts to scalars */ 356506656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 356688ebb749SStefano Zampini 356788ebb749SStefano Zampini PetscFunctionBegin; 35689a962809SStefano 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"); 3569ffd830a3SStefano Zampini 3570ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3571b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 35724f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3573b371cd4fSStefano Zampini n_B = pcis->n_B; 3574b371cd4fSStefano Zampini n_D = pcis->n - n_B; 357588ebb749SStefano Zampini n_R = pcis->n - n_vertices; 357688ebb749SStefano Zampini 357788ebb749SStefano Zampini /* vertices in boundary numbering */ 3578785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 35790e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 35806c4ed002SBarry Smith if (i != n_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D\n",n_vertices,i); 358188ebb749SStefano Zampini 358206656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3583019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 358406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 358506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 358606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 358706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 358806656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 358906656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 359006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 359106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 359206656605SStefano Zampini 359306656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 359406656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 359506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 359606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 359706656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 3598ffd830a3SStefano Zampini lda_rhs = n_R; 3599a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 360006656605SStefano Zampini if (isLU || isILU || isCHOL) { 360106656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 3602b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 3603df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3604d62866d3SStefano Zampini MatFactorType type; 3605d62866d3SStefano Zampini 3606df4d28bfSStefano Zampini F = reuse_solver->F; 36076816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 3608d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 3609ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 361022db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 361106656605SStefano Zampini } else { 361206656605SStefano Zampini F = NULL; 361306656605SStefano Zampini } 361406656605SStefano Zampini 3615c58f9fdbSStefano Zampini /* determine if we can use a sparse right-hand side */ 3616c58f9fdbSStefano Zampini sparserhs = PETSC_FALSE; 3617c58f9fdbSStefano Zampini if (F) { 3618ea799195SBarry Smith MatSolverType solver; 3619c58f9fdbSStefano Zampini 36203ca39a21SBarry Smith ierr = MatFactorGetSolverType(F,&solver);CHKERRQ(ierr); 3621c58f9fdbSStefano Zampini ierr = PetscStrcmp(solver,MATSOLVERMUMPS,&sparserhs);CHKERRQ(ierr); 3622c58f9fdbSStefano Zampini } 3623c58f9fdbSStefano Zampini 3624ffd830a3SStefano Zampini /* allocate workspace */ 3625ffd830a3SStefano Zampini n = 0; 3626ffd830a3SStefano Zampini if (n_constraints) { 3627ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3628ffd830a3SStefano Zampini } 3629ffd830a3SStefano Zampini if (n_vertices) { 3630ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3631ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3632ffd830a3SStefano Zampini } 36332a3a6641Sstefano_zampini if (!pcbddc->symmetric_primal) { 36342a3a6641Sstefano_zampini n = PetscMax(2*lda_rhs*pcbddc->local_primal_size,n); 36352a3a6641Sstefano_zampini } 3636ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3637ffd830a3SStefano Zampini 36385cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 36395cbda25cSStefano Zampini dummy_vec = NULL; 36405cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 36415cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 36425cbda25cSStefano Zampini } 36435cbda25cSStefano Zampini 364488ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 364588ebb749SStefano Zampini if (n_constraints) { 3646837cedc9SStefano Zampini Mat M3,C_B; 364706656605SStefano Zampini IS is_aux; 364880677318SStefano Zampini PetscScalar *array,*array2; 364906656605SStefano Zampini 3650f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 365180677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 365288ebb749SStefano Zampini 365325084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 365425084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 36557dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 36567dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 365788ebb749SStefano Zampini 365880677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 365980677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 3660c58f9fdbSStefano Zampini if (!sparserhs) { 3661ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 366288ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 366306656605SStefano Zampini const PetscScalar *row_cmat_values; 366406656605SStefano Zampini const PetscInt *row_cmat_indices; 366506656605SStefano Zampini PetscInt size_of_constraint,j; 366688ebb749SStefano Zampini 366706656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 366806656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 3669ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 367006656605SStefano Zampini } 367106656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 367206656605SStefano Zampini } 3673c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&Brhs);CHKERRQ(ierr); 3674c58f9fdbSStefano Zampini } else { 3675c58f9fdbSStefano Zampini Mat tC_CR; 3676c58f9fdbSStefano Zampini 3677c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3678c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 3679c58f9fdbSStefano Zampini PetscScalar *aa; 3680c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 3681c58f9fdbSStefano Zampini PetscBool done; 3682c58f9fdbSStefano Zampini 3683c58f9fdbSStefano Zampini ierr = MatGetRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 368413903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 3685c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(C_CR,&aa);CHKERRQ(ierr); 3686c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_constraints,lda_rhs,ii,jj,aa,&tC_CR);CHKERRQ(ierr); 3687c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 368813903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 3689c58f9fdbSStefano Zampini } else { 3690c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)C_CR);CHKERRQ(ierr); 3691c58f9fdbSStefano Zampini tC_CR = C_CR; 3692c58f9fdbSStefano Zampini } 3693c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tC_CR,&Brhs);CHKERRQ(ierr); 3694c58f9fdbSStefano Zampini ierr = MatDestroy(&tC_CR);CHKERRQ(ierr); 3695c58f9fdbSStefano Zampini } 3696ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 369706656605SStefano Zampini if (F) { 3698a3df083aSStefano Zampini if (need_benign_correction) { 3699df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3700a3df083aSStefano Zampini 370172b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 370272b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 3703a3df083aSStefano Zampini } 3704c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,local_auxmat2_R);CHKERRQ(ierr); 3705a3df083aSStefano Zampini if (need_benign_correction) { 3706a3df083aSStefano Zampini PetscScalar *marr; 3707df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3708a3df083aSStefano Zampini 3709a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 37105cbda25cSStefano Zampini if (lda_rhs != n_R) { 37115cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 37125cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 37135cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 37145cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 37155cbda25cSStefano Zampini } 37165cbda25cSStefano Zampini } else { 3717a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 3718a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 37195cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3720a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3721a3df083aSStefano Zampini } 37225cbda25cSStefano Zampini } 3723a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 3724a3df083aSStefano Zampini } 372506656605SStefano Zampini } else { 372680677318SStefano Zampini PetscScalar *marr; 372780677318SStefano Zampini 372880677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 372906656605SStefano Zampini for (i=0;i<n_constraints;i++) { 3730ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3731ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 373206656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 373306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 373406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 373506656605SStefano Zampini } 373680677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 373706656605SStefano Zampini } 3738c58f9fdbSStefano Zampini if (sparserhs) { 3739c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3740c58f9fdbSStefano Zampini } 3741c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 374280677318SStefano Zampini if (!pcbddc->switch_static) { 374380677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 374480677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 374580677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 374680677318SStefano Zampini for (i=0;i<n_constraints;i++) { 3747ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 374880677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 374980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 375080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 375180677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 375280677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 375380677318SStefano Zampini } 375480677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 375580677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 375672b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 375780677318SStefano Zampini } else { 3758ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3759ffd830a3SStefano Zampini IS dummy; 3760ffd830a3SStefano Zampini 3761ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 37627dae84e0SHong Zhang ierr = MatCreateSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 3763ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 3764ffd830a3SStefano Zampini } else { 376580677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 376680677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 3767ffd830a3SStefano Zampini } 376825084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 376980677318SStefano Zampini } 377080677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 377180677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 377280677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 377380677318SStefano Zampini if (isCHOL) { 377480677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 377580677318SStefano Zampini } else { 377625084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 377780677318SStefano Zampini } 3778837cedc9SStefano Zampini ierr = MatSeqDenseInvertFactors_Private(M3);CHKERRQ(ierr); 377980677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 3780837cedc9SStefano Zampini ierr = MatMatMult(M3,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 378172b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 3782837cedc9SStefano Zampini ierr = MatCopy(M3,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 3783837cedc9SStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 3784f4ddd8eeSStefano Zampini } 3785fc227af8SStefano Zampini 3786fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 378788ebb749SStefano Zampini if (n_vertices) { 378806656605SStefano Zampini IS is_aux; 3789c58f9fdbSStefano Zampini PetscBool isseqaij; 37903a50541eSStefano Zampini 3791b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 37926816873aSStefano Zampini IS tis; 37936816873aSStefano Zampini 37946816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 37956816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 37966816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 37976816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 37986816873aSStefano Zampini } else { 37993a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 38006816873aSStefano Zampini } 38017dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 38027dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 3803c58f9fdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 3804c58f9fdbSStefano Zampini if (!isseqaij) { /* MatMatMult(A_VR,A_RRmA_RV) below will raise an error */ 3805c58f9fdbSStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 3806c58f9fdbSStefano Zampini } 38077dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 380825084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 380988ebb749SStefano Zampini } 381088ebb749SStefano Zampini 381188ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 3812f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 381306656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 381406656605SStefano Zampini if (pcbddc->coarse_phi_D) { 381506656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 381606656605SStefano Zampini } 3817f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 381806656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 381906656605SStefano Zampini PetscScalar *marray; 382006656605SStefano Zampini 382106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 382206656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 3823f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3824f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3825f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3826f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3827f4ddd8eeSStefano Zampini } 3828f4ddd8eeSStefano Zampini } 382906656605SStefano Zampini 3830f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 3831a6e023c1Sstefano_zampini PetscScalar *marr; 383288ebb749SStefano Zampini 3833a6e023c1Sstefano_zampini /* memory size */ 383406656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 3835a6e023c1Sstefano_zampini if (pcbddc->switch_static || pcbddc->dbg_flag) n += n_D*pcbddc->local_primal_size; 3836a6e023c1Sstefano_zampini if (!pcbddc->symmetric_primal) n *= 2; 3837a6e023c1Sstefano_zampini ierr = PetscCalloc1(n,&marr);CHKERRQ(ierr); 3838a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3839a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 38408eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3841a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3842a6e023c1Sstefano_zampini marr += n_D*pcbddc->local_primal_size; 384388ebb749SStefano Zampini } 38443301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 3845a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3846a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 38478eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3848a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 384988ebb749SStefano Zampini } 385088ebb749SStefano Zampini } else { 3851c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 3852c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 38531b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3854c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 3855c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 3856c0553b1fSStefano Zampini } 385788ebb749SStefano Zampini } 385806656605SStefano Zampini } 3859019a44ceSStefano Zampini 386006656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 38614f1b2e48SStefano Zampini p0_lidx_I = NULL; 38624f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 3863d12edf2fSStefano Zampini const PetscInt *idxs; 3864d12edf2fSStefano Zampini 3865d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 38664f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 38674f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 38684f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 38694f1b2e48SStefano Zampini } 3870d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 3871d12edf2fSStefano Zampini } 3872d16cbb6bSStefano Zampini 387306656605SStefano Zampini /* vertices */ 387406656605SStefano Zampini if (n_vertices) { 3875c58f9fdbSStefano Zampini PetscBool restoreavr = PETSC_FALSE; 387616f15bc4SStefano Zampini 3877af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 387804708bb6SStefano Zampini 387916f15bc4SStefano Zampini if (n_R) { 388014393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 388106656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 388216f15bc4SStefano Zampini PetscScalar *x,*y; 388306656605SStefano Zampini 388421eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 388514393ed6SStefano Zampini if (need_benign_correction) { 388614393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 388714393ed6SStefano Zampini IS is_p0; 388814393ed6SStefano Zampini PetscInt *idxs_p0,n; 388914393ed6SStefano Zampini 389014393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 389114393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 389214393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 3893af25d912SStefano Zampini if (n != pcbddc->benign_n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in R numbering for benign p0! %d != %d\n",n,pcbddc->benign_n); 389414393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 389514393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 38967dae84e0SHong Zhang ierr = MatCreateSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 389714393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 389814393ed6SStefano Zampini } 389914393ed6SStefano Zampini 3900c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3901c58f9fdbSStefano Zampini if (!sparserhs || need_benign_correction) { 3902ffd830a3SStefano Zampini if (lda_rhs == n_R) { 3903af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3904ffd830a3SStefano Zampini } else { 3905ca92afb2SStefano Zampini PetscScalar *av,*array; 3906ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 3907ca92afb2SStefano Zampini PetscInt n; 3908ca92afb2SStefano Zampini PetscBool flg_row; 3909ffd830a3SStefano Zampini 3910ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 3911ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 39129d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3913ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3914ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 3915ca92afb2SStefano Zampini for (i=0;i<n;i++) { 3916ca92afb2SStefano Zampini PetscInt j; 3917ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 3918ffd830a3SStefano Zampini } 3919ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3920ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3921ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 3922ffd830a3SStefano Zampini } 3923a3df083aSStefano Zampini if (need_benign_correction) { 3924df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3925a3df083aSStefano Zampini PetscScalar *marr; 3926a3df083aSStefano Zampini 3927a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 392814393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 392914393ed6SStefano Zampini 393014393ed6SStefano Zampini | 0 0 0 | (V) 393114393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 393214393ed6SStefano Zampini | 0 0 -1 | (p0) 393314393ed6SStefano Zampini 393414393ed6SStefano Zampini */ 3935df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 393614393ed6SStefano Zampini const PetscScalar *vals; 393714393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 393814393ed6SStefano Zampini PetscInt n,j,nz; 393914393ed6SStefano Zampini 3940df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3941df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 394214393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 394314393ed6SStefano Zampini for (j=0;j<n;j++) { 394414393ed6SStefano Zampini PetscScalar val = vals[j]; 394514393ed6SStefano Zampini PetscInt k,col = idxs[j]; 394614393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 394714393ed6SStefano Zampini } 394814393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3949df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 395014393ed6SStefano Zampini } 395172b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 395272b8c272SStefano Zampini } 3953c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RV);CHKERRQ(ierr); 3954c58f9fdbSStefano Zampini Brhs = A_RV; 3955c58f9fdbSStefano Zampini } else { 3956c58f9fdbSStefano Zampini Mat tA_RVT,A_RVT; 3957c58f9fdbSStefano Zampini 3958c58f9fdbSStefano Zampini if (!pcbddc->symmetric_primal) { 3959fb6280fbSStefano Zampini /* A_RV already scaled by -1 */ 3960c58f9fdbSStefano Zampini ierr = MatTranspose(A_RV,MAT_INITIAL_MATRIX,&A_RVT);CHKERRQ(ierr); 3961c58f9fdbSStefano Zampini } else { 3962c58f9fdbSStefano Zampini restoreavr = PETSC_TRUE; 3963c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 3964c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_VR);CHKERRQ(ierr); 3965c58f9fdbSStefano Zampini A_RVT = A_VR; 3966c58f9fdbSStefano Zampini } 3967c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 3968c58f9fdbSStefano Zampini PetscScalar *aa; 3969c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 3970c58f9fdbSStefano Zampini PetscBool done; 3971c58f9fdbSStefano Zampini 3972c58f9fdbSStefano Zampini ierr = MatGetRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 397313903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 3974c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(A_RVT,&aa);CHKERRQ(ierr); 3975c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_vertices,lda_rhs,ii,jj,aa,&tA_RVT);CHKERRQ(ierr); 3976c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 397713903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 3978c58f9fdbSStefano Zampini } else { 3979c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RVT);CHKERRQ(ierr); 3980c58f9fdbSStefano Zampini tA_RVT = A_RVT; 3981c58f9fdbSStefano Zampini } 3982c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tA_RVT,&Brhs);CHKERRQ(ierr); 3983c58f9fdbSStefano Zampini ierr = MatDestroy(&tA_RVT);CHKERRQ(ierr); 3984c58f9fdbSStefano Zampini ierr = MatDestroy(&A_RVT);CHKERRQ(ierr); 3985c58f9fdbSStefano Zampini } 398672b8c272SStefano Zampini if (F) { 398714393ed6SStefano Zampini /* need to correct the rhs */ 398872b8c272SStefano Zampini if (need_benign_correction) { 398972b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 399072b8c272SStefano Zampini PetscScalar *marr; 399172b8c272SStefano Zampini 3992c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&marr);CHKERRQ(ierr); 39935cbda25cSStefano Zampini if (lda_rhs != n_R) { 39945cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 39955cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 39965cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 39975cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 39985cbda25cSStefano Zampini } 39995cbda25cSStefano Zampini } else { 4000a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4001a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 40025cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 4003a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4004a3df083aSStefano Zampini } 40055cbda25cSStefano Zampini } 4006c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&marr);CHKERRQ(ierr); 4007a3df083aSStefano Zampini } 4008c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,A_RRmA_RV);CHKERRQ(ierr); 4009c58f9fdbSStefano Zampini if (restoreavr) { 4010c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4011c58f9fdbSStefano Zampini } 401214393ed6SStefano Zampini /* need to correct the solution */ 4013a3df083aSStefano Zampini if (need_benign_correction) { 4014df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4015a3df083aSStefano Zampini PetscScalar *marr; 4016a3df083aSStefano Zampini 4017a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 40185cbda25cSStefano Zampini if (lda_rhs != n_R) { 40195cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 40205cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 40215cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 40225cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 40235cbda25cSStefano Zampini } 40245cbda25cSStefano Zampini } else { 4025a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4026a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 40275cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 4028a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4029a3df083aSStefano Zampini } 40305cbda25cSStefano Zampini } 4031a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 4032a3df083aSStefano Zampini } 403306656605SStefano Zampini } else { 4034c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&y);CHKERRQ(ierr); 403506656605SStefano Zampini for (i=0;i<n_vertices;i++) { 4036ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 4037ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 403806656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 403906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 404006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 404106656605SStefano Zampini } 4042c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&y);CHKERRQ(ierr); 404306656605SStefano Zampini } 404480677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4045c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 4046ffd830a3SStefano Zampini /* S_VV and S_CV */ 404706656605SStefano Zampini if (n_constraints) { 404806656605SStefano Zampini Mat B; 404980677318SStefano Zampini 4050ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 405180677318SStefano Zampini for (i=0;i<n_vertices;i++) { 4052ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 4053ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 405480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 405580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 405680677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 405780677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 405880677318SStefano Zampini } 4059ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 406080677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 406180677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 4062ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 406380677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 406406656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 4065ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 4066ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 406706656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 406806656605SStefano Zampini } 4069ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4070ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 4071ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4072ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 4073ffd830a3SStefano Zampini } 407406656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 407514393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 407614393ed6SStefano Zampini if (need_benign_correction) { 4077df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 407814393ed6SStefano Zampini PetscScalar *marr,*sums; 407914393ed6SStefano Zampini 408014393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 4081f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 4082df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 408314393ed6SStefano Zampini const PetscScalar *vals; 408414393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 408514393ed6SStefano Zampini PetscInt n,j,nz; 408614393ed6SStefano Zampini 4087df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4088df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 408914393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 409014393ed6SStefano Zampini PetscInt k; 409114393ed6SStefano Zampini sums[j] = 0.; 409214393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 409314393ed6SStefano Zampini } 409414393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 409514393ed6SStefano Zampini for (j=0;j<n;j++) { 409614393ed6SStefano Zampini PetscScalar val = vals[j]; 409714393ed6SStefano Zampini PetscInt k; 409814393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 409914393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 410014393ed6SStefano Zampini } 410114393ed6SStefano Zampini } 410214393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4103df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 410414393ed6SStefano Zampini } 410514393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 4106f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 410714393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 410814393ed6SStefano Zampini } 410980677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 411006656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 411106656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 411206656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 411306656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 411406656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 411506656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 411606656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4117d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 4118019a44ceSStefano Zampini } else { 4119d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4120d16cbb6bSStefano Zampini } 412121eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 4122d16cbb6bSStefano Zampini 412306656605SStefano Zampini /* coarse basis functions */ 412406656605SStefano Zampini for (i=0;i<n_vertices;i++) { 412516f15bc4SStefano Zampini PetscScalar *y; 412616f15bc4SStefano Zampini 4127ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 412806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 412906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 413006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 413106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 413206656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 413306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 413406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 413506656605SStefano Zampini 413606656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 41374f1b2e48SStefano Zampini PetscInt j; 41384f1b2e48SStefano Zampini 413906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 414006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 414106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 414206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 414306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 41444f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 414506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 414606656605SStefano Zampini } 414706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 414806656605SStefano Zampini } 414904708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 415004708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 415106656605SStefano Zampini } 41525cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 415306656605SStefano Zampini 415406656605SStefano Zampini if (n_constraints) { 415506656605SStefano Zampini Mat B; 415606656605SStefano Zampini 4157ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 415806656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 415980677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 416006656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 416106656605SStefano Zampini if (n_vertices) { 416203dfb2d7SStefano Zampini if (isCHOL || need_benign_correction) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 416380677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 416480677318SStefano Zampini } else { 416580677318SStefano Zampini Mat S_VCt; 416680677318SStefano Zampini 4167ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4168ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 416972b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 4170ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 4171ffd830a3SStefano Zampini } 417280677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 417380677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 417480677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 417580677318SStefano Zampini } 417606656605SStefano Zampini } 417706656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 417806656605SStefano Zampini /* coarse basis functions */ 417906656605SStefano Zampini for (i=0;i<n_constraints;i++) { 418006656605SStefano Zampini PetscScalar *y; 418106656605SStefano Zampini 4182ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 418306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 418406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 418506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 418606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 418706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 418806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 418906656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 41904f1b2e48SStefano Zampini PetscInt j; 41914f1b2e48SStefano Zampini 419206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 419306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 419406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 419506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 419606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 41974f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 419806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 419906656605SStefano Zampini } 420006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 420106656605SStefano Zampini } 420206656605SStefano Zampini } 420380677318SStefano Zampini if (n_constraints) { 420480677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 420580677318SStefano Zampini } 42064f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 420772b8c272SStefano Zampini 420872b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 420972b8c272SStefano Zampini if (pcbddc->benign_n) { 421072b8c272SStefano Zampini Mat B0_B,B0_BPHI; 421172b8c272SStefano Zampini IS is_dummy; 421272b8c272SStefano Zampini PetscScalar *data; 421372b8c272SStefano Zampini PetscInt j; 421472b8c272SStefano Zampini 421572b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 42167dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 421772b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 421872b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 421986c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 422072b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 422172b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 422272b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 422372b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 422472b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 422572b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 422672b8c272SStefano Zampini } 422772b8c272SStefano Zampini } 422872b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 422972b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 423072b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 423172b8c272SStefano Zampini } 4232019a44ceSStefano Zampini 423306656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 42343301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4235ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 4236ffd830a3SStefano Zampini PetscScalar *marray; 423706656605SStefano Zampini 423806656605SStefano Zampini if (n_constraints) { 4239ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 424006656605SStefano Zampini 4241abc8f43dSstefano_zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 424206656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 4243ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 424416f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 424506656605SStefano Zampini if (n_vertices) { 4246ffd830a3SStefano Zampini Mat S_VCT; 424706656605SStefano Zampini 424806656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 4249ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 425016f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 425106656605SStefano Zampini } 4252ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 42535b782168SStefano Zampini } else { 42545b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 425506656605SStefano Zampini } 425616f15bc4SStefano Zampini if (n_vertices && n_R) { 4257ffd830a3SStefano Zampini PetscScalar *av,*marray; 4258ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 4259ffd830a3SStefano Zampini PetscInt n; 4260ffd830a3SStefano Zampini PetscBool flg_row; 426106656605SStefano Zampini 4262ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 4263af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4264ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4265ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 4266ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4267ffd830a3SStefano Zampini for (i=0;i<n;i++) { 4268ffd830a3SStefano Zampini PetscInt j; 4269ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 4270ffd830a3SStefano Zampini } 4271ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4272ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4273ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 427406656605SStefano Zampini } 427506656605SStefano Zampini 4276ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 4277abc8f43dSstefano_zampini if (n_vertices) { 4278ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4279ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 4280ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 4281ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 428206656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 428306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 428406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 428506656605SStefano Zampini } 4286ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4287abc8f43dSstefano_zampini } 42885b782168SStefano Zampini if (B_C) { 4289ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 4290ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 4291ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 4292ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 4293ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4294ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4295ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 429606656605SStefano Zampini } 4297ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 42985b782168SStefano Zampini } 429906656605SStefano Zampini /* coarse basis functions */ 430006656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 430106656605SStefano Zampini PetscScalar *y; 430206656605SStefano Zampini 4303ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 430406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 430506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 430606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 430706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 430806656605SStefano Zampini if (i<n_vertices) { 430906656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 431006656605SStefano Zampini } 431106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 431206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 431306656605SStefano Zampini 431406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 431506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 431606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 431706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 431806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 431906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 432006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 432106656605SStefano Zampini } 432206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 432306656605SStefano Zampini } 4324ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 4325ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 432606656605SStefano Zampini } 4327a6e023c1Sstefano_zampini 4328d62866d3SStefano Zampini /* free memory */ 432988ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 433006656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 433106656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 433206656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 433306656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 4334d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4335d62866d3SStefano Zampini if (n_vertices) { 4336d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 4337d62866d3SStefano Zampini } 4338d62866d3SStefano Zampini if (n_constraints) { 4339d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 4340d62866d3SStefano Zampini } 434188ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 434288ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 434388ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 4344d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 434588ebb749SStefano Zampini Mat coarse_sub_mat; 434625084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 434788ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 434888ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 434988ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 43508bec7fa6SStefano Zampini Mat C_B,CPHI; 43518bec7fa6SStefano Zampini IS is_dummy; 43528bec7fa6SStefano Zampini Vec mones; 435388ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 435488ebb749SStefano Zampini PetscReal real_value; 435588ebb749SStefano Zampini 4356a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 4357a3df083aSStefano Zampini Mat A; 4358a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 43597dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 43607dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 43617dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 43627dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4363a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 4364a3df083aSStefano Zampini } else { 436588ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 436688ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 436788ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 436888ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4369a3df083aSStefano Zampini } 437088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 437188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 4372ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 437388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 437488ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 437588ebb749SStefano Zampini } 437688ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 437788ebb749SStefano Zampini 437825084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 43793301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 438025084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4381ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 438288ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 438388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 438488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 438588ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 438688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 438788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 438888ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 438988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 439088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 439188ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 439288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 439388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 439488ebb749SStefano Zampini } else { 439588ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 439688ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 439788ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 439888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 439988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 440088ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 440188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 440288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 440388ebb749SStefano Zampini } 440488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 440588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 440688ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 4407511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 44084f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4409fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 4410d12edf2fSStefano Zampini PetscScalar *data,*data2; 44114f1b2e48SStefano Zampini PetscInt j; 4412d12edf2fSStefano Zampini 44134f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 44147dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 4415d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 441686c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 4417d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 4418d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 44194f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 44204f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 4421d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 44224f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 44234f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 44244f1b2e48SStefano Zampini } 4425d12edf2fSStefano Zampini } 4426d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 4427d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 4428d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4429d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4430d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4431d12edf2fSStefano Zampini } 4432d12edf2fSStefano Zampini #if 0 4433d12edf2fSStefano Zampini { 4434d12edf2fSStefano Zampini PetscViewer viewer; 4435d12edf2fSStefano Zampini char filename[256]; 4436ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4437d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4438a7414863SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4439ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4440ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4441ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4442d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 4443a7414863SStefano Zampini if (pcbddc->coarse_phi_B) { 4444ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4445ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 444672b8c272SStefano Zampini } 4447ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4448ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4449ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4450ffd830a3SStefano Zampini } 4451ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4452ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4453ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4454ffd830a3SStefano Zampini } 445572b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4456ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4457ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4458ffd830a3SStefano Zampini } 4459fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->local_mat,"A");CHKERRQ(ierr); 4460fb6280fbSStefano Zampini ierr = MatView(pcbddc->local_mat,viewer);CHKERRQ(ierr); 4461fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->ConstraintMatrix,"C");CHKERRQ(ierr); 4462fb6280fbSStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,viewer);CHKERRQ(ierr); 4463fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_I_local,"I");CHKERRQ(ierr); 4464fb6280fbSStefano Zampini ierr = ISView(pcis->is_I_local,viewer);CHKERRQ(ierr); 4465fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_B_local,"B");CHKERRQ(ierr); 4466fb6280fbSStefano Zampini ierr = ISView(pcis->is_B_local,viewer);CHKERRQ(ierr); 4467fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->is_R_local,"R");CHKERRQ(ierr); 4468fb6280fbSStefano Zampini ierr = ISView(pcbddc->is_R_local,viewer);CHKERRQ(ierr); 4469d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4470d12edf2fSStefano Zampini } 4471d12edf2fSStefano Zampini #endif 447281d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 44738bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 44741575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 447506656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 44768bec7fa6SStefano Zampini 44778bec7fa6SStefano Zampini /* check constraints */ 4478a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 44797dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 44804f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 44818bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4482a00504b5SStefano Zampini } else { 4483a00504b5SStefano Zampini PetscScalar *data; 4484a00504b5SStefano Zampini Mat tmat; 4485a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4486a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4487a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4488a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4489a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4490a00504b5SStefano Zampini } 44918bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 44928bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 44938bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 44948bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4495bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4496ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4497bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4498bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4499bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4500bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4501bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 450288ebb749SStefano Zampini } 45038bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 45048bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 45058bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 45068bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 450725084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 450888ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 450988ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 451088ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 451188ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 451288ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 451388ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 451488ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 451588ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 451688ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 451788ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4518ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 451988ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 452088ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 452188ebb749SStefano Zampini } 452288ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 452388ebb749SStefano Zampini } 45248629588bSStefano Zampini /* get back data */ 45258629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 452688ebb749SStefano Zampini PetscFunctionReturn(0); 452788ebb749SStefano Zampini } 452888ebb749SStefano Zampini 45297dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4530aa0d41d4SStefano Zampini { 4531d65f70fdSStefano Zampini Mat *work_mat; 4532d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4533d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4534c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4535aa0d41d4SStefano Zampini PetscErrorCode ierr; 4536aa0d41d4SStefano Zampini 4537aa0d41d4SStefano Zampini PetscFunctionBegin; 4538d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4539d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4540d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4541d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4542aa0d41d4SStefano Zampini 4543d65f70fdSStefano Zampini if (!rsorted) { 4544906d46d4SStefano Zampini const PetscInt *idxs; 4545906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4546aa0d41d4SStefano Zampini 4547d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4548d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4549d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4550d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4551aa0d41d4SStefano Zampini } 4552d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4553d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4554d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4555d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4556aa0d41d4SStefano Zampini } 4557d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4558d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4559d65f70fdSStefano Zampini } else { 4560d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4561d65f70fdSStefano Zampini isrow_s = isrow; 4562aa0d41d4SStefano Zampini } 4563906d46d4SStefano Zampini 4564d65f70fdSStefano Zampini if (!csorted) { 4565d65f70fdSStefano Zampini if (isrow == iscol) { 4566d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4567d65f70fdSStefano Zampini iscol_s = isrow_s; 4568d65f70fdSStefano Zampini } else { 4569d65f70fdSStefano Zampini const PetscInt *idxs; 4570d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4571906d46d4SStefano Zampini 4572d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4573d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4574d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4575d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4576d65f70fdSStefano Zampini } 4577d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 4578d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 4579d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4580d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 4581d65f70fdSStefano Zampini } 4582d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 4583d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 4584d65f70fdSStefano Zampini } 4585d65f70fdSStefano Zampini } else { 4586d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 4587d65f70fdSStefano Zampini iscol_s = iscol; 4588d65f70fdSStefano Zampini } 4589d65f70fdSStefano Zampini 45907dae84e0SHong Zhang ierr = MatCreateSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4591d65f70fdSStefano Zampini 4592d65f70fdSStefano Zampini if (!rsorted || !csorted) { 4593906d46d4SStefano Zampini Mat new_mat; 4594d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 4595906d46d4SStefano Zampini 4596d65f70fdSStefano Zampini if (!rsorted) { 4597d65f70fdSStefano Zampini PetscInt *idxs_r,i; 4598d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 4599d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4600d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 4601906d46d4SStefano Zampini } 4602d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 4603d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 4604d65f70fdSStefano Zampini } else { 4605d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 4606906d46d4SStefano Zampini } 4607d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 4608d65f70fdSStefano Zampini 4609d65f70fdSStefano Zampini if (!csorted) { 4610d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 4611d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 4612d65f70fdSStefano Zampini is_perm_c = is_perm_r; 4613d65f70fdSStefano Zampini } else { 4614d65f70fdSStefano Zampini PetscInt *idxs_c,i; 4615f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 4616d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 4617d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4618d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 4619d65f70fdSStefano Zampini } 4620d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 4621d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 4622d65f70fdSStefano Zampini } 4623d65f70fdSStefano Zampini } else { 4624d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 4625d65f70fdSStefano Zampini } 4626d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 4627d65f70fdSStefano Zampini 4628d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 4629d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 4630d65f70fdSStefano Zampini work_mat[0] = new_mat; 4631d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 4632d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 4633d65f70fdSStefano Zampini } 4634d65f70fdSStefano Zampini 4635d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 4636d65f70fdSStefano Zampini *B = work_mat[0]; 4637d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 4638d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 4639d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 4640d65f70fdSStefano Zampini PetscFunctionReturn(0); 4641d65f70fdSStefano Zampini } 4642d65f70fdSStefano Zampini 46435e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 4644aa0d41d4SStefano Zampini { 4645aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 46465e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4647022d8d2bSstefano_zampini Mat new_mat,lA; 46485e8657edSStefano Zampini IS is_local,is_global; 4649d65f70fdSStefano Zampini PetscInt local_size; 4650d65f70fdSStefano Zampini PetscBool isseqaij; 4651aa0d41d4SStefano Zampini PetscErrorCode ierr; 4652aa0d41d4SStefano Zampini 4653aa0d41d4SStefano Zampini PetscFunctionBegin; 4654aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 46555e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 46565e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 4657b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 4658aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 46597dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 4660aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 4661906d46d4SStefano Zampini 4662906d46d4SStefano Zampini /* check */ 4663906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4664906d46d4SStefano Zampini Vec x,x_change; 4665906d46d4SStefano Zampini PetscReal error; 4666906d46d4SStefano Zampini 46675e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 4668906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 46695e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 4670e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4671e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4672d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 467388428137SStefano Zampini if (!pcbddc->change_interior) { 467488428137SStefano Zampini const PetscScalar *x,*y,*v; 467588428137SStefano Zampini PetscReal lerror = 0.; 467688428137SStefano Zampini PetscInt i; 467788428137SStefano Zampini 467888428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 467988428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 468088428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 468188428137SStefano Zampini for (i=0;i<local_size;i++) 468288428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 468388428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 468488428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 468588428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 468688428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 468788428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4688637e8532SStefano Zampini if (error > PETSC_SMALL) { 4689637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4690637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on I: %1.6e\n",error); 4691637e8532SStefano Zampini } else { 4692637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on I: %1.6e\n",error); 4693637e8532SStefano Zampini } 4694637e8532SStefano Zampini } 469588428137SStefano Zampini } 4696e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4697e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4698906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4699906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4700637e8532SStefano Zampini if (error > PETSC_SMALL) { 4701637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4702637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 4703637e8532SStefano Zampini } else { 4704637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on N: %1.6e\n",error); 4705637e8532SStefano Zampini } 4706637e8532SStefano Zampini } 4707906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4708906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4709906d46d4SStefano Zampini } 4710906d46d4SStefano Zampini 4711022d8d2bSstefano_zampini /* lA is present if we are setting up an inner BDDC for a saddle point FETI-DP */ 4712022d8d2bSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 4713022d8d2bSstefano_zampini 471422d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 47159b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 471622d5777bSStefano Zampini if (isseqaij) { 4717a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4718a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 4719022d8d2bSstefano_zampini if (lA) { 4720022d8d2bSstefano_zampini Mat work; 4721022d8d2bSstefano_zampini ierr = MatPtAP(lA,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4722022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4723022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4724022d8d2bSstefano_zampini } 4725aa0d41d4SStefano Zampini } else { 4726a00504b5SStefano Zampini Mat work_mat; 47271cf9b237SStefano Zampini 4728a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4729aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4730a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 47311d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 4732022d8d2bSstefano_zampini if (lA) { 4733022d8d2bSstefano_zampini Mat work; 4734022d8d2bSstefano_zampini ierr = MatConvert(lA,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4735022d8d2bSstefano_zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4736022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4737022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4738022d8d2bSstefano_zampini } 4739aa0d41d4SStefano Zampini } 47403301b35fSStefano Zampini if (matis->A->symmetric_set) { 47413301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 4742e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 47433301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 4744e496cd5dSStefano Zampini #endif 47453301b35fSStefano Zampini } 4746d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 4747aa0d41d4SStefano Zampini PetscFunctionReturn(0); 4748aa0d41d4SStefano Zampini } 4749aa0d41d4SStefano Zampini 47508ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 4751a64d13efSStefano Zampini { 4752a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4753a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4754d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 475553892102SStefano Zampini PetscInt *idx_R_local=NULL; 47563a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 47573a50541eSStefano Zampini PetscInt vbs,bs; 47586816873aSStefano Zampini PetscBT bitmask=NULL; 4759a64d13efSStefano Zampini PetscErrorCode ierr; 4760a64d13efSStefano Zampini 4761a64d13efSStefano Zampini PetscFunctionBegin; 4762b23d619eSStefano Zampini /* 4763b23d619eSStefano Zampini No need to setup local scatters if 4764b23d619eSStefano Zampini - primal space is unchanged 4765b23d619eSStefano Zampini AND 4766b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 4767b23d619eSStefano Zampini AND 4768b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 4769b23d619eSStefano Zampini */ 4770b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 4771f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 4772f4ddd8eeSStefano Zampini } 4773f4ddd8eeSStefano Zampini /* destroy old objects */ 4774f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 4775f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 4776f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 4777a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 4778b371cd4fSStefano Zampini n_B = pcis->n_B; 4779b371cd4fSStefano Zampini n_D = pcis->n - n_B; 4780b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 47813a50541eSStefano Zampini 4782a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 47836816873aSStefano Zampini 478453892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 4785b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4786854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 4787a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 4788a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 47890e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 4790a64d13efSStefano Zampini } 4791a64d13efSStefano Zampini 4792a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 47934641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 47946816873aSStefano Zampini idx_R_local[n_R++] = i; 4795a64d13efSStefano Zampini } 4796a64d13efSStefano Zampini } 4797df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 4798df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 47996816873aSStefano Zampini 4800df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4801df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 48026816873aSStefano Zampini } 48033a50541eSStefano Zampini 48043a50541eSStefano Zampini /* Block code */ 48053a50541eSStefano Zampini vbs = 1; 48063a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 48073a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 48083a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 48093a50541eSStefano Zampini PetscInt *vary; 4810b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4811785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 48123a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 4813d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 4814d3df7717SStefano 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 */ 48150e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 4816d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 48173a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 48183a50541eSStefano Zampini is_blocked = PETSC_FALSE; 48193a50541eSStefano Zampini break; 48203a50541eSStefano Zampini } 48213a50541eSStefano Zampini } 4822d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 4823d3df7717SStefano Zampini } else { 4824d3df7717SStefano Zampini /* Verify directly the R set */ 4825d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 4826d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 4827d3df7717SStefano Zampini for (j=1; j<bs; j++) { 4828d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 4829d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 4830d3df7717SStefano Zampini break; 4831d3df7717SStefano Zampini } 4832d3df7717SStefano Zampini } 4833d3df7717SStefano Zampini } 4834d3df7717SStefano Zampini } 48353a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 48363a50541eSStefano Zampini vbs = bs; 48373a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 48383a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 48393a50541eSStefano Zampini } 48403a50541eSStefano Zampini } 48413a50541eSStefano Zampini } 48423a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 4843b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4844df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 484553892102SStefano Zampini 4846df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4847df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 484853892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 4849df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 485053892102SStefano Zampini } else { 48513a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 485253892102SStefano Zampini } 4853a64d13efSStefano Zampini 4854a64d13efSStefano Zampini /* print some info if requested */ 4855a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 4856a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4857a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 48581575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4859a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 4860a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 48614f1b2e48SStefano 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); 4862a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4863a64d13efSStefano Zampini } 4864a64d13efSStefano Zampini 4865a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 4866b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 48676816873aSStefano Zampini IS is_aux1,is_aux2; 48686816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 48696816873aSStefano Zampini 48703a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4871854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 4872854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 4873a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 48744641a718SStefano Zampini for (i=0; i<n_D; i++) { 48754641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 48764641a718SStefano Zampini } 4877a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4878a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 48794641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 48804641a718SStefano Zampini aux_array1[j++] = i; 4881a64d13efSStefano Zampini } 4882a64d13efSStefano Zampini } 4883a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4884a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4885a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 48864641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 48874641a718SStefano Zampini aux_array2[j++] = i; 4888a64d13efSStefano Zampini } 4889a64d13efSStefano Zampini } 4890a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4891a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 4892a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 4893a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4894a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 4895a64d13efSStefano Zampini 48968eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4897785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 4898a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 48994641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 49004641a718SStefano Zampini aux_array1[j++] = i; 4901a64d13efSStefano Zampini } 4902a64d13efSStefano Zampini } 4903a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4904a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 4905a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4906a64d13efSStefano Zampini } 49074641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 49083a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4909d62866d3SStefano Zampini } else { 4910df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 49116816873aSStefano Zampini IS tis; 49126816873aSStefano Zampini PetscInt schur_size; 49136816873aSStefano Zampini 4914df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 49156816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 4916df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 49176816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 49186816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 49196816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 49206816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 49216816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 4922d62866d3SStefano Zampini } 4923d62866d3SStefano Zampini } 4924a64d13efSStefano Zampini PetscFunctionReturn(0); 4925a64d13efSStefano Zampini } 4926a64d13efSStefano Zampini 4927304d26faSStefano Zampini 4928684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 4929304d26faSStefano Zampini { 4930304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4931304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4932304d26faSStefano Zampini PC pc_temp; 4933304d26faSStefano Zampini Mat A_RR; 4934f4ddd8eeSStefano Zampini MatReuse reuse; 4935304d26faSStefano Zampini PetscScalar m_one = -1.0; 4936304d26faSStefano Zampini PetscReal value; 493704708bb6SStefano Zampini PetscInt n_D,n_R; 493835529e7bSStefano Zampini PetscBool check_corr,issbaij; 4939304d26faSStefano Zampini PetscErrorCode ierr; 4940e604994aSStefano Zampini /* prefixes stuff */ 4941312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 4942e604994aSStefano Zampini size_t len; 4943304d26faSStefano Zampini 4944304d26faSStefano Zampini PetscFunctionBegin; 4945304d26faSStefano Zampini 4946e604994aSStefano Zampini /* compute prefixes */ 4947e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 4948e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 4949e604994aSStefano Zampini if (!pcbddc->current_level) { 4950e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4951e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4952e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4953e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4954e604994aSStefano Zampini } else { 495535529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 4956e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4957e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 4958312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4959312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 496034d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 496134d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4962e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4963e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4964e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 4965e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 4966e604994aSStefano Zampini } 4967e604994aSStefano Zampini 4968304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 4969684f6988SStefano Zampini if (dirichlet) { 4970d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4971450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 49729a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 4973450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 4974a3df083aSStefano Zampini Mat A_IIn; 4975a3df083aSStefano Zampini 4976a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 4977a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 4978a3df083aSStefano Zampini pcis->A_II = A_IIn; 4979a3df083aSStefano Zampini } 4980450f8f5eSStefano Zampini } 49813301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 49823301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 4983964fefecSStefano Zampini } 4984ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 4985964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 4986304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 4987304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 4988304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 4989304d26faSStefano Zampini /* default */ 4990304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 4991e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 49929577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 4993304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 49949577ea80SStefano Zampini if (issbaij) { 49959577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 49969577ea80SStefano Zampini } else { 4997304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 49989577ea80SStefano Zampini } 4999304d26faSStefano Zampini /* Allow user's customization */ 5000304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 5001304d26faSStefano Zampini } 5002d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 5003b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5004df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5005d62866d3SStefano Zampini 5006df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 5007d5574798SStefano Zampini } 5008304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5009304d26faSStefano Zampini if (!n_D) { 5010304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 5011304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5012304d26faSStefano Zampini } 5013304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 5014304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 5015304d26faSStefano Zampini /* set ksp_D into pcis data */ 5016304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 5017304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 5018304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 5019684f6988SStefano Zampini } 5020304d26faSStefano Zampini 5021304d26faSStefano Zampini /* NEUMANN PROBLEM */ 5022684f6988SStefano Zampini A_RR = 0; 5023684f6988SStefano Zampini if (neumann) { 5024d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 502504708bb6SStefano Zampini PetscInt ibs,mbs; 50260aa714b2SStefano Zampini PetscBool issbaij, reuse_neumann_solver; 502704708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 50280aa714b2SStefano Zampini 50290aa714b2SStefano Zampini reuse_neumann_solver = PETSC_FALSE; 50300aa714b2SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 50310aa714b2SStefano Zampini IS iP; 50320aa714b2SStefano Zampini 50330aa714b2SStefano Zampini reuse_neumann_solver = PETSC_TRUE; 50340aa714b2SStefano Zampini ierr = PetscObjectQuery((PetscObject)sub_schurs->A,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 50350aa714b2SStefano Zampini if (iP) reuse_neumann_solver = PETSC_FALSE; 50360aa714b2SStefano Zampini } 5037f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 50388ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 5039f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 5040f4ddd8eeSStefano Zampini PetscInt nn_R; 504181d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 5042f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5043f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 5044f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 5045f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 5046f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5047f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5048f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 5049727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 5050f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5051f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5052f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 5053f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 5054f4ddd8eeSStefano Zampini } 5055f4ddd8eeSStefano Zampini } 5056f4ddd8eeSStefano Zampini /* last check */ 5057d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 5058f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5059f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5060f4ddd8eeSStefano Zampini } 5061f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 5062f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5063f4ddd8eeSStefano Zampini } 5064a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 5065af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 5066af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 506704708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 506804708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 506904708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 507004708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 507104708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 5072af732b37SStefano Zampini } else { 5073511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 50746816873aSStefano Zampini } 507504708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 507604708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 507704708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 507804708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 507904708bb6SStefano Zampini } else { 5080511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 508104708bb6SStefano Zampini } 508204708bb6SStefano Zampini } 5083a00504b5SStefano Zampini /* extract A_RR */ 50840aa714b2SStefano Zampini if (reuse_neumann_solver) { 5085a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5086a00504b5SStefano Zampini 5087a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 508816e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5089a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 509016e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 509116e386b8SStefano Zampini } else { 50927dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 5093a00504b5SStefano Zampini } 5094a00504b5SStefano Zampini } else { 5095a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5096a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 5097a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5098a00504b5SStefano Zampini } 5099a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 51007dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 510116e386b8SStefano Zampini } 51023301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 51033301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 51046816873aSStefano Zampini } 5105f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 5106304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 5107304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 5108304d26faSStefano Zampini /* default */ 5109304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 5110e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 5111304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 51129577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 51139577ea80SStefano Zampini if (issbaij) { 51149577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 51159577ea80SStefano Zampini } else { 5116304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 51179577ea80SStefano Zampini } 5118304d26faSStefano Zampini /* Allow user's customization */ 5119304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 5120304d26faSStefano Zampini } 5121304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5122304d26faSStefano Zampini if (!n_R) { 5123304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 5124304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5125304d26faSStefano Zampini } 51265cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 5127df4d28bfSStefano Zampini /* Reuse solver if it is present */ 51280aa714b2SStefano Zampini if (reuse_neumann_solver) { 5129df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5130d62866d3SStefano Zampini 5131df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 5132d62866d3SStefano Zampini } 5133304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 5134304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 5135684f6988SStefano Zampini } 5136304d26faSStefano Zampini 5137684f6988SStefano Zampini if (pcbddc->dbg_flag) { 5138684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 51391575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5140684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5141684f6988SStefano Zampini } 5142c7017625SStefano Zampini 5143c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 514435529e7bSStefano Zampini check_corr = PETSC_FALSE; 5145c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 5146c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 5147c7017625SStefano Zampini } 5148c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 514935529e7bSStefano Zampini check_corr = PETSC_TRUE; 5150c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 5151c7017625SStefano Zampini } 5152c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 515335529e7bSStefano Zampini check_corr = PETSC_TRUE; 5154c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 5155c7017625SStefano Zampini } 5156c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 5157c7017625SStefano Zampini if (pcbddc->dbg_flag) { 5158684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 51590fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 51600fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 51610fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 51620fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 51630fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 5164e604994aSStefano 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); 516535529e7bSStefano Zampini if (check_corr) { 5166c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 5167c7017625SStefano Zampini } 5168304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5169304d26faSStefano Zampini } 5170684f6988SStefano Zampini if (neumann) { /* Neumann */ 51710fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 51720fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 51730fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 51740fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 51750fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 5176e604994aSStefano 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); 517735529e7bSStefano Zampini if (check_corr) { 5178c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 5179c7017625SStefano Zampini } 5180304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5181304d26faSStefano Zampini } 5182684f6988SStefano Zampini } 51835cbda25cSStefano Zampini /* free Neumann problem's matrix */ 51845cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5185304d26faSStefano Zampini PetscFunctionReturn(0); 5186304d26faSStefano Zampini } 5187304d26faSStefano Zampini 518880677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 5189674ae819SStefano Zampini { 5190674ae819SStefano Zampini PetscErrorCode ierr; 5191674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5192be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5193b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 5194674ae819SStefano Zampini 5195674ae819SStefano Zampini PetscFunctionBegin; 5196b334f244SStefano Zampini if (!reuse_solver) { 519780677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 519820c7b377SStefano Zampini } 519980677318SStefano Zampini if (!pcbddc->switch_static) { 520080677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 520180677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 520280677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 520320c7b377SStefano Zampini } 5204b334f244SStefano Zampini if (!reuse_solver) { 520580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 520680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 520720c7b377SStefano Zampini } else { 5208df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5209be83ff47SStefano Zampini 5210df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5211df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 521220c7b377SStefano Zampini } 5213be83ff47SStefano Zampini } else { 521480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 521580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 521680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 521780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 521880677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 521980677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 522080677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 522180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 522280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5223674ae819SStefano Zampini } 5224674ae819SStefano Zampini } 5225b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 522680677318SStefano Zampini if (applytranspose) { 522780677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 522880677318SStefano Zampini } else { 522980677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 523080677318SStefano Zampini } 5231be83ff47SStefano Zampini } else { 5232df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5233be83ff47SStefano Zampini 5234be83ff47SStefano Zampini if (applytranspose) { 5235df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5236be83ff47SStefano Zampini } else { 5237df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5238be83ff47SStefano Zampini } 5239be83ff47SStefano Zampini } 524080677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 524180677318SStefano Zampini if (!pcbddc->switch_static) { 5242b334f244SStefano Zampini if (!reuse_solver) { 524380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 524480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5245be83ff47SStefano Zampini } else { 5246df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5247be83ff47SStefano Zampini 5248df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5249df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5250be83ff47SStefano Zampini } 525180677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 525280677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 525380677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 525480677318SStefano Zampini } 525580677318SStefano Zampini } else { 525680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 525780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 525880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 525980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 526080677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 526180677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 526280677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 526380677318SStefano Zampini } 526480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 526580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 526680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 526780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5268674ae819SStefano Zampini } 5269674ae819SStefano Zampini PetscFunctionReturn(0); 5270674ae819SStefano Zampini } 5271674ae819SStefano Zampini 5272dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 5273dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 5274674ae819SStefano Zampini { 5275674ae819SStefano Zampini PetscErrorCode ierr; 5276674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5277674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 5278674ae819SStefano Zampini const PetscScalar zero = 0.0; 5279674ae819SStefano Zampini 5280674ae819SStefano Zampini PetscFunctionBegin; 5281dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 52824fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5283dc359a40SStefano Zampini if (applytranspose) { 5284674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 52858eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 5286dc359a40SStefano Zampini } else { 5287674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 5288674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 528915aaf578SStefano Zampini } 52904fee134fSStefano Zampini } else { 52914fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 52924fee134fSStefano Zampini } 5293efc2fbd9SStefano Zampini 5294efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 52954f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5296efc2fbd9SStefano Zampini PetscScalar *array; 52974f1b2e48SStefano Zampini PetscInt j; 5298efc2fbd9SStefano Zampini 5299efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 53004f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 5301efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5302efc2fbd9SStefano Zampini } 5303efc2fbd9SStefano Zampini 530412edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 530512edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 530612edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 530712edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 530812edc857SStefano Zampini 53099f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 531012edc857SStefano Zampini if (pcbddc->coarse_ksp) { 531151694757SStefano Zampini Mat coarse_mat; 5312964fefecSStefano Zampini Vec rhs,sol; 531351694757SStefano Zampini MatNullSpace nullsp; 531427b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 5315964fefecSStefano Zampini 531627b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 531727b6a85dSStefano Zampini PC coarse_pc; 531827b6a85dSStefano Zampini 531927b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 532027b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 532127b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 532227b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 532327b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 532427b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 53253bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 532627b6a85dSStefano Zampini } 532727b6a85dSStefano Zampini } 5328964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 5329964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 533051694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 533151694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 533251694757SStefano Zampini if (nullsp) { 533351694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 533451694757SStefano Zampini } 533512edc857SStefano Zampini if (applytranspose) { 53369a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 5337964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 53382701bc32SStefano Zampini } else { 53391f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 53402701bc32SStefano Zampini PC coarse_pc; 53412701bc32SStefano Zampini 53422701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 53432701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 53443e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 53452701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 534612edc857SStefano Zampini } else { 5347964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 534812edc857SStefano Zampini } 53492701bc32SStefano Zampini } 53501d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 535127b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 535227b6a85dSStefano Zampini PC coarse_pc; 535327b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 535427b6a85dSStefano Zampini 535527b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 535627b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 535727b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 53583bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 535927b6a85dSStefano Zampini } 536051694757SStefano Zampini if (nullsp) { 536151694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 536251694757SStefano Zampini } 536312edc857SStefano Zampini } 5364674ae819SStefano Zampini 5365674ae819SStefano Zampini /* Local solution on R nodes */ 53664fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 536780677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 53689f00e9b4SStefano Zampini } 53699f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 53709f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 537112edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5372674ae819SStefano Zampini 53734fee134fSStefano Zampini /* Sum contributions from the two levels */ 53744fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5375dc359a40SStefano Zampini if (applytranspose) { 5376dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5377dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5378dc359a40SStefano Zampini } else { 5379674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 53808eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5381dc359a40SStefano Zampini } 5382efc2fbd9SStefano Zampini /* store p0 */ 53834f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5384efc2fbd9SStefano Zampini PetscScalar *array; 53854f1b2e48SStefano Zampini PetscInt j; 5386efc2fbd9SStefano Zampini 5387efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 53884f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 5389efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5390efc2fbd9SStefano Zampini } 53914fee134fSStefano Zampini } else { /* expand the coarse solution */ 53924fee134fSStefano Zampini if (applytranspose) { 53934fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 53944fee134fSStefano Zampini } else { 53954fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 53964fee134fSStefano Zampini } 53974fee134fSStefano Zampini } 5398674ae819SStefano Zampini PetscFunctionReturn(0); 5399674ae819SStefano Zampini } 5400674ae819SStefano Zampini 540112edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 5402674ae819SStefano Zampini { 5403674ae819SStefano Zampini PetscErrorCode ierr; 5404674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 540558da7f69SStefano Zampini PetscScalar *array; 540612edc857SStefano Zampini Vec from,to; 5407674ae819SStefano Zampini 5408674ae819SStefano Zampini PetscFunctionBegin; 540912edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 541012edc857SStefano Zampini from = pcbddc->coarse_vec; 541112edc857SStefano Zampini to = pcbddc->vec1_P; 541212edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 541312edc857SStefano Zampini Vec tvec; 541458da7f69SStefano Zampini 541558da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 541658da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 541712edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 541858da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 541958da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 542058da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 542112edc857SStefano Zampini } 542212edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 542312edc857SStefano Zampini from = pcbddc->vec1_P; 542412edc857SStefano Zampini to = pcbddc->coarse_vec; 542512edc857SStefano Zampini } 542612edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 5427674ae819SStefano Zampini PetscFunctionReturn(0); 5428674ae819SStefano Zampini } 5429674ae819SStefano Zampini 543012edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 5431674ae819SStefano Zampini { 5432674ae819SStefano Zampini PetscErrorCode ierr; 5433674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 543458da7f69SStefano Zampini PetscScalar *array; 543512edc857SStefano Zampini Vec from,to; 5436674ae819SStefano Zampini 5437674ae819SStefano Zampini PetscFunctionBegin; 543812edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 543912edc857SStefano Zampini from = pcbddc->coarse_vec; 544012edc857SStefano Zampini to = pcbddc->vec1_P; 544112edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 544212edc857SStefano Zampini from = pcbddc->vec1_P; 544312edc857SStefano Zampini to = pcbddc->coarse_vec; 544412edc857SStefano Zampini } 544512edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 544612edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 544712edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 544812edc857SStefano Zampini Vec tvec; 544958da7f69SStefano Zampini 545012edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 545158da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 545258da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 545358da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 545458da7f69SStefano Zampini } 545558da7f69SStefano Zampini } else { 545658da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 545758da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 545812edc857SStefano Zampini } 545912edc857SStefano Zampini } 5460674ae819SStefano Zampini PetscFunctionReturn(0); 5461674ae819SStefano Zampini } 5462674ae819SStefano Zampini 5463984c4197SStefano Zampini /* uncomment for testing purposes */ 5464984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 5465674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 5466674ae819SStefano Zampini { 5467674ae819SStefano Zampini PetscErrorCode ierr; 5468674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5469674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5470674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5471984c4197SStefano Zampini /* one and zero */ 5472984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 5473984c4197SStefano Zampini /* space to store constraints and their local indices */ 54749162d606SStefano Zampini PetscScalar *constraints_data; 54759162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 54769162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 54779162d606SStefano Zampini PetscInt *constraints_n; 5478984c4197SStefano Zampini /* iterators */ 5479b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 5480984c4197SStefano Zampini /* BLAS integers */ 5481e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 5482e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 5483c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 5484727cdba6SStefano Zampini /* reuse */ 54850e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 54860e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 5487984c4197SStefano Zampini /* change of basis */ 5488b3d85658SStefano Zampini PetscBool qr_needed; 54899162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 5490984c4197SStefano Zampini /* auxiliary stuff */ 549164efe560SStefano Zampini PetscInt *nnz,*is_indices; 54928a0068c3SStefano Zampini PetscInt ncc; 5493984c4197SStefano Zampini /* some quantities */ 549445a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 5495a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 5496984c4197SStefano Zampini 5497674ae819SStefano Zampini PetscFunctionBegin; 54988e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 54998e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 55008e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 550116909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 5502088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 5503088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 55040e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 55050e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 55060e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 55070e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 55080e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 5509088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5510cf5a6209SStefano Zampini 5511cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 55129162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 5513cf5a6209SStefano Zampini MatNullSpace nearnullsp; 5514cf5a6209SStefano Zampini const Vec *nearnullvecs; 5515cf5a6209SStefano Zampini Vec *localnearnullsp; 5516cf5a6209SStefano Zampini PetscScalar *array; 5517cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 5518cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 5519674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 5520b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 5521674ae819SStefano Zampini PetscScalar *work; 5522674ae819SStefano Zampini PetscReal *singular_vals; 5523674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5524674ae819SStefano Zampini PetscReal *rwork; 5525674ae819SStefano Zampini #endif 5526674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5527674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 5528674ae819SStefano Zampini #else 5529964fefecSStefano Zampini PetscBLASInt dummy_int=1; 5530964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 5531674ae819SStefano Zampini #endif 5532674ae819SStefano Zampini 5533674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 5534d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 5535e4d548c7SStefano Zampini /* print some info */ 55365c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 5537e4d548c7SStefano Zampini PetscInt nv; 5538e4d548c7SStefano Zampini 5539c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5540e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 5541e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5542e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5543e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 5544e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 5545e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 5546e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5547e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5548e4d548c7SStefano Zampini } 5549e4d548c7SStefano Zampini 5550d06fc5fdSStefano Zampini /* free unneeded index sets */ 5551d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 5552d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 5553674ae819SStefano Zampini } 5554d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 5555d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5556d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5557d06fc5fdSStefano Zampini } 5558d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5559d06fc5fdSStefano Zampini n_ISForEdges = 0; 5560d06fc5fdSStefano Zampini } 5561d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 5562d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5563d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5564d06fc5fdSStefano Zampini } 5565d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5566d06fc5fdSStefano Zampini n_ISForFaces = 0; 5567d06fc5fdSStefano Zampini } 556870022509SStefano Zampini 5569674ae819SStefano Zampini /* check if near null space is attached to global mat */ 5570674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 5571674ae819SStefano Zampini if (nearnullsp) { 5572674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 5573f4ddd8eeSStefano Zampini /* remove any stored info */ 5574f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 5575f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5576f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 5577f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 5578f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 5579473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5580f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 5581f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 5582f4ddd8eeSStefano Zampini } 5583984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 5584984c4197SStefano Zampini nnsp_size = 0; 5585674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 5586674ae819SStefano Zampini } 5587984c4197SStefano Zampini /* get max number of constraints on a single cc */ 5588984c4197SStefano Zampini max_constraints = nnsp_size; 5589984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 5590984c4197SStefano Zampini 5591674ae819SStefano Zampini /* 5592674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 55939162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 55949162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 55959162d606SStefano Zampini There can be multiple constraints per connected component 5596674ae819SStefano Zampini */ 5597674ae819SStefano Zampini n_vertices = 0; 5598674ae819SStefano Zampini if (ISForVertices) { 5599674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 5600674ae819SStefano Zampini } 56019162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 56029162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 56039162d606SStefano Zampini 56049162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 56059162d606SStefano Zampini total_counts *= max_constraints; 5606674ae819SStefano Zampini total_counts += n_vertices; 56074641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 56089162d606SStefano Zampini 5609674ae819SStefano Zampini total_counts = 0; 5610674ae819SStefano Zampini max_size_of_constraint = 0; 5611674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 56129162d606SStefano Zampini IS used_is; 5613674ae819SStefano Zampini if (i<n_ISForEdges) { 56149162d606SStefano Zampini used_is = ISForEdges[i]; 5615674ae819SStefano Zampini } else { 56169162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 5617674ae819SStefano Zampini } 56189162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 5619674ae819SStefano Zampini total_counts += j; 5620674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 5621674ae819SStefano Zampini } 56229162d606SStefano 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); 56239162d606SStefano Zampini 5624984c4197SStefano Zampini /* get local part of global near null space vectors */ 5625785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 5626984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5627984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 5628e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5629e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5630984c4197SStefano Zampini } 5631674ae819SStefano Zampini 5632242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 5633242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 5634a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 5635242a89d7SStefano Zampini 5636984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 5637a773dcb8SStefano Zampini if (!skip_lapack) { 5638674ae819SStefano Zampini PetscScalar temp_work; 5639911cabfeSStefano Zampini 5640674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5641984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 5642785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 5643785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 5644785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 5645674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5646785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 5647674ae819SStefano Zampini #endif 5648674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5649c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 5650c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 5651674ae819SStefano Zampini lwork = -1; 5652674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5653674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5654c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 5655674ae819SStefano Zampini #else 5656c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 5657674ae819SStefano Zampini #endif 5658674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5659984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 5660674ae819SStefano Zampini #else /* on missing GESVD */ 5661674ae819SStefano Zampini /* SVD */ 5662674ae819SStefano Zampini PetscInt max_n,min_n; 5663674ae819SStefano Zampini max_n = max_size_of_constraint; 5664984c4197SStefano Zampini min_n = max_constraints; 5665984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 5666674ae819SStefano Zampini min_n = max_size_of_constraint; 5667984c4197SStefano Zampini max_n = max_constraints; 5668674ae819SStefano Zampini } 5669785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 5670674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5671785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 5672674ae819SStefano Zampini #endif 5673674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5674674ae819SStefano Zampini lwork = -1; 5675e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 5676e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 5677b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 5678674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5679674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 56809162d606SStefano 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)); 5681674ae819SStefano Zampini #else 56829162d606SStefano 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)); 5683674ae819SStefano Zampini #endif 5684674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5685984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 5686984c4197SStefano Zampini #endif /* on missing GESVD */ 5687674ae819SStefano Zampini /* Allocate optimal workspace */ 5688674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 5689854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 5690674ae819SStefano Zampini } 5691674ae819SStefano Zampini /* Now we can loop on constraining sets */ 5692674ae819SStefano Zampini total_counts = 0; 56939162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 56949162d606SStefano Zampini constraints_data_ptr[0] = 0; 5695674ae819SStefano Zampini /* vertices */ 56969162d606SStefano Zampini if (n_vertices) { 5697674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 56989162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 5699674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 57009162d606SStefano Zampini constraints_n[total_counts] = 1; 57019162d606SStefano Zampini constraints_data[total_counts] = 1.0; 57029162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 57039162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 5704674ae819SStefano Zampini total_counts++; 5705674ae819SStefano Zampini } 5706674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5707674ae819SStefano Zampini n_vertices = total_counts; 5708674ae819SStefano Zampini } 5709984c4197SStefano Zampini 5710674ae819SStefano Zampini /* edges and faces */ 57119162d606SStefano Zampini total_counts_cc = total_counts; 5712911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 57139162d606SStefano Zampini IS used_is; 57149162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 57159162d606SStefano Zampini 5716911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 57179162d606SStefano Zampini used_is = ISForEdges[ncc]; 5718984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 5719674ae819SStefano Zampini } else { 57209162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 5721984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 5722674ae819SStefano Zampini } 5723674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 57249162d606SStefano Zampini 57259162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 57269162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5727984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 5728984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 5729674ae819SStefano Zampini if (nnsp_has_cnst) { 57305b08dc53SStefano Zampini PetscScalar quad_value; 57319162d606SStefano Zampini 57329162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 57339162d606SStefano Zampini idxs_copied = PETSC_TRUE; 57349162d606SStefano Zampini 5735a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 5736674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 5737a773dcb8SStefano Zampini } else { 5738a773dcb8SStefano Zampini quad_value = 1.0; 5739a773dcb8SStefano Zampini } 5740674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 57419162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 5742674ae819SStefano Zampini } 57439162d606SStefano Zampini temp_constraints++; 5744674ae819SStefano Zampini total_counts++; 5745674ae819SStefano Zampini } 5746674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 5747984c4197SStefano Zampini PetscReal real_value; 57489162d606SStefano Zampini PetscScalar *ptr_to_data; 57499162d606SStefano Zampini 5750984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 57519162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 5752674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 57539162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 5754674ae819SStefano Zampini } 5755984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 5756984c4197SStefano Zampini /* check if array is null on the connected component */ 5757e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 57589162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 57595b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 5760674ae819SStefano Zampini temp_constraints++; 5761674ae819SStefano Zampini total_counts++; 57629162d606SStefano Zampini if (!idxs_copied) { 57639162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 57649162d606SStefano Zampini idxs_copied = PETSC_TRUE; 5765674ae819SStefano Zampini } 5766674ae819SStefano Zampini } 57679162d606SStefano Zampini } 57689162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 576945a1bb75SStefano Zampini valid_constraints = temp_constraints; 5770eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 5771a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 57729162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 57739162d606SStefano Zampini 57749162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5775a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 57769162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 5777a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 57789162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 5779a773dcb8SStefano Zampini } else { /* perform SVD */ 5780984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 57819162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5782674ae819SStefano Zampini 5783674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5784984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 5785984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 5786984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 5787984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 5788984c4197SStefano Zampini from that computed using LAPACKgesvd 5789984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 5790984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 5791984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 5792674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 5793e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5794984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5795674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 5796674ae819SStefano Zampini for (k=0;k<j+1;k++) { 57979162d606SStefano 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)); 5798674ae819SStefano Zampini } 5799674ae819SStefano Zampini } 5800e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 5801e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5802e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 5803674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5804c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 5805674ae819SStefano Zampini #else 5806c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 5807674ae819SStefano Zampini #endif 5808674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5809984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 5810984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 5811674ae819SStefano Zampini j = 0; 5812984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 5813674ae819SStefano Zampini total_counts = total_counts-j; 581445a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 5815e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 5816c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5817c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5818c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 5819c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5820c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 5821c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5822674ae819SStefano Zampini if (j<temp_constraints) { 5823984c4197SStefano Zampini PetscInt ii; 5824984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 5825674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 58269162d606SStefano 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)); 5827674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5828984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 5829674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 58309162d606SStefano 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]; 5831674ae819SStefano Zampini } 5832674ae819SStefano Zampini } 5833674ae819SStefano Zampini } 5834674ae819SStefano Zampini #else /* on missing GESVD */ 5835e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5836e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5837b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5838674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5839674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 58409162d606SStefano 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)); 5841674ae819SStefano Zampini #else 58429162d606SStefano 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)); 5843674ae819SStefano Zampini #endif 5844984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 5845674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5846984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 5847e310c8b4SStefano Zampini k = temp_constraints; 5848e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 5849674ae819SStefano Zampini j = 0; 5850e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 585145a1bb75SStefano Zampini valid_constraints = k-j; 5852911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 5853984c4197SStefano Zampini #endif /* on missing GESVD */ 5854674ae819SStefano Zampini } 5855a773dcb8SStefano Zampini } 58569162d606SStefano Zampini /* update pointers information */ 58579162d606SStefano Zampini if (valid_constraints) { 58589162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 58599162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 58609162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 58619162d606SStefano Zampini /* set change_of_basis flag */ 586245a1bb75SStefano Zampini if (boolforchange) { 5863b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 58649162d606SStefano Zampini } 5865b3d85658SStefano Zampini total_counts_cc++; 586645a1bb75SStefano Zampini } 586745a1bb75SStefano Zampini } 5868984c4197SStefano Zampini /* free workspace */ 58698f1c130eSStefano Zampini if (!skip_lapack) { 5870984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 5871984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5872984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 5873984c4197SStefano Zampini #endif 5874984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 5875984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5876984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 5877984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 5878984c4197SStefano Zampini #endif 5879984c4197SStefano Zampini } 5880984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5881984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 5882984c4197SStefano Zampini } 5883984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 5884cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 5885cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5886cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5887cf5a6209SStefano Zampini } 5888cf5a6209SStefano Zampini if (n_ISForFaces) { 5889cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5890cf5a6209SStefano Zampini } 5891cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5892cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5893cf5a6209SStefano Zampini } 5894cf5a6209SStefano Zampini if (n_ISForEdges) { 5895cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5896cf5a6209SStefano Zampini } 5897cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 589808122e43SStefano Zampini } else { 589908122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5900984c4197SStefano Zampini 590108122e43SStefano Zampini total_counts = 0; 590208122e43SStefano Zampini n_vertices = 0; 5903d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 5904d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 590508122e43SStefano Zampini } 590608122e43SStefano Zampini max_constraints = 0; 59079162d606SStefano Zampini total_counts_cc = 0; 590808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 590908122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 59109162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 591108122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 591208122e43SStefano Zampini } 59139162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 59149162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 59159162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 59169162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 591774d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 59189162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 59199162d606SStefano Zampini total_counts_cc = 0; 59209162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 59219162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 59229162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 592308122e43SStefano Zampini } 592408122e43SStefano Zampini } 59259162d606SStefano Zampini #if 0 59269162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 59279162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 59289162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 59299162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 59309162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 59319162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 59329162d606SStefano Zampini } 59339162d606SStefano Zampini printf("\n"); 59349162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 59359162d606SStefano Zampini } 59361b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 59378bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 59381b968477SStefano Zampini } 59391b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 59408bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] sub %d, edge %d, n %d\n",PetscGlobalRank,i,(PetscBool)PetscBTLookup(sub_schurs->is_edge,i),pcbddc->adaptive_constraints_n[i+n_vertices]); 59411b968477SStefano Zampini } 594208122e43SStefano Zampini #endif 594308122e43SStefano Zampini 59448bec7fa6SStefano Zampini max_size_of_constraint = 0; 59459162d606SStefano 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]); 59469162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 594708122e43SStefano Zampini /* Change of basis */ 5948b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 594908122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 595008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 595108122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 5952b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 595308122e43SStefano Zampini } 595408122e43SStefano Zampini } 595508122e43SStefano Zampini } 595608122e43SStefano Zampini } 5957984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 59584f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 595908122e43SStefano Zampini 59609162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 59619162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 5962eee23b56SStefano Zampini if (i != constraints_idxs_ptr[total_counts_cc]) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for constraints indices %D != %D\n",constraints_idxs_ptr[total_counts_cc],i); 5963674ae819SStefano Zampini 5964674ae819SStefano Zampini /* Create constraint matrix */ 5965674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 596616f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 5967984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 5968984c4197SStefano Zampini 5969984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 5970a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 5971a717540cSStefano Zampini qr_needed = PETSC_FALSE; 597274d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 5973984c4197SStefano Zampini total_primal_vertices=0; 5974b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 59759162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 59769162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 597772b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 59789162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 5979b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 598064efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 59819162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 59829162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 5983a717540cSStefano Zampini } 5984b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 598591af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 5986a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 5987a717540cSStefano Zampini qr_needed = PETSC_TRUE; 5988a717540cSStefano Zampini } 5989fa434743SStefano Zampini } else { 5990b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 5991fa434743SStefano Zampini } 5992a717540cSStefano Zampini } 5993b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 5994b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 5995674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 599670022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 59974f1b2e48SStefano 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); 59980e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 59990e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 6000984c4197SStefano Zampini 6001984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 600274d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 6003785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 6004984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 600574d5cdf7SStefano Zampini 6006984c4197SStefano Zampini j = total_primal_vertices; 600774d5cdf7SStefano Zampini total_counts = total_primal_vertices; 6008b3d85658SStefano Zampini cum = total_primal_vertices; 60099162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 60104641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 6011b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 6012b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 6013b3d85658SStefano Zampini cum++; 60149162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 601574d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 601674d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 601774d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 601874d5cdf7SStefano Zampini } 60199162d606SStefano Zampini j += constraints_n[i]; 6020674ae819SStefano Zampini } 6021674ae819SStefano Zampini } 6022674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 6023674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 6024088faed8SStefano Zampini 6025674ae819SStefano Zampini /* set values in constraint matrix */ 6026984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 60270e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6028674ae819SStefano Zampini } 6029984c4197SStefano Zampini total_counts = total_primal_vertices; 60309162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 60314641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 60329162d606SStefano Zampini PetscInt *cols; 60339162d606SStefano Zampini 60349162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 60359162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 60369162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 60379162d606SStefano Zampini PetscInt row = total_counts+k; 60389162d606SStefano Zampini PetscScalar *vals; 60399162d606SStefano Zampini 60409162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 60419162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 60429162d606SStefano Zampini } 60439162d606SStefano Zampini total_counts += constraints_n[i]; 6044674ae819SStefano Zampini } 6045674ae819SStefano Zampini } 6046674ae819SStefano Zampini /* assembling */ 6047674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6048674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6049088faed8SStefano Zampini 6050984c4197SStefano Zampini /* 60516a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 6052984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 6053f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 6054984c4197SStefano Zampini */ 6055674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 6056674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 6057026de310SStefano Zampini /* dual and primal dofs on a single cc */ 6058984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 6059984c4197SStefano Zampini /* working stuff for GEQRF */ 606081d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 6061984c4197SStefano Zampini PetscBLASInt lqr_work; 6062984c4197SStefano Zampini /* working stuff for UNGQR */ 6063984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 6064984c4197SStefano Zampini PetscBLASInt lgqr_work; 6065984c4197SStefano Zampini /* working stuff for TRTRS */ 6066984c4197SStefano Zampini PetscScalar *trs_rhs; 60673f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 6068984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 6069984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 6070984c4197SStefano Zampini PetscScalar *start_vals; 6071984c4197SStefano Zampini /* working stuff for values insertion */ 60724641a718SStefano Zampini PetscBT is_primal; 607364efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 6074906d46d4SStefano Zampini /* matrix sizes */ 6075906d46d4SStefano Zampini PetscInt global_size,local_size; 6076906d46d4SStefano Zampini /* temporary change of basis */ 6077906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 6078cf5a6209SStefano Zampini /* extra space for debugging */ 6079cf5a6209SStefano Zampini PetscScalar *dbg_work; 6080984c4197SStefano Zampini 6081906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 6082906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 608316f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 6084bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 6085906d46d4SStefano Zampini /* nonzeros for local mat */ 6086bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 60871dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6088bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 60891dd7afcfSStefano Zampini } else { 60901dd7afcfSStefano Zampini const PetscInt *ii; 60911dd7afcfSStefano Zampini PetscInt n; 60921dd7afcfSStefano Zampini PetscBool flg_row; 60931dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 60941dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 60951dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 60961dd7afcfSStefano Zampini } 60979162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 6098a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 60999162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 6100a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 61019162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 6102a717540cSStefano Zampini } else { 61039162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 61049162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 6105a717540cSStefano Zampini } 6106a717540cSStefano Zampini } 6107a717540cSStefano Zampini } 6108906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 6109bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 61101dd7afcfSStefano Zampini /* Set interior change in the matrix */ 61111dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6112bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 6113906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 6114a717540cSStefano Zampini } 61151dd7afcfSStefano Zampini } else { 61161dd7afcfSStefano Zampini const PetscInt *ii,*jj; 61171dd7afcfSStefano Zampini PetscScalar *aa; 61181dd7afcfSStefano Zampini PetscInt n; 61191dd7afcfSStefano Zampini PetscBool flg_row; 61201dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 61211dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 61221dd7afcfSStefano Zampini for (i=0;i<n;i++) { 61231dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 61241dd7afcfSStefano Zampini } 61251dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 61261dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 61271dd7afcfSStefano Zampini } 6128a717540cSStefano Zampini 6129a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6130a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6131a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6132a717540cSStefano Zampini } 6133a717540cSStefano Zampini 6134a717540cSStefano Zampini 6135a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 6136a717540cSStefano Zampini /* 6137a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 6138a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 6139a717540cSStefano Zampini 6140a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 6141a717540cSStefano Zampini 6142a6b551f4SStefano 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) 6143a6b551f4SStefano Zampini 6144a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 6145a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 6146a717540cSStefano Zampini | ... | 6147a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 6148a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 6149a717540cSStefano Zampini 6150a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 6151a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 6152a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 6153a6b551f4SStefano Zampini 6154a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 6155a717540cSStefano Zampini */ 6156a717540cSStefano Zampini if (qr_needed) { 6157984c4197SStefano Zampini /* space to store Q */ 6158854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 61594e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 61604e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 6161984c4197SStefano Zampini /* first we issue queries for optimal work */ 61623f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 61633f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 61643f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6165984c4197SStefano Zampini lqr_work = -1; 61663f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 6167984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 6168984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 6169785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 6170984c4197SStefano Zampini lgqr_work = -1; 61713f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 61723f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 61733f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 61743f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 61753f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 6176c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 6177c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to ORGQR/UNGQR Lapack routine %d",(int)lierr); 6178984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 6179785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 6180984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 6181785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 6182a717540cSStefano Zampini /* allocating workspace for check */ 6183a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6184cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 6185a717540cSStefano Zampini } 6186a717540cSStefano Zampini } 6187984c4197SStefano Zampini /* array to store whether a node is primal or not */ 61884641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 6189473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 61900e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 6191eee23b56SStefano Zampini if (i != total_primal_vertices) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Error in boundary numbering for BDDC vertices! %D != %D\n",total_primal_vertices,i); 619239e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 619339e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 619439e2fb2aSStefano Zampini } 619539e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 6196984c4197SStefano Zampini 6197a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 61989162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 61999162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 62004641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 6201984c4197SStefano Zampini /* get constraint info */ 62029162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 6203984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 6204984c4197SStefano Zampini 6205984c4197SStefano Zampini if (pcbddc->dbg_flag) { 62069162d606SStefano 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); 6207674ae819SStefano Zampini } 6208984c4197SStefano Zampini 6209fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 6210a717540cSStefano Zampini 6211a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 6212a717540cSStefano Zampini if (pcbddc->dbg_flag) { 62139162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6214a717540cSStefano Zampini } 6215984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 62169162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6217984c4197SStefano Zampini 6218984c4197SStefano Zampini /* compute QR decomposition of constraints */ 62193f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 62203f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 62213f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6222674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 62233f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 6224984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 6225674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6226984c4197SStefano Zampini 6227984c4197SStefano Zampini /* explictly compute R^-T */ 6228984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 6229984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 62303f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 62313f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 62323f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 62333f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 6234984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 62353f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 6236984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 6237984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6238984c4197SStefano Zampini 6239a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 62403f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 62413f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 62423f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 62433f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6244984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6245c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 6246c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in ORGQR/UNGQR Lapack routine %d",(int)lierr); 6247984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6248984c4197SStefano Zampini 6249984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 6250984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 6251984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 62523f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 62533f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 62543f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 62553f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 62563f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 62573f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6258984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 62599162d606SStefano 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)); 6260984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 62619162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6262984c4197SStefano Zampini 6263984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 62649162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 6265984c4197SStefano Zampini /* insert cols for primal dofs */ 6266984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 6267984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 62689162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6269906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6270984c4197SStefano Zampini } 6271984c4197SStefano Zampini /* insert cols for dual dofs */ 6272984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 62739162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 6274984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 62759162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6276906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6277984c4197SStefano Zampini j++; 6278674ae819SStefano Zampini } 6279674ae819SStefano Zampini } 6280984c4197SStefano Zampini 6281984c4197SStefano Zampini /* check change of basis */ 6282984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6283984c4197SStefano Zampini PetscInt ii,jj; 6284984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 6285c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 6286c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6287c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 6288c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6289c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 6290c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 6291984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6292cf5a6209SStefano 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)); 6293984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6294984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6295984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6296cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 6297c068d9bbSLisandro 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; 6298674ae819SStefano Zampini } 6299674ae819SStefano Zampini } 6300984c4197SStefano Zampini if (!valid_qr) { 630122d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 6302984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6303984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6304cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 6305cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not orthogonal to constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 6306674ae819SStefano Zampini } 6307c068d9bbSLisandro Dalcin if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-(PetscReal)1) > 1.e-12) { 6308cf5a6209SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\tQr basis function %d is not unitary w.r.t constraint %d (%1.14e)!\n",jj,ii,PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii])); 6309984c4197SStefano Zampini } 6310984c4197SStefano Zampini } 6311984c4197SStefano Zampini } 6312674ae819SStefano Zampini } else { 631322d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 6314674ae819SStefano Zampini } 6315674ae819SStefano Zampini } 6316a717540cSStefano Zampini } else { /* simple transformation block */ 6317a717540cSStefano Zampini PetscInt row,col; 6318a6b551f4SStefano Zampini PetscScalar val,norm; 6319a6b551f4SStefano Zampini 6320a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 63219162d606SStefano 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)); 6322a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 63239162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 63249162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6325bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 63269162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 6327906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 63289162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 6329a717540cSStefano Zampini } else { 6330a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 63319162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6332a717540cSStefano Zampini if (row != col) { 63339162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 6334a717540cSStefano Zampini } else { 63359162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 6336a717540cSStefano Zampini } 6337906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 6338a717540cSStefano Zampini } 6339a717540cSStefano Zampini } 6340a717540cSStefano Zampini } 634198a51de6SStefano Zampini if (pcbddc->dbg_flag) { 634222d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 6343a717540cSStefano Zampini } 6344674ae819SStefano Zampini } 6345984c4197SStefano Zampini } else { 6346984c4197SStefano Zampini if (pcbddc->dbg_flag) { 63479162d606SStefano 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); 6348674ae819SStefano Zampini } 6349674ae819SStefano Zampini } 6350674ae819SStefano Zampini } 6351a717540cSStefano Zampini 6352a717540cSStefano Zampini /* free workspace */ 6353a717540cSStefano Zampini if (qr_needed) { 6354984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6355cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 6356984c4197SStefano Zampini } 6357984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 6358984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 6359984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 6360984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 6361984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 6362674ae819SStefano Zampini } 6363a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 6364906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6365906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6366906d46d4SStefano Zampini 6367906d46d4SStefano Zampini /* assembling of global change of variable */ 636888c03ad3SStefano Zampini if (!pcbddc->fake_change) { 6369bbb9e6c6SStefano Zampini Mat tmat; 637016f15bc4SStefano Zampini PetscInt bs; 637116f15bc4SStefano Zampini 6372906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 6373906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 6374bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 6375bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 6376bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6377bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 637816f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 637916f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 6380906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 6381bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 6382bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6383bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6384bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6385bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6386e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6387e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6388bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 6389bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 639088c03ad3SStefano Zampini 6391906d46d4SStefano Zampini /* check */ 6392906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 6393906d46d4SStefano Zampini PetscReal error; 6394906d46d4SStefano Zampini Vec x,x_change; 6395906d46d4SStefano Zampini 6396906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 6397906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 6398906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 6399906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 6400e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6401e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6402bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 6403e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6404e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6405906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 6406906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 6407906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 6408637e8532SStefano Zampini if (error > PETSC_SMALL) { 6409637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 6410637e8532SStefano Zampini } 6411906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 6412906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 6413906d46d4SStefano Zampini } 6414b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 6415b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 6416b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6417bf3a8328SStefano Zampini 641813903a91SSatish 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"); 6419b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 6420ac632422SStefano Zampini Mat S_new,tmat; 6421bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 6422bbb9e6c6SStefano Zampini 6423bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 64247dae84e0SHong Zhang ierr = MatCreateSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 6425bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6426bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 6427bf3a8328SStefano Zampini IS is_V; 6428b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 6429b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 6430b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 6431b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 6432b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 6433bf3a8328SStefano Zampini } 6434bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 6435ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6436b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 6437ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6438bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6439bf3a8328SStefano Zampini const PetscScalar *array; 6440bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 6441bf3a8328SStefano Zampini PetscInt i,n_V; 6442bf3a8328SStefano Zampini 6443b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6444b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 6445b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6446b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6447b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 6448b087196eSStefano Zampini for (i=0;i<n_V;i++) { 6449b087196eSStefano Zampini PetscScalar val; 6450b087196eSStefano Zampini PetscInt idx; 6451b087196eSStefano Zampini 6452b087196eSStefano Zampini idx = idxs_V[i]; 6453b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 6454b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 6455b087196eSStefano Zampini } 6456b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6457b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6458bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 6459bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6460bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6461bf3a8328SStefano Zampini } 6462ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 6463ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6464ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 6465ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6466b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 6467ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6468bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6469b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6470bf3a8328SStefano Zampini } 6471ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 6472ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6473ac632422SStefano Zampini } 6474b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 647588c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6476b96c3477SStefano Zampini } 6477c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 6478b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 6479c9db6a07SStefano Zampini PetscInt i; 6480c9db6a07SStefano Zampini 6481c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 6482c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 6483c9db6a07SStefano Zampini } 6484c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 6485c9db6a07SStefano Zampini } 6486b96c3477SStefano Zampini } 648716909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 648816909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 648916909a7fSStefano Zampini } else { 6490906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 649116909a7fSStefano Zampini } 64921dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 649327b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 649472b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 649572b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 649672b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 649772b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 649872b8c272SStefano Zampini } 64991dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 650027b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 6501b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 6502b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 6503906d46d4SStefano Zampini } else { 65041dd7afcfSStefano Zampini Mat benign_global = NULL; 650527b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 65061dd7afcfSStefano Zampini Mat tmat; 65071dd7afcfSStefano Zampini 65081dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 65091dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 65101dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 65111dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 65121dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 65131dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 65141dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 65151dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 65161dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 65171dd7afcfSStefano Zampini if (pcbddc->benign_change) { 65181dd7afcfSStefano Zampini Mat M; 65191dd7afcfSStefano Zampini 65201dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 65211dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 65221dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 65231dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 6524906d46d4SStefano Zampini } else { 65251dd7afcfSStefano Zampini Mat eye; 65261dd7afcfSStefano Zampini PetscScalar *array; 65271dd7afcfSStefano Zampini 65281dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 65291dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 65301dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 65311dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 6532906d46d4SStefano Zampini } 65331dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 65341dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 65351dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 65361dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 65371dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 65381dd7afcfSStefano Zampini } 65391dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 65401dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 65411dd7afcfSStefano Zampini } 65421dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 65431dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 65441dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 654527b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 65461dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 65471dd7afcfSStefano Zampini } 65481dd7afcfSStefano Zampini } 654916909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 655016909a7fSStefano Zampini IS is_global; 655116909a7fSStefano Zampini const PetscInt *gidxs; 655216909a7fSStefano Zampini 655316909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 655416909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 655516909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 65567dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 655716909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 655816909a7fSStefano Zampini } 65591dd7afcfSStefano Zampini } 65601dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 65611dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 6562b9b85e73SStefano Zampini } 6563a717540cSStefano Zampini 656472b8c272SStefano Zampini if (!pcbddc->fake_change) { 65654f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 65664f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 65674f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 65684f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 6569019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 6570019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 6571019a44ceSStefano Zampini pcbddc->local_primal_size++; 6572019a44ceSStefano Zampini } 6573019a44ceSStefano Zampini 6574019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 6575727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 6576727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 65779f47a83aSStefano 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); 6578c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 65790e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 65809f47a83aSStefano 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); 6581727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 6582727cdba6SStefano Zampini } 65830e6343abSStefano Zampini } 6584727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 6585b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 658672b8c272SStefano Zampini } 658772b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 6588727cdba6SStefano Zampini 6589a717540cSStefano Zampini /* flush dbg viewer */ 6590b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 6591b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6592b8ffe317SStefano Zampini } 6593a717540cSStefano Zampini 6594e310c8b4SStefano Zampini /* free workspace */ 6595a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 65964641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 659708122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 65989162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 65999162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 660008122e43SStefano Zampini } else { 66019162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 66029162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 66039162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 660408122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 660508122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 66069162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 66079162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 660808122e43SStefano Zampini } 6609674ae819SStefano Zampini PetscFunctionReturn(0); 6610674ae819SStefano Zampini } 6611674ae819SStefano Zampini 6612674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 6613674ae819SStefano Zampini { 661471582508SStefano Zampini ISLocalToGlobalMapping map; 6615674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6616674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 661766da6bd7Sstefano_zampini PetscInt i,N; 661866da6bd7Sstefano_zampini PetscBool rcsr = PETSC_FALSE; 661966da6bd7Sstefano_zampini PetscErrorCode ierr; 6620674ae819SStefano Zampini 6621674ae819SStefano Zampini PetscFunctionBegin; 66228af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 6623b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 66248e61c736SStefano Zampini /* Reset previously computed graph */ 66258e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 6626674ae819SStefano Zampini /* Init local Graph struct */ 66277fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 662871582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 6629be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 6630674ae819SStefano Zampini 66317a0e7b2cSstefano_zampini if (pcbddc->user_primal_vertices_local && !pcbddc->user_primal_vertices) { 66327a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 66337a0e7b2cSstefano_zampini } 6634575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 66359a962809SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr && pcbddc->mat_graph->nvtxs_csr != pcbddc->mat_graph->nvtxs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid size of local CSR graph! Found %d, expected %d\n",pcbddc->mat_graph->nvtxs_csr,pcbddc->mat_graph->nvtxs); 66369577ea80SStefano Zampini 6637674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 663866da6bd7Sstefano_zampini if (!pcbddc->mat_graph->xadj && pcbddc->use_local_adj) { 66394d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 66404d379d7bSStefano Zampini PetscInt nvtxs; 6641e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 6642674ae819SStefano Zampini 66432fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 66442fffb893SStefano Zampini if (flg_row) { 66454d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 6646b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 66472fffb893SStefano Zampini } 66482fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 664966da6bd7Sstefano_zampini rcsr = PETSC_TRUE; 6650674ae819SStefano Zampini } 66519b28b941SStefano Zampini if (pcbddc->dbg_flag) { 66529b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6653674ae819SStefano Zampini } 6654674ae819SStefano Zampini 6655674ae819SStefano Zampini /* Setup of Graph */ 66564b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 665714f95afaSStefano 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); 6658674ae819SStefano Zampini 66594f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 66604f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 66614f1b2e48SStefano Zampini PetscInt *local_subs; 66624f1b2e48SStefano Zampini 66634f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 66644f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 66654f1b2e48SStefano Zampini const PetscInt *idxs; 66664f1b2e48SStefano Zampini PetscInt nl,j; 66674f1b2e48SStefano Zampini 66684f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 66694f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 667071582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 66714f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 66724f1b2e48SStefano Zampini } 66734f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 66744f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 66754f1b2e48SStefano Zampini } 66768af8fcf9SStefano Zampini } 66774f1b2e48SStefano Zampini 6678cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 6679674ae819SStefano Zampini /* Graph's connected components analysis */ 6680674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 668171582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 66828af8fcf9SStefano Zampini } 668366da6bd7Sstefano_zampini if (rcsr) pcbddc->mat_graph->nvtxs_csr = 0; 6684674ae819SStefano Zampini PetscFunctionReturn(0); 6685674ae819SStefano Zampini } 6686674ae819SStefano Zampini 66879a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 66889a7d3425SStefano Zampini { 66899a7d3425SStefano Zampini PetscInt i,j; 66909a7d3425SStefano Zampini PetscScalar *alphas; 66919a7d3425SStefano Zampini PetscErrorCode ierr; 66929a7d3425SStefano Zampini 66939a7d3425SStefano Zampini PetscFunctionBegin; 6694785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 66959a7d3425SStefano Zampini for (i=0;i<n;i++) { 66969a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 6697669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 6698669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 6699669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 67009a7d3425SStefano Zampini } 67019a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 67029a7d3425SStefano Zampini PetscFunctionReturn(0); 67039a7d3425SStefano Zampini } 67049a7d3425SStefano Zampini 6705bb360cb4SStefano Zampini PetscErrorCode PCBDDCMatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 6706e7931f94SStefano Zampini { 670757de7509SStefano Zampini Mat A; 6708e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 6709e7931f94SStefano Zampini PetscMPIInt size,rank,color; 671052e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 671152e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 6712bb360cb4SStefano Zampini PetscInt im_active,active_procs,N,n,i,j,threshold = 2; 671357de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 671427b6a85dSStefano Zampini PetscInt xadj_count,*count; 671527b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 671627b6a85dSStefano Zampini PetscSubcomm psubcomm; 671727b6a85dSStefano Zampini MPI_Comm subcomm; 671852e5ac9dSStefano Zampini PetscErrorCode ierr; 6719a57a6d2fSStefano Zampini 6720e7931f94SStefano Zampini PetscFunctionBegin; 672157de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 672257de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 6723fbfcfee5SBarry 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); 672457de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 672557de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 672657de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 672757de7509SStefano Zampini 672857de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 672957de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 673057de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 673157de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 673257de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 6733bb360cb4SStefano Zampini im_active = !!n; 673457de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 673557de7509SStefano Zampini void_procs = size - active_procs; 673657de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 673757de7509SStefano Zampini if (void_procs) { 673857de7509SStefano Zampini PetscInt ncand; 673957de7509SStefano Zampini 674057de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 674157de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 674257de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 674357de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 674457de7509SStefano Zampini if (!procs_candidates[i]) { 674557de7509SStefano Zampini procs_candidates[ncand++] = i; 674657de7509SStefano Zampini } 674757de7509SStefano Zampini } 674857de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 674957de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 675057de7509SStefano Zampini } 675157de7509SStefano Zampini 6752bb360cb4SStefano Zampini /* number of subdomains requested greater than active processes or matrix size -> just shift the matrix 675314f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 6754bb360cb4SStefano Zampini ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 6755bb360cb4SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1 || N <= *n_subdomains) { 675614f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 675714f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 675814f0bfb9SStefano Zampini else dest = rank; 675957de7509SStefano Zampini if (im_active) { 676057de7509SStefano Zampini issize = 1; 676157de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 676214f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 676357de7509SStefano Zampini } else { 676414f0bfb9SStefano Zampini isidx = dest; 676557de7509SStefano Zampini } 676657de7509SStefano Zampini } else { 676757de7509SStefano Zampini issize = 0; 676857de7509SStefano Zampini isidx = -1; 676957de7509SStefano Zampini } 6770bb360cb4SStefano Zampini if (*n_subdomains != 1) *n_subdomains = active_procs; 677157de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 6772daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 677357de7509SStefano Zampini PetscFunctionReturn(0); 677457de7509SStefano Zampini } 6775c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 6776c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 677727b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 6778e7931f94SStefano Zampini 6779e7931f94SStefano Zampini /* Get info on mapping */ 67803bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6781e7931f94SStefano Zampini 6782e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 6783785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 6784e7931f94SStefano Zampini xadj[0] = 0; 6785e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 6786785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 6787785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 6788bb360cb4SStefano Zampini ierr = PetscCalloc1(n,&count);CHKERRQ(ierr); 678927b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 679027b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 679127b6a85dSStefano Zampini count[shared[i][j]] += 1; 6792e7931f94SStefano Zampini 679327b6a85dSStefano Zampini xadj_count = 0; 67942b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 679527b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 679627b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 6797d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 6798d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 6799d023bfaeSStefano Zampini xadj_count++; 680027b6a85dSStefano Zampini break; 680127b6a85dSStefano Zampini } 6802e7931f94SStefano Zampini } 6803e7931f94SStefano Zampini } 6804d023bfaeSStefano Zampini xadj[1] = xadj_count; 680527b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 68063bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6807e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 6808e7931f94SStefano Zampini 68093837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 6810e7931f94SStefano Zampini 681127b6a85dSStefano Zampini /* Restrict work on active processes only */ 681227b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 681327b6a85dSStefano Zampini if (void_procs) { 681427b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 681527b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 681627b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 681727b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 681827b6a85dSStefano Zampini } else { 681927b6a85dSStefano Zampini psubcomm = NULL; 682027b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 682127b6a85dSStefano Zampini } 682227b6a85dSStefano Zampini 682327b6a85dSStefano Zampini v_wgt = NULL; 682427b6a85dSStefano Zampini if (!color) { 6825e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 6826e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 6827e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6828c8587f34SStefano Zampini } else { 682952e5ac9dSStefano Zampini Mat subdomain_adj; 683052e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 683152e5ac9dSStefano Zampini MatPartitioning partitioner; 683227b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 683352e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 683457de7509SStefano Zampini PetscMPIInt size; 6835b0c7d250SStefano Zampini PetscBool aggregate; 6836b0c7d250SStefano Zampini 683727b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 683827b6a85dSStefano Zampini if (void_procs) { 683927b6a85dSStefano Zampini PetscInt prank = rank; 6840785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 684127b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 6842e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 6843e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 6844c8587f34SStefano Zampini } 6845e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 684627b6a85dSStefano Zampini } else { 684727b6a85dSStefano Zampini oldranks = NULL; 684827b6a85dSStefano Zampini } 6849b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 685027b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 6851b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 6852b0c7d250SStefano Zampini PetscMPIInt nrank; 6853b0c7d250SStefano Zampini PetscScalar *vals; 6854b0c7d250SStefano Zampini 685527b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 6856b0c7d250SStefano Zampini lrows = 0; 6857b0c7d250SStefano Zampini if (nrank<redprocs) { 6858b0c7d250SStefano Zampini lrows = size/redprocs; 6859b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 6860b0c7d250SStefano Zampini } 686127b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 6862b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 6863b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6864b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6865b0c7d250SStefano Zampini row = nrank; 6866b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 6867b0c7d250SStefano Zampini cols = adjncy; 6868b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 6869b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 6870b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 6871b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6872b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 687352e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 687452e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 687552e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6876b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 687727b6a85dSStefano Zampini if (use_vwgt) { 687827b6a85dSStefano Zampini Vec v; 687927b6a85dSStefano Zampini const PetscScalar *array; 688027b6a85dSStefano Zampini PetscInt nl; 688127b6a85dSStefano Zampini 688227b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 6883bb360cb4SStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)n,INSERT_VALUES);CHKERRQ(ierr); 688427b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 688527b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 688627b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 688727b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 688827b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 688922db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 689027b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 689127b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 689227b6a85dSStefano Zampini } 6893b0c7d250SStefano Zampini } else { 689427b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 689527b6a85dSStefano Zampini if (use_vwgt) { 689627b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 6897bb360cb4SStefano Zampini v_wgt[0] = n; 689827b6a85dSStefano Zampini } 6899b0c7d250SStefano Zampini } 690022b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 6901e7931f94SStefano Zampini 6902e7931f94SStefano Zampini /* Partition */ 690327b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 6904e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 690527b6a85dSStefano Zampini if (v_wgt) { 6906e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 6907c8587f34SStefano Zampini } 690857de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 690957de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 6910e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 6911e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 691222b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 6913e7931f94SStefano Zampini 691452e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 69156583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 691652e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 691752e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 691857de7509SStefano Zampini if (!aggregate) { 691957de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 692027b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 692127b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 692227b6a85dSStefano Zampini #endif 692357de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 692427b6a85dSStefano Zampini } else if (oldranks) { 6925b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 692627b6a85dSStefano Zampini } else { 692727b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 692857de7509SStefano Zampini } 692928143c3dSStefano Zampini } else { 69307fb8a5e4SKarl Rupp PetscInt idx = 0; 6931b0c7d250SStefano Zampini PetscMPIInt tag; 6932b0c7d250SStefano Zampini MPI_Request *reqs; 6933b0c7d250SStefano Zampini 6934b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 6935b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 6936b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 693727b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 693828143c3dSStefano Zampini } 69397fb8a5e4SKarl Rupp ierr = MPI_Recv(&idx,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 6940b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6941b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 694257de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 694327b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 694427b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 694527b6a85dSStefano Zampini #endif 69467fb8a5e4SKarl Rupp ranks_send_to_idx[0] = procs_candidates[oldranks[idx]]; 694727b6a85dSStefano Zampini } else if (oldranks) { 69487fb8a5e4SKarl Rupp ranks_send_to_idx[0] = oldranks[idx]; 694927b6a85dSStefano Zampini } else { 69507fb8a5e4SKarl Rupp ranks_send_to_idx[0] = idx; 6951e7931f94SStefano Zampini } 695257de7509SStefano Zampini } 695352e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6954e7931f94SStefano Zampini /* clean up */ 6955e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 695652e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 6957e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 6958e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 6959e7931f94SStefano Zampini } 696027b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 696157de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 6962e7931f94SStefano Zampini 6963e7931f94SStefano Zampini /* assemble parallel IS for sends */ 6964e7931f94SStefano Zampini i = 1; 696527b6a85dSStefano Zampini if (!color) i=0; 696657de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 6967e7931f94SStefano Zampini PetscFunctionReturn(0); 6968e7931f94SStefano Zampini } 6969e7931f94SStefano Zampini 6970e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 6971e7931f94SStefano Zampini 69721e0482f5SStefano 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[]) 6973e7931f94SStefano Zampini { 697470cf5478SStefano Zampini Mat local_mat; 6975e7931f94SStefano Zampini IS is_sends_internal; 69769d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 69771ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 69789d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 6979e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 6980e7931f94SStefano Zampini PetscInt* l2gmap_indices; 6981e7931f94SStefano Zampini const PetscInt* is_indices; 6982e7931f94SStefano Zampini MatType new_local_type; 6983e7931f94SStefano Zampini /* buffers */ 6984e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 698528143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 69869d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 6987e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 69881ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 6989e7931f94SStefano Zampini /* MPI */ 699028143c3dSStefano Zampini MPI_Comm comm,comm_n; 699128143c3dSStefano Zampini PetscSubcomm subcomm; 6992e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 699328143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 699428143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 69951ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 69961ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 69971ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 6998e7931f94SStefano Zampini PetscErrorCode ierr; 6999e7931f94SStefano Zampini 7000e7931f94SStefano Zampini PetscFunctionBegin; 700157de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7002e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 7003fbfcfee5SBarry 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); 700457de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 700557de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 700657de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 700757de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 700857de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 70091ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 70101ae86dd6SStefano Zampini if (nvecs) { 70111ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 70121ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 70131ae86dd6SStefano Zampini } 701457de7509SStefano Zampini /* further checks */ 7015e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7016e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 7017e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 7018e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 7019e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 702057de7509SStefano Zampini if (reuse && *mat_n) { 702170cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 702257de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 702370cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 702428143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 702570cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 702670cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 702770cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 702870cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 702970cf5478SStefano Zampini } 7030e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 7031e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 703257de7509SStefano Zampini 7033e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 7034e7931f94SStefano Zampini if (!is_sends) { 703528143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 7036bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 7037c8587f34SStefano Zampini } else { 7038e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 7039e7931f94SStefano Zampini is_sends_internal = is_sends; 7040c8587f34SStefano Zampini } 7041e7931f94SStefano Zampini 7042e7931f94SStefano Zampini /* get comm */ 7043a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 7044e7931f94SStefano Zampini 7045e7931f94SStefano Zampini /* compute number of sends */ 7046e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 7047e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 7048e7931f94SStefano Zampini 7049e7931f94SStefano Zampini /* compute number of receives */ 7050e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 7051785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 7052e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 7053e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7054e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 7055e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 7056e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 7057e7931f94SStefano Zampini 705828143c3dSStefano Zampini /* restrict comm if requested */ 705928143c3dSStefano Zampini subcomm = 0; 706028143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 706128143c3dSStefano Zampini if (restrict_comm) { 7062779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 7063779c1cceSStefano Zampini 706428143c3dSStefano Zampini color = 0; 706553a05cb3SStefano Zampini if (restrict_full) { 706653a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 706753a05cb3SStefano Zampini } else { 706853a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 706953a05cb3SStefano Zampini } 7070b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 707128143c3dSStefano Zampini subcommsize = commsize - subcommsize; 707228143c3dSStefano Zampini /* check if reuse has been requested */ 707357de7509SStefano Zampini if (reuse) { 707428143c3dSStefano Zampini if (*mat_n) { 707528143c3dSStefano Zampini PetscMPIInt subcommsize2; 707628143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 707728143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 707828143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 707928143c3dSStefano Zampini } else { 708028143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 708128143c3dSStefano Zampini } 708228143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 7083779c1cceSStefano Zampini PetscMPIInt rank; 7084779c1cceSStefano Zampini 7085779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 708628143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 708728143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 708828143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 7089306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 709028143c3dSStefano Zampini } 709128143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 709228143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 709328143c3dSStefano Zampini } else { 709428143c3dSStefano Zampini comm_n = comm; 709528143c3dSStefano Zampini } 709628143c3dSStefano Zampini 7097e7931f94SStefano Zampini /* prepare send/receive buffers */ 7098785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 7099e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 7100785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 7101e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 710228143c3dSStefano Zampini if (nis) { 7103854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 710428143c3dSStefano Zampini } 7105e7931f94SStefano Zampini 710628143c3dSStefano Zampini /* Get data from local matrices */ 71076c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 7108e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 7109e7931f94SStefano Zampini /* 7110e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 7111e7931f94SStefano Zampini send_buffer_idxs should contain: 7112e7931f94SStefano Zampini - MatType_PRIVATE type 7113e7931f94SStefano Zampini - PetscInt size_of_l2gmap 7114e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 7115e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 7116e7931f94SStefano Zampini */ 71176c4ed002SBarry Smith else { 7118e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 71193bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 7120854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 7121e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 7122e7931f94SStefano Zampini send_buffer_idxs[1] = i; 71233bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7124e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 71253bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7126e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 7127e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7128e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 7129e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 7130c8587f34SStefano Zampini } 7131c8587f34SStefano Zampini } 7132e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 713328143c3dSStefano Zampini /* additional is (if any) */ 713428143c3dSStefano Zampini if (nis) { 713528143c3dSStefano Zampini PetscMPIInt psum; 713628143c3dSStefano Zampini PetscInt j; 713728143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 713828143c3dSStefano Zampini PetscInt plen; 713928143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 714028143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 714128143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 714228143c3dSStefano Zampini } 7143854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 714428143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 714528143c3dSStefano Zampini PetscInt plen; 714628143c3dSStefano Zampini const PetscInt *is_array_idxs; 714728143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 714828143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 714928143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 715028143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 715128143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 715228143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 715328143c3dSStefano Zampini } 715428143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 715528143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 715628143c3dSStefano Zampini } 715728143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 715828143c3dSStefano Zampini } 71593b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 716028143c3dSStefano Zampini 7161e7931f94SStefano Zampini buf_size_idxs = 0; 7162e7931f94SStefano Zampini buf_size_vals = 0; 716328143c3dSStefano Zampini buf_size_idxs_is = 0; 71641ae86dd6SStefano Zampini buf_size_vecs = 0; 7165e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7166e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 7167e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 716828143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 71691ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 7170e7931f94SStefano Zampini } 7171785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 7172785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 717395ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 71741ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 7175e7931f94SStefano Zampini 7176e7931f94SStefano Zampini /* get new tags for clean communications */ 7177e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 7178e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 717928143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 71801ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 7181e7931f94SStefano Zampini 7182e7931f94SStefano Zampini /* allocate for requests */ 7183785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 7184785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 718595ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 71861ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 7187785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 7188785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 718995ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 71901ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 7191e7931f94SStefano Zampini 7192e7931f94SStefano Zampini /* communications */ 7193e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7194e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 719528143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 71961ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 7197e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7198e7931f94SStefano Zampini source_dest = onodes[i]; 7199e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 7200e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 7201e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7202e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 720328143c3dSStefano Zampini if (nis) { 720457de7509SStefano Zampini source_dest = onodes_is[i]; 720528143c3dSStefano 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); 720628143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 720728143c3dSStefano Zampini } 72081ae86dd6SStefano Zampini if (nvecs) { 72091ae86dd6SStefano Zampini source_dest = onodes[i]; 72101ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 72111ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 72121ae86dd6SStefano Zampini } 7213e7931f94SStefano Zampini } 7214e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7215e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 7216e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 7217e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 721828143c3dSStefano Zampini if (nis) { 721928143c3dSStefano 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); 722028143c3dSStefano Zampini } 72211ae86dd6SStefano Zampini if (nvecs) { 72221ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 72231ae86dd6SStefano 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); 72241ae86dd6SStefano Zampini } 7225e7931f94SStefano Zampini } 7226e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7227e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 7228e7931f94SStefano Zampini 7229e7931f94SStefano Zampini /* assemble new l2g map */ 7230e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7231e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 72329d30be91SStefano Zampini new_local_rows = 0; 7233e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 72349d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7235e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7236e7931f94SStefano Zampini } 72379d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 7238e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 72399d30be91SStefano Zampini new_local_rows = 0; 7240e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 72419d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 72429d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7243e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7244e7931f94SStefano Zampini } 72459d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 72469d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 7247e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 7248e7931f94SStefano Zampini 7249e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 7250e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 7251e7931f94SStefano 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) */ 7252e7931f94SStefano Zampini if (n_recvs) { 725328143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 7254e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7255e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7256e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 7257e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 7258e7931f94SStefano Zampini break; 7259e7931f94SStefano Zampini } 7260e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7261e7931f94SStefano Zampini } 7262e7931f94SStefano Zampini switch (new_local_type_private) { 726328143c3dSStefano Zampini case MATDENSE_PRIVATE: 7264e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7265e7931f94SStefano Zampini bs = 1; 7266e7931f94SStefano Zampini break; 7267e7931f94SStefano Zampini case MATAIJ_PRIVATE: 7268e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7269e7931f94SStefano Zampini bs = 1; 7270e7931f94SStefano Zampini break; 7271e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 7272e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 7273e7931f94SStefano Zampini break; 7274e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 7275e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 7276e7931f94SStefano Zampini break; 7277e7931f94SStefano Zampini default: 7278fbfcfee5SBarry Smith SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,PETSC_FUNCTION_NAME); 7279e7931f94SStefano Zampini break; 7280e7931f94SStefano Zampini } 7281ed8ed4edSstefano_zampini } else { /* by default, new_local_type is seqaij */ 7282ed8ed4edSstefano_zampini new_local_type = MATSEQAIJ; 728328143c3dSStefano Zampini bs = 1; 7284e7931f94SStefano Zampini } 7285e7931f94SStefano Zampini 728670cf5478SStefano Zampini /* create MATIS object if needed */ 728757de7509SStefano Zampini if (!reuse) { 7288e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 7289e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 729070cf5478SStefano Zampini } else { 729170cf5478SStefano Zampini /* it also destroys the local matrices */ 729257de7509SStefano Zampini if (*mat_n) { 729370cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 729457de7509SStefano Zampini } else { /* this is a fake object */ 729557de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 729657de7509SStefano Zampini } 729770cf5478SStefano Zampini } 729870cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 7299e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 73009d30be91SStefano Zampini 73019d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 73029d30be91SStefano Zampini 73039d30be91SStefano Zampini /* Global to local map of received indices */ 73049d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 73059d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 73069d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 73079d30be91SStefano Zampini 73089d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 73099d30be91SStefano Zampini buf_size_idxs = 0; 73109d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 73119d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 73129d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 73139d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 73149d30be91SStefano Zampini } 73159d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 73169d30be91SStefano Zampini 73179d30be91SStefano Zampini /* set preallocation */ 73189d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 73199d30be91SStefano Zampini if (!newisdense) { 73209d30be91SStefano Zampini PetscInt *new_local_nnz=0; 73219d30be91SStefano Zampini 73229d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 73239d30be91SStefano Zampini if (n_recvs) { 73249d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 73259d30be91SStefano Zampini } 73269d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 73279d30be91SStefano Zampini PetscInt j; 73289d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 73299d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 73309d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 73319d30be91SStefano Zampini } 73329d30be91SStefano Zampini } else { 73339d30be91SStefano Zampini /* TODO */ 73349d30be91SStefano Zampini } 73359d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 73369d30be91SStefano Zampini } 73379d30be91SStefano Zampini if (new_local_nnz) { 73389d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 73399d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 73409d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 73419d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 73429d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 73439d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 73449d30be91SStefano Zampini } else { 73459d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 73469d30be91SStefano Zampini } 73479d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 73489d30be91SStefano Zampini } else { 73499d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 73509d30be91SStefano Zampini } 7351e7931f94SStefano Zampini 7352e7931f94SStefano Zampini /* set values */ 7353e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 73549d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 7355e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7356e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 7357e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 73589d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 7359e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7360e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7361e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 736228143c3dSStefano Zampini } else { 736328143c3dSStefano Zampini /* TODO */ 7364e7931f94SStefano Zampini } 7365e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7366e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 7367e7931f94SStefano Zampini } 7368e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7369e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 73703b3b1effSJed Brown ierr = MatISRestoreLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 737170cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 737270cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 73739d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 7374e7931f94SStefano Zampini 7375dfd14d43SStefano Zampini #if 0 737628143c3dSStefano Zampini if (!restrict_comm) { /* check */ 7377e7931f94SStefano Zampini Vec lvec,rvec; 7378e7931f94SStefano Zampini PetscReal infty_error; 7379e7931f94SStefano Zampini 73802a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 7381e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 7382e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 7383e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 738470cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 7385e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 7386e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 7387e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 7388e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 7389e7931f94SStefano Zampini } 739028143c3dSStefano Zampini #endif 7391e7931f94SStefano Zampini 739228143c3dSStefano Zampini /* assemble new additional is (if any) */ 739328143c3dSStefano Zampini if (nis) { 739428143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 739528143c3dSStefano Zampini 739628143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7397854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 739828143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 739928143c3dSStefano Zampini psum = 0; 740028143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 740128143c3dSStefano Zampini for (j=0;j<nis;j++) { 740228143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 740328143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 740428143c3dSStefano Zampini psum += plen; 740528143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 740628143c3dSStefano Zampini } 740728143c3dSStefano Zampini } 7408854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 7409854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 741028143c3dSStefano Zampini for (i=1;i<nis;i++) { 741128143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 741228143c3dSStefano Zampini } 741328143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 741428143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 741528143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 741628143c3dSStefano Zampini for (j=0;j<nis;j++) { 741728143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 741828143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 741928143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 742028143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 742128143c3dSStefano Zampini } 742228143c3dSStefano Zampini } 742328143c3dSStefano Zampini for (i=0;i<nis;i++) { 742428143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 742528143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 742628143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 742728143c3dSStefano Zampini } 742828143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 742928143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 743028143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 743128143c3dSStefano Zampini } 7432e7931f94SStefano Zampini /* free workspace */ 743328143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 7434e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7435e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 7436e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7437e7931f94SStefano Zampini if (isdense) { 7438e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7439e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 74403b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 7441e7931f94SStefano Zampini } else { 7442e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 7443e7931f94SStefano Zampini } 744428143c3dSStefano Zampini if (nis) { 744528143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 744628143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 744728143c3dSStefano Zampini } 74481ae86dd6SStefano Zampini 74491ae86dd6SStefano Zampini if (nvecs) { 74501ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 74511ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 74521ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 74531ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 74541ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 74551ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 74561ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 74571ae86dd6SStefano Zampini /* set values */ 74581ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 74591ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 74601ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 74611ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 74621ae86dd6SStefano Zampini PetscInt j; 74631ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 74641ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 74651ae86dd6SStefano Zampini } 74661ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 74671ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 74681ae86dd6SStefano Zampini } 74691ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 74701ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 74711ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 74721ae86dd6SStefano Zampini } 74731ae86dd6SStefano Zampini 74741ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 74751ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 7476e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 7477e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 74781ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 747928143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 7480e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 7481e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 74821ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 748328143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 7484e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 7485e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 7486e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 7487e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 7488e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 748928143c3dSStefano Zampini if (nis) { 749028143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 749128143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 749228143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 749328143c3dSStefano Zampini } 749428143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 749528143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 749628143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 749728143c3dSStefano Zampini for (i=0;i<nis;i++) { 749828143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 749928143c3dSStefano Zampini } 75001ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 75011ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 75021ae86dd6SStefano Zampini } 750353a05cb3SStefano Zampini *mat_n = NULL; 750428143c3dSStefano Zampini } 7505e7931f94SStefano Zampini PetscFunctionReturn(0); 7506e7931f94SStefano Zampini } 7507a57a6d2fSStefano Zampini 750812edc857SStefano Zampini /* temporary hack into ksp private data structure */ 7509af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 751012edc857SStefano Zampini 7511c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 7512c8587f34SStefano Zampini { 7513c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7514c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 751520a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 75161ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 75171e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 75189881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 751920a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 75206e683305SStefano Zampini IS coarse_is,*isarray; 75216e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 752230368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 7523f9eb5b7dSStefano Zampini PC pc_temp; 7524c8587f34SStefano Zampini PCType coarse_pc_type; 7525c8587f34SStefano Zampini KSPType coarse_ksp_type; 7526f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 75277274672aSStefano Zampini PetscBool coarse_reuse; 75281e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 752968457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 753022bc73bbSStefano Zampini PetscScalar *array; 753157de7509SStefano Zampini MatReuse coarse_mat_reuse; 753257de7509SStefano Zampini PetscBool restr, full_restr, have_void; 75337de4f681Sstefano_zampini PetscMPIInt commsize; 75349881197aSStefano Zampini PetscErrorCode ierr; 7535fdc09c96SStefano Zampini 7536c8587f34SStefano Zampini PetscFunctionBegin; 7537c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 753868457ee5SStefano 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 */ 7539fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 75405a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 75417de4f681Sstefano_zampini 75427de4f681Sstefano_zampini pcbddc->new_primal_space = PETSC_TRUE; 7543fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 7544f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 7545f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 7546f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 7547fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 754851bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 754951bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 7550727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 7551fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7552fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 7553fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7554f4ddd8eeSStefano Zampini } 7555fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 7556fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7557f4ddd8eeSStefano Zampini } 755870cf5478SStefano Zampini /* reset any subassembling information */ 755957de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 756070cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 756157de7509SStefano Zampini } 75626e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 7563fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7564f4ddd8eeSStefano Zampini } 756557de7509SStefano Zampini /* assemble coarse matrix */ 756657de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 756757de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 756857de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 756957de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 757018a45a71SStefano Zampini } else { 757157de7509SStefano Zampini coarse_mat = NULL; 757257de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 75736e683305SStefano Zampini } 7574e7931f94SStefano Zampini 7575abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 7576abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 7577abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 7578abbbba34SStefano Zampini 7579abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 758022bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 758122bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 758222bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 758322bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 7584e176bc59SStefano 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); 75856e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 75866e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 75876e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7588abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 7589abbbba34SStefano Zampini 759057de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 759157de7509SStefano Zampini im_active = !!(pcis->n); 759257de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 759357de7509SStefano Zampini 759414f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 759557de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 759657de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 75977de4f681Sstefano_zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&commsize);CHKERRQ(ierr); 759857de7509SStefano Zampini coarse_mat_is = NULL; 759957de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 760057de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 76011ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 760257de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 760357de7509SStefano Zampini if (multilevel_requested) { 760457de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 760557de7509SStefano Zampini restr = PETSC_FALSE; 760657de7509SStefano Zampini full_restr = PETSC_FALSE; 760757de7509SStefano Zampini } else { 760857de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 760957de7509SStefano Zampini restr = PETSC_TRUE; 761057de7509SStefano Zampini full_restr = PETSC_TRUE; 761157de7509SStefano Zampini } 76127de4f681Sstefano_zampini if (!pcbddc->coarse_size || commsize == 1) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 761357de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 761457de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 7615a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 7616bb360cb4SStefano Zampini if (multilevel_requested) { 7617bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7618bb360cb4SStefano Zampini } else { 7619bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7620bb360cb4SStefano Zampini } 7621a198735bSStefano Zampini } else { 76227de4f681Sstefano_zampini PetscMPIInt rank; 7623a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 76247de4f681Sstefano_zampini have_void = (active_procs == (PetscInt)commsize) ? PETSC_FALSE : PETSC_TRUE; 7625a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 7626a198735bSStefano Zampini } 762757de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 762857de7509SStefano Zampini PetscInt psum; 762957de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 763057de7509SStefano Zampini else psum = 0; 763157de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 76327de4f681Sstefano_zampini if (ncoarse < commsize) have_void = PETSC_TRUE; 763357de7509SStefano Zampini } 763457de7509SStefano Zampini /* determine if we can go multilevel */ 763557de7509SStefano Zampini if (multilevel_requested) { 763657de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 763757de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 763857de7509SStefano Zampini } 763957de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 764057de7509SStefano Zampini 7641e4d548c7SStefano Zampini /* dump subassembling pattern */ 7642e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 7643e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 7644e4d548c7SStefano Zampini } 7645e4d548c7SStefano Zampini 76466e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 76471e0482f5SStefano Zampini nedcfield = -1; 76481e0482f5SStefano Zampini if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal)) { /* protects from unneded computations */ 76496e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 76506e683305SStefano Zampini const PetscInt *idxs; 76516e683305SStefano Zampini ISLocalToGlobalMapping tmap; 76526e683305SStefano Zampini 76536e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 76540be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 76556e683305SStefano Zampini /* allocate space for temporary storage */ 7656854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 7657854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 76586e683305SStefano Zampini /* allocate for IS array */ 76596e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 76601e0482f5SStefano Zampini if (pcbddc->nedclocal) { 76611e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 76621e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 76631e0482f5SStefano Zampini } else { 76641e0482f5SStefano Zampini nedcfield = 0; 76651e0482f5SStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%d)",nisdofs); 76661e0482f5SStefano Zampini nisdofs = 1; 76671e0482f5SStefano Zampini } 76681e0482f5SStefano Zampini } 76696e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 767027b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 767130368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 7672854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 76736e683305SStefano Zampini /* dofs splitting */ 76746e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 76756e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 76761e0482f5SStefano Zampini if (nedcfield != i) { 76776e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 76786e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 76796e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 76806e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 76811e0482f5SStefano Zampini } else { 76821e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 76831e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 76841e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 7685eee23b56SStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping coarse nedelec field! %d != %d\n",tsize,nout); 76861e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 76871e0482f5SStefano Zampini } 76886e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 768930368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 76906e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 76916e683305SStefano Zampini } 76926e683305SStefano Zampini /* neumann boundaries */ 76936e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 76946e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 76956e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 76966e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 76976e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 76986e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 76996e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 770030368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 77016e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 77026e683305SStefano Zampini } 77036e683305SStefano Zampini /* free memory */ 77046e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 77056e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 77066e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 77076e683305SStefano Zampini } else { 77086e683305SStefano Zampini nis = 0; 77096e683305SStefano Zampini nisdofs = 0; 77106e683305SStefano Zampini nisneu = 0; 771130368db7SStefano Zampini nisvert = 0; 77126e683305SStefano Zampini isarray = NULL; 77136e683305SStefano Zampini } 77146e683305SStefano Zampini /* destroy no longer needed map */ 77156e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 77166e683305SStefano Zampini 771757de7509SStefano Zampini /* subassemble */ 771857de7509SStefano Zampini if (multilevel_allowed) { 77191ae86dd6SStefano Zampini Vec vp[1]; 77201ae86dd6SStefano Zampini PetscInt nvecs = 0; 772157de7509SStefano Zampini PetscBool reuse,reuser; 77221ae86dd6SStefano Zampini 772357de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 772457de7509SStefano Zampini else reuse = PETSC_FALSE; 772557de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 77261ae86dd6SStefano Zampini vp[0] = NULL; 77271ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 77281ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 77291ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 77301ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 77311ae86dd6SStefano Zampini nvecs = 1; 77321ae86dd6SStefano Zampini 77331ae86dd6SStefano Zampini if (pcbddc->divudotp) { 7734a198735bSStefano Zampini Mat B,loc_divudotp; 77351ae86dd6SStefano Zampini Vec v,p; 77361ae86dd6SStefano Zampini IS dummy; 77371ae86dd6SStefano Zampini PetscInt np; 77381ae86dd6SStefano Zampini 7739a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 7740a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 77411ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 77427dae84e0SHong Zhang ierr = MatCreateSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 77431ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 77441ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 77451ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 77461ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 77471ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 77481ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 77491ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 77501ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 77511ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 77521ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 77531ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 77541ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 775574e2c79eSStefano Zampini } 77561ae86dd6SStefano Zampini } 77571ae86dd6SStefano Zampini if (reuser) { 77581e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 775974e2c79eSStefano Zampini } else { 77601e0482f5SStefano 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); 77611ae86dd6SStefano Zampini } 77621ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 77631ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 77641ae86dd6SStefano Zampini PetscInt nl; 77651ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 77661ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 77671ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 77681ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 77691ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 77701ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 77711ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 77721ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 7773a198735bSStefano Zampini } else { 7774a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 77751ae86dd6SStefano Zampini } 77761ae86dd6SStefano Zampini } else { 77771e0482f5SStefano 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); 77786e683305SStefano Zampini } 777957de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 778057de7509SStefano Zampini PetscMPIInt size; 7781f913dca9SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size);CHKERRQ(ierr); 778257de7509SStefano Zampini if (!multilevel_allowed) { 778357de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 77846e683305SStefano Zampini } else { 778557de7509SStefano Zampini Mat A; 7786779c1cceSStefano Zampini 778757de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 778857de7509SStefano Zampini if (coarse_mat_is) { 778957de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 779057de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 779157de7509SStefano Zampini coarse_mat = coarse_mat_is; 779257de7509SStefano Zampini } 779357de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 779457de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 779557de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 7796779c1cceSStefano Zampini } 7797779c1cceSStefano Zampini } 779857de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 779957de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 78006e683305SStefano Zampini 78016e683305SStefano Zampini /* create local to global scatters for coarse problem */ 780268457ee5SStefano Zampini if (compute_vecs) { 78036e683305SStefano Zampini PetscInt lrows; 78046e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 780557de7509SStefano Zampini if (coarse_mat) { 780657de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 78076e683305SStefano Zampini } else { 78086e683305SStefano Zampini lrows = 0; 78096e683305SStefano Zampini } 78106e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 78116e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 78126e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 78136e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 78146e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 78156e683305SStefano Zampini } 78166e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 7817c8587f34SStefano Zampini 7818f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 7819f9eb5b7dSStefano Zampini if (multilevel_allowed) { 7820f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 7821f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 7822f9eb5b7dSStefano Zampini } else { 7823f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 7824f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 7825c8587f34SStefano Zampini } 7826c8587f34SStefano Zampini 78276e683305SStefano Zampini /* print some info if requested */ 78286e683305SStefano Zampini if (pcbddc->dbg_flag) { 78296e683305SStefano Zampini if (!multilevel_allowed) { 78306e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 78316e683305SStefano Zampini if (multilevel_requested) { 78326e683305SStefano 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); 78336e683305SStefano Zampini } else if (pcbddc->max_levels) { 78346e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 78356e683305SStefano Zampini } 78366e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 78376e683305SStefano Zampini } 78386e683305SStefano Zampini } 78396e683305SStefano Zampini 78401e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 78411e0482f5SStefano Zampini coarseG = NULL; 78421e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 78431e0482f5SStefano Zampini MPI_Comm ccomm; 78441e0482f5SStefano Zampini if (coarse_mat) { 78451e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 78461e0482f5SStefano Zampini } else { 78471e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 78481e0482f5SStefano Zampini } 78491e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 78501e0482f5SStefano Zampini } 78511e0482f5SStefano Zampini 7852f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 785357de7509SStefano Zampini if (coarse_mat) { 78547274672aSStefano Zampini PetscBool isredundant,isnn,isbddc; 78556a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 78567274672aSStefano Zampini 78576e683305SStefano Zampini if (pcbddc->dbg_flag) { 785857de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 78596e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 78606e683305SStefano Zampini } 7861f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 7862312be037SStefano Zampini char prefix[256],str_level[16]; 7863e604994aSStefano Zampini size_t len; 78641e0482f5SStefano Zampini 786557de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 7866422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 7867c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 7868f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 786957de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7870c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 78716e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 7872c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 78731e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 7874c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7875e604994aSStefano Zampini /* prefix */ 7876e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 7877e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 7878e604994aSStefano Zampini if (!pcbddc->current_level) { 7879e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 7880e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 7881c8587f34SStefano Zampini } else { 7882e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 7883312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 7884312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 788534d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 788635529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 7887e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 7888e604994aSStefano Zampini } 7889e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 78903e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 78913e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 78923e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 78933e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 7894f9eb5b7dSStefano Zampini /* allow user customization */ 7895f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 78963e3c6dadSStefano Zampini } 78973e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 789851bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 78993e3c6dadSStefano Zampini if (nisdofs) { 79003e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 79013e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 79023e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 79033e3c6dadSStefano Zampini } 79043e3c6dadSStefano Zampini } 79053e3c6dadSStefano Zampini if (nisneu) { 79063e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 79073e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 7908312be037SStefano Zampini } 790930368db7SStefano Zampini if (nisvert) { 791030368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 791130368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 791230368db7SStefano Zampini } 79131e0482f5SStefano Zampini if (coarseG) { 79141e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 79151e0482f5SStefano Zampini } 7916f9eb5b7dSStefano Zampini 7917f9eb5b7dSStefano Zampini /* get some info after set from options */ 7918f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 7919b76f3995Sstefano_zampini /* multilevel can only be requested via -pc_bddc_levels or PCBDDCSetLevels */ 7920b76f3995Sstefano_zampini if (isbddc && !multilevel_allowed) { 7921f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7922f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 7923f9eb5b7dSStefano Zampini } 7924b76f3995Sstefano_zampini /* multilevel cannot be done with coarse PCs different from BDDC or NN */ 79257274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 79267274672aSStefano Zampini if (multilevel_requested && multilevel_allowed && !isbddc && !isnn) { 7927b76f3995Sstefano_zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 7928b76f3995Sstefano_zampini isbddc = PETSC_TRUE; 7929b76f3995Sstefano_zampini } 79307274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 79314f3a063dSStefano Zampini if (isredundant) { 79324f3a063dSStefano Zampini KSP inner_ksp; 79334f3a063dSStefano Zampini PC inner_pc; 79349326c5c6Sstefano_zampini 79354f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 79364f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 79374f3a063dSStefano Zampini } 7938f9eb5b7dSStefano Zampini 793957de7509SStefano Zampini /* parameters which miss an API */ 79407274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 794157de7509SStefano Zampini if (isbddc) { 7942720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 79437274672aSStefano Zampini 7944720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 794557de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 794627b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 794727b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 7948a198735bSStefano Zampini Mat coarsedivudotp_is; 7949a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 7950a198735bSStefano Zampini IS row,col; 7951a198735bSStefano Zampini const PetscInt *gidxs; 7952a198735bSStefano Zampini PetscInt n,st,M,N; 7953a198735bSStefano Zampini 7954a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 7955a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 7956a198735bSStefano Zampini st = st-n; 7957a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 7958a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 7959a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 7960a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7961a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 7962a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7963a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 7964a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 7965a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 7966a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 7967a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 7968a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 7969a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 7970a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 7971a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 7972a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 7973a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 7974a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 7975a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 7976a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 79778ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 7978a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 7979720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 798059e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 7981720d30f9SStefano Zampini } 7982d4d8cf7bSStefano Zampini } 79839881197aSStefano Zampini 79843301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 79855a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 79863301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 79873301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 79883301b35fSStefano Zampini } 79893301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 79903301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 79913301b35fSStefano Zampini } 79923301b35fSStefano Zampini if (pc->pmat->spd_set) { 79933301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 79943301b35fSStefano Zampini } 799527b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 799627b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 799727b6a85dSStefano Zampini } 79986e683305SStefano Zampini /* set operators */ 79995f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 80006e683305SStefano Zampini if (pcbddc->dbg_flag) { 80016e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 80026e683305SStefano Zampini } 80036e683305SStefano Zampini } 80041e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 80056e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 8006b1ecc7b1SStefano Zampini #if 0 8007b9b85e73SStefano Zampini { 8008b9b85e73SStefano Zampini PetscViewer viewer; 8009b9b85e73SStefano Zampini char filename[256]; 8010b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 8011b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 80126a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 8013b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 8014f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 8015b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 8016b9b85e73SStefano Zampini } 8017b9b85e73SStefano Zampini #endif 8018f9eb5b7dSStefano Zampini 801998a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 802098a51de6SStefano Zampini Vec crhs,csol; 802104708bb6SStefano Zampini 8022f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 8023f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 8024f347579bSStefano Zampini if (!csol) { 80252a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 8026f9eb5b7dSStefano Zampini } 8027f347579bSStefano Zampini if (!crhs) { 80282a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 8029f347579bSStefano Zampini } 8030b0f5fe93SStefano Zampini } 80311ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 8032b0f5fe93SStefano Zampini 8033b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 8034b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 8035b0f5fe93SStefano Zampini 8036b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 80374f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 80384f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 80394f1b2e48SStefano Zampini } 8040b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 8041b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 8042b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8043b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8044b0f5fe93SStefano Zampini if (coarse_mat) { 8045b0f5fe93SStefano Zampini Vec nullv; 8046b0f5fe93SStefano Zampini PetscScalar *array,*array2; 8047b0f5fe93SStefano Zampini PetscInt nl; 8048b0f5fe93SStefano Zampini 8049b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 8050b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 8051b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8052b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 8053b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 8054b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 8055b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8056b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 8057b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 8058b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 8059b0f5fe93SStefano Zampini } 8060b0f5fe93SStefano Zampini } 8061b0f5fe93SStefano Zampini 8062b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 8063b0f5fe93SStefano Zampini PetscBool ispreonly; 8064b0f5fe93SStefano Zampini 8065b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8066b0f5fe93SStefano Zampini PetscBool isnull; 8067b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 8068bef83e63SStefano Zampini if (isnull) { 8069b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 8070b0f5fe93SStefano Zampini } 8071bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 8072b0f5fe93SStefano Zampini } 8073b0f5fe93SStefano Zampini /* setup coarse ksp */ 8074b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 8075cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 8076cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 80776e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 8078c8587f34SStefano Zampini KSP check_ksp; 80792b510759SStefano Zampini KSPType check_ksp_type; 8080c8587f34SStefano Zampini PC check_pc; 80816e683305SStefano Zampini Vec check_vec,coarse_vec; 80826a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 80832b510759SStefano Zampini PetscInt its; 80846e683305SStefano Zampini PetscBool compute_eigs; 80856e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 80866e683305SStefano Zampini PetscInt neigs; 80878e185a42SStefano Zampini const char *prefix; 8088c8587f34SStefano Zampini 80892b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 80906e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 8091422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 809223ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8093f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 8094e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 8095e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 8096e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 80972b510759SStefano Zampini if (ispreonly) { 80982b510759SStefano Zampini check_ksp_type = KSPPREONLY; 80996e683305SStefano Zampini compute_eigs = PETSC_FALSE; 81002b510759SStefano Zampini } else { 8101cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 81026e683305SStefano Zampini compute_eigs = PETSC_TRUE; 8103c8587f34SStefano Zampini } 8104c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 81056e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 81066e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 81076e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 8108a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 8109a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 8110a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 8111a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 8112c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 8113c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 8114c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 8115c8587f34SStefano Zampini /* create random vec */ 81162701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 8117c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 81186e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 8119c8587f34SStefano Zampini /* solve coarse problem */ 81206e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 8121cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 81226e683305SStefano Zampini if (compute_eigs) { 8123854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 8124854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 81256e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 81261ae86dd6SStefano Zampini if (neigs) { 81276e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 81286e683305SStefano Zampini lambda_min = eigs_r[0]; 81296e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 81302701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 81312701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 8132cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 8133cbcc2c2aSStefano Zampini } 8134c8587f34SStefano Zampini } 8135c8587f34SStefano Zampini } 81361ae86dd6SStefano Zampini } 8137cbcc2c2aSStefano Zampini 8138c8587f34SStefano Zampini /* check coarse problem residual error */ 81396e683305SStefano Zampini if (pcbddc->dbg_flag) { 81406e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 81416e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 81426e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 8143c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 81446e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 81456e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 8146779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 81476e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 81486e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 81496e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 81506e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 8151b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8152b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 8153b0f5fe93SStefano Zampini } 81546e683305SStefano Zampini if (compute_eigs) { 81556e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 8156b03ebc13SStefano Zampini KSPConvergedReason reason; 8157deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 8158c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 8159b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 81606e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 8161b03ebc13SStefano 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); 81626e683305SStefano Zampini for (i=0;i<neigs;i++) { 81636e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 8164c8587f34SStefano Zampini } 81656e683305SStefano Zampini } 81666e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 81676e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 81686e683305SStefano Zampini } 8169e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 81702701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 8171c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 81726e683305SStefano Zampini if (compute_eigs) { 81736e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 81746e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 8175c8587f34SStefano Zampini } 81766e683305SStefano Zampini } 81776e683305SStefano Zampini } 8178bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 8179cbcc2c2aSStefano Zampini /* print additional info */ 8180cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 81816e683305SStefano Zampini /* waits until all processes reaches this point */ 81826e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 8183cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 8184cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8185cbcc2c2aSStefano Zampini } 8186cbcc2c2aSStefano Zampini 81872b510759SStefano Zampini /* free memory */ 8188fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 8189c8587f34SStefano Zampini PetscFunctionReturn(0); 8190c8587f34SStefano Zampini } 8191674ae819SStefano Zampini 8192f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 8193f34684f1SStefano Zampini { 8194f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 8195f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 8196f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 8197dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 8198dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 819973be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 8200dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 8201f34684f1SStefano Zampini PetscErrorCode ierr; 8202f34684f1SStefano Zampini 8203f34684f1SStefano Zampini PetscFunctionBegin; 8204f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 82056c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 8206dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 82073bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 8208dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8209dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 82106583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 8211dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 8212dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 8213dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 82146c4ed002SBarry 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); 8215dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 8216dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8217dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 8218dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8219dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8220f34684f1SStefano Zampini 8221f34684f1SStefano Zampini /* check numbering */ 8222f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 8223019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 8224dc456d91SStefano Zampini PetscInt i; 8225b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 8226f34684f1SStefano Zampini 8227f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8228f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8229f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 82301575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8231019a44ceSStefano Zampini /* counter */ 8232019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8233019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 8234019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8235019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8236019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8237019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8238f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 8239f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 8240727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 8241f34684f1SStefano Zampini } 8242f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8243f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8244f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8245e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8246e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8247e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8248e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8249f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8250019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8251f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8252019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 82532c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 825475c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 8255b9b85e73SStefano Zampini set_error = PETSC_TRUE; 82562c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 82572c66d082SStefano 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); 8258f34684f1SStefano Zampini } 8259f34684f1SStefano Zampini } 8260019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8261b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8262f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8263f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8264f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 8265f34684f1SStefano Zampini } 8266f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8267f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8268e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8269e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8270f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 8271f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 8272b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 8273ca8b9ea9SStefano Zampini PetscInt *gidxs; 8274ca8b9ea9SStefano Zampini 8275ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 82763bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 8277f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 8278f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8279f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 8280f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 82814bc2dc4bSStefano 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); 8282f34684f1SStefano Zampini } 8283f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8284ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 8285f34684f1SStefano Zampini } 8286f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 82871575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8288302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 8289f34684f1SStefano Zampini } 82908bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 8291f34684f1SStefano Zampini /* get back data */ 8292f34684f1SStefano Zampini *coarse_size_n = coarse_size; 8293f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 8294674ae819SStefano Zampini PetscFunctionReturn(0); 8295674ae819SStefano Zampini } 8296674ae819SStefano Zampini 8297a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 8298e456f2a8SStefano Zampini { 8299e456f2a8SStefano Zampini IS localis_t; 8300a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 8301e456f2a8SStefano Zampini PetscScalar *vals; 8302e456f2a8SStefano Zampini PetscErrorCode ierr; 8303e456f2a8SStefano Zampini 8304e456f2a8SStefano Zampini PetscFunctionBegin; 8305a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 8306e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 8307854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 8308e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 8309e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8310a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 8311a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 83121035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 83133151afb1SStefano Zampini ierr = VecSetOption(gwork,VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE);CHKERRQ(ierr); 8314a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 83151035eff8SStefano Zampini } 8316a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 8317e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8318e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 8319a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 8320a7dc3881SStefano Zampini /* now compute set in local ordering */ 8321a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8322a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8323a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8324a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 8325a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8326ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8327e456f2a8SStefano Zampini lsize++; 8328e456f2a8SStefano Zampini } 8329e456f2a8SStefano Zampini } 8330854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 8331a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8332ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8333e456f2a8SStefano Zampini idxs[lsize++] = i; 8334e456f2a8SStefano Zampini } 8335e456f2a8SStefano Zampini } 8336a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8337a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 8338e456f2a8SStefano Zampini *localis = localis_t; 8339e456f2a8SStefano Zampini PetscFunctionReturn(0); 8340e456f2a8SStefano Zampini } 8341906d46d4SStefano Zampini 834208122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 8343b96c3477SStefano Zampini { 8344a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8345b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8346b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 8347a64f4aa4SStefano Zampini Mat S_j; 8348b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 8349b96c3477SStefano Zampini PetscBool free_used_adj; 8350b96c3477SStefano Zampini PetscErrorCode ierr; 8351b96c3477SStefano Zampini 8352b96c3477SStefano Zampini PetscFunctionBegin; 8353b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 8354b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 835508122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 8356b96c3477SStefano Zampini used_xadj = NULL; 8357b96c3477SStefano Zampini used_adjncy = NULL; 8358b96c3477SStefano Zampini } else { 835908122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 836008122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 836108122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 836208122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 8363b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 8364b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 8365b96c3477SStefano Zampini } else { 83662fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 8367b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 8368b96c3477SStefano Zampini PetscInt nvtxs; 8369b96c3477SStefano Zampini 83702fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 83712fffb893SStefano Zampini if (flg_row) { 8372b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 8373b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 8374b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 8375b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 83762fffb893SStefano Zampini } else { 83772fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 83782fffb893SStefano Zampini used_xadj = NULL; 83792fffb893SStefano Zampini used_adjncy = NULL; 83802fffb893SStefano Zampini } 83812fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 8382b96c3477SStefano Zampini } 8383b96c3477SStefano Zampini } 8384d5574798SStefano Zampini 8385d5574798SStefano Zampini /* setup sub_schurs data */ 8386a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8387df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 8388df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 8389a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 839091af6908SStefano 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); 8391a64f4aa4SStefano Zampini } else { 839272b8c272SStefano Zampini Mat change = NULL; 83939d54b7f4SStefano Zampini Vec scaling = NULL; 8394111315fdSstefano_zampini IS change_primal = NULL, iP; 8395111315fdSstefano_zampini PetscInt benign_n; 8396111315fdSstefano_zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 8397111315fdSstefano_zampini PetscBool isseqaij,need_change = PETSC_FALSE; 8398111315fdSstefano_zampini PetscBool discrete_harmonic = PETSC_FALSE; 8399a3df083aSStefano Zampini 84005feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 84015feab87aSStefano Zampini PetscInt n_vertices; 84025feab87aSStefano Zampini 84035feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 84042034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 84055feab87aSStefano Zampini } 840604708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 840704708bb6SStefano Zampini if (!isseqaij) { 840804708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 840904708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 841004708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 841104708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 841204708bb6SStefano Zampini } else { 8413511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 841404708bb6SStefano Zampini } 841504708bb6SStefano Zampini } 8416a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 8417a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 8418ca92afb2SStefano Zampini } else { 8419a3df083aSStefano Zampini benign_n = 0; 8420ca92afb2SStefano Zampini } 8421b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 8422b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 8423b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 842472b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 842522db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 8426b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 842722db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 8428b7ab4a40SStefano Zampini } 8429b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 8430b7ab4a40SStefano 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 */ 8431b7ab4a40SStefano Zampini if (need_change) { 843288c03ad3SStefano Zampini PC_IS *pcisf; 843388c03ad3SStefano Zampini PC_BDDC *pcbddcf; 843488c03ad3SStefano Zampini PC pcf; 843588c03ad3SStefano Zampini 8436e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 843788c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 843888c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 843988c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 8440b9be95fcSstefano_zampini 844188c03ad3SStefano Zampini /* hacks */ 844288c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 844372b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 844472b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 844572b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 844672b8c272SStefano Zampini pcisf->n = pcis->n; 844772b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 844888c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 844988c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 845088c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 845188c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 845288c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 845388c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 845472b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 845588c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 8456b9be95fcSstefano_zampini 8457b9be95fcSstefano_zampini /* setup constraints so that we can get information on primal vertices and change of basis (in local numbering) */ 845888c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 845972b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 846072b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 846172b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 846272b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 8463b9be95fcSstefano_zampini 846488c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 846572b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 846688c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 846788c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 846888c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 846988c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 847088c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 847188c03ad3SStefano Zampini pcf->ops->destroy = NULL; 8472b9be95fcSstefano_zampini pcf->ops->reset = NULL; 847388c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 847488c03ad3SStefano Zampini } 84759d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 8476111315fdSstefano_zampini 8477111315fdSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 8478111315fdSstefano_zampini if (iP) { 8479111315fdSstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)iP),sub_schurs->prefix,"BDDC sub_schurs options","PC");CHKERRQ(ierr); 8480111315fdSstefano_zampini ierr = PetscOptionsBool("-sub_schurs_discrete_harmonic",NULL,NULL,discrete_harmonic,&discrete_harmonic,NULL);CHKERRQ(ierr); 8481111315fdSstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 8482111315fdSstefano_zampini } 8483111315fdSstefano_zampini if (discrete_harmonic) { 8484111315fdSstefano_zampini Mat A; 8485111315fdSstefano_zampini ierr = MatDuplicate(pcbddc->local_mat,MAT_COPY_VALUES,&A);CHKERRQ(ierr); 8486111315fdSstefano_zampini ierr = MatZeroRowsColumnsIS(A,iP,1.0,NULL,NULL);CHKERRQ(ierr); 8487111315fdSstefano_zampini ierr = PetscObjectCompose((PetscObject)A,"__KSPFETIDP_iP",(PetscObject)iP);CHKERRQ(ierr); 8488111315fdSstefano_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); 8489111315fdSstefano_zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 8490111315fdSstefano_zampini } else { 849191af6908SStefano 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); 8492111315fdSstefano_zampini } 849372b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 849472b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 8495ca92afb2SStefano Zampini } 8496d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8497b96c3477SStefano Zampini 8498b96c3477SStefano Zampini /* free adjacency */ 8499b96c3477SStefano Zampini if (free_used_adj) { 8500b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 8501b96c3477SStefano Zampini } 8502b96c3477SStefano Zampini PetscFunctionReturn(0); 8503b96c3477SStefano Zampini } 8504b96c3477SStefano Zampini 850508122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 8506b96c3477SStefano Zampini { 8507b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8508b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8509b96c3477SStefano Zampini PCBDDCGraph graph; 8510b96c3477SStefano Zampini PetscErrorCode ierr; 8511b96c3477SStefano Zampini 8512b96c3477SStefano Zampini PetscFunctionBegin; 8513b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 851408122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 85153301b35fSStefano Zampini IS verticesIS,verticescomm; 85163301b35fSStefano Zampini PetscInt vsize,*idxs; 8517b96c3477SStefano Zampini 8518b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 85193301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 85203301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 85213301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 85223301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 8523c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 8524b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 8525be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 8526441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 85273301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 8528b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 8529b96c3477SStefano Zampini } else { 8530b96c3477SStefano Zampini graph = pcbddc->mat_graph; 8531b96c3477SStefano Zampini } 8532e4d548c7SStefano Zampini /* print some info */ 85335c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 8534e4d548c7SStefano Zampini IS vertices; 8535e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 8536c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 8537e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8538e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 8539e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8540e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 8541e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 8542e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 8543e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 8544e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8545e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8546c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8547e4d548c7SStefano Zampini } 8548b96c3477SStefano Zampini 8549b96c3477SStefano Zampini /* sub_schurs init */ 8550b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 8551b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 8552b334f244SStefano Zampini } 855388113c35SStefano 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); 8554a64f4aa4SStefano Zampini 8555b96c3477SStefano Zampini /* free graph struct */ 855608122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 8557b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 8558b96c3477SStefano Zampini } 8559b96c3477SStefano Zampini PetscFunctionReturn(0); 8560b96c3477SStefano Zampini } 8561fa34dd3eSStefano Zampini 8562fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 8563fa34dd3eSStefano Zampini { 8564fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8565fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8566fa34dd3eSStefano Zampini PetscErrorCode ierr; 8567fa34dd3eSStefano Zampini 8568fa34dd3eSStefano Zampini PetscFunctionBegin; 8569fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 8570fa34dd3eSStefano Zampini IS zerodiag = NULL; 85714f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 8572fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 85734f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 857475c01103SStefano Zampini PetscReal norm; 8575fa34dd3eSStefano Zampini PetscInt i; 8576fa34dd3eSStefano Zampini 8577fa34dd3eSStefano Zampini /* B0 and B0_B */ 8578fa34dd3eSStefano Zampini if (zerodiag) { 8579fa34dd3eSStefano Zampini IS dummy; 8580fa34dd3eSStefano Zampini 85814f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 85827dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 8583fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 8584fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 8585fa34dd3eSStefano Zampini } 8586fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 8587fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 8588fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 8589fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8590fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8591fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8592fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8593fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 8594fa34dd3eSStefano Zampini /* S_j */ 8595fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8596fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 8597fa34dd3eSStefano Zampini 8598fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 8599fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 8600fa34dd3eSStefano Zampini /* continuous in primal space */ 8601fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 8602fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8603fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8604fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 86054f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 86064f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 8607fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8608fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8609fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8610fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8611fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8612fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8613fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 8614fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 8615fa34dd3eSStefano Zampini 8616fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 8617fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 8618fa34dd3eSStefano Zampini /* local with Schur */ 8619fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 8620fa34dd3eSStefano Zampini if (zerodiag) { 8621fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 86224f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 8623fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8624fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 8625fa34dd3eSStefano Zampini } 8626fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 8627fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8628fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8629fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8630fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8631fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 8632fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8633fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8634fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 8635fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8636fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8637fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8638fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8639fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8640fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 8641fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 8642fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8643fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8644fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8645fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8646fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8647fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8648fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 8649fa34dd3eSStefano Zampini if (zerodiag) { 8650fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 8651fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 86524f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 8653fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8654fa34dd3eSStefano Zampini } 8655fa34dd3eSStefano Zampini /* BDDC */ 8656fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 8657fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 8658fa34dd3eSStefano Zampini 8659fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 8660fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 8661fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 8662fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 86634f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 86644f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 8665fa34dd3eSStefano Zampini } 86664f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 8667fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 8668fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 8669fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 8670fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8671fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 8672fa34dd3eSStefano Zampini } 8673fa34dd3eSStefano Zampini PetscFunctionReturn(0); 8674fa34dd3eSStefano Zampini } 86751e0482f5SStefano Zampini 86761e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 86771e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 86781e0482f5SStefano Zampini { 86791e0482f5SStefano Zampini Mat At; 86801e0482f5SStefano Zampini IS rows; 86811e0482f5SStefano Zampini PetscInt rst,ren; 86821e0482f5SStefano Zampini PetscErrorCode ierr; 86831e0482f5SStefano Zampini PetscLayout rmap; 86841e0482f5SStefano Zampini 86851e0482f5SStefano Zampini PetscFunctionBegin; 86861e0482f5SStefano Zampini rst = ren = 0; 86871e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 86881e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 86891e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 86901e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 86911e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 86921e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 86931e0482f5SStefano Zampini } 8694e07686f2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),ren-rst,rst,1,&rows);CHKERRQ(ierr); 86957dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 86961e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 86971e0482f5SStefano Zampini 86981e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 86991e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 87001e0482f5SStefano Zampini IS from,to; 87011e0482f5SStefano Zampini Vec gvec; 87021e0482f5SStefano Zampini PetscInt lsize; 87031e0482f5SStefano Zampini 87041e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 87051e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 87061e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 87071e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 87081e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 87091e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 87101e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 87111e0482f5SStefano Zampini ierr = MPI_Comm_size(ccomm,&b->size);CHKERRQ(ierr); 87121e0482f5SStefano Zampini ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRQ(ierr); 87131e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 87141e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 87151e0482f5SStefano Zampini b->A = a->A; 87161e0482f5SStefano Zampini b->B = a->B; 87171e0482f5SStefano Zampini 87181e0482f5SStefano Zampini b->donotstash = a->donotstash; 87191e0482f5SStefano Zampini b->roworiented = a->roworiented; 87201e0482f5SStefano Zampini b->rowindices = 0; 87211e0482f5SStefano Zampini b->rowvalues = 0; 87221e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 87231e0482f5SStefano Zampini 87241e0482f5SStefano Zampini (*B)->rmap = rmap; 87251e0482f5SStefano Zampini (*B)->factortype = A->factortype; 87261e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 87271e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 87281e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 87291e0482f5SStefano Zampini 87301e0482f5SStefano Zampini if (a->colmap) { 87311e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 87321e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 87331e0482f5SStefano Zampini #else 87341e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 87351e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 87361e0482f5SStefano Zampini ierr = PetscMemcpy(b->colmap,a->colmap,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 87371e0482f5SStefano Zampini #endif 87381e0482f5SStefano Zampini } else b->colmap = 0; 87391e0482f5SStefano Zampini if (a->garray) { 87401e0482f5SStefano Zampini PetscInt len; 87411e0482f5SStefano Zampini len = a->B->cmap->n; 87421e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 87431e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 87441e0482f5SStefano Zampini if (len) { ierr = PetscMemcpy(b->garray,a->garray,len*sizeof(PetscInt));CHKERRQ(ierr); } 87451e0482f5SStefano Zampini } else b->garray = 0; 87461e0482f5SStefano Zampini 87471e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 87481e0482f5SStefano Zampini b->lvec = a->lvec; 87491e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 87501e0482f5SStefano Zampini 87511e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 87521e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 87531e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 87541e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 87551e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 87561e0482f5SStefano Zampini ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 87571e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 87581e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 87591e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 87601e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 87611e0482f5SStefano Zampini } 87621e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 87631e0482f5SStefano Zampini PetscFunctionReturn(0); 87641e0482f5SStefano Zampini } 8765