11cf9b237SStefano Zampini #include <../src/mat/impls/aij/seq/aij.h> 2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> 3ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 4*837cedc9SStefano 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 IS *faces,*edges; 1518669cc0f4SStefano Zampini PetscScalar *vals; 1519669cc0f4SStefano Zampini const PetscScalar *array; 1520669cc0f4SStefano Zampini PetscInt i,maxneighs,lmaxneighs,maxsize,nf,ne; 15211ae86dd6SStefano Zampini PetscMPIInt rank; 1522a198735bSStefano Zampini PetscErrorCode ierr; 1523669cc0f4SStefano Zampini 1524669cc0f4SStefano Zampini PetscFunctionBegin; 1525669cc0f4SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1526669cc0f4SStefano Zampini if (graph->twodim) { 1527669cc0f4SStefano Zampini lmaxneighs = 2; 1528669cc0f4SStefano Zampini } else { 1529669cc0f4SStefano Zampini lmaxneighs = 1; 1530669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1531669cc0f4SStefano Zampini const PetscInt *idxs; 1532669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1533669cc0f4SStefano Zampini lmaxneighs = PetscMax(lmaxneighs,graph->count[idxs[0]]); 1534669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1535669cc0f4SStefano Zampini } 1536669cc0f4SStefano Zampini lmaxneighs++; /* graph count does not include self */ 1537669cc0f4SStefano Zampini } 1538669cc0f4SStefano Zampini ierr = MPIU_Allreduce(&lmaxneighs,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 1539669cc0f4SStefano Zampini maxsize = 0; 1540669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1541669cc0f4SStefano Zampini PetscInt nn; 1542669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1543669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1544669cc0f4SStefano Zampini } 1545669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1546669cc0f4SStefano Zampini PetscInt nn; 1547669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1548669cc0f4SStefano Zampini maxsize = PetscMax(maxsize,nn); 1549669cc0f4SStefano Zampini } 1550669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1551669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1552669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 15538ae0ca82SStefano Zampini if (!transpose) { 15548ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 15558ae0ca82SStefano Zampini } else { 15568ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 15578ae0ca82SStefano Zampini } 1558669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 15591ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1560d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1561669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1562ddc40e2cSstefano_zampini ierr = VecLockPop(quad_vecs[i]);CHKERRQ(ierr); 15638ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 1564669cc0f4SStefano Zampini } 1565d8203eabSStefano Zampini 1566669cc0f4SStefano Zampini /* compute local quad vec */ 1567a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 15688ae0ca82SStefano Zampini if (!transpose) { 1569a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 15708ae0ca82SStefano Zampini } else { 15718ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 15728ae0ca82SStefano Zampini } 1573669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 15748ae0ca82SStefano Zampini if (!transpose) { 1575a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 15768ae0ca82SStefano Zampini } else { 15778ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 15788ae0ca82SStefano Zampini } 1579fa23a32eSStefano Zampini if (vl2l) { 1580187c917aSStefano Zampini Mat lA; 1581187c917aSStefano Zampini VecScatter sc; 1582187c917aSStefano Zampini 1583187c917aSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1584187c917aSStefano Zampini ierr = MatCreateVecs(lA,&vins,NULL);CHKERRQ(ierr); 1585187c917aSStefano Zampini ierr = VecScatterCreate(v,vl2l,vins,NULL,&sc);CHKERRQ(ierr); 1586187c917aSStefano Zampini ierr = VecScatterBegin(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1587187c917aSStefano Zampini ierr = VecScatterEnd(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1588187c917aSStefano Zampini ierr = VecScatterDestroy(&sc);CHKERRQ(ierr); 1589fa23a32eSStefano Zampini } else { 1590fa23a32eSStefano Zampini vins = v; 1591fa23a32eSStefano Zampini } 1592fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1593669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 15949a962809SStefano Zampini 15951ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 15961ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1597669cc0f4SStefano Zampini for (i=0;i<nf;i++) { 1598669cc0f4SStefano Zampini const PetscInt *idxs; 1599669cc0f4SStefano Zampini PetscInt idx,nn,j; 1600669cc0f4SStefano Zampini 1601669cc0f4SStefano Zampini ierr = ISGetIndices(faces[i],&idxs);CHKERRQ(ierr); 1602669cc0f4SStefano Zampini ierr = ISGetLocalSize(faces[i],&nn);CHKERRQ(ierr); 1603669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 16041ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1605669cc0f4SStefano Zampini idx = -(idx+1); 1606669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1607669cc0f4SStefano Zampini ierr = ISRestoreIndices(faces[i],&idxs);CHKERRQ(ierr); 1608669cc0f4SStefano Zampini } 1609669cc0f4SStefano Zampini for (i=0;i<ne;i++) { 1610669cc0f4SStefano Zampini const PetscInt *idxs; 1611669cc0f4SStefano Zampini PetscInt idx,nn,j; 1612669cc0f4SStefano Zampini 1613669cc0f4SStefano Zampini ierr = ISGetIndices(edges[i],&idxs);CHKERRQ(ierr); 1614669cc0f4SStefano Zampini ierr = ISGetLocalSize(edges[i],&nn);CHKERRQ(ierr); 1615669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 16161ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1617669cc0f4SStefano Zampini idx = -(idx+1); 1618669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1619669cc0f4SStefano Zampini ierr = ISRestoreIndices(edges[i],&idxs);CHKERRQ(ierr); 1620669cc0f4SStefano Zampini } 1621c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nf,&faces,&ne,&edges,NULL);CHKERRQ(ierr); 1622fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1623fa23a32eSStefano Zampini if (vl2l) { 1624187c917aSStefano Zampini ierr = VecDestroy(&vins);CHKERRQ(ierr); 1625fa23a32eSStefano Zampini } 1626669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1627669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1628669cc0f4SStefano Zampini 1629669cc0f4SStefano Zampini /* assemble near null space */ 1630669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1631669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1632669cc0f4SStefano Zampini } 1633669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1634669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 1635ddc40e2cSstefano_zampini ierr = VecLockPush(quad_vecs[i]);CHKERRQ(ierr); 1636669cc0f4SStefano Zampini } 1637669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1638669cc0f4SStefano Zampini PetscFunctionReturn(0); 1639669cc0f4SStefano Zampini } 1640669cc0f4SStefano Zampini 16417620a527SStefano Zampini PetscErrorCode PCBDDCAddPrimalVerticesLocalIS(PC pc, IS primalv) 16427620a527SStefano Zampini { 16437620a527SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16447620a527SStefano Zampini PetscErrorCode ierr; 16457620a527SStefano Zampini 16467620a527SStefano Zampini PetscFunctionBegin; 16477620a527SStefano Zampini if (primalv) { 16487620a527SStefano Zampini if (pcbddc->user_primal_vertices_local) { 16497620a527SStefano Zampini IS list[2], newp; 16507620a527SStefano Zampini 16517620a527SStefano Zampini list[0] = primalv; 16527620a527SStefano Zampini list[1] = pcbddc->user_primal_vertices_local; 16537620a527SStefano Zampini ierr = ISConcatenate(PetscObjectComm((PetscObject)pc),2,list,&newp);CHKERRQ(ierr); 16547620a527SStefano Zampini ierr = ISSortRemoveDups(newp);CHKERRQ(ierr); 16557620a527SStefano Zampini ierr = ISDestroy(&list[1]);CHKERRQ(ierr); 16567620a527SStefano Zampini pcbddc->user_primal_vertices_local = newp; 16577620a527SStefano Zampini } else { 16587620a527SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 16597620a527SStefano Zampini } 16607620a527SStefano Zampini } 16617620a527SStefano Zampini PetscFunctionReturn(0); 16627620a527SStefano Zampini } 1663669cc0f4SStefano Zampini 16641f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 16651f4df5f7SStefano Zampini { 16661f4df5f7SStefano Zampini PetscErrorCode ierr; 16671f4df5f7SStefano Zampini Vec local,global; 16681f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16691f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 16705c5e10d6SStefano Zampini PetscBool monolithic = PETSC_FALSE; 16711f4df5f7SStefano Zampini 16721f4df5f7SStefano Zampini PetscFunctionBegin; 16735c5e10d6SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC topology options","PC");CHKERRQ(ierr); 16745c5e10d6SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_monolithic","Discard any information on dofs splitting",NULL,monolithic,&monolithic,NULL);CHKERRQ(ierr); 16755c5e10d6SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 16761f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 167721ef3d20SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 16781f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 16795c5e10d6SStefano Zampini if (monolithic) goto boundary; 16805c5e10d6SStefano Zampini 16811f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 16821f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 16831f4df5f7SStefano Zampini PetscInt i; 16841f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16851f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 16861f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16871f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 16881f4df5f7SStefano Zampini } 16891f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 16901f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 16911f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 16921f4df5f7SStefano Zampini } 16931f4df5f7SStefano Zampini } else { 169421ef3d20SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present */ 169521ef3d20SStefano Zampini DM dm; 169621ef3d20SStefano Zampini 169721ef3d20SStefano Zampini ierr = PCGetDM(pc, &dm);CHKERRQ(ierr); 169821ef3d20SStefano Zampini if (!dm) { 169921ef3d20SStefano Zampini ierr = MatGetDM(pc->pmat, &dm);CHKERRQ(ierr); 170021ef3d20SStefano Zampini } 170121ef3d20SStefano Zampini if (dm) { 170221ef3d20SStefano Zampini IS *fields; 170321ef3d20SStefano Zampini PetscInt nf,i; 170421ef3d20SStefano Zampini ierr = DMCreateFieldDecomposition(dm,&nf,NULL,&fields,NULL);CHKERRQ(ierr); 170521ef3d20SStefano Zampini ierr = PetscMalloc1(nf,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 170621ef3d20SStefano Zampini for (i=0;i<nf;i++) { 170721ef3d20SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,fields[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 170821ef3d20SStefano Zampini ierr = ISDestroy(&fields[i]);CHKERRQ(ierr); 170921ef3d20SStefano Zampini } 171021ef3d20SStefano Zampini ierr = PetscFree(fields);CHKERRQ(ierr); 171121ef3d20SStefano Zampini pcbddc->n_ISForDofsLocal = nf; 171221ef3d20SStefano Zampini } else { /* See if MATIS has fields attached by the conversion from MatNest */ 171321ef3d20SStefano Zampini PetscContainer c; 171421ef3d20SStefano Zampini 171521ef3d20SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc->pmat,"_convert_nest_lfields",(PetscObject*)&c);CHKERRQ(ierr); 171621ef3d20SStefano Zampini if (c) { 171721ef3d20SStefano Zampini MatISLocalFields lf; 171821ef3d20SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&lf);CHKERRQ(ierr); 171921ef3d20SStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,lf->nr,lf->rf);CHKERRQ(ierr); 172021ef3d20SStefano Zampini } else { /* fallback, create the default fields if bs > 1 */ 17211f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1722986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 172321ef3d20SStefano Zampini if (i > 1) { 1724986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 17251f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 17261f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 17271f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 17281f4df5f7SStefano Zampini } 17291f4df5f7SStefano Zampini } 173021ef3d20SStefano Zampini } 173121ef3d20SStefano Zampini } 17327a0e7b2cSstefano_zampini } else { 17337a0e7b2cSstefano_zampini PetscInt i; 17347a0e7b2cSstefano_zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 17357a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 17367a0e7b2cSstefano_zampini } 17371f4df5f7SStefano Zampini } 1738986cdee1SStefano Zampini } 17391f4df5f7SStefano Zampini 17405c5e10d6SStefano Zampini boundary: 17411f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 17421f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 17437a0e7b2cSstefano_zampini } else if (pcbddc->DirichletBoundariesLocal) { 17447a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 17451f4df5f7SStefano Zampini } 17461f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 17471f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 17487a0e7b2cSstefano_zampini } else if (pcbddc->NeumannBoundariesLocal) { 17497a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 17501f4df5f7SStefano Zampini } 17511f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 17521f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 17531f4df5f7SStefano Zampini } 17541f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 17551f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 17567620a527SStefano Zampini /* detect local disconnected subdomains if requested (use matis->A) */ 17577620a527SStefano Zampini if (pcbddc->detect_disconnected) { 17587620a527SStefano Zampini IS primalv = NULL; 17597620a527SStefano Zampini PetscInt i; 17607a0e7b2cSstefano_zampini 17617620a527SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 17627620a527SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 17637620a527SStefano Zampini } 17647620a527SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 17657620a527SStefano Zampini ierr = PCBDDCDetectDisconnectedComponents(pc,&pcbddc->n_local_subs,&pcbddc->local_subs,&primalv);CHKERRQ(ierr); 17667620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 17677620a527SStefano Zampini ierr = ISDestroy(&primalv);CHKERRQ(ierr); 17687620a527SStefano Zampini } 17697620a527SStefano Zampini /* early stage corner detection */ 17707620a527SStefano Zampini { 17717620a527SStefano Zampini DM dm; 17727620a527SStefano Zampini 17737620a527SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 17747620a527SStefano Zampini if (dm) { 17757620a527SStefano Zampini PetscBool isda; 17767620a527SStefano Zampini 17777620a527SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&isda);CHKERRQ(ierr); 17787620a527SStefano Zampini if (isda) { 17797620a527SStefano Zampini ISLocalToGlobalMapping l2l; 17807620a527SStefano Zampini IS corners; 17817620a527SStefano Zampini Mat lA; 17827620a527SStefano Zampini 1783d4a6ed37SStefano Zampini ierr = DMDAGetSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17847620a527SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17857620a527SStefano Zampini ierr = MatGetLocalToGlobalMapping(lA,&l2l,NULL);CHKERRQ(ierr); 17867620a527SStefano Zampini ierr = MatISRestoreLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17877620a527SStefano Zampini if (l2l) { 17887620a527SStefano Zampini const PetscInt *idx; 17897620a527SStefano Zampini PetscInt bs,*idxout,n; 17907620a527SStefano Zampini 17917620a527SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(l2l,&bs);CHKERRQ(ierr); 17927620a527SStefano Zampini ierr = ISGetLocalSize(corners,&n);CHKERRQ(ierr); 17937620a527SStefano Zampini ierr = ISGetIndices(corners,&idx);CHKERRQ(ierr); 17947620a527SStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 17957620a527SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(l2l,n,idx,idxout);CHKERRQ(ierr); 17967620a527SStefano Zampini ierr = ISRestoreIndices(corners,&idx);CHKERRQ(ierr); 1797d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17987620a527SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)pc),bs,n,idxout,PETSC_OWN_POINTER,&corners);CHKERRQ(ierr); 17997620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,corners);CHKERRQ(ierr); 18007620a527SStefano Zampini ierr = ISDestroy(&corners);CHKERRQ(ierr); 18017620a527SStefano Zampini } else { /* not from DMDA */ 1802d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 18037620a527SStefano Zampini } 18047620a527SStefano Zampini } 18057620a527SStefano Zampini } 18067620a527SStefano Zampini } 18077a0e7b2cSstefano_zampini PetscFunctionReturn(0); 18087a0e7b2cSstefano_zampini } 18097a0e7b2cSstefano_zampini 18107a0e7b2cSstefano_zampini PetscErrorCode PCBDDCConsistencyCheckIS(PC pc, MPI_Op mop, IS *is) 18117a0e7b2cSstefano_zampini { 18127a0e7b2cSstefano_zampini Mat_IS *matis = (Mat_IS*)(pc->pmat->data); 18137a0e7b2cSstefano_zampini PetscErrorCode ierr; 18147a0e7b2cSstefano_zampini IS nis; 18157a0e7b2cSstefano_zampini const PetscInt *idxs; 18167a0e7b2cSstefano_zampini PetscInt i,nd,n = matis->A->rmap->n,*nidxs,nnd; 18177a0e7b2cSstefano_zampini PetscBool *ld; 18187a0e7b2cSstefano_zampini 18197a0e7b2cSstefano_zampini PetscFunctionBegin; 18207a0e7b2cSstefano_zampini if (mop != MPI_LAND && mop != MPI_LOR) SETERRQ(PetscObjectComm((PetscObject)(pc)),PETSC_ERR_SUP,"Supported are MPI_LAND and MPI_LOR"); 18217a0e7b2cSstefano_zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 18227a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18237a0e7b2cSstefano_zampini /* init rootdata with true */ 18247a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_rootdata; 18257a0e7b2cSstefano_zampini for (i=0;i<pc->pmat->rmap->n;i++) ld[i] = PETSC_TRUE; 18267a0e7b2cSstefano_zampini } else { 18277a0e7b2cSstefano_zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscBool));CHKERRQ(ierr); 18287a0e7b2cSstefano_zampini } 18297a0e7b2cSstefano_zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscBool));CHKERRQ(ierr); 18307a0e7b2cSstefano_zampini ierr = ISGetLocalSize(*is,&nd);CHKERRQ(ierr); 18317a0e7b2cSstefano_zampini ierr = ISGetIndices(*is,&idxs);CHKERRQ(ierr); 18327a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_leafdata; 18337a0e7b2cSstefano_zampini for (i=0;i<nd;i++) 18347a0e7b2cSstefano_zampini if (-1 < idxs[i] && idxs[i] < n) 18357a0e7b2cSstefano_zampini ld[idxs[i]] = PETSC_TRUE; 18367a0e7b2cSstefano_zampini ierr = ISRestoreIndices(*is,&idxs);CHKERRQ(ierr); 18377a0e7b2cSstefano_zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18387a0e7b2cSstefano_zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18397a0e7b2cSstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18407a0e7b2cSstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18417a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18427a0e7b2cSstefano_zampini ierr = PetscMalloc1(nd,&nidxs);CHKERRQ(ierr); 18437a0e7b2cSstefano_zampini } else { 18447a0e7b2cSstefano_zampini ierr = PetscMalloc1(n,&nidxs);CHKERRQ(ierr); 18457a0e7b2cSstefano_zampini } 18467a0e7b2cSstefano_zampini for (i=0,nnd=0;i<n;i++) 18477a0e7b2cSstefano_zampini if (ld[i]) 18487a0e7b2cSstefano_zampini nidxs[nnd++] = i; 18497a0e7b2cSstefano_zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(*is)),nnd,nidxs,PETSC_OWN_POINTER,&nis);CHKERRQ(ierr); 18507a0e7b2cSstefano_zampini ierr = ISDestroy(is);CHKERRQ(ierr); 18517a0e7b2cSstefano_zampini *is = nis; 18521f4df5f7SStefano Zampini PetscFunctionReturn(0); 18531f4df5f7SStefano Zampini } 18541f4df5f7SStefano Zampini 18553e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 18563e589ea0SStefano Zampini { 18573e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 18583e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 18593e589ea0SStefano Zampini PetscErrorCode ierr; 18603e589ea0SStefano Zampini 18613e589ea0SStefano Zampini PetscFunctionBegin; 18623e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 18633e589ea0SStefano Zampini PetscFunctionReturn(0); 18643e589ea0SStefano Zampini } 18653e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18663e589ea0SStefano Zampini Vec swap; 18673e589ea0SStefano Zampini 18683e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 18693e589ea0SStefano Zampini swap = pcbddc->work_change; 18703e589ea0SStefano Zampini pcbddc->work_change = r; 18713e589ea0SStefano Zampini r = swap; 18723e589ea0SStefano Zampini } 18733e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18743e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18753e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 18763e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 18773e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18783e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18793e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1880f913dca9SStefano Zampini pcbddc->work_change = r; 18813e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 18823e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 18833e589ea0SStefano Zampini } 18843e589ea0SStefano Zampini PetscFunctionReturn(0); 18853e589ea0SStefano Zampini } 18863e589ea0SStefano Zampini 1887a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1888a3df083aSStefano Zampini { 1889a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1890a3df083aSStefano Zampini PetscErrorCode ierr; 1891a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1892a3df083aSStefano Zampini 1893a3df083aSStefano Zampini PetscFunctionBegin; 1894a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1895a3df083aSStefano Zampini if (transpose) { 1896a3df083aSStefano Zampini apply_right = ctx->apply_left; 1897a3df083aSStefano Zampini apply_left = ctx->apply_right; 1898a3df083aSStefano Zampini } else { 1899a3df083aSStefano Zampini apply_right = ctx->apply_right; 1900a3df083aSStefano Zampini apply_left = ctx->apply_left; 1901a3df083aSStefano Zampini } 1902a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1903a3df083aSStefano Zampini if (apply_right) { 1904a3df083aSStefano Zampini const PetscScalar *ax; 1905a3df083aSStefano Zampini PetscInt nl,i; 1906a3df083aSStefano Zampini 1907a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1908a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1909a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1910a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1911a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1912a3df083aSStefano Zampini PetscScalar sum,val; 1913a3df083aSStefano Zampini const PetscInt *idxs; 1914a3df083aSStefano Zampini PetscInt nz,j; 1915a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1916a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1917a3df083aSStefano Zampini sum = 0.; 1918a3df083aSStefano Zampini if (ctx->apply_p0) { 1919a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1920a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1921a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1922a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1923a3df083aSStefano Zampini } 1924a3df083aSStefano Zampini } else { 1925a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1926a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1927a3df083aSStefano Zampini } 1928a3df083aSStefano Zampini } 1929a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1930a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1931a3df083aSStefano Zampini } 1932a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1933a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1934a3df083aSStefano Zampini } 1935a3df083aSStefano Zampini if (transpose) { 1936a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1937a3df083aSStefano Zampini } else { 1938a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1939a3df083aSStefano Zampini } 1940a3df083aSStefano Zampini if (reset_x) { 1941a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1942a3df083aSStefano Zampini } 1943a3df083aSStefano Zampini if (apply_left) { 1944a3df083aSStefano Zampini PetscScalar *ay; 1945a3df083aSStefano Zampini PetscInt i; 1946a3df083aSStefano Zampini 1947a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1948a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1949a3df083aSStefano Zampini PetscScalar sum,val; 1950a3df083aSStefano Zampini const PetscInt *idxs; 1951a3df083aSStefano Zampini PetscInt nz,j; 1952a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1953a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1954a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1955a3df083aSStefano Zampini if (ctx->apply_p0) { 1956a3df083aSStefano Zampini sum = 0.; 1957a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1958a3df083aSStefano Zampini sum += ay[idxs[j]]; 1959a3df083aSStefano Zampini ay[idxs[j]] += val; 1960a3df083aSStefano Zampini } 1961a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1962a3df083aSStefano Zampini } else { 1963a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1964a3df083aSStefano Zampini ay[idxs[j]] += val; 1965a3df083aSStefano Zampini } 1966a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1967a3df083aSStefano Zampini } 1968a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1969a3df083aSStefano Zampini } 1970a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1971a3df083aSStefano Zampini } 1972a3df083aSStefano Zampini PetscFunctionReturn(0); 1973a3df083aSStefano Zampini } 1974a3df083aSStefano Zampini 1975a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1976a3df083aSStefano Zampini { 1977a3df083aSStefano Zampini PetscErrorCode ierr; 1978a3df083aSStefano Zampini 1979a3df083aSStefano Zampini PetscFunctionBegin; 1980a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1981a3df083aSStefano Zampini PetscFunctionReturn(0); 1982a3df083aSStefano Zampini } 1983a3df083aSStefano Zampini 1984a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1985a3df083aSStefano Zampini { 1986a3df083aSStefano Zampini PetscErrorCode ierr; 1987a3df083aSStefano Zampini 1988a3df083aSStefano Zampini PetscFunctionBegin; 1989a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1990a3df083aSStefano Zampini PetscFunctionReturn(0); 1991a3df083aSStefano Zampini } 1992a3df083aSStefano Zampini 1993a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1994a3df083aSStefano Zampini { 1995a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1996a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1997a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1998a3df083aSStefano Zampini PetscErrorCode ierr; 1999a3df083aSStefano Zampini 2000a3df083aSStefano Zampini PetscFunctionBegin; 2001a3df083aSStefano Zampini if (!restore) { 20021dd7afcfSStefano Zampini Mat A_IB,A_BI; 2003a3df083aSStefano Zampini PetscScalar *work; 2004b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 2005a3df083aSStefano Zampini 20069a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 20079a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 2008a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 2009a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 2010a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2011a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 2012a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 2013a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 2014a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 2015a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 2016a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 2017a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 2018a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 2019a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 2020059032f7SStefano Zampini if (reuse) { 2021a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 20221dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 2023059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 2024059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 2025059032f7SStefano Zampini PetscInt i; 2026059032f7SStefano Zampini 2027059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 2028059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2029059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2030059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2031059032f7SStefano Zampini } 2032059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 20331dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 2034059032f7SStefano Zampini } 2035a3df083aSStefano Zampini ctx->A = pcis->A_IB; 2036a3df083aSStefano Zampini ctx->work = work; 2037a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 2038a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2039a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2040a3df083aSStefano Zampini pcis->A_IB = A_IB; 2041a3df083aSStefano Zampini 2042a3df083aSStefano Zampini /* A_BI as A_IB^T */ 2043a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 2044a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 2045a3df083aSStefano Zampini pcis->A_BI = A_BI; 2046a3df083aSStefano Zampini } else { 20471dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 20481dd7afcfSStefano Zampini PetscFunctionReturn(0); 20491dd7afcfSStefano Zampini } 2050a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 2051a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 2052a3df083aSStefano Zampini pcis->A_IB = ctx->A; 20531dd7afcfSStefano Zampini ctx->A = NULL; 20541dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 20551dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 20561dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 20571dd7afcfSStefano Zampini if (ctx->free) { 2058059032f7SStefano Zampini PetscInt i; 20591dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 2060059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2061059032f7SStefano Zampini } 2062059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2063059032f7SStefano Zampini } 2064a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 2065a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 2066a3df083aSStefano Zampini } 2067a3df083aSStefano Zampini PetscFunctionReturn(0); 2068a3df083aSStefano Zampini } 2069a3df083aSStefano Zampini 2070a3df083aSStefano Zampini /* used just in bddc debug mode */ 2071a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 2072a3df083aSStefano Zampini { 2073a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2074a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2075a3df083aSStefano Zampini Mat An; 2076a3df083aSStefano Zampini PetscErrorCode ierr; 2077a3df083aSStefano Zampini 2078a3df083aSStefano Zampini PetscFunctionBegin; 2079a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 2080a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 2081a3df083aSStefano Zampini if (is1) { 20827dae84e0SHong Zhang ierr = MatCreateSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 2083a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 2084a3df083aSStefano Zampini } else { 2085a3df083aSStefano Zampini *B = An; 2086a3df083aSStefano Zampini } 2087a3df083aSStefano Zampini PetscFunctionReturn(0); 2088a3df083aSStefano Zampini } 2089a3df083aSStefano Zampini 20901cf9b237SStefano Zampini /* TODO: add reuse flag */ 20911cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 20921cf9b237SStefano Zampini { 20931cf9b237SStefano Zampini Mat Bt; 20941cf9b237SStefano Zampini PetscScalar *a,*bdata; 20951cf9b237SStefano Zampini const PetscInt *ii,*ij; 20961cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 20971cf9b237SStefano Zampini PetscBool flg_row; 20981cf9b237SStefano Zampini PetscErrorCode ierr; 20991cf9b237SStefano Zampini 21001cf9b237SStefano Zampini PetscFunctionBegin; 21011cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 21021cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 21031cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 21041cf9b237SStefano Zampini nnz = n; 21051cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 21061cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 21071cf9b237SStefano Zampini } 21081cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 21091cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 21101cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 21111cf9b237SStefano Zampini nnz = 0; 21121cf9b237SStefano Zampini bii[0] = 0; 21131cf9b237SStefano Zampini for (i=0;i<n;i++) { 21141cf9b237SStefano Zampini PetscInt j; 21151cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 21161cf9b237SStefano Zampini PetscScalar entry = a[j]; 21171cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || ij[j] == i) { 21181cf9b237SStefano Zampini bij[nnz] = ij[j]; 21191cf9b237SStefano Zampini bdata[nnz] = entry; 21201cf9b237SStefano Zampini nnz++; 21211cf9b237SStefano Zampini } 21221cf9b237SStefano Zampini } 21231cf9b237SStefano Zampini bii[i+1] = nnz; 21241cf9b237SStefano Zampini } 21251cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 21261cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 21271cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 21281cf9b237SStefano Zampini { 21291cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 21301cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 21311cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 21321cf9b237SStefano Zampini } 21331cf9b237SStefano Zampini *B = Bt; 21341cf9b237SStefano Zampini PetscFunctionReturn(0); 21351cf9b237SStefano Zampini } 21361cf9b237SStefano Zampini 2137c80a6c00SStefano Zampini PetscErrorCode PCBDDCDetectDisconnectedComponents(PC pc, PetscInt *ncc, IS* cc[], IS* primalv) 21384f1b2e48SStefano Zampini { 2139c80a6c00SStefano Zampini Mat B = NULL; 2140c80a6c00SStefano Zampini DM dm; 21414f1b2e48SStefano Zampini IS is_dummy,*cc_n; 21424f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 21434f1b2e48SStefano Zampini PCBDDCGraph graph; 2144c80a6c00SStefano Zampini PetscInt *xadj_filtered = NULL,*adjncy_filtered = NULL; 21454f1b2e48SStefano Zampini PetscInt i,n; 21464f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 2147c80a6c00SStefano Zampini PetscBool isplex = PETSC_FALSE; 21484f1b2e48SStefano Zampini PetscErrorCode ierr; 21494f1b2e48SStefano Zampini 21504f1b2e48SStefano Zampini PetscFunctionBegin; 2151a2eca866SStefano Zampini if (ncc) *ncc = 0; 2152a2eca866SStefano Zampini if (cc) *cc = NULL; 2153a2eca866SStefano Zampini if (primalv) *primalv = NULL; 2154c80a6c00SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 2155c80a6c00SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 2156c80a6c00SStefano Zampini if (!dm) { 2157c80a6c00SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 2158c80a6c00SStefano Zampini } 2159c80a6c00SStefano Zampini if (dm) { 2160c80a6c00SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMPLEX,&isplex);CHKERRQ(ierr); 2161c80a6c00SStefano Zampini } 2162c80a6c00SStefano Zampini if (isplex) { /* this code has been modified from plexpartition.c */ 2163c80a6c00SStefano Zampini PetscInt p, pStart, pEnd, a, adjSize, idx, size, nroots; 2164c80a6c00SStefano Zampini PetscInt *adj = NULL; 2165c80a6c00SStefano Zampini IS cellNumbering; 2166c80a6c00SStefano Zampini const PetscInt *cellNum; 2167c80a6c00SStefano Zampini PetscBool useCone, useClosure; 2168c80a6c00SStefano Zampini PetscSection section; 2169c80a6c00SStefano Zampini PetscSegBuffer adjBuffer; 2170c80a6c00SStefano Zampini PetscSF sfPoint; 2171c80a6c00SStefano Zampini PetscErrorCode ierr; 2172c80a6c00SStefano Zampini 2173c80a6c00SStefano Zampini PetscFunctionBegin; 2174c80a6c00SStefano Zampini ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 2175c80a6c00SStefano Zampini ierr = DMGetPointSF(dm, &sfPoint);CHKERRQ(ierr); 2176c80a6c00SStefano Zampini ierr = PetscSFGetGraph(sfPoint, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 2177c80a6c00SStefano Zampini /* Build adjacency graph via a section/segbuffer */ 2178c80a6c00SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), §ion);CHKERRQ(ierr); 2179c80a6c00SStefano Zampini ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 2180c80a6c00SStefano Zampini ierr = PetscSegBufferCreate(sizeof(PetscInt),1000,&adjBuffer);CHKERRQ(ierr); 2181c80a6c00SStefano Zampini /* Always use FVM adjacency to create partitioner graph */ 2182c80a6c00SStefano Zampini ierr = DMPlexGetAdjacencyUseCone(dm, &useCone);CHKERRQ(ierr); 2183c80a6c00SStefano Zampini ierr = DMPlexGetAdjacencyUseClosure(dm, &useClosure);CHKERRQ(ierr); 2184c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseCone(dm, PETSC_TRUE);CHKERRQ(ierr); 2185c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseClosure(dm, PETSC_FALSE);CHKERRQ(ierr); 2186956e2312SStefano Zampini ierr = DMPlexGetCellNumbering(dm, &cellNumbering);CHKERRQ(ierr); 2187c80a6c00SStefano Zampini ierr = ISGetIndices(cellNumbering, &cellNum);CHKERRQ(ierr); 2188c80a6c00SStefano Zampini for (n = 0, p = pStart; p < pEnd; p++) { 2189c80a6c00SStefano Zampini /* Skip non-owned cells in parallel (ParMetis expects no overlap) */ 2190c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2191c80a6c00SStefano Zampini adjSize = PETSC_DETERMINE; 2192c80a6c00SStefano Zampini ierr = DMPlexGetAdjacency(dm, p, &adjSize, &adj);CHKERRQ(ierr); 2193c80a6c00SStefano Zampini for (a = 0; a < adjSize; ++a) { 2194c80a6c00SStefano Zampini const PetscInt point = adj[a]; 21955cef3d0dSStefano Zampini if (pStart <= point && point < pEnd) { 2196c80a6c00SStefano Zampini PetscInt *PETSC_RESTRICT pBuf; 2197c80a6c00SStefano Zampini ierr = PetscSectionAddDof(section, p, 1);CHKERRQ(ierr); 2198c80a6c00SStefano Zampini ierr = PetscSegBufferGetInts(adjBuffer, 1, &pBuf);CHKERRQ(ierr); 2199c80a6c00SStefano Zampini *pBuf = point; 2200c80a6c00SStefano Zampini } 2201c80a6c00SStefano Zampini } 2202c80a6c00SStefano Zampini n++; 2203c80a6c00SStefano Zampini } 2204c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseCone(dm, useCone);CHKERRQ(ierr); 2205c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseClosure(dm, useClosure);CHKERRQ(ierr); 2206c80a6c00SStefano Zampini /* Derive CSR graph from section/segbuffer */ 2207c80a6c00SStefano Zampini ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 2208c80a6c00SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 2209c80a6c00SStefano Zampini ierr = PetscMalloc1(n+1, &xadj);CHKERRQ(ierr); 2210c80a6c00SStefano Zampini for (idx = 0, p = pStart; p < pEnd; p++) { 2211c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2212c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(section, p, &(xadj[idx++]));CHKERRQ(ierr); 2213c80a6c00SStefano Zampini } 2214c80a6c00SStefano Zampini xadj[n] = size; 2215c80a6c00SStefano Zampini ierr = PetscSegBufferExtractAlloc(adjBuffer, &adjncy);CHKERRQ(ierr); 2216c80a6c00SStefano Zampini /* Clean up */ 2217c80a6c00SStefano Zampini ierr = PetscSegBufferDestroy(&adjBuffer);CHKERRQ(ierr); 2218c80a6c00SStefano Zampini ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 2219c80a6c00SStefano Zampini ierr = PetscFree(adj);CHKERRQ(ierr); 2220c80a6c00SStefano Zampini graph->xadj = xadj; 2221c80a6c00SStefano Zampini graph->adjncy = adjncy; 2222c80a6c00SStefano Zampini } else { 2223c80a6c00SStefano Zampini Mat A; 2224c80a6c00SStefano Zampini PetscBool filter = PETSC_FALSE, isseqaij, flg_row; 2225c80a6c00SStefano Zampini 2226c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 222763c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 2228a2eca866SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 222963c961adSStefano Zampini PetscFunctionReturn(0); 223063c961adSStefano Zampini } 22314f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 22324f1b2e48SStefano Zampini if (!isseqaij && filter) { 22331cf9b237SStefano Zampini PetscBool isseqdense; 22341cf9b237SStefano Zampini 22351cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 22361cf9b237SStefano Zampini if (!isseqdense) { 22374f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 22381cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 22391cf9b237SStefano Zampini PetscScalar *array; 22401cf9b237SStefano Zampini PetscReal chop=1.e-6; 22411cf9b237SStefano Zampini 22421cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 22431cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 22441cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 22451cf9b237SStefano Zampini for (i=0;i<n;i++) { 22461cf9b237SStefano Zampini PetscInt j; 22471cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 22481cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 22491cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 22501cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 22511cf9b237SStefano Zampini } 22521cf9b237SStefano Zampini } 22531cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 22549d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 22551cf9b237SStefano Zampini } 22564f1b2e48SStefano Zampini } else { 2257c80a6c00SStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22584f1b2e48SStefano Zampini B = A; 22594f1b2e48SStefano Zampini } 22604f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 22614f1b2e48SStefano Zampini 22624f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 22634f1b2e48SStefano Zampini if (filter) { 22644f1b2e48SStefano Zampini PetscScalar *data; 22654f1b2e48SStefano Zampini PetscInt j,cum; 22664f1b2e48SStefano Zampini 22674f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 22684f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 22694f1b2e48SStefano Zampini cum = 0; 22704f1b2e48SStefano Zampini for (i=0;i<n;i++) { 22714f1b2e48SStefano Zampini PetscInt t; 22724f1b2e48SStefano Zampini 22734f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 22744f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 22754f1b2e48SStefano Zampini continue; 22764f1b2e48SStefano Zampini } 22774f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 22784f1b2e48SStefano Zampini } 22794f1b2e48SStefano Zampini t = xadj_filtered[i]; 22804f1b2e48SStefano Zampini xadj_filtered[i] = cum; 22814f1b2e48SStefano Zampini cum += t; 22824f1b2e48SStefano Zampini } 22834f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 22844f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 22854f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 22864f1b2e48SStefano Zampini } else { 22874f1b2e48SStefano Zampini graph->xadj = xadj; 22884f1b2e48SStefano Zampini graph->adjncy = adjncy; 22894f1b2e48SStefano Zampini } 2290c80a6c00SStefano Zampini } 2291c80a6c00SStefano Zampini /* compute local connected components using PCBDDCGraph */ 2292c80a6c00SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 2293c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 2294c80a6c00SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2295c80a6c00SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 2296c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 22974f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 22984f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 2299c80a6c00SStefano Zampini 23004f1b2e48SStefano Zampini /* partial clean up */ 23014f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 2302c80a6c00SStefano Zampini if (B) { 2303c80a6c00SStefano Zampini PetscBool flg_row; 23044f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 23054f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 23064f1b2e48SStefano Zampini } 2307c80a6c00SStefano Zampini if (isplex) { 2308c80a6c00SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 2309c80a6c00SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 2310c80a6c00SStefano Zampini } 23114f1b2e48SStefano Zampini 23124f1b2e48SStefano Zampini /* get back data */ 2313c80a6c00SStefano Zampini if (isplex) { 2314c80a6c00SStefano Zampini if (ncc) *ncc = graph->ncc; 2315c80a6c00SStefano Zampini if (cc || primalv) { 2316c80a6c00SStefano Zampini Mat A; 2317c80a6c00SStefano Zampini PetscBT btv,btvt; 2318c80a6c00SStefano Zampini PetscSection subSection; 2319c80a6c00SStefano Zampini PetscInt *ids,cum,cump,*cids,*pids; 2320c80a6c00SStefano Zampini 2321c80a6c00SStefano Zampini ierr = DMPlexGetSubdomainSection(dm,&subSection);CHKERRQ(ierr); 2322c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 2323c80a6c00SStefano Zampini ierr = PetscMalloc3(A->rmap->n,&ids,graph->ncc+1,&cids,A->rmap->n,&pids);CHKERRQ(ierr); 2324c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btv);CHKERRQ(ierr); 2325c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btvt);CHKERRQ(ierr); 2326c80a6c00SStefano Zampini 2327c80a6c00SStefano Zampini cids[0] = 0; 2328c80a6c00SStefano Zampini for (i = 0, cump = 0, cum = 0; i < graph->ncc; i++) { 2329c80a6c00SStefano Zampini PetscInt j; 2330c80a6c00SStefano Zampini 2331c80a6c00SStefano Zampini ierr = PetscBTMemzero(A->rmap->n,btvt);CHKERRQ(ierr); 2332c80a6c00SStefano Zampini for (j = graph->cptr[i]; j < graph->cptr[i+1]; j++) { 2333c80a6c00SStefano Zampini PetscInt k, size, *closure = NULL, cell = graph->queue[j]; 2334c80a6c00SStefano Zampini 2335c80a6c00SStefano Zampini ierr = DMPlexGetTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2336c80a6c00SStefano Zampini for (k = 0; k < 2*size; k += 2) { 2337c80a6c00SStefano Zampini PetscInt s, p = closure[k], off, dof, cdof; 2338c80a6c00SStefano Zampini 2339c80a6c00SStefano Zampini ierr = PetscSectionGetConstraintDof(subSection, p, &cdof);CHKERRQ(ierr); 2340c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(subSection,p,&off);CHKERRQ(ierr); 2341c80a6c00SStefano Zampini ierr = PetscSectionGetDof(subSection,p,&dof);CHKERRQ(ierr); 2342c80a6c00SStefano Zampini for (s = 0; s < dof-cdof; s++) { 2343c80a6c00SStefano Zampini if (PetscBTLookupSet(btvt,off+s)) continue; 2344c80a6c00SStefano Zampini if (!PetscBTLookup(btv,off+s)) { 2345c80a6c00SStefano Zampini ids[cum++] = off+s; 2346c80a6c00SStefano Zampini } else { /* cross-vertex */ 2347c80a6c00SStefano Zampini pids[cump++] = off+s; 2348c80a6c00SStefano Zampini } 2349c80a6c00SStefano Zampini } 2350c80a6c00SStefano Zampini } 2351c80a6c00SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2352c80a6c00SStefano Zampini } 2353c80a6c00SStefano Zampini cids[i+1] = cum; 2354c80a6c00SStefano Zampini /* mark dofs as already assigned */ 2355c80a6c00SStefano Zampini for (j = cids[i]; j < cids[i+1]; j++) { 2356c80a6c00SStefano Zampini ierr = PetscBTSet(btv,ids[j]);CHKERRQ(ierr); 2357c80a6c00SStefano Zampini } 2358c80a6c00SStefano Zampini } 2359c80a6c00SStefano Zampini if (cc) { 2360c80a6c00SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 2361c80a6c00SStefano Zampini for (i = 0; i < graph->ncc; i++) { 2362c80a6c00SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cids[i+1]-cids[i],ids+cids[i],PETSC_COPY_VALUES,&cc_n[i]);CHKERRQ(ierr); 2363c80a6c00SStefano Zampini } 2364c80a6c00SStefano Zampini *cc = cc_n; 2365c80a6c00SStefano Zampini } 2366c80a6c00SStefano Zampini if (primalv) { 2367c80a6c00SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),cump,pids,PETSC_COPY_VALUES,primalv);CHKERRQ(ierr); 2368c80a6c00SStefano Zampini } 2369c80a6c00SStefano Zampini ierr = PetscFree3(ids,cids,pids);CHKERRQ(ierr); 2370c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 2371c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btvt);CHKERRQ(ierr); 2372c80a6c00SStefano Zampini } 2373c80a6c00SStefano Zampini } else { 23741cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 23751cf9b237SStefano Zampini if (cc) { 23764f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 23774f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 23784f1b2e48SStefano 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); 23794f1b2e48SStefano Zampini } 23804f1b2e48SStefano Zampini *cc = cc_n; 23811cf9b237SStefano Zampini } 2382c80a6c00SStefano Zampini } 23834f1b2e48SStefano Zampini /* clean up graph */ 23844f1b2e48SStefano Zampini graph->xadj = 0; 23854f1b2e48SStefano Zampini graph->adjncy = 0; 23864f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 23874f1b2e48SStefano Zampini PetscFunctionReturn(0); 23884f1b2e48SStefano Zampini } 23894f1b2e48SStefano Zampini 23905408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 23915408967cSStefano Zampini { 23925408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 23935408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2394dee84bffSStefano Zampini IS dirIS = NULL; 23954f1b2e48SStefano Zampini PetscInt i; 23965408967cSStefano Zampini PetscErrorCode ierr; 23975408967cSStefano Zampini 23985408967cSStefano Zampini PetscFunctionBegin; 2399dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 24005408967cSStefano Zampini if (zerodiag) { 24015408967cSStefano Zampini Mat A; 24025408967cSStefano Zampini Vec vec3_N; 24035408967cSStefano Zampini PetscScalar *vals; 24045408967cSStefano Zampini const PetscInt *idxs; 2405d12d3064SStefano Zampini PetscInt nz,*count; 24065408967cSStefano Zampini 24075408967cSStefano Zampini /* p0 */ 24085408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 24095408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 24105408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 24115408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 24124f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 24135408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24145408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 24155408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 24165408967cSStefano Zampini /* v_I */ 24175408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 24185408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 24195408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24205408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 24215408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 24225408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 24235408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24245408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 24255408967cSStefano Zampini if (dirIS) { 24265408967cSStefano Zampini PetscInt n; 24275408967cSStefano Zampini 24285408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 24295408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 24305408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 24315408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24325408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 24335408967cSStefano Zampini } 24345408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 24355408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 24365408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 24375408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2438669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 24395408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 24405408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 24419a962809SStefano 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])); 24425408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 24435408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2444d12d3064SStefano Zampini 2445d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 2446d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 2447d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2448d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 2449d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2450d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 24519a962809SStefano 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]); 2452d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2453d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 24545408967cSStefano Zampini } 2455dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 24565408967cSStefano Zampini 24575408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 24585408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 24594f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 24605408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 24614f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 24625408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2463f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2464f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 246513903a91SSatish 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); 2466f2a566d8SStefano Zampini } 24675408967cSStefano Zampini PetscFunctionReturn(0); 24685408967cSStefano Zampini } 24695408967cSStefano Zampini 2470339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 2471339f8db1SStefano Zampini { 2472339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 24734edc6404Sstefano_zampini IS pressures,zerodiag,zerodiag_save,*zerodiag_subs; 2474b0f5fe93SStefano Zampini PetscInt nz,n; 24754edc6404Sstefano_zampini PetscInt *interior_dofs,n_interior_dofs,nneu; 24764edc6404Sstefano_zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag,checkb; 2477339f8db1SStefano Zampini PetscErrorCode ierr; 2478339f8db1SStefano Zampini 2479339f8db1SStefano Zampini PetscFunctionBegin; 24809f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 24819f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 2482a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 2483a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 2484a3df083aSStefano Zampini } 2485a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2486a3df083aSStefano Zampini pcbddc->benign_n = 0; 248728b8efb1Sstefano_zampini 248828b8efb1Sstefano_zampini /* if a local info on dofs is present, uses the last field for "pressures" (or fid by command line) 24894f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 24904f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 24914f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 24921ae86dd6SStefano Zampini since the local Schur complements are already SPD 24934f1b2e48SStefano Zampini */ 24944f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 24954f1b2e48SStefano Zampini have_null = PETSC_TRUE; 249640fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 24977fbe2174Sstefano_zampini IS iP = NULL; 24984f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 24994f1b2e48SStefano Zampini 250028b8efb1Sstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC benign options","PC");CHKERRQ(ierr); 250128b8efb1Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_pressure_field","Field id for pressures",NULL,p,&p,NULL);CHKERRQ(ierr); 250228b8efb1Sstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 250328b8efb1Sstefano_zampini if (p < 0 || p > pcbddc->n_ISForDofsLocal-1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Invalid field id for pressures %D",p); 25044f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 25054f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 25064f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 25074f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 2508ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 25097fbe2174Sstefano_zampini /* remove zeroed out pressures if we are setting up a BDDC solver for a saddle-point FETI-DP */ 25107fbe2174Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP",(PetscObject*)&iP);CHKERRQ(ierr); 25117fbe2174Sstefano_zampini if (iP) { 25127fbe2174Sstefano_zampini IS newpressures; 25137fbe2174Sstefano_zampini 25147fbe2174Sstefano_zampini ierr = ISDifference(pressures,iP,&newpressures);CHKERRQ(ierr); 25157fbe2174Sstefano_zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 25167fbe2174Sstefano_zampini pressures = newpressures; 25177fbe2174Sstefano_zampini } 251840fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 251940fa8d13SStefano Zampini if (!sorted) { 252040fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 252140fa8d13SStefano Zampini } 252240fa8d13SStefano Zampini } else { 252340fa8d13SStefano Zampini pressures = NULL; 252440fa8d13SStefano Zampini } 252597d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 252697d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 252727b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 252897d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 2529339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 2530339f8db1SStefano Zampini if (!sorted) { 2531339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 2532339f8db1SStefano Zampini } 25334edc6404Sstefano_zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 25344edc6404Sstefano_zampini zerodiag_save = zerodiag; 2535339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 25364f1b2e48SStefano Zampini if (!nz) { 25374f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 25384f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 253940fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 254040fa8d13SStefano Zampini } 25414f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 25424f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 25434f1b2e48SStefano Zampini zerodiag_subs = NULL; 25444f1b2e48SStefano Zampini pcbddc->benign_n = 0; 25451f4df5f7SStefano Zampini n_interior_dofs = 0; 25461f4df5f7SStefano Zampini interior_dofs = NULL; 25474edc6404Sstefano_zampini nneu = 0; 25484edc6404Sstefano_zampini if (pcbddc->NeumannBoundariesLocal) { 25494edc6404Sstefano_zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nneu);CHKERRQ(ierr); 25504edc6404Sstefano_zampini } 25513369cb78Sstefano_zampini checkb = (PetscBool)(!pcbddc->NeumannBoundariesLocal || pcbddc->current_level); 25524edc6404Sstefano_zampini if (checkb) { /* need to compute interior nodes */ 25531f4df5f7SStefano Zampini PetscInt n,i,j; 25541f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 25551f4df5f7SStefano Zampini PetscInt *iwork; 25561f4df5f7SStefano Zampini 25571f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 25581f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 25591f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 25601f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 256190648384SStefano Zampini for (i=1;i<n_neigh;i++) 25621f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 25631f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 25641f4df5f7SStefano Zampini for (i=0;i<n;i++) 25651f4df5f7SStefano Zampini if (!iwork[i]) 25661f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 25671f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 25681f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 25691f4df5f7SStefano Zampini } 25704f1b2e48SStefano Zampini if (has_null_pressures) { 25714f1b2e48SStefano Zampini IS *subs; 25724edc6404Sstefano_zampini PetscInt nsubs,i,j,nl; 25731f4df5f7SStefano Zampini const PetscInt *idxs; 25741f4df5f7SStefano Zampini PetscScalar *array; 25751f4df5f7SStefano Zampini Vec *work; 25761f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 25774f1b2e48SStefano Zampini 25784f1b2e48SStefano Zampini subs = pcbddc->local_subs; 25794f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 25801f4df5f7SStefano 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) */ 25814edc6404Sstefano_zampini if (checkb) { 25821f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 25831f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 25841f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 25851f4df5f7SStefano Zampini /* work[0] = 1_p */ 25861f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 25871f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 25881f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 25891f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 25901f4df5f7SStefano Zampini /* work[0] = 1_v */ 25911f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 25921f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 25931f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 25941f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 25951f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 25961f4df5f7SStefano Zampini } 25974f1b2e48SStefano Zampini if (nsubs > 1) { 25984f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 25994f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 26004f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 26014f1b2e48SStefano Zampini IS t_zerodiag_subs; 26024f1b2e48SStefano Zampini PetscInt nl; 26034f1b2e48SStefano Zampini 26044f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 26054f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 26064f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 26074f1b2e48SStefano Zampini if (nl) { 26084f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 26094f1b2e48SStefano Zampini 26104edc6404Sstefano_zampini if (checkb) { 26111f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 26121f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 26131f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 26141f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 26151f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 26161f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 26171f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 26181f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 26191f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 26201f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 26211f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 26221f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 26231f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 26241f4df5f7SStefano Zampini valid = PETSC_FALSE; 26251f4df5f7SStefano Zampini break; 26261f4df5f7SStefano Zampini } 26271f4df5f7SStefano Zampini } 26281f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 26291f4df5f7SStefano Zampini } 26306632bad2Sstefano_zampini if (valid && nneu) { 26316632bad2Sstefano_zampini const PetscInt *idxs; 26321f4df5f7SStefano Zampini PetscInt nzb; 26331f4df5f7SStefano Zampini 26346632bad2Sstefano_zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 26356632bad2Sstefano_zampini ierr = ISGlobalToLocalMappingApply(l2g,IS_GTOLM_DROP,nneu,idxs,&nzb,NULL);CHKERRQ(ierr); 26366632bad2Sstefano_zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 26371f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 26381f4df5f7SStefano Zampini } 26391f4df5f7SStefano Zampini if (valid && pressures) { 26404f1b2e48SStefano Zampini IS t_pressure_subs; 26414f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 26424f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 26434f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 26444f1b2e48SStefano Zampini } 26454f1b2e48SStefano Zampini if (valid) { 26464f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 26474f1b2e48SStefano Zampini pcbddc->benign_n++; 26484f1b2e48SStefano Zampini } else { 26494f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 26504f1b2e48SStefano Zampini } 26514f1b2e48SStefano Zampini } 26524f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 26534f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 26544f1b2e48SStefano Zampini } 26554f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 26564f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 26571f4df5f7SStefano Zampini 26586632bad2Sstefano_zampini if (nneu) valid = PETSC_FALSE; 26591f4df5f7SStefano Zampini if (valid && pressures) { 26604f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 26614f1b2e48SStefano Zampini } 26624edc6404Sstefano_zampini if (valid && checkb) { 26631f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 26641f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 26651f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 26661f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 26671f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 26681f4df5f7SStefano Zampini valid = PETSC_FALSE; 26691f4df5f7SStefano Zampini break; 26701f4df5f7SStefano Zampini } 26711f4df5f7SStefano Zampini } 26721f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 26731f4df5f7SStefano Zampini } 26744f1b2e48SStefano Zampini if (valid) { 26754f1b2e48SStefano Zampini pcbddc->benign_n = 1; 2676ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 26774f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 26784f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 26794f1b2e48SStefano Zampini } 26804f1b2e48SStefano Zampini } 26814edc6404Sstefano_zampini if (checkb) { 26821f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 26834f1b2e48SStefano Zampini } 26841f4df5f7SStefano Zampini } 26851f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 26864f1b2e48SStefano Zampini 26874f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2688b9b0e38cSStefano Zampini PetscInt n; 2689b9b0e38cSStefano Zampini 26904f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 26914f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2692b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 2693b9b0e38cSStefano Zampini if (n) { 26944f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 26954f1b2e48SStefano Zampini have_null = PETSC_FALSE; 26964f1b2e48SStefano Zampini } 2697b9b0e38cSStefano Zampini } 26984f1b2e48SStefano Zampini 26994f1b2e48SStefano Zampini /* final check for null pressures */ 27004f1b2e48SStefano Zampini if (zerodiag && pressures) { 27014f1b2e48SStefano Zampini PetscInt nz,np; 27024f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 27034f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 27044f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 27054f1b2e48SStefano Zampini } 27064f1b2e48SStefano Zampini 27074f1b2e48SStefano Zampini if (recompute_zerodiag) { 27084f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 27094f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 27104f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 27114f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 27124f1b2e48SStefano Zampini } else { 27134f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 27144f1b2e48SStefano Zampini 27154f1b2e48SStefano Zampini nzn = 0; 27164f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 27174f1b2e48SStefano Zampini PetscInt ns; 27184f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 27194f1b2e48SStefano Zampini nzn += ns; 27204f1b2e48SStefano Zampini } 27214f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 27224f1b2e48SStefano Zampini nzn = 0; 27234f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 27244f1b2e48SStefano Zampini PetscInt ns,*idxs; 27254f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 27264f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 27274f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 27284f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 27294f1b2e48SStefano Zampini nzn += ns; 27304f1b2e48SStefano Zampini } 27314f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 27324f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 27334f1b2e48SStefano Zampini } 27344f1b2e48SStefano Zampini have_null = PETSC_FALSE; 27354f1b2e48SStefano Zampini } 27364f1b2e48SStefano Zampini 2737669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2738a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2739a198735bSStefano Zampini Mat A,loc_divudotp; 2740a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2741a198735bSStefano Zampini IS row,col,isused = NULL; 2742a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2743a198735bSStefano Zampini 27441f4df5f7SStefano Zampini if (pressures) { 27451f4df5f7SStefano Zampini isused = pressures; 27461f4df5f7SStefano Zampini } else { 27474edc6404Sstefano_zampini isused = zerodiag_save; 27481f4df5f7SStefano Zampini } 2749a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2750669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 27511ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 27521ae86dd6SStefano 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"); 2753a198735bSStefano Zampini n_isused = 0; 2754a198735bSStefano Zampini if (isused) { 2755a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2756a198735bSStefano Zampini } 2757a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2758a198735bSStefano Zampini st = st-n_isused; 27591ae86dd6SStefano Zampini if (n) { 2760a198735bSStefano Zampini const PetscInt *gidxs; 2761a198735bSStefano Zampini 27627dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2763a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2764a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2765a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2766a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2767a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 27681ae86dd6SStefano Zampini } else { 2769a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2770a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2771a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2772a198735bSStefano Zampini } 2773a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2774a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2775a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2776a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2777a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2778a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2779a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2780a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2781a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2782a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2783a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2784a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2785a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2786a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 27871ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27881ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27891ae86dd6SStefano Zampini } 27904edc6404Sstefano_zampini ierr = ISDestroy(&zerodiag_save);CHKERRQ(ierr); 2791b3afcdbeSStefano Zampini 2792b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 27934f1b2e48SStefano Zampini if (has_null_pressures) { 27944f1b2e48SStefano Zampini IS zerodiagc; 27954f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 27964f1b2e48SStefano Zampini PetscInt i,s,*nnz; 27974f1b2e48SStefano Zampini 27984f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2799339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 2800339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 2801339f8db1SStefano Zampini /* local change of basis for pressures */ 2802339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 280397d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2804339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2805339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2806339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 28074f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 28084f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 28094f1b2e48SStefano Zampini PetscInt nzs,j; 28104f1b2e48SStefano Zampini 28114f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 28124f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 28134f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 28144f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 28154f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 28164f1b2e48SStefano Zampini } 2817339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2818339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2819339f8db1SStefano Zampini /* set identity on velocities */ 2820339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 2821339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 2822339f8db1SStefano Zampini } 28234f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 28244f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 28259f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 28264f1b2e48SStefano 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); 2827339f8db1SStefano Zampini /* set change on pressures */ 28284f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 28294f1b2e48SStefano Zampini PetscScalar *array; 28304f1b2e48SStefano Zampini PetscInt nzs; 28314f1b2e48SStefano Zampini 28324f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 28334f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 28344f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2835339f8db1SStefano Zampini PetscScalar vals[2]; 2836339f8db1SStefano Zampini PetscInt cols[2]; 2837339f8db1SStefano Zampini 2838339f8db1SStefano Zampini cols[0] = idxs[i]; 28394f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2840339f8db1SStefano Zampini vals[0] = 1.; 2841b0f5fe93SStefano Zampini vals[1] = 1.; 28424f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2843339f8db1SStefano Zampini } 28444f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 28454f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 28464f1b2e48SStefano Zampini array[nzs-1] = 1.; 28474f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 28484f1b2e48SStefano Zampini /* store local idxs for p0 */ 28494f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 28504f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2851339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 28524f1b2e48SStefano Zampini } 2853339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2854339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2855a3df083aSStefano Zampini /* project if needed */ 2856a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 28571dd7afcfSStefano Zampini Mat M; 28581dd7afcfSStefano Zampini 28591dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2860339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 28611dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 28621dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2863a3df083aSStefano Zampini } 28644f1b2e48SStefano Zampini /* store global idxs for p0 */ 28654f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2866339f8db1SStefano Zampini } 2867ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 28684f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 2869b0f5fe93SStefano Zampini 2870b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 2871b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 287227b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 287327b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2874339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2875339f8db1SStefano Zampini PetscFunctionReturn(0); 2876339f8db1SStefano Zampini } 2877339f8db1SStefano Zampini 2878015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2879efc2fbd9SStefano Zampini { 2880efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2881de9d7bd0SStefano Zampini PetscScalar *array; 2882efc2fbd9SStefano Zampini PetscErrorCode ierr; 2883efc2fbd9SStefano Zampini 2884efc2fbd9SStefano Zampini PetscFunctionBegin; 2885efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 2886efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 28874f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2888efc2fbd9SStefano Zampini } 2889de9d7bd0SStefano Zampini if (get) { 2890efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 28914f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 28924f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 2893efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 2894de9d7bd0SStefano Zampini } else { 2895de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 2896de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2897de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2898de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 2899efc2fbd9SStefano Zampini } 2900efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2901efc2fbd9SStefano Zampini } 2902efc2fbd9SStefano Zampini 2903c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 2904c263805aSStefano Zampini { 2905c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2906c263805aSStefano Zampini PetscErrorCode ierr; 2907c263805aSStefano Zampini 2908c263805aSStefano Zampini PetscFunctionBegin; 2909c263805aSStefano Zampini /* TODO: add error checking 2910c263805aSStefano Zampini - avoid nested pop (or push) calls. 2911c263805aSStefano Zampini - cannot push before pop. 29121c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2913c263805aSStefano Zampini */ 29144f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2915efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2916efc2fbd9SStefano Zampini } 2917c263805aSStefano Zampini if (pop) { 2918a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 29194f1b2e48SStefano Zampini IS is_p0; 29204f1b2e48SStefano Zampini MatReuse reuse; 2921c263805aSStefano Zampini 2922c263805aSStefano Zampini /* extract B_0 */ 29234f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 29244f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 29254f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 29264f1b2e48SStefano Zampini } 29274f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 29287dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2929c263805aSStefano Zampini /* remove rows and cols from local problem */ 2930c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 293197d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 29324f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 29334f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2934a3df083aSStefano Zampini } else { 2935a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2936a3df083aSStefano Zampini PetscScalar *vals; 2937a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2938a3df083aSStefano Zampini 2939a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2940a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2941a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 29420b5adadeSStefano Zampini PetscInt *nnz; 2943a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2944a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2945a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2946331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2947331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2948331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2949331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2950331e053bSStefano Zampini } 2951331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2952331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2953331e053bSStefano Zampini } 2954a3df083aSStefano Zampini 2955a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2956a3df083aSStefano Zampini PetscScalar *array; 2957a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2958a3df083aSStefano Zampini 2959a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2960a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2961a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2962a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2963a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2964a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2965a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2966a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2967a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2968a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2969a3df083aSStefano Zampini cum = 0; 2970a3df083aSStefano Zampini for (j=0;j<n;j++) { 297122db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2972a3df083aSStefano Zampini vals[cum] = array[j]; 2973a3df083aSStefano Zampini idxs_ins[cum] = j; 2974a3df083aSStefano Zampini cum++; 2975a3df083aSStefano Zampini } 2976a3df083aSStefano Zampini } 2977a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2978a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2979a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2980a3df083aSStefano Zampini } 2981a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2982a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2983a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2984a3df083aSStefano Zampini } 2985c263805aSStefano Zampini } else { /* push */ 2986a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 29874f1b2e48SStefano Zampini PetscInt i; 29884f1b2e48SStefano Zampini 29894f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 29904f1b2e48SStefano Zampini PetscScalar *B0_vals; 29914f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 29924f1b2e48SStefano Zampini 29934f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 29944f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 29957b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 29964f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 29974f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 29984f1b2e48SStefano Zampini } 2999c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3000c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 3001a3df083aSStefano Zampini } else { 3002a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 3003a3df083aSStefano Zampini } 3004c263805aSStefano Zampini } 3005c263805aSStefano Zampini PetscFunctionReturn(0); 3006c263805aSStefano Zampini } 3007c263805aSStefano Zampini 300808122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 3009b1b3d7a2SStefano Zampini { 3010b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 301108122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 301208122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 301308122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 301408122e43SStefano Zampini PetscScalar *work,lwork; 301508122e43SStefano Zampini PetscScalar *St,*S,*eigv; 301608122e43SStefano Zampini PetscScalar *Sarray,*Starray; 301708122e43SStefano Zampini PetscReal *eigs,thresh; 30181b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 3019f6f667cfSStefano Zampini PetscBool allocated_S_St; 302008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 302108122e43SStefano Zampini PetscReal *rwork; 302208122e43SStefano Zampini #endif 3023b1b3d7a2SStefano Zampini PetscErrorCode ierr; 3024b1b3d7a2SStefano Zampini 3025b1b3d7a2SStefano Zampini PetscFunctionBegin; 3026b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 3027af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 3028d750e150Sstefano_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); 302906a4e24aSStefano Zampini 3030fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3031fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3032fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3033fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 30341575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3035fd14bc51SStefano Zampini } 3036fd14bc51SStefano Zampini 3037e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 3038e496cd5dSStefano 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); 3039e496cd5dSStefano Zampini } 3040e496cd5dSStefano Zampini 304108122e43SStefano Zampini /* max size of subsets */ 304208122e43SStefano Zampini mss = 0; 304308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 304408122e43SStefano Zampini PetscInt subset_size; 3045862806e4SStefano Zampini 304608122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 304708122e43SStefano Zampini mss = PetscMax(mss,subset_size); 304808122e43SStefano Zampini } 304908122e43SStefano Zampini 305008122e43SStefano Zampini /* min/max and threshold */ 305108122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 3052f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 305308122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 3054f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 3055f6f667cfSStefano Zampini if (nmin) { 3056f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 3057f6f667cfSStefano Zampini } 305808122e43SStefano Zampini 305908122e43SStefano Zampini /* allocate lapack workspace */ 306008122e43SStefano Zampini cum = cum2 = 0; 306108122e43SStefano Zampini maxneigs = 0; 306208122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 306308122e43SStefano Zampini PetscInt n,subset_size; 3064f6f667cfSStefano Zampini 306508122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 306608122e43SStefano Zampini n = PetscMin(subset_size,nmax); 30679162d606SStefano Zampini cum += subset_size; 30689162d606SStefano Zampini cum2 += subset_size*n; 306908122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 307008122e43SStefano Zampini } 307108122e43SStefano Zampini if (mss) { 30729ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 307308122e43SStefano Zampini PetscBLASInt B_itype = 1; 307408122e43SStefano Zampini PetscBLASInt B_N = mss; 30754c6709b3SStefano Zampini PetscReal zero = 0.0; 30764c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 307708122e43SStefano Zampini 307808122e43SStefano Zampini B_lwork = -1; 307908122e43SStefano Zampini S = NULL; 308008122e43SStefano Zampini St = NULL; 3081a58a30b4SStefano Zampini eigs = NULL; 3082a58a30b4SStefano Zampini eigv = NULL; 3083a58a30b4SStefano Zampini B_iwork = NULL; 3084a58a30b4SStefano Zampini B_ifail = NULL; 3085d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3086d1710679SStefano Zampini rwork = NULL; 3087d1710679SStefano Zampini #endif 30888bec7fa6SStefano Zampini thresh = 1.0; 308908122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 309008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 309108122e43SStefano 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)); 309208122e43SStefano Zampini #else 309308122e43SStefano 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)); 309408122e43SStefano Zampini #endif 309508122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 309608122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 309708122e43SStefano Zampini } else { 309808122e43SStefano Zampini /* TODO */ 309908122e43SStefano Zampini } 310008122e43SStefano Zampini } else { 310108122e43SStefano Zampini lwork = 0; 310208122e43SStefano Zampini } 310308122e43SStefano Zampini 310408122e43SStefano Zampini nv = 0; 3105d62866d3SStefano 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) */ 3106d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 310708122e43SStefano Zampini } 31084c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 3109f6f667cfSStefano Zampini if (allocated_S_St) { 3110f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 3111f6f667cfSStefano Zampini } 3112f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 311308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 311408122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 311508122e43SStefano Zampini #endif 31169162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 31179162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 31189162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 311908122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 31209162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 312108122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 312208122e43SStefano Zampini 312308122e43SStefano Zampini maxneigs = 0; 312472b8c272SStefano Zampini cum = cumarray = 0; 31259162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 31269162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 3127d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 312808122e43SStefano Zampini const PetscInt *idxs; 312908122e43SStefano Zampini 3130d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 313108122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 313208122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 313308122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 313408122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 31359162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 31369162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 313708122e43SStefano Zampini } 3138d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 313908122e43SStefano Zampini } 314008122e43SStefano Zampini 314108122e43SStefano Zampini if (mss) { /* multilevel */ 314208122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 314308122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 314408122e43SStefano Zampini } 314508122e43SStefano Zampini 3146ffd830a3SStefano Zampini thresh = pcbddc->adaptive_threshold; 314708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 314808122e43SStefano Zampini const PetscInt *idxs; 31499d54b7f4SStefano Zampini PetscReal upper,lower; 3150862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 315108122e43SStefano Zampini PetscBLASInt B_N; 3152aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 315308122e43SStefano Zampini 31549d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 31559d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 31569d54b7f4SStefano Zampini lower = thresh; 31579d54b7f4SStefano Zampini } else { 31589d54b7f4SStefano Zampini upper = 1./thresh; 31599d54b7f4SStefano Zampini lower = 0.; 31609d54b7f4SStefano Zampini } 3161862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 3162ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 3163f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 3164f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 31659ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 3166aff50787SStefano Zampini PetscInt j,k; 3167aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 3168aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 3169aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 317008122e43SStefano Zampini } 317108122e43SStefano Zampini for (j=0;j<subset_size;j++) { 3172aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 3173aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 3174aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 3175aff50787SStefano Zampini } 317608122e43SStefano Zampini } 317708122e43SStefano Zampini } else { 317808122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 317908122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 318008122e43SStefano Zampini } 31818bec7fa6SStefano Zampini } else { 3182f6f667cfSStefano Zampini S = Sarray + cumarray; 3183f6f667cfSStefano Zampini St = Starray + cumarray; 31848bec7fa6SStefano Zampini } 3185aff50787SStefano Zampini /* see if we can save some work */ 3186b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 3187aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 3188aff50787SStefano Zampini } 3189aff50787SStefano Zampini 3190b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 3191aff50787SStefano Zampini B_neigs = 0; 3192aff50787SStefano Zampini } else { 31939ab7bb16SStefano Zampini if (sub_schurs->is_hermitian && sub_schurs->is_posdef) { 319408122e43SStefano Zampini PetscBLASInt B_itype = 1; 3195f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 31964c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 31979552c7c7SStefano Zampini PetscInt nmin_s; 3198b7ab4a40SStefano Zampini PetscBool compute_range = PETSC_FALSE; 319908122e43SStefano Zampini 3200fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3201eee23b56SStefano 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]]); 3202fd14bc51SStefano Zampini } 3203d16cbb6bSStefano Zampini 3204b7ab4a40SStefano Zampini compute_range = PETSC_FALSE; 3205b7ab4a40SStefano Zampini if (thresh > 1.+PETSC_SMALL && !same_data) { 3206b7ab4a40SStefano Zampini compute_range = PETSC_TRUE; 3207b7ab4a40SStefano Zampini } 3208b7ab4a40SStefano Zampini 320908122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3210b7ab4a40SStefano Zampini if (compute_range) { 3211d16cbb6bSStefano Zampini 3212d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 321308122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 32149d54b7f4SStefano 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)); 321508122e43SStefano Zampini #else 32169d54b7f4SStefano 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)); 321708122e43SStefano Zampini #endif 3218b7ab4a40SStefano Zampini } else if (!same_data) { 3219d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 3220d16cbb6bSStefano Zampini B_IL = 1; 3221d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 32229d54b7f4SStefano 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)); 3223d16cbb6bSStefano Zampini #else 32249d54b7f4SStefano 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)); 3225d16cbb6bSStefano Zampini #endif 3226b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 3227b7ab4a40SStefano Zampini PetscInt k; 3228b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 3229b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 3230b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 3231b7ab4a40SStefano Zampini nmin = nmax; 3232b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 3233b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 3234b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 3235b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 3236b7ab4a40SStefano Zampini } 3237d16cbb6bSStefano Zampini } 323808122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 323908122e43SStefano Zampini if (B_ierr) { 32406c4ed002SBarry 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); 32416c4ed002SBarry 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); 32426c4ed002SBarry 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); 324308122e43SStefano Zampini } 324408122e43SStefano Zampini 324508122e43SStefano Zampini if (B_neigs > nmax) { 3246fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3247fd14bc51SStefano Zampini PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax); 3248fd14bc51SStefano Zampini } 32499d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = B_neigs -nmax; 325008122e43SStefano Zampini B_neigs = nmax; 325108122e43SStefano Zampini } 325208122e43SStefano Zampini 32539552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 32549552c7c7SStefano Zampini if (B_neigs < nmin_s) { 325508122e43SStefano Zampini PetscBLASInt B_neigs2; 325608122e43SStefano Zampini 32579d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3258f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 32599d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 32609d54b7f4SStefano Zampini } else { 32619d54b7f4SStefano Zampini B_IL = B_neigs + 1; 32629d54b7f4SStefano Zampini B_IU = nmin_s; 32639d54b7f4SStefano Zampini } 3264fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3265fd14bc51SStefano 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); 3266fd14bc51SStefano Zampini } 32679ab7bb16SStefano Zampini if (sub_schurs->is_hermitian) { 32681ae86dd6SStefano Zampini PetscInt j,k; 326908122e43SStefano Zampini for (j=0;j<subset_size;j++) { 32701ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 32711ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 32721ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 327308122e43SStefano Zampini } 327408122e43SStefano Zampini } 327508122e43SStefano Zampini } else { 327608122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 327708122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 327808122e43SStefano Zampini } 327908122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 328008122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 32819d54b7f4SStefano 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)); 328208122e43SStefano Zampini #else 32839d54b7f4SStefano 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)); 328408122e43SStefano Zampini #endif 328508122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 328608122e43SStefano Zampini B_neigs += B_neigs2; 328708122e43SStefano Zampini } 328808122e43SStefano Zampini if (B_ierr) { 32896c4ed002SBarry 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); 32906c4ed002SBarry 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); 32916c4ed002SBarry 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); 329208122e43SStefano Zampini } 3293fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3294ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 329508122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 329608122e43SStefano Zampini if (eigs[j] == 0.0) { 3297ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 329808122e43SStefano Zampini } else { 32999d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3300ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 33019d54b7f4SStefano Zampini } else { 33029d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 33039d54b7f4SStefano Zampini } 3304fd14bc51SStefano Zampini } 330508122e43SStefano Zampini } 330608122e43SStefano Zampini } 330708122e43SStefano Zampini } else { 330808122e43SStefano Zampini /* TODO */ 330908122e43SStefano Zampini } 3310aff50787SStefano Zampini } 33116c3e6151SStefano Zampini /* change the basis back to the original one */ 33126c3e6151SStefano Zampini if (sub_schurs->change) { 331372b8c272SStefano Zampini Mat change,phi,phit; 33146c3e6151SStefano Zampini 331503dfb2d7SStefano Zampini if (pcbddc->dbg_flag > 2) { 33166c3e6151SStefano Zampini PetscInt ii; 33176c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 33186c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 33196c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 3320684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3321684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 3322684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 3323684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3324684229deSStefano Zampini #else 33256c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 3326684229deSStefano Zampini #endif 33276c3e6151SStefano Zampini } 33286c3e6151SStefano Zampini } 33296c3e6151SStefano Zampini } 333072b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 33316c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 333272b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 33336c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 33346c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 33356c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 33366c3e6151SStefano Zampini } 33378bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 33388bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 33399162d606SStefano Zampini if (B_neigs) { 33409162d606SStefano 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); 3341fd14bc51SStefano Zampini 3342fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 33439552c7c7SStefano Zampini PetscInt ii; 33449552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 3345ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 33469552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 3347ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3348ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3349ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3350ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3351ac47001eSStefano Zampini #else 3352ac47001eSStefano 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); 3353ac47001eSStefano Zampini #endif 33549552c7c7SStefano Zampini } 33559552c7c7SStefano Zampini } 3356fd14bc51SStefano Zampini } 33579162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 33589162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 33599162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 33609162d606SStefano Zampini cum++; 336108122e43SStefano Zampini } 336208122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 336308122e43SStefano Zampini /* shift for next computation */ 336408122e43SStefano Zampini cumarray += subset_size*subset_size; 336508122e43SStefano Zampini } 3366fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3367fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3368fd14bc51SStefano Zampini } 336908122e43SStefano Zampini 337008122e43SStefano Zampini if (mss) { 337108122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 337208122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 3373f6f667cfSStefano Zampini /* destroy matrices (junk) */ 3374f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 3375f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 337608122e43SStefano Zampini } 3377f6f667cfSStefano Zampini if (allocated_S_St) { 3378f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 3379f6f667cfSStefano Zampini } 3380f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 338108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 338208122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 338308122e43SStefano Zampini #endif 338408122e43SStefano Zampini if (pcbddc->dbg_flag) { 33851b968477SStefano Zampini PetscInt maxneigs_r; 3386b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 33879b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 338808122e43SStefano Zampini } 338908122e43SStefano Zampini PetscFunctionReturn(0); 339008122e43SStefano Zampini } 3391b1b3d7a2SStefano Zampini 3392c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 3393c8587f34SStefano Zampini { 33948629588bSStefano Zampini PetscScalar *coarse_submat_vals; 3395c8587f34SStefano Zampini PetscErrorCode ierr; 3396c8587f34SStefano Zampini 3397c8587f34SStefano Zampini PetscFunctionBegin; 3398f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 33995e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3400c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3401c8587f34SStefano Zampini 3402684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 34030fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3404684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3405c8587f34SStefano Zampini 34068629588bSStefano Zampini /* 34078629588bSStefano Zampini Setup local correction and local part of coarse basis. 34088629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 34098629588bSStefano Zampini */ 341047f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 34118629588bSStefano Zampini 34128629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 34138629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 34148629588bSStefano Zampini 34158629588bSStefano Zampini /* free */ 34168629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3417c8587f34SStefano Zampini PetscFunctionReturn(0); 3418c8587f34SStefano Zampini } 3419c8587f34SStefano Zampini 3420674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3421674ae819SStefano Zampini { 3422674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3423674ae819SStefano Zampini PetscErrorCode ierr; 3424674ae819SStefano Zampini 3425674ae819SStefano Zampini PetscFunctionBegin; 3426674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 342730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3428674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3429785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3430674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3431f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3432f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3433785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 343463602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 343563602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3436674ae819SStefano Zampini PetscFunctionReturn(0); 3437674ae819SStefano Zampini } 3438674ae819SStefano Zampini 3439674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3440674ae819SStefano Zampini { 3441674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 34424f1b2e48SStefano Zampini PetscInt i; 3443674ae819SStefano Zampini PetscErrorCode ierr; 3444674ae819SStefano Zampini 3445674ae819SStefano Zampini PetscFunctionBegin; 34461e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 34471e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3448a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3449b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3450674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 345116909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 34521dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3453674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3454669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3455fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 34569326c5c6Sstefano_zampini ierr = PCBDDCGraphDestroy(&pcbddc->mat_graph);CHKERRQ(ierr); 34574f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 34584f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 34594f1b2e48SStefano Zampini } 3460e68a0315Sstefano_zampini pcbddc->n_local_subs = 0; 34614f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3462e68a0315Sstefano_zampini ierr = PCBDDCSubSchursDestroy(&pcbddc->sub_schurs);CHKERRQ(ierr); 3463c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 34648af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 3465674ae819SStefano Zampini PetscFunctionReturn(0); 3466674ae819SStefano Zampini } 3467674ae819SStefano Zampini 3468674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3469674ae819SStefano Zampini { 3470674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3471674ae819SStefano Zampini PetscErrorCode ierr; 3472674ae819SStefano Zampini 3473674ae819SStefano Zampini PetscFunctionBegin; 3474674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 347558da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3476ca92afb2SStefano Zampini PetscScalar *array; 347706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 347806656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 347958da7f69SStefano Zampini } 3480674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3481674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 348215aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 348315aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3484674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3485674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3486674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 348706656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3488674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3489674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 34908ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3491674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3492674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3493674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 34949326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_D);CHKERRQ(ierr); 34959326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 34969326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3497f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3498727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 34990e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3500f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 350170cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 350281d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 35030369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 35041dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 35054f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 35068b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3507ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3508ca92afb2SStefano Zampini PetscInt i; 3509ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3510ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3511ca92afb2SStefano Zampini } 3512ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3513ca92afb2SStefano Zampini } 35144f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3515674ae819SStefano Zampini PetscFunctionReturn(0); 3516674ae819SStefano Zampini } 3517674ae819SStefano Zampini 3518f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 35196bfb1811SStefano Zampini { 35206bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 35216bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 35226bfb1811SStefano Zampini VecType impVecType; 35234f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 35246bfb1811SStefano Zampini PetscErrorCode ierr; 35256bfb1811SStefano Zampini 35266bfb1811SStefano Zampini PetscFunctionBegin; 35274f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3528b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 35296bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3530e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3531e7b262bdSStefano Zampini /* R nodes */ 3532e7b262bdSStefano Zampini old_size = -1; 3533e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3534e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3535e7b262bdSStefano Zampini } 3536e7b262bdSStefano Zampini if (n_R != old_size) { 3537e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3538e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 35396bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 35406bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 35416bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 35426bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3543e7b262bdSStefano Zampini } 3544e7b262bdSStefano Zampini /* local primal dofs */ 3545e7b262bdSStefano Zampini old_size = -1; 3546e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3547e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3548e7b262bdSStefano Zampini } 3549e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3550e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 355183b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3552e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 35536bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3554e7b262bdSStefano Zampini } 3555e7b262bdSStefano Zampini /* local explicit constraints */ 3556e7b262bdSStefano Zampini old_size = -1; 3557e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3558e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3559e7b262bdSStefano Zampini } 3560e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3561e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 356283b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 356383b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 356483b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 356583b7ccabSStefano Zampini } 35666bfb1811SStefano Zampini PetscFunctionReturn(0); 35676bfb1811SStefano Zampini } 35686bfb1811SStefano Zampini 356947f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 357088ebb749SStefano Zampini { 357125084f0cSStefano Zampini PetscErrorCode ierr; 357225084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 357388ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 357488ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3575d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 357625084f0cSStefano Zampini /* submatrices of local problem */ 357780677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 357806656605SStefano Zampini /* submatrices of local coarse problem */ 357906656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 358025084f0cSStefano Zampini /* working matrices */ 358106656605SStefano Zampini Mat C_CR; 358225084f0cSStefano Zampini /* additional working stuff */ 358306656605SStefano Zampini PC pc_R; 3584c58f9fdbSStefano Zampini Mat F,Brhs = NULL; 35855cbda25cSStefano Zampini Vec dummy_vec; 3586c58f9fdbSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction,sparserhs; 358725084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 358806656605SStefano Zampini PetscScalar *work; 358906656605SStefano Zampini PetscInt *idx_V_B; 3590ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 359106656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 3592ffd830a3SStefano Zampini 359325084f0cSStefano Zampini /* some shortcuts to scalars */ 359406656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 359588ebb749SStefano Zampini 359688ebb749SStefano Zampini PetscFunctionBegin; 35979a962809SStefano 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"); 3598ffd830a3SStefano Zampini 3599ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3600b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 36014f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3602b371cd4fSStefano Zampini n_B = pcis->n_B; 3603b371cd4fSStefano Zampini n_D = pcis->n - n_B; 360488ebb749SStefano Zampini n_R = pcis->n - n_vertices; 360588ebb749SStefano Zampini 360688ebb749SStefano Zampini /* vertices in boundary numbering */ 3607785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 36080e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 36096c4ed002SBarry 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); 361088ebb749SStefano Zampini 361106656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3612019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 361306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 361406656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 361506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 361606656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 361706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 361806656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 361906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 362006656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 362106656605SStefano Zampini 362206656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 362306656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 362406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 362506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 362606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 3627ffd830a3SStefano Zampini lda_rhs = n_R; 3628a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 362906656605SStefano Zampini if (isLU || isILU || isCHOL) { 363006656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 3631b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 3632df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3633d62866d3SStefano Zampini MatFactorType type; 3634d62866d3SStefano Zampini 3635df4d28bfSStefano Zampini F = reuse_solver->F; 36366816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 3637d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 3638ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 363922db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 364006656605SStefano Zampini } else { 364106656605SStefano Zampini F = NULL; 364206656605SStefano Zampini } 364306656605SStefano Zampini 3644c58f9fdbSStefano Zampini /* determine if we can use a sparse right-hand side */ 3645c58f9fdbSStefano Zampini sparserhs = PETSC_FALSE; 3646c58f9fdbSStefano Zampini if (F) { 3647ea799195SBarry Smith MatSolverType solver; 3648c58f9fdbSStefano Zampini 36493ca39a21SBarry Smith ierr = MatFactorGetSolverType(F,&solver);CHKERRQ(ierr); 3650c58f9fdbSStefano Zampini ierr = PetscStrcmp(solver,MATSOLVERMUMPS,&sparserhs);CHKERRQ(ierr); 3651c58f9fdbSStefano Zampini } 3652c58f9fdbSStefano Zampini 3653ffd830a3SStefano Zampini /* allocate workspace */ 3654ffd830a3SStefano Zampini n = 0; 3655ffd830a3SStefano Zampini if (n_constraints) { 3656ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3657ffd830a3SStefano Zampini } 3658ffd830a3SStefano Zampini if (n_vertices) { 3659ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3660ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3661ffd830a3SStefano Zampini } 36622a3a6641Sstefano_zampini if (!pcbddc->symmetric_primal) { 36632a3a6641Sstefano_zampini n = PetscMax(2*lda_rhs*pcbddc->local_primal_size,n); 36642a3a6641Sstefano_zampini } 3665ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3666ffd830a3SStefano Zampini 36675cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 36685cbda25cSStefano Zampini dummy_vec = NULL; 36695cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 36705cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 36715cbda25cSStefano Zampini } 36725cbda25cSStefano Zampini 367388ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 367488ebb749SStefano Zampini if (n_constraints) { 3675*837cedc9SStefano Zampini Mat M3,C_B; 367606656605SStefano Zampini IS is_aux; 367780677318SStefano Zampini PetscScalar *array,*array2; 367806656605SStefano Zampini 3679f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 368080677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 368188ebb749SStefano Zampini 368225084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 368325084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 36847dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 36857dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 368688ebb749SStefano Zampini 368780677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 368880677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 3689c58f9fdbSStefano Zampini if (!sparserhs) { 3690ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 369188ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 369206656605SStefano Zampini const PetscScalar *row_cmat_values; 369306656605SStefano Zampini const PetscInt *row_cmat_indices; 369406656605SStefano Zampini PetscInt size_of_constraint,j; 369588ebb749SStefano Zampini 369606656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 369706656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 3698ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 369906656605SStefano Zampini } 370006656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 370106656605SStefano Zampini } 3702c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&Brhs);CHKERRQ(ierr); 3703c58f9fdbSStefano Zampini } else { 3704c58f9fdbSStefano Zampini Mat tC_CR; 3705c58f9fdbSStefano Zampini 3706c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3707c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 3708c58f9fdbSStefano Zampini PetscScalar *aa; 3709c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 3710c58f9fdbSStefano Zampini PetscBool done; 3711c58f9fdbSStefano Zampini 3712c58f9fdbSStefano Zampini ierr = MatGetRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 371313903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 3714c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(C_CR,&aa);CHKERRQ(ierr); 3715c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_constraints,lda_rhs,ii,jj,aa,&tC_CR);CHKERRQ(ierr); 3716c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 371713903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 3718c58f9fdbSStefano Zampini } else { 3719c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)C_CR);CHKERRQ(ierr); 3720c58f9fdbSStefano Zampini tC_CR = C_CR; 3721c58f9fdbSStefano Zampini } 3722c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tC_CR,&Brhs);CHKERRQ(ierr); 3723c58f9fdbSStefano Zampini ierr = MatDestroy(&tC_CR);CHKERRQ(ierr); 3724c58f9fdbSStefano Zampini } 3725ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 372606656605SStefano Zampini if (F) { 3727a3df083aSStefano Zampini if (need_benign_correction) { 3728df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3729a3df083aSStefano Zampini 373072b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 373172b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 3732a3df083aSStefano Zampini } 3733c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,local_auxmat2_R);CHKERRQ(ierr); 3734a3df083aSStefano Zampini if (need_benign_correction) { 3735a3df083aSStefano Zampini PetscScalar *marr; 3736df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3737a3df083aSStefano Zampini 3738a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 37395cbda25cSStefano Zampini if (lda_rhs != n_R) { 37405cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 37415cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 37425cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 37435cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 37445cbda25cSStefano Zampini } 37455cbda25cSStefano Zampini } else { 3746a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 3747a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 37485cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3749a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3750a3df083aSStefano Zampini } 37515cbda25cSStefano Zampini } 3752a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 3753a3df083aSStefano Zampini } 375406656605SStefano Zampini } else { 375580677318SStefano Zampini PetscScalar *marr; 375680677318SStefano Zampini 375780677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 375806656605SStefano Zampini for (i=0;i<n_constraints;i++) { 3759ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3760ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 376106656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 376206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 376306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 376406656605SStefano Zampini } 376580677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 376606656605SStefano Zampini } 3767c58f9fdbSStefano Zampini if (sparserhs) { 3768c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3769c58f9fdbSStefano Zampini } 3770c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 377180677318SStefano Zampini if (!pcbddc->switch_static) { 377280677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 377380677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 377480677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 377580677318SStefano Zampini for (i=0;i<n_constraints;i++) { 3776ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 377780677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 377880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 377980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 378080677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 378180677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 378280677318SStefano Zampini } 378380677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 378480677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 378572b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 378680677318SStefano Zampini } else { 3787ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3788ffd830a3SStefano Zampini IS dummy; 3789ffd830a3SStefano Zampini 3790ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 37917dae84e0SHong Zhang ierr = MatCreateSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 3792ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 3793ffd830a3SStefano Zampini } else { 379480677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 379580677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 3796ffd830a3SStefano Zampini } 379725084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 379880677318SStefano Zampini } 379980677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 380080677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 380180677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 380280677318SStefano Zampini if (isCHOL) { 380380677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 380480677318SStefano Zampini } else { 380525084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 380680677318SStefano Zampini } 3807*837cedc9SStefano Zampini ierr = MatSeqDenseInvertFactors_Private(M3);CHKERRQ(ierr); 380880677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 3809*837cedc9SStefano Zampini ierr = MatMatMult(M3,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 381072b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 3811*837cedc9SStefano Zampini ierr = MatCopy(M3,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 3812*837cedc9SStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 3813f4ddd8eeSStefano Zampini } 3814fc227af8SStefano Zampini 3815fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 381688ebb749SStefano Zampini if (n_vertices) { 381706656605SStefano Zampini IS is_aux; 3818c58f9fdbSStefano Zampini PetscBool isseqaij; 38193a50541eSStefano Zampini 3820b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 38216816873aSStefano Zampini IS tis; 38226816873aSStefano Zampini 38236816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 38246816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 38256816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 38266816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 38276816873aSStefano Zampini } else { 38283a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 38296816873aSStefano Zampini } 38307dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 38317dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 3832c58f9fdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 3833c58f9fdbSStefano Zampini if (!isseqaij) { /* MatMatMult(A_VR,A_RRmA_RV) below will raise an error */ 3834c58f9fdbSStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 3835c58f9fdbSStefano Zampini } 38367dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 383725084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 383888ebb749SStefano Zampini } 383988ebb749SStefano Zampini 384088ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 3841f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 384206656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 384306656605SStefano Zampini if (pcbddc->coarse_phi_D) { 384406656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 384506656605SStefano Zampini } 3846f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 384706656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 384806656605SStefano Zampini PetscScalar *marray; 384906656605SStefano Zampini 385006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 385106656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 3852f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3853f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3854f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3855f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3856f4ddd8eeSStefano Zampini } 3857f4ddd8eeSStefano Zampini } 385806656605SStefano Zampini 3859f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 3860a6e023c1Sstefano_zampini PetscScalar *marr; 386188ebb749SStefano Zampini 3862a6e023c1Sstefano_zampini /* memory size */ 386306656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 3864a6e023c1Sstefano_zampini if (pcbddc->switch_static || pcbddc->dbg_flag) n += n_D*pcbddc->local_primal_size; 3865a6e023c1Sstefano_zampini if (!pcbddc->symmetric_primal) n *= 2; 3866a6e023c1Sstefano_zampini ierr = PetscCalloc1(n,&marr);CHKERRQ(ierr); 3867a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3868a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 38698eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3870a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3871a6e023c1Sstefano_zampini marr += n_D*pcbddc->local_primal_size; 387288ebb749SStefano Zampini } 38733301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 3874a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3875a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 38768eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3877a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 387888ebb749SStefano Zampini } 387988ebb749SStefano Zampini } else { 3880c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 3881c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 38821b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3883c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 3884c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 3885c0553b1fSStefano Zampini } 388688ebb749SStefano Zampini } 388706656605SStefano Zampini } 3888019a44ceSStefano Zampini 388906656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 38904f1b2e48SStefano Zampini p0_lidx_I = NULL; 38914f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 3892d12edf2fSStefano Zampini const PetscInt *idxs; 3893d12edf2fSStefano Zampini 3894d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 38954f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 38964f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 38974f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 38984f1b2e48SStefano Zampini } 3899d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 3900d12edf2fSStefano Zampini } 3901d16cbb6bSStefano Zampini 390206656605SStefano Zampini /* vertices */ 390306656605SStefano Zampini if (n_vertices) { 3904c58f9fdbSStefano Zampini PetscBool restoreavr = PETSC_FALSE; 390516f15bc4SStefano Zampini 3906af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 390704708bb6SStefano Zampini 390816f15bc4SStefano Zampini if (n_R) { 390914393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 391006656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 391116f15bc4SStefano Zampini PetscScalar *x,*y; 391206656605SStefano Zampini 391321eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 391414393ed6SStefano Zampini if (need_benign_correction) { 391514393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 391614393ed6SStefano Zampini IS is_p0; 391714393ed6SStefano Zampini PetscInt *idxs_p0,n; 391814393ed6SStefano Zampini 391914393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 392014393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 392114393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 3922af25d912SStefano 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); 392314393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 392414393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 39257dae84e0SHong Zhang ierr = MatCreateSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 392614393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 392714393ed6SStefano Zampini } 392814393ed6SStefano Zampini 3929c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3930c58f9fdbSStefano Zampini if (!sparserhs || need_benign_correction) { 3931ffd830a3SStefano Zampini if (lda_rhs == n_R) { 3932af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3933ffd830a3SStefano Zampini } else { 3934ca92afb2SStefano Zampini PetscScalar *av,*array; 3935ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 3936ca92afb2SStefano Zampini PetscInt n; 3937ca92afb2SStefano Zampini PetscBool flg_row; 3938ffd830a3SStefano Zampini 3939ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 3940ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 39419d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3942ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3943ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 3944ca92afb2SStefano Zampini for (i=0;i<n;i++) { 3945ca92afb2SStefano Zampini PetscInt j; 3946ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 3947ffd830a3SStefano Zampini } 3948ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3949ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 3950ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 3951ffd830a3SStefano Zampini } 3952a3df083aSStefano Zampini if (need_benign_correction) { 3953df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3954a3df083aSStefano Zampini PetscScalar *marr; 3955a3df083aSStefano Zampini 3956a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 395714393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 395814393ed6SStefano Zampini 395914393ed6SStefano Zampini | 0 0 0 | (V) 396014393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 396114393ed6SStefano Zampini | 0 0 -1 | (p0) 396214393ed6SStefano Zampini 396314393ed6SStefano Zampini */ 3964df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 396514393ed6SStefano Zampini const PetscScalar *vals; 396614393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 396714393ed6SStefano Zampini PetscInt n,j,nz; 396814393ed6SStefano Zampini 3969df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 3970df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 397114393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 397214393ed6SStefano Zampini for (j=0;j<n;j++) { 397314393ed6SStefano Zampini PetscScalar val = vals[j]; 397414393ed6SStefano Zampini PetscInt k,col = idxs[j]; 397514393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 397614393ed6SStefano Zampini } 397714393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 3978df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 397914393ed6SStefano Zampini } 398072b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 398172b8c272SStefano Zampini } 3982c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RV);CHKERRQ(ierr); 3983c58f9fdbSStefano Zampini Brhs = A_RV; 3984c58f9fdbSStefano Zampini } else { 3985c58f9fdbSStefano Zampini Mat tA_RVT,A_RVT; 3986c58f9fdbSStefano Zampini 3987c58f9fdbSStefano Zampini if (!pcbddc->symmetric_primal) { 3988c58f9fdbSStefano Zampini ierr = MatTranspose(A_RV,MAT_INITIAL_MATRIX,&A_RVT);CHKERRQ(ierr); 3989c58f9fdbSStefano Zampini } else { 3990c58f9fdbSStefano Zampini restoreavr = PETSC_TRUE; 3991c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 3992c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_VR);CHKERRQ(ierr); 3993c58f9fdbSStefano Zampini A_RVT = A_VR; 3994c58f9fdbSStefano Zampini } 3995c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 3996c58f9fdbSStefano Zampini PetscScalar *aa; 3997c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 3998c58f9fdbSStefano Zampini PetscBool done; 3999c58f9fdbSStefano Zampini 4000c58f9fdbSStefano Zampini ierr = MatGetRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 400113903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 4002c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(A_RVT,&aa);CHKERRQ(ierr); 4003c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_vertices,lda_rhs,ii,jj,aa,&tA_RVT);CHKERRQ(ierr); 4004c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 400513903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 4006c58f9fdbSStefano Zampini } else { 4007c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RVT);CHKERRQ(ierr); 4008c58f9fdbSStefano Zampini tA_RVT = A_RVT; 4009c58f9fdbSStefano Zampini } 4010c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tA_RVT,&Brhs);CHKERRQ(ierr); 4011c58f9fdbSStefano Zampini ierr = MatDestroy(&tA_RVT);CHKERRQ(ierr); 4012c58f9fdbSStefano Zampini ierr = MatDestroy(&A_RVT);CHKERRQ(ierr); 4013c58f9fdbSStefano Zampini } 401472b8c272SStefano Zampini if (F) { 401514393ed6SStefano Zampini /* need to correct the rhs */ 401672b8c272SStefano Zampini if (need_benign_correction) { 401772b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 401872b8c272SStefano Zampini PetscScalar *marr; 401972b8c272SStefano Zampini 4020c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&marr);CHKERRQ(ierr); 40215cbda25cSStefano Zampini if (lda_rhs != n_R) { 40225cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 40235cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 40245cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 40255cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 40265cbda25cSStefano Zampini } 40275cbda25cSStefano Zampini } else { 4028a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4029a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 40305cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 4031a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4032a3df083aSStefano Zampini } 40335cbda25cSStefano Zampini } 4034c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&marr);CHKERRQ(ierr); 4035a3df083aSStefano Zampini } 4036c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,A_RRmA_RV);CHKERRQ(ierr); 4037c58f9fdbSStefano Zampini if (restoreavr) { 4038c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4039c58f9fdbSStefano Zampini } 404014393ed6SStefano Zampini /* need to correct the solution */ 4041a3df083aSStefano Zampini if (need_benign_correction) { 4042df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4043a3df083aSStefano Zampini PetscScalar *marr; 4044a3df083aSStefano Zampini 4045a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 40465cbda25cSStefano Zampini if (lda_rhs != n_R) { 40475cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 40485cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 40495cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 40505cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 40515cbda25cSStefano Zampini } 40525cbda25cSStefano Zampini } else { 4053a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4054a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 40555cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 4056a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4057a3df083aSStefano Zampini } 40585cbda25cSStefano Zampini } 4059a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 4060a3df083aSStefano Zampini } 406106656605SStefano Zampini } else { 4062c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&y);CHKERRQ(ierr); 406306656605SStefano Zampini for (i=0;i<n_vertices;i++) { 4064ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 4065ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 406606656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 406706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 406806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 406906656605SStefano Zampini } 4070c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&y);CHKERRQ(ierr); 407106656605SStefano Zampini } 407280677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4073c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 4074ffd830a3SStefano Zampini /* S_VV and S_CV */ 407506656605SStefano Zampini if (n_constraints) { 407606656605SStefano Zampini Mat B; 407780677318SStefano Zampini 4078ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 407980677318SStefano Zampini for (i=0;i<n_vertices;i++) { 4080ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 4081ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 408280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 408380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 408480677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 408580677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 408680677318SStefano Zampini } 4087ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 408880677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 408980677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 4090ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 409180677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 409206656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 4093ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 4094ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 409506656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 409606656605SStefano Zampini } 4097ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4098ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 4099ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4100ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 4101ffd830a3SStefano Zampini } 410206656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 410314393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 410414393ed6SStefano Zampini if (need_benign_correction) { 4105df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 410614393ed6SStefano Zampini PetscScalar *marr,*sums; 410714393ed6SStefano Zampini 410814393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 4109f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 4110df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 411114393ed6SStefano Zampini const PetscScalar *vals; 411214393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 411314393ed6SStefano Zampini PetscInt n,j,nz; 411414393ed6SStefano Zampini 4115df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4116df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 411714393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 411814393ed6SStefano Zampini PetscInt k; 411914393ed6SStefano Zampini sums[j] = 0.; 412014393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 412114393ed6SStefano Zampini } 412214393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 412314393ed6SStefano Zampini for (j=0;j<n;j++) { 412414393ed6SStefano Zampini PetscScalar val = vals[j]; 412514393ed6SStefano Zampini PetscInt k; 412614393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 412714393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 412814393ed6SStefano Zampini } 412914393ed6SStefano Zampini } 413014393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4131df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 413214393ed6SStefano Zampini } 413314393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 4134f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 413514393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 413614393ed6SStefano Zampini } 413780677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 413806656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 413906656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 414006656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 414106656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 414206656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 414306656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 414406656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4145d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 4146019a44ceSStefano Zampini } else { 4147d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4148d16cbb6bSStefano Zampini } 414921eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 4150d16cbb6bSStefano Zampini 415106656605SStefano Zampini /* coarse basis functions */ 415206656605SStefano Zampini for (i=0;i<n_vertices;i++) { 415316f15bc4SStefano Zampini PetscScalar *y; 415416f15bc4SStefano Zampini 4155ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 415606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 415706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 415806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 415906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 416006656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 416106656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 416206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 416306656605SStefano Zampini 416406656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 41654f1b2e48SStefano Zampini PetscInt j; 41664f1b2e48SStefano Zampini 416706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 416806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 416906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 417006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 417106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 41724f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 417306656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 417406656605SStefano Zampini } 417506656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 417606656605SStefano Zampini } 417704708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 417804708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 417906656605SStefano Zampini } 41805cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 418106656605SStefano Zampini 418206656605SStefano Zampini if (n_constraints) { 418306656605SStefano Zampini Mat B; 418406656605SStefano Zampini 4185ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 418606656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 418780677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 418806656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 418906656605SStefano Zampini if (n_vertices) { 419003dfb2d7SStefano Zampini if (isCHOL || need_benign_correction) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 419180677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 419280677318SStefano Zampini } else { 419380677318SStefano Zampini Mat S_VCt; 419480677318SStefano Zampini 4195ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4196ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 419772b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 4198ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 4199ffd830a3SStefano Zampini } 420080677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 420180677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 420280677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 420380677318SStefano Zampini } 420406656605SStefano Zampini } 420506656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 420606656605SStefano Zampini /* coarse basis functions */ 420706656605SStefano Zampini for (i=0;i<n_constraints;i++) { 420806656605SStefano Zampini PetscScalar *y; 420906656605SStefano Zampini 4210ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 421106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 421206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 421306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 421406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 421506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 421606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 421706656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 42184f1b2e48SStefano Zampini PetscInt j; 42194f1b2e48SStefano Zampini 422006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 422106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 422206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 422306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 422406656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 42254f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 422606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 422706656605SStefano Zampini } 422806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 422906656605SStefano Zampini } 423006656605SStefano Zampini } 423180677318SStefano Zampini if (n_constraints) { 423280677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 423380677318SStefano Zampini } 42344f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 423572b8c272SStefano Zampini 423672b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 423772b8c272SStefano Zampini if (pcbddc->benign_n) { 423872b8c272SStefano Zampini Mat B0_B,B0_BPHI; 423972b8c272SStefano Zampini IS is_dummy; 424072b8c272SStefano Zampini PetscScalar *data; 424172b8c272SStefano Zampini PetscInt j; 424272b8c272SStefano Zampini 424372b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 42447dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 424572b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 424672b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 424786c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 424872b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 424972b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 425072b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 425172b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 425272b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 425372b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 425472b8c272SStefano Zampini } 425572b8c272SStefano Zampini } 425672b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 425772b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 425872b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 425972b8c272SStefano Zampini } 4260019a44ceSStefano Zampini 426106656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 42623301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4263ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 4264ffd830a3SStefano Zampini PetscScalar *marray; 426506656605SStefano Zampini 426606656605SStefano Zampini if (n_constraints) { 4267ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 426806656605SStefano Zampini 4269abc8f43dSstefano_zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 427006656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 4271ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 427216f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 427306656605SStefano Zampini if (n_vertices) { 4274ffd830a3SStefano Zampini Mat S_VCT; 427506656605SStefano Zampini 427606656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 4277ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 427816f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 427906656605SStefano Zampini } 4280ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 42815b782168SStefano Zampini } else { 42825b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 428306656605SStefano Zampini } 428416f15bc4SStefano Zampini if (n_vertices && n_R) { 4285ffd830a3SStefano Zampini PetscScalar *av,*marray; 4286ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 4287ffd830a3SStefano Zampini PetscInt n; 4288ffd830a3SStefano Zampini PetscBool flg_row; 428906656605SStefano Zampini 4290ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 4291af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4292ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4293ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 4294ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4295ffd830a3SStefano Zampini for (i=0;i<n;i++) { 4296ffd830a3SStefano Zampini PetscInt j; 4297ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 4298ffd830a3SStefano Zampini } 4299ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4300ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4301ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 430206656605SStefano Zampini } 430306656605SStefano Zampini 4304ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 4305abc8f43dSstefano_zampini if (n_vertices) { 4306ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4307ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 4308ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 4309ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 431006656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 431106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 431206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 431306656605SStefano Zampini } 4314ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4315abc8f43dSstefano_zampini } 43165b782168SStefano Zampini if (B_C) { 4317ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 4318ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 4319ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 4320ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 4321ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4322ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4323ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 432406656605SStefano Zampini } 4325ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 43265b782168SStefano Zampini } 432706656605SStefano Zampini /* coarse basis functions */ 432806656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 432906656605SStefano Zampini PetscScalar *y; 433006656605SStefano Zampini 4331ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 433206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 433306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 433406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 433506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 433606656605SStefano Zampini if (i<n_vertices) { 433706656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 433806656605SStefano Zampini } 433906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 434006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 434106656605SStefano Zampini 434206656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 434306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 434406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 434506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 434606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 434706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 434806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 434906656605SStefano Zampini } 435006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 435106656605SStefano Zampini } 4352ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 4353ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 435406656605SStefano Zampini } 4355a6e023c1Sstefano_zampini 4356d62866d3SStefano Zampini /* free memory */ 435788ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 435806656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 435906656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 436006656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 436106656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 4362d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4363d62866d3SStefano Zampini if (n_vertices) { 4364d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 4365d62866d3SStefano Zampini } 4366d62866d3SStefano Zampini if (n_constraints) { 4367d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 4368d62866d3SStefano Zampini } 436988ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 437088ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 437188ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 4372d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 437388ebb749SStefano Zampini Mat coarse_sub_mat; 437425084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 437588ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 437688ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 437788ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 43788bec7fa6SStefano Zampini Mat C_B,CPHI; 43798bec7fa6SStefano Zampini IS is_dummy; 43808bec7fa6SStefano Zampini Vec mones; 438188ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 438288ebb749SStefano Zampini PetscReal real_value; 438388ebb749SStefano Zampini 4384a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 4385a3df083aSStefano Zampini Mat A; 4386a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 43877dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 43887dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 43897dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 43907dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4391a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 4392a3df083aSStefano Zampini } else { 439388ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 439488ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 439588ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 439688ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4397a3df083aSStefano Zampini } 439888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 439988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 4400ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 440188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 440288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 440388ebb749SStefano Zampini } 440488ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 440588ebb749SStefano Zampini 440625084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 44073301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 440825084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4409ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 441088ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 441188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 441288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 441388ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 441488ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 441588ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 441688ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 441788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 441888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 441988ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 442088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 442188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 442288ebb749SStefano Zampini } else { 442388ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 442488ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 442588ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 442688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 442788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 442888ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 442988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 443088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 443188ebb749SStefano Zampini } 443288ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 443388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 443488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 4435511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 44364f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4437fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 4438d12edf2fSStefano Zampini PetscScalar *data,*data2; 44394f1b2e48SStefano Zampini PetscInt j; 4440d12edf2fSStefano Zampini 44414f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 44427dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 4443d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 444486c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 4445d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 4446d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 44474f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 44484f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 4449d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 44504f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 44514f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 44524f1b2e48SStefano Zampini } 4453d12edf2fSStefano Zampini } 4454d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 4455d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 4456d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4457d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4458d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4459d12edf2fSStefano Zampini } 4460d12edf2fSStefano Zampini #if 0 4461d12edf2fSStefano Zampini { 4462d12edf2fSStefano Zampini PetscViewer viewer; 4463d12edf2fSStefano Zampini char filename[256]; 4464ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4465d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4466a7414863SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4467ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4468ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4469ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4470d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 4471a7414863SStefano Zampini if (pcbddc->coarse_phi_B) { 4472ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4473ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 447472b8c272SStefano Zampini } 4475ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4476ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4477ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4478ffd830a3SStefano Zampini } 4479ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4480ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4481ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4482ffd830a3SStefano Zampini } 448372b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4484ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4485ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4486ffd830a3SStefano Zampini } 4487d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4488d12edf2fSStefano Zampini } 4489d12edf2fSStefano Zampini #endif 449081d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 44918bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 44921575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 449306656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 44948bec7fa6SStefano Zampini 44958bec7fa6SStefano Zampini /* check constraints */ 4496a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 44977dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 44984f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 44998bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4500a00504b5SStefano Zampini } else { 4501a00504b5SStefano Zampini PetscScalar *data; 4502a00504b5SStefano Zampini Mat tmat; 4503a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4504a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4505a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4506a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4507a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4508a00504b5SStefano Zampini } 45098bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 45108bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 45118bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 45128bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4513bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4514ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4515bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4516bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4517bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4518bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4519bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 452088ebb749SStefano Zampini } 45218bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 45228bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 45238bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 45248bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 452525084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 452688ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 452788ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 452888ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 452988ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 453088ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 453188ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 453288ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 453388ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 453488ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 453588ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4536ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 453788ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 453888ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 453988ebb749SStefano Zampini } 454088ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 454188ebb749SStefano Zampini } 45428629588bSStefano Zampini /* get back data */ 45438629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 454488ebb749SStefano Zampini PetscFunctionReturn(0); 454588ebb749SStefano Zampini } 454688ebb749SStefano Zampini 45477dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4548aa0d41d4SStefano Zampini { 4549d65f70fdSStefano Zampini Mat *work_mat; 4550d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4551d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4552c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4553aa0d41d4SStefano Zampini PetscErrorCode ierr; 4554aa0d41d4SStefano Zampini 4555aa0d41d4SStefano Zampini PetscFunctionBegin; 4556d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4557d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4558d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4559d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4560aa0d41d4SStefano Zampini 4561d65f70fdSStefano Zampini if (!rsorted) { 4562906d46d4SStefano Zampini const PetscInt *idxs; 4563906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4564aa0d41d4SStefano Zampini 4565d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4566d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4567d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4568d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4569aa0d41d4SStefano Zampini } 4570d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4571d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4572d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4573d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4574aa0d41d4SStefano Zampini } 4575d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4576d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4577d65f70fdSStefano Zampini } else { 4578d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4579d65f70fdSStefano Zampini isrow_s = isrow; 4580aa0d41d4SStefano Zampini } 4581906d46d4SStefano Zampini 4582d65f70fdSStefano Zampini if (!csorted) { 4583d65f70fdSStefano Zampini if (isrow == iscol) { 4584d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4585d65f70fdSStefano Zampini iscol_s = isrow_s; 4586d65f70fdSStefano Zampini } else { 4587d65f70fdSStefano Zampini const PetscInt *idxs; 4588d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4589906d46d4SStefano Zampini 4590d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4591d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4592d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4593d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4594d65f70fdSStefano Zampini } 4595d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 4596d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 4597d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4598d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 4599d65f70fdSStefano Zampini } 4600d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 4601d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 4602d65f70fdSStefano Zampini } 4603d65f70fdSStefano Zampini } else { 4604d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 4605d65f70fdSStefano Zampini iscol_s = iscol; 4606d65f70fdSStefano Zampini } 4607d65f70fdSStefano Zampini 46087dae84e0SHong Zhang ierr = MatCreateSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4609d65f70fdSStefano Zampini 4610d65f70fdSStefano Zampini if (!rsorted || !csorted) { 4611906d46d4SStefano Zampini Mat new_mat; 4612d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 4613906d46d4SStefano Zampini 4614d65f70fdSStefano Zampini if (!rsorted) { 4615d65f70fdSStefano Zampini PetscInt *idxs_r,i; 4616d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 4617d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4618d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 4619906d46d4SStefano Zampini } 4620d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 4621d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 4622d65f70fdSStefano Zampini } else { 4623d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 4624906d46d4SStefano Zampini } 4625d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 4626d65f70fdSStefano Zampini 4627d65f70fdSStefano Zampini if (!csorted) { 4628d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 4629d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 4630d65f70fdSStefano Zampini is_perm_c = is_perm_r; 4631d65f70fdSStefano Zampini } else { 4632d65f70fdSStefano Zampini PetscInt *idxs_c,i; 4633f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 4634d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 4635d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4636d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 4637d65f70fdSStefano Zampini } 4638d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 4639d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 4640d65f70fdSStefano Zampini } 4641d65f70fdSStefano Zampini } else { 4642d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 4643d65f70fdSStefano Zampini } 4644d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 4645d65f70fdSStefano Zampini 4646d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 4647d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 4648d65f70fdSStefano Zampini work_mat[0] = new_mat; 4649d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 4650d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 4651d65f70fdSStefano Zampini } 4652d65f70fdSStefano Zampini 4653d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 4654d65f70fdSStefano Zampini *B = work_mat[0]; 4655d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 4656d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 4657d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 4658d65f70fdSStefano Zampini PetscFunctionReturn(0); 4659d65f70fdSStefano Zampini } 4660d65f70fdSStefano Zampini 46615e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 4662aa0d41d4SStefano Zampini { 4663aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 46645e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4665022d8d2bSstefano_zampini Mat new_mat,lA; 46665e8657edSStefano Zampini IS is_local,is_global; 4667d65f70fdSStefano Zampini PetscInt local_size; 4668d65f70fdSStefano Zampini PetscBool isseqaij; 4669aa0d41d4SStefano Zampini PetscErrorCode ierr; 4670aa0d41d4SStefano Zampini 4671aa0d41d4SStefano Zampini PetscFunctionBegin; 4672aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 46735e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 46745e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 4675b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 4676aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 46777dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 4678aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 4679906d46d4SStefano Zampini 4680906d46d4SStefano Zampini /* check */ 4681906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4682906d46d4SStefano Zampini Vec x,x_change; 4683906d46d4SStefano Zampini PetscReal error; 4684906d46d4SStefano Zampini 46855e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 4686906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 46875e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 4688e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4689e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4690d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 469188428137SStefano Zampini if (!pcbddc->change_interior) { 469288428137SStefano Zampini const PetscScalar *x,*y,*v; 469388428137SStefano Zampini PetscReal lerror = 0.; 469488428137SStefano Zampini PetscInt i; 469588428137SStefano Zampini 469688428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 469788428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 469888428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 469988428137SStefano Zampini for (i=0;i<local_size;i++) 470088428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 470188428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 470288428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 470388428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 470488428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 470588428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4706637e8532SStefano Zampini if (error > PETSC_SMALL) { 4707637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4708637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on I: %1.6e\n",error); 4709637e8532SStefano Zampini } else { 4710637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on I: %1.6e\n",error); 4711637e8532SStefano Zampini } 4712637e8532SStefano Zampini } 471388428137SStefano Zampini } 4714e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4715e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4716906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4717906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4718637e8532SStefano Zampini if (error > PETSC_SMALL) { 4719637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4720637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 4721637e8532SStefano Zampini } else { 4722637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on N: %1.6e\n",error); 4723637e8532SStefano Zampini } 4724637e8532SStefano Zampini } 4725906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4726906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4727906d46d4SStefano Zampini } 4728906d46d4SStefano Zampini 4729022d8d2bSstefano_zampini /* lA is present if we are setting up an inner BDDC for a saddle point FETI-DP */ 4730022d8d2bSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 4731022d8d2bSstefano_zampini 473222d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 47339b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 473422d5777bSStefano Zampini if (isseqaij) { 4735a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4736a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 4737022d8d2bSstefano_zampini if (lA) { 4738022d8d2bSstefano_zampini Mat work; 4739022d8d2bSstefano_zampini ierr = MatPtAP(lA,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4740022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4741022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4742022d8d2bSstefano_zampini } 4743aa0d41d4SStefano Zampini } else { 4744a00504b5SStefano Zampini Mat work_mat; 47451cf9b237SStefano Zampini 4746a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4747aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4748a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 47491d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 4750022d8d2bSstefano_zampini if (lA) { 4751022d8d2bSstefano_zampini Mat work; 4752022d8d2bSstefano_zampini ierr = MatConvert(lA,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4753022d8d2bSstefano_zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4754022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4755022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4756022d8d2bSstefano_zampini } 4757aa0d41d4SStefano Zampini } 47583301b35fSStefano Zampini if (matis->A->symmetric_set) { 47593301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 4760e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 47613301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 4762e496cd5dSStefano Zampini #endif 47633301b35fSStefano Zampini } 4764d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 4765aa0d41d4SStefano Zampini PetscFunctionReturn(0); 4766aa0d41d4SStefano Zampini } 4767aa0d41d4SStefano Zampini 47688ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 4769a64d13efSStefano Zampini { 4770a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4771a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4772d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 477353892102SStefano Zampini PetscInt *idx_R_local=NULL; 47743a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 47753a50541eSStefano Zampini PetscInt vbs,bs; 47766816873aSStefano Zampini PetscBT bitmask=NULL; 4777a64d13efSStefano Zampini PetscErrorCode ierr; 4778a64d13efSStefano Zampini 4779a64d13efSStefano Zampini PetscFunctionBegin; 4780b23d619eSStefano Zampini /* 4781b23d619eSStefano Zampini No need to setup local scatters if 4782b23d619eSStefano Zampini - primal space is unchanged 4783b23d619eSStefano Zampini AND 4784b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 4785b23d619eSStefano Zampini AND 4786b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 4787b23d619eSStefano Zampini */ 4788b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 4789f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 4790f4ddd8eeSStefano Zampini } 4791f4ddd8eeSStefano Zampini /* destroy old objects */ 4792f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 4793f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 4794f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 4795a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 4796b371cd4fSStefano Zampini n_B = pcis->n_B; 4797b371cd4fSStefano Zampini n_D = pcis->n - n_B; 4798b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 47993a50541eSStefano Zampini 4800a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 48016816873aSStefano Zampini 480253892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 4803b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4804854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 4805a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 4806a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 48070e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 4808a64d13efSStefano Zampini } 4809a64d13efSStefano Zampini 4810a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 48114641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 48126816873aSStefano Zampini idx_R_local[n_R++] = i; 4813a64d13efSStefano Zampini } 4814a64d13efSStefano Zampini } 4815df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 4816df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 48176816873aSStefano Zampini 4818df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4819df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 48206816873aSStefano Zampini } 48213a50541eSStefano Zampini 48223a50541eSStefano Zampini /* Block code */ 48233a50541eSStefano Zampini vbs = 1; 48243a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 48253a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 48263a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 48273a50541eSStefano Zampini PetscInt *vary; 4828b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4829785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 48303a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 4831d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 4832d3df7717SStefano 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 */ 48330e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 4834d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 48353a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 48363a50541eSStefano Zampini is_blocked = PETSC_FALSE; 48373a50541eSStefano Zampini break; 48383a50541eSStefano Zampini } 48393a50541eSStefano Zampini } 4840d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 4841d3df7717SStefano Zampini } else { 4842d3df7717SStefano Zampini /* Verify directly the R set */ 4843d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 4844d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 4845d3df7717SStefano Zampini for (j=1; j<bs; j++) { 4846d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 4847d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 4848d3df7717SStefano Zampini break; 4849d3df7717SStefano Zampini } 4850d3df7717SStefano Zampini } 4851d3df7717SStefano Zampini } 4852d3df7717SStefano Zampini } 48533a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 48543a50541eSStefano Zampini vbs = bs; 48553a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 48563a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 48573a50541eSStefano Zampini } 48583a50541eSStefano Zampini } 48593a50541eSStefano Zampini } 48603a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 4861b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4862df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 486353892102SStefano Zampini 4864df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4865df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 486653892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 4867df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 486853892102SStefano Zampini } else { 48693a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 487053892102SStefano Zampini } 4871a64d13efSStefano Zampini 4872a64d13efSStefano Zampini /* print some info if requested */ 4873a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 4874a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4875a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 48761575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4877a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 4878a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 48794f1b2e48SStefano 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); 4880a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4881a64d13efSStefano Zampini } 4882a64d13efSStefano Zampini 4883a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 4884b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 48856816873aSStefano Zampini IS is_aux1,is_aux2; 48866816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 48876816873aSStefano Zampini 48883a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4889854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 4890854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 4891a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 48924641a718SStefano Zampini for (i=0; i<n_D; i++) { 48934641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 48944641a718SStefano Zampini } 4895a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4896a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 48974641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 48984641a718SStefano Zampini aux_array1[j++] = i; 4899a64d13efSStefano Zampini } 4900a64d13efSStefano Zampini } 4901a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4902a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4903a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 49044641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 49054641a718SStefano Zampini aux_array2[j++] = i; 4906a64d13efSStefano Zampini } 4907a64d13efSStefano Zampini } 4908a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4909a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 4910a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 4911a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4912a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 4913a64d13efSStefano Zampini 49148eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4915785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 4916a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 49174641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 49184641a718SStefano Zampini aux_array1[j++] = i; 4919a64d13efSStefano Zampini } 4920a64d13efSStefano Zampini } 4921a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4922a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 4923a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4924a64d13efSStefano Zampini } 49254641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 49263a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4927d62866d3SStefano Zampini } else { 4928df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 49296816873aSStefano Zampini IS tis; 49306816873aSStefano Zampini PetscInt schur_size; 49316816873aSStefano Zampini 4932df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 49336816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 4934df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 49356816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 49366816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 49376816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 49386816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 49396816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 4940d62866d3SStefano Zampini } 4941d62866d3SStefano Zampini } 4942a64d13efSStefano Zampini PetscFunctionReturn(0); 4943a64d13efSStefano Zampini } 4944a64d13efSStefano Zampini 4945304d26faSStefano Zampini 4946684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 4947304d26faSStefano Zampini { 4948304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 4949304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 4950304d26faSStefano Zampini PC pc_temp; 4951304d26faSStefano Zampini Mat A_RR; 4952f4ddd8eeSStefano Zampini MatReuse reuse; 4953304d26faSStefano Zampini PetscScalar m_one = -1.0; 4954304d26faSStefano Zampini PetscReal value; 495504708bb6SStefano Zampini PetscInt n_D,n_R; 495635529e7bSStefano Zampini PetscBool check_corr,issbaij; 4957304d26faSStefano Zampini PetscErrorCode ierr; 4958e604994aSStefano Zampini /* prefixes stuff */ 4959312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 4960e604994aSStefano Zampini size_t len; 4961304d26faSStefano Zampini 4962304d26faSStefano Zampini PetscFunctionBegin; 4963304d26faSStefano Zampini 4964e604994aSStefano Zampini /* compute prefixes */ 4965e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 4966e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 4967e604994aSStefano Zampini if (!pcbddc->current_level) { 4968e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4969e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 4970e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4971e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4972e604994aSStefano Zampini } else { 497335529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 4974e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 4975e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 4976312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 4977312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 497834d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 497934d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 4980e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 4981e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 4982e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 4983e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 4984e604994aSStefano Zampini } 4985e604994aSStefano Zampini 4986304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 4987684f6988SStefano Zampini if (dirichlet) { 4988d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 4989450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 49909a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 4991450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 4992a3df083aSStefano Zampini Mat A_IIn; 4993a3df083aSStefano Zampini 4994a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 4995a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 4996a3df083aSStefano Zampini pcis->A_II = A_IIn; 4997a3df083aSStefano Zampini } 4998450f8f5eSStefano Zampini } 49993301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 50003301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 5001964fefecSStefano Zampini } 5002ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 5003964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 5004304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 5005304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 5006304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 5007304d26faSStefano Zampini /* default */ 5008304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 5009e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 50109577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 5011304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 50129577ea80SStefano Zampini if (issbaij) { 50139577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 50149577ea80SStefano Zampini } else { 5015304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 50169577ea80SStefano Zampini } 5017304d26faSStefano Zampini /* Allow user's customization */ 5018304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 5019304d26faSStefano Zampini } 5020d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 5021b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5022df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5023d62866d3SStefano Zampini 5024df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 5025d5574798SStefano Zampini } 5026304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5027304d26faSStefano Zampini if (!n_D) { 5028304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 5029304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5030304d26faSStefano Zampini } 5031304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 5032304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 5033304d26faSStefano Zampini /* set ksp_D into pcis data */ 5034304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 5035304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 5036304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 5037684f6988SStefano Zampini } 5038304d26faSStefano Zampini 5039304d26faSStefano Zampini /* NEUMANN PROBLEM */ 5040684f6988SStefano Zampini A_RR = 0; 5041684f6988SStefano Zampini if (neumann) { 5042d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 504304708bb6SStefano Zampini PetscInt ibs,mbs; 50440aa714b2SStefano Zampini PetscBool issbaij, reuse_neumann_solver; 504504708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 50460aa714b2SStefano Zampini 50470aa714b2SStefano Zampini reuse_neumann_solver = PETSC_FALSE; 50480aa714b2SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 50490aa714b2SStefano Zampini IS iP; 50500aa714b2SStefano Zampini 50510aa714b2SStefano Zampini reuse_neumann_solver = PETSC_TRUE; 50520aa714b2SStefano Zampini ierr = PetscObjectQuery((PetscObject)sub_schurs->A,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 50530aa714b2SStefano Zampini if (iP) reuse_neumann_solver = PETSC_FALSE; 50540aa714b2SStefano Zampini } 5055f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 50568ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 5057f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 5058f4ddd8eeSStefano Zampini PetscInt nn_R; 505981d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 5060f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5061f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 5062f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 5063f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 5064f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5065f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5066f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 5067727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 5068f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5069f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5070f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 5071f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 5072f4ddd8eeSStefano Zampini } 5073f4ddd8eeSStefano Zampini } 5074f4ddd8eeSStefano Zampini /* last check */ 5075d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 5076f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5077f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5078f4ddd8eeSStefano Zampini } 5079f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 5080f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5081f4ddd8eeSStefano Zampini } 5082a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 5083af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 5084af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 508504708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 508604708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 508704708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 508804708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 508904708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 5090af732b37SStefano Zampini } else { 5091511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 50926816873aSStefano Zampini } 509304708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 509404708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 509504708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 509604708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 509704708bb6SStefano Zampini } else { 5098511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 509904708bb6SStefano Zampini } 510004708bb6SStefano Zampini } 5101a00504b5SStefano Zampini /* extract A_RR */ 51020aa714b2SStefano Zampini if (reuse_neumann_solver) { 5103a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5104a00504b5SStefano Zampini 5105a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 510616e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5107a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 510816e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 510916e386b8SStefano Zampini } else { 51107dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 5111a00504b5SStefano Zampini } 5112a00504b5SStefano Zampini } else { 5113a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5114a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 5115a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5116a00504b5SStefano Zampini } 5117a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 51187dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 511916e386b8SStefano Zampini } 51203301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 51213301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 51226816873aSStefano Zampini } 5123f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 5124304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 5125304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 5126304d26faSStefano Zampini /* default */ 5127304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 5128e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 5129304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 51309577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 51319577ea80SStefano Zampini if (issbaij) { 51329577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 51339577ea80SStefano Zampini } else { 5134304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 51359577ea80SStefano Zampini } 5136304d26faSStefano Zampini /* Allow user's customization */ 5137304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 5138304d26faSStefano Zampini } 5139304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5140304d26faSStefano Zampini if (!n_R) { 5141304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 5142304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5143304d26faSStefano Zampini } 51445cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 5145df4d28bfSStefano Zampini /* Reuse solver if it is present */ 51460aa714b2SStefano Zampini if (reuse_neumann_solver) { 5147df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5148d62866d3SStefano Zampini 5149df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 5150d62866d3SStefano Zampini } 5151304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 5152304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 5153684f6988SStefano Zampini } 5154304d26faSStefano Zampini 5155684f6988SStefano Zampini if (pcbddc->dbg_flag) { 5156684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 51571575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5158684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5159684f6988SStefano Zampini } 5160c7017625SStefano Zampini 5161c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 516235529e7bSStefano Zampini check_corr = PETSC_FALSE; 5163c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 5164c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 5165c7017625SStefano Zampini } 5166c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 516735529e7bSStefano Zampini check_corr = PETSC_TRUE; 5168c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 5169c7017625SStefano Zampini } 5170c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 517135529e7bSStefano Zampini check_corr = PETSC_TRUE; 5172c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 5173c7017625SStefano Zampini } 5174c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 5175c7017625SStefano Zampini if (pcbddc->dbg_flag) { 5176684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 51770fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 51780fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 51790fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 51800fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 51810fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 5182e604994aSStefano 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); 518335529e7bSStefano Zampini if (check_corr) { 5184c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 5185c7017625SStefano Zampini } 5186304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5187304d26faSStefano Zampini } 5188684f6988SStefano Zampini if (neumann) { /* Neumann */ 51890fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 51900fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 51910fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 51920fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 51930fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 5194e604994aSStefano 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); 519535529e7bSStefano Zampini if (check_corr) { 5196c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 5197c7017625SStefano Zampini } 5198304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5199304d26faSStefano Zampini } 5200684f6988SStefano Zampini } 52015cbda25cSStefano Zampini /* free Neumann problem's matrix */ 52025cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5203304d26faSStefano Zampini PetscFunctionReturn(0); 5204304d26faSStefano Zampini } 5205304d26faSStefano Zampini 520680677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 5207674ae819SStefano Zampini { 5208674ae819SStefano Zampini PetscErrorCode ierr; 5209674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5210be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5211b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 5212674ae819SStefano Zampini 5213674ae819SStefano Zampini PetscFunctionBegin; 5214b334f244SStefano Zampini if (!reuse_solver) { 521580677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 521620c7b377SStefano Zampini } 521780677318SStefano Zampini if (!pcbddc->switch_static) { 521880677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 521980677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 522080677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 522120c7b377SStefano Zampini } 5222b334f244SStefano Zampini if (!reuse_solver) { 522380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 522480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 522520c7b377SStefano Zampini } else { 5226df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5227be83ff47SStefano Zampini 5228df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5229df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 523020c7b377SStefano Zampini } 5231be83ff47SStefano Zampini } else { 523280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 523380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 523480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 523580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 523680677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 523780677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 523880677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 523980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 524080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5241674ae819SStefano Zampini } 5242674ae819SStefano Zampini } 5243b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 524480677318SStefano Zampini if (applytranspose) { 524580677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 524680677318SStefano Zampini } else { 524780677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 524880677318SStefano Zampini } 5249be83ff47SStefano Zampini } else { 5250df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5251be83ff47SStefano Zampini 5252be83ff47SStefano Zampini if (applytranspose) { 5253df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5254be83ff47SStefano Zampini } else { 5255df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5256be83ff47SStefano Zampini } 5257be83ff47SStefano Zampini } 525880677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 525980677318SStefano Zampini if (!pcbddc->switch_static) { 5260b334f244SStefano Zampini if (!reuse_solver) { 526180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 526280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5263be83ff47SStefano Zampini } else { 5264df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5265be83ff47SStefano Zampini 5266df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5267df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5268be83ff47SStefano Zampini } 526980677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 527080677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 527180677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 527280677318SStefano Zampini } 527380677318SStefano Zampini } else { 527480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 527580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 527680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 527780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 527880677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 527980677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 528080677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 528180677318SStefano Zampini } 528280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 528380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 528480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 528580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5286674ae819SStefano Zampini } 5287674ae819SStefano Zampini PetscFunctionReturn(0); 5288674ae819SStefano Zampini } 5289674ae819SStefano Zampini 5290dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 5291dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 5292674ae819SStefano Zampini { 5293674ae819SStefano Zampini PetscErrorCode ierr; 5294674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5295674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 5296674ae819SStefano Zampini const PetscScalar zero = 0.0; 5297674ae819SStefano Zampini 5298674ae819SStefano Zampini PetscFunctionBegin; 5299d4a6ed37SStefano Zampini PetscBool ss = PETSC_FALSE; 5300d4a6ed37SStefano Zampini ierr = PetscOptionsGetBool(NULL,NULL,"-swap",&ss,NULL);CHKERRQ(ierr); 5301d4a6ed37SStefano Zampini if (ss) { 5302d4a6ed37SStefano Zampini Mat save_B = pcbddc->coarse_phi_B; 5303d4a6ed37SStefano Zampini pcbddc->coarse_phi_B = pcbddc->coarse_psi_B; 5304d4a6ed37SStefano Zampini pcbddc->coarse_psi_B = save_B; 5305d4a6ed37SStefano Zampini Mat save_D = pcbddc->coarse_phi_D; 5306d4a6ed37SStefano Zampini pcbddc->coarse_phi_D = pcbddc->coarse_psi_D; 5307d4a6ed37SStefano Zampini pcbddc->coarse_psi_D = save_D; 5308d4a6ed37SStefano Zampini } 5309dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 53104fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5311dc359a40SStefano Zampini if (applytranspose) { 5312674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 53138eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 5314dc359a40SStefano Zampini } else { 5315674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 5316674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 531715aaf578SStefano Zampini } 53184fee134fSStefano Zampini } else { 53194fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 53204fee134fSStefano Zampini } 5321efc2fbd9SStefano Zampini 5322efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 53234f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5324efc2fbd9SStefano Zampini PetscScalar *array; 53254f1b2e48SStefano Zampini PetscInt j; 5326efc2fbd9SStefano Zampini 5327efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 53284f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 5329efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5330efc2fbd9SStefano Zampini } 5331efc2fbd9SStefano Zampini 533212edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 533312edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 533412edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 533512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 533612edc857SStefano Zampini 53379f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 533812edc857SStefano Zampini if (pcbddc->coarse_ksp) { 533951694757SStefano Zampini Mat coarse_mat; 5340964fefecSStefano Zampini Vec rhs,sol; 534151694757SStefano Zampini MatNullSpace nullsp; 534227b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 5343964fefecSStefano Zampini 534427b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 534527b6a85dSStefano Zampini PC coarse_pc; 534627b6a85dSStefano Zampini 534727b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 534827b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 534927b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 535027b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 535127b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 535227b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 53533bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 535427b6a85dSStefano Zampini } 535527b6a85dSStefano Zampini } 5356964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 5357964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 535851694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 535951694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 536051694757SStefano Zampini if (nullsp) { 536151694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 536251694757SStefano Zampini } 536312edc857SStefano Zampini if (applytranspose) { 53649a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 5365964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 53662701bc32SStefano Zampini } else { 53671f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 53682701bc32SStefano Zampini PC coarse_pc; 53692701bc32SStefano Zampini 53702701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 53712701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 53723e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 53732701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 537412edc857SStefano Zampini } else { 5375964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 537612edc857SStefano Zampini } 53772701bc32SStefano Zampini } 53781d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 537927b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 538027b6a85dSStefano Zampini PC coarse_pc; 538127b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 538227b6a85dSStefano Zampini 538327b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 538427b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 538527b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 53863bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 538727b6a85dSStefano Zampini } 538851694757SStefano Zampini if (nullsp) { 538951694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 539051694757SStefano Zampini } 539112edc857SStefano Zampini } 5392674ae819SStefano Zampini 5393674ae819SStefano Zampini /* Local solution on R nodes */ 53944fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 539580677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 53969f00e9b4SStefano Zampini } 53979f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 53989f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 539912edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5400674ae819SStefano Zampini 54014fee134fSStefano Zampini /* Sum contributions from the two levels */ 54024fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5403dc359a40SStefano Zampini if (applytranspose) { 5404dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5405dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5406dc359a40SStefano Zampini } else { 5407674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 54088eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5409dc359a40SStefano Zampini } 5410efc2fbd9SStefano Zampini /* store p0 */ 54114f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5412efc2fbd9SStefano Zampini PetscScalar *array; 54134f1b2e48SStefano Zampini PetscInt j; 5414efc2fbd9SStefano Zampini 5415efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 54164f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 5417efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5418efc2fbd9SStefano Zampini } 54194fee134fSStefano Zampini } else { /* expand the coarse solution */ 54204fee134fSStefano Zampini if (applytranspose) { 54214fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 54224fee134fSStefano Zampini } else { 54234fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 54244fee134fSStefano Zampini } 54254fee134fSStefano Zampini } 5426d4a6ed37SStefano Zampini if (ss) { 5427d4a6ed37SStefano Zampini Mat save_B = pcbddc->coarse_phi_B; 5428d4a6ed37SStefano Zampini pcbddc->coarse_phi_B = pcbddc->coarse_psi_B; 5429d4a6ed37SStefano Zampini pcbddc->coarse_psi_B = save_B; 5430d4a6ed37SStefano Zampini Mat save_D = pcbddc->coarse_phi_D; 5431d4a6ed37SStefano Zampini pcbddc->coarse_phi_D = pcbddc->coarse_psi_D; 5432d4a6ed37SStefano Zampini pcbddc->coarse_psi_D = save_D; 5433d4a6ed37SStefano Zampini } 5434674ae819SStefano Zampini PetscFunctionReturn(0); 5435674ae819SStefano Zampini } 5436674ae819SStefano Zampini 543712edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 5438674ae819SStefano Zampini { 5439674ae819SStefano Zampini PetscErrorCode ierr; 5440674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 544158da7f69SStefano Zampini PetscScalar *array; 544212edc857SStefano Zampini Vec from,to; 5443674ae819SStefano Zampini 5444674ae819SStefano Zampini PetscFunctionBegin; 544512edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 544612edc857SStefano Zampini from = pcbddc->coarse_vec; 544712edc857SStefano Zampini to = pcbddc->vec1_P; 544812edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 544912edc857SStefano Zampini Vec tvec; 545058da7f69SStefano Zampini 545158da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 545258da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 545312edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 545458da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 545558da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 545658da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 545712edc857SStefano Zampini } 545812edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 545912edc857SStefano Zampini from = pcbddc->vec1_P; 546012edc857SStefano Zampini to = pcbddc->coarse_vec; 546112edc857SStefano Zampini } 546212edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 5463674ae819SStefano Zampini PetscFunctionReturn(0); 5464674ae819SStefano Zampini } 5465674ae819SStefano Zampini 546612edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 5467674ae819SStefano Zampini { 5468674ae819SStefano Zampini PetscErrorCode ierr; 5469674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 547058da7f69SStefano Zampini PetscScalar *array; 547112edc857SStefano Zampini Vec from,to; 5472674ae819SStefano Zampini 5473674ae819SStefano Zampini PetscFunctionBegin; 547412edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 547512edc857SStefano Zampini from = pcbddc->coarse_vec; 547612edc857SStefano Zampini to = pcbddc->vec1_P; 547712edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 547812edc857SStefano Zampini from = pcbddc->vec1_P; 547912edc857SStefano Zampini to = pcbddc->coarse_vec; 548012edc857SStefano Zampini } 548112edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 548212edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 548312edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 548412edc857SStefano Zampini Vec tvec; 548558da7f69SStefano Zampini 548612edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 548758da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 548858da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 548958da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 549058da7f69SStefano Zampini } 549158da7f69SStefano Zampini } else { 549258da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 549358da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 549412edc857SStefano Zampini } 549512edc857SStefano Zampini } 5496674ae819SStefano Zampini PetscFunctionReturn(0); 5497674ae819SStefano Zampini } 5498674ae819SStefano Zampini 5499984c4197SStefano Zampini /* uncomment for testing purposes */ 5500984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 5501674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 5502674ae819SStefano Zampini { 5503674ae819SStefano Zampini PetscErrorCode ierr; 5504674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5505674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5506674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5507984c4197SStefano Zampini /* one and zero */ 5508984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 5509984c4197SStefano Zampini /* space to store constraints and their local indices */ 55109162d606SStefano Zampini PetscScalar *constraints_data; 55119162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 55129162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 55139162d606SStefano Zampini PetscInt *constraints_n; 5514984c4197SStefano Zampini /* iterators */ 5515b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 5516984c4197SStefano Zampini /* BLAS integers */ 5517e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 5518e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 5519c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 5520727cdba6SStefano Zampini /* reuse */ 55210e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 55220e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 5523984c4197SStefano Zampini /* change of basis */ 5524b3d85658SStefano Zampini PetscBool qr_needed; 55259162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 5526984c4197SStefano Zampini /* auxiliary stuff */ 552764efe560SStefano Zampini PetscInt *nnz,*is_indices; 55288a0068c3SStefano Zampini PetscInt ncc; 5529984c4197SStefano Zampini /* some quantities */ 553045a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 5531a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 5532984c4197SStefano Zampini 5533674ae819SStefano Zampini PetscFunctionBegin; 55348e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 55358e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 55368e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 553716909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 5538088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 5539088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 55400e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 55410e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 55420e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 55430e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 55440e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 5545088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5546cf5a6209SStefano Zampini 5547cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 55489162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 5549cf5a6209SStefano Zampini MatNullSpace nearnullsp; 5550cf5a6209SStefano Zampini const Vec *nearnullvecs; 5551cf5a6209SStefano Zampini Vec *localnearnullsp; 5552cf5a6209SStefano Zampini PetscScalar *array; 5553cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 5554cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 5555674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 5556b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 5557674ae819SStefano Zampini PetscScalar *work; 5558674ae819SStefano Zampini PetscReal *singular_vals; 5559674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5560674ae819SStefano Zampini PetscReal *rwork; 5561674ae819SStefano Zampini #endif 5562674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5563674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 5564674ae819SStefano Zampini #else 5565964fefecSStefano Zampini PetscBLASInt dummy_int=1; 5566964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 5567674ae819SStefano Zampini #endif 5568674ae819SStefano Zampini 5569674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 5570d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 5571e4d548c7SStefano Zampini /* print some info */ 55725c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 5573e4d548c7SStefano Zampini PetscInt nv; 5574e4d548c7SStefano Zampini 5575c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5576e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 5577e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5578e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5579e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 5580e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 5581e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 5582e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5583e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5584e4d548c7SStefano Zampini } 5585e4d548c7SStefano Zampini 5586d06fc5fdSStefano Zampini /* free unneeded index sets */ 5587d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 5588d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 5589674ae819SStefano Zampini } 5590d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 5591d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5592d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5593d06fc5fdSStefano Zampini } 5594d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5595d06fc5fdSStefano Zampini n_ISForEdges = 0; 5596d06fc5fdSStefano Zampini } 5597d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 5598d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5599d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5600d06fc5fdSStefano Zampini } 5601d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5602d06fc5fdSStefano Zampini n_ISForFaces = 0; 5603d06fc5fdSStefano Zampini } 560470022509SStefano Zampini 5605674ae819SStefano Zampini /* check if near null space is attached to global mat */ 5606674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 5607674ae819SStefano Zampini if (nearnullsp) { 5608674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 5609f4ddd8eeSStefano Zampini /* remove any stored info */ 5610f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 5611f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5612f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 5613f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 5614f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 5615473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5616f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 5617f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 5618f4ddd8eeSStefano Zampini } 5619984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 5620984c4197SStefano Zampini nnsp_size = 0; 5621674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 5622674ae819SStefano Zampini } 5623984c4197SStefano Zampini /* get max number of constraints on a single cc */ 5624984c4197SStefano Zampini max_constraints = nnsp_size; 5625984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 5626984c4197SStefano Zampini 5627674ae819SStefano Zampini /* 5628674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 56299162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 56309162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 56319162d606SStefano Zampini There can be multiple constraints per connected component 5632674ae819SStefano Zampini */ 5633674ae819SStefano Zampini n_vertices = 0; 5634674ae819SStefano Zampini if (ISForVertices) { 5635674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 5636674ae819SStefano Zampini } 56379162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 56389162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 56399162d606SStefano Zampini 56409162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 56419162d606SStefano Zampini total_counts *= max_constraints; 5642674ae819SStefano Zampini total_counts += n_vertices; 56434641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 56449162d606SStefano Zampini 5645674ae819SStefano Zampini total_counts = 0; 5646674ae819SStefano Zampini max_size_of_constraint = 0; 5647674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 56489162d606SStefano Zampini IS used_is; 5649674ae819SStefano Zampini if (i<n_ISForEdges) { 56509162d606SStefano Zampini used_is = ISForEdges[i]; 5651674ae819SStefano Zampini } else { 56529162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 5653674ae819SStefano Zampini } 56549162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 5655674ae819SStefano Zampini total_counts += j; 5656674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 5657674ae819SStefano Zampini } 56589162d606SStefano 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); 56599162d606SStefano Zampini 5660984c4197SStefano Zampini /* get local part of global near null space vectors */ 5661785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 5662984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5663984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 5664e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5665e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5666984c4197SStefano Zampini } 5667674ae819SStefano Zampini 5668242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 5669242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 5670a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 5671242a89d7SStefano Zampini 5672984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 5673a773dcb8SStefano Zampini if (!skip_lapack) { 5674674ae819SStefano Zampini PetscScalar temp_work; 5675911cabfeSStefano Zampini 5676674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5677984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 5678785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 5679785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 5680785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 5681674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5682785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 5683674ae819SStefano Zampini #endif 5684674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5685c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 5686c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 5687674ae819SStefano Zampini lwork = -1; 5688674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5689674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5690c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 5691674ae819SStefano Zampini #else 5692c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 5693674ae819SStefano Zampini #endif 5694674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5695984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 5696674ae819SStefano Zampini #else /* on missing GESVD */ 5697674ae819SStefano Zampini /* SVD */ 5698674ae819SStefano Zampini PetscInt max_n,min_n; 5699674ae819SStefano Zampini max_n = max_size_of_constraint; 5700984c4197SStefano Zampini min_n = max_constraints; 5701984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 5702674ae819SStefano Zampini min_n = max_size_of_constraint; 5703984c4197SStefano Zampini max_n = max_constraints; 5704674ae819SStefano Zampini } 5705785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 5706674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5707785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 5708674ae819SStefano Zampini #endif 5709674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5710674ae819SStefano Zampini lwork = -1; 5711e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 5712e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 5713b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 5714674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5715674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 57169162d606SStefano 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)); 5717674ae819SStefano Zampini #else 57189162d606SStefano 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)); 5719674ae819SStefano Zampini #endif 5720674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5721984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 5722984c4197SStefano Zampini #endif /* on missing GESVD */ 5723674ae819SStefano Zampini /* Allocate optimal workspace */ 5724674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 5725854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 5726674ae819SStefano Zampini } 5727674ae819SStefano Zampini /* Now we can loop on constraining sets */ 5728674ae819SStefano Zampini total_counts = 0; 57299162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 57309162d606SStefano Zampini constraints_data_ptr[0] = 0; 5731674ae819SStefano Zampini /* vertices */ 57329162d606SStefano Zampini if (n_vertices) { 5733674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 57349162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 5735674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 57369162d606SStefano Zampini constraints_n[total_counts] = 1; 57379162d606SStefano Zampini constraints_data[total_counts] = 1.0; 57389162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 57399162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 5740674ae819SStefano Zampini total_counts++; 5741674ae819SStefano Zampini } 5742674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5743674ae819SStefano Zampini n_vertices = total_counts; 5744674ae819SStefano Zampini } 5745984c4197SStefano Zampini 5746674ae819SStefano Zampini /* edges and faces */ 57479162d606SStefano Zampini total_counts_cc = total_counts; 5748911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 57499162d606SStefano Zampini IS used_is; 57509162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 57519162d606SStefano Zampini 5752911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 57539162d606SStefano Zampini used_is = ISForEdges[ncc]; 5754984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 5755674ae819SStefano Zampini } else { 57569162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 5757984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 5758674ae819SStefano Zampini } 5759674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 57609162d606SStefano Zampini 57619162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 57629162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5763984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 5764984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 5765674ae819SStefano Zampini if (nnsp_has_cnst) { 57665b08dc53SStefano Zampini PetscScalar quad_value; 57679162d606SStefano Zampini 57689162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 57699162d606SStefano Zampini idxs_copied = PETSC_TRUE; 57709162d606SStefano Zampini 5771a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 5772674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 5773a773dcb8SStefano Zampini } else { 5774a773dcb8SStefano Zampini quad_value = 1.0; 5775a773dcb8SStefano Zampini } 5776674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 57779162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 5778674ae819SStefano Zampini } 57799162d606SStefano Zampini temp_constraints++; 5780674ae819SStefano Zampini total_counts++; 5781674ae819SStefano Zampini } 5782674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 5783984c4197SStefano Zampini PetscReal real_value; 57849162d606SStefano Zampini PetscScalar *ptr_to_data; 57859162d606SStefano Zampini 5786984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 57879162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 5788674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 57899162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 5790674ae819SStefano Zampini } 5791984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 5792984c4197SStefano Zampini /* check if array is null on the connected component */ 5793e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 57949162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 57955b08dc53SStefano Zampini if (real_value > 0.0) { /* keep indices and values */ 5796674ae819SStefano Zampini temp_constraints++; 5797674ae819SStefano Zampini total_counts++; 57989162d606SStefano Zampini if (!idxs_copied) { 57999162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 58009162d606SStefano Zampini idxs_copied = PETSC_TRUE; 5801674ae819SStefano Zampini } 5802674ae819SStefano Zampini } 58039162d606SStefano Zampini } 58049162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 580545a1bb75SStefano Zampini valid_constraints = temp_constraints; 5806eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 5807a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 58089162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 58099162d606SStefano Zampini 58109162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5811a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 58129162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 5813a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 58149162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 5815a773dcb8SStefano Zampini } else { /* perform SVD */ 5816984c4197SStefano Zampini PetscReal tol = 1.0e-8; /* tolerance for retaining eigenmodes */ 58179162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5818674ae819SStefano Zampini 5819674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5820984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 5821984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 5822984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 5823984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 5824984c4197SStefano Zampini from that computed using LAPACKgesvd 5825984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 5826984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 5827984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 5828674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 5829e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5830984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5831674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 5832674ae819SStefano Zampini for (k=0;k<j+1;k++) { 58339162d606SStefano 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)); 5834674ae819SStefano Zampini } 5835674ae819SStefano Zampini } 5836e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 5837e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5838e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 5839674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5840c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 5841674ae819SStefano Zampini #else 5842c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 5843674ae819SStefano Zampini #endif 5844674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5845984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 5846984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 5847674ae819SStefano Zampini j = 0; 5848984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 5849674ae819SStefano Zampini total_counts = total_counts-j; 585045a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 5851e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 5852c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5853c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5854c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 5855c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5856c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 5857c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5858674ae819SStefano Zampini if (j<temp_constraints) { 5859984c4197SStefano Zampini PetscInt ii; 5860984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 5861674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 58629162d606SStefano 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)); 5863674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5864984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 5865674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 58669162d606SStefano 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]; 5867674ae819SStefano Zampini } 5868674ae819SStefano Zampini } 5869674ae819SStefano Zampini } 5870674ae819SStefano Zampini #else /* on missing GESVD */ 5871e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5872e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5873b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5874674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5875674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 58769162d606SStefano 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)); 5877674ae819SStefano Zampini #else 58789162d606SStefano 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)); 5879674ae819SStefano Zampini #endif 5880984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 5881674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5882984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 5883e310c8b4SStefano Zampini k = temp_constraints; 5884e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 5885674ae819SStefano Zampini j = 0; 5886e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 588745a1bb75SStefano Zampini valid_constraints = k-j; 5888911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 5889984c4197SStefano Zampini #endif /* on missing GESVD */ 5890674ae819SStefano Zampini } 5891a773dcb8SStefano Zampini } 58929162d606SStefano Zampini /* update pointers information */ 58939162d606SStefano Zampini if (valid_constraints) { 58949162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 58959162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 58969162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 58979162d606SStefano Zampini /* set change_of_basis flag */ 589845a1bb75SStefano Zampini if (boolforchange) { 5899b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 59009162d606SStefano Zampini } 5901b3d85658SStefano Zampini total_counts_cc++; 590245a1bb75SStefano Zampini } 590345a1bb75SStefano Zampini } 5904984c4197SStefano Zampini /* free workspace */ 59058f1c130eSStefano Zampini if (!skip_lapack) { 5906984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 5907984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5908984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 5909984c4197SStefano Zampini #endif 5910984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 5911984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5912984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 5913984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 5914984c4197SStefano Zampini #endif 5915984c4197SStefano Zampini } 5916984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5917984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 5918984c4197SStefano Zampini } 5919984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 5920cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 5921cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5922cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5923cf5a6209SStefano Zampini } 5924cf5a6209SStefano Zampini if (n_ISForFaces) { 5925cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5926cf5a6209SStefano Zampini } 5927cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5928cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5929cf5a6209SStefano Zampini } 5930cf5a6209SStefano Zampini if (n_ISForEdges) { 5931cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5932cf5a6209SStefano Zampini } 5933cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 593408122e43SStefano Zampini } else { 593508122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5936984c4197SStefano Zampini 593708122e43SStefano Zampini total_counts = 0; 593808122e43SStefano Zampini n_vertices = 0; 5939d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 5940d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 594108122e43SStefano Zampini } 594208122e43SStefano Zampini max_constraints = 0; 59439162d606SStefano Zampini total_counts_cc = 0; 594408122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 594508122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 59469162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 594708122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 594808122e43SStefano Zampini } 59499162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 59509162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 59519162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 59529162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 595374d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 59549162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 59559162d606SStefano Zampini total_counts_cc = 0; 59569162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 59579162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 59589162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 595908122e43SStefano Zampini } 596008122e43SStefano Zampini } 59619162d606SStefano Zampini #if 0 59629162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 59639162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 59649162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 59659162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 59669162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 59679162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 59689162d606SStefano Zampini } 59699162d606SStefano Zampini printf("\n"); 59709162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 59719162d606SStefano Zampini } 59721b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 59738bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 59741b968477SStefano Zampini } 59751b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 59768bec7fa6SStefano 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]); 59771b968477SStefano Zampini } 597808122e43SStefano Zampini #endif 597908122e43SStefano Zampini 59808bec7fa6SStefano Zampini max_size_of_constraint = 0; 59819162d606SStefano 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]); 59829162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 598308122e43SStefano Zampini /* Change of basis */ 5984b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 598508122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 598608122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 598708122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 5988b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 598908122e43SStefano Zampini } 599008122e43SStefano Zampini } 599108122e43SStefano Zampini } 599208122e43SStefano Zampini } 5993984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 59944f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 599508122e43SStefano Zampini 59969162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 59979162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 5998eee23b56SStefano 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); 5999674ae819SStefano Zampini 6000674ae819SStefano Zampini /* Create constraint matrix */ 6001674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 600216f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 6003984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 6004984c4197SStefano Zampini 6005984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 6006a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 6007a717540cSStefano Zampini qr_needed = PETSC_FALSE; 600874d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 6009984c4197SStefano Zampini total_primal_vertices=0; 6010b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 60119162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 60129162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 601372b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 60149162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 6015b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 601664efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 60179162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 60189162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 6019a717540cSStefano Zampini } 6020b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 602191af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 6022a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 6023a717540cSStefano Zampini qr_needed = PETSC_TRUE; 6024a717540cSStefano Zampini } 6025fa434743SStefano Zampini } else { 6026b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 6027fa434743SStefano Zampini } 6028a717540cSStefano Zampini } 6029b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 6030b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 6031674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 603270022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 60334f1b2e48SStefano 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); 60340e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 60350e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 6036984c4197SStefano Zampini 6037984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 603874d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 6039785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 6040984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 604174d5cdf7SStefano Zampini 6042984c4197SStefano Zampini j = total_primal_vertices; 604374d5cdf7SStefano Zampini total_counts = total_primal_vertices; 6044b3d85658SStefano Zampini cum = total_primal_vertices; 60459162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 60464641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 6047b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 6048b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 6049b3d85658SStefano Zampini cum++; 60509162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 605174d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 605274d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 605374d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 605474d5cdf7SStefano Zampini } 60559162d606SStefano Zampini j += constraints_n[i]; 6056674ae819SStefano Zampini } 6057674ae819SStefano Zampini } 6058674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 6059674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 6060088faed8SStefano Zampini 6061674ae819SStefano Zampini /* set values in constraint matrix */ 6062984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 60630e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6064674ae819SStefano Zampini } 6065984c4197SStefano Zampini total_counts = total_primal_vertices; 60669162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 60674641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 60689162d606SStefano Zampini PetscInt *cols; 60699162d606SStefano Zampini 60709162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 60719162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 60729162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 60739162d606SStefano Zampini PetscInt row = total_counts+k; 60749162d606SStefano Zampini PetscScalar *vals; 60759162d606SStefano Zampini 60769162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 60779162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 60789162d606SStefano Zampini } 60799162d606SStefano Zampini total_counts += constraints_n[i]; 6080674ae819SStefano Zampini } 6081674ae819SStefano Zampini } 6082674ae819SStefano Zampini /* assembling */ 6083674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6084674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6085088faed8SStefano Zampini 6086984c4197SStefano Zampini /* 60876a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 6088984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 6089f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 6090984c4197SStefano Zampini */ 6091674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 6092674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 6093026de310SStefano Zampini /* dual and primal dofs on a single cc */ 6094984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 6095984c4197SStefano Zampini /* working stuff for GEQRF */ 609681d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 6097984c4197SStefano Zampini PetscBLASInt lqr_work; 6098984c4197SStefano Zampini /* working stuff for UNGQR */ 6099984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 6100984c4197SStefano Zampini PetscBLASInt lgqr_work; 6101984c4197SStefano Zampini /* working stuff for TRTRS */ 6102984c4197SStefano Zampini PetscScalar *trs_rhs; 61033f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 6104984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 6105984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 6106984c4197SStefano Zampini PetscScalar *start_vals; 6107984c4197SStefano Zampini /* working stuff for values insertion */ 61084641a718SStefano Zampini PetscBT is_primal; 610964efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 6110906d46d4SStefano Zampini /* matrix sizes */ 6111906d46d4SStefano Zampini PetscInt global_size,local_size; 6112906d46d4SStefano Zampini /* temporary change of basis */ 6113906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 6114cf5a6209SStefano Zampini /* extra space for debugging */ 6115cf5a6209SStefano Zampini PetscScalar *dbg_work; 6116984c4197SStefano Zampini 6117906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 6118906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 611916f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 6120bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 6121906d46d4SStefano Zampini /* nonzeros for local mat */ 6122bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 61231dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6124bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 61251dd7afcfSStefano Zampini } else { 61261dd7afcfSStefano Zampini const PetscInt *ii; 61271dd7afcfSStefano Zampini PetscInt n; 61281dd7afcfSStefano Zampini PetscBool flg_row; 61291dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 61301dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 61311dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 61321dd7afcfSStefano Zampini } 61339162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 6134a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 61359162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 6136a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 61379162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 6138a717540cSStefano Zampini } else { 61399162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 61409162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 6141a717540cSStefano Zampini } 6142a717540cSStefano Zampini } 6143a717540cSStefano Zampini } 6144906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 6145bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 61461dd7afcfSStefano Zampini /* Set interior change in the matrix */ 61471dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6148bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 6149906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 6150a717540cSStefano Zampini } 61511dd7afcfSStefano Zampini } else { 61521dd7afcfSStefano Zampini const PetscInt *ii,*jj; 61531dd7afcfSStefano Zampini PetscScalar *aa; 61541dd7afcfSStefano Zampini PetscInt n; 61551dd7afcfSStefano Zampini PetscBool flg_row; 61561dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 61571dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 61581dd7afcfSStefano Zampini for (i=0;i<n;i++) { 61591dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 61601dd7afcfSStefano Zampini } 61611dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 61621dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 61631dd7afcfSStefano Zampini } 6164a717540cSStefano Zampini 6165a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6166a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6167a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6168a717540cSStefano Zampini } 6169a717540cSStefano Zampini 6170a717540cSStefano Zampini 6171a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 6172a717540cSStefano Zampini /* 6173a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 6174a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 6175a717540cSStefano Zampini 6176a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 6177a717540cSStefano Zampini 6178a6b551f4SStefano 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) 6179a6b551f4SStefano Zampini 6180a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 6181a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 6182a717540cSStefano Zampini | ... | 6183a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 6184a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 6185a717540cSStefano Zampini 6186a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 6187a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 6188a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 6189a6b551f4SStefano Zampini 6190a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 6191a717540cSStefano Zampini */ 6192a717540cSStefano Zampini if (qr_needed) { 6193984c4197SStefano Zampini /* space to store Q */ 6194854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 61954e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 61964e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 6197984c4197SStefano Zampini /* first we issue queries for optimal work */ 61983f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 61993f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 62003f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6201984c4197SStefano Zampini lqr_work = -1; 62023f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 6203984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 6204984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 6205785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 6206984c4197SStefano Zampini lgqr_work = -1; 62073f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 62083f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 62093f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 62103f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 62113f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 6212c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 6213c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to ORGQR/UNGQR Lapack routine %d",(int)lierr); 6214984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 6215785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 6216984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 6217785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 6218a717540cSStefano Zampini /* allocating workspace for check */ 6219a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6220cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 6221a717540cSStefano Zampini } 6222a717540cSStefano Zampini } 6223984c4197SStefano Zampini /* array to store whether a node is primal or not */ 62244641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 6225473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 62260e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 6227eee23b56SStefano 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); 622839e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 622939e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 623039e2fb2aSStefano Zampini } 623139e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 6232984c4197SStefano Zampini 6233a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 62349162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 62359162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 62364641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 6237984c4197SStefano Zampini /* get constraint info */ 62389162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 6239984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 6240984c4197SStefano Zampini 6241984c4197SStefano Zampini if (pcbddc->dbg_flag) { 62429162d606SStefano 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); 6243674ae819SStefano Zampini } 6244984c4197SStefano Zampini 6245fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 6246a717540cSStefano Zampini 6247a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 6248a717540cSStefano Zampini if (pcbddc->dbg_flag) { 62499162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6250a717540cSStefano Zampini } 6251984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 62529162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6253984c4197SStefano Zampini 6254984c4197SStefano Zampini /* compute QR decomposition of constraints */ 62553f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 62563f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 62573f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6258674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 62593f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 6260984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 6261674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6262984c4197SStefano Zampini 6263984c4197SStefano Zampini /* explictly compute R^-T */ 6264984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 6265984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 62663f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 62673f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 62683f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 62693f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 6270984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 62713f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 6272984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 6273984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6274984c4197SStefano Zampini 6275a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 62763f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 62773f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 62783f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 62793f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6280984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6281c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 6282c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in ORGQR/UNGQR Lapack routine %d",(int)lierr); 6283984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6284984c4197SStefano Zampini 6285984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 6286984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 6287984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 62883f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 62893f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 62903f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 62913f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 62923f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 62933f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6294984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 62959162d606SStefano 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)); 6296984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 62979162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6298984c4197SStefano Zampini 6299984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 63009162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 6301984c4197SStefano Zampini /* insert cols for primal dofs */ 6302984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 6303984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 63049162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6305906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6306984c4197SStefano Zampini } 6307984c4197SStefano Zampini /* insert cols for dual dofs */ 6308984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 63099162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 6310984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 63119162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6312906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6313984c4197SStefano Zampini j++; 6314674ae819SStefano Zampini } 6315674ae819SStefano Zampini } 6316984c4197SStefano Zampini 6317984c4197SStefano Zampini /* check change of basis */ 6318984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6319984c4197SStefano Zampini PetscInt ii,jj; 6320984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 6321c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 6322c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6323c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 6324c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6325c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 6326c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 6327984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6328cf5a6209SStefano 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)); 6329984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6330984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6331984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6332cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 6333c068d9bbSLisandro 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; 6334674ae819SStefano Zampini } 6335674ae819SStefano Zampini } 6336984c4197SStefano Zampini if (!valid_qr) { 633722d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 6338984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6339984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6340cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 6341cf5a6209SStefano 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])); 6342674ae819SStefano Zampini } 6343c068d9bbSLisandro Dalcin if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-(PetscReal)1) > 1.e-12) { 6344cf5a6209SStefano 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])); 6345984c4197SStefano Zampini } 6346984c4197SStefano Zampini } 6347984c4197SStefano Zampini } 6348674ae819SStefano Zampini } else { 634922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 6350674ae819SStefano Zampini } 6351674ae819SStefano Zampini } 6352a717540cSStefano Zampini } else { /* simple transformation block */ 6353a717540cSStefano Zampini PetscInt row,col; 6354a6b551f4SStefano Zampini PetscScalar val,norm; 6355a6b551f4SStefano Zampini 6356a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 63579162d606SStefano 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)); 6358a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 63599162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 63609162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6361bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 63629162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 6363906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 63649162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 6365a717540cSStefano Zampini } else { 6366a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 63679162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6368a717540cSStefano Zampini if (row != col) { 63699162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 6370a717540cSStefano Zampini } else { 63719162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 6372a717540cSStefano Zampini } 6373906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 6374a717540cSStefano Zampini } 6375a717540cSStefano Zampini } 6376a717540cSStefano Zampini } 637798a51de6SStefano Zampini if (pcbddc->dbg_flag) { 637822d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 6379a717540cSStefano Zampini } 6380674ae819SStefano Zampini } 6381984c4197SStefano Zampini } else { 6382984c4197SStefano Zampini if (pcbddc->dbg_flag) { 63839162d606SStefano 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); 6384674ae819SStefano Zampini } 6385674ae819SStefano Zampini } 6386674ae819SStefano Zampini } 6387a717540cSStefano Zampini 6388a717540cSStefano Zampini /* free workspace */ 6389a717540cSStefano Zampini if (qr_needed) { 6390984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6391cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 6392984c4197SStefano Zampini } 6393984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 6394984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 6395984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 6396984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 6397984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 6398674ae819SStefano Zampini } 6399a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 6400906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6401906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6402906d46d4SStefano Zampini 6403906d46d4SStefano Zampini /* assembling of global change of variable */ 640488c03ad3SStefano Zampini if (!pcbddc->fake_change) { 6405bbb9e6c6SStefano Zampini Mat tmat; 640616f15bc4SStefano Zampini PetscInt bs; 640716f15bc4SStefano Zampini 6408906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 6409906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 6410bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 6411bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 6412bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6413bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 641416f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 641516f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 6416906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 6417bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 6418bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6419bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6420bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6421bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6422e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6423e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6424bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 6425bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 642688c03ad3SStefano Zampini 6427906d46d4SStefano Zampini /* check */ 6428906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 6429906d46d4SStefano Zampini PetscReal error; 6430906d46d4SStefano Zampini Vec x,x_change; 6431906d46d4SStefano Zampini 6432906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 6433906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 6434906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 6435906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 6436e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6437e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6438bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 6439e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6440e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6441906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 6442906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 6443906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 6444637e8532SStefano Zampini if (error > PETSC_SMALL) { 6445637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 6446637e8532SStefano Zampini } 6447906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 6448906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 6449906d46d4SStefano Zampini } 6450b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 6451b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 6452b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6453bf3a8328SStefano Zampini 645413903a91SSatish 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"); 6455b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 6456ac632422SStefano Zampini Mat S_new,tmat; 6457bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 6458bbb9e6c6SStefano Zampini 6459bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 64607dae84e0SHong Zhang ierr = MatCreateSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 6461bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6462bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 6463bf3a8328SStefano Zampini IS is_V; 6464b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 6465b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 6466b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 6467b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 6468b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 6469bf3a8328SStefano Zampini } 6470bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 6471ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6472b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 6473ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6474bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6475bf3a8328SStefano Zampini const PetscScalar *array; 6476bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 6477bf3a8328SStefano Zampini PetscInt i,n_V; 6478bf3a8328SStefano Zampini 6479b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6480b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 6481b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6482b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6483b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 6484b087196eSStefano Zampini for (i=0;i<n_V;i++) { 6485b087196eSStefano Zampini PetscScalar val; 6486b087196eSStefano Zampini PetscInt idx; 6487b087196eSStefano Zampini 6488b087196eSStefano Zampini idx = idxs_V[i]; 6489b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 6490b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 6491b087196eSStefano Zampini } 6492b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6493b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6494bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 6495bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6496bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6497bf3a8328SStefano Zampini } 6498ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 6499ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6500ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 6501ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6502b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 6503ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6504bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6505b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6506bf3a8328SStefano Zampini } 6507ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 6508ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6509ac632422SStefano Zampini } 6510b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 651188c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6512b96c3477SStefano Zampini } 6513c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 6514b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 6515c9db6a07SStefano Zampini PetscInt i; 6516c9db6a07SStefano Zampini 6517c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 6518c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 6519c9db6a07SStefano Zampini } 6520c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 6521c9db6a07SStefano Zampini } 6522b96c3477SStefano Zampini } 652316909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 652416909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 652516909a7fSStefano Zampini } else { 6526906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 652716909a7fSStefano Zampini } 65281dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 652927b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 653072b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 653172b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 653272b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 653372b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 653472b8c272SStefano Zampini } 65351dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 653627b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 6537b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 6538b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 6539906d46d4SStefano Zampini } else { 65401dd7afcfSStefano Zampini Mat benign_global = NULL; 654127b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 65421dd7afcfSStefano Zampini Mat tmat; 65431dd7afcfSStefano Zampini 65441dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 65451dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 65461dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 65471dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 65481dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 65491dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 65501dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 65511dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 65521dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 65531dd7afcfSStefano Zampini if (pcbddc->benign_change) { 65541dd7afcfSStefano Zampini Mat M; 65551dd7afcfSStefano Zampini 65561dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 65571dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 65581dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 65591dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 6560906d46d4SStefano Zampini } else { 65611dd7afcfSStefano Zampini Mat eye; 65621dd7afcfSStefano Zampini PetscScalar *array; 65631dd7afcfSStefano Zampini 65641dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 65651dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 65661dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 65671dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 6568906d46d4SStefano Zampini } 65691dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 65701dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 65711dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 65721dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 65731dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 65741dd7afcfSStefano Zampini } 65751dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 65761dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 65771dd7afcfSStefano Zampini } 65781dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 65791dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 65801dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 658127b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 65821dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 65831dd7afcfSStefano Zampini } 65841dd7afcfSStefano Zampini } 658516909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 658616909a7fSStefano Zampini IS is_global; 658716909a7fSStefano Zampini const PetscInt *gidxs; 658816909a7fSStefano Zampini 658916909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 659016909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 659116909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 65927dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 659316909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 659416909a7fSStefano Zampini } 65951dd7afcfSStefano Zampini } 65961dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 65971dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 6598b9b85e73SStefano Zampini } 6599a717540cSStefano Zampini 660072b8c272SStefano Zampini if (!pcbddc->fake_change) { 66014f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 66024f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 66034f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 66044f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 6605019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 6606019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 6607019a44ceSStefano Zampini pcbddc->local_primal_size++; 6608019a44ceSStefano Zampini } 6609019a44ceSStefano Zampini 6610019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 6611727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 6612727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 66139f47a83aSStefano 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); 6614c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 66150e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 66169f47a83aSStefano 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); 6617727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 6618727cdba6SStefano Zampini } 66190e6343abSStefano Zampini } 6620727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 6621b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 662272b8c272SStefano Zampini } 662372b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 6624727cdba6SStefano Zampini 6625a717540cSStefano Zampini /* flush dbg viewer */ 6626b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 6627b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6628b8ffe317SStefano Zampini } 6629a717540cSStefano Zampini 6630e310c8b4SStefano Zampini /* free workspace */ 6631a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 66324641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 663308122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 66349162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 66359162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 663608122e43SStefano Zampini } else { 66379162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 66389162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 66399162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 664008122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 664108122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 66429162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 66439162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 664408122e43SStefano Zampini } 6645674ae819SStefano Zampini PetscFunctionReturn(0); 6646674ae819SStefano Zampini } 6647674ae819SStefano Zampini 6648674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 6649674ae819SStefano Zampini { 665071582508SStefano Zampini ISLocalToGlobalMapping map; 6651674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6652674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 665366da6bd7Sstefano_zampini PetscInt i,N; 665466da6bd7Sstefano_zampini PetscBool rcsr = PETSC_FALSE; 665566da6bd7Sstefano_zampini PetscErrorCode ierr; 6656674ae819SStefano Zampini 6657674ae819SStefano Zampini PetscFunctionBegin; 66588af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 6659b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 66608e61c736SStefano Zampini /* Reset previously computed graph */ 66618e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 6662674ae819SStefano Zampini /* Init local Graph struct */ 66637fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 666471582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 6665be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 6666674ae819SStefano Zampini 66677a0e7b2cSstefano_zampini if (pcbddc->user_primal_vertices_local && !pcbddc->user_primal_vertices) { 66687a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 66697a0e7b2cSstefano_zampini } 6670575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 66719a962809SStefano 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); 66729577ea80SStefano Zampini 6673674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 667466da6bd7Sstefano_zampini if (!pcbddc->mat_graph->xadj && pcbddc->use_local_adj) { 66754d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 66764d379d7bSStefano Zampini PetscInt nvtxs; 6677e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 6678674ae819SStefano Zampini 66792fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 66802fffb893SStefano Zampini if (flg_row) { 66814d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 6682b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 66832fffb893SStefano Zampini } 66842fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 668566da6bd7Sstefano_zampini rcsr = PETSC_TRUE; 6686674ae819SStefano Zampini } 66879b28b941SStefano Zampini if (pcbddc->dbg_flag) { 66889b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6689674ae819SStefano Zampini } 6690674ae819SStefano Zampini 6691674ae819SStefano Zampini /* Setup of Graph */ 66924b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 669314f95afaSStefano 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); 6694674ae819SStefano Zampini 66954f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 66964f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 66974f1b2e48SStefano Zampini PetscInt *local_subs; 66984f1b2e48SStefano Zampini 66994f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 67004f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 67014f1b2e48SStefano Zampini const PetscInt *idxs; 67024f1b2e48SStefano Zampini PetscInt nl,j; 67034f1b2e48SStefano Zampini 67044f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 67054f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 670671582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 67074f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 67084f1b2e48SStefano Zampini } 67094f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 67104f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 67114f1b2e48SStefano Zampini } 67128af8fcf9SStefano Zampini } 67134f1b2e48SStefano Zampini 6714cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 6715674ae819SStefano Zampini /* Graph's connected components analysis */ 6716674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 671771582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 67188af8fcf9SStefano Zampini } 671966da6bd7Sstefano_zampini if (rcsr) pcbddc->mat_graph->nvtxs_csr = 0; 6720674ae819SStefano Zampini PetscFunctionReturn(0); 6721674ae819SStefano Zampini } 6722674ae819SStefano Zampini 67239a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 67249a7d3425SStefano Zampini { 67259a7d3425SStefano Zampini PetscInt i,j; 67269a7d3425SStefano Zampini PetscScalar *alphas; 67279a7d3425SStefano Zampini PetscErrorCode ierr; 67289a7d3425SStefano Zampini 67299a7d3425SStefano Zampini PetscFunctionBegin; 6730785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 67319a7d3425SStefano Zampini for (i=0;i<n;i++) { 67329a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 6733669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 6734669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 6735669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 67369a7d3425SStefano Zampini } 67379a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 67389a7d3425SStefano Zampini PetscFunctionReturn(0); 67399a7d3425SStefano Zampini } 67409a7d3425SStefano Zampini 6741bb360cb4SStefano Zampini PetscErrorCode PCBDDCMatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 6742e7931f94SStefano Zampini { 674357de7509SStefano Zampini Mat A; 6744e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 6745e7931f94SStefano Zampini PetscMPIInt size,rank,color; 674652e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 674752e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 6748bb360cb4SStefano Zampini PetscInt im_active,active_procs,N,n,i,j,threshold = 2; 674957de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 675027b6a85dSStefano Zampini PetscInt xadj_count,*count; 675127b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 675227b6a85dSStefano Zampini PetscSubcomm psubcomm; 675327b6a85dSStefano Zampini MPI_Comm subcomm; 675452e5ac9dSStefano Zampini PetscErrorCode ierr; 6755a57a6d2fSStefano Zampini 6756e7931f94SStefano Zampini PetscFunctionBegin; 675757de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 675857de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 6759fbfcfee5SBarry 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); 676057de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 676157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 676257de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 676357de7509SStefano Zampini 676457de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 676557de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 676657de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 676757de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 676857de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 6769bb360cb4SStefano Zampini im_active = !!n; 677057de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 677157de7509SStefano Zampini void_procs = size - active_procs; 677257de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 677357de7509SStefano Zampini if (void_procs) { 677457de7509SStefano Zampini PetscInt ncand; 677557de7509SStefano Zampini 677657de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 677757de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 677857de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 677957de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 678057de7509SStefano Zampini if (!procs_candidates[i]) { 678157de7509SStefano Zampini procs_candidates[ncand++] = i; 678257de7509SStefano Zampini } 678357de7509SStefano Zampini } 678457de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 678557de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 678657de7509SStefano Zampini } 678757de7509SStefano Zampini 6788bb360cb4SStefano Zampini /* number of subdomains requested greater than active processes or matrix size -> just shift the matrix 678914f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 6790bb360cb4SStefano Zampini ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 6791bb360cb4SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1 || N <= *n_subdomains) { 679214f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 679314f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 679414f0bfb9SStefano Zampini else dest = rank; 679557de7509SStefano Zampini if (im_active) { 679657de7509SStefano Zampini issize = 1; 679757de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 679814f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 679957de7509SStefano Zampini } else { 680014f0bfb9SStefano Zampini isidx = dest; 680157de7509SStefano Zampini } 680257de7509SStefano Zampini } else { 680357de7509SStefano Zampini issize = 0; 680457de7509SStefano Zampini isidx = -1; 680557de7509SStefano Zampini } 6806bb360cb4SStefano Zampini if (*n_subdomains != 1) *n_subdomains = active_procs; 680757de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 6808daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 680957de7509SStefano Zampini PetscFunctionReturn(0); 681057de7509SStefano Zampini } 6811c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 6812c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 681327b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 6814e7931f94SStefano Zampini 6815e7931f94SStefano Zampini /* Get info on mapping */ 68163bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6817e7931f94SStefano Zampini 6818e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 6819785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 6820e7931f94SStefano Zampini xadj[0] = 0; 6821e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 6822785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 6823785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 6824bb360cb4SStefano Zampini ierr = PetscCalloc1(n,&count);CHKERRQ(ierr); 682527b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 682627b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 682727b6a85dSStefano Zampini count[shared[i][j]] += 1; 6828e7931f94SStefano Zampini 682927b6a85dSStefano Zampini xadj_count = 0; 68302b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 683127b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 683227b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 6833d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 6834d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 6835d023bfaeSStefano Zampini xadj_count++; 683627b6a85dSStefano Zampini break; 683727b6a85dSStefano Zampini } 6838e7931f94SStefano Zampini } 6839e7931f94SStefano Zampini } 6840d023bfaeSStefano Zampini xadj[1] = xadj_count; 684127b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 68423bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6843e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 6844e7931f94SStefano Zampini 68453837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 6846e7931f94SStefano Zampini 684727b6a85dSStefano Zampini /* Restrict work on active processes only */ 684827b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 684927b6a85dSStefano Zampini if (void_procs) { 685027b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 685127b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 685227b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 685327b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 685427b6a85dSStefano Zampini } else { 685527b6a85dSStefano Zampini psubcomm = NULL; 685627b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 685727b6a85dSStefano Zampini } 685827b6a85dSStefano Zampini 685927b6a85dSStefano Zampini v_wgt = NULL; 686027b6a85dSStefano Zampini if (!color) { 6861e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 6862e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 6863e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6864c8587f34SStefano Zampini } else { 686552e5ac9dSStefano Zampini Mat subdomain_adj; 686652e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 686752e5ac9dSStefano Zampini MatPartitioning partitioner; 686827b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 686952e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 687057de7509SStefano Zampini PetscMPIInt size; 6871b0c7d250SStefano Zampini PetscBool aggregate; 6872b0c7d250SStefano Zampini 687327b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 687427b6a85dSStefano Zampini if (void_procs) { 687527b6a85dSStefano Zampini PetscInt prank = rank; 6876785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 687727b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 6878e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 6879e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 6880c8587f34SStefano Zampini } 6881e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 688227b6a85dSStefano Zampini } else { 688327b6a85dSStefano Zampini oldranks = NULL; 688427b6a85dSStefano Zampini } 6885b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 688627b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 6887b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 6888b0c7d250SStefano Zampini PetscMPIInt nrank; 6889b0c7d250SStefano Zampini PetscScalar *vals; 6890b0c7d250SStefano Zampini 689127b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 6892b0c7d250SStefano Zampini lrows = 0; 6893b0c7d250SStefano Zampini if (nrank<redprocs) { 6894b0c7d250SStefano Zampini lrows = size/redprocs; 6895b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 6896b0c7d250SStefano Zampini } 689727b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 6898b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 6899b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6900b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 6901b0c7d250SStefano Zampini row = nrank; 6902b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 6903b0c7d250SStefano Zampini cols = adjncy; 6904b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 6905b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 6906b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 6907b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6908b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 690952e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 691052e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 691152e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6912b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 691327b6a85dSStefano Zampini if (use_vwgt) { 691427b6a85dSStefano Zampini Vec v; 691527b6a85dSStefano Zampini const PetscScalar *array; 691627b6a85dSStefano Zampini PetscInt nl; 691727b6a85dSStefano Zampini 691827b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 6919bb360cb4SStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)n,INSERT_VALUES);CHKERRQ(ierr); 692027b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 692127b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 692227b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 692327b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 692427b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 692522db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 692627b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 692727b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 692827b6a85dSStefano Zampini } 6929b0c7d250SStefano Zampini } else { 693027b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 693127b6a85dSStefano Zampini if (use_vwgt) { 693227b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 6933bb360cb4SStefano Zampini v_wgt[0] = n; 693427b6a85dSStefano Zampini } 6935b0c7d250SStefano Zampini } 693622b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 6937e7931f94SStefano Zampini 6938e7931f94SStefano Zampini /* Partition */ 693927b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 6940e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 694127b6a85dSStefano Zampini if (v_wgt) { 6942e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 6943c8587f34SStefano Zampini } 694457de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 694557de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 6946e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 6947e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 694822b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 6949e7931f94SStefano Zampini 695052e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 69516583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 695252e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 695352e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 695457de7509SStefano Zampini if (!aggregate) { 695557de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 695627b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 695727b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 695827b6a85dSStefano Zampini #endif 695957de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 696027b6a85dSStefano Zampini } else if (oldranks) { 6961b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 696227b6a85dSStefano Zampini } else { 696327b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 696457de7509SStefano Zampini } 696528143c3dSStefano Zampini } else { 69667fb8a5e4SKarl Rupp PetscInt idx = 0; 6967b0c7d250SStefano Zampini PetscMPIInt tag; 6968b0c7d250SStefano Zampini MPI_Request *reqs; 6969b0c7d250SStefano Zampini 6970b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 6971b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 6972b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 697327b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 697428143c3dSStefano Zampini } 69757fb8a5e4SKarl Rupp ierr = MPI_Recv(&idx,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 6976b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 6977b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 697857de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 697927b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 698027b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 698127b6a85dSStefano Zampini #endif 69827fb8a5e4SKarl Rupp ranks_send_to_idx[0] = procs_candidates[oldranks[idx]]; 698327b6a85dSStefano Zampini } else if (oldranks) { 69847fb8a5e4SKarl Rupp ranks_send_to_idx[0] = oldranks[idx]; 698527b6a85dSStefano Zampini } else { 69867fb8a5e4SKarl Rupp ranks_send_to_idx[0] = idx; 6987e7931f94SStefano Zampini } 698857de7509SStefano Zampini } 698952e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 6990e7931f94SStefano Zampini /* clean up */ 6991e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 699252e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 6993e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 6994e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 6995e7931f94SStefano Zampini } 699627b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 699757de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 6998e7931f94SStefano Zampini 6999e7931f94SStefano Zampini /* assemble parallel IS for sends */ 7000e7931f94SStefano Zampini i = 1; 700127b6a85dSStefano Zampini if (!color) i=0; 700257de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 7003e7931f94SStefano Zampini PetscFunctionReturn(0); 7004e7931f94SStefano Zampini } 7005e7931f94SStefano Zampini 7006e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 7007e7931f94SStefano Zampini 70081e0482f5SStefano 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[]) 7009e7931f94SStefano Zampini { 701070cf5478SStefano Zampini Mat local_mat; 7011e7931f94SStefano Zampini IS is_sends_internal; 70129d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 70131ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 70149d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 7015e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 7016e7931f94SStefano Zampini PetscInt* l2gmap_indices; 7017e7931f94SStefano Zampini const PetscInt* is_indices; 7018e7931f94SStefano Zampini MatType new_local_type; 7019e7931f94SStefano Zampini /* buffers */ 7020e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 702128143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 70229d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 7023e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 70241ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 7025e7931f94SStefano Zampini /* MPI */ 702628143c3dSStefano Zampini MPI_Comm comm,comm_n; 702728143c3dSStefano Zampini PetscSubcomm subcomm; 7028e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 702928143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 703028143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 70311ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 70321ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 70331ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 7034e7931f94SStefano Zampini PetscErrorCode ierr; 7035e7931f94SStefano Zampini 7036e7931f94SStefano Zampini PetscFunctionBegin; 703757de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7038e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 7039fbfcfee5SBarry 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); 704057de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 704157de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 704257de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 704357de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 704457de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 70451ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 70461ae86dd6SStefano Zampini if (nvecs) { 70471ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 70481ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 70491ae86dd6SStefano Zampini } 705057de7509SStefano Zampini /* further checks */ 7051e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7052e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 7053e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 7054e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 7055e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 705657de7509SStefano Zampini if (reuse && *mat_n) { 705770cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 705857de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 705970cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 706028143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 706170cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 706270cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 706370cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 706470cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 706570cf5478SStefano Zampini } 7066e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 7067e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 706857de7509SStefano Zampini 7069e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 7070e7931f94SStefano Zampini if (!is_sends) { 707128143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 7072bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 7073c8587f34SStefano Zampini } else { 7074e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 7075e7931f94SStefano Zampini is_sends_internal = is_sends; 7076c8587f34SStefano Zampini } 7077e7931f94SStefano Zampini 7078e7931f94SStefano Zampini /* get comm */ 7079a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 7080e7931f94SStefano Zampini 7081e7931f94SStefano Zampini /* compute number of sends */ 7082e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 7083e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 7084e7931f94SStefano Zampini 7085e7931f94SStefano Zampini /* compute number of receives */ 7086e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 7087785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 7088e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 7089e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7090e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 7091e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 7092e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 7093e7931f94SStefano Zampini 709428143c3dSStefano Zampini /* restrict comm if requested */ 709528143c3dSStefano Zampini subcomm = 0; 709628143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 709728143c3dSStefano Zampini if (restrict_comm) { 7098779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 7099779c1cceSStefano Zampini 710028143c3dSStefano Zampini color = 0; 710153a05cb3SStefano Zampini if (restrict_full) { 710253a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 710353a05cb3SStefano Zampini } else { 710453a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 710553a05cb3SStefano Zampini } 7106b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 710728143c3dSStefano Zampini subcommsize = commsize - subcommsize; 710828143c3dSStefano Zampini /* check if reuse has been requested */ 710957de7509SStefano Zampini if (reuse) { 711028143c3dSStefano Zampini if (*mat_n) { 711128143c3dSStefano Zampini PetscMPIInt subcommsize2; 711228143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 711328143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 711428143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 711528143c3dSStefano Zampini } else { 711628143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 711728143c3dSStefano Zampini } 711828143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 7119779c1cceSStefano Zampini PetscMPIInt rank; 7120779c1cceSStefano Zampini 7121779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 712228143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 712328143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 712428143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 7125306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 712628143c3dSStefano Zampini } 712728143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 712828143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 712928143c3dSStefano Zampini } else { 713028143c3dSStefano Zampini comm_n = comm; 713128143c3dSStefano Zampini } 713228143c3dSStefano Zampini 7133e7931f94SStefano Zampini /* prepare send/receive buffers */ 7134785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 7135e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 7136785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 7137e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 713828143c3dSStefano Zampini if (nis) { 7139854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 714028143c3dSStefano Zampini } 7141e7931f94SStefano Zampini 714228143c3dSStefano Zampini /* Get data from local matrices */ 71436c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 7144e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 7145e7931f94SStefano Zampini /* 7146e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 7147e7931f94SStefano Zampini send_buffer_idxs should contain: 7148e7931f94SStefano Zampini - MatType_PRIVATE type 7149e7931f94SStefano Zampini - PetscInt size_of_l2gmap 7150e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 7151e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 7152e7931f94SStefano Zampini */ 71536c4ed002SBarry Smith else { 7154e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 71553bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 7156854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 7157e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 7158e7931f94SStefano Zampini send_buffer_idxs[1] = i; 71593bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7160e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 71613bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7162e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 7163e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7164e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 7165e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 7166c8587f34SStefano Zampini } 7167c8587f34SStefano Zampini } 7168e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 716928143c3dSStefano Zampini /* additional is (if any) */ 717028143c3dSStefano Zampini if (nis) { 717128143c3dSStefano Zampini PetscMPIInt psum; 717228143c3dSStefano Zampini PetscInt j; 717328143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 717428143c3dSStefano Zampini PetscInt plen; 717528143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 717628143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 717728143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 717828143c3dSStefano Zampini } 7179854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 718028143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 718128143c3dSStefano Zampini PetscInt plen; 718228143c3dSStefano Zampini const PetscInt *is_array_idxs; 718328143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 718428143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 718528143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 718628143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 718728143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 718828143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 718928143c3dSStefano Zampini } 719028143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 719128143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 719228143c3dSStefano Zampini } 719328143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 719428143c3dSStefano Zampini } 71953b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 719628143c3dSStefano Zampini 7197e7931f94SStefano Zampini buf_size_idxs = 0; 7198e7931f94SStefano Zampini buf_size_vals = 0; 719928143c3dSStefano Zampini buf_size_idxs_is = 0; 72001ae86dd6SStefano Zampini buf_size_vecs = 0; 7201e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7202e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 7203e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 720428143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 72051ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 7206e7931f94SStefano Zampini } 7207785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 7208785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 720995ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 72101ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 7211e7931f94SStefano Zampini 7212e7931f94SStefano Zampini /* get new tags for clean communications */ 7213e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 7214e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 721528143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 72161ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 7217e7931f94SStefano Zampini 7218e7931f94SStefano Zampini /* allocate for requests */ 7219785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 7220785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 722195ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 72221ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 7223785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 7224785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 722595ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 72261ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 7227e7931f94SStefano Zampini 7228e7931f94SStefano Zampini /* communications */ 7229e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7230e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 723128143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 72321ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 7233e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7234e7931f94SStefano Zampini source_dest = onodes[i]; 7235e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 7236e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 7237e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7238e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 723928143c3dSStefano Zampini if (nis) { 724057de7509SStefano Zampini source_dest = onodes_is[i]; 724128143c3dSStefano 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); 724228143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 724328143c3dSStefano Zampini } 72441ae86dd6SStefano Zampini if (nvecs) { 72451ae86dd6SStefano Zampini source_dest = onodes[i]; 72461ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 72471ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 72481ae86dd6SStefano Zampini } 7249e7931f94SStefano Zampini } 7250e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7251e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 7252e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 7253e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 725428143c3dSStefano Zampini if (nis) { 725528143c3dSStefano 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); 725628143c3dSStefano Zampini } 72571ae86dd6SStefano Zampini if (nvecs) { 72581ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 72591ae86dd6SStefano 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); 72601ae86dd6SStefano Zampini } 7261e7931f94SStefano Zampini } 7262e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7263e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 7264e7931f94SStefano Zampini 7265e7931f94SStefano Zampini /* assemble new l2g map */ 7266e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7267e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 72689d30be91SStefano Zampini new_local_rows = 0; 7269e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 72709d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7271e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7272e7931f94SStefano Zampini } 72739d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 7274e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 72759d30be91SStefano Zampini new_local_rows = 0; 7276e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 72779d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 72789d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7279e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7280e7931f94SStefano Zampini } 72819d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 72829d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 7283e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 7284e7931f94SStefano Zampini 7285e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 7286e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 7287e7931f94SStefano 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) */ 7288e7931f94SStefano Zampini if (n_recvs) { 728928143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 7290e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7291e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7292e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 7293e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 7294e7931f94SStefano Zampini break; 7295e7931f94SStefano Zampini } 7296e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7297e7931f94SStefano Zampini } 7298e7931f94SStefano Zampini switch (new_local_type_private) { 729928143c3dSStefano Zampini case MATDENSE_PRIVATE: 7300e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7301e7931f94SStefano Zampini bs = 1; 7302e7931f94SStefano Zampini break; 7303e7931f94SStefano Zampini case MATAIJ_PRIVATE: 7304e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7305e7931f94SStefano Zampini bs = 1; 7306e7931f94SStefano Zampini break; 7307e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 7308e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 7309e7931f94SStefano Zampini break; 7310e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 7311e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 7312e7931f94SStefano Zampini break; 7313e7931f94SStefano Zampini default: 7314fbfcfee5SBarry Smith SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,PETSC_FUNCTION_NAME); 7315e7931f94SStefano Zampini break; 7316e7931f94SStefano Zampini } 7317ed8ed4edSstefano_zampini } else { /* by default, new_local_type is seqaij */ 7318ed8ed4edSstefano_zampini new_local_type = MATSEQAIJ; 731928143c3dSStefano Zampini bs = 1; 7320e7931f94SStefano Zampini } 7321e7931f94SStefano Zampini 732270cf5478SStefano Zampini /* create MATIS object if needed */ 732357de7509SStefano Zampini if (!reuse) { 7324e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 7325e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 732670cf5478SStefano Zampini } else { 732770cf5478SStefano Zampini /* it also destroys the local matrices */ 732857de7509SStefano Zampini if (*mat_n) { 732970cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 733057de7509SStefano Zampini } else { /* this is a fake object */ 733157de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 733257de7509SStefano Zampini } 733370cf5478SStefano Zampini } 733470cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 7335e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 73369d30be91SStefano Zampini 73379d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 73389d30be91SStefano Zampini 73399d30be91SStefano Zampini /* Global to local map of received indices */ 73409d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 73419d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 73429d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 73439d30be91SStefano Zampini 73449d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 73459d30be91SStefano Zampini buf_size_idxs = 0; 73469d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 73479d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 73489d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 73499d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 73509d30be91SStefano Zampini } 73519d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 73529d30be91SStefano Zampini 73539d30be91SStefano Zampini /* set preallocation */ 73549d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 73559d30be91SStefano Zampini if (!newisdense) { 73569d30be91SStefano Zampini PetscInt *new_local_nnz=0; 73579d30be91SStefano Zampini 73589d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 73599d30be91SStefano Zampini if (n_recvs) { 73609d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 73619d30be91SStefano Zampini } 73629d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 73639d30be91SStefano Zampini PetscInt j; 73649d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 73659d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 73669d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 73679d30be91SStefano Zampini } 73689d30be91SStefano Zampini } else { 73699d30be91SStefano Zampini /* TODO */ 73709d30be91SStefano Zampini } 73719d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 73729d30be91SStefano Zampini } 73739d30be91SStefano Zampini if (new_local_nnz) { 73749d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 73759d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 73769d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 73779d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 73789d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 73799d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 73809d30be91SStefano Zampini } else { 73819d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 73829d30be91SStefano Zampini } 73839d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 73849d30be91SStefano Zampini } else { 73859d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 73869d30be91SStefano Zampini } 7387e7931f94SStefano Zampini 7388e7931f94SStefano Zampini /* set values */ 7389e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 73909d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 7391e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7392e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 7393e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 73949d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 7395e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7396e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7397e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 739828143c3dSStefano Zampini } else { 739928143c3dSStefano Zampini /* TODO */ 7400e7931f94SStefano Zampini } 7401e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7402e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 7403e7931f94SStefano Zampini } 7404e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7405e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 74063b3b1effSJed Brown ierr = MatISRestoreLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 740770cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 740870cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 74099d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 7410e7931f94SStefano Zampini 7411dfd14d43SStefano Zampini #if 0 741228143c3dSStefano Zampini if (!restrict_comm) { /* check */ 7413e7931f94SStefano Zampini Vec lvec,rvec; 7414e7931f94SStefano Zampini PetscReal infty_error; 7415e7931f94SStefano Zampini 74162a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 7417e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 7418e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 7419e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 742070cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 7421e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 7422e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 7423e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 7424e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 7425e7931f94SStefano Zampini } 742628143c3dSStefano Zampini #endif 7427e7931f94SStefano Zampini 742828143c3dSStefano Zampini /* assemble new additional is (if any) */ 742928143c3dSStefano Zampini if (nis) { 743028143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 743128143c3dSStefano Zampini 743228143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7433854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 743428143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 743528143c3dSStefano Zampini psum = 0; 743628143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 743728143c3dSStefano Zampini for (j=0;j<nis;j++) { 743828143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 743928143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 744028143c3dSStefano Zampini psum += plen; 744128143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 744228143c3dSStefano Zampini } 744328143c3dSStefano Zampini } 7444854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 7445854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 744628143c3dSStefano Zampini for (i=1;i<nis;i++) { 744728143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 744828143c3dSStefano Zampini } 744928143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 745028143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 745128143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 745228143c3dSStefano Zampini for (j=0;j<nis;j++) { 745328143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 745428143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 745528143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 745628143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 745728143c3dSStefano Zampini } 745828143c3dSStefano Zampini } 745928143c3dSStefano Zampini for (i=0;i<nis;i++) { 746028143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 746128143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 746228143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 746328143c3dSStefano Zampini } 746428143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 746528143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 746628143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 746728143c3dSStefano Zampini } 7468e7931f94SStefano Zampini /* free workspace */ 746928143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 7470e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7471e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 7472e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7473e7931f94SStefano Zampini if (isdense) { 7474e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7475e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 74763b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 7477e7931f94SStefano Zampini } else { 7478e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 7479e7931f94SStefano Zampini } 748028143c3dSStefano Zampini if (nis) { 748128143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 748228143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 748328143c3dSStefano Zampini } 74841ae86dd6SStefano Zampini 74851ae86dd6SStefano Zampini if (nvecs) { 74861ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 74871ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 74881ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 74891ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 74901ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 74911ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 74921ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 74931ae86dd6SStefano Zampini /* set values */ 74941ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 74951ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 74961ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 74971ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 74981ae86dd6SStefano Zampini PetscInt j; 74991ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 75001ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 75011ae86dd6SStefano Zampini } 75021ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 75031ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 75041ae86dd6SStefano Zampini } 75051ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 75061ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 75071ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 75081ae86dd6SStefano Zampini } 75091ae86dd6SStefano Zampini 75101ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 75111ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 7512e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 7513e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 75141ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 751528143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 7516e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 7517e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 75181ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 751928143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 7520e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 7521e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 7522e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 7523e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 7524e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 752528143c3dSStefano Zampini if (nis) { 752628143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 752728143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 752828143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 752928143c3dSStefano Zampini } 753028143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 753128143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 753228143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 753328143c3dSStefano Zampini for (i=0;i<nis;i++) { 753428143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 753528143c3dSStefano Zampini } 75361ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 75371ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 75381ae86dd6SStefano Zampini } 753953a05cb3SStefano Zampini *mat_n = NULL; 754028143c3dSStefano Zampini } 7541e7931f94SStefano Zampini PetscFunctionReturn(0); 7542e7931f94SStefano Zampini } 7543a57a6d2fSStefano Zampini 754412edc857SStefano Zampini /* temporary hack into ksp private data structure */ 7545af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 754612edc857SStefano Zampini 7547c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 7548c8587f34SStefano Zampini { 7549c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7550c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 755120a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 75521ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 75531e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 75549881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 755520a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 75566e683305SStefano Zampini IS coarse_is,*isarray; 75576e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 755830368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 7559f9eb5b7dSStefano Zampini PC pc_temp; 7560c8587f34SStefano Zampini PCType coarse_pc_type; 7561c8587f34SStefano Zampini KSPType coarse_ksp_type; 7562f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 75637274672aSStefano Zampini PetscBool coarse_reuse; 75641e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 756568457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 756622bc73bbSStefano Zampini PetscScalar *array; 756757de7509SStefano Zampini MatReuse coarse_mat_reuse; 756857de7509SStefano Zampini PetscBool restr, full_restr, have_void; 75697de4f681Sstefano_zampini PetscMPIInt commsize; 75709881197aSStefano Zampini PetscErrorCode ierr; 7571fdc09c96SStefano Zampini 7572c8587f34SStefano Zampini PetscFunctionBegin; 7573c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 757468457ee5SStefano 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 */ 7575fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 75765a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 75777de4f681Sstefano_zampini 75787de4f681Sstefano_zampini pcbddc->new_primal_space = PETSC_TRUE; 7579fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 7580f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 7581f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 7582f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 7583fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 758451bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 758551bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 7586727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 7587fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7588fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 7589fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7590f4ddd8eeSStefano Zampini } 7591fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 7592fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7593f4ddd8eeSStefano Zampini } 759470cf5478SStefano Zampini /* reset any subassembling information */ 759557de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 759670cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 759757de7509SStefano Zampini } 75986e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 7599fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7600f4ddd8eeSStefano Zampini } 760157de7509SStefano Zampini /* assemble coarse matrix */ 760257de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 760357de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 760457de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 760557de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 760618a45a71SStefano Zampini } else { 760757de7509SStefano Zampini coarse_mat = NULL; 760857de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 76096e683305SStefano Zampini } 7610e7931f94SStefano Zampini 7611abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 7612abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 7613abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 7614abbbba34SStefano Zampini 7615abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 761622bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 761722bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 761822bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 761922bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 7620e176bc59SStefano 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); 76216e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 76226e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 76236e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7624abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 7625abbbba34SStefano Zampini 762657de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 762757de7509SStefano Zampini im_active = !!(pcis->n); 762857de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 762957de7509SStefano Zampini 763014f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 763157de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 763257de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 76337de4f681Sstefano_zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&commsize);CHKERRQ(ierr); 763457de7509SStefano Zampini coarse_mat_is = NULL; 763557de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 763657de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 76371ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 763857de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 763957de7509SStefano Zampini if (multilevel_requested) { 764057de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 764157de7509SStefano Zampini restr = PETSC_FALSE; 764257de7509SStefano Zampini full_restr = PETSC_FALSE; 764357de7509SStefano Zampini } else { 764457de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 764557de7509SStefano Zampini restr = PETSC_TRUE; 764657de7509SStefano Zampini full_restr = PETSC_TRUE; 764757de7509SStefano Zampini } 76487de4f681Sstefano_zampini if (!pcbddc->coarse_size || commsize == 1) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 764957de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 765057de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 7651a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 7652bb360cb4SStefano Zampini if (multilevel_requested) { 7653bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7654bb360cb4SStefano Zampini } else { 7655bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7656bb360cb4SStefano Zampini } 7657a198735bSStefano Zampini } else { 76587de4f681Sstefano_zampini PetscMPIInt rank; 7659a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 76607de4f681Sstefano_zampini have_void = (active_procs == (PetscInt)commsize) ? PETSC_FALSE : PETSC_TRUE; 7661a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 7662a198735bSStefano Zampini } 766357de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 766457de7509SStefano Zampini PetscInt psum; 766557de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 766657de7509SStefano Zampini else psum = 0; 766757de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 76687de4f681Sstefano_zampini if (ncoarse < commsize) have_void = PETSC_TRUE; 766957de7509SStefano Zampini } 767057de7509SStefano Zampini /* determine if we can go multilevel */ 767157de7509SStefano Zampini if (multilevel_requested) { 767257de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 767357de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 767457de7509SStefano Zampini } 767557de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 767657de7509SStefano Zampini 7677e4d548c7SStefano Zampini /* dump subassembling pattern */ 7678e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 7679e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 7680e4d548c7SStefano Zampini } 7681e4d548c7SStefano Zampini 76826e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 76831e0482f5SStefano Zampini nedcfield = -1; 76841e0482f5SStefano Zampini if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal)) { /* protects from unneded computations */ 76856e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 76866e683305SStefano Zampini const PetscInt *idxs; 76876e683305SStefano Zampini ISLocalToGlobalMapping tmap; 76886e683305SStefano Zampini 76896e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 76900be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 76916e683305SStefano Zampini /* allocate space for temporary storage */ 7692854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 7693854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 76946e683305SStefano Zampini /* allocate for IS array */ 76956e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 76961e0482f5SStefano Zampini if (pcbddc->nedclocal) { 76971e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 76981e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 76991e0482f5SStefano Zampini } else { 77001e0482f5SStefano Zampini nedcfield = 0; 77011e0482f5SStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%d)",nisdofs); 77021e0482f5SStefano Zampini nisdofs = 1; 77031e0482f5SStefano Zampini } 77041e0482f5SStefano Zampini } 77056e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 770627b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 770730368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 7708854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 77096e683305SStefano Zampini /* dofs splitting */ 77106e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 77116e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 77121e0482f5SStefano Zampini if (nedcfield != i) { 77136e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 77146e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 77156e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 77166e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 77171e0482f5SStefano Zampini } else { 77181e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 77191e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 77201e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 7721eee23b56SStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping coarse nedelec field! %d != %d\n",tsize,nout); 77221e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 77231e0482f5SStefano Zampini } 77246e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 772530368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 77266e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 77276e683305SStefano Zampini } 77286e683305SStefano Zampini /* neumann boundaries */ 77296e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 77306e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 77316e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 77326e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 77336e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 77346e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 77356e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 773630368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 77376e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 77386e683305SStefano Zampini } 77396e683305SStefano Zampini /* free memory */ 77406e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 77416e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 77426e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 77436e683305SStefano Zampini } else { 77446e683305SStefano Zampini nis = 0; 77456e683305SStefano Zampini nisdofs = 0; 77466e683305SStefano Zampini nisneu = 0; 774730368db7SStefano Zampini nisvert = 0; 77486e683305SStefano Zampini isarray = NULL; 77496e683305SStefano Zampini } 77506e683305SStefano Zampini /* destroy no longer needed map */ 77516e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 77526e683305SStefano Zampini 775357de7509SStefano Zampini /* subassemble */ 775457de7509SStefano Zampini if (multilevel_allowed) { 77551ae86dd6SStefano Zampini Vec vp[1]; 77561ae86dd6SStefano Zampini PetscInt nvecs = 0; 775757de7509SStefano Zampini PetscBool reuse,reuser; 77581ae86dd6SStefano Zampini 775957de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 776057de7509SStefano Zampini else reuse = PETSC_FALSE; 776157de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 77621ae86dd6SStefano Zampini vp[0] = NULL; 77631ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 77641ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 77651ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 77661ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 77671ae86dd6SStefano Zampini nvecs = 1; 77681ae86dd6SStefano Zampini 77691ae86dd6SStefano Zampini if (pcbddc->divudotp) { 7770a198735bSStefano Zampini Mat B,loc_divudotp; 77711ae86dd6SStefano Zampini Vec v,p; 77721ae86dd6SStefano Zampini IS dummy; 77731ae86dd6SStefano Zampini PetscInt np; 77741ae86dd6SStefano Zampini 7775a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 7776a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 77771ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 77787dae84e0SHong Zhang ierr = MatCreateSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 77791ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 77801ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 77811ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 77821ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 77831ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 77841ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 77851ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 77861ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 77871ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 77881ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 77891ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 77901ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 779174e2c79eSStefano Zampini } 77921ae86dd6SStefano Zampini } 77931ae86dd6SStefano Zampini if (reuser) { 77941e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 779574e2c79eSStefano Zampini } else { 77961e0482f5SStefano 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); 77971ae86dd6SStefano Zampini } 77981ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 77991ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 78001ae86dd6SStefano Zampini PetscInt nl; 78011ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 78021ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 78031ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 78041ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 78051ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 78061ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 78071ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 78081ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 7809a198735bSStefano Zampini } else { 7810a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 78111ae86dd6SStefano Zampini } 78121ae86dd6SStefano Zampini } else { 78131e0482f5SStefano 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); 78146e683305SStefano Zampini } 781557de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 781657de7509SStefano Zampini PetscMPIInt size; 7817f913dca9SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size);CHKERRQ(ierr); 781857de7509SStefano Zampini if (!multilevel_allowed) { 781957de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 78206e683305SStefano Zampini } else { 782157de7509SStefano Zampini Mat A; 7822779c1cceSStefano Zampini 782357de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 782457de7509SStefano Zampini if (coarse_mat_is) { 782557de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 782657de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 782757de7509SStefano Zampini coarse_mat = coarse_mat_is; 782857de7509SStefano Zampini } 782957de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 783057de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 783157de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 7832779c1cceSStefano Zampini } 7833779c1cceSStefano Zampini } 783457de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 783557de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 78366e683305SStefano Zampini 78376e683305SStefano Zampini /* create local to global scatters for coarse problem */ 783868457ee5SStefano Zampini if (compute_vecs) { 78396e683305SStefano Zampini PetscInt lrows; 78406e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 784157de7509SStefano Zampini if (coarse_mat) { 784257de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 78436e683305SStefano Zampini } else { 78446e683305SStefano Zampini lrows = 0; 78456e683305SStefano Zampini } 78466e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 78476e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 78486e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 78496e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 78506e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 78516e683305SStefano Zampini } 78526e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 7853c8587f34SStefano Zampini 7854f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 7855f9eb5b7dSStefano Zampini if (multilevel_allowed) { 7856f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 7857f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 7858f9eb5b7dSStefano Zampini } else { 7859f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 7860f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 7861c8587f34SStefano Zampini } 7862c8587f34SStefano Zampini 78636e683305SStefano Zampini /* print some info if requested */ 78646e683305SStefano Zampini if (pcbddc->dbg_flag) { 78656e683305SStefano Zampini if (!multilevel_allowed) { 78666e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 78676e683305SStefano Zampini if (multilevel_requested) { 78686e683305SStefano 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); 78696e683305SStefano Zampini } else if (pcbddc->max_levels) { 78706e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 78716e683305SStefano Zampini } 78726e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 78736e683305SStefano Zampini } 78746e683305SStefano Zampini } 78756e683305SStefano Zampini 78761e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 78771e0482f5SStefano Zampini coarseG = NULL; 78781e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 78791e0482f5SStefano Zampini MPI_Comm ccomm; 78801e0482f5SStefano Zampini if (coarse_mat) { 78811e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 78821e0482f5SStefano Zampini } else { 78831e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 78841e0482f5SStefano Zampini } 78851e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 78861e0482f5SStefano Zampini } 78871e0482f5SStefano Zampini 7888f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 788957de7509SStefano Zampini if (coarse_mat) { 78907274672aSStefano Zampini PetscBool isredundant,isnn,isbddc; 78916a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 78927274672aSStefano Zampini 78936e683305SStefano Zampini if (pcbddc->dbg_flag) { 789457de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 78956e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 78966e683305SStefano Zampini } 7897f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 7898312be037SStefano Zampini char prefix[256],str_level[16]; 7899e604994aSStefano Zampini size_t len; 79001e0482f5SStefano Zampini 790157de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 7902422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 7903c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 7904f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 790557de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 7906c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 79076e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 7908c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 79091e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 7910c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7911e604994aSStefano Zampini /* prefix */ 7912e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 7913e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 7914e604994aSStefano Zampini if (!pcbddc->current_level) { 7915e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 7916e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 7917c8587f34SStefano Zampini } else { 7918e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 7919312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 7920312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 792134d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 792235529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 7923e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 7924e604994aSStefano Zampini } 7925e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 79263e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 79273e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 79283e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 79293e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 7930f9eb5b7dSStefano Zampini /* allow user customization */ 7931f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 79323e3c6dadSStefano Zampini } 79333e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 793451bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 79353e3c6dadSStefano Zampini if (nisdofs) { 79363e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 79373e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 79383e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 79393e3c6dadSStefano Zampini } 79403e3c6dadSStefano Zampini } 79413e3c6dadSStefano Zampini if (nisneu) { 79423e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 79433e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 7944312be037SStefano Zampini } 794530368db7SStefano Zampini if (nisvert) { 794630368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 794730368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 794830368db7SStefano Zampini } 79491e0482f5SStefano Zampini if (coarseG) { 79501e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 79511e0482f5SStefano Zampini } 7952f9eb5b7dSStefano Zampini 7953f9eb5b7dSStefano Zampini /* get some info after set from options */ 7954f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 7955b76f3995Sstefano_zampini /* multilevel can only be requested via -pc_bddc_levels or PCBDDCSetLevels */ 7956b76f3995Sstefano_zampini if (isbddc && !multilevel_allowed) { 7957f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 7958f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 7959f9eb5b7dSStefano Zampini } 7960b76f3995Sstefano_zampini /* multilevel cannot be done with coarse PCs different from BDDC or NN */ 79617274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 79627274672aSStefano Zampini if (multilevel_requested && multilevel_allowed && !isbddc && !isnn) { 7963b76f3995Sstefano_zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 7964b76f3995Sstefano_zampini isbddc = PETSC_TRUE; 7965b76f3995Sstefano_zampini } 79667274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 79674f3a063dSStefano Zampini if (isredundant) { 79684f3a063dSStefano Zampini KSP inner_ksp; 79694f3a063dSStefano Zampini PC inner_pc; 79709326c5c6Sstefano_zampini 79714f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 79724f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 79734f3a063dSStefano Zampini } 7974f9eb5b7dSStefano Zampini 797557de7509SStefano Zampini /* parameters which miss an API */ 79767274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 797757de7509SStefano Zampini if (isbddc) { 7978720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 79797274672aSStefano Zampini 7980720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 798157de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 798227b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 798327b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 7984a198735bSStefano Zampini Mat coarsedivudotp_is; 7985a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 7986a198735bSStefano Zampini IS row,col; 7987a198735bSStefano Zampini const PetscInt *gidxs; 7988a198735bSStefano Zampini PetscInt n,st,M,N; 7989a198735bSStefano Zampini 7990a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 7991a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 7992a198735bSStefano Zampini st = st-n; 7993a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 7994a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 7995a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 7996a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7997a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 7998a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 7999a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 8000a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 8001a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 8002a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 8003a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 8004a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 8005a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 8006a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 8007a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 8008a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 8009a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 8010a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 8011a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 8012a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 80138ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 8014a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 8015720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 801659e48ca4SStefano Zampini if (pcbddc->adaptive_threshold < 1.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 8017720d30f9SStefano Zampini } 8018d4d8cf7bSStefano Zampini } 80199881197aSStefano Zampini 80203301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 80215a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 80223301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 80233301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 80243301b35fSStefano Zampini } 80253301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 80263301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 80273301b35fSStefano Zampini } 80283301b35fSStefano Zampini if (pc->pmat->spd_set) { 80293301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 80303301b35fSStefano Zampini } 803127b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 803227b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 803327b6a85dSStefano Zampini } 80346e683305SStefano Zampini /* set operators */ 80355f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 80366e683305SStefano Zampini if (pcbddc->dbg_flag) { 80376e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 80386e683305SStefano Zampini } 80396e683305SStefano Zampini } 80401e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 80416e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 8042b1ecc7b1SStefano Zampini #if 0 8043b9b85e73SStefano Zampini { 8044b9b85e73SStefano Zampini PetscViewer viewer; 8045b9b85e73SStefano Zampini char filename[256]; 8046b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 8047b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 80486a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 8049b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 8050f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 8051b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 8052b9b85e73SStefano Zampini } 8053b9b85e73SStefano Zampini #endif 8054f9eb5b7dSStefano Zampini 805598a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 805698a51de6SStefano Zampini Vec crhs,csol; 805704708bb6SStefano Zampini 8058f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 8059f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 8060f347579bSStefano Zampini if (!csol) { 80612a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 8062f9eb5b7dSStefano Zampini } 8063f347579bSStefano Zampini if (!crhs) { 80642a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 8065f347579bSStefano Zampini } 8066b0f5fe93SStefano Zampini } 80671ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 8068b0f5fe93SStefano Zampini 8069b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 8070b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 8071b0f5fe93SStefano Zampini 8072b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 80734f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 80744f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 80754f1b2e48SStefano Zampini } 8076b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 8077b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 8078b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8079b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8080b0f5fe93SStefano Zampini if (coarse_mat) { 8081b0f5fe93SStefano Zampini Vec nullv; 8082b0f5fe93SStefano Zampini PetscScalar *array,*array2; 8083b0f5fe93SStefano Zampini PetscInt nl; 8084b0f5fe93SStefano Zampini 8085b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 8086b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 8087b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8088b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 8089b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 8090b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 8091b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8092b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 8093b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 8094b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 8095b0f5fe93SStefano Zampini } 8096b0f5fe93SStefano Zampini } 8097b0f5fe93SStefano Zampini 8098b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 8099b0f5fe93SStefano Zampini PetscBool ispreonly; 8100b0f5fe93SStefano Zampini 8101b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8102b0f5fe93SStefano Zampini PetscBool isnull; 8103b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 8104bef83e63SStefano Zampini if (isnull) { 8105b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 8106b0f5fe93SStefano Zampini } 8107bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 8108b0f5fe93SStefano Zampini } 8109b0f5fe93SStefano Zampini /* setup coarse ksp */ 8110b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 8111cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 8112cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 81136e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 8114c8587f34SStefano Zampini KSP check_ksp; 81152b510759SStefano Zampini KSPType check_ksp_type; 8116c8587f34SStefano Zampini PC check_pc; 81176e683305SStefano Zampini Vec check_vec,coarse_vec; 81186a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 81192b510759SStefano Zampini PetscInt its; 81206e683305SStefano Zampini PetscBool compute_eigs; 81216e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 81226e683305SStefano Zampini PetscInt neigs; 81238e185a42SStefano Zampini const char *prefix; 8124c8587f34SStefano Zampini 81252b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 81266e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 8127422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 812823ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8129f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 8130e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 8131e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 8132e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 81332b510759SStefano Zampini if (ispreonly) { 81342b510759SStefano Zampini check_ksp_type = KSPPREONLY; 81356e683305SStefano Zampini compute_eigs = PETSC_FALSE; 81362b510759SStefano Zampini } else { 8137cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 81386e683305SStefano Zampini compute_eigs = PETSC_TRUE; 8139c8587f34SStefano Zampini } 8140c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 81416e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 81426e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 81436e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 8144a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 8145a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 8146a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 8147a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 8148c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 8149c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 8150c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 8151c8587f34SStefano Zampini /* create random vec */ 81522701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 8153c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 81546e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 8155c8587f34SStefano Zampini /* solve coarse problem */ 81566e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 8157cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 81586e683305SStefano Zampini if (compute_eigs) { 8159854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 8160854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 81616e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 81621ae86dd6SStefano Zampini if (neigs) { 81636e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 81646e683305SStefano Zampini lambda_min = eigs_r[0]; 81656e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 81662701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 81672701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 8168cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 8169cbcc2c2aSStefano Zampini } 8170c8587f34SStefano Zampini } 8171c8587f34SStefano Zampini } 81721ae86dd6SStefano Zampini } 8173cbcc2c2aSStefano Zampini 8174c8587f34SStefano Zampini /* check coarse problem residual error */ 81756e683305SStefano Zampini if (pcbddc->dbg_flag) { 81766e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 81776e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 81786e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 8179c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 81806e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 81816e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 8182779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 81836e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 81846e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 81856e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 81866e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 8187b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8188b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 8189b0f5fe93SStefano Zampini } 81906e683305SStefano Zampini if (compute_eigs) { 81916e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 8192b03ebc13SStefano Zampini KSPConvergedReason reason; 8193deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 8194c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 8195b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 81966e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 8197b03ebc13SStefano 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); 81986e683305SStefano Zampini for (i=0;i<neigs;i++) { 81996e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 8200c8587f34SStefano Zampini } 82016e683305SStefano Zampini } 82026e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 82036e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 82046e683305SStefano Zampini } 8205e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 82062701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 8207c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 82086e683305SStefano Zampini if (compute_eigs) { 82096e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 82106e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 8211c8587f34SStefano Zampini } 82126e683305SStefano Zampini } 82136e683305SStefano Zampini } 8214bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 8215cbcc2c2aSStefano Zampini /* print additional info */ 8216cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 82176e683305SStefano Zampini /* waits until all processes reaches this point */ 82186e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 8219cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 8220cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8221cbcc2c2aSStefano Zampini } 8222cbcc2c2aSStefano Zampini 82232b510759SStefano Zampini /* free memory */ 8224fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 8225c8587f34SStefano Zampini PetscFunctionReturn(0); 8226c8587f34SStefano Zampini } 8227674ae819SStefano Zampini 8228f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 8229f34684f1SStefano Zampini { 8230f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 8231f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 8232f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 8233dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 8234dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 823573be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 8236dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 8237f34684f1SStefano Zampini PetscErrorCode ierr; 8238f34684f1SStefano Zampini 8239f34684f1SStefano Zampini PetscFunctionBegin; 8240f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 82416c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 8242dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 82433bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 8244dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8245dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 82466583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 8247dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 8248dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 8249dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 82506c4ed002SBarry 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); 8251dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 8252dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8253dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 8254dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8255dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8256f34684f1SStefano Zampini 8257f34684f1SStefano Zampini /* check numbering */ 8258f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 8259019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 8260dc456d91SStefano Zampini PetscInt i; 8261b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 8262f34684f1SStefano Zampini 8263f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8264f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8265f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 82661575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8267019a44ceSStefano Zampini /* counter */ 8268019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8269019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 8270019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8271019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8272019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8273019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8274f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 8275f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 8276727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 8277f34684f1SStefano Zampini } 8278f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8279f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8280f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8281e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8282e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8283e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8284e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8285f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8286019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8287f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8288019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 82892c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 829075c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 8291b9b85e73SStefano Zampini set_error = PETSC_TRUE; 82922c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 82932c66d082SStefano 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); 8294f34684f1SStefano Zampini } 8295f34684f1SStefano Zampini } 8296019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8297b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8298f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8299f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8300f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 8301f34684f1SStefano Zampini } 8302f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8303f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8304e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8305e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8306f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 8307f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 8308b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 8309ca8b9ea9SStefano Zampini PetscInt *gidxs; 8310ca8b9ea9SStefano Zampini 8311ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 83123bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 8313f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 8314f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8315f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 8316f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 83174bc2dc4bSStefano 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); 8318f34684f1SStefano Zampini } 8319f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8320ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 8321f34684f1SStefano Zampini } 8322f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 83231575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8324302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 8325f34684f1SStefano Zampini } 83268bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 8327f34684f1SStefano Zampini /* get back data */ 8328f34684f1SStefano Zampini *coarse_size_n = coarse_size; 8329f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 8330674ae819SStefano Zampini PetscFunctionReturn(0); 8331674ae819SStefano Zampini } 8332674ae819SStefano Zampini 8333a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 8334e456f2a8SStefano Zampini { 8335e456f2a8SStefano Zampini IS localis_t; 8336a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 8337e456f2a8SStefano Zampini PetscScalar *vals; 8338e456f2a8SStefano Zampini PetscErrorCode ierr; 8339e456f2a8SStefano Zampini 8340e456f2a8SStefano Zampini PetscFunctionBegin; 8341a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 8342e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 8343854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 8344e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 8345e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8346a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 8347a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 83481035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 83493151afb1SStefano Zampini ierr = VecSetOption(gwork,VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE);CHKERRQ(ierr); 8350a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 83511035eff8SStefano Zampini } 8352a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 8353e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8354e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 8355a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 8356a7dc3881SStefano Zampini /* now compute set in local ordering */ 8357a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8358a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8359a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8360a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 8361a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8362ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8363e456f2a8SStefano Zampini lsize++; 8364e456f2a8SStefano Zampini } 8365e456f2a8SStefano Zampini } 8366854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 8367a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8368ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8369e456f2a8SStefano Zampini idxs[lsize++] = i; 8370e456f2a8SStefano Zampini } 8371e456f2a8SStefano Zampini } 8372a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8373a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 8374e456f2a8SStefano Zampini *localis = localis_t; 8375e456f2a8SStefano Zampini PetscFunctionReturn(0); 8376e456f2a8SStefano Zampini } 8377906d46d4SStefano Zampini 837808122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 8379b96c3477SStefano Zampini { 8380a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8381b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8382b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 8383a64f4aa4SStefano Zampini Mat S_j; 8384b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 8385b96c3477SStefano Zampini PetscBool free_used_adj; 8386b96c3477SStefano Zampini PetscErrorCode ierr; 8387b96c3477SStefano Zampini 8388b96c3477SStefano Zampini PetscFunctionBegin; 8389b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 8390b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 839108122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 8392b96c3477SStefano Zampini used_xadj = NULL; 8393b96c3477SStefano Zampini used_adjncy = NULL; 8394b96c3477SStefano Zampini } else { 839508122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 839608122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 839708122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 839808122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 8399b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 8400b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 8401b96c3477SStefano Zampini } else { 84022fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 8403b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 8404b96c3477SStefano Zampini PetscInt nvtxs; 8405b96c3477SStefano Zampini 84062fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 84072fffb893SStefano Zampini if (flg_row) { 8408b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 8409b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 8410b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 8411b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 84122fffb893SStefano Zampini } else { 84132fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 84142fffb893SStefano Zampini used_xadj = NULL; 84152fffb893SStefano Zampini used_adjncy = NULL; 84162fffb893SStefano Zampini } 84172fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 8418b96c3477SStefano Zampini } 8419b96c3477SStefano Zampini } 8420d5574798SStefano Zampini 8421d5574798SStefano Zampini /* setup sub_schurs data */ 8422a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8423df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 8424df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 8425a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 842691af6908SStefano 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); 8427a64f4aa4SStefano Zampini } else { 842872b8c272SStefano Zampini Mat change = NULL; 84299d54b7f4SStefano Zampini Vec scaling = NULL; 8430111315fdSstefano_zampini IS change_primal = NULL, iP; 8431111315fdSstefano_zampini PetscInt benign_n; 8432111315fdSstefano_zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 8433111315fdSstefano_zampini PetscBool isseqaij,need_change = PETSC_FALSE; 8434111315fdSstefano_zampini PetscBool discrete_harmonic = PETSC_FALSE; 8435a3df083aSStefano Zampini 84365feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 84375feab87aSStefano Zampini PetscInt n_vertices; 84385feab87aSStefano Zampini 84395feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 84402034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 84415feab87aSStefano Zampini } 844204708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 844304708bb6SStefano Zampini if (!isseqaij) { 844404708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 844504708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 844604708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 844704708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 844804708bb6SStefano Zampini } else { 8449511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 845004708bb6SStefano Zampini } 845104708bb6SStefano Zampini } 8452a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 8453a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 8454ca92afb2SStefano Zampini } else { 8455a3df083aSStefano Zampini benign_n = 0; 8456ca92afb2SStefano Zampini } 8457b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 8458b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 8459b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 846072b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 846122db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 8462b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 846322db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 8464b7ab4a40SStefano Zampini } 8465b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 8466b7ab4a40SStefano 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 */ 8467b7ab4a40SStefano Zampini if (need_change) { 846888c03ad3SStefano Zampini PC_IS *pcisf; 846988c03ad3SStefano Zampini PC_BDDC *pcbddcf; 847088c03ad3SStefano Zampini PC pcf; 847188c03ad3SStefano Zampini 8472e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 847388c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 847488c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 847588c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 8476b9be95fcSstefano_zampini 847788c03ad3SStefano Zampini /* hacks */ 847888c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 847972b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 848072b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 848172b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 848272b8c272SStefano Zampini pcisf->n = pcis->n; 848372b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 848488c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 848588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 848688c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 848788c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 848888c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 848988c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 849072b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 849188c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 8492b9be95fcSstefano_zampini 8493b9be95fcSstefano_zampini /* setup constraints so that we can get information on primal vertices and change of basis (in local numbering) */ 849488c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 849572b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 849672b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 849772b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 849872b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 8499b9be95fcSstefano_zampini 850088c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 850172b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 850288c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 850388c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 850488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 850588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 850688c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 850788c03ad3SStefano Zampini pcf->ops->destroy = NULL; 8508b9be95fcSstefano_zampini pcf->ops->reset = NULL; 850988c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 851088c03ad3SStefano Zampini } 85119d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 8512111315fdSstefano_zampini 8513111315fdSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 8514111315fdSstefano_zampini if (iP) { 8515111315fdSstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)iP),sub_schurs->prefix,"BDDC sub_schurs options","PC");CHKERRQ(ierr); 8516111315fdSstefano_zampini ierr = PetscOptionsBool("-sub_schurs_discrete_harmonic",NULL,NULL,discrete_harmonic,&discrete_harmonic,NULL);CHKERRQ(ierr); 8517111315fdSstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 8518111315fdSstefano_zampini } 8519111315fdSstefano_zampini if (discrete_harmonic) { 8520111315fdSstefano_zampini Mat A; 8521111315fdSstefano_zampini ierr = MatDuplicate(pcbddc->local_mat,MAT_COPY_VALUES,&A);CHKERRQ(ierr); 8522111315fdSstefano_zampini ierr = MatZeroRowsColumnsIS(A,iP,1.0,NULL,NULL);CHKERRQ(ierr); 8523111315fdSstefano_zampini ierr = PetscObjectCompose((PetscObject)A,"__KSPFETIDP_iP",(PetscObject)iP);CHKERRQ(ierr); 8524111315fdSstefano_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); 8525111315fdSstefano_zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 8526111315fdSstefano_zampini } else { 852791af6908SStefano 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); 8528111315fdSstefano_zampini } 852972b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 853072b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 8531ca92afb2SStefano Zampini } 8532d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8533b96c3477SStefano Zampini 8534b96c3477SStefano Zampini /* free adjacency */ 8535b96c3477SStefano Zampini if (free_used_adj) { 8536b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 8537b96c3477SStefano Zampini } 8538b96c3477SStefano Zampini PetscFunctionReturn(0); 8539b96c3477SStefano Zampini } 8540b96c3477SStefano Zampini 854108122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 8542b96c3477SStefano Zampini { 8543b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8544b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8545b96c3477SStefano Zampini PCBDDCGraph graph; 8546b96c3477SStefano Zampini PetscErrorCode ierr; 8547b96c3477SStefano Zampini 8548b96c3477SStefano Zampini PetscFunctionBegin; 8549b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 855008122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 85513301b35fSStefano Zampini IS verticesIS,verticescomm; 85523301b35fSStefano Zampini PetscInt vsize,*idxs; 8553b96c3477SStefano Zampini 8554b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 85553301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 85563301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 85573301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 85583301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 8559c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 8560b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 8561be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 8562441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 85633301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 8564b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 8565b96c3477SStefano Zampini } else { 8566b96c3477SStefano Zampini graph = pcbddc->mat_graph; 8567b96c3477SStefano Zampini } 8568e4d548c7SStefano Zampini /* print some info */ 85695c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 8570e4d548c7SStefano Zampini IS vertices; 8571e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 8572c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 8573e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8574e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 8575e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8576e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 8577e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 8578e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 8579e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 8580e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8581e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8582c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8583e4d548c7SStefano Zampini } 8584b96c3477SStefano Zampini 8585b96c3477SStefano Zampini /* sub_schurs init */ 8586b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 8587b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 8588b334f244SStefano Zampini } 85898b6046baSStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap,pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 8590e62b6521Sstefano_zampini pcbddc->sub_schurs->prefix = ((PetscObject)pc)->prefix; 8591a64f4aa4SStefano Zampini 8592b96c3477SStefano Zampini /* free graph struct */ 859308122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 8594b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 8595b96c3477SStefano Zampini } 8596b96c3477SStefano Zampini PetscFunctionReturn(0); 8597b96c3477SStefano Zampini } 8598fa34dd3eSStefano Zampini 8599fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 8600fa34dd3eSStefano Zampini { 8601fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8602fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8603fa34dd3eSStefano Zampini PetscErrorCode ierr; 8604fa34dd3eSStefano Zampini 8605fa34dd3eSStefano Zampini PetscFunctionBegin; 8606fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 8607fa34dd3eSStefano Zampini IS zerodiag = NULL; 86084f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 8609fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 86104f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 861175c01103SStefano Zampini PetscReal norm; 8612fa34dd3eSStefano Zampini PetscInt i; 8613fa34dd3eSStefano Zampini 8614fa34dd3eSStefano Zampini /* B0 and B0_B */ 8615fa34dd3eSStefano Zampini if (zerodiag) { 8616fa34dd3eSStefano Zampini IS dummy; 8617fa34dd3eSStefano Zampini 86184f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 86197dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 8620fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 8621fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 8622fa34dd3eSStefano Zampini } 8623fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 8624fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 8625fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 8626fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8627fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8628fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8629fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8630fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 8631fa34dd3eSStefano Zampini /* S_j */ 8632fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8633fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 8634fa34dd3eSStefano Zampini 8635fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 8636fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 8637fa34dd3eSStefano Zampini /* continuous in primal space */ 8638fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 8639fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8640fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8641fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 86424f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 86434f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 8644fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8645fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8646fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8647fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8648fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8649fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8650fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 8651fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 8652fa34dd3eSStefano Zampini 8653fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 8654fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 8655fa34dd3eSStefano Zampini /* local with Schur */ 8656fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 8657fa34dd3eSStefano Zampini if (zerodiag) { 8658fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 86594f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 8660fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8661fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 8662fa34dd3eSStefano Zampini } 8663fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 8664fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8665fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8666fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8667fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8668fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 8669fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8670fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8671fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 8672fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8673fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8674fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8675fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8676fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8677fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 8678fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 8679fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8680fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8681fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8682fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8683fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8684fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8685fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 8686fa34dd3eSStefano Zampini if (zerodiag) { 8687fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 8688fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 86894f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 8690fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8691fa34dd3eSStefano Zampini } 8692fa34dd3eSStefano Zampini /* BDDC */ 8693fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 8694fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 8695fa34dd3eSStefano Zampini 8696fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 8697fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 8698fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 8699fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 87004f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 87014f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 8702fa34dd3eSStefano Zampini } 87034f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 8704fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 8705fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 8706fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 8707fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8708fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 8709fa34dd3eSStefano Zampini } 8710fa34dd3eSStefano Zampini PetscFunctionReturn(0); 8711fa34dd3eSStefano Zampini } 87121e0482f5SStefano Zampini 87131e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 87141e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 87151e0482f5SStefano Zampini { 87161e0482f5SStefano Zampini Mat At; 87171e0482f5SStefano Zampini IS rows; 87181e0482f5SStefano Zampini PetscInt rst,ren; 87191e0482f5SStefano Zampini PetscErrorCode ierr; 87201e0482f5SStefano Zampini PetscLayout rmap; 87211e0482f5SStefano Zampini 87221e0482f5SStefano Zampini PetscFunctionBegin; 87231e0482f5SStefano Zampini rst = ren = 0; 87241e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 87251e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 87261e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 87271e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 87281e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 87291e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 87301e0482f5SStefano Zampini } 8731e07686f2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),ren-rst,rst,1,&rows);CHKERRQ(ierr); 87327dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 87331e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 87341e0482f5SStefano Zampini 87351e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 87361e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 87371e0482f5SStefano Zampini IS from,to; 87381e0482f5SStefano Zampini Vec gvec; 87391e0482f5SStefano Zampini PetscInt lsize; 87401e0482f5SStefano Zampini 87411e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 87421e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 87431e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 87441e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 87451e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 87461e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 87471e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 87481e0482f5SStefano Zampini ierr = MPI_Comm_size(ccomm,&b->size);CHKERRQ(ierr); 87491e0482f5SStefano Zampini ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRQ(ierr); 87501e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 87511e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 87521e0482f5SStefano Zampini b->A = a->A; 87531e0482f5SStefano Zampini b->B = a->B; 87541e0482f5SStefano Zampini 87551e0482f5SStefano Zampini b->donotstash = a->donotstash; 87561e0482f5SStefano Zampini b->roworiented = a->roworiented; 87571e0482f5SStefano Zampini b->rowindices = 0; 87581e0482f5SStefano Zampini b->rowvalues = 0; 87591e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 87601e0482f5SStefano Zampini 87611e0482f5SStefano Zampini (*B)->rmap = rmap; 87621e0482f5SStefano Zampini (*B)->factortype = A->factortype; 87631e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 87641e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 87651e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 87661e0482f5SStefano Zampini 87671e0482f5SStefano Zampini if (a->colmap) { 87681e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 87691e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 87701e0482f5SStefano Zampini #else 87711e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 87721e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 87731e0482f5SStefano Zampini ierr = PetscMemcpy(b->colmap,a->colmap,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 87741e0482f5SStefano Zampini #endif 87751e0482f5SStefano Zampini } else b->colmap = 0; 87761e0482f5SStefano Zampini if (a->garray) { 87771e0482f5SStefano Zampini PetscInt len; 87781e0482f5SStefano Zampini len = a->B->cmap->n; 87791e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 87801e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 87811e0482f5SStefano Zampini if (len) { ierr = PetscMemcpy(b->garray,a->garray,len*sizeof(PetscInt));CHKERRQ(ierr); } 87821e0482f5SStefano Zampini } else b->garray = 0; 87831e0482f5SStefano Zampini 87841e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 87851e0482f5SStefano Zampini b->lvec = a->lvec; 87861e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 87871e0482f5SStefano Zampini 87881e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 87891e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 87901e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 87911e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 87921e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 87931e0482f5SStefano Zampini ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 87941e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 87951e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 87961e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 87971e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 87981e0482f5SStefano Zampini } 87991e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 88001e0482f5SStefano Zampini PetscFunctionReturn(0); 88011e0482f5SStefano Zampini } 8802