11cf9b237SStefano Zampini #include <../src/mat/impls/aij/seq/aij.h> 2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> 3ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 4837cedc9SStefano Zampini #include <../src/mat/impls/dense/seq/dense.h> 5c80a6c00SStefano Zampini #include <petscdmplex.h> 6674ae819SStefano Zampini #include <petscblaslapack.h> 7daf8a457SStefano Zampini #include <petsc/private/sfimpl.h> 8c80a6c00SStefano Zampini #include <petsc/private/dmpleximpl.h> 97620a527SStefano Zampini #include <petscdmda.h> 10674ae819SStefano Zampini 111e0482f5SStefano Zampini static PetscErrorCode MatMPIAIJRestrict(Mat,MPI_Comm,Mat*); 121e0482f5SStefano Zampini 13f498cd09SStefano Zampini /* if range is true, it returns B s.t. span{B} = range(A) 14f498cd09SStefano Zampini if range is false, it returns B s.t. range(B) _|_ range(A) */ 15f498cd09SStefano Zampini PetscErrorCode MatDenseOrthogonalRangeOrComplement(Mat A, PetscBool range, PetscInt lw, PetscScalar *work, PetscReal *rwork, Mat *B) 16a13144ffSStefano Zampini { 17a13144ffSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 18a13144ffSStefano Zampini PetscScalar *uwork,*data,*U, ds = 0.; 19a13144ffSStefano Zampini PetscReal *sing; 20a13144ffSStefano Zampini PetscBLASInt bM,bN,lwork,lierr,di = 1; 21a13144ffSStefano Zampini PetscInt ulw,i,nr,nc,n; 22a13144ffSStefano Zampini PetscErrorCode ierr; 23a13144ffSStefano Zampini 24a13144ffSStefano Zampini PetscFunctionBegin; 25a13144ffSStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 26a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"LAPACK _GESVD not available"); 27614dbb09SStefano Zampini #else 28a13144ffSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 29a13144ffSStefano Zampini if (!nr || !nc) PetscFunctionReturn(0); 30a13144ffSStefano Zampini 31a13144ffSStefano Zampini /* workspace */ 32a13144ffSStefano Zampini if (!work) { 33a13144ffSStefano Zampini ulw = PetscMax(PetscMax(1,5*PetscMin(nr,nc)),3*PetscMin(nr,nc)+PetscMax(nr,nc)); 34f913dca9SStefano Zampini ierr = PetscMalloc1(ulw,&uwork);CHKERRQ(ierr); 35a13144ffSStefano Zampini } else { 36a13144ffSStefano Zampini ulw = lw; 37a13144ffSStefano Zampini uwork = work; 38a13144ffSStefano Zampini } 39a13144ffSStefano Zampini n = PetscMin(nr,nc); 40a13144ffSStefano Zampini if (!rwork) { 41a13144ffSStefano Zampini ierr = PetscMalloc1(n,&sing);CHKERRQ(ierr); 42a13144ffSStefano Zampini } else { 43a13144ffSStefano Zampini sing = rwork; 44a13144ffSStefano Zampini } 45a13144ffSStefano Zampini 46a13144ffSStefano Zampini /* SVD */ 47a13144ffSStefano Zampini ierr = PetscMalloc1(nr*nr,&U);CHKERRQ(ierr); 48a13144ffSStefano Zampini ierr = PetscBLASIntCast(nr,&bM);CHKERRQ(ierr); 49a13144ffSStefano Zampini ierr = PetscBLASIntCast(nc,&bN);CHKERRQ(ierr); 50a13144ffSStefano Zampini ierr = PetscBLASIntCast(ulw,&lwork);CHKERRQ(ierr); 51a13144ffSStefano Zampini ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); 52a13144ffSStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 53a13144ffSStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("A","N",&bM,&bN,data,&bM,sing,U,&bM,&ds,&di,uwork,&lwork,&lierr)); 54a13144ffSStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 55a13144ffSStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 56a13144ffSStefano Zampini ierr = MatDenseRestoreArray(A,&data);CHKERRQ(ierr); 57a13144ffSStefano Zampini for (i=0;i<n;i++) if (sing[i] < PETSC_SMALL) break; 58a13144ffSStefano Zampini if (!rwork) { 59a13144ffSStefano Zampini ierr = PetscFree(sing);CHKERRQ(ierr); 60a13144ffSStefano Zampini } 61a13144ffSStefano Zampini if (!work) { 62a13144ffSStefano Zampini ierr = PetscFree(uwork);CHKERRQ(ierr); 63a13144ffSStefano Zampini } 64a13144ffSStefano Zampini /* create B */ 65f498cd09SStefano Zampini if (!range) { 66a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,nr-i,NULL,B);CHKERRQ(ierr); 67a13144ffSStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 68a13144ffSStefano Zampini ierr = PetscMemcpy(data,U+nr*i,(nr-i)*nr*sizeof(PetscScalar));CHKERRQ(ierr); 69f498cd09SStefano Zampini } else { 70f498cd09SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,i,NULL,B);CHKERRQ(ierr); 71f498cd09SStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 72f498cd09SStefano Zampini ierr = PetscMemcpy(data,U,i*nr*sizeof(PetscScalar));CHKERRQ(ierr); 73f498cd09SStefano Zampini } 74a13144ffSStefano Zampini ierr = MatDenseRestoreArray(*B,&data);CHKERRQ(ierr); 75a13144ffSStefano Zampini ierr = PetscFree(U);CHKERRQ(ierr); 76614dbb09SStefano Zampini #endif 77614dbb09SStefano Zampini #else /* PETSC_USE_COMPLEX */ 78a13144ffSStefano Zampini PetscFunctionBegin; 79a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for complexes"); 80a13144ffSStefano Zampini #endif 81a13144ffSStefano Zampini PetscFunctionReturn(0); 82a13144ffSStefano Zampini } 83a13144ffSStefano Zampini 841e0482f5SStefano Zampini /* TODO REMOVE */ 851e0482f5SStefano Zampini #if defined(PRINT_GDET) 861e0482f5SStefano Zampini static int inc = 0; 871e0482f5SStefano Zampini static int lev = 0; 881e0482f5SStefano Zampini #endif 891e0482f5SStefano Zampini 901e0482f5SStefano Zampini PetscErrorCode PCBDDCComputeNedelecChangeEdge(Mat lG, IS edge, IS extrow, IS extcol, IS corners, Mat* Gins, Mat* GKins, PetscScalar cvals[2], PetscScalar *work, PetscReal *rwork) 91a13144ffSStefano Zampini { 92a13144ffSStefano Zampini PetscErrorCode ierr; 93a13144ffSStefano Zampini Mat GE,GEd; 94a13144ffSStefano Zampini PetscInt rsize,csize,esize; 95a13144ffSStefano Zampini PetscScalar *ptr; 96a13144ffSStefano Zampini 97a13144ffSStefano Zampini PetscFunctionBegin; 98a13144ffSStefano Zampini ierr = ISGetSize(edge,&esize);CHKERRQ(ierr); 99c3c0e390SStefano Zampini if (!esize) PetscFunctionReturn(0); 100a13144ffSStefano Zampini ierr = ISGetSize(extrow,&rsize);CHKERRQ(ierr); 101a13144ffSStefano Zampini ierr = ISGetSize(extcol,&csize);CHKERRQ(ierr); 102a13144ffSStefano Zampini 103a13144ffSStefano Zampini /* gradients */ 104a13144ffSStefano Zampini ptr = work + 5*esize; 1057dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,extrow,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 106a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,rsize,csize,ptr,Gins);CHKERRQ(ierr); 107a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,Gins);CHKERRQ(ierr); 108a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 109a13144ffSStefano Zampini 110a13144ffSStefano Zampini /* constants */ 111a13144ffSStefano Zampini ptr += rsize*csize; 112a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,esize,csize,ptr,&GEd);CHKERRQ(ierr); 1137dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,edge,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 114a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,&GEd);CHKERRQ(ierr); 115a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 116f498cd09SStefano Zampini ierr = MatDenseOrthogonalRangeOrComplement(GEd,PETSC_FALSE,5*esize,work,rwork,GKins);CHKERRQ(ierr); 117a13144ffSStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1181e0482f5SStefano Zampini 1191e0482f5SStefano Zampini if (corners) { 1201e0482f5SStefano Zampini Mat GEc; 1211e0482f5SStefano Zampini PetscScalar *vals,v; 1221e0482f5SStefano Zampini 1237dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,edge,corners,MAT_INITIAL_MATRIX,&GEc);CHKERRQ(ierr); 1241e0482f5SStefano Zampini ierr = MatTransposeMatMult(GEc,*GKins,MAT_INITIAL_MATRIX,1.0,&GEd);CHKERRQ(ierr); 1251e0482f5SStefano Zampini ierr = MatDenseGetArray(GEd,&vals);CHKERRQ(ierr); 126637e8532SStefano Zampini /* v = PetscAbsScalar(vals[0]) */; 127637e8532SStefano Zampini v = 1.; 1281e0482f5SStefano Zampini cvals[0] = vals[0]/v; 1291e0482f5SStefano Zampini cvals[1] = vals[1]/v; 1301e0482f5SStefano Zampini ierr = MatDenseRestoreArray(GEd,&vals);CHKERRQ(ierr); 1311e0482f5SStefano Zampini ierr = MatScale(*GKins,1./v);CHKERRQ(ierr); 1321e0482f5SStefano Zampini #if defined(PRINT_GDET) 1331e0482f5SStefano Zampini { 1341e0482f5SStefano Zampini PetscViewer viewer; 1351e0482f5SStefano Zampini char filename[256]; 1361e0482f5SStefano Zampini sprintf(filename,"Gdet_l%d_r%d_cc%d.m",lev,PetscGlobalRank,inc++); 1371e0482f5SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1381e0482f5SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1391e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEc,"GEc");CHKERRQ(ierr); 1401e0482f5SStefano Zampini ierr = MatView(GEc,viewer);CHKERRQ(ierr); 1411e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)(*GKins),"GK");CHKERRQ(ierr); 1421e0482f5SStefano Zampini ierr = MatView(*GKins,viewer);CHKERRQ(ierr); 1431e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEd,"Gproj");CHKERRQ(ierr); 1441e0482f5SStefano Zampini ierr = MatView(GEd,viewer);CHKERRQ(ierr); 1451e0482f5SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1461e0482f5SStefano Zampini } 1471e0482f5SStefano Zampini #endif 1481e0482f5SStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1491e0482f5SStefano Zampini ierr = MatDestroy(&GEc);CHKERRQ(ierr); 1501e0482f5SStefano Zampini } 1511e0482f5SStefano Zampini 152a13144ffSStefano Zampini PetscFunctionReturn(0); 153a13144ffSStefano Zampini } 154a13144ffSStefano Zampini 155a13144ffSStefano Zampini PetscErrorCode PCBDDCNedelecSupport(PC pc) 156a13144ffSStefano Zampini { 157a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 158a13144ffSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1590569b399SStefano Zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGe,lGinit; 160eee23b56SStefano Zampini Vec tvec; 161a13144ffSStefano Zampini PetscSF sfv; 1621e0482f5SStefano Zampini ISLocalToGlobalMapping el2g,vl2g,fl2g,al2g; 163a13144ffSStefano Zampini MPI_Comm comm; 164c2151214SStefano Zampini IS lned,primals,allprimals,nedfieldlocal; 165c2151214SStefano Zampini IS *eedges,*extrows,*extcols,*alleedges; 1667d871cd7SStefano Zampini PetscBT btv,bte,btvc,btb,btbd,btvcand,btvi,btee,bter; 167a13144ffSStefano Zampini PetscScalar *vals,*work; 168a13144ffSStefano Zampini PetscReal *rwork; 169a13144ffSStefano Zampini const PetscInt *idxs,*ii,*jj,*iit,*jjt; 1701e0482f5SStefano Zampini PetscInt ne,nv,Lv,order,n,field; 171a13144ffSStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 172eee23b56SStefano Zampini PetscInt i,j,extmem,cum,maxsize,nee; 173b03ebc13SStefano Zampini PetscInt *extrow,*extrowcum,*marks,*vmarks,*gidxs; 174a13144ffSStefano Zampini PetscInt *sfvleaves,*sfvroots; 175b03ebc13SStefano Zampini PetscInt *corners,*cedges; 176637e8532SStefano Zampini PetscInt *ecount,**eneighs,*vcount,**vneighs; 177b03ebc13SStefano Zampini #if defined(PETSC_USE_DEBUG) 178b03ebc13SStefano Zampini PetscInt *emarks; 179b03ebc13SStefano Zampini #endif 180213b8bfaSStefano Zampini PetscBool print,eerr,done,lrc[2],conforming,global,singular,setprimal; 181a13144ffSStefano Zampini PetscErrorCode ierr; 182a13144ffSStefano Zampini 183a13144ffSStefano Zampini PetscFunctionBegin; 184213b8bfaSStefano Zampini /* If the discrete gradient is defined for a subset of dofs and global is true, 185213b8bfaSStefano Zampini it assumes G is given in global ordering for all the dofs. 186213b8bfaSStefano Zampini Otherwise, the ordering is global for the Nedelec field */ 187213b8bfaSStefano Zampini order = pcbddc->nedorder; 188213b8bfaSStefano Zampini conforming = pcbddc->conforming; 189213b8bfaSStefano Zampini field = pcbddc->nedfield; 190213b8bfaSStefano Zampini global = pcbddc->nedglobal; 191213b8bfaSStefano Zampini setprimal = PETSC_FALSE; 192a13144ffSStefano Zampini print = PETSC_FALSE; 193213b8bfaSStefano Zampini singular = PETSC_FALSE; 194a13144ffSStefano Zampini 195213b8bfaSStefano Zampini /* Command line customization */ 196213b8bfaSStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC Nedelec options","PC");CHKERRQ(ierr); 197213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_field_primal","All edge dofs set as primals: Toselli's algorithm C",NULL,setprimal,&setprimal,NULL);CHKERRQ(ierr); 198213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_singular","Infer nullspace from discrete gradient",NULL,singular,&singular,NULL);CHKERRQ(ierr); 199213b8bfaSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_nedelec_order","Test variable order code (to be removed)",NULL,order,&order,NULL);CHKERRQ(ierr); 200213b8bfaSStefano Zampini /* print debug info TODO: to be removed */ 201213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_print","Print debug info",NULL,print,&print,NULL);CHKERRQ(ierr); 202213b8bfaSStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 203213b8bfaSStefano Zampini 204213b8bfaSStefano Zampini /* Return if there are no edges in the decomposition and the problem is not singular */ 2051e0482f5SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&al2g,NULL);CHKERRQ(ierr); 2061e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(al2g,&n);CHKERRQ(ierr); 207213b8bfaSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 208213b8bfaSStefano Zampini if (!singular) { 209a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 210a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 211c2151214SStefano Zampini for (i=0;i<n;i++) { 212a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 213a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 214a13144ffSStefano Zampini break; 215a13144ffSStefano Zampini } 216a13144ffSStefano Zampini } 217a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 218a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 219a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 220213b8bfaSStefano Zampini } 221a13144ffSStefano Zampini 222213b8bfaSStefano Zampini /* Get Nedelec field */ 223213b8bfaSStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 224c2151214SStefano Zampini if (pcbddc->n_ISForDofsLocal && field >= pcbddc->n_ISForDofsLocal) SETERRQ2(comm,PETSC_ERR_USER,"Invalid field for Nedelec %d: number of fields is %d",field,pcbddc->n_ISForDofsLocal); 225213b8bfaSStefano Zampini if (pcbddc->n_ISForDofsLocal && field >= 0) { 226c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[field]);CHKERRQ(ierr); 227c2151214SStefano Zampini nedfieldlocal = pcbddc->ISForDofsLocal[field]; 228c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 229213b8bfaSStefano Zampini } else if (!pcbddc->n_ISForDofsLocal && field != PETSC_DECIDE) { 230213b8bfaSStefano Zampini ne = n; 231213b8bfaSStefano Zampini nedfieldlocal = NULL; 232213b8bfaSStefano Zampini global = PETSC_TRUE; 233213b8bfaSStefano Zampini } else if (field == PETSC_DECIDE) { 234213b8bfaSStefano Zampini PetscInt rst,ren,*idx; 235213b8bfaSStefano Zampini 236213b8bfaSStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 237213b8bfaSStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 238213b8bfaSStefano Zampini ierr = MatGetOwnershipRange(pcbddc->discretegradient,&rst,&ren);CHKERRQ(ierr); 239213b8bfaSStefano Zampini for (i=rst;i<ren;i++) { 240213b8bfaSStefano Zampini PetscInt nc; 241213b8bfaSStefano Zampini 242213b8bfaSStefano Zampini ierr = MatGetRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 243213b8bfaSStefano Zampini if (nc > 1) matis->sf_rootdata[i-rst] = 1; 244213b8bfaSStefano Zampini ierr = MatRestoreRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 245213b8bfaSStefano Zampini } 246213b8bfaSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 247213b8bfaSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 248213b8bfaSStefano Zampini ierr = PetscMalloc1(n,&idx);CHKERRQ(ierr); 249213b8bfaSStefano Zampini for (i=0,ne=0;i<n;i++) if (matis->sf_leafdata[i]) idx[ne++] = i; 250213b8bfaSStefano Zampini ierr = ISCreateGeneral(comm,ne,idx,PETSC_OWN_POINTER,&nedfieldlocal);CHKERRQ(ierr); 251213b8bfaSStefano Zampini } else { 252213b8bfaSStefano Zampini SETERRQ(comm,PETSC_ERR_USER,"When multiple fields are present, the Nedelec field has to be specified"); 253213b8bfaSStefano Zampini } 254213b8bfaSStefano Zampini 255213b8bfaSStefano Zampini /* Sanity checks */ 256213b8bfaSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 257213b8bfaSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 258213b8bfaSStefano Zampini if (order && ne%order) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"The number of local edge dofs %d it's not a multiple of the order %d",ne,order); 259213b8bfaSStefano Zampini 260213b8bfaSStefano Zampini /* Just set primal dofs and return */ 2611e0482f5SStefano Zampini if (setprimal) { 262eee23b56SStefano Zampini IS enedfieldlocal; 263eee23b56SStefano Zampini PetscInt *eidxs; 264eee23b56SStefano Zampini 265eee23b56SStefano Zampini ierr = PetscMalloc1(ne,&eidxs);CHKERRQ(ierr); 266eee23b56SStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 267213b8bfaSStefano Zampini if (nedfieldlocal) { 268213b8bfaSStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 269eee23b56SStefano Zampini for (i=0,cum=0;i<ne;i++) { 270eee23b56SStefano Zampini if (PetscRealPart(vals[idxs[i]]) > 2.) { 271eee23b56SStefano Zampini eidxs[cum++] = idxs[i]; 272eee23b56SStefano Zampini } 273eee23b56SStefano Zampini } 274eee23b56SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 275213b8bfaSStefano Zampini } else { 276213b8bfaSStefano Zampini for (i=0,cum=0;i<ne;i++) { 277213b8bfaSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 278213b8bfaSStefano Zampini eidxs[cum++] = i; 279213b8bfaSStefano Zampini } 280213b8bfaSStefano Zampini } 281213b8bfaSStefano Zampini } 282213b8bfaSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 283eee23b56SStefano Zampini ierr = ISCreateGeneral(comm,cum,eidxs,PETSC_COPY_VALUES,&enedfieldlocal);CHKERRQ(ierr); 284eee23b56SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,enedfieldlocal);CHKERRQ(ierr); 285eee23b56SStefano Zampini ierr = PetscFree(eidxs);CHKERRQ(ierr); 2861e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 287eee23b56SStefano Zampini ierr = ISDestroy(&enedfieldlocal);CHKERRQ(ierr); 2881e0482f5SStefano Zampini PetscFunctionReturn(0); 2891e0482f5SStefano Zampini } 290a13144ffSStefano Zampini 291213b8bfaSStefano Zampini /* Compute some l2g maps */ 292213b8bfaSStefano Zampini if (nedfieldlocal) { 293c2151214SStefano Zampini IS is; 294c2151214SStefano Zampini 295c2151214SStefano Zampini /* need to map from the local Nedelec field to local numbering */ 296c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nedfieldlocal,&fl2g);CHKERRQ(ierr); 2971e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering for the whole dofs*/ 2981e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(al2g,nedfieldlocal,&is);CHKERRQ(ierr); 2991e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&al2g);CHKERRQ(ierr); 3001e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering (for Nedelec only) */ 3011e0482f5SStefano Zampini if (global) { 3021e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3031e0482f5SStefano Zampini el2g = al2g; 3041e0482f5SStefano Zampini } else { 3051e0482f5SStefano Zampini IS gis; 3061e0482f5SStefano Zampini 3071e0482f5SStefano Zampini ierr = ISRenumber(is,NULL,NULL,&gis);CHKERRQ(ierr); 3081e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gis,&el2g);CHKERRQ(ierr); 3091e0482f5SStefano Zampini ierr = ISDestroy(&gis);CHKERRQ(ierr); 3101e0482f5SStefano Zampini } 311c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 312c2151214SStefano Zampini } else { 3131e0482f5SStefano Zampini /* restore default */ 3141e0482f5SStefano Zampini pcbddc->nedfield = -1; 3151e0482f5SStefano Zampini /* one ref for the destruction of al2g, one for el2g */ 3161e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3171e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3181e0482f5SStefano Zampini el2g = al2g; 319c2151214SStefano Zampini fl2g = NULL; 320c2151214SStefano Zampini } 321a13144ffSStefano Zampini 322213b8bfaSStefano Zampini /* Start communication to drop connections for interior edges (for cc analysis only) */ 323c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 324c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 325c2151214SStefano Zampini if (nedfieldlocal) { 326c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 327c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 328c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 329c2151214SStefano Zampini } else { 330c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 331c2151214SStefano Zampini } 332c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 333c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 334213b8bfaSStefano Zampini 335213b8bfaSStefano Zampini if (!singular) { /* drop connections with interior edges to avoid unneeded communications and memory movements */ 336213b8bfaSStefano Zampini ierr = MatDuplicate(pcbddc->discretegradient,MAT_COPY_VALUES,&G);CHKERRQ(ierr); 337213b8bfaSStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 3381e0482f5SStefano Zampini if (global) { 3391e0482f5SStefano Zampini PetscInt rst; 3401e0482f5SStefano Zampini 341c2151214SStefano Zampini ierr = MatGetOwnershipRange(G,&rst,NULL);CHKERRQ(ierr); 342c2151214SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 343c2151214SStefano Zampini if (matis->sf_rootdata[i] < 2) { 344c2151214SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 345c2151214SStefano Zampini } 346c2151214SStefano Zampini } 347a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 348c2151214SStefano Zampini ierr = MatZeroRows(G,cum,matis->sf_rootdata,0.,NULL,NULL);CHKERRQ(ierr); 3491e0482f5SStefano Zampini } else { 3501e0482f5SStefano Zampini PetscInt *tbz; 3511e0482f5SStefano Zampini 3521e0482f5SStefano Zampini ierr = PetscMalloc1(ne,&tbz);CHKERRQ(ierr); 3531e0482f5SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3541e0482f5SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3551e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3561e0482f5SStefano Zampini for (i=0,cum=0;i<ne;i++) 3571e0482f5SStefano Zampini if (matis->sf_leafdata[idxs[i]] == 1) 3581e0482f5SStefano Zampini tbz[cum++] = i; 3591e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3601e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApply(el2g,cum,tbz,tbz);CHKERRQ(ierr); 3611e0482f5SStefano Zampini ierr = MatZeroRows(G,cum,tbz,0.,NULL,NULL);CHKERRQ(ierr); 3621e0482f5SStefano Zampini ierr = PetscFree(tbz);CHKERRQ(ierr); 3631e0482f5SStefano Zampini } 364213b8bfaSStefano Zampini } else { /* we need the entire G to infer the nullspace */ 365213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->discretegradient);CHKERRQ(ierr); 366213b8bfaSStefano Zampini G = pcbddc->discretegradient; 367213b8bfaSStefano Zampini } 368a13144ffSStefano Zampini 369a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 370a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 371a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 3727dae84e0SHong Zhang ierr = MatCreateSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 373a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 374a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 375a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 376a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 377a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 378a13144ffSStefano Zampini 379213b8bfaSStefano Zampini /* SF for nodal dofs communications */ 380c2151214SStefano Zampini ierr = MatGetLocalSize(G,NULL,&Lv);CHKERRQ(ierr); 381a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 382a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 383a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 384a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 385a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 386a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 387a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 388213b8bfaSStefano Zampini i = singular ? 2 : 1; 389213b8bfaSStefano Zampini ierr = PetscMalloc2(i*nv,&sfvleaves,i*Lv,&sfvroots);CHKERRQ(ierr); 390a13144ffSStefano Zampini 3911e0482f5SStefano Zampini /* Destroy temporary G created in MATIS format and modified G */ 392213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 393a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 394213b8bfaSStefano Zampini ierr = MatDestroy(&G);CHKERRQ(ierr); 395a13144ffSStefano Zampini 396213b8bfaSStefano Zampini if (print) { 397213b8bfaSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 398213b8bfaSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 399213b8bfaSStefano Zampini } 400213b8bfaSStefano Zampini 401213b8bfaSStefano Zampini /* Save lG for values insertion in change of basis */ 4020569b399SStefano Zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGinit);CHKERRQ(ierr); 4030569b399SStefano Zampini 404a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 4054e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 4064e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 407a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 408a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 409a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 4107d871cd7SStefano Zampini ierr = PetscBTCreate(ne,&btbd);CHKERRQ(ierr); 411c2151214SStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 412a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 413a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 414a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 415c2151214SStefano Zampini IS is; 416c2151214SStefano Zampini 417c2151214SStefano Zampini if (fl2g) { 418c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->DirichletBoundariesLocal,&is);CHKERRQ(ierr); 419c2151214SStefano Zampini } else { 420c2151214SStefano Zampini is = pcbddc->DirichletBoundariesLocal; 421c2151214SStefano Zampini } 422c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 423c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 424a13144ffSStefano Zampini for (i=0;i<cum;i++) { 425a13144ffSStefano Zampini if (idxs[i] >= 0) { 426a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 4277d871cd7SStefano Zampini ierr = PetscBTSet(btbd,idxs[i]);CHKERRQ(ierr); 428a13144ffSStefano Zampini } 429a13144ffSStefano Zampini } 430c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 431c2151214SStefano Zampini if (fl2g) { 432c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 433c2151214SStefano Zampini } 434a13144ffSStefano Zampini } 435a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 436c2151214SStefano Zampini IS is; 437c2151214SStefano Zampini 438c2151214SStefano Zampini if (fl2g) { 439c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->NeumannBoundariesLocal,&is);CHKERRQ(ierr); 440c2151214SStefano Zampini } else { 441c2151214SStefano Zampini is = pcbddc->NeumannBoundariesLocal; 442c2151214SStefano Zampini } 443c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 444c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 445a13144ffSStefano Zampini for (i=0;i<cum;i++) { 446a13144ffSStefano Zampini if (idxs[i] >= 0) { 447a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 448a13144ffSStefano Zampini } 449a13144ffSStefano Zampini } 450c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 451c2151214SStefano Zampini if (fl2g) { 452c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 453a13144ffSStefano Zampini } 454c2151214SStefano Zampini } 455c2151214SStefano Zampini 456213b8bfaSStefano Zampini /* Count neighs per dof */ 457*b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(el2g,NULL,&ecount,&eneighs);CHKERRQ(ierr); 458*b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingGetNodeInfo(vl2g,NULL,&vcount,&vneighs);CHKERRQ(ierr); 459637e8532SStefano Zampini 4607d871cd7SStefano Zampini /* need to remove coarse faces' dofs and coarse edges' dirichlet dofs 4617d871cd7SStefano Zampini for proper detection of coarse edges' endpoints */ 46262b0c6f7SStefano Zampini ierr = PetscBTCreate(ne,&btee);CHKERRQ(ierr); 46362b0c6f7SStefano Zampini for (i=0;i<ne;i++) { 464*b63b1311SStefano Zampini if ((ecount[i] > 2 && !PetscBTLookup(btbd,i)) || (ecount[i] == 2 && PetscBTLookup(btb,i))) { 46562b0c6f7SStefano Zampini ierr = PetscBTSet(btee,i);CHKERRQ(ierr); 46662b0c6f7SStefano Zampini } 46762b0c6f7SStefano Zampini } 468637e8532SStefano Zampini ierr = PetscMalloc1(ne,&marks);CHKERRQ(ierr); 46962b0c6f7SStefano Zampini if (!conforming) { 47062b0c6f7SStefano Zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 47162b0c6f7SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 47262b0c6f7SStefano Zampini } 4734e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 474dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 47562b0c6f7SStefano Zampini cum = 0; 476a13144ffSStefano Zampini for (i=0;i<ne;i++) { 477dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 47862b0c6f7SStefano Zampini if (!PetscBTLookup(btee,i)) { 479a13144ffSStefano Zampini marks[cum++] = i; 480dec27d64SStefano Zampini continue; 481dec27d64SStefano Zampini } 482dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 48362b0c6f7SStefano Zampini if (!conforming) { 48462b0c6f7SStefano Zampini if (ii[i+1]-ii[i] != order + 1) { /* every row of G on the coarse edge should list order+1 nodal dofs */ 485a13144ffSStefano Zampini marks[cum++] = i; 486a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 487a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 488a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 489a13144ffSStefano Zampini } 49062b0c6f7SStefano Zampini } else { 49162b0c6f7SStefano Zampini /* every edge dofs should be connected trough a certain number of nodal dofs 49262b0c6f7SStefano Zampini to other edge dofs belonging to coarse edges 49362b0c6f7SStefano Zampini - at most 2 endpoints 49462b0c6f7SStefano Zampini - order-1 interior nodal dofs 49562b0c6f7SStefano Zampini - no undefined nodal dofs (nconn < order) 49662b0c6f7SStefano Zampini */ 49762b0c6f7SStefano Zampini PetscInt ends = 0,ints = 0, undef = 0; 49862b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 49962b0c6f7SStefano Zampini PetscInt v = jj[j],k; 50062b0c6f7SStefano Zampini PetscInt nconn = iit[v+1]-iit[v]; 50162b0c6f7SStefano Zampini for (k=iit[v];k<iit[v+1];k++) if (!PetscBTLookup(btee,jjt[k])) nconn--; 50262b0c6f7SStefano Zampini if (nconn > order) ends++; 50362b0c6f7SStefano Zampini else if (nconn == order) ints++; 50462b0c6f7SStefano Zampini else undef++; 50562b0c6f7SStefano Zampini } 50662b0c6f7SStefano Zampini if (undef || ends > 2 || ints != order -1) { 50762b0c6f7SStefano Zampini marks[cum++] = i; 50862b0c6f7SStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 50962b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 51062b0c6f7SStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 51162b0c6f7SStefano Zampini } 51262b0c6f7SStefano Zampini } 51362b0c6f7SStefano Zampini } 514a13144ffSStefano Zampini } 515dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 516dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 517dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 518dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 519a13144ffSStefano Zampini } 520dec27d64SStefano Zampini } 52162b0c6f7SStefano Zampini ierr = PetscBTDestroy(&btee);CHKERRQ(ierr); 522dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 5234e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 52462b0c6f7SStefano Zampini if (!conforming) { 52562b0c6f7SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 52662b0c6f7SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 52762b0c6f7SStefano Zampini } 5284e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 529637e8532SStefano Zampini 530b03ebc13SStefano Zampini /* identify splitpoints and corner candidates */ 5314e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 532a13144ffSStefano Zampini if (print) { 5334e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 5344e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 5354e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 536a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 537a13144ffSStefano Zampini } 538a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 539dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 540a13144ffSStefano Zampini for (i=0;i<nv;i++) { 541637e8532SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i], vc = vcount[i]; 5427d871cd7SStefano Zampini PetscBool sneighs = PETSC_TRUE, bdir = PETSC_FALSE; 543b03ebc13SStefano Zampini if (!order) { /* variable order */ 544dec27d64SStefano Zampini PetscReal vorder = 0.; 545dec27d64SStefano Zampini 546dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 547dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 548dec27d64SStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%d)",vorder,test); 549dec27d64SStefano Zampini ord = 1; 550dec27d64SStefano Zampini } 551a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 552dec27d64SStefano Zampini if (test%ord) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected number of edge dofs %d connected with nodal dof %d with order %d",test,i,ord); 553a13144ffSStefano Zampini #endif 554637e8532SStefano Zampini for (j=ii[i];j<ii[i+1] && sneighs;j++) { 5557d871cd7SStefano Zampini if (PetscBTLookup(btbd,jj[j])) { 5567d871cd7SStefano Zampini bdir = PETSC_TRUE; 5577d871cd7SStefano Zampini break; 5587d871cd7SStefano Zampini } 559637e8532SStefano Zampini if (vc != ecount[jj[j]]) { 560637e8532SStefano Zampini sneighs = PETSC_FALSE; 561637e8532SStefano Zampini } else { 562637e8532SStefano Zampini PetscInt k,*vn = vneighs[i], *en = eneighs[jj[j]]; 563637e8532SStefano Zampini for (k=0;k<vc;k++) { 564637e8532SStefano Zampini if (vn[k] != en[k]) { 565637e8532SStefano Zampini sneighs = PETSC_FALSE; 566637e8532SStefano Zampini break; 567637e8532SStefano Zampini } 568637e8532SStefano Zampini } 569637e8532SStefano Zampini } 570637e8532SStefano Zampini } 5717d871cd7SStefano Zampini if (!sneighs || test >= 3*ord || bdir) { /* splitpoints */ 5727d871cd7SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %d (%d %d %d)\n",i,!sneighs,test >= 3*ord,bdir); 573a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 574dec27d64SStefano Zampini } else if (test == ord) { 575b03ebc13SStefano Zampini if (order == 1 || (!order && ii[i+1]-ii[i] == 1)) { 576a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %d\n",i); 577a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 578a13144ffSStefano Zampini } else { 579a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %d\n",i); 580a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 581a13144ffSStefano Zampini } 582a13144ffSStefano Zampini } 583a13144ffSStefano Zampini } 584*b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(el2g,NULL,&ecount,&eneighs);CHKERRQ(ierr); 585*b63b1311SStefano Zampini ierr = ISLocalToGlobalMappingRestoreNodeInfo(vl2g,NULL,&vcount,&vneighs);CHKERRQ(ierr); 5867d871cd7SStefano Zampini ierr = PetscBTDestroy(&btbd);CHKERRQ(ierr); 587b03ebc13SStefano Zampini 588b03ebc13SStefano Zampini /* a candidate is valid if it is connected to another candidate via a non-primal edge dof */ 589b03ebc13SStefano Zampini if (order != 1) { 590b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"INSPECTING CANDIDATES\n"); 591b03ebc13SStefano Zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 592b03ebc13SStefano Zampini for (i=0;i<nv;i++) { 593b03ebc13SStefano Zampini if (PetscBTLookup(btvcand,i)) { 594b03ebc13SStefano Zampini PetscBool found = PETSC_FALSE; 595b03ebc13SStefano Zampini for (j=ii[i];j<ii[i+1] && !found;j++) { 596b03ebc13SStefano Zampini PetscInt k,e = jj[j]; 597b03ebc13SStefano Zampini if (PetscBTLookup(bte,e)) continue; 598b03ebc13SStefano Zampini for (k=iit[e];k<iit[e+1];k++) { 599b03ebc13SStefano Zampini PetscInt v = jjt[k]; 600b03ebc13SStefano Zampini if (v != i && PetscBTLookup(btvcand,v)) { 601b03ebc13SStefano Zampini found = PETSC_TRUE; 602b03ebc13SStefano Zampini break; 603b03ebc13SStefano Zampini } 604b03ebc13SStefano Zampini } 605b03ebc13SStefano Zampini } 606b03ebc13SStefano Zampini if (!found) { 607b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d CLEARED\n",i); 608b03ebc13SStefano Zampini ierr = PetscBTClear(btvcand,i);CHKERRQ(ierr); 609b03ebc13SStefano Zampini } else { 610b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d ACCEPTED\n",i); 611b03ebc13SStefano Zampini } 612b03ebc13SStefano Zampini } 613b03ebc13SStefano Zampini } 614b03ebc13SStefano Zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 615b03ebc13SStefano Zampini } 616dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 617a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 618b03ebc13SStefano Zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 619a13144ffSStefano Zampini 620a13144ffSStefano Zampini /* Get the local G^T explicitly */ 6210569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 622a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 6234e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 624a13144ffSStefano Zampini 6254e64d54eSstefano_zampini /* Mark interior nodal dofs */ 626a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 6274e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 628a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 629a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 6304e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 631a13144ffSStefano Zampini } 632a13144ffSStefano Zampini } 633a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 634a13144ffSStefano Zampini 635a13144ffSStefano Zampini /* communicate corners and splitpoints */ 636a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 637a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 638a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 639a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 640a13144ffSStefano Zampini 641a13144ffSStefano Zampini if (print) { 642a13144ffSStefano Zampini IS tbz; 643a13144ffSStefano Zampini 644a13144ffSStefano Zampini cum = 0; 645a13144ffSStefano Zampini for (i=0;i<nv;i++) 646a13144ffSStefano Zampini if (sfvleaves[i]) 647a13144ffSStefano Zampini vmarks[cum++] = i; 648a13144ffSStefano Zampini 649a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 650a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 651a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 652a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 653a13144ffSStefano Zampini } 654a13144ffSStefano Zampini 655a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 656a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 657a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 658a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 659a13144ffSStefano Zampini 6604e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 6614e64d54eSstefano_zampini and interior nodal dofs */ 662a13144ffSStefano Zampini cum = 0; 663a13144ffSStefano Zampini for (i=0;i<nv;i++) { 664a13144ffSStefano Zampini if (sfvleaves[i]) { 665a13144ffSStefano Zampini vmarks[cum++] = i; 666a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 667a13144ffSStefano Zampini } 6684e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 669a13144ffSStefano Zampini } 6704e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 671a13144ffSStefano Zampini if (print) { 672a13144ffSStefano Zampini IS tbz; 673a13144ffSStefano Zampini 674a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 6754e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 676a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 677a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 678a13144ffSStefano Zampini } 679a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 680a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 681a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 682a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 683a13144ffSStefano Zampini 684a13144ffSStefano Zampini /* Recompute G */ 685a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 686a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 687a13144ffSStefano Zampini if (print) { 688a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 689a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 690a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 691a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 692a13144ffSStefano Zampini } 693a13144ffSStefano Zampini 694a13144ffSStefano Zampini /* Get primal dofs (if any) */ 695a13144ffSStefano Zampini cum = 0; 696a13144ffSStefano Zampini for (i=0;i<ne;i++) { 697a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 698a13144ffSStefano Zampini } 699c2151214SStefano Zampini if (fl2g) { 700c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 701c2151214SStefano Zampini } 702a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 703a13144ffSStefano Zampini if (print) { 704a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 705a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 706a13144ffSStefano Zampini } 707a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 708c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 709a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 710a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 711a13144ffSStefano Zampini 712a13144ffSStefano Zampini /* Compute edge connectivity */ 713a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 714a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 715a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 716c2151214SStefano Zampini if (fl2g) { 717c2151214SStefano Zampini PetscBT btf; 718c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 719c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 720c2151214SStefano Zampini 721c2151214SStefano Zampini /* create CSR for all local dofs */ 722c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 723c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 724c2151214SStefano 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); 725c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 726c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 727c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 728c2151214SStefano Zampini rest = PETSC_TRUE; 729c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 730c2151214SStefano Zampini } else { 731c2151214SStefano Zampini free = PETSC_TRUE; 732c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 733c2151214SStefano Zampini iiu[0] = 0; 734c2151214SStefano Zampini for (i=0;i<n;i++) { 735c2151214SStefano Zampini iiu[i+1] = i+1; 736c2151214SStefano Zampini jju[i] = -1; 737d904f53bSStefano Zampini } 738c2151214SStefano Zampini } 739c2151214SStefano Zampini 740c2151214SStefano Zampini /* import sizes of CSR */ 741c2151214SStefano Zampini iia[0] = 0; 742c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 743c2151214SStefano Zampini 744c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 745c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 746c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 747c2151214SStefano Zampini for (i=0;i<ne;i++) { 748c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 749c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 750c2151214SStefano Zampini } 751c2151214SStefano Zampini 752c2151214SStefano Zampini /* iia in CSR */ 753c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 754c2151214SStefano Zampini 755c2151214SStefano Zampini /* jja in CSR */ 756c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 757c2151214SStefano Zampini for (i=0;i<n;i++) 758c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 759c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 760c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 761c2151214SStefano Zampini 762c2151214SStefano Zampini /* map edge dofs connectivity */ 7631e0482f5SStefano Zampini if (jj) { 764c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 765c2151214SStefano Zampini for (i=0;i<ne;i++) { 766c2151214SStefano Zampini PetscInt e = idxs[i]; 767c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 768c2151214SStefano Zampini } 7691e0482f5SStefano Zampini } 770c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 771c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 772c2151214SStefano Zampini if (rest) { 773c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 774c2151214SStefano Zampini } 775c2151214SStefano Zampini if (free) { 776c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 777c2151214SStefano Zampini } 778c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 779c2151214SStefano Zampini } else { 780c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 781c2151214SStefano Zampini } 782c2151214SStefano Zampini 783a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 784a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 785213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 786a13144ffSStefano Zampini 787a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 788c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 789a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 790a13144ffSStefano Zampini 791c2151214SStefano Zampini if (fl2g) { 792c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 793c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 794c2151214SStefano Zampini for (i=0;i<nee;i++) { 795c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 796c2151214SStefano Zampini } 797c2151214SStefano Zampini } else { 798c2151214SStefano Zampini eedges = alleedges; 799c2151214SStefano Zampini primals = allprimals; 800c2151214SStefano Zampini } 801c2151214SStefano Zampini 802a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 803a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 804c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 805c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 806c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 807c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 808c2151214SStefano Zampini if (print) { 809c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 810c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 811c2151214SStefano Zampini } 812c2151214SStefano Zampini 813c2151214SStefano Zampini maxsize = 0; 814a13144ffSStefano Zampini for (i=0;i<nee;i++) { 815a13144ffSStefano Zampini PetscInt size,mark = i+1; 816a13144ffSStefano Zampini 817a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 818a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 819a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 820a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 821a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 822a13144ffSStefano Zampini } 823a13144ffSStefano Zampini 824a13144ffSStefano Zampini /* Find coarse edge endpoints */ 825a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 826a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 827a13144ffSStefano Zampini for (i=0;i<nee;i++) { 828a13144ffSStefano Zampini PetscInt mark = i+1,size; 829a13144ffSStefano Zampini 830a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8311e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8321e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 833a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 834a13144ffSStefano Zampini if (print) { 835a13144ffSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %d\n",i); 836a13144ffSStefano Zampini ISView(eedges[i],NULL); 837a13144ffSStefano Zampini } 838a13144ffSStefano Zampini for (j=0;j<size;j++) { 839a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 840a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %d\n",ee); 841a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 842a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %d\n",jj[k]); 843a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 844a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %d\n",jj[k]); 845a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 846a13144ffSStefano Zampini PetscInt k2; 847a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 848a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 849c2151214SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," INSPECTING %d: mark %d (ref mark %d), boundary %d\n",jjt[k2],marks[jjt[k2]],mark,!!PetscBTLookup(btb,jjt[k2])); 850c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 851c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 852c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 853a13144ffSStefano Zampini corner = PETSC_TRUE; 854a13144ffSStefano Zampini break; 855a13144ffSStefano Zampini } 856a13144ffSStefano Zampini } 857a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 858a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %d\n",jj[k]); 859a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 860a13144ffSStefano Zampini } else { 861a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 862a13144ffSStefano Zampini } 863a13144ffSStefano Zampini } 864a13144ffSStefano Zampini } 865a13144ffSStefano Zampini } 866a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 867a13144ffSStefano Zampini } 868a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 869a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 870c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 871a13144ffSStefano Zampini 872a13144ffSStefano Zampini /* Reset marked primal dofs */ 873a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 874a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 875a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 876a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 877a13144ffSStefano Zampini 8780569b399SStefano Zampini /* Now use the initial lG */ 8790569b399SStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 8800569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 8810569b399SStefano Zampini lG = lGinit; 8820569b399SStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 8830569b399SStefano Zampini 884a13144ffSStefano Zampini /* Compute extended cols indices */ 885b03ebc13SStefano Zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 886b03ebc13SStefano Zampini ierr = PetscBTCreate(nee,&bter);CHKERRQ(ierr); 887a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 888a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 889a13144ffSStefano Zampini i *= maxsize; 890b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 891a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 892a13144ffSStefano Zampini eerr = PETSC_FALSE; 893a13144ffSStefano Zampini for (i=0;i<nee;i++) { 894b03ebc13SStefano Zampini PetscInt size,found = 0; 895a13144ffSStefano Zampini 896a13144ffSStefano Zampini cum = 0; 897a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8981e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8991e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 900a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 901b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 902a13144ffSStefano Zampini for (j=0;j<size;j++) { 903a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 904b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 905b03ebc13SStefano Zampini PetscInt vv = jj[k]; 906b03ebc13SStefano Zampini if (!PetscBTLookup(btv,vv)) extrow[cum++] = vv; 907b03ebc13SStefano Zampini else if (!PetscBTLookupSet(btvc,vv)) found++; 908b03ebc13SStefano Zampini } 909a13144ffSStefano Zampini } 910a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 911a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 912a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 913a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 914a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 915a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 916a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 917b03ebc13SStefano Zampini if (cum != size -1 || found != 2) { 918b03ebc13SStefano Zampini ierr = PetscBTSet(bter,i);CHKERRQ(ierr); 919a13144ffSStefano Zampini if (print) { 920a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 921a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 922a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 923a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 924a13144ffSStefano Zampini } 925a13144ffSStefano Zampini eerr = PETSC_TRUE; 926a13144ffSStefano Zampini } 927a13144ffSStefano Zampini } 9284e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 929a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 930a13144ffSStefano Zampini if (done) { 931a13144ffSStefano Zampini PetscInt *newprimals; 932a13144ffSStefano Zampini 933a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 934a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 935a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 936a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 937a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 9380569b399SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 939b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"DOING SECOND PASS (eerr %d)\n",eerr); 940a13144ffSStefano Zampini for (i=0;i<nee;i++) { 941b03ebc13SStefano Zampini PetscBool has_candidates = PETSC_FALSE; 942b03ebc13SStefano Zampini if (PetscBTLookup(bter,i)) { 943a13144ffSStefano Zampini PetscInt size,mark = i+1; 944a13144ffSStefano Zampini 945a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 946a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 947c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 948a13144ffSStefano Zampini for (j=0;j<size;j++) { 949a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 950b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"Inspecting edge dof %d [%d %d)\n",ee,ii[ee],ii[ee+1]); 951a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 952a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 953a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 954a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 955b03ebc13SStefano Zampini has_candidates = PETSC_TRUE; 956b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Candidate set to vertex %d\n",vv); 957a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 958a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 959a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 960a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 961a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 962b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected edge dof set to primal %d\n",ee2); 963a13144ffSStefano Zampini newprimals[cum++] = ee2; 964a13144ffSStefano Zampini /* finally set the new corners */ 965a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 966b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected nodal dof set to vertex %d\n",jj[k3]); 967a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 968a13144ffSStefano Zampini } 969a13144ffSStefano Zampini } 970a13144ffSStefano Zampini } 971b03ebc13SStefano Zampini } else { 972b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Not a candidate vertex %d\n",jj[k]); 973a13144ffSStefano Zampini } 974a13144ffSStefano Zampini } 975a13144ffSStefano Zampini } 976b03ebc13SStefano Zampini if (!has_candidates) { /* circular edge */ 977b03ebc13SStefano Zampini PetscInt k, ee = idxs[0],*tmarks; 978b03ebc13SStefano Zampini 979b03ebc13SStefano Zampini ierr = PetscCalloc1(ne,&tmarks);CHKERRQ(ierr); 980b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Circular edge %d\n",i); 981b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 982b03ebc13SStefano Zampini PetscInt k2; 983b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Set to corner %d\n",jj[k]); 984b03ebc13SStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 985b03ebc13SStefano Zampini for (k2=iit[jj[k]];k2<iit[jj[k]+1];k2++) tmarks[jjt[k2]]++; 986b03ebc13SStefano Zampini } 987b03ebc13SStefano Zampini for (j=0;j<size;j++) { 988b03ebc13SStefano Zampini if (tmarks[idxs[j]] > 1) { 989b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Edge dof set to primal %d\n",idxs[j]); 990b03ebc13SStefano Zampini newprimals[cum++] = idxs[j]; 991b03ebc13SStefano Zampini } 992b03ebc13SStefano Zampini } 993b03ebc13SStefano Zampini ierr = PetscFree(tmarks);CHKERRQ(ierr); 994b03ebc13SStefano Zampini } 995a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 996a13144ffSStefano Zampini } 997a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 998a13144ffSStefano Zampini } 999b03ebc13SStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 10000569b399SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 1001a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 1002c2151214SStefano Zampini if (fl2g) { 1003c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 1004c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1005c2151214SStefano Zampini for (i=0;i<nee;i++) { 1006c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1007c2151214SStefano Zampini } 1008c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1009c2151214SStefano Zampini } 1010c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1011a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 1012a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 1013a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 1014a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1015a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 1016213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 1017c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1018c2151214SStefano Zampini if (fl2g) { 1019c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 1020c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 1021c2151214SStefano Zampini for (i=0;i<nee;i++) { 1022c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 1023c2151214SStefano Zampini } 1024c2151214SStefano Zampini } else { 1025c2151214SStefano Zampini eedges = alleedges; 1026c2151214SStefano Zampini primals = allprimals; 1027c2151214SStefano Zampini } 1028b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 1029a13144ffSStefano Zampini 1030a13144ffSStefano Zampini /* Mark again */ 1031a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 1032a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1033a13144ffSStefano Zampini PetscInt size,mark = i+1; 1034a13144ffSStefano Zampini 1035a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 1036a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1037a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 1038a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1039a13144ffSStefano Zampini } 1040a13144ffSStefano Zampini if (print) { 1041a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 1042a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 1043a13144ffSStefano Zampini } 1044a13144ffSStefano Zampini 1045a13144ffSStefano Zampini /* Recompute extended cols */ 1046a13144ffSStefano Zampini eerr = PETSC_FALSE; 1047a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1048a13144ffSStefano Zampini PetscInt size; 1049a13144ffSStefano Zampini 1050a13144ffSStefano Zampini cum = 0; 1051a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 10521e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 10531e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 1054a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1055a13144ffSStefano Zampini for (j=0;j<size;j++) { 1056a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 10571e0482f5SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 1058a13144ffSStefano Zampini } 1059a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1060a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 1061a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 1062a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 1063a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 1064a13144ffSStefano Zampini if (cum != size -1) { 1065a13144ffSStefano Zampini if (print) { 1066a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 1067a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 1068a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 1069a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 1070a13144ffSStefano Zampini } 1071a13144ffSStefano Zampini eerr = PETSC_TRUE; 1072a13144ffSStefano Zampini } 1073a13144ffSStefano Zampini } 1074a13144ffSStefano Zampini } 1075a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1076a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 1077b03ebc13SStefano Zampini ierr = PetscBTDestroy(&bter);CHKERRQ(ierr); 10787d871cd7SStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 1079a13144ffSStefano Zampini /* an error should not occur at this point */ 1080a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 1081a13144ffSStefano Zampini 10824e64d54eSstefano_zampini /* Check the number of endpoints */ 10830569b399SStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1084b03ebc13SStefano Zampini ierr = PetscMalloc1(2*nee,&corners);CHKERRQ(ierr); 1085b03ebc13SStefano Zampini ierr = PetscMalloc1(nee,&cedges);CHKERRQ(ierr); 10864e64d54eSstefano_zampini for (i=0;i<nee;i++) { 1087b03ebc13SStefano Zampini PetscInt size, found = 0, gc[2]; 10884e64d54eSstefano_zampini 1089b03ebc13SStefano Zampini /* init with defaults */ 1090b03ebc13SStefano Zampini cedges[i] = corners[i*2] = corners[i*2+1] = -1; 10914e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 10921e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 10931e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 10944e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1095b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 10964e64d54eSstefano_zampini for (j=0;j<size;j++) { 10974e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 10984e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 10994e64d54eSstefano_zampini PetscInt vv = jj[k]; 11004e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 1101b03ebc13SStefano Zampini if (found == 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found more then two corners for edge %d\n",i); 1102b03ebc13SStefano Zampini corners[i*2+found++] = vv; 11034e64d54eSstefano_zampini } 11044e64d54eSstefano_zampini } 11054e64d54eSstefano_zampini } 1106b03ebc13SStefano Zampini if (found != 2) { 1107b03ebc13SStefano Zampini PetscInt e; 1108b03ebc13SStefano Zampini if (fl2g) { 1109b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,1,idxs,&e);CHKERRQ(ierr); 1110b03ebc13SStefano Zampini } else { 1111b03ebc13SStefano Zampini e = idxs[0]; 1112b03ebc13SStefano Zampini } 1113b03ebc13SStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %d corners for edge %d (astart %d, estart %d)\n",found,i,e,idxs[0]); 1114b03ebc13SStefano Zampini } 1115eee23b56SStefano Zampini 1116eee23b56SStefano Zampini /* get primal dof index on this coarse edge */ 1117b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,2,corners+2*i,gc);CHKERRQ(ierr); 1118b03ebc13SStefano Zampini if (gc[0] > gc[1]) { 1119b03ebc13SStefano Zampini PetscInt swap = corners[2*i]; 1120b03ebc13SStefano Zampini corners[2*i] = corners[2*i+1]; 1121b03ebc13SStefano Zampini corners[2*i+1] = swap; 1122b03ebc13SStefano Zampini } 1123eee23b56SStefano Zampini cedges[i] = idxs[size-1]; 11244e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1125b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"EDGE %d: ce %d, corners (%d,%d)\n",i,cedges[i],corners[2*i],corners[2*i+1]); 11264e64d54eSstefano_zampini } 11270569b399SStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 11284e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 11294e64d54eSstefano_zampini 1130a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 1131a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 1132a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 1133a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 1134a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1135a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1136a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 1137a13144ffSStefano Zampini 1138a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1139a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 1140a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 1141a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 1142a13144ffSStefano Zampini if (emax < emarks[j]) { 1143a13144ffSStefano Zampini emax = emarks[j]; 1144a13144ffSStefano Zampini eemax = j; 1145a13144ffSStefano Zampini } 1146a13144ffSStefano Zampini } 1147a13144ffSStefano Zampini /* not relevant for edges */ 1148a13144ffSStefano Zampini if (!eemax) continue; 1149a13144ffSStefano Zampini 1150a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 1151a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 1152c2151214SStefano 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]); 1153a13144ffSStefano Zampini } 1154a13144ffSStefano Zampini } 1155a13144ffSStefano Zampini } 1156a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 1157a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1158a13144ffSStefano Zampini #endif 1159a13144ffSStefano Zampini 1160a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 1161a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1162a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 1163a13144ffSStefano Zampini extmem *= maxsize; 1164a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 1165a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 1166a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 1167a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1168a13144ffSStefano Zampini PetscInt mark = 0,size,start; 1169213b8bfaSStefano Zampini 1170a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1171a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 1172a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 1173a13144ffSStefano Zampini mark = marks[jj[j]]; 1174a13144ffSStefano Zampini 1175a13144ffSStefano Zampini /* not relevant */ 1176a13144ffSStefano Zampini if (!mark) continue; 1177a13144ffSStefano Zampini 1178a13144ffSStefano Zampini /* import extended row */ 1179a13144ffSStefano Zampini mark--; 1180a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 1181a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 1182a13144ffSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %d > %d",extrowcum[mark] + size,extmem); 1183a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 1184a13144ffSStefano Zampini extrowcum[mark] += size; 1185a13144ffSStefano Zampini } 1186a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1187213b8bfaSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 1188213b8bfaSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 1189213b8bfaSStefano Zampini 1190213b8bfaSStefano Zampini /* Compress extrows */ 1191a13144ffSStefano Zampini cum = 0; 1192a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1193a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 1194a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 1195a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 1196a13144ffSStefano Zampini cum = PetscMax(cum,size); 1197a13144ffSStefano Zampini } 1198a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 1199a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 1200a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 1201a13144ffSStefano Zampini 1202a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 1203a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 1204a13144ffSStefano Zampini 1205a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 1206a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1207c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 1208c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 1209a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 1210a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 1211a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 12121e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(T,al2g,al2g);CHKERRQ(ierr); 1213a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 1214a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1215213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&al2g);CHKERRQ(ierr); 1216a13144ffSStefano Zampini 1217a13144ffSStefano Zampini /* Defaults to identity */ 1218c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 1219a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 1220a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 1221a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 1222a13144ffSStefano Zampini 12231e0482f5SStefano Zampini /* Create discrete gradient for the coarser level if needed */ 12241e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 12251e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 12261e0482f5SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 12271e0482f5SStefano Zampini ISLocalToGlobalMapping cel2g,cvl2g; 12281e0482f5SStefano Zampini IS wis,gwis; 12291e0482f5SStefano Zampini PetscInt cnv,cne; 12301e0482f5SStefano Zampini 12311e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,nee,cedges,PETSC_COPY_VALUES,&wis);CHKERRQ(ierr); 12321e0482f5SStefano Zampini if (fl2g) { 12331e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(fl2g,wis,&pcbddc->nedclocal);CHKERRQ(ierr); 12341e0482f5SStefano Zampini } else { 12351e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)wis);CHKERRQ(ierr); 12361e0482f5SStefano Zampini pcbddc->nedclocal = wis; 12371e0482f5SStefano Zampini } 12381e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,wis,&gwis);CHKERRQ(ierr); 12391e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12401e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cne,&wis);CHKERRQ(ierr); 12411e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cel2g);CHKERRQ(ierr); 12421e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12431e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 12441e0482f5SStefano Zampini 12451e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,2*nee,corners,PETSC_USE_POINTER,&wis);CHKERRQ(ierr); 12461e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(vl2g,wis,&gwis);CHKERRQ(ierr); 12471e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12481e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cnv,&wis);CHKERRQ(ierr); 12491e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cvl2g);CHKERRQ(ierr); 12501e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12511e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 12521e0482f5SStefano Zampini 12531e0482f5SStefano Zampini ierr = MatCreate(comm,&pcbddc->nedcG);CHKERRQ(ierr); 12541e0482f5SStefano Zampini ierr = MatSetSizes(pcbddc->nedcG,PETSC_DECIDE,PETSC_DECIDE,cne,cnv);CHKERRQ(ierr); 12551e0482f5SStefano Zampini ierr = MatSetType(pcbddc->nedcG,MATAIJ);CHKERRQ(ierr); 12561e0482f5SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->nedcG,2,NULL);CHKERRQ(ierr); 12571e0482f5SStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->nedcG,2,NULL,2,NULL);CHKERRQ(ierr); 12581e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->nedcG,cel2g,cvl2g);CHKERRQ(ierr); 12591e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cel2g);CHKERRQ(ierr); 12601e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cvl2g);CHKERRQ(ierr); 12611e0482f5SStefano Zampini } 1262213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 12631e0482f5SStefano Zampini 12641e0482f5SStefano Zampini #if defined(PRINT_GDET) 12651e0482f5SStefano Zampini inc = 0; 12661e0482f5SStefano Zampini lev = pcbddc->current_level; 12671e0482f5SStefano Zampini #endif 1268213b8bfaSStefano Zampini 1269213b8bfaSStefano Zampini /* Insert values in the change of basis matrix */ 1270a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1271a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 12721e0482f5SStefano Zampini IS cornersis = NULL; 12731e0482f5SStefano Zampini PetscScalar cvals[2]; 1274a13144ffSStefano Zampini 12751e0482f5SStefano Zampini if (pcbddc->nedcG) { 12761e0482f5SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,2,corners+2*i,PETSC_USE_POINTER,&cornersis);CHKERRQ(ierr); 12771e0482f5SStefano Zampini } 12781e0482f5SStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],cornersis,&Gins,&GKins,cvals,work,rwork);CHKERRQ(ierr); 1279a13144ffSStefano Zampini if (Gins && GKins) { 1280a13144ffSStefano Zampini PetscScalar *data; 1281a13144ffSStefano Zampini const PetscInt *rows,*cols; 1282a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 1283a13144ffSStefano Zampini 1284a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 1285a13144ffSStefano Zampini /* H1 */ 1286a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 1287a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 1288a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 1289a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 1290a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 1291a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 1292a13144ffSStefano Zampini /* complement */ 1293a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 12941e0482f5SStefano Zampini if (!ncc) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Constant function has not been generated for coarse edge %d",i); 1295213b8bfaSStefano 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); 1296213b8bfaSStefano Zampini if (ncc != 1 && pcbddc->nedcG) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot generate the coarse discrete gradient for coarse edge %d with ncc %d",i,ncc); 1297a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 1298a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 1299a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 13001e0482f5SStefano Zampini 13011e0482f5SStefano Zampini /* coarse discrete gradient */ 13021e0482f5SStefano Zampini if (pcbddc->nedcG) { 13031e0482f5SStefano Zampini PetscInt cols[2]; 13041e0482f5SStefano Zampini 13051e0482f5SStefano Zampini cols[0] = 2*i; 13061e0482f5SStefano Zampini cols[1] = 2*i+1; 13071e0482f5SStefano Zampini ierr = MatSetValuesLocal(pcbddc->nedcG,1,&i,2,cols,cvals,INSERT_VALUES);CHKERRQ(ierr); 13081e0482f5SStefano Zampini } 1309a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 1310a13144ffSStefano Zampini } 1311a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 1312a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 13131e0482f5SStefano Zampini ierr = ISDestroy(&cornersis);CHKERRQ(ierr); 1314a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 1315a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 1316a13144ffSStefano Zampini } 1317213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 1318a13144ffSStefano Zampini 1319a13144ffSStefano Zampini /* Start assembling */ 1320a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13211e0482f5SStefano Zampini if (pcbddc->nedcG) { 13221e0482f5SStefano Zampini ierr = MatAssemblyBegin(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13231e0482f5SStefano Zampini } 1324a13144ffSStefano Zampini 1325a13144ffSStefano Zampini /* Free */ 1326c2151214SStefano Zampini if (fl2g) { 1327c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1328c2151214SStefano Zampini for (i=0;i<nee;i++) { 1329c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1330c2151214SStefano Zampini } 1331c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1332c2151214SStefano Zampini } 1333eee23b56SStefano Zampini 1334eee23b56SStefano Zampini /* hack mat_graph with primal dofs on the coarse edges */ 1335eee23b56SStefano Zampini { 1336eee23b56SStefano Zampini PCBDDCGraph graph = pcbddc->mat_graph; 1337eee23b56SStefano Zampini PetscInt *oqueue = graph->queue; 1338eee23b56SStefano Zampini PetscInt *ocptr = graph->cptr; 1339eee23b56SStefano Zampini PetscInt ncc,*idxs; 1340eee23b56SStefano Zampini 1341eee23b56SStefano Zampini /* find first primal edge */ 1342eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1343eee23b56SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1344eee23b56SStefano Zampini } else { 1345eee23b56SStefano Zampini if (fl2g) { 1346eee23b56SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,nee,cedges,cedges);CHKERRQ(ierr); 1347eee23b56SStefano Zampini } 1348eee23b56SStefano Zampini idxs = cedges; 1349eee23b56SStefano Zampini } 1350eee23b56SStefano Zampini cum = 0; 1351eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1352eee23b56SStefano Zampini 1353eee23b56SStefano Zampini /* adapt connected components */ 1354eee23b56SStefano Zampini ierr = PetscMalloc2(graph->nvtxs+1,&graph->cptr,ocptr[graph->ncc],&graph->queue);CHKERRQ(ierr); 1355eee23b56SStefano Zampini graph->cptr[0] = 0; 1356eee23b56SStefano Zampini for (i=0,ncc=0;i<graph->ncc;i++) { 1357eee23b56SStefano Zampini PetscInt lc = ocptr[i+1]-ocptr[i]; 1358eee23b56SStefano Zampini if (cum != nee && oqueue[ocptr[i+1]-1] == cedges[cum]) { /* this cc has a primal dof */ 1359eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc]+1; 1360eee23b56SStefano Zampini graph->queue[graph->cptr[ncc]] = cedges[cum]; 1361eee23b56SStefano Zampini ncc++; 1362eee23b56SStefano Zampini lc--; 1363eee23b56SStefano Zampini cum++; 1364eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1365eee23b56SStefano Zampini } 1366eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc] + lc; 1367eee23b56SStefano Zampini for (j=0;j<lc;j++) graph->queue[graph->cptr[ncc]+j] = oqueue[ocptr[i]+j]; 1368eee23b56SStefano Zampini ncc++; 1369eee23b56SStefano Zampini } 1370eee23b56SStefano Zampini graph->ncc = ncc; 1371eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1372eee23b56SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1373eee23b56SStefano Zampini } 1374eee23b56SStefano Zampini ierr = PetscFree2(ocptr,oqueue);CHKERRQ(ierr); 1375eee23b56SStefano Zampini } 1376213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 1377c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1378c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1379213b8bfaSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1380eee23b56SStefano Zampini 1381c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1382a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 1383a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 1384b03ebc13SStefano Zampini ierr = PetscFree(corners);CHKERRQ(ierr); 1385b03ebc13SStefano Zampini ierr = PetscFree(cedges);CHKERRQ(ierr); 1386a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 1387a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 1388a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 1389a13144ffSStefano Zampini 1390a13144ffSStefano Zampini /* Complete assembling */ 1391a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13921e0482f5SStefano Zampini if (pcbddc->nedcG) { 13931e0482f5SStefano Zampini ierr = MatAssemblyEnd(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13941e0482f5SStefano Zampini #if 0 13951e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->nedcG,"coarse_G");CHKERRQ(ierr); 13961e0482f5SStefano Zampini ierr = MatView(pcbddc->nedcG,NULL);CHKERRQ(ierr); 13971e0482f5SStefano Zampini #endif 13981e0482f5SStefano Zampini } 1399a13144ffSStefano Zampini 1400a13144ffSStefano Zampini /* set change of basis */ 1401213b8bfaSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,singular);CHKERRQ(ierr); 1402a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1403a13144ffSStefano Zampini 1404a13144ffSStefano Zampini PetscFunctionReturn(0); 1405a13144ffSStefano Zampini } 1406a13144ffSStefano Zampini 1407d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1408d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1409d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1410d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1411d8203eabSStefano Zampini { 1412d8203eabSStefano Zampini PetscErrorCode ierr; 1413d8203eabSStefano Zampini PetscInt i; 1414d8203eabSStefano Zampini 1415d8203eabSStefano Zampini PetscFunctionBegin; 1416d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1417d8203eabSStefano Zampini PetscInt first,last; 1418d8203eabSStefano Zampini 1419d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 142086fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1421d8203eabSStefano Zampini if (i>=first && i < last) { 1422d8203eabSStefano Zampini PetscScalar *data; 1423d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1424d8203eabSStefano Zampini if (!has_const) { 1425d8203eabSStefano Zampini data[i-first] = 1.; 1426d8203eabSStefano Zampini } else { 142786fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 142886fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1429d8203eabSStefano Zampini } 1430d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1431d8203eabSStefano Zampini } 1432d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1433d8203eabSStefano Zampini } 1434d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1435d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1436d8203eabSStefano Zampini PetscInt first,last; 1437ddc40e2cSstefano_zampini ierr = VecLockPop(quad_vecs[i]);CHKERRQ(ierr); 1438d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1439d8203eabSStefano Zampini if (i>=first && i < last) { 1440d8203eabSStefano Zampini PetscScalar *data; 1441d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1442d8203eabSStefano Zampini if (!has_const) { 1443d8203eabSStefano Zampini data[i-first] = 0.; 1444d8203eabSStefano Zampini } else { 144586fa73c5SStefano Zampini data[2*i-first] = 0.; 144686fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1447d8203eabSStefano Zampini } 1448d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1449d8203eabSStefano Zampini } 1450d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1451ddc40e2cSstefano_zampini ierr = VecLockPush(quad_vecs[i]);CHKERRQ(ierr); 1452d8203eabSStefano Zampini } 1453d8203eabSStefano Zampini PetscFunctionReturn(0); 1454d8203eabSStefano Zampini } 1455d8203eabSStefano Zampini 14568ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1457669cc0f4SStefano Zampini { 1458a198735bSStefano Zampini Mat loc_divudotp; 1459fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 14608ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1461669cc0f4SStefano Zampini PetscScalar *vals; 1462669cc0f4SStefano Zampini const PetscScalar *array; 1463a040e873SStefano Zampini PetscInt i,maxneighs,maxsize; 1464a040e873SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 14651ae86dd6SStefano Zampini PetscMPIInt rank; 1466a198735bSStefano Zampini PetscErrorCode ierr; 1467669cc0f4SStefano Zampini 1468669cc0f4SStefano Zampini PetscFunctionBegin; 1469a040e873SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1470a040e873SStefano Zampini ierr = MPIU_Allreduce(&n_neigh,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 14718037d520SStefano Zampini if (!maxneighs) { 14728037d520SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 14738037d520SStefano Zampini *nnsp = NULL; 14748037d520SStefano Zampini PetscFunctionReturn(0); 1475669cc0f4SStefano Zampini } 1476669cc0f4SStefano Zampini maxsize = 0; 1477a040e873SStefano Zampini for (i=0;i<n_neigh;i++) maxsize = PetscMax(n_shared[i],maxsize); 1478669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1479669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1480669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 14818ae0ca82SStefano Zampini if (!transpose) { 14828ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 14838ae0ca82SStefano Zampini } else { 14848ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 14858ae0ca82SStefano Zampini } 1486669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 14871ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1488d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1489669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1490ddc40e2cSstefano_zampini ierr = VecLockPop(quad_vecs[i]);CHKERRQ(ierr); 14918ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 1492669cc0f4SStefano Zampini } 1493d8203eabSStefano Zampini 1494669cc0f4SStefano Zampini /* compute local quad vec */ 1495a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 14968ae0ca82SStefano Zampini if (!transpose) { 1497a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 14988ae0ca82SStefano Zampini } else { 14998ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 15008ae0ca82SStefano Zampini } 1501669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 15028ae0ca82SStefano Zampini if (!transpose) { 1503a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 15048ae0ca82SStefano Zampini } else { 15058ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 15068ae0ca82SStefano Zampini } 1507fa23a32eSStefano Zampini if (vl2l) { 1508187c917aSStefano Zampini Mat lA; 1509187c917aSStefano Zampini VecScatter sc; 1510187c917aSStefano Zampini 1511187c917aSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1512187c917aSStefano Zampini ierr = MatCreateVecs(lA,&vins,NULL);CHKERRQ(ierr); 1513187c917aSStefano Zampini ierr = VecScatterCreate(v,vl2l,vins,NULL,&sc);CHKERRQ(ierr); 1514187c917aSStefano Zampini ierr = VecScatterBegin(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1515187c917aSStefano Zampini ierr = VecScatterEnd(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1516187c917aSStefano Zampini ierr = VecScatterDestroy(&sc);CHKERRQ(ierr); 1517fa23a32eSStefano Zampini } else { 1518fa23a32eSStefano Zampini vins = v; 1519fa23a32eSStefano Zampini } 1520fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1521669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 15229a962809SStefano Zampini 15231ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 15241ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1525a040e873SStefano Zampini for (i=0;i<n_neigh;i++) { 1526669cc0f4SStefano Zampini const PetscInt *idxs; 1527669cc0f4SStefano Zampini PetscInt idx,nn,j; 1528669cc0f4SStefano Zampini 1529a040e873SStefano Zampini idxs = shared[i]; 1530a040e873SStefano Zampini nn = n_shared[i]; 1531669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 15321ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1533669cc0f4SStefano Zampini idx = -(idx+1); 1534669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1535669cc0f4SStefano Zampini } 1536a040e873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1537fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1538fa23a32eSStefano Zampini if (vl2l) { 1539187c917aSStefano Zampini ierr = VecDestroy(&vins);CHKERRQ(ierr); 1540fa23a32eSStefano Zampini } 1541669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1542669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1543669cc0f4SStefano Zampini 1544669cc0f4SStefano Zampini /* assemble near null space */ 1545669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1546669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1547669cc0f4SStefano Zampini } 1548669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1549669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 15503272d46bSStefano Zampini ierr = VecViewFromOptions(quad_vecs[i],NULL,"-pc_bddc_quad_vecs_view");CHKERRQ(ierr); 1551ddc40e2cSstefano_zampini ierr = VecLockPush(quad_vecs[i]);CHKERRQ(ierr); 1552669cc0f4SStefano Zampini } 1553669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1554669cc0f4SStefano Zampini PetscFunctionReturn(0); 1555669cc0f4SStefano Zampini } 1556669cc0f4SStefano Zampini 15577620a527SStefano Zampini PetscErrorCode PCBDDCAddPrimalVerticesLocalIS(PC pc, IS primalv) 15587620a527SStefano Zampini { 15597620a527SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15607620a527SStefano Zampini PetscErrorCode ierr; 15617620a527SStefano Zampini 15627620a527SStefano Zampini PetscFunctionBegin; 15637620a527SStefano Zampini if (primalv) { 15647620a527SStefano Zampini if (pcbddc->user_primal_vertices_local) { 15657620a527SStefano Zampini IS list[2], newp; 15667620a527SStefano Zampini 15677620a527SStefano Zampini list[0] = primalv; 15687620a527SStefano Zampini list[1] = pcbddc->user_primal_vertices_local; 15697620a527SStefano Zampini ierr = ISConcatenate(PetscObjectComm((PetscObject)pc),2,list,&newp);CHKERRQ(ierr); 15707620a527SStefano Zampini ierr = ISSortRemoveDups(newp);CHKERRQ(ierr); 15717620a527SStefano Zampini ierr = ISDestroy(&list[1]);CHKERRQ(ierr); 15727620a527SStefano Zampini pcbddc->user_primal_vertices_local = newp; 15737620a527SStefano Zampini } else { 15747620a527SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 15757620a527SStefano Zampini } 15767620a527SStefano Zampini } 15777620a527SStefano Zampini PetscFunctionReturn(0); 15787620a527SStefano Zampini } 1579669cc0f4SStefano Zampini 15801c7a958bSStefano Zampini static PetscErrorCode func_coords_private(PetscInt dim, PetscReal t, const PetscReal X[], PetscInt Nf, PetscScalar *out, void *ctx) 15811c7a958bSStefano Zampini { 15821c7a958bSStefano Zampini PetscInt f, *comp = (PetscInt *)ctx; 15831c7a958bSStefano Zampini 15841c7a958bSStefano Zampini PetscFunctionBegin; 15851c7a958bSStefano Zampini for (f=0;f<Nf;f++) out[f] = X[*comp]; 15861c7a958bSStefano Zampini PetscFunctionReturn(0); 15871c7a958bSStefano Zampini } 1588674ae819SStefano Zampini 15891f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 15901f4df5f7SStefano Zampini { 15911f4df5f7SStefano Zampini PetscErrorCode ierr; 15921f4df5f7SStefano Zampini Vec local,global; 15931f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 15941f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 15955c5e10d6SStefano Zampini PetscBool monolithic = PETSC_FALSE; 15961f4df5f7SStefano Zampini 15971f4df5f7SStefano Zampini PetscFunctionBegin; 15985c5e10d6SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC topology options","PC");CHKERRQ(ierr); 15995c5e10d6SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_monolithic","Discard any information on dofs splitting",NULL,monolithic,&monolithic,NULL);CHKERRQ(ierr); 16005c5e10d6SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 16011f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 160221ef3d20SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 16031f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 16046a8fc67bSStefano Zampini if (monolithic) { /* just get block size to properly compute vertices */ 16056a8fc67bSStefano Zampini if (pcbddc->vertex_size == 1) { 16066a8fc67bSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->vertex_size);CHKERRQ(ierr); 16076a8fc67bSStefano Zampini } 16086a8fc67bSStefano Zampini goto boundary; 16096a8fc67bSStefano Zampini } 16105c5e10d6SStefano Zampini 16111f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 16121f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 16131f4df5f7SStefano Zampini PetscInt i; 16141f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16151f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 16161f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16171f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 16181f4df5f7SStefano Zampini } 16191f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 16201f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 16211f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 16221f4df5f7SStefano Zampini } 16231f4df5f7SStefano Zampini } else { 162421ef3d20SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present */ 162521ef3d20SStefano Zampini DM dm; 162621ef3d20SStefano Zampini 162721ef3d20SStefano Zampini ierr = PCGetDM(pc, &dm);CHKERRQ(ierr); 162821ef3d20SStefano Zampini if (!dm) { 162921ef3d20SStefano Zampini ierr = MatGetDM(pc->pmat, &dm);CHKERRQ(ierr); 163021ef3d20SStefano Zampini } 163121ef3d20SStefano Zampini if (dm) { 163221ef3d20SStefano Zampini IS *fields; 163321ef3d20SStefano Zampini PetscInt nf,i; 163421ef3d20SStefano Zampini ierr = DMCreateFieldDecomposition(dm,&nf,NULL,&fields,NULL);CHKERRQ(ierr); 163521ef3d20SStefano Zampini ierr = PetscMalloc1(nf,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 163621ef3d20SStefano Zampini for (i=0;i<nf;i++) { 163721ef3d20SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,fields[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 163821ef3d20SStefano Zampini ierr = ISDestroy(&fields[i]);CHKERRQ(ierr); 163921ef3d20SStefano Zampini } 164021ef3d20SStefano Zampini ierr = PetscFree(fields);CHKERRQ(ierr); 164121ef3d20SStefano Zampini pcbddc->n_ISForDofsLocal = nf; 164221ef3d20SStefano Zampini } else { /* See if MATIS has fields attached by the conversion from MatNest */ 164321ef3d20SStefano Zampini PetscContainer c; 164421ef3d20SStefano Zampini 164521ef3d20SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc->pmat,"_convert_nest_lfields",(PetscObject*)&c);CHKERRQ(ierr); 164621ef3d20SStefano Zampini if (c) { 164721ef3d20SStefano Zampini MatISLocalFields lf; 164821ef3d20SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&lf);CHKERRQ(ierr); 164921ef3d20SStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,lf->nr,lf->rf);CHKERRQ(ierr); 165021ef3d20SStefano Zampini } else { /* fallback, create the default fields if bs > 1 */ 16511f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1652986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 165321ef3d20SStefano Zampini if (i > 1) { 1654986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 16551f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16561f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16571f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16581f4df5f7SStefano Zampini } 16591f4df5f7SStefano Zampini } 166021ef3d20SStefano Zampini } 166121ef3d20SStefano Zampini } 16627a0e7b2cSstefano_zampini } else { 16637a0e7b2cSstefano_zampini PetscInt i; 16647a0e7b2cSstefano_zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16657a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16667a0e7b2cSstefano_zampini } 16671f4df5f7SStefano Zampini } 1668986cdee1SStefano Zampini } 16691f4df5f7SStefano Zampini 16705c5e10d6SStefano Zampini boundary: 16711f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 16721f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16737a0e7b2cSstefano_zampini } else if (pcbddc->DirichletBoundariesLocal) { 16747a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 16751f4df5f7SStefano Zampini } 16761f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 16771f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16787a0e7b2cSstefano_zampini } else if (pcbddc->NeumannBoundariesLocal) { 16797a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 16801f4df5f7SStefano Zampini } 16811f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 16821f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 16831f4df5f7SStefano Zampini } 16841f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 16851f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 16867620a527SStefano Zampini /* detect local disconnected subdomains if requested (use matis->A) */ 16877620a527SStefano Zampini if (pcbddc->detect_disconnected) { 16887620a527SStefano Zampini IS primalv = NULL; 16897620a527SStefano Zampini PetscInt i; 16907a0e7b2cSstefano_zampini 16917620a527SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 16927620a527SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 16937620a527SStefano Zampini } 16947620a527SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 16957620a527SStefano Zampini ierr = PCBDDCDetectDisconnectedComponents(pc,&pcbddc->n_local_subs,&pcbddc->local_subs,&primalv);CHKERRQ(ierr); 16967620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 16977620a527SStefano Zampini ierr = ISDestroy(&primalv);CHKERRQ(ierr); 16987620a527SStefano Zampini } 16997620a527SStefano Zampini /* early stage corner detection */ 17007620a527SStefano Zampini { 17017620a527SStefano Zampini DM dm; 17027620a527SStefano Zampini 17037620a527SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 17047620a527SStefano Zampini if (dm) { 17057620a527SStefano Zampini PetscBool isda; 17067620a527SStefano Zampini 17077620a527SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&isda);CHKERRQ(ierr); 17087620a527SStefano Zampini if (isda) { 17097620a527SStefano Zampini ISLocalToGlobalMapping l2l; 17107620a527SStefano Zampini IS corners; 17117620a527SStefano Zampini Mat lA; 17127620a527SStefano Zampini 1713d4a6ed37SStefano Zampini ierr = DMDAGetSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17147620a527SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17157620a527SStefano Zampini ierr = MatGetLocalToGlobalMapping(lA,&l2l,NULL);CHKERRQ(ierr); 17167620a527SStefano Zampini ierr = MatISRestoreLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17177620a527SStefano Zampini if (l2l) { 17187620a527SStefano Zampini const PetscInt *idx; 17197620a527SStefano Zampini PetscInt bs,*idxout,n; 17207620a527SStefano Zampini 17217620a527SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(l2l,&bs);CHKERRQ(ierr); 17227620a527SStefano Zampini ierr = ISGetLocalSize(corners,&n);CHKERRQ(ierr); 17237620a527SStefano Zampini ierr = ISGetIndices(corners,&idx);CHKERRQ(ierr); 17247620a527SStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 17257620a527SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(l2l,n,idx,idxout);CHKERRQ(ierr); 17267620a527SStefano Zampini ierr = ISRestoreIndices(corners,&idx);CHKERRQ(ierr); 1727d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17287620a527SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)pc),bs,n,idxout,PETSC_OWN_POINTER,&corners);CHKERRQ(ierr); 17297620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,corners);CHKERRQ(ierr); 17307620a527SStefano Zampini ierr = ISDestroy(&corners);CHKERRQ(ierr); 17311c7a958bSStefano Zampini pcbddc->corner_selected = PETSC_TRUE; 17327620a527SStefano Zampini } else { /* not from DMDA */ 1733d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17347620a527SStefano Zampini } 17357620a527SStefano Zampini } 17367620a527SStefano Zampini } 17377620a527SStefano Zampini } 17381c7a958bSStefano Zampini if (pcbddc->corner_selection && !pcbddc->mat_graph->cdim) { 17391c7a958bSStefano Zampini DM dm; 17401c7a958bSStefano Zampini 17411c7a958bSStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 17421c7a958bSStefano Zampini if (!dm) { 17431c7a958bSStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 17441c7a958bSStefano Zampini } 17451c7a958bSStefano Zampini if (dm) { 17461c7a958bSStefano Zampini Vec vcoords; 17471c7a958bSStefano Zampini PetscSection section; 17481c7a958bSStefano Zampini PetscReal *coords; 17491c7a958bSStefano Zampini PetscInt d,cdim,nl,nf,**ctxs; 17501c7a958bSStefano Zampini PetscErrorCode (**funcs)(PetscInt, PetscReal, const PetscReal *, PetscInt, PetscScalar *, void *); 17511c7a958bSStefano Zampini 17521c7a958bSStefano Zampini ierr = DMGetCoordinateDim(dm,&cdim);CHKERRQ(ierr); 17531c7a958bSStefano Zampini ierr = DMGetDefaultSection(dm,§ion);CHKERRQ(ierr); 17541c7a958bSStefano Zampini ierr = PetscSectionGetNumFields(section,&nf);CHKERRQ(ierr); 17551c7a958bSStefano Zampini ierr = DMCreateGlobalVector(dm,&vcoords);CHKERRQ(ierr); 17561c7a958bSStefano Zampini ierr = VecGetLocalSize(vcoords,&nl);CHKERRQ(ierr); 17571c7a958bSStefano Zampini ierr = PetscMalloc1(nl*cdim,&coords);CHKERRQ(ierr); 17581c7a958bSStefano Zampini ierr = PetscMalloc2(nf,&funcs,nf,&ctxs);CHKERRQ(ierr); 17591c7a958bSStefano Zampini ierr = PetscMalloc1(nf,&ctxs[0]);CHKERRQ(ierr); 17601c7a958bSStefano Zampini for (d=0;d<nf;d++) funcs[d] = func_coords_private; 17611c7a958bSStefano Zampini for (d=1;d<nf;d++) ctxs[d] = ctxs[d-1] + 1; 17621c7a958bSStefano Zampini for (d=0;d<cdim;d++) { 17631c7a958bSStefano Zampini PetscInt i; 17641c7a958bSStefano Zampini const PetscScalar *v; 17651c7a958bSStefano Zampini 17661c7a958bSStefano Zampini for (i=0;i<nf;i++) ctxs[i][0] = d; 17671c7a958bSStefano Zampini ierr = DMProjectFunction(dm,0.0,funcs,(void**)ctxs,INSERT_VALUES,vcoords);CHKERRQ(ierr); 17681c7a958bSStefano Zampini ierr = VecGetArrayRead(vcoords,&v);CHKERRQ(ierr); 17691c7a958bSStefano Zampini for (i=0;i<nl;i++) coords[i*cdim+d] = PetscRealPart(v[i]); 17701c7a958bSStefano Zampini ierr = VecRestoreArrayRead(vcoords,&v);CHKERRQ(ierr); 17711c7a958bSStefano Zampini } 17721c7a958bSStefano Zampini ierr = VecDestroy(&vcoords);CHKERRQ(ierr); 17731c7a958bSStefano Zampini ierr = PCSetCoordinates(pc,cdim,nl,coords);CHKERRQ(ierr); 17741c7a958bSStefano Zampini ierr = PetscFree(coords);CHKERRQ(ierr); 17751c7a958bSStefano Zampini ierr = PetscFree(ctxs[0]);CHKERRQ(ierr); 17761c7a958bSStefano Zampini ierr = PetscFree2(funcs,ctxs);CHKERRQ(ierr); 17771c7a958bSStefano Zampini } 17781c7a958bSStefano Zampini } 17797a0e7b2cSstefano_zampini PetscFunctionReturn(0); 17807a0e7b2cSstefano_zampini } 17817a0e7b2cSstefano_zampini 17827a0e7b2cSstefano_zampini PetscErrorCode PCBDDCConsistencyCheckIS(PC pc, MPI_Op mop, IS *is) 17837a0e7b2cSstefano_zampini { 17847a0e7b2cSstefano_zampini Mat_IS *matis = (Mat_IS*)(pc->pmat->data); 17857a0e7b2cSstefano_zampini PetscErrorCode ierr; 17867a0e7b2cSstefano_zampini IS nis; 17877a0e7b2cSstefano_zampini const PetscInt *idxs; 17887a0e7b2cSstefano_zampini PetscInt i,nd,n = matis->A->rmap->n,*nidxs,nnd; 17897a0e7b2cSstefano_zampini PetscBool *ld; 17907a0e7b2cSstefano_zampini 17917a0e7b2cSstefano_zampini PetscFunctionBegin; 17927a0e7b2cSstefano_zampini if (mop != MPI_LAND && mop != MPI_LOR) SETERRQ(PetscObjectComm((PetscObject)(pc)),PETSC_ERR_SUP,"Supported are MPI_LAND and MPI_LOR"); 17937a0e7b2cSstefano_zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 17947a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 17957a0e7b2cSstefano_zampini /* init rootdata with true */ 17967a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_rootdata; 17977a0e7b2cSstefano_zampini for (i=0;i<pc->pmat->rmap->n;i++) ld[i] = PETSC_TRUE; 17987a0e7b2cSstefano_zampini } else { 17997a0e7b2cSstefano_zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscBool));CHKERRQ(ierr); 18007a0e7b2cSstefano_zampini } 18017a0e7b2cSstefano_zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscBool));CHKERRQ(ierr); 18027a0e7b2cSstefano_zampini ierr = ISGetLocalSize(*is,&nd);CHKERRQ(ierr); 18037a0e7b2cSstefano_zampini ierr = ISGetIndices(*is,&idxs);CHKERRQ(ierr); 18047a0e7b2cSstefano_zampini ld = (PetscBool*) matis->sf_leafdata; 18057a0e7b2cSstefano_zampini for (i=0;i<nd;i++) 18067a0e7b2cSstefano_zampini if (-1 < idxs[i] && idxs[i] < n) 18077a0e7b2cSstefano_zampini ld[idxs[i]] = PETSC_TRUE; 18087a0e7b2cSstefano_zampini ierr = ISRestoreIndices(*is,&idxs);CHKERRQ(ierr); 18097a0e7b2cSstefano_zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18107a0e7b2cSstefano_zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_BOOL,matis->sf_leafdata,matis->sf_rootdata,mop);CHKERRQ(ierr); 18117a0e7b2cSstefano_zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18127a0e7b2cSstefano_zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_BOOL,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 18137a0e7b2cSstefano_zampini if (mop == MPI_LAND) { 18147a0e7b2cSstefano_zampini ierr = PetscMalloc1(nd,&nidxs);CHKERRQ(ierr); 18157a0e7b2cSstefano_zampini } else { 18167a0e7b2cSstefano_zampini ierr = PetscMalloc1(n,&nidxs);CHKERRQ(ierr); 18177a0e7b2cSstefano_zampini } 18187a0e7b2cSstefano_zampini for (i=0,nnd=0;i<n;i++) 18197a0e7b2cSstefano_zampini if (ld[i]) 18207a0e7b2cSstefano_zampini nidxs[nnd++] = i; 18217a0e7b2cSstefano_zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(*is)),nnd,nidxs,PETSC_OWN_POINTER,&nis);CHKERRQ(ierr); 18227a0e7b2cSstefano_zampini ierr = ISDestroy(is);CHKERRQ(ierr); 18237a0e7b2cSstefano_zampini *is = nis; 18241f4df5f7SStefano Zampini PetscFunctionReturn(0); 18251f4df5f7SStefano Zampini } 18261f4df5f7SStefano Zampini 18273e589ea0SStefano Zampini PetscErrorCode PCBDDCBenignRemoveInterior(PC pc,Vec r,Vec z) 18283e589ea0SStefano Zampini { 18293e589ea0SStefano Zampini PC_IS *pcis = (PC_IS*)(pc->data); 18303e589ea0SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)(pc->data); 18313e589ea0SStefano Zampini PetscErrorCode ierr; 18323e589ea0SStefano Zampini 18333e589ea0SStefano Zampini PetscFunctionBegin; 18343e589ea0SStefano Zampini if (!pcbddc->benign_have_null) { 18353e589ea0SStefano Zampini PetscFunctionReturn(0); 18363e589ea0SStefano Zampini } 18373e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 18383e589ea0SStefano Zampini Vec swap; 18393e589ea0SStefano Zampini 18403e589ea0SStefano Zampini ierr = MatMultTranspose(pcbddc->ChangeOfBasisMatrix,r,pcbddc->work_change);CHKERRQ(ierr); 18413e589ea0SStefano Zampini swap = pcbddc->work_change; 18423e589ea0SStefano Zampini pcbddc->work_change = r; 18433e589ea0SStefano Zampini r = swap; 18443e589ea0SStefano Zampini } 18453e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18463e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,r,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 18473e589ea0SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 18483e589ea0SStefano Zampini ierr = VecSet(z,0.);CHKERRQ(ierr); 18493e589ea0SStefano Zampini ierr = VecScatterBegin(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18503e589ea0SStefano Zampini ierr = VecScatterEnd(pcis->global_to_D,pcis->vec2_D,z,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 18513e589ea0SStefano Zampini if (pcbddc->ChangeOfBasisMatrix) { 1852f913dca9SStefano Zampini pcbddc->work_change = r; 18533e589ea0SStefano Zampini ierr = VecCopy(z,pcbddc->work_change);CHKERRQ(ierr); 18543e589ea0SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcbddc->work_change,z);CHKERRQ(ierr); 18553e589ea0SStefano Zampini } 18563e589ea0SStefano Zampini PetscFunctionReturn(0); 18573e589ea0SStefano Zampini } 18583e589ea0SStefano Zampini 1859a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private_Private(Mat A, Vec x, Vec y, PetscBool transpose) 1860a3df083aSStefano Zampini { 1861a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1862a3df083aSStefano Zampini PetscErrorCode ierr; 1863a3df083aSStefano Zampini PetscBool apply_right,apply_left,reset_x; 1864a3df083aSStefano Zampini 1865a3df083aSStefano Zampini PetscFunctionBegin; 1866a3df083aSStefano Zampini ierr = MatShellGetContext(A,&ctx);CHKERRQ(ierr); 1867a3df083aSStefano Zampini if (transpose) { 1868a3df083aSStefano Zampini apply_right = ctx->apply_left; 1869a3df083aSStefano Zampini apply_left = ctx->apply_right; 1870a3df083aSStefano Zampini } else { 1871a3df083aSStefano Zampini apply_right = ctx->apply_right; 1872a3df083aSStefano Zampini apply_left = ctx->apply_left; 1873a3df083aSStefano Zampini } 1874a3df083aSStefano Zampini reset_x = PETSC_FALSE; 1875a3df083aSStefano Zampini if (apply_right) { 1876a3df083aSStefano Zampini const PetscScalar *ax; 1877a3df083aSStefano Zampini PetscInt nl,i; 1878a3df083aSStefano Zampini 1879a3df083aSStefano Zampini ierr = VecGetLocalSize(x,&nl);CHKERRQ(ierr); 1880a3df083aSStefano Zampini ierr = VecGetArrayRead(x,&ax);CHKERRQ(ierr); 1881a3df083aSStefano Zampini ierr = PetscMemcpy(ctx->work,ax,nl*sizeof(PetscScalar));CHKERRQ(ierr); 1882a3df083aSStefano Zampini ierr = VecRestoreArrayRead(x,&ax);CHKERRQ(ierr); 1883a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1884a3df083aSStefano Zampini PetscScalar sum,val; 1885a3df083aSStefano Zampini const PetscInt *idxs; 1886a3df083aSStefano Zampini PetscInt nz,j; 1887a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1888a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1889a3df083aSStefano Zampini sum = 0.; 1890a3df083aSStefano Zampini if (ctx->apply_p0) { 1891a3df083aSStefano Zampini val = ctx->work[idxs[nz-1]]; 1892a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1893a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1894a3df083aSStefano Zampini ctx->work[idxs[j]] += val; 1895a3df083aSStefano Zampini } 1896a3df083aSStefano Zampini } else { 1897a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1898a3df083aSStefano Zampini sum += ctx->work[idxs[j]]; 1899a3df083aSStefano Zampini } 1900a3df083aSStefano Zampini } 1901a3df083aSStefano Zampini ctx->work[idxs[nz-1]] -= sum; 1902a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1903a3df083aSStefano Zampini } 1904a3df083aSStefano Zampini ierr = VecPlaceArray(x,ctx->work);CHKERRQ(ierr); 1905a3df083aSStefano Zampini reset_x = PETSC_TRUE; 1906a3df083aSStefano Zampini } 1907a3df083aSStefano Zampini if (transpose) { 1908a3df083aSStefano Zampini ierr = MatMultTranspose(ctx->A,x,y);CHKERRQ(ierr); 1909a3df083aSStefano Zampini } else { 1910a3df083aSStefano Zampini ierr = MatMult(ctx->A,x,y);CHKERRQ(ierr); 1911a3df083aSStefano Zampini } 1912a3df083aSStefano Zampini if (reset_x) { 1913a3df083aSStefano Zampini ierr = VecResetArray(x);CHKERRQ(ierr); 1914a3df083aSStefano Zampini } 1915a3df083aSStefano Zampini if (apply_left) { 1916a3df083aSStefano Zampini PetscScalar *ay; 1917a3df083aSStefano Zampini PetscInt i; 1918a3df083aSStefano Zampini 1919a3df083aSStefano Zampini ierr = VecGetArray(y,&ay);CHKERRQ(ierr); 1920a3df083aSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 1921a3df083aSStefano Zampini PetscScalar sum,val; 1922a3df083aSStefano Zampini const PetscInt *idxs; 1923a3df083aSStefano Zampini PetscInt nz,j; 1924a3df083aSStefano Zampini ierr = ISGetLocalSize(ctx->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 1925a3df083aSStefano Zampini ierr = ISGetIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1926a3df083aSStefano Zampini val = -ay[idxs[nz-1]]; 1927a3df083aSStefano Zampini if (ctx->apply_p0) { 1928a3df083aSStefano Zampini sum = 0.; 1929a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1930a3df083aSStefano Zampini sum += ay[idxs[j]]; 1931a3df083aSStefano Zampini ay[idxs[j]] += val; 1932a3df083aSStefano Zampini } 1933a3df083aSStefano Zampini ay[idxs[nz-1]] += sum; 1934a3df083aSStefano Zampini } else { 1935a3df083aSStefano Zampini for (j=0;j<nz-1;j++) { 1936a3df083aSStefano Zampini ay[idxs[j]] += val; 1937a3df083aSStefano Zampini } 1938a3df083aSStefano Zampini ay[idxs[nz-1]] = 0.; 1939a3df083aSStefano Zampini } 1940a3df083aSStefano Zampini ierr = ISRestoreIndices(ctx->benign_zerodiag_subs[i],&idxs);CHKERRQ(ierr); 1941a3df083aSStefano Zampini } 1942a3df083aSStefano Zampini ierr = VecRestoreArray(y,&ay);CHKERRQ(ierr); 1943a3df083aSStefano Zampini } 1944a3df083aSStefano Zampini PetscFunctionReturn(0); 1945a3df083aSStefano Zampini } 1946a3df083aSStefano Zampini 1947a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMultTranspose_Private(Mat A, Vec x, Vec y) 1948a3df083aSStefano Zampini { 1949a3df083aSStefano Zampini PetscErrorCode ierr; 1950a3df083aSStefano Zampini 1951a3df083aSStefano Zampini PetscFunctionBegin; 1952a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_TRUE);CHKERRQ(ierr); 1953a3df083aSStefano Zampini PetscFunctionReturn(0); 1954a3df083aSStefano Zampini } 1955a3df083aSStefano Zampini 1956a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignMatMult_Private(Mat A, Vec x, Vec y) 1957a3df083aSStefano Zampini { 1958a3df083aSStefano Zampini PetscErrorCode ierr; 1959a3df083aSStefano Zampini 1960a3df083aSStefano Zampini PetscFunctionBegin; 1961a3df083aSStefano Zampini ierr = PCBDDCBenignMatMult_Private_Private(A,x,y,PETSC_FALSE);CHKERRQ(ierr); 1962a3df083aSStefano Zampini PetscFunctionReturn(0); 1963a3df083aSStefano Zampini } 1964a3df083aSStefano Zampini 1965a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignShellMat(PC pc, PetscBool restore) 1966a3df083aSStefano Zampini { 1967a3df083aSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 1968a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 1969a3df083aSStefano Zampini PCBDDCBenignMatMult_ctx ctx; 1970a3df083aSStefano Zampini PetscErrorCode ierr; 1971a3df083aSStefano Zampini 1972a3df083aSStefano Zampini PetscFunctionBegin; 1973a3df083aSStefano Zampini if (!restore) { 19741dd7afcfSStefano Zampini Mat A_IB,A_BI; 1975a3df083aSStefano Zampini PetscScalar *work; 1976b334f244SStefano Zampini PCBDDCReuseSolvers reuse = pcbddc->sub_schurs ? pcbddc->sub_schurs->reuse_solver : NULL; 1977a3df083aSStefano Zampini 19789a962809SStefano Zampini if (pcbddc->benign_original_mat) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Benign original mat has not been restored"); 19799a962809SStefano Zampini if (!pcbddc->benign_change || !pcbddc->benign_n || pcbddc->benign_change_explicit) PetscFunctionReturn(0); 1980a3df083aSStefano Zampini ierr = PetscMalloc1(pcis->n,&work);CHKERRQ(ierr); 1981a3df083aSStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&A_IB);CHKERRQ(ierr); 1982a3df083aSStefano Zampini ierr = MatSetSizes(A_IB,pcis->n-pcis->n_B,pcis->n_B,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 1983a3df083aSStefano Zampini ierr = MatSetType(A_IB,MATSHELL);CHKERRQ(ierr); 1984a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT,(void (*)(void))PCBDDCBenignMatMult_Private);CHKERRQ(ierr); 1985a3df083aSStefano Zampini ierr = MatShellSetOperation(A_IB,MATOP_MULT_TRANSPOSE,(void (*)(void))PCBDDCBenignMatMultTranspose_Private);CHKERRQ(ierr); 1986a3df083aSStefano Zampini ierr = PetscNew(&ctx);CHKERRQ(ierr); 1987a3df083aSStefano Zampini ierr = MatShellSetContext(A_IB,ctx);CHKERRQ(ierr); 1988a3df083aSStefano Zampini ctx->apply_left = PETSC_TRUE; 1989a3df083aSStefano Zampini ctx->apply_right = PETSC_FALSE; 1990a3df083aSStefano Zampini ctx->apply_p0 = PETSC_FALSE; 1991a3df083aSStefano Zampini ctx->benign_n = pcbddc->benign_n; 1992059032f7SStefano Zampini if (reuse) { 1993a3df083aSStefano Zampini ctx->benign_zerodiag_subs = reuse->benign_zerodiag_subs; 19941dd7afcfSStefano Zampini ctx->free = PETSC_FALSE; 1995059032f7SStefano Zampini } else { /* TODO: could be optimized for successive solves */ 1996059032f7SStefano Zampini ISLocalToGlobalMapping N_to_D; 1997059032f7SStefano Zampini PetscInt i; 1998059032f7SStefano Zampini 1999059032f7SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcis->is_I_local,&N_to_D);CHKERRQ(ierr); 2000059032f7SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2001059032f7SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2002059032f7SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(N_to_D,IS_GTOLM_DROP,pcbddc->benign_zerodiag_subs[i],&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2003059032f7SStefano Zampini } 2004059032f7SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&N_to_D);CHKERRQ(ierr); 20051dd7afcfSStefano Zampini ctx->free = PETSC_TRUE; 2006059032f7SStefano Zampini } 2007a3df083aSStefano Zampini ctx->A = pcis->A_IB; 2008a3df083aSStefano Zampini ctx->work = work; 2009a3df083aSStefano Zampini ierr = MatSetUp(A_IB);CHKERRQ(ierr); 2010a3df083aSStefano Zampini ierr = MatAssemblyBegin(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2011a3df083aSStefano Zampini ierr = MatAssemblyEnd(A_IB,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2012a3df083aSStefano Zampini pcis->A_IB = A_IB; 2013a3df083aSStefano Zampini 2014a3df083aSStefano Zampini /* A_BI as A_IB^T */ 2015a3df083aSStefano Zampini ierr = MatCreateTranspose(A_IB,&A_BI);CHKERRQ(ierr); 2016a3df083aSStefano Zampini pcbddc->benign_original_mat = pcis->A_BI; 2017a3df083aSStefano Zampini pcis->A_BI = A_BI; 2018a3df083aSStefano Zampini } else { 20191dd7afcfSStefano Zampini if (!pcbddc->benign_original_mat) { 20201dd7afcfSStefano Zampini PetscFunctionReturn(0); 20211dd7afcfSStefano Zampini } 2022a3df083aSStefano Zampini ierr = MatShellGetContext(pcis->A_IB,&ctx);CHKERRQ(ierr); 2023a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_IB);CHKERRQ(ierr); 2024a3df083aSStefano Zampini pcis->A_IB = ctx->A; 20251dd7afcfSStefano Zampini ctx->A = NULL; 20261dd7afcfSStefano Zampini ierr = MatDestroy(&pcis->A_BI);CHKERRQ(ierr); 20271dd7afcfSStefano Zampini pcis->A_BI = pcbddc->benign_original_mat; 20281dd7afcfSStefano Zampini pcbddc->benign_original_mat = NULL; 20291dd7afcfSStefano Zampini if (ctx->free) { 2030059032f7SStefano Zampini PetscInt i; 20311dd7afcfSStefano Zampini for (i=0;i<ctx->benign_n;i++) { 2032059032f7SStefano Zampini ierr = ISDestroy(&ctx->benign_zerodiag_subs[i]);CHKERRQ(ierr); 2033059032f7SStefano Zampini } 2034059032f7SStefano Zampini ierr = PetscFree(ctx->benign_zerodiag_subs);CHKERRQ(ierr); 2035059032f7SStefano Zampini } 2036a3df083aSStefano Zampini ierr = PetscFree(ctx->work);CHKERRQ(ierr); 2037a3df083aSStefano Zampini ierr = PetscFree(ctx);CHKERRQ(ierr); 2038a3df083aSStefano Zampini } 2039a3df083aSStefano Zampini PetscFunctionReturn(0); 2040a3df083aSStefano Zampini } 2041a3df083aSStefano Zampini 2042a3df083aSStefano Zampini /* used just in bddc debug mode */ 2043a3df083aSStefano Zampini PetscErrorCode PCBDDCBenignProject(PC pc, IS is1, IS is2, Mat *B) 2044a3df083aSStefano Zampini { 2045a3df083aSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 2046a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2047a3df083aSStefano Zampini Mat An; 2048a3df083aSStefano Zampini PetscErrorCode ierr; 2049a3df083aSStefano Zampini 2050a3df083aSStefano Zampini PetscFunctionBegin; 2051a3df083aSStefano Zampini ierr = MatPtAP(matis->A,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&An);CHKERRQ(ierr); 2052a3df083aSStefano Zampini ierr = MatZeroRowsColumns(An,pcbddc->benign_n,pcbddc->benign_p0_lidx,1.0,NULL,NULL);CHKERRQ(ierr); 2053a3df083aSStefano Zampini if (is1) { 20547dae84e0SHong Zhang ierr = MatCreateSubMatrix(An,is1,is2,MAT_INITIAL_MATRIX,B);CHKERRQ(ierr); 2055a3df083aSStefano Zampini ierr = MatDestroy(&An);CHKERRQ(ierr); 2056a3df083aSStefano Zampini } else { 2057a3df083aSStefano Zampini *B = An; 2058a3df083aSStefano Zampini } 2059a3df083aSStefano Zampini PetscFunctionReturn(0); 2060a3df083aSStefano Zampini } 2061a3df083aSStefano Zampini 20621cf9b237SStefano Zampini /* TODO: add reuse flag */ 20631cf9b237SStefano Zampini PetscErrorCode MatSeqAIJCompress(Mat A, Mat *B) 20641cf9b237SStefano Zampini { 20651cf9b237SStefano Zampini Mat Bt; 20661cf9b237SStefano Zampini PetscScalar *a,*bdata; 20671cf9b237SStefano Zampini const PetscInt *ii,*ij; 20681cf9b237SStefano Zampini PetscInt m,n,i,nnz,*bii,*bij; 20691cf9b237SStefano Zampini PetscBool flg_row; 20701cf9b237SStefano Zampini PetscErrorCode ierr; 20711cf9b237SStefano Zampini 20721cf9b237SStefano Zampini PetscFunctionBegin; 20731cf9b237SStefano Zampini ierr = MatGetSize(A,&n,&m);CHKERRQ(ierr); 20741cf9b237SStefano Zampini ierr = MatGetRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 20751cf9b237SStefano Zampini ierr = MatSeqAIJGetArray(A,&a);CHKERRQ(ierr); 20761cf9b237SStefano Zampini nnz = n; 20771cf9b237SStefano Zampini for (i=0;i<ii[n];i++) { 20781cf9b237SStefano Zampini if (PetscLikely(PetscAbsScalar(a[i]) > PETSC_SMALL)) nnz++; 20791cf9b237SStefano Zampini } 20801cf9b237SStefano Zampini ierr = PetscMalloc1(n+1,&bii);CHKERRQ(ierr); 20811cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bij);CHKERRQ(ierr); 20821cf9b237SStefano Zampini ierr = PetscMalloc1(nnz,&bdata);CHKERRQ(ierr); 20831cf9b237SStefano Zampini nnz = 0; 20841cf9b237SStefano Zampini bii[0] = 0; 20851cf9b237SStefano Zampini for (i=0;i<n;i++) { 20861cf9b237SStefano Zampini PetscInt j; 20871cf9b237SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 20881cf9b237SStefano Zampini PetscScalar entry = a[j]; 20893272d46bSStefano Zampini if (PetscLikely(PetscAbsScalar(entry) > PETSC_SMALL) || (n == m && ij[j] == i)) { 20901cf9b237SStefano Zampini bij[nnz] = ij[j]; 20911cf9b237SStefano Zampini bdata[nnz] = entry; 20921cf9b237SStefano Zampini nnz++; 20931cf9b237SStefano Zampini } 20941cf9b237SStefano Zampini } 20951cf9b237SStefano Zampini bii[i+1] = nnz; 20961cf9b237SStefano Zampini } 20971cf9b237SStefano Zampini ierr = MatSeqAIJRestoreArray(A,&a);CHKERRQ(ierr); 20981cf9b237SStefano Zampini ierr = MatCreateSeqAIJWithArrays(PetscObjectComm((PetscObject)A),n,m,bii,bij,bdata,&Bt);CHKERRQ(ierr); 20991cf9b237SStefano Zampini ierr = MatRestoreRowIJ(A,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&ij,&flg_row);CHKERRQ(ierr); 21001cf9b237SStefano Zampini { 21011cf9b237SStefano Zampini Mat_SeqAIJ *b = (Mat_SeqAIJ*)(Bt->data); 21021cf9b237SStefano Zampini b->free_a = PETSC_TRUE; 21031cf9b237SStefano Zampini b->free_ij = PETSC_TRUE; 21041cf9b237SStefano Zampini } 21053272d46bSStefano Zampini if (*B == A) { 21063272d46bSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 21073272d46bSStefano Zampini } 21081cf9b237SStefano Zampini *B = Bt; 21091cf9b237SStefano Zampini PetscFunctionReturn(0); 21101cf9b237SStefano Zampini } 21111cf9b237SStefano Zampini 2112c80a6c00SStefano Zampini PetscErrorCode PCBDDCDetectDisconnectedComponents(PC pc, PetscInt *ncc, IS* cc[], IS* primalv) 21134f1b2e48SStefano Zampini { 2114c80a6c00SStefano Zampini Mat B = NULL; 2115c80a6c00SStefano Zampini DM dm; 21164f1b2e48SStefano Zampini IS is_dummy,*cc_n; 21174f1b2e48SStefano Zampini ISLocalToGlobalMapping l2gmap_dummy; 21184f1b2e48SStefano Zampini PCBDDCGraph graph; 2119c80a6c00SStefano Zampini PetscInt *xadj_filtered = NULL,*adjncy_filtered = NULL; 21204f1b2e48SStefano Zampini PetscInt i,n; 21214f1b2e48SStefano Zampini PetscInt *xadj,*adjncy; 2122c80a6c00SStefano Zampini PetscBool isplex = PETSC_FALSE; 21234f1b2e48SStefano Zampini PetscErrorCode ierr; 21244f1b2e48SStefano Zampini 21254f1b2e48SStefano Zampini PetscFunctionBegin; 2126a2eca866SStefano Zampini if (ncc) *ncc = 0; 2127a2eca866SStefano Zampini if (cc) *cc = NULL; 2128a2eca866SStefano Zampini if (primalv) *primalv = NULL; 2129c80a6c00SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 2130c80a6c00SStefano Zampini ierr = PCGetDM(pc,&dm);CHKERRQ(ierr); 2131c80a6c00SStefano Zampini if (!dm) { 2132c80a6c00SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 2133c80a6c00SStefano Zampini } 2134c80a6c00SStefano Zampini if (dm) { 2135c80a6c00SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMPLEX,&isplex);CHKERRQ(ierr); 2136c80a6c00SStefano Zampini } 2137c80a6c00SStefano Zampini if (isplex) { /* this code has been modified from plexpartition.c */ 2138c80a6c00SStefano Zampini PetscInt p, pStart, pEnd, a, adjSize, idx, size, nroots; 2139c80a6c00SStefano Zampini PetscInt *adj = NULL; 2140c80a6c00SStefano Zampini IS cellNumbering; 2141c80a6c00SStefano Zampini const PetscInt *cellNum; 2142c80a6c00SStefano Zampini PetscBool useCone, useClosure; 2143c80a6c00SStefano Zampini PetscSection section; 2144c80a6c00SStefano Zampini PetscSegBuffer adjBuffer; 2145c80a6c00SStefano Zampini PetscSF sfPoint; 2146c80a6c00SStefano Zampini PetscErrorCode ierr; 2147c80a6c00SStefano Zampini 2148c80a6c00SStefano Zampini PetscFunctionBegin; 2149c80a6c00SStefano Zampini ierr = DMPlexGetHeightStratum(dm, 0, &pStart, &pEnd);CHKERRQ(ierr); 2150c80a6c00SStefano Zampini ierr = DMGetPointSF(dm, &sfPoint);CHKERRQ(ierr); 2151c80a6c00SStefano Zampini ierr = PetscSFGetGraph(sfPoint, &nroots, NULL, NULL, NULL);CHKERRQ(ierr); 2152c80a6c00SStefano Zampini /* Build adjacency graph via a section/segbuffer */ 2153c80a6c00SStefano Zampini ierr = PetscSectionCreate(PetscObjectComm((PetscObject) dm), §ion);CHKERRQ(ierr); 2154c80a6c00SStefano Zampini ierr = PetscSectionSetChart(section, pStart, pEnd);CHKERRQ(ierr); 2155c80a6c00SStefano Zampini ierr = PetscSegBufferCreate(sizeof(PetscInt),1000,&adjBuffer);CHKERRQ(ierr); 2156c80a6c00SStefano Zampini /* Always use FVM adjacency to create partitioner graph */ 2157c80a6c00SStefano Zampini ierr = DMPlexGetAdjacencyUseCone(dm, &useCone);CHKERRQ(ierr); 2158c80a6c00SStefano Zampini ierr = DMPlexGetAdjacencyUseClosure(dm, &useClosure);CHKERRQ(ierr); 2159c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseCone(dm, PETSC_TRUE);CHKERRQ(ierr); 2160c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseClosure(dm, PETSC_FALSE);CHKERRQ(ierr); 2161956e2312SStefano Zampini ierr = DMPlexGetCellNumbering(dm, &cellNumbering);CHKERRQ(ierr); 2162c80a6c00SStefano Zampini ierr = ISGetIndices(cellNumbering, &cellNum);CHKERRQ(ierr); 2163c80a6c00SStefano Zampini for (n = 0, p = pStart; p < pEnd; p++) { 2164c80a6c00SStefano Zampini /* Skip non-owned cells in parallel (ParMetis expects no overlap) */ 2165c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2166c80a6c00SStefano Zampini adjSize = PETSC_DETERMINE; 2167c80a6c00SStefano Zampini ierr = DMPlexGetAdjacency(dm, p, &adjSize, &adj);CHKERRQ(ierr); 2168c80a6c00SStefano Zampini for (a = 0; a < adjSize; ++a) { 2169c80a6c00SStefano Zampini const PetscInt point = adj[a]; 21705cef3d0dSStefano Zampini if (pStart <= point && point < pEnd) { 2171c80a6c00SStefano Zampini PetscInt *PETSC_RESTRICT pBuf; 2172c80a6c00SStefano Zampini ierr = PetscSectionAddDof(section, p, 1);CHKERRQ(ierr); 2173c80a6c00SStefano Zampini ierr = PetscSegBufferGetInts(adjBuffer, 1, &pBuf);CHKERRQ(ierr); 2174c80a6c00SStefano Zampini *pBuf = point; 2175c80a6c00SStefano Zampini } 2176c80a6c00SStefano Zampini } 2177c80a6c00SStefano Zampini n++; 2178c80a6c00SStefano Zampini } 2179c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseCone(dm, useCone);CHKERRQ(ierr); 2180c80a6c00SStefano Zampini ierr = DMPlexSetAdjacencyUseClosure(dm, useClosure);CHKERRQ(ierr); 2181c80a6c00SStefano Zampini /* Derive CSR graph from section/segbuffer */ 2182c80a6c00SStefano Zampini ierr = PetscSectionSetUp(section);CHKERRQ(ierr); 2183c80a6c00SStefano Zampini ierr = PetscSectionGetStorageSize(section, &size);CHKERRQ(ierr); 2184c80a6c00SStefano Zampini ierr = PetscMalloc1(n+1, &xadj);CHKERRQ(ierr); 2185c80a6c00SStefano Zampini for (idx = 0, p = pStart; p < pEnd; p++) { 2186c80a6c00SStefano Zampini if (nroots > 0) {if (cellNum[p] < 0) continue;} 2187c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(section, p, &(xadj[idx++]));CHKERRQ(ierr); 2188c80a6c00SStefano Zampini } 2189c80a6c00SStefano Zampini xadj[n] = size; 2190c80a6c00SStefano Zampini ierr = PetscSegBufferExtractAlloc(adjBuffer, &adjncy);CHKERRQ(ierr); 2191c80a6c00SStefano Zampini /* Clean up */ 2192c80a6c00SStefano Zampini ierr = PetscSegBufferDestroy(&adjBuffer);CHKERRQ(ierr); 2193c80a6c00SStefano Zampini ierr = PetscSectionDestroy(§ion);CHKERRQ(ierr); 2194c80a6c00SStefano Zampini ierr = PetscFree(adj);CHKERRQ(ierr); 2195c80a6c00SStefano Zampini graph->xadj = xadj; 2196c80a6c00SStefano Zampini graph->adjncy = adjncy; 2197c80a6c00SStefano Zampini } else { 2198c80a6c00SStefano Zampini Mat A; 2199c80a6c00SStefano Zampini PetscBool filter = PETSC_FALSE, isseqaij, flg_row; 2200c80a6c00SStefano Zampini 2201c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 220263c961adSStefano Zampini if (!A->rmap->N || !A->cmap->N) { 2203a2eca866SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 220463c961adSStefano Zampini PetscFunctionReturn(0); 220563c961adSStefano Zampini } 22064f1b2e48SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 22074f1b2e48SStefano Zampini if (!isseqaij && filter) { 22081cf9b237SStefano Zampini PetscBool isseqdense; 22091cf9b237SStefano Zampini 22101cf9b237SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A,MATSEQDENSE,&isseqdense);CHKERRQ(ierr); 22111cf9b237SStefano Zampini if (!isseqdense) { 22124f1b2e48SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 22131cf9b237SStefano Zampini } else { /* TODO: rectangular case and LDA */ 22141cf9b237SStefano Zampini PetscScalar *array; 22151cf9b237SStefano Zampini PetscReal chop=1.e-6; 22161cf9b237SStefano Zampini 22171cf9b237SStefano Zampini ierr = MatDuplicate(A,MAT_COPY_VALUES,&B);CHKERRQ(ierr); 22181cf9b237SStefano Zampini ierr = MatDenseGetArray(B,&array);CHKERRQ(ierr); 22191cf9b237SStefano Zampini ierr = MatGetSize(B,&n,NULL);CHKERRQ(ierr); 22201cf9b237SStefano Zampini for (i=0;i<n;i++) { 22211cf9b237SStefano Zampini PetscInt j; 22221cf9b237SStefano Zampini for (j=i+1;j<n;j++) { 22231cf9b237SStefano Zampini PetscReal thresh = chop*(PetscAbsScalar(array[i*(n+1)])+PetscAbsScalar(array[j*(n+1)])); 22241cf9b237SStefano Zampini if (PetscAbsScalar(array[i*n+j]) < thresh) array[i*n+j] = 0.; 22251cf9b237SStefano Zampini if (PetscAbsScalar(array[j*n+i]) < thresh) array[j*n+i] = 0.; 22261cf9b237SStefano Zampini } 22271cf9b237SStefano Zampini } 22281cf9b237SStefano Zampini ierr = MatDenseRestoreArray(B,&array);CHKERRQ(ierr); 22299d54b7f4SStefano Zampini ierr = MatConvert(B,MATSEQAIJ,MAT_INPLACE_MATRIX,&B);CHKERRQ(ierr); 22301cf9b237SStefano Zampini } 22314f1b2e48SStefano Zampini } else { 2232c80a6c00SStefano Zampini ierr = PetscObjectReference((PetscObject)A);CHKERRQ(ierr); 22334f1b2e48SStefano Zampini B = A; 22344f1b2e48SStefano Zampini } 22354f1b2e48SStefano Zampini ierr = MatGetRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 22364f1b2e48SStefano Zampini 22374f1b2e48SStefano Zampini /* if filter is true, then removes entries lower than PETSC_SMALL in magnitude */ 22384f1b2e48SStefano Zampini if (filter) { 22394f1b2e48SStefano Zampini PetscScalar *data; 22404f1b2e48SStefano Zampini PetscInt j,cum; 22414f1b2e48SStefano Zampini 22424f1b2e48SStefano Zampini ierr = PetscCalloc2(n+1,&xadj_filtered,xadj[n],&adjncy_filtered);CHKERRQ(ierr); 22434f1b2e48SStefano Zampini ierr = MatSeqAIJGetArray(B,&data);CHKERRQ(ierr); 22444f1b2e48SStefano Zampini cum = 0; 22454f1b2e48SStefano Zampini for (i=0;i<n;i++) { 22464f1b2e48SStefano Zampini PetscInt t; 22474f1b2e48SStefano Zampini 22484f1b2e48SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) { 22494f1b2e48SStefano Zampini if (PetscUnlikely(PetscAbsScalar(data[j]) < PETSC_SMALL)) { 22504f1b2e48SStefano Zampini continue; 22514f1b2e48SStefano Zampini } 22524f1b2e48SStefano Zampini adjncy_filtered[cum+xadj_filtered[i]++] = adjncy[j]; 22534f1b2e48SStefano Zampini } 22544f1b2e48SStefano Zampini t = xadj_filtered[i]; 22554f1b2e48SStefano Zampini xadj_filtered[i] = cum; 22564f1b2e48SStefano Zampini cum += t; 22574f1b2e48SStefano Zampini } 22584f1b2e48SStefano Zampini ierr = MatSeqAIJRestoreArray(B,&data);CHKERRQ(ierr); 22594f1b2e48SStefano Zampini graph->xadj = xadj_filtered; 22604f1b2e48SStefano Zampini graph->adjncy = adjncy_filtered; 22614f1b2e48SStefano Zampini } else { 22624f1b2e48SStefano Zampini graph->xadj = xadj; 22634f1b2e48SStefano Zampini graph->adjncy = adjncy; 22644f1b2e48SStefano Zampini } 2265c80a6c00SStefano Zampini } 2266c80a6c00SStefano Zampini /* compute local connected components using PCBDDCGraph */ 2267c80a6c00SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n,0,1,&is_dummy);CHKERRQ(ierr); 2268c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_dummy,&l2gmap_dummy);CHKERRQ(ierr); 2269c80a6c00SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 2270c80a6c00SStefano Zampini ierr = PCBDDCGraphInit(graph,l2gmap_dummy,n,PETSC_MAX_INT);CHKERRQ(ierr); 2271c80a6c00SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap_dummy);CHKERRQ(ierr); 22724f1b2e48SStefano Zampini ierr = PCBDDCGraphSetUp(graph,1,NULL,NULL,0,NULL,NULL);CHKERRQ(ierr); 22734f1b2e48SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 2274c80a6c00SStefano Zampini 22754f1b2e48SStefano Zampini /* partial clean up */ 22764f1b2e48SStefano Zampini ierr = PetscFree2(xadj_filtered,adjncy_filtered);CHKERRQ(ierr); 2277c80a6c00SStefano Zampini if (B) { 2278c80a6c00SStefano Zampini PetscBool flg_row; 22794f1b2e48SStefano Zampini ierr = MatRestoreRowIJ(B,0,PETSC_TRUE,PETSC_FALSE,&n,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 22804f1b2e48SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 22814f1b2e48SStefano Zampini } 2282c80a6c00SStefano Zampini if (isplex) { 2283c80a6c00SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 2284c80a6c00SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 2285c80a6c00SStefano Zampini } 22864f1b2e48SStefano Zampini 22874f1b2e48SStefano Zampini /* get back data */ 2288c80a6c00SStefano Zampini if (isplex) { 2289c80a6c00SStefano Zampini if (ncc) *ncc = graph->ncc; 2290c80a6c00SStefano Zampini if (cc || primalv) { 2291c80a6c00SStefano Zampini Mat A; 2292c80a6c00SStefano Zampini PetscBT btv,btvt; 2293c80a6c00SStefano Zampini PetscSection subSection; 2294c80a6c00SStefano Zampini PetscInt *ids,cum,cump,*cids,*pids; 2295c80a6c00SStefano Zampini 2296c80a6c00SStefano Zampini ierr = DMPlexGetSubdomainSection(dm,&subSection);CHKERRQ(ierr); 2297c80a6c00SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 2298c80a6c00SStefano Zampini ierr = PetscMalloc3(A->rmap->n,&ids,graph->ncc+1,&cids,A->rmap->n,&pids);CHKERRQ(ierr); 2299c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btv);CHKERRQ(ierr); 2300c80a6c00SStefano Zampini ierr = PetscBTCreate(A->rmap->n,&btvt);CHKERRQ(ierr); 2301c80a6c00SStefano Zampini 2302c80a6c00SStefano Zampini cids[0] = 0; 2303c80a6c00SStefano Zampini for (i = 0, cump = 0, cum = 0; i < graph->ncc; i++) { 2304c80a6c00SStefano Zampini PetscInt j; 2305c80a6c00SStefano Zampini 2306c80a6c00SStefano Zampini ierr = PetscBTMemzero(A->rmap->n,btvt);CHKERRQ(ierr); 2307c80a6c00SStefano Zampini for (j = graph->cptr[i]; j < graph->cptr[i+1]; j++) { 2308c80a6c00SStefano Zampini PetscInt k, size, *closure = NULL, cell = graph->queue[j]; 2309c80a6c00SStefano Zampini 2310c80a6c00SStefano Zampini ierr = DMPlexGetTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2311c80a6c00SStefano Zampini for (k = 0; k < 2*size; k += 2) { 2312c80a6c00SStefano Zampini PetscInt s, p = closure[k], off, dof, cdof; 2313c80a6c00SStefano Zampini 2314c80a6c00SStefano Zampini ierr = PetscSectionGetConstraintDof(subSection, p, &cdof);CHKERRQ(ierr); 2315c80a6c00SStefano Zampini ierr = PetscSectionGetOffset(subSection,p,&off);CHKERRQ(ierr); 2316c80a6c00SStefano Zampini ierr = PetscSectionGetDof(subSection,p,&dof);CHKERRQ(ierr); 2317c80a6c00SStefano Zampini for (s = 0; s < dof-cdof; s++) { 2318c80a6c00SStefano Zampini if (PetscBTLookupSet(btvt,off+s)) continue; 2319c80a6c00SStefano Zampini if (!PetscBTLookup(btv,off+s)) { 2320c80a6c00SStefano Zampini ids[cum++] = off+s; 2321c80a6c00SStefano Zampini } else { /* cross-vertex */ 2322c80a6c00SStefano Zampini pids[cump++] = off+s; 2323c80a6c00SStefano Zampini } 2324c80a6c00SStefano Zampini } 2325c80a6c00SStefano Zampini } 2326c80a6c00SStefano Zampini ierr = DMPlexRestoreTransitiveClosure(dm,cell,PETSC_TRUE,&size,&closure);CHKERRQ(ierr); 2327c80a6c00SStefano Zampini } 2328c80a6c00SStefano Zampini cids[i+1] = cum; 2329c80a6c00SStefano Zampini /* mark dofs as already assigned */ 2330c80a6c00SStefano Zampini for (j = cids[i]; j < cids[i+1]; j++) { 2331c80a6c00SStefano Zampini ierr = PetscBTSet(btv,ids[j]);CHKERRQ(ierr); 2332c80a6c00SStefano Zampini } 2333c80a6c00SStefano Zampini } 2334c80a6c00SStefano Zampini if (cc) { 2335c80a6c00SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 2336c80a6c00SStefano Zampini for (i = 0; i < graph->ncc; i++) { 2337c80a6c00SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cids[i+1]-cids[i],ids+cids[i],PETSC_COPY_VALUES,&cc_n[i]);CHKERRQ(ierr); 2338c80a6c00SStefano Zampini } 2339c80a6c00SStefano Zampini *cc = cc_n; 2340c80a6c00SStefano Zampini } 2341c80a6c00SStefano Zampini if (primalv) { 2342c80a6c00SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),cump,pids,PETSC_COPY_VALUES,primalv);CHKERRQ(ierr); 2343c80a6c00SStefano Zampini } 2344c80a6c00SStefano Zampini ierr = PetscFree3(ids,cids,pids);CHKERRQ(ierr); 2345c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 2346c80a6c00SStefano Zampini ierr = PetscBTDestroy(&btvt);CHKERRQ(ierr); 2347c80a6c00SStefano Zampini } 2348c80a6c00SStefano Zampini } else { 23491cf9b237SStefano Zampini if (ncc) *ncc = graph->ncc; 23501cf9b237SStefano Zampini if (cc) { 23514f1b2e48SStefano Zampini ierr = PetscMalloc1(graph->ncc,&cc_n);CHKERRQ(ierr); 23524f1b2e48SStefano Zampini for (i=0;i<graph->ncc;i++) { 23534f1b2e48SStefano 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); 23544f1b2e48SStefano Zampini } 23554f1b2e48SStefano Zampini *cc = cc_n; 23561cf9b237SStefano Zampini } 2357c80a6c00SStefano Zampini } 23584f1b2e48SStefano Zampini /* clean up graph */ 23594f1b2e48SStefano Zampini graph->xadj = 0; 23604f1b2e48SStefano Zampini graph->adjncy = 0; 23614f1b2e48SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 23624f1b2e48SStefano Zampini PetscFunctionReturn(0); 23634f1b2e48SStefano Zampini } 23644f1b2e48SStefano Zampini 23655408967cSStefano Zampini PetscErrorCode PCBDDCBenignCheck(PC pc, IS zerodiag) 23665408967cSStefano Zampini { 23675408967cSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 23685408967cSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 2369dee84bffSStefano Zampini IS dirIS = NULL; 23704f1b2e48SStefano Zampini PetscInt i; 23715408967cSStefano Zampini PetscErrorCode ierr; 23725408967cSStefano Zampini 23735408967cSStefano Zampini PetscFunctionBegin; 2374dee84bffSStefano Zampini ierr = PCBDDCGraphGetDirichletDofs(pcbddc->mat_graph,&dirIS);CHKERRQ(ierr); 23755408967cSStefano Zampini if (zerodiag) { 23765408967cSStefano Zampini Mat A; 23775408967cSStefano Zampini Vec vec3_N; 23785408967cSStefano Zampini PetscScalar *vals; 23795408967cSStefano Zampini const PetscInt *idxs; 2380d12d3064SStefano Zampini PetscInt nz,*count; 23815408967cSStefano Zampini 23825408967cSStefano Zampini /* p0 */ 23835408967cSStefano Zampini ierr = VecSet(pcis->vec1_N,0.);CHKERRQ(ierr); 23845408967cSStefano Zampini ierr = PetscMalloc1(pcis->n,&vals);CHKERRQ(ierr); 23855408967cSStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 23865408967cSStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 23874f1b2e48SStefano Zampini for (i=0;i<nz;i++) vals[i] = 1.; 23885408967cSStefano Zampini ierr = VecSetValues(pcis->vec1_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 23895408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 23905408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 23915408967cSStefano Zampini /* v_I */ 23925408967cSStefano Zampini ierr = VecSetRandom(pcis->vec2_N,NULL);CHKERRQ(ierr); 23935408967cSStefano Zampini for (i=0;i<nz;i++) vals[i] = 0.; 23945408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 23955408967cSStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 23965408967cSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 23975408967cSStefano Zampini for (i=0;i<pcis->n_B;i++) vals[i] = 0.; 23985408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,pcis->n_B,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 23995408967cSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 24005408967cSStefano Zampini if (dirIS) { 24015408967cSStefano Zampini PetscInt n; 24025408967cSStefano Zampini 24035408967cSStefano Zampini ierr = ISGetLocalSize(dirIS,&n);CHKERRQ(ierr); 24045408967cSStefano Zampini ierr = ISGetIndices(dirIS,&idxs);CHKERRQ(ierr); 24055408967cSStefano Zampini for (i=0;i<n;i++) vals[i] = 0.; 24065408967cSStefano Zampini ierr = VecSetValues(pcis->vec2_N,n,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 24075408967cSStefano Zampini ierr = ISRestoreIndices(dirIS,&idxs);CHKERRQ(ierr); 24085408967cSStefano Zampini } 24095408967cSStefano Zampini ierr = VecAssemblyBegin(pcis->vec2_N);CHKERRQ(ierr); 24105408967cSStefano Zampini ierr = VecAssemblyEnd(pcis->vec2_N);CHKERRQ(ierr); 24115408967cSStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&vec3_N);CHKERRQ(ierr); 24125408967cSStefano Zampini ierr = VecSet(vec3_N,0.);CHKERRQ(ierr); 2413669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 24145408967cSStefano Zampini ierr = MatMult(A,pcis->vec1_N,vec3_N);CHKERRQ(ierr); 24155408967cSStefano Zampini ierr = VecDot(vec3_N,pcis->vec2_N,&vals[0]);CHKERRQ(ierr); 24169a962809SStefano 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])); 24175408967cSStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 24185408967cSStefano Zampini ierr = VecDestroy(&vec3_N);CHKERRQ(ierr); 2419d12d3064SStefano Zampini 2420d12d3064SStefano Zampini /* there should not be any pressure dofs lying on the interface */ 2421d12d3064SStefano Zampini ierr = PetscCalloc1(pcis->n,&count);CHKERRQ(ierr); 2422d12d3064SStefano Zampini ierr = ISGetIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2423d12d3064SStefano Zampini for (i=0;i<pcis->n_B;i++) count[idxs[i]]++; 2424d12d3064SStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,&idxs);CHKERRQ(ierr); 2425d12d3064SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 24269a962809SStefano 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]); 2427d12d3064SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 2428d12d3064SStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 24295408967cSStefano Zampini } 2430dee84bffSStefano Zampini ierr = ISDestroy(&dirIS);CHKERRQ(ierr); 24315408967cSStefano Zampini 24325408967cSStefano Zampini /* check PCBDDCBenignGetOrSetP0 */ 24335408967cSStefano Zampini ierr = VecSetRandom(pcis->vec1_global,NULL);CHKERRQ(ierr); 24344f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = -PetscGlobalRank-i; 24355408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_FALSE);CHKERRQ(ierr); 24364f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = 1; 24375408967cSStefano Zampini ierr = PCBDDCBenignGetOrSetP0(pc,pcis->vec1_global,PETSC_TRUE);CHKERRQ(ierr); 2438f2a566d8SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2439f2a566d8SStefano Zampini PetscInt val = PetscRealPart(pcbddc->benign_p0[i]); 244013903a91SSatish 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); 2441f2a566d8SStefano Zampini } 24425408967cSStefano Zampini PetscFunctionReturn(0); 24435408967cSStefano Zampini } 24445408967cSStefano Zampini 2445339f8db1SStefano Zampini PetscErrorCode PCBDDCBenignDetectSaddlePoint(PC pc, IS *zerodiaglocal) 2446339f8db1SStefano Zampini { 2447339f8db1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 24484edc6404Sstefano_zampini IS pressures,zerodiag,zerodiag_save,*zerodiag_subs; 2449b0f5fe93SStefano Zampini PetscInt nz,n; 24504edc6404Sstefano_zampini PetscInt *interior_dofs,n_interior_dofs,nneu; 24514edc6404Sstefano_zampini PetscBool sorted,have_null,has_null_pressures,recompute_zerodiag,checkb; 2452339f8db1SStefano Zampini PetscErrorCode ierr; 2453339f8db1SStefano Zampini 2454339f8db1SStefano Zampini PetscFunctionBegin; 24559f47a83aSStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 24569f47a83aSStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 2457a3df083aSStefano Zampini for (n=0;n<pcbddc->benign_n;n++) { 2458a3df083aSStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[n]);CHKERRQ(ierr); 2459a3df083aSStefano Zampini } 2460a3df083aSStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 2461a3df083aSStefano Zampini pcbddc->benign_n = 0; 246228b8efb1Sstefano_zampini 246328b8efb1Sstefano_zampini /* if a local info on dofs is present, uses the last field for "pressures" (or fid by command line) 24644f1b2e48SStefano Zampini otherwise, it uses only zerodiagonal dofs (ok if the pressure block is all zero; it could fail if it is not) 24654f1b2e48SStefano Zampini Checks if all the pressure dofs in each subdomain have a zero diagonal 24664f1b2e48SStefano Zampini If not, a change of basis on pressures is not needed 24671ae86dd6SStefano Zampini since the local Schur complements are already SPD 24684f1b2e48SStefano Zampini */ 24694f1b2e48SStefano Zampini has_null_pressures = PETSC_TRUE; 24704f1b2e48SStefano Zampini have_null = PETSC_TRUE; 247140fa8d13SStefano Zampini if (pcbddc->n_ISForDofsLocal) { 24727fbe2174Sstefano_zampini IS iP = NULL; 24734f1b2e48SStefano Zampini PetscInt npl,*idxs,p = pcbddc->n_ISForDofsLocal-1; 24744f1b2e48SStefano Zampini 247528b8efb1Sstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC benign options","PC");CHKERRQ(ierr); 247628b8efb1Sstefano_zampini ierr = PetscOptionsInt("-pc_bddc_pressure_field","Field id for pressures",NULL,p,&p,NULL);CHKERRQ(ierr); 247728b8efb1Sstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 247828b8efb1Sstefano_zampini if (p < 0 || p > pcbddc->n_ISForDofsLocal-1) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Invalid field id for pressures %D",p); 24794f1b2e48SStefano Zampini /* Dofs splitting for BDDC cannot have PETSC_COMM_SELF, so create a sequential IS */ 24804f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[p],&npl);CHKERRQ(ierr); 24814f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 24824f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,npl,idxs,PETSC_COPY_VALUES,&pressures);CHKERRQ(ierr); 2483ba14f8e3SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[p],(const PetscInt**)&idxs);CHKERRQ(ierr); 24847fbe2174Sstefano_zampini /* remove zeroed out pressures if we are setting up a BDDC solver for a saddle-point FETI-DP */ 24857fbe2174Sstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lP",(PetscObject*)&iP);CHKERRQ(ierr); 24867fbe2174Sstefano_zampini if (iP) { 24877fbe2174Sstefano_zampini IS newpressures; 24887fbe2174Sstefano_zampini 24897fbe2174Sstefano_zampini ierr = ISDifference(pressures,iP,&newpressures);CHKERRQ(ierr); 24907fbe2174Sstefano_zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 24917fbe2174Sstefano_zampini pressures = newpressures; 24927fbe2174Sstefano_zampini } 249340fa8d13SStefano Zampini ierr = ISSorted(pressures,&sorted);CHKERRQ(ierr); 249440fa8d13SStefano Zampini if (!sorted) { 249540fa8d13SStefano Zampini ierr = ISSort(pressures);CHKERRQ(ierr); 249640fa8d13SStefano Zampini } 249740fa8d13SStefano Zampini } else { 249840fa8d13SStefano Zampini pressures = NULL; 249940fa8d13SStefano Zampini } 250097d764eeSStefano Zampini /* pcis has not been setup yet, so get the local size from the subdomain matrix */ 250197d764eeSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 250227b6a85dSStefano Zampini if (!n) pcbddc->benign_change_explicit = PETSC_TRUE; 250397d764eeSStefano Zampini ierr = MatFindZeroDiagonals(pcbddc->local_mat,&zerodiag);CHKERRQ(ierr); 2504339f8db1SStefano Zampini ierr = ISSorted(zerodiag,&sorted);CHKERRQ(ierr); 2505339f8db1SStefano Zampini if (!sorted) { 2506339f8db1SStefano Zampini ierr = ISSort(zerodiag);CHKERRQ(ierr); 2507339f8db1SStefano Zampini } 25084edc6404Sstefano_zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 25094edc6404Sstefano_zampini zerodiag_save = zerodiag; 2510339f8db1SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 25114f1b2e48SStefano Zampini if (!nz) { 25124f1b2e48SStefano Zampini if (n) have_null = PETSC_FALSE; 25134f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 251440fa8d13SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 251540fa8d13SStefano Zampini } 25164f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 25174f1b2e48SStefano Zampini /* in case disconnected subdomains info is present, split the pressures accordingly (otherwise the benign trick could fail) */ 25184f1b2e48SStefano Zampini zerodiag_subs = NULL; 25194f1b2e48SStefano Zampini pcbddc->benign_n = 0; 25201f4df5f7SStefano Zampini n_interior_dofs = 0; 25211f4df5f7SStefano Zampini interior_dofs = NULL; 25224edc6404Sstefano_zampini nneu = 0; 25234edc6404Sstefano_zampini if (pcbddc->NeumannBoundariesLocal) { 25244edc6404Sstefano_zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&nneu);CHKERRQ(ierr); 25254edc6404Sstefano_zampini } 25263369cb78Sstefano_zampini checkb = (PetscBool)(!pcbddc->NeumannBoundariesLocal || pcbddc->current_level); 25274edc6404Sstefano_zampini if (checkb) { /* need to compute interior nodes */ 25281f4df5f7SStefano Zampini PetscInt n,i,j; 25291f4df5f7SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 25301f4df5f7SStefano Zampini PetscInt *iwork; 25311f4df5f7SStefano Zampini 25321f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(pc->pmat->rmap->mapping,&n);CHKERRQ(ierr); 25331f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 25341f4df5f7SStefano Zampini ierr = PetscCalloc1(n,&iwork);CHKERRQ(ierr); 25351f4df5f7SStefano Zampini ierr = PetscMalloc1(n,&interior_dofs);CHKERRQ(ierr); 253690648384SStefano Zampini for (i=1;i<n_neigh;i++) 25371f4df5f7SStefano Zampini for (j=0;j<n_shared[i];j++) 25381f4df5f7SStefano Zampini iwork[shared[i][j]] += 1; 25391f4df5f7SStefano Zampini for (i=0;i<n;i++) 25401f4df5f7SStefano Zampini if (!iwork[i]) 25411f4df5f7SStefano Zampini interior_dofs[n_interior_dofs++] = i; 25421f4df5f7SStefano Zampini ierr = PetscFree(iwork);CHKERRQ(ierr); 25431f4df5f7SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(pc->pmat->rmap->mapping,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 25441f4df5f7SStefano Zampini } 25454f1b2e48SStefano Zampini if (has_null_pressures) { 25464f1b2e48SStefano Zampini IS *subs; 25474edc6404Sstefano_zampini PetscInt nsubs,i,j,nl; 25481f4df5f7SStefano Zampini const PetscInt *idxs; 25491f4df5f7SStefano Zampini PetscScalar *array; 25501f4df5f7SStefano Zampini Vec *work; 25511f4df5f7SStefano Zampini Mat_IS* matis = (Mat_IS*)(pc->pmat->data); 25524f1b2e48SStefano Zampini 25534f1b2e48SStefano Zampini subs = pcbddc->local_subs; 25544f1b2e48SStefano Zampini nsubs = pcbddc->n_local_subs; 25551f4df5f7SStefano 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) */ 25564edc6404Sstefano_zampini if (checkb) { 25571f4df5f7SStefano Zampini ierr = VecDuplicateVecs(matis->y,2,&work);CHKERRQ(ierr); 25581f4df5f7SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nl);CHKERRQ(ierr); 25591f4df5f7SStefano Zampini ierr = ISGetIndices(zerodiag,&idxs);CHKERRQ(ierr); 25601f4df5f7SStefano Zampini /* work[0] = 1_p */ 25611f4df5f7SStefano Zampini ierr = VecSet(work[0],0.);CHKERRQ(ierr); 25621f4df5f7SStefano Zampini ierr = VecGetArray(work[0],&array);CHKERRQ(ierr); 25631f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 25641f4df5f7SStefano Zampini ierr = VecRestoreArray(work[0],&array);CHKERRQ(ierr); 25651f4df5f7SStefano Zampini /* work[0] = 1_v */ 25661f4df5f7SStefano Zampini ierr = VecSet(work[1],1.);CHKERRQ(ierr); 25671f4df5f7SStefano Zampini ierr = VecGetArray(work[1],&array);CHKERRQ(ierr); 25681f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 0.; 25691f4df5f7SStefano Zampini ierr = VecRestoreArray(work[1],&array);CHKERRQ(ierr); 25701f4df5f7SStefano Zampini ierr = ISRestoreIndices(zerodiag,&idxs);CHKERRQ(ierr); 25711f4df5f7SStefano Zampini } 25724f1b2e48SStefano Zampini if (nsubs > 1) { 25734f1b2e48SStefano Zampini ierr = PetscCalloc1(nsubs,&zerodiag_subs);CHKERRQ(ierr); 25744f1b2e48SStefano Zampini for (i=0;i<nsubs;i++) { 25754f1b2e48SStefano Zampini ISLocalToGlobalMapping l2g; 25764f1b2e48SStefano Zampini IS t_zerodiag_subs; 25774f1b2e48SStefano Zampini PetscInt nl; 25784f1b2e48SStefano Zampini 25794f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(subs[i],&l2g);CHKERRQ(ierr); 25804f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,zerodiag,&t_zerodiag_subs);CHKERRQ(ierr); 25814f1b2e48SStefano Zampini ierr = ISGetLocalSize(t_zerodiag_subs,&nl);CHKERRQ(ierr); 25824f1b2e48SStefano Zampini if (nl) { 25834f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 25844f1b2e48SStefano Zampini 25854edc6404Sstefano_zampini if (checkb) { 25861f4df5f7SStefano Zampini ierr = VecSet(matis->x,0);CHKERRQ(ierr); 25871f4df5f7SStefano Zampini ierr = ISGetLocalSize(subs[i],&nl);CHKERRQ(ierr); 25881f4df5f7SStefano Zampini ierr = ISGetIndices(subs[i],&idxs);CHKERRQ(ierr); 25891f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 25901f4df5f7SStefano Zampini for (j=0;j<nl;j++) array[idxs[j]] = 1.; 25911f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 25921f4df5f7SStefano Zampini ierr = ISRestoreIndices(subs[i],&idxs);CHKERRQ(ierr); 25931f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[0],matis->x);CHKERRQ(ierr); 25941f4df5f7SStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 25951f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->y,work[1],matis->y);CHKERRQ(ierr); 25961f4df5f7SStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 25971f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 25981f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 25991f4df5f7SStefano Zampini valid = PETSC_FALSE; 26001f4df5f7SStefano Zampini break; 26011f4df5f7SStefano Zampini } 26021f4df5f7SStefano Zampini } 26031f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 26041f4df5f7SStefano Zampini } 26056632bad2Sstefano_zampini if (valid && nneu) { 26066632bad2Sstefano_zampini const PetscInt *idxs; 26071f4df5f7SStefano Zampini PetscInt nzb; 26081f4df5f7SStefano Zampini 26096632bad2Sstefano_zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 26106632bad2Sstefano_zampini ierr = ISGlobalToLocalMappingApply(l2g,IS_GTOLM_DROP,nneu,idxs,&nzb,NULL);CHKERRQ(ierr); 26116632bad2Sstefano_zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 26121f4df5f7SStefano Zampini if (nzb) valid = PETSC_FALSE; 26131f4df5f7SStefano Zampini } 26141f4df5f7SStefano Zampini if (valid && pressures) { 26154f1b2e48SStefano Zampini IS t_pressure_subs; 26164f1b2e48SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(l2g,IS_GTOLM_DROP,pressures,&t_pressure_subs);CHKERRQ(ierr); 26174f1b2e48SStefano Zampini ierr = ISEqual(t_pressure_subs,t_zerodiag_subs,&valid);CHKERRQ(ierr); 26184f1b2e48SStefano Zampini ierr = ISDestroy(&t_pressure_subs);CHKERRQ(ierr); 26194f1b2e48SStefano Zampini } 26204f1b2e48SStefano Zampini if (valid) { 26214f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(l2g,t_zerodiag_subs,&zerodiag_subs[pcbddc->benign_n]);CHKERRQ(ierr); 26224f1b2e48SStefano Zampini pcbddc->benign_n++; 26234f1b2e48SStefano Zampini } else { 26244f1b2e48SStefano Zampini recompute_zerodiag = PETSC_TRUE; 26254f1b2e48SStefano Zampini } 26264f1b2e48SStefano Zampini } 26274f1b2e48SStefano Zampini ierr = ISDestroy(&t_zerodiag_subs);CHKERRQ(ierr); 26284f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2g);CHKERRQ(ierr); 26294f1b2e48SStefano Zampini } 26304f1b2e48SStefano Zampini } else { /* there's just one subdomain (or zero if they have not been detected */ 26314f1b2e48SStefano Zampini PetscBool valid = PETSC_TRUE; 26321f4df5f7SStefano Zampini 26336632bad2Sstefano_zampini if (nneu) valid = PETSC_FALSE; 26341f4df5f7SStefano Zampini if (valid && pressures) { 26354f1b2e48SStefano Zampini ierr = ISEqual(pressures,zerodiag,&valid);CHKERRQ(ierr); 26364f1b2e48SStefano Zampini } 26374edc6404Sstefano_zampini if (valid && checkb) { 26381f4df5f7SStefano Zampini ierr = MatMult(matis->A,work[0],matis->x);CHKERRQ(ierr); 26391f4df5f7SStefano Zampini ierr = VecPointwiseMult(matis->x,work[1],matis->x);CHKERRQ(ierr); 26401f4df5f7SStefano Zampini ierr = VecGetArray(matis->x,&array);CHKERRQ(ierr); 26411f4df5f7SStefano Zampini for (j=0;j<n_interior_dofs;j++) { 26421f4df5f7SStefano Zampini if (PetscAbsScalar(array[interior_dofs[j]]) > PETSC_SMALL) { 26431f4df5f7SStefano Zampini valid = PETSC_FALSE; 26441f4df5f7SStefano Zampini break; 26451f4df5f7SStefano Zampini } 26461f4df5f7SStefano Zampini } 26471f4df5f7SStefano Zampini ierr = VecRestoreArray(matis->x,&array);CHKERRQ(ierr); 26481f4df5f7SStefano Zampini } 26494f1b2e48SStefano Zampini if (valid) { 26504f1b2e48SStefano Zampini pcbddc->benign_n = 1; 2651ca92afb2SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&zerodiag_subs);CHKERRQ(ierr); 26524f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag);CHKERRQ(ierr); 26534f1b2e48SStefano Zampini zerodiag_subs[0] = zerodiag; 26544f1b2e48SStefano Zampini } 26554f1b2e48SStefano Zampini } 26564edc6404Sstefano_zampini if (checkb) { 26571f4df5f7SStefano Zampini ierr = VecDestroyVecs(2,&work);CHKERRQ(ierr); 26584f1b2e48SStefano Zampini } 26591f4df5f7SStefano Zampini } 26601f4df5f7SStefano Zampini ierr = PetscFree(interior_dofs);CHKERRQ(ierr); 26614f1b2e48SStefano Zampini 26624f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2663b9b0e38cSStefano Zampini PetscInt n; 2664b9b0e38cSStefano Zampini 26654f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 26664f1b2e48SStefano Zampini recompute_zerodiag = PETSC_FALSE; 2667b9b0e38cSStefano Zampini ierr = MatGetLocalSize(pcbddc->local_mat,&n,NULL);CHKERRQ(ierr); 2668b9b0e38cSStefano Zampini if (n) { 26694f1b2e48SStefano Zampini has_null_pressures = PETSC_FALSE; 26704f1b2e48SStefano Zampini have_null = PETSC_FALSE; 26714f1b2e48SStefano Zampini } 2672b9b0e38cSStefano Zampini } 26734f1b2e48SStefano Zampini 26744f1b2e48SStefano Zampini /* final check for null pressures */ 26754f1b2e48SStefano Zampini if (zerodiag && pressures) { 26764f1b2e48SStefano Zampini PetscInt nz,np; 26774f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 26784f1b2e48SStefano Zampini ierr = ISGetLocalSize(pressures,&np);CHKERRQ(ierr); 26794f1b2e48SStefano Zampini if (nz != np) have_null = PETSC_FALSE; 26804f1b2e48SStefano Zampini } 26814f1b2e48SStefano Zampini 26824f1b2e48SStefano Zampini if (recompute_zerodiag) { 26834f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiag);CHKERRQ(ierr); 26844f1b2e48SStefano Zampini if (pcbddc->benign_n == 1) { 26854f1b2e48SStefano Zampini ierr = PetscObjectReference((PetscObject)zerodiag_subs[0]);CHKERRQ(ierr); 26864f1b2e48SStefano Zampini zerodiag = zerodiag_subs[0]; 26874f1b2e48SStefano Zampini } else { 26884f1b2e48SStefano Zampini PetscInt i,nzn,*new_idxs; 26894f1b2e48SStefano Zampini 26904f1b2e48SStefano Zampini nzn = 0; 26914f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 26924f1b2e48SStefano Zampini PetscInt ns; 26934f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 26944f1b2e48SStefano Zampini nzn += ns; 26954f1b2e48SStefano Zampini } 26964f1b2e48SStefano Zampini ierr = PetscMalloc1(nzn,&new_idxs);CHKERRQ(ierr); 26974f1b2e48SStefano Zampini nzn = 0; 26984f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 26994f1b2e48SStefano Zampini PetscInt ns,*idxs; 27004f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&ns);CHKERRQ(ierr); 27014f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 27024f1b2e48SStefano Zampini ierr = PetscMemcpy(new_idxs+nzn,idxs,ns*sizeof(PetscInt));CHKERRQ(ierr); 27034f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 27044f1b2e48SStefano Zampini nzn += ns; 27054f1b2e48SStefano Zampini } 27064f1b2e48SStefano Zampini ierr = PetscSortInt(nzn,new_idxs);CHKERRQ(ierr); 27074f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,nzn,new_idxs,PETSC_OWN_POINTER,&zerodiag);CHKERRQ(ierr); 27084f1b2e48SStefano Zampini } 27094f1b2e48SStefano Zampini have_null = PETSC_FALSE; 27104f1b2e48SStefano Zampini } 27114f1b2e48SStefano Zampini 2712669cc0f4SStefano Zampini /* Prepare matrix to compute no-net-flux */ 2713a198735bSStefano Zampini if (pcbddc->compute_nonetflux && !pcbddc->divudotp) { 2714a198735bSStefano Zampini Mat A,loc_divudotp; 2715a198735bSStefano Zampini ISLocalToGlobalMapping rl2g,cl2g,l2gmap; 2716a198735bSStefano Zampini IS row,col,isused = NULL; 2717a198735bSStefano Zampini PetscInt M,N,n,st,n_isused; 2718a198735bSStefano Zampini 27191f4df5f7SStefano Zampini if (pressures) { 27201f4df5f7SStefano Zampini isused = pressures; 27211f4df5f7SStefano Zampini } else { 27224edc6404Sstefano_zampini isused = zerodiag_save; 27231f4df5f7SStefano Zampini } 2724a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&l2gmap,NULL);CHKERRQ(ierr); 2725669cc0f4SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&A);CHKERRQ(ierr); 27261ae86dd6SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 27271ae86dd6SStefano 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"); 2728a198735bSStefano Zampini n_isused = 0; 2729a198735bSStefano Zampini if (isused) { 2730a198735bSStefano Zampini ierr = ISGetLocalSize(isused,&n_isused);CHKERRQ(ierr); 2731a198735bSStefano Zampini } 2732a198735bSStefano Zampini ierr = MPI_Scan(&n_isused,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2733a198735bSStefano Zampini st = st-n_isused; 27341ae86dd6SStefano Zampini if (n) { 2735a198735bSStefano Zampini const PetscInt *gidxs; 2736a198735bSStefano Zampini 27377dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,isused,NULL,MAT_INITIAL_MATRIX,&loc_divudotp);CHKERRQ(ierr); 2738a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 2739a198735bSStefano Zampini /* TODO: extend ISCreateStride with st = PETSC_DECIDE */ 2740a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2741a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2742a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 27431ae86dd6SStefano Zampini } else { 2744a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&loc_divudotp);CHKERRQ(ierr); 2745a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n_isused,st,1,&row);CHKERRQ(ierr); 2746a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),0,NULL,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 2747a198735bSStefano Zampini } 2748a198735bSStefano Zampini ierr = MatGetSize(pc->pmat,NULL,&N);CHKERRQ(ierr); 2749a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 2750a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 2751a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 2752a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 2753a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 2754a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->divudotp);CHKERRQ(ierr); 2755a198735bSStefano Zampini ierr = MatSetType(pcbddc->divudotp,MATIS);CHKERRQ(ierr); 2756a198735bSStefano Zampini ierr = MatSetSizes(pcbddc->divudotp,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 2757a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->divudotp,rl2g,cl2g);CHKERRQ(ierr); 2758a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 2759a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 2760a198735bSStefano Zampini ierr = MatISSetLocalMat(pcbddc->divudotp,loc_divudotp);CHKERRQ(ierr); 2761a198735bSStefano Zampini ierr = MatDestroy(&loc_divudotp);CHKERRQ(ierr); 27621ae86dd6SStefano Zampini ierr = MatAssemblyBegin(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27631ae86dd6SStefano Zampini ierr = MatAssemblyEnd(pcbddc->divudotp,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 27641ae86dd6SStefano Zampini } 27654edc6404Sstefano_zampini ierr = ISDestroy(&zerodiag_save);CHKERRQ(ierr); 2766b3afcdbeSStefano Zampini 2767b3afcdbeSStefano Zampini /* change of basis and p0 dofs */ 27684f1b2e48SStefano Zampini if (has_null_pressures) { 27694f1b2e48SStefano Zampini IS zerodiagc; 27704f1b2e48SStefano Zampini const PetscInt *idxs,*idxsc; 27714f1b2e48SStefano Zampini PetscInt i,s,*nnz; 27724f1b2e48SStefano Zampini 27734f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag,&nz);CHKERRQ(ierr); 2774339f8db1SStefano Zampini ierr = ISComplement(zerodiag,0,n,&zerodiagc);CHKERRQ(ierr); 2775339f8db1SStefano Zampini ierr = ISGetIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 2776339f8db1SStefano Zampini /* local change of basis for pressures */ 2777339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 277897d764eeSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_change);CHKERRQ(ierr); 2779339f8db1SStefano Zampini ierr = MatSetType(pcbddc->benign_change,MATAIJ);CHKERRQ(ierr); 2780339f8db1SStefano Zampini ierr = MatSetSizes(pcbddc->benign_change,n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2781339f8db1SStefano Zampini ierr = PetscMalloc1(n,&nnz);CHKERRQ(ierr); 27824f1b2e48SStefano Zampini for (i=0;i<n-nz;i++) nnz[idxsc[i]] = 1; /* identity on velocities plus pressure dofs for non-singular subdomains */ 27834f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 27844f1b2e48SStefano Zampini PetscInt nzs,j; 27854f1b2e48SStefano Zampini 27864f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[i],&nzs);CHKERRQ(ierr); 27874f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 27884f1b2e48SStefano Zampini for (j=0;j<nzs-1;j++) nnz[idxs[j]] = 2; /* change on pressures */ 27894f1b2e48SStefano Zampini nnz[idxs[nzs-1]] = nzs; /* last local pressure dof in subdomain */ 27904f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[i],&idxs);CHKERRQ(ierr); 27914f1b2e48SStefano Zampini } 2792339f8db1SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_change,0,nnz);CHKERRQ(ierr); 2793339f8db1SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2794339f8db1SStefano Zampini /* set identity on velocities */ 2795339f8db1SStefano Zampini for (i=0;i<n-nz;i++) { 2796339f8db1SStefano Zampini ierr = MatSetValue(pcbddc->benign_change,idxsc[i],idxsc[i],1.,INSERT_VALUES);CHKERRQ(ierr); 2797339f8db1SStefano Zampini } 27984f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiagc,&idxsc);CHKERRQ(ierr); 27994f1b2e48SStefano Zampini ierr = ISDestroy(&zerodiagc);CHKERRQ(ierr); 28009f47a83aSStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 28014f1b2e48SStefano 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); 2802339f8db1SStefano Zampini /* set change on pressures */ 28034f1b2e48SStefano Zampini for (s=0;s<pcbddc->benign_n;s++) { 28044f1b2e48SStefano Zampini PetscScalar *array; 28054f1b2e48SStefano Zampini PetscInt nzs; 28064f1b2e48SStefano Zampini 28074f1b2e48SStefano Zampini ierr = ISGetLocalSize(zerodiag_subs[s],&nzs);CHKERRQ(ierr); 28084f1b2e48SStefano Zampini ierr = ISGetIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 28094f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) { 2810339f8db1SStefano Zampini PetscScalar vals[2]; 2811339f8db1SStefano Zampini PetscInt cols[2]; 2812339f8db1SStefano Zampini 2813339f8db1SStefano Zampini cols[0] = idxs[i]; 28144f1b2e48SStefano Zampini cols[1] = idxs[nzs-1]; 2815339f8db1SStefano Zampini vals[0] = 1.; 2816b0f5fe93SStefano Zampini vals[1] = 1.; 28174f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,cols,2,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 2818339f8db1SStefano Zampini } 28194f1b2e48SStefano Zampini ierr = PetscMalloc1(nzs,&array);CHKERRQ(ierr); 28204f1b2e48SStefano Zampini for (i=0;i<nzs-1;i++) array[i] = -1.; 28214f1b2e48SStefano Zampini array[nzs-1] = 1.; 28224f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->benign_change,1,idxs+nzs-1,nzs,idxs,array,INSERT_VALUES);CHKERRQ(ierr); 28234f1b2e48SStefano Zampini /* store local idxs for p0 */ 28244f1b2e48SStefano Zampini pcbddc->benign_p0_lidx[s] = idxs[nzs-1]; 28254f1b2e48SStefano Zampini ierr = ISRestoreIndices(zerodiag_subs[s],&idxs);CHKERRQ(ierr); 2826339f8db1SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 28274f1b2e48SStefano Zampini } 2828339f8db1SStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2829339f8db1SStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_change,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2830a3df083aSStefano Zampini /* project if needed */ 2831a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 28321dd7afcfSStefano Zampini Mat M; 28331dd7afcfSStefano Zampini 28341dd7afcfSStefano Zampini ierr = MatPtAP(pcbddc->local_mat,pcbddc->benign_change,MAT_INITIAL_MATRIX,2.0,&M);CHKERRQ(ierr); 2835339f8db1SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 28361dd7afcfSStefano Zampini ierr = MatSeqAIJCompress(M,&pcbddc->local_mat);CHKERRQ(ierr); 28371dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 2838a3df083aSStefano Zampini } 28394f1b2e48SStefano Zampini /* store global idxs for p0 */ 28404f1b2e48SStefano Zampini ierr = ISLocalToGlobalMappingApply(pc->pmat->rmap->mapping,pcbddc->benign_n,pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2841339f8db1SStefano Zampini } 2842ca92afb2SStefano Zampini pcbddc->benign_zerodiag_subs = zerodiag_subs; 28434f1b2e48SStefano Zampini ierr = ISDestroy(&pressures);CHKERRQ(ierr); 2844b0f5fe93SStefano Zampini 2845b0f5fe93SStefano Zampini /* determines if the coarse solver will be singular or not */ 2846b0f5fe93SStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_null,1,MPIU_BOOL,MPI_LAND,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 284727b6a85dSStefano Zampini /* determines if the problem has subdomains with 0 pressure block */ 2848c69e9cc1SStefano Zampini have_null = (PetscBool)(!!pcbddc->benign_n); 284927b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2850339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2851339f8db1SStefano Zampini PetscFunctionReturn(0); 2852339f8db1SStefano Zampini } 2853339f8db1SStefano Zampini 2854015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2855efc2fbd9SStefano Zampini { 2856efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2857de9d7bd0SStefano Zampini PetscScalar *array; 2858efc2fbd9SStefano Zampini PetscErrorCode ierr; 2859efc2fbd9SStefano Zampini 2860efc2fbd9SStefano Zampini PetscFunctionBegin; 2861efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 2862efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 28634f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2864efc2fbd9SStefano Zampini } 2865de9d7bd0SStefano Zampini if (get) { 2866efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 28674f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 28684f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 2869efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 2870de9d7bd0SStefano Zampini } else { 2871de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 2872de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2873de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2874de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 2875efc2fbd9SStefano Zampini } 2876efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2877efc2fbd9SStefano Zampini } 2878efc2fbd9SStefano Zampini 2879c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 2880c263805aSStefano Zampini { 2881c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2882c263805aSStefano Zampini PetscErrorCode ierr; 2883c263805aSStefano Zampini 2884c263805aSStefano Zampini PetscFunctionBegin; 2885c263805aSStefano Zampini /* TODO: add error checking 2886c263805aSStefano Zampini - avoid nested pop (or push) calls. 2887c263805aSStefano Zampini - cannot push before pop. 28881c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2889c263805aSStefano Zampini */ 28904f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2891efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2892efc2fbd9SStefano Zampini } 2893c263805aSStefano Zampini if (pop) { 2894a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 28954f1b2e48SStefano Zampini IS is_p0; 28964f1b2e48SStefano Zampini MatReuse reuse; 2897c263805aSStefano Zampini 2898c263805aSStefano Zampini /* extract B_0 */ 28994f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 29004f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 29014f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 29024f1b2e48SStefano Zampini } 29034f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 29047dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2905c263805aSStefano Zampini /* remove rows and cols from local problem */ 2906c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 290797d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 29084f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 29094f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2910a3df083aSStefano Zampini } else { 2911a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2912a3df083aSStefano Zampini PetscScalar *vals; 2913a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2914a3df083aSStefano Zampini 2915a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2916a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2917a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 29180b5adadeSStefano Zampini PetscInt *nnz; 2919a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2920a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2921a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2922331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2923331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2924331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2925331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2926331e053bSStefano Zampini } 2927331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2928331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2929331e053bSStefano Zampini } 2930a3df083aSStefano Zampini 2931a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2932a3df083aSStefano Zampini PetscScalar *array; 2933a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2934a3df083aSStefano Zampini 2935a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2936a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2937a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2938a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2939a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2940a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2941a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2942a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2943a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2944a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2945a3df083aSStefano Zampini cum = 0; 2946a3df083aSStefano Zampini for (j=0;j<n;j++) { 294722db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2948a3df083aSStefano Zampini vals[cum] = array[j]; 2949a3df083aSStefano Zampini idxs_ins[cum] = j; 2950a3df083aSStefano Zampini cum++; 2951a3df083aSStefano Zampini } 2952a3df083aSStefano Zampini } 2953a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2954a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2955a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2956a3df083aSStefano Zampini } 2957a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2958a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2959a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2960a3df083aSStefano Zampini } 2961c263805aSStefano Zampini } else { /* push */ 2962a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 29634f1b2e48SStefano Zampini PetscInt i; 29644f1b2e48SStefano Zampini 29654f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 29664f1b2e48SStefano Zampini PetscScalar *B0_vals; 29674f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 29684f1b2e48SStefano Zampini 29694f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 29704f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 29717b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 29724f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 29734f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 29744f1b2e48SStefano Zampini } 2975c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2976c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2977a3df083aSStefano Zampini } else { 2978a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 2979a3df083aSStefano Zampini } 2980c263805aSStefano Zampini } 2981c263805aSStefano Zampini PetscFunctionReturn(0); 2982c263805aSStefano Zampini } 2983c263805aSStefano Zampini 298408122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 2985b1b3d7a2SStefano Zampini { 2986b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 298708122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 298808122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 298908122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 299008122e43SStefano Zampini PetscScalar *work,lwork; 299108122e43SStefano Zampini PetscScalar *St,*S,*eigv; 299208122e43SStefano Zampini PetscScalar *Sarray,*Starray; 2993bd2a564bSStefano Zampini PetscReal *eigs,thresh,lthresh,uthresh; 29941b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 2995f6f667cfSStefano Zampini PetscBool allocated_S_St; 299608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 299708122e43SStefano Zampini PetscReal *rwork; 299808122e43SStefano Zampini #endif 2999b1b3d7a2SStefano Zampini PetscErrorCode ierr; 3000b1b3d7a2SStefano Zampini 3001b1b3d7a2SStefano Zampini PetscFunctionBegin; 3002b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 3003af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 3004bd2a564bSStefano Zampini if (sub_schurs->n_subs && (!sub_schurs->is_symmetric)) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_SUP,"Adaptive selection not yet implemented for this matrix pencil (herm %d, symm %d, posdef %d)",sub_schurs->is_hermitian,sub_schurs->is_symmetric,sub_schurs->is_posdef); 300506a4e24aSStefano Zampini 3006fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3007fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3008fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3009fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 30101575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3011fd14bc51SStefano Zampini } 3012fd14bc51SStefano Zampini 3013e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 3014e496cd5dSStefano 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); 3015e496cd5dSStefano Zampini } 3016e496cd5dSStefano Zampini 301708122e43SStefano Zampini /* max size of subsets */ 301808122e43SStefano Zampini mss = 0; 301908122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 302008122e43SStefano Zampini PetscInt subset_size; 3021862806e4SStefano Zampini 302208122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 302308122e43SStefano Zampini mss = PetscMax(mss,subset_size); 302408122e43SStefano Zampini } 302508122e43SStefano Zampini 302608122e43SStefano Zampini /* min/max and threshold */ 302708122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 3028f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 302908122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 3030f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 3031bd2a564bSStefano Zampini if (nmin || !sub_schurs->is_posdef) { /* XXX */ 3032f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 3033f6f667cfSStefano Zampini } 303408122e43SStefano Zampini 303508122e43SStefano Zampini /* allocate lapack workspace */ 303608122e43SStefano Zampini cum = cum2 = 0; 303708122e43SStefano Zampini maxneigs = 0; 303808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 303908122e43SStefano Zampini PetscInt n,subset_size; 3040f6f667cfSStefano Zampini 304108122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 304208122e43SStefano Zampini n = PetscMin(subset_size,nmax); 30439162d606SStefano Zampini cum += subset_size; 30449162d606SStefano Zampini cum2 += subset_size*n; 304508122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 304608122e43SStefano Zampini } 304708122e43SStefano Zampini if (mss) { 3048bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 304908122e43SStefano Zampini PetscBLASInt B_itype = 1; 305008122e43SStefano Zampini PetscBLASInt B_N = mss; 30514c6709b3SStefano Zampini PetscReal zero = 0.0; 30524c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 305308122e43SStefano Zampini 305408122e43SStefano Zampini B_lwork = -1; 305508122e43SStefano Zampini S = NULL; 305608122e43SStefano Zampini St = NULL; 3057a58a30b4SStefano Zampini eigs = NULL; 3058a58a30b4SStefano Zampini eigv = NULL; 3059a58a30b4SStefano Zampini B_iwork = NULL; 3060a58a30b4SStefano Zampini B_ifail = NULL; 3061d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3062d1710679SStefano Zampini rwork = NULL; 3063d1710679SStefano Zampini #endif 30648bec7fa6SStefano Zampini thresh = 1.0; 306508122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 306608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 306708122e43SStefano 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)); 306808122e43SStefano Zampini #else 306908122e43SStefano 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)); 307008122e43SStefano Zampini #endif 307108122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 307208122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3073bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 307408122e43SStefano Zampini } else { 307508122e43SStefano Zampini lwork = 0; 307608122e43SStefano Zampini } 307708122e43SStefano Zampini 307808122e43SStefano Zampini nv = 0; 3079d62866d3SStefano 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) */ 3080d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 308108122e43SStefano Zampini } 30824c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 3083f6f667cfSStefano Zampini if (allocated_S_St) { 3084f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 3085f6f667cfSStefano Zampini } 3086f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 308708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 308808122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 308908122e43SStefano Zampini #endif 30909162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 30919162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 30929162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 309308122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 30949162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 309508122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 309608122e43SStefano Zampini 309708122e43SStefano Zampini maxneigs = 0; 309872b8c272SStefano Zampini cum = cumarray = 0; 30999162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 31009162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 3101d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 310208122e43SStefano Zampini const PetscInt *idxs; 310308122e43SStefano Zampini 3104d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 310508122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 310608122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 310708122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 310808122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 31099162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 31109162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 311108122e43SStefano Zampini } 3112d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 311308122e43SStefano Zampini } 311408122e43SStefano Zampini 311508122e43SStefano Zampini if (mss) { /* multilevel */ 311608122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 311708122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 311808122e43SStefano Zampini } 311908122e43SStefano Zampini 3120bd2a564bSStefano Zampini lthresh = pcbddc->adaptive_threshold[0]; 3121bd2a564bSStefano Zampini uthresh = pcbddc->adaptive_threshold[1]; 312208122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 312308122e43SStefano Zampini const PetscInt *idxs; 31249d54b7f4SStefano Zampini PetscReal upper,lower; 3125862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 312608122e43SStefano Zampini PetscBLASInt B_N; 3127aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 3128bd2a564bSStefano Zampini PetscBool scal = PETSC_FALSE; 312908122e43SStefano Zampini 31309d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 31319d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 3132bd2a564bSStefano Zampini lower = uthresh; 31339d54b7f4SStefano Zampini } else { 3134bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented without deluxe scaling"); 3135bd2a564bSStefano Zampini upper = 1./uthresh; 31369d54b7f4SStefano Zampini lower = 0.; 31379d54b7f4SStefano Zampini } 3138862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 3139ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 3140f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 3141bd2a564bSStefano Zampini /* this is experimental: we assume the dofs have been properly grouped to have 3142bd2a564bSStefano Zampini the diagonal blocks Schur complements either positive or negative definite (true for Stokes) */ 3143bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) { 3144bd2a564bSStefano Zampini Mat T; 3145bd2a564bSStefano Zampini 3146bd2a564bSStefano Zampini for (j=0;j<subset_size;j++) { 3147bd2a564bSStefano Zampini if (PetscRealPart(*(Sarray+cumarray+j*(subset_size+1))) < 0.0) { 3148bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Sarray+cumarray,&T);CHKERRQ(ierr); 3149bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3150bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3151bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Starray+cumarray,&T);CHKERRQ(ierr); 3152bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3153bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3154bd2a564bSStefano Zampini if (sub_schurs->change_primal_sub) { 3155bd2a564bSStefano Zampini PetscInt nz,k; 3156bd2a564bSStefano Zampini const PetscInt *idxs; 3157bd2a564bSStefano Zampini 3158bd2a564bSStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nz);CHKERRQ(ierr); 3159bd2a564bSStefano Zampini ierr = ISGetIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3160bd2a564bSStefano Zampini for (k=0;k<nz;k++) { 3161bd2a564bSStefano Zampini *( Sarray + cumarray + idxs[k]*(subset_size+1)) *= -1.0; 3162bd2a564bSStefano Zampini *(Starray + cumarray + idxs[k]*(subset_size+1)) = 0.0; 3163bd2a564bSStefano Zampini } 3164bd2a564bSStefano Zampini ierr = ISRestoreIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3165bd2a564bSStefano Zampini } 3166bd2a564bSStefano Zampini scal = PETSC_TRUE; 3167bd2a564bSStefano Zampini break; 3168bd2a564bSStefano Zampini } 3169bd2a564bSStefano Zampini } 3170bd2a564bSStefano Zampini } 3171bd2a564bSStefano Zampini 3172f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 3173bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 3174aff50787SStefano Zampini PetscInt j,k; 3175aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 3176aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 3177aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 317808122e43SStefano Zampini } 317908122e43SStefano Zampini for (j=0;j<subset_size;j++) { 3180aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 3181aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 3182aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 3183aff50787SStefano Zampini } 318408122e43SStefano Zampini } 318508122e43SStefano Zampini } else { 318608122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 318708122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 318808122e43SStefano Zampini } 31898bec7fa6SStefano Zampini } else { 3190f6f667cfSStefano Zampini S = Sarray + cumarray; 3191f6f667cfSStefano Zampini St = Starray + cumarray; 31928bec7fa6SStefano Zampini } 3193aff50787SStefano Zampini /* see if we can save some work */ 3194b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 3195aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 3196aff50787SStefano Zampini } 3197aff50787SStefano Zampini 3198b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 3199aff50787SStefano Zampini B_neigs = 0; 3200aff50787SStefano Zampini } else { 3201bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 320208122e43SStefano Zampini PetscBLASInt B_itype = 1; 3203f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 32044c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 32059552c7c7SStefano Zampini PetscInt nmin_s; 3206bd2a564bSStefano Zampini PetscBool compute_range; 3207bd2a564bSStefano Zampini 32089036ceccSStefano Zampini B_neigs = 0; 3209bd2a564bSStefano Zampini compute_range = (PetscBool)!same_data; 3210bd2a564bSStefano Zampini if (nmin >= subset_size) compute_range = PETSC_FALSE; 321108122e43SStefano Zampini 3212fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 32139036ceccSStefano Zampini PetscInt nc = 0; 3214d16cbb6bSStefano Zampini 32159036ceccSStefano Zampini if (sub_schurs->change_primal_sub) { 32169036ceccSStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nc);CHKERRQ(ierr); 32179036ceccSStefano Zampini } 32189036ceccSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %d/%d size %d count %d fid %d (range %d) (change %d).\n",i,sub_schurs->n_subs,subset_size,pcbddc->mat_graph->count[idxs[0]]+1,pcbddc->mat_graph->which_dof[idxs[0]],compute_range,nc);CHKERRQ(ierr); 3219b7ab4a40SStefano Zampini } 3220b7ab4a40SStefano Zampini 322108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3222b7ab4a40SStefano Zampini if (compute_range) { 3223d16cbb6bSStefano Zampini 3224d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 3225bd2a564bSStefano Zampini if (sub_schurs->is_posdef) { 322608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 32279d54b7f4SStefano 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)); 322808122e43SStefano Zampini #else 32299d54b7f4SStefano 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)); 323008122e43SStefano Zampini #endif 3231bd2a564bSStefano Zampini } else { /* no theory so far, but it works nicely */ 32329036ceccSStefano Zampini PetscInt recipe = 0,recipe_m = 1; 3233bd2a564bSStefano Zampini PetscReal bb[2]; 3234bd2a564bSStefano Zampini 3235bd2a564bSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe",&recipe,NULL);CHKERRQ(ierr); 3236bd2a564bSStefano Zampini switch (recipe) { 3237bd2a564bSStefano Zampini case 0: 3238bd2a564bSStefano Zampini if (scal) { bb[0] = PETSC_MIN_REAL; bb[1] = lthresh; } 3239bd2a564bSStefano Zampini else { bb[0] = uthresh; bb[1] = PETSC_MAX_REAL; } 3240bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3241bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 3242bd2a564bSStefano Zampini #else 3243bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 3244bd2a564bSStefano Zampini #endif 3245bd2a564bSStefano Zampini break; 3246bd2a564bSStefano Zampini case 1: 3247bd2a564bSStefano Zampini bb[0] = PETSC_MIN_REAL; bb[1] = lthresh*lthresh; 3248bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3249bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 3250bd2a564bSStefano Zampini #else 3251bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 3252bd2a564bSStefano Zampini #endif 3253bd2a564bSStefano Zampini if (!scal) { 32549036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 3255bd2a564bSStefano Zampini 3256aed7e7d0SStefano Zampini bb[0] = PetscMax(lthresh*lthresh,uthresh); bb[1] = PETSC_MAX_REAL; 3257bd2a564bSStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 3258bd2a564bSStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 3259bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3260bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 3261bd2a564bSStefano Zampini #else 3262bd2a564bSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 3263bd2a564bSStefano Zampini #endif 3264bd2a564bSStefano Zampini B_neigs += B_neigs2; 3265bd2a564bSStefano Zampini } 3266bd2a564bSStefano Zampini break; 32679036ceccSStefano Zampini case 2: 32689036ceccSStefano Zampini if (scal) { 32699036ceccSStefano Zampini bb[0] = PETSC_MIN_REAL; 32709036ceccSStefano Zampini bb[1] = 0; 32719036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 32729036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 32739036ceccSStefano Zampini #else 32749036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 32759036ceccSStefano Zampini #endif 32769036ceccSStefano Zampini } else { 32779036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 32789036ceccSStefano Zampini PetscBool import = PETSC_FALSE; 32799036ceccSStefano Zampini 32809036ceccSStefano Zampini lthresh = PetscMax(lthresh,0.0); 32819036ceccSStefano Zampini if (lthresh > 0.0) { 32829036ceccSStefano Zampini bb[0] = PETSC_MIN_REAL; 32839036ceccSStefano Zampini bb[1] = lthresh*lthresh; 32849036ceccSStefano Zampini 32859036ceccSStefano Zampini import = PETSC_TRUE; 32869036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 32879036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 32889036ceccSStefano Zampini #else 32899036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 32909036ceccSStefano Zampini #endif 32919036ceccSStefano Zampini } 32929036ceccSStefano Zampini bb[0] = PetscMax(lthresh*lthresh,uthresh); 32939036ceccSStefano Zampini bb[1] = PETSC_MAX_REAL; 32949036ceccSStefano Zampini if (import) { 32959036ceccSStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 32969036ceccSStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 32979036ceccSStefano Zampini } 32989036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 32999036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 33009036ceccSStefano Zampini #else 33019036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 33029036ceccSStefano Zampini #endif 33039036ceccSStefano Zampini B_neigs += B_neigs2; 33049036ceccSStefano Zampini } 33059036ceccSStefano Zampini break; 33069036ceccSStefano Zampini case 3: 33079036ceccSStefano Zampini if (scal) { 33089036ceccSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe3_min_scal",&recipe_m,NULL);CHKERRQ(ierr); 33099036ceccSStefano Zampini } else { 33109036ceccSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe3_min",&recipe_m,NULL);CHKERRQ(ierr); 33119036ceccSStefano Zampini } 33129036ceccSStefano Zampini if (!scal) { 33139036ceccSStefano Zampini bb[0] = uthresh; 33149036ceccSStefano Zampini bb[1] = PETSC_MAX_REAL; 33159036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 33169036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 33179036ceccSStefano Zampini #else 33189036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 33199036ceccSStefano Zampini #endif 33209036ceccSStefano Zampini } 33219036ceccSStefano Zampini if (recipe_m > 0 && B_N - B_neigs > 0) { 33229036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 33239036ceccSStefano Zampini 33249036ceccSStefano Zampini B_IL = 1; 33259036ceccSStefano Zampini ierr = PetscBLASIntCast(PetscMin(recipe_m,B_N - B_neigs),&B_IU);CHKERRQ(ierr); 33269036ceccSStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 33279036ceccSStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 33289036ceccSStefano Zampini #if defined(PETSC_USE_COMPLEX) 33299036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 33309036ceccSStefano Zampini #else 33319036ceccSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","I","L",&B_N,St,&B_N,S,&B_N,&lower,&upper,&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 33329036ceccSStefano Zampini #endif 33339036ceccSStefano Zampini B_neigs += B_neigs2; 33349036ceccSStefano Zampini } 33359036ceccSStefano Zampini break; 333648cebe81SStefano Zampini case 4: 333748cebe81SStefano Zampini bb[0] = PETSC_MIN_REAL; bb[1] = lthresh; 333848cebe81SStefano Zampini #if defined(PETSC_USE_COMPLEX) 333948cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 334048cebe81SStefano Zampini #else 334148cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 334248cebe81SStefano Zampini #endif 334348cebe81SStefano Zampini { 334448cebe81SStefano Zampini PetscBLASInt B_neigs2 = 0; 334548cebe81SStefano Zampini 334648cebe81SStefano Zampini bb[0] = PetscMax(lthresh+PETSC_SMALL,uthresh); bb[1] = PETSC_MAX_REAL; 334748cebe81SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 334848cebe81SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 334948cebe81SStefano Zampini #if defined(PETSC_USE_COMPLEX) 335048cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 335148cebe81SStefano Zampini #else 335248cebe81SStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","V","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs2,eigs+B_neigs,eigv+B_neigs*B_N,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 335348cebe81SStefano Zampini #endif 335448cebe81SStefano Zampini B_neigs += B_neigs2; 335548cebe81SStefano Zampini } 335648cebe81SStefano Zampini break; 335780db8efeSStefano Zampini case 5: /* same as before: first compute all eigenvalues, then filter */ 335880db8efeSStefano Zampini #if defined(PETSC_USE_COMPLEX) 335980db8efeSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","A","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,rwork,B_iwork,B_ifail,&B_ierr)); 336080db8efeSStefano Zampini #else 336180db8efeSStefano Zampini PetscStackCallBLAS("LAPACKsygvx",LAPACKsygvx_(&B_itype,"V","A","L",&B_N,St,&B_N,S,&B_N,&bb[0],&bb[1],&B_IL,&B_IU,&eps,&B_neigs,eigs,eigv,&B_N,work,&B_lwork,B_iwork,B_ifail,&B_ierr)); 336280db8efeSStefano Zampini #endif 336380db8efeSStefano Zampini { 336480db8efeSStefano Zampini PetscInt e,k,ne; 336580db8efeSStefano Zampini for (e=0,ne=0;e<B_neigs;e++) { 336680db8efeSStefano Zampini if (eigs[e] < lthresh || eigs[e] > uthresh) { 336780db8efeSStefano Zampini for (k=0;k<B_N;k++) S[ne*B_N+k] = eigv[e*B_N+k]; 336880db8efeSStefano Zampini eigs[ne] = eigs[e]; 336980db8efeSStefano Zampini ne++; 337080db8efeSStefano Zampini } 337180db8efeSStefano Zampini } 337280db8efeSStefano Zampini ierr = PetscMemcpy(eigv,S,B_N*ne*sizeof(PetscScalar));CHKERRQ(ierr); 337380db8efeSStefano Zampini B_neigs = ne; 337480db8efeSStefano Zampini } 337580db8efeSStefano Zampini break; 3376bd2a564bSStefano Zampini default: 3377bd2a564bSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Unknown recipe %D",recipe); 3378bd2a564bSStefano Zampini break; 3379bd2a564bSStefano Zampini } 3380bd2a564bSStefano Zampini } 3381bd2a564bSStefano Zampini } else if (!same_data) { /* this is just to see all the eigenvalues */ 3382d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 3383d16cbb6bSStefano Zampini B_IL = 1; 3384d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 33859d54b7f4SStefano 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)); 3386d16cbb6bSStefano Zampini #else 33879d54b7f4SStefano 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)); 3388d16cbb6bSStefano Zampini #endif 3389b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 3390b7ab4a40SStefano Zampini PetscInt k; 3391b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 3392b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 3393b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 3394b7ab4a40SStefano Zampini nmin = nmax; 3395b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 3396b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 3397b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 3398b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 3399b7ab4a40SStefano Zampini } 3400d16cbb6bSStefano Zampini } 340108122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 340208122e43SStefano Zampini if (B_ierr) { 34036c4ed002SBarry 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); 34046c4ed002SBarry 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); 34056c4ed002SBarry 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); 340608122e43SStefano Zampini } 340708122e43SStefano Zampini 340808122e43SStefano Zampini if (B_neigs > nmax) { 3409fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3410bd2a564bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax);CHKERRQ(ierr); 3411fd14bc51SStefano Zampini } 3412bd2a564bSStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = scal ? 0 : B_neigs-nmax; 341308122e43SStefano Zampini B_neigs = nmax; 341408122e43SStefano Zampini } 341508122e43SStefano Zampini 34169552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 34179552c7c7SStefano Zampini if (B_neigs < nmin_s) { 34189036ceccSStefano Zampini PetscBLASInt B_neigs2 = 0; 341908122e43SStefano Zampini 34209d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3421bd2a564bSStefano Zampini if (scal) { 3422bd2a564bSStefano Zampini B_IU = nmin_s; 3423bd2a564bSStefano Zampini B_IL = B_neigs + 1; 3424bd2a564bSStefano Zampini } else { 3425f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 34269d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 3427bd2a564bSStefano Zampini } 34289d54b7f4SStefano Zampini } else { 34299d54b7f4SStefano Zampini B_IL = B_neigs + 1; 34309d54b7f4SStefano Zampini B_IU = nmin_s; 34319d54b7f4SStefano Zampini } 3432fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3433fd14bc51SStefano 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); 3434fd14bc51SStefano Zampini } 3435bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 34361ae86dd6SStefano Zampini PetscInt j,k; 343708122e43SStefano Zampini for (j=0;j<subset_size;j++) { 34381ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 34391ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 34401ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 344108122e43SStefano Zampini } 344208122e43SStefano Zampini } 344308122e43SStefano Zampini } else { 344408122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 344508122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 344608122e43SStefano Zampini } 344708122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 344808122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 34499d54b7f4SStefano 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)); 345008122e43SStefano Zampini #else 34519d54b7f4SStefano 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)); 345208122e43SStefano Zampini #endif 345308122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 345408122e43SStefano Zampini B_neigs += B_neigs2; 345508122e43SStefano Zampini } 345608122e43SStefano Zampini if (B_ierr) { 34576c4ed002SBarry 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); 34586c4ed002SBarry 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); 34596c4ed002SBarry 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); 346008122e43SStefano Zampini } 3461fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3462ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 346308122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 346408122e43SStefano Zampini if (eigs[j] == 0.0) { 3465ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 346608122e43SStefano Zampini } else { 34679d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3468ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 34699d54b7f4SStefano Zampini } else { 34709d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 34719d54b7f4SStefano Zampini } 3472fd14bc51SStefano Zampini } 347308122e43SStefano Zampini } 347408122e43SStefano Zampini } 3475bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 3476aff50787SStefano Zampini } 34776c3e6151SStefano Zampini /* change the basis back to the original one */ 34786c3e6151SStefano Zampini if (sub_schurs->change) { 347972b8c272SStefano Zampini Mat change,phi,phit; 34806c3e6151SStefano Zampini 348103dfb2d7SStefano Zampini if (pcbddc->dbg_flag > 2) { 34826c3e6151SStefano Zampini PetscInt ii; 34836c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 34846c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 34856c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 3486684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3487684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 3488684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 3489684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3490684229deSStefano Zampini #else 34916c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 3492684229deSStefano Zampini #endif 34936c3e6151SStefano Zampini } 34946c3e6151SStefano Zampini } 34956c3e6151SStefano Zampini } 349672b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 34976c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 349872b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 34996c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 35006c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 35016c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 35026c3e6151SStefano Zampini } 35038bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 35048bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 35059162d606SStefano Zampini if (B_neigs) { 35069162d606SStefano 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); 3507fd14bc51SStefano Zampini 3508fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 35099552c7c7SStefano Zampini PetscInt ii; 35109552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 3511ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 35129552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 3513ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3514ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3515ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3516ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3517ac47001eSStefano Zampini #else 3518ac47001eSStefano 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); 3519ac47001eSStefano Zampini #endif 35209552c7c7SStefano Zampini } 35219552c7c7SStefano Zampini } 3522fd14bc51SStefano Zampini } 35239162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 35249162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 35259162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 35269162d606SStefano Zampini cum++; 352708122e43SStefano Zampini } 352808122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 352908122e43SStefano Zampini /* shift for next computation */ 353008122e43SStefano Zampini cumarray += subset_size*subset_size; 353108122e43SStefano Zampini } 3532fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3533fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3534fd14bc51SStefano Zampini } 353508122e43SStefano Zampini 353608122e43SStefano Zampini if (mss) { 353708122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 353808122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 3539f6f667cfSStefano Zampini /* destroy matrices (junk) */ 3540f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 3541f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 354208122e43SStefano Zampini } 3543f6f667cfSStefano Zampini if (allocated_S_St) { 3544f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 3545f6f667cfSStefano Zampini } 3546f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 354708122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 354808122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 354908122e43SStefano Zampini #endif 355008122e43SStefano Zampini if (pcbddc->dbg_flag) { 35511b968477SStefano Zampini PetscInt maxneigs_r; 3552b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 35539b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 355408122e43SStefano Zampini } 355508122e43SStefano Zampini PetscFunctionReturn(0); 355608122e43SStefano Zampini } 3557b1b3d7a2SStefano Zampini 3558c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 3559c8587f34SStefano Zampini { 35608629588bSStefano Zampini PetscScalar *coarse_submat_vals; 3561c8587f34SStefano Zampini PetscErrorCode ierr; 3562c8587f34SStefano Zampini 3563c8587f34SStefano Zampini PetscFunctionBegin; 3564f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 35655e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3566c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3567c8587f34SStefano Zampini 3568684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 35690fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3570684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3571c8587f34SStefano Zampini 35728629588bSStefano Zampini /* 35738629588bSStefano Zampini Setup local correction and local part of coarse basis. 35748629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 35758629588bSStefano Zampini */ 357647f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 35778629588bSStefano Zampini 35788629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 35798629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 35808629588bSStefano Zampini 35818629588bSStefano Zampini /* free */ 35828629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3583c8587f34SStefano Zampini PetscFunctionReturn(0); 3584c8587f34SStefano Zampini } 3585c8587f34SStefano Zampini 3586674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3587674ae819SStefano Zampini { 3588674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3589674ae819SStefano Zampini PetscErrorCode ierr; 3590674ae819SStefano Zampini 3591674ae819SStefano Zampini PetscFunctionBegin; 3592674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 359330368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3594674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3595785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3596674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3597f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3598f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3599785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 360063602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 360163602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3602674ae819SStefano Zampini PetscFunctionReturn(0); 3603674ae819SStefano Zampini } 3604674ae819SStefano Zampini 3605674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3606674ae819SStefano Zampini { 3607674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 36084f1b2e48SStefano Zampini PetscInt i; 3609674ae819SStefano Zampini PetscErrorCode ierr; 3610674ae819SStefano Zampini 3611674ae819SStefano Zampini PetscFunctionBegin; 36121e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 36131e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3614a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3615b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3616674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 361716909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 36181dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3619674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3620669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3621fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 36229326c5c6Sstefano_zampini ierr = PCBDDCGraphDestroy(&pcbddc->mat_graph);CHKERRQ(ierr); 36234f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 36244f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 36254f1b2e48SStefano Zampini } 3626e68a0315Sstefano_zampini pcbddc->n_local_subs = 0; 36274f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3628e68a0315Sstefano_zampini ierr = PCBDDCSubSchursDestroy(&pcbddc->sub_schurs);CHKERRQ(ierr); 3629c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 36308af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 36311c7a958bSStefano Zampini pcbddc->corner_selected = PETSC_FALSE; 3632674ae819SStefano Zampini PetscFunctionReturn(0); 3633674ae819SStefano Zampini } 3634674ae819SStefano Zampini 3635674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3636674ae819SStefano Zampini { 3637674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3638674ae819SStefano Zampini PetscErrorCode ierr; 3639674ae819SStefano Zampini 3640674ae819SStefano Zampini PetscFunctionBegin; 3641674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 364258da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3643ca92afb2SStefano Zampini PetscScalar *array; 364406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 364506656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 364658da7f69SStefano Zampini } 3647674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3648674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 364915aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 365015aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3651674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3652674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3653674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 365406656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3655674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3656674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 36578ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3658674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3659674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3660674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 36619326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_D);CHKERRQ(ierr); 36629326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 36639326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3664f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3665727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 36660e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3667f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 366870cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 366981d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 36700369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 36711dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 36724f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 36738b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3674ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3675ca92afb2SStefano Zampini PetscInt i; 3676ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3677ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3678ca92afb2SStefano Zampini } 3679ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3680ca92afb2SStefano Zampini } 36814f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3682674ae819SStefano Zampini PetscFunctionReturn(0); 3683674ae819SStefano Zampini } 3684674ae819SStefano Zampini 3685f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 36866bfb1811SStefano Zampini { 36876bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 36886bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 36896bfb1811SStefano Zampini VecType impVecType; 36904f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 36916bfb1811SStefano Zampini PetscErrorCode ierr; 36926bfb1811SStefano Zampini 36936bfb1811SStefano Zampini PetscFunctionBegin; 36944f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3695b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 36966bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3697e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3698e7b262bdSStefano Zampini /* R nodes */ 3699e7b262bdSStefano Zampini old_size = -1; 3700e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3701e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3702e7b262bdSStefano Zampini } 3703e7b262bdSStefano Zampini if (n_R != old_size) { 3704e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3705e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 37066bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 37076bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 37086bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 37096bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3710e7b262bdSStefano Zampini } 3711e7b262bdSStefano Zampini /* local primal dofs */ 3712e7b262bdSStefano Zampini old_size = -1; 3713e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3714e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3715e7b262bdSStefano Zampini } 3716e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3717e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 371883b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3719e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 37206bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3721e7b262bdSStefano Zampini } 3722e7b262bdSStefano Zampini /* local explicit constraints */ 3723e7b262bdSStefano Zampini old_size = -1; 3724e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3725e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3726e7b262bdSStefano Zampini } 3727e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3728e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 372983b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 373083b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 373183b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 373283b7ccabSStefano Zampini } 37336bfb1811SStefano Zampini PetscFunctionReturn(0); 37346bfb1811SStefano Zampini } 37356bfb1811SStefano Zampini 373647f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 373788ebb749SStefano Zampini { 373825084f0cSStefano Zampini PetscErrorCode ierr; 373925084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 374088ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 374188ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3742d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 374325084f0cSStefano Zampini /* submatrices of local problem */ 374480677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 374506656605SStefano Zampini /* submatrices of local coarse problem */ 374606656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 374725084f0cSStefano Zampini /* working matrices */ 374806656605SStefano Zampini Mat C_CR; 374925084f0cSStefano Zampini /* additional working stuff */ 375006656605SStefano Zampini PC pc_R; 3751c58f9fdbSStefano Zampini Mat F,Brhs = NULL; 37525cbda25cSStefano Zampini Vec dummy_vec; 3753c58f9fdbSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction,sparserhs; 375425084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 375506656605SStefano Zampini PetscScalar *work; 375606656605SStefano Zampini PetscInt *idx_V_B; 3757ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 375806656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 3759ffd830a3SStefano Zampini 376025084f0cSStefano Zampini /* some shortcuts to scalars */ 376106656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 376288ebb749SStefano Zampini 376388ebb749SStefano Zampini PetscFunctionBegin; 37649a962809SStefano 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"); 3765ffd830a3SStefano Zampini 3766ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3767b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 37684f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3769b371cd4fSStefano Zampini n_B = pcis->n_B; 3770b371cd4fSStefano Zampini n_D = pcis->n - n_B; 377188ebb749SStefano Zampini n_R = pcis->n - n_vertices; 377288ebb749SStefano Zampini 377388ebb749SStefano Zampini /* vertices in boundary numbering */ 3774785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 37750e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 37766c4ed002SBarry 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); 377788ebb749SStefano Zampini 377806656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3779019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 378006656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 378106656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 378206656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 378306656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 378406656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 378506656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 378606656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 378706656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 378806656605SStefano Zampini 378906656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 379006656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 37912958b453SStefano Zampini ierr = PCSetUp(pc_R);CHKERRQ(ierr); 379206656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 379306656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 379406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 3795ffd830a3SStefano Zampini lda_rhs = n_R; 3796a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 379706656605SStefano Zampini if (isLU || isILU || isCHOL) { 379806656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 3799b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 3800df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3801d62866d3SStefano Zampini MatFactorType type; 3802d62866d3SStefano Zampini 3803df4d28bfSStefano Zampini F = reuse_solver->F; 38046816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 3805d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 3806ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 380722db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 380806656605SStefano Zampini } else { 380906656605SStefano Zampini F = NULL; 381006656605SStefano Zampini } 381106656605SStefano Zampini 3812c58f9fdbSStefano Zampini /* determine if we can use a sparse right-hand side */ 3813c58f9fdbSStefano Zampini sparserhs = PETSC_FALSE; 3814c58f9fdbSStefano Zampini if (F) { 3815ea799195SBarry Smith MatSolverType solver; 3816c58f9fdbSStefano Zampini 38173ca39a21SBarry Smith ierr = MatFactorGetSolverType(F,&solver);CHKERRQ(ierr); 3818c58f9fdbSStefano Zampini ierr = PetscStrcmp(solver,MATSOLVERMUMPS,&sparserhs);CHKERRQ(ierr); 3819c58f9fdbSStefano Zampini } 3820c58f9fdbSStefano Zampini 3821ffd830a3SStefano Zampini /* allocate workspace */ 3822ffd830a3SStefano Zampini n = 0; 3823ffd830a3SStefano Zampini if (n_constraints) { 3824ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3825ffd830a3SStefano Zampini } 3826ffd830a3SStefano Zampini if (n_vertices) { 3827ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3828ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3829ffd830a3SStefano Zampini } 38302a3a6641Sstefano_zampini if (!pcbddc->symmetric_primal) { 38312a3a6641Sstefano_zampini n = PetscMax(2*lda_rhs*pcbddc->local_primal_size,n); 38322a3a6641Sstefano_zampini } 3833ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3834ffd830a3SStefano Zampini 38355cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 38365cbda25cSStefano Zampini dummy_vec = NULL; 38375cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 38385cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 38395cbda25cSStefano Zampini } 38405cbda25cSStefano Zampini 384188ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 384288ebb749SStefano Zampini if (n_constraints) { 3843837cedc9SStefano Zampini Mat M3,C_B; 384406656605SStefano Zampini IS is_aux; 384580677318SStefano Zampini PetscScalar *array,*array2; 384606656605SStefano Zampini 3847f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 384880677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 384988ebb749SStefano Zampini 385025084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 385125084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 38527dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 38537dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 385488ebb749SStefano Zampini 385580677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 385680677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 3857c58f9fdbSStefano Zampini if (!sparserhs) { 3858ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 385988ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 386006656605SStefano Zampini const PetscScalar *row_cmat_values; 386106656605SStefano Zampini const PetscInt *row_cmat_indices; 386206656605SStefano Zampini PetscInt size_of_constraint,j; 386388ebb749SStefano Zampini 386406656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 386506656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 3866ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 386706656605SStefano Zampini } 386806656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 386906656605SStefano Zampini } 3870c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&Brhs);CHKERRQ(ierr); 3871c58f9fdbSStefano Zampini } else { 3872c58f9fdbSStefano Zampini Mat tC_CR; 3873c58f9fdbSStefano Zampini 3874c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3875c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 3876c58f9fdbSStefano Zampini PetscScalar *aa; 3877c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 3878c58f9fdbSStefano Zampini PetscBool done; 3879c58f9fdbSStefano Zampini 3880c58f9fdbSStefano Zampini ierr = MatGetRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 388113903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 3882c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(C_CR,&aa);CHKERRQ(ierr); 3883c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_constraints,lda_rhs,ii,jj,aa,&tC_CR);CHKERRQ(ierr); 3884c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 388513903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 3886c58f9fdbSStefano Zampini } else { 3887c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)C_CR);CHKERRQ(ierr); 3888c58f9fdbSStefano Zampini tC_CR = C_CR; 3889c58f9fdbSStefano Zampini } 3890c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tC_CR,&Brhs);CHKERRQ(ierr); 3891c58f9fdbSStefano Zampini ierr = MatDestroy(&tC_CR);CHKERRQ(ierr); 3892c58f9fdbSStefano Zampini } 3893ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 389406656605SStefano Zampini if (F) { 3895a3df083aSStefano Zampini if (need_benign_correction) { 3896df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3897a3df083aSStefano Zampini 389872b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 389972b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 3900a3df083aSStefano Zampini } 3901c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,local_auxmat2_R);CHKERRQ(ierr); 3902a3df083aSStefano Zampini if (need_benign_correction) { 3903a3df083aSStefano Zampini PetscScalar *marr; 3904df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3905a3df083aSStefano Zampini 3906a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 39075cbda25cSStefano Zampini if (lda_rhs != n_R) { 39085cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 39095cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 39105cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 39115cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 39125cbda25cSStefano Zampini } 39135cbda25cSStefano Zampini } else { 3914a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 3915a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 39165cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3917a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3918a3df083aSStefano Zampini } 39195cbda25cSStefano Zampini } 3920a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 3921a3df083aSStefano Zampini } 392206656605SStefano Zampini } else { 392380677318SStefano Zampini PetscScalar *marr; 392480677318SStefano Zampini 392580677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 392606656605SStefano Zampini for (i=0;i<n_constraints;i++) { 3927ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3928ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 392906656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 393006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 393106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 393206656605SStefano Zampini } 393380677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 393406656605SStefano Zampini } 3935c58f9fdbSStefano Zampini if (sparserhs) { 3936c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3937c58f9fdbSStefano Zampini } 3938c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 393980677318SStefano Zampini if (!pcbddc->switch_static) { 394080677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 394180677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 394280677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 394380677318SStefano Zampini for (i=0;i<n_constraints;i++) { 3944ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 394580677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 394680677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 394780677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 394880677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 394980677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 395080677318SStefano Zampini } 395180677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 395280677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 395372b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 395480677318SStefano Zampini } else { 3955ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3956ffd830a3SStefano Zampini IS dummy; 3957ffd830a3SStefano Zampini 3958ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 39597dae84e0SHong Zhang ierr = MatCreateSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 3960ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 3961ffd830a3SStefano Zampini } else { 396280677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 396380677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 3964ffd830a3SStefano Zampini } 396525084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 396680677318SStefano Zampini } 396780677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 396880677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 396980677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 397080677318SStefano Zampini if (isCHOL) { 397180677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 397280677318SStefano Zampini } else { 397325084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 397480677318SStefano Zampini } 3975837cedc9SStefano Zampini ierr = MatSeqDenseInvertFactors_Private(M3);CHKERRQ(ierr); 397680677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 3977837cedc9SStefano Zampini ierr = MatMatMult(M3,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 397872b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 3979837cedc9SStefano Zampini ierr = MatCopy(M3,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 3980837cedc9SStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 3981f4ddd8eeSStefano Zampini } 3982fc227af8SStefano Zampini 3983fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 398488ebb749SStefano Zampini if (n_vertices) { 398506656605SStefano Zampini IS is_aux; 3986c58f9fdbSStefano Zampini PetscBool isseqaij; 39873a50541eSStefano Zampini 3988b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 39896816873aSStefano Zampini IS tis; 39906816873aSStefano Zampini 39916816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 39926816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 39936816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 39946816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 39956816873aSStefano Zampini } else { 39963a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 39976816873aSStefano Zampini } 39987dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 39997dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 4000c58f9fdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 4001c58f9fdbSStefano Zampini if (!isseqaij) { /* MatMatMult(A_VR,A_RRmA_RV) below will raise an error */ 4002c58f9fdbSStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4003c58f9fdbSStefano Zampini } 40047dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 400525084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 400688ebb749SStefano Zampini } 400788ebb749SStefano Zampini 400888ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 4009f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 401006656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 401106656605SStefano Zampini if (pcbddc->coarse_phi_D) { 401206656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 401306656605SStefano Zampini } 4014f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 401506656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 401606656605SStefano Zampini PetscScalar *marray; 401706656605SStefano Zampini 401806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 401906656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 4020f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 4021f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 4022f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 4023f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 4024f4ddd8eeSStefano Zampini } 4025f4ddd8eeSStefano Zampini } 402606656605SStefano Zampini 4027f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 4028a6e023c1Sstefano_zampini PetscScalar *marr; 402988ebb749SStefano Zampini 4030a6e023c1Sstefano_zampini /* memory size */ 403106656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 4032a6e023c1Sstefano_zampini if (pcbddc->switch_static || pcbddc->dbg_flag) n += n_D*pcbddc->local_primal_size; 4033a6e023c1Sstefano_zampini if (!pcbddc->symmetric_primal) n *= 2; 4034a6e023c1Sstefano_zampini ierr = PetscCalloc1(n,&marr);CHKERRQ(ierr); 4035a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 4036a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 40378eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4038a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 4039a6e023c1Sstefano_zampini marr += n_D*pcbddc->local_primal_size; 404088ebb749SStefano Zampini } 40413301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4042a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 4043a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 40448eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4045a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 404688ebb749SStefano Zampini } 404788ebb749SStefano Zampini } else { 4048c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 4049c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 40501b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4051c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 4052c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 4053c0553b1fSStefano Zampini } 405488ebb749SStefano Zampini } 405506656605SStefano Zampini } 4056019a44ceSStefano Zampini 405706656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 40584f1b2e48SStefano Zampini p0_lidx_I = NULL; 40594f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 4060d12edf2fSStefano Zampini const PetscInt *idxs; 4061d12edf2fSStefano Zampini 4062d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 40634f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 40644f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 40654f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 40664f1b2e48SStefano Zampini } 4067d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 4068d12edf2fSStefano Zampini } 4069d16cbb6bSStefano Zampini 407006656605SStefano Zampini /* vertices */ 407106656605SStefano Zampini if (n_vertices) { 4072c58f9fdbSStefano Zampini PetscBool restoreavr = PETSC_FALSE; 407316f15bc4SStefano Zampini 4074af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 407504708bb6SStefano Zampini 407616f15bc4SStefano Zampini if (n_R) { 407714393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 407806656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 407916f15bc4SStefano Zampini PetscScalar *x,*y; 408006656605SStefano Zampini 408121eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 408214393ed6SStefano Zampini if (need_benign_correction) { 408314393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 408414393ed6SStefano Zampini IS is_p0; 408514393ed6SStefano Zampini PetscInt *idxs_p0,n; 408614393ed6SStefano Zampini 408714393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 408814393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 408914393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 4090af25d912SStefano 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); 409114393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 409214393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 40937dae84e0SHong Zhang ierr = MatCreateSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 409414393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 409514393ed6SStefano Zampini } 409614393ed6SStefano Zampini 4097c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4098c58f9fdbSStefano Zampini if (!sparserhs || need_benign_correction) { 4099ffd830a3SStefano Zampini if (lda_rhs == n_R) { 4100af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 4101ffd830a3SStefano Zampini } else { 4102ca92afb2SStefano Zampini PetscScalar *av,*array; 4103ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 4104ca92afb2SStefano Zampini PetscInt n; 4105ca92afb2SStefano Zampini PetscBool flg_row; 4106ffd830a3SStefano Zampini 4107ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 4108ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 41099d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 4110ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4111ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 4112ca92afb2SStefano Zampini for (i=0;i<n;i++) { 4113ca92afb2SStefano Zampini PetscInt j; 4114ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 4115ffd830a3SStefano Zampini } 4116ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4117ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4118ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 4119ffd830a3SStefano Zampini } 4120a3df083aSStefano Zampini if (need_benign_correction) { 4121df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4122a3df083aSStefano Zampini PetscScalar *marr; 4123a3df083aSStefano Zampini 4124a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 412514393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 412614393ed6SStefano Zampini 412714393ed6SStefano Zampini | 0 0 0 | (V) 412814393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 412914393ed6SStefano Zampini | 0 0 -1 | (p0) 413014393ed6SStefano Zampini 413114393ed6SStefano Zampini */ 4132df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 413314393ed6SStefano Zampini const PetscScalar *vals; 413414393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 413514393ed6SStefano Zampini PetscInt n,j,nz; 413614393ed6SStefano Zampini 4137df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4138df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 413914393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 414014393ed6SStefano Zampini for (j=0;j<n;j++) { 414114393ed6SStefano Zampini PetscScalar val = vals[j]; 414214393ed6SStefano Zampini PetscInt k,col = idxs[j]; 414314393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 414414393ed6SStefano Zampini } 414514393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4146df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 414714393ed6SStefano Zampini } 414872b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 414972b8c272SStefano Zampini } 4150c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RV);CHKERRQ(ierr); 4151c58f9fdbSStefano Zampini Brhs = A_RV; 4152c58f9fdbSStefano Zampini } else { 4153c58f9fdbSStefano Zampini Mat tA_RVT,A_RVT; 4154c58f9fdbSStefano Zampini 4155c58f9fdbSStefano Zampini if (!pcbddc->symmetric_primal) { 4156fb6280fbSStefano Zampini /* A_RV already scaled by -1 */ 4157c58f9fdbSStefano Zampini ierr = MatTranspose(A_RV,MAT_INITIAL_MATRIX,&A_RVT);CHKERRQ(ierr); 4158c58f9fdbSStefano Zampini } else { 4159c58f9fdbSStefano Zampini restoreavr = PETSC_TRUE; 4160c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4161c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_VR);CHKERRQ(ierr); 4162c58f9fdbSStefano Zampini A_RVT = A_VR; 4163c58f9fdbSStefano Zampini } 4164c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 4165c58f9fdbSStefano Zampini PetscScalar *aa; 4166c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 4167c58f9fdbSStefano Zampini PetscBool done; 4168c58f9fdbSStefano Zampini 4169c58f9fdbSStefano Zampini ierr = MatGetRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 417013903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 4171c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(A_RVT,&aa);CHKERRQ(ierr); 4172c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_vertices,lda_rhs,ii,jj,aa,&tA_RVT);CHKERRQ(ierr); 4173c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 417413903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 4175c58f9fdbSStefano Zampini } else { 4176c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RVT);CHKERRQ(ierr); 4177c58f9fdbSStefano Zampini tA_RVT = A_RVT; 4178c58f9fdbSStefano Zampini } 4179c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tA_RVT,&Brhs);CHKERRQ(ierr); 4180c58f9fdbSStefano Zampini ierr = MatDestroy(&tA_RVT);CHKERRQ(ierr); 4181c58f9fdbSStefano Zampini ierr = MatDestroy(&A_RVT);CHKERRQ(ierr); 4182c58f9fdbSStefano Zampini } 418372b8c272SStefano Zampini if (F) { 418414393ed6SStefano Zampini /* need to correct the rhs */ 418572b8c272SStefano Zampini if (need_benign_correction) { 418672b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 418772b8c272SStefano Zampini PetscScalar *marr; 418872b8c272SStefano Zampini 4189c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&marr);CHKERRQ(ierr); 41905cbda25cSStefano Zampini if (lda_rhs != n_R) { 41915cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 41925cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 41935cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 41945cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 41955cbda25cSStefano Zampini } 41965cbda25cSStefano Zampini } else { 4197a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4198a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 41995cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 4200a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4201a3df083aSStefano Zampini } 42025cbda25cSStefano Zampini } 4203c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&marr);CHKERRQ(ierr); 4204a3df083aSStefano Zampini } 4205c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,A_RRmA_RV);CHKERRQ(ierr); 4206c58f9fdbSStefano Zampini if (restoreavr) { 4207c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4208c58f9fdbSStefano Zampini } 420914393ed6SStefano Zampini /* need to correct the solution */ 4210a3df083aSStefano Zampini if (need_benign_correction) { 4211df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4212a3df083aSStefano Zampini PetscScalar *marr; 4213a3df083aSStefano Zampini 4214a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 42155cbda25cSStefano Zampini if (lda_rhs != n_R) { 42165cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 42175cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 42185cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 42195cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 42205cbda25cSStefano Zampini } 42215cbda25cSStefano Zampini } else { 4222a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4223a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 42245cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 4225a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4226a3df083aSStefano Zampini } 42275cbda25cSStefano Zampini } 4228a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 4229a3df083aSStefano Zampini } 423006656605SStefano Zampini } else { 4231c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&y);CHKERRQ(ierr); 423206656605SStefano Zampini for (i=0;i<n_vertices;i++) { 4233ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 4234ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 423506656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 423606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 423706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 423806656605SStefano Zampini } 4239c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&y);CHKERRQ(ierr); 424006656605SStefano Zampini } 424180677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4242c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 4243ffd830a3SStefano Zampini /* S_VV and S_CV */ 424406656605SStefano Zampini if (n_constraints) { 424506656605SStefano Zampini Mat B; 424680677318SStefano Zampini 4247ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 424880677318SStefano Zampini for (i=0;i<n_vertices;i++) { 4249ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 4250ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 425180677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 425280677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 425380677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 425480677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 425580677318SStefano Zampini } 4256ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 425780677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 425880677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 4259ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 426080677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 426106656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 4262ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 4263ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 426406656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 426506656605SStefano Zampini } 4266ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4267ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 4268ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4269ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 4270ffd830a3SStefano Zampini } 427106656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 427214393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 427314393ed6SStefano Zampini if (need_benign_correction) { 4274df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 427514393ed6SStefano Zampini PetscScalar *marr,*sums; 427614393ed6SStefano Zampini 427714393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 4278f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 4279df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 428014393ed6SStefano Zampini const PetscScalar *vals; 428114393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 428214393ed6SStefano Zampini PetscInt n,j,nz; 428314393ed6SStefano Zampini 4284df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4285df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 428614393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 428714393ed6SStefano Zampini PetscInt k; 428814393ed6SStefano Zampini sums[j] = 0.; 428914393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 429014393ed6SStefano Zampini } 429114393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 429214393ed6SStefano Zampini for (j=0;j<n;j++) { 429314393ed6SStefano Zampini PetscScalar val = vals[j]; 429414393ed6SStefano Zampini PetscInt k; 429514393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 429614393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 429714393ed6SStefano Zampini } 429814393ed6SStefano Zampini } 429914393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4300df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 430114393ed6SStefano Zampini } 430214393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 4303f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 430414393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 430514393ed6SStefano Zampini } 430680677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 430706656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 430806656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 430906656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 431006656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 431106656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 431206656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 431306656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4314d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 4315019a44ceSStefano Zampini } else { 4316d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4317d16cbb6bSStefano Zampini } 431821eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 4319d16cbb6bSStefano Zampini 432006656605SStefano Zampini /* coarse basis functions */ 432106656605SStefano Zampini for (i=0;i<n_vertices;i++) { 432216f15bc4SStefano Zampini PetscScalar *y; 432316f15bc4SStefano Zampini 4324ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 432506656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 432606656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 432706656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 432806656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 432906656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 433006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 433106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 433206656605SStefano Zampini 433306656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 43344f1b2e48SStefano Zampini PetscInt j; 43354f1b2e48SStefano Zampini 433606656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 433706656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 433806656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 433906656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 434006656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 43414f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 434206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 434306656605SStefano Zampini } 434406656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 434506656605SStefano Zampini } 434604708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 434704708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 434806656605SStefano Zampini } 43495cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 435006656605SStefano Zampini 435106656605SStefano Zampini if (n_constraints) { 435206656605SStefano Zampini Mat B; 435306656605SStefano Zampini 4354ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 435506656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 435680677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 435706656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 435806656605SStefano Zampini if (n_vertices) { 435903dfb2d7SStefano Zampini if (isCHOL || need_benign_correction) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 436080677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 436180677318SStefano Zampini } else { 436280677318SStefano Zampini Mat S_VCt; 436380677318SStefano Zampini 4364ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4365ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 436672b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 4367ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 4368ffd830a3SStefano Zampini } 436980677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 437080677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 437180677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 437280677318SStefano Zampini } 437306656605SStefano Zampini } 437406656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 437506656605SStefano Zampini /* coarse basis functions */ 437606656605SStefano Zampini for (i=0;i<n_constraints;i++) { 437706656605SStefano Zampini PetscScalar *y; 437806656605SStefano Zampini 4379ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 438006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 438106656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 438206656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 438306656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 438406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 438506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 438606656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 43874f1b2e48SStefano Zampini PetscInt j; 43884f1b2e48SStefano Zampini 438906656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 439006656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 439106656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 439206656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 439306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 43944f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 439506656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 439606656605SStefano Zampini } 439706656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 439806656605SStefano Zampini } 439906656605SStefano Zampini } 440080677318SStefano Zampini if (n_constraints) { 440180677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 440280677318SStefano Zampini } 44034f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 440472b8c272SStefano Zampini 440572b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 440672b8c272SStefano Zampini if (pcbddc->benign_n) { 440772b8c272SStefano Zampini Mat B0_B,B0_BPHI; 440872b8c272SStefano Zampini IS is_dummy; 440972b8c272SStefano Zampini PetscScalar *data; 441072b8c272SStefano Zampini PetscInt j; 441172b8c272SStefano Zampini 441272b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 44137dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 441472b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 441572b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 441686c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 441772b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 441872b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 441972b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 442072b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 442172b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 442272b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 442372b8c272SStefano Zampini } 442472b8c272SStefano Zampini } 442572b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 442672b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 442772b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 442872b8c272SStefano Zampini } 4429019a44ceSStefano Zampini 443006656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 44313301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4432ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 4433ffd830a3SStefano Zampini PetscScalar *marray; 443406656605SStefano Zampini 443506656605SStefano Zampini if (n_constraints) { 4436ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 443706656605SStefano Zampini 4438abc8f43dSstefano_zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 443906656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 4440ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 444116f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 444206656605SStefano Zampini if (n_vertices) { 4443ffd830a3SStefano Zampini Mat S_VCT; 444406656605SStefano Zampini 444506656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 4446ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 444716f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 444806656605SStefano Zampini } 4449ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 44505b782168SStefano Zampini } else { 44515b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 445206656605SStefano Zampini } 445316f15bc4SStefano Zampini if (n_vertices && n_R) { 4454ffd830a3SStefano Zampini PetscScalar *av,*marray; 4455ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 4456ffd830a3SStefano Zampini PetscInt n; 4457ffd830a3SStefano Zampini PetscBool flg_row; 445806656605SStefano Zampini 4459ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 4460af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4461ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4462ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 4463ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4464ffd830a3SStefano Zampini for (i=0;i<n;i++) { 4465ffd830a3SStefano Zampini PetscInt j; 4466ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 4467ffd830a3SStefano Zampini } 4468ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4469ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4470ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 447106656605SStefano Zampini } 447206656605SStefano Zampini 4473ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 4474abc8f43dSstefano_zampini if (n_vertices) { 4475ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4476ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 4477ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 4478ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 447906656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 448006656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 448106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 448206656605SStefano Zampini } 4483ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4484abc8f43dSstefano_zampini } 44855b782168SStefano Zampini if (B_C) { 4486ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 4487ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 4488ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 4489ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 4490ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4491ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4492ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 449306656605SStefano Zampini } 4494ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 44955b782168SStefano Zampini } 449606656605SStefano Zampini /* coarse basis functions */ 449706656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 449806656605SStefano Zampini PetscScalar *y; 449906656605SStefano Zampini 4500ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 450106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 450206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 450306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 450406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 450506656605SStefano Zampini if (i<n_vertices) { 450606656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 450706656605SStefano Zampini } 450806656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 450906656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 451006656605SStefano Zampini 451106656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 451206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 451306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 451406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 451506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 451606656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 451706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 451806656605SStefano Zampini } 451906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 452006656605SStefano Zampini } 4521ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 4522ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 452306656605SStefano Zampini } 4524a6e023c1Sstefano_zampini 4525d62866d3SStefano Zampini /* free memory */ 452688ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 452706656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 452806656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 452906656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 453006656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 4531d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4532d62866d3SStefano Zampini if (n_vertices) { 4533d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 4534d62866d3SStefano Zampini } 4535d62866d3SStefano Zampini if (n_constraints) { 4536d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 4537d62866d3SStefano Zampini } 453888ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 453988ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 454088ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 4541d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 454288ebb749SStefano Zampini Mat coarse_sub_mat; 454325084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 454488ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 454588ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 454688ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 45478bec7fa6SStefano Zampini Mat C_B,CPHI; 45488bec7fa6SStefano Zampini IS is_dummy; 45498bec7fa6SStefano Zampini Vec mones; 455088ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 455188ebb749SStefano Zampini PetscReal real_value; 455288ebb749SStefano Zampini 4553a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 4554a3df083aSStefano Zampini Mat A; 4555a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 45567dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 45577dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 45587dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 45597dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4560a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 4561a3df083aSStefano Zampini } else { 456288ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 456388ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 456488ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 456588ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4566a3df083aSStefano Zampini } 456788ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 456888ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 4569ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 457088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 457188ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 457288ebb749SStefano Zampini } 457388ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 457488ebb749SStefano Zampini 457525084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 45763301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 457725084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4578ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 457988ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 458088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 458188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 458288ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 458388ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 458488ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 458588ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 458688ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 458788ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 458888ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 458988ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 459088ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 459188ebb749SStefano Zampini } else { 459288ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 459388ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 459488ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 459588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 459688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 459788ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 459888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 459988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 460088ebb749SStefano Zampini } 460188ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 460288ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 460388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 4604511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 46054f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4606fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 4607d12edf2fSStefano Zampini PetscScalar *data,*data2; 46084f1b2e48SStefano Zampini PetscInt j; 4609d12edf2fSStefano Zampini 46104f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 46117dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 4612d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 461386c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 4614d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 4615d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 46164f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 46174f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 4618d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 46194f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 46204f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 46214f1b2e48SStefano Zampini } 4622d12edf2fSStefano Zampini } 4623d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 4624d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 4625d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4626d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4627d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4628d12edf2fSStefano Zampini } 4629d12edf2fSStefano Zampini #if 0 4630d12edf2fSStefano Zampini { 4631d12edf2fSStefano Zampini PetscViewer viewer; 4632d12edf2fSStefano Zampini char filename[256]; 4633ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4634d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4635a7414863SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4636ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4637ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4638ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4639d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 4640a7414863SStefano Zampini if (pcbddc->coarse_phi_B) { 4641ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4642ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 464372b8c272SStefano Zampini } 4644ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4645ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4646ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4647ffd830a3SStefano Zampini } 4648ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4649ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4650ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4651ffd830a3SStefano Zampini } 465272b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4653ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4654ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4655ffd830a3SStefano Zampini } 4656fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->local_mat,"A");CHKERRQ(ierr); 4657fb6280fbSStefano Zampini ierr = MatView(pcbddc->local_mat,viewer);CHKERRQ(ierr); 4658fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->ConstraintMatrix,"C");CHKERRQ(ierr); 4659fb6280fbSStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,viewer);CHKERRQ(ierr); 4660fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_I_local,"I");CHKERRQ(ierr); 4661fb6280fbSStefano Zampini ierr = ISView(pcis->is_I_local,viewer);CHKERRQ(ierr); 4662fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_B_local,"B");CHKERRQ(ierr); 4663fb6280fbSStefano Zampini ierr = ISView(pcis->is_B_local,viewer);CHKERRQ(ierr); 4664fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->is_R_local,"R");CHKERRQ(ierr); 4665fb6280fbSStefano Zampini ierr = ISView(pcbddc->is_R_local,viewer);CHKERRQ(ierr); 4666d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4667d12edf2fSStefano Zampini } 4668d12edf2fSStefano Zampini #endif 466981d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 46708bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 46711575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 467206656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 46738bec7fa6SStefano Zampini 46748bec7fa6SStefano Zampini /* check constraints */ 4675a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 46767dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 46774f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 46788bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4679a00504b5SStefano Zampini } else { 4680a00504b5SStefano Zampini PetscScalar *data; 4681a00504b5SStefano Zampini Mat tmat; 4682a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4683a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4684a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4685a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4686a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4687a00504b5SStefano Zampini } 46888bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 46898bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 46908bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 46918bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4692bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4693ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4694bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4695bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4696bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4697bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4698bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 469988ebb749SStefano Zampini } 47008bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 47018bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 47028bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 47038bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 470425084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 470588ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 470688ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 470788ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 470888ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 470988ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 471088ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 471188ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 471288ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 471388ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 471488ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4715ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 471688ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 471788ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 471888ebb749SStefano Zampini } 471988ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 472088ebb749SStefano Zampini } 47218629588bSStefano Zampini /* get back data */ 47228629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 472388ebb749SStefano Zampini PetscFunctionReturn(0); 472488ebb749SStefano Zampini } 472588ebb749SStefano Zampini 47267dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4727aa0d41d4SStefano Zampini { 4728d65f70fdSStefano Zampini Mat *work_mat; 4729d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4730d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4731c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4732aa0d41d4SStefano Zampini PetscErrorCode ierr; 4733aa0d41d4SStefano Zampini 4734aa0d41d4SStefano Zampini PetscFunctionBegin; 4735d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4736d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4737d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4738d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4739aa0d41d4SStefano Zampini 4740d65f70fdSStefano Zampini if (!rsorted) { 4741906d46d4SStefano Zampini const PetscInt *idxs; 4742906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4743aa0d41d4SStefano Zampini 4744d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4745d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4746d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4747d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4748aa0d41d4SStefano Zampini } 4749d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4750d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4751d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4752d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4753aa0d41d4SStefano Zampini } 4754d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4755d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4756d65f70fdSStefano Zampini } else { 4757d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4758d65f70fdSStefano Zampini isrow_s = isrow; 4759aa0d41d4SStefano Zampini } 4760906d46d4SStefano Zampini 4761d65f70fdSStefano Zampini if (!csorted) { 4762d65f70fdSStefano Zampini if (isrow == iscol) { 4763d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4764d65f70fdSStefano Zampini iscol_s = isrow_s; 4765d65f70fdSStefano Zampini } else { 4766d65f70fdSStefano Zampini const PetscInt *idxs; 4767d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4768906d46d4SStefano Zampini 4769d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4770d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4771d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4772d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4773d65f70fdSStefano Zampini } 4774d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 4775d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 4776d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4777d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 4778d65f70fdSStefano Zampini } 4779d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 4780d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 4781d65f70fdSStefano Zampini } 4782d65f70fdSStefano Zampini } else { 4783d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 4784d65f70fdSStefano Zampini iscol_s = iscol; 4785d65f70fdSStefano Zampini } 4786d65f70fdSStefano Zampini 47877dae84e0SHong Zhang ierr = MatCreateSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4788d65f70fdSStefano Zampini 4789d65f70fdSStefano Zampini if (!rsorted || !csorted) { 4790906d46d4SStefano Zampini Mat new_mat; 4791d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 4792906d46d4SStefano Zampini 4793d65f70fdSStefano Zampini if (!rsorted) { 4794d65f70fdSStefano Zampini PetscInt *idxs_r,i; 4795d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 4796d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4797d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 4798906d46d4SStefano Zampini } 4799d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 4800d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 4801d65f70fdSStefano Zampini } else { 4802d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 4803906d46d4SStefano Zampini } 4804d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 4805d65f70fdSStefano Zampini 4806d65f70fdSStefano Zampini if (!csorted) { 4807d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 4808d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 4809d65f70fdSStefano Zampini is_perm_c = is_perm_r; 4810d65f70fdSStefano Zampini } else { 4811d65f70fdSStefano Zampini PetscInt *idxs_c,i; 4812f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 4813d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 4814d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4815d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 4816d65f70fdSStefano Zampini } 4817d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 4818d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 4819d65f70fdSStefano Zampini } 4820d65f70fdSStefano Zampini } else { 4821d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 4822d65f70fdSStefano Zampini } 4823d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 4824d65f70fdSStefano Zampini 4825d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 4826d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 4827d65f70fdSStefano Zampini work_mat[0] = new_mat; 4828d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 4829d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 4830d65f70fdSStefano Zampini } 4831d65f70fdSStefano Zampini 4832d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 4833d65f70fdSStefano Zampini *B = work_mat[0]; 4834d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 4835d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 4836d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 4837d65f70fdSStefano Zampini PetscFunctionReturn(0); 4838d65f70fdSStefano Zampini } 4839d65f70fdSStefano Zampini 48405e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 4841aa0d41d4SStefano Zampini { 4842aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 48435e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4844022d8d2bSstefano_zampini Mat new_mat,lA; 48455e8657edSStefano Zampini IS is_local,is_global; 4846d65f70fdSStefano Zampini PetscInt local_size; 4847d65f70fdSStefano Zampini PetscBool isseqaij; 4848aa0d41d4SStefano Zampini PetscErrorCode ierr; 4849aa0d41d4SStefano Zampini 4850aa0d41d4SStefano Zampini PetscFunctionBegin; 4851aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 48525e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 48535e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 4854b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 4855aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 48567dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 4857aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 4858906d46d4SStefano Zampini 4859906d46d4SStefano Zampini /* check */ 4860906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4861906d46d4SStefano Zampini Vec x,x_change; 4862906d46d4SStefano Zampini PetscReal error; 4863906d46d4SStefano Zampini 48645e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 4865906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 48665e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 4867e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4868e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4869d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 487088428137SStefano Zampini if (!pcbddc->change_interior) { 487188428137SStefano Zampini const PetscScalar *x,*y,*v; 487288428137SStefano Zampini PetscReal lerror = 0.; 487388428137SStefano Zampini PetscInt i; 487488428137SStefano Zampini 487588428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 487688428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 487788428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 487888428137SStefano Zampini for (i=0;i<local_size;i++) 487988428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 488088428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 488188428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 488288428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 488388428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 488488428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4885637e8532SStefano Zampini if (error > PETSC_SMALL) { 4886637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4887637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on I: %1.6e\n",error); 4888637e8532SStefano Zampini } else { 4889637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on I: %1.6e\n",error); 4890637e8532SStefano Zampini } 4891637e8532SStefano Zampini } 489288428137SStefano Zampini } 4893e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4894e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4895906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4896906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4897637e8532SStefano Zampini if (error > PETSC_SMALL) { 4898637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4899637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 4900637e8532SStefano Zampini } else { 4901637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on N: %1.6e\n",error); 4902637e8532SStefano Zampini } 4903637e8532SStefano Zampini } 4904906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4905906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4906906d46d4SStefano Zampini } 4907906d46d4SStefano Zampini 4908022d8d2bSstefano_zampini /* lA is present if we are setting up an inner BDDC for a saddle point FETI-DP */ 4909022d8d2bSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 4910022d8d2bSstefano_zampini 491122d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 49129b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 491322d5777bSStefano Zampini if (isseqaij) { 4914a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4915a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 4916022d8d2bSstefano_zampini if (lA) { 4917022d8d2bSstefano_zampini Mat work; 4918022d8d2bSstefano_zampini ierr = MatPtAP(lA,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4919022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4920022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4921022d8d2bSstefano_zampini } 4922aa0d41d4SStefano Zampini } else { 4923a00504b5SStefano Zampini Mat work_mat; 49241cf9b237SStefano Zampini 4925a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4926aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4927a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 49281d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 4929022d8d2bSstefano_zampini if (lA) { 4930022d8d2bSstefano_zampini Mat work; 4931022d8d2bSstefano_zampini ierr = MatConvert(lA,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4932022d8d2bSstefano_zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4933022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4934022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4935022d8d2bSstefano_zampini } 4936aa0d41d4SStefano Zampini } 49373301b35fSStefano Zampini if (matis->A->symmetric_set) { 49383301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 4939e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 49403301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 4941e496cd5dSStefano Zampini #endif 49423301b35fSStefano Zampini } 4943d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 4944aa0d41d4SStefano Zampini PetscFunctionReturn(0); 4945aa0d41d4SStefano Zampini } 4946aa0d41d4SStefano Zampini 49478ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 4948a64d13efSStefano Zampini { 4949a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4950a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4951d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 495253892102SStefano Zampini PetscInt *idx_R_local=NULL; 49533a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 49543a50541eSStefano Zampini PetscInt vbs,bs; 49556816873aSStefano Zampini PetscBT bitmask=NULL; 4956a64d13efSStefano Zampini PetscErrorCode ierr; 4957a64d13efSStefano Zampini 4958a64d13efSStefano Zampini PetscFunctionBegin; 4959b23d619eSStefano Zampini /* 4960b23d619eSStefano Zampini No need to setup local scatters if 4961b23d619eSStefano Zampini - primal space is unchanged 4962b23d619eSStefano Zampini AND 4963b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 4964b23d619eSStefano Zampini AND 4965b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 4966b23d619eSStefano Zampini */ 4967b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 4968f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 4969f4ddd8eeSStefano Zampini } 4970f4ddd8eeSStefano Zampini /* destroy old objects */ 4971f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 4972f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 4973f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 4974a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 4975b371cd4fSStefano Zampini n_B = pcis->n_B; 4976b371cd4fSStefano Zampini n_D = pcis->n - n_B; 4977b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 49783a50541eSStefano Zampini 4979a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 49806816873aSStefano Zampini 498153892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 4982b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4983854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 4984a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 4985a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 49860e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 4987a64d13efSStefano Zampini } 4988a64d13efSStefano Zampini 4989a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 49904641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 49916816873aSStefano Zampini idx_R_local[n_R++] = i; 4992a64d13efSStefano Zampini } 4993a64d13efSStefano Zampini } 4994df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 4995df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 49966816873aSStefano Zampini 4997df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4998df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 49996816873aSStefano Zampini } 50003a50541eSStefano Zampini 50013a50541eSStefano Zampini /* Block code */ 50023a50541eSStefano Zampini vbs = 1; 50033a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 50043a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 50053a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 50063a50541eSStefano Zampini PetscInt *vary; 5007b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 5008785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 50093a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 5010d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 5011d3df7717SStefano 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 */ 50120e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 5013d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 50143a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 50153a50541eSStefano Zampini is_blocked = PETSC_FALSE; 50163a50541eSStefano Zampini break; 50173a50541eSStefano Zampini } 50183a50541eSStefano Zampini } 5019d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 5020d3df7717SStefano Zampini } else { 5021d3df7717SStefano Zampini /* Verify directly the R set */ 5022d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 5023d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 5024d3df7717SStefano Zampini for (j=1; j<bs; j++) { 5025d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 5026d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 5027d3df7717SStefano Zampini break; 5028d3df7717SStefano Zampini } 5029d3df7717SStefano Zampini } 5030d3df7717SStefano Zampini } 5031d3df7717SStefano Zampini } 50323a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 50333a50541eSStefano Zampini vbs = bs; 50343a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 50353a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 50363a50541eSStefano Zampini } 50373a50541eSStefano Zampini } 50383a50541eSStefano Zampini } 50393a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 5040b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5041df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 504253892102SStefano Zampini 5043df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5044df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 504553892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 5046df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 504753892102SStefano Zampini } else { 50483a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 504953892102SStefano Zampini } 5050a64d13efSStefano Zampini 5051a64d13efSStefano Zampini /* print some info if requested */ 5052a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 5053a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5054a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 50551575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5056a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 5057a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 50584f1b2e48SStefano 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); 5059a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5060a64d13efSStefano Zampini } 5061a64d13efSStefano Zampini 5062a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 5063b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 50646816873aSStefano Zampini IS is_aux1,is_aux2; 50656816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 50666816873aSStefano Zampini 50673a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5068854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 5069854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 5070a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 50714641a718SStefano Zampini for (i=0; i<n_D; i++) { 50724641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 50734641a718SStefano Zampini } 5074a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5075a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 50764641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 50774641a718SStefano Zampini aux_array1[j++] = i; 5078a64d13efSStefano Zampini } 5079a64d13efSStefano Zampini } 5080a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 5081a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5082a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 50834641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 50844641a718SStefano Zampini aux_array2[j++] = i; 5085a64d13efSStefano Zampini } 5086a64d13efSStefano Zampini } 5087a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5088a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 5089a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 5090a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 5091a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 5092a64d13efSStefano Zampini 50938eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 5094785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 5095a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 50964641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 50974641a718SStefano Zampini aux_array1[j++] = i; 5098a64d13efSStefano Zampini } 5099a64d13efSStefano Zampini } 5100a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 5101a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 5102a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 5103a64d13efSStefano Zampini } 51044641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 51053a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 5106d62866d3SStefano Zampini } else { 5107df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 51086816873aSStefano Zampini IS tis; 51096816873aSStefano Zampini PetscInt schur_size; 51106816873aSStefano Zampini 5111df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 51126816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 5113df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 51146816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 51156816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 51166816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 51176816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 51186816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 5119d62866d3SStefano Zampini } 5120d62866d3SStefano Zampini } 5121a64d13efSStefano Zampini PetscFunctionReturn(0); 5122a64d13efSStefano Zampini } 5123a64d13efSStefano Zampini 5124304d26faSStefano Zampini 5125684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 5126304d26faSStefano Zampini { 5127304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5128304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 5129304d26faSStefano Zampini PC pc_temp; 5130304d26faSStefano Zampini Mat A_RR; 5131f4ddd8eeSStefano Zampini MatReuse reuse; 5132304d26faSStefano Zampini PetscScalar m_one = -1.0; 5133304d26faSStefano Zampini PetscReal value; 513404708bb6SStefano Zampini PetscInt n_D,n_R; 513535529e7bSStefano Zampini PetscBool check_corr,issbaij; 5136304d26faSStefano Zampini PetscErrorCode ierr; 5137e604994aSStefano Zampini /* prefixes stuff */ 5138312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 5139e604994aSStefano Zampini size_t len; 5140304d26faSStefano Zampini 5141304d26faSStefano Zampini PetscFunctionBegin; 5142304d26faSStefano Zampini 5143e604994aSStefano Zampini /* compute prefixes */ 5144e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 5145e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 5146e604994aSStefano Zampini if (!pcbddc->current_level) { 5147a126751eSBarry Smith ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,sizeof(dir_prefix));CHKERRQ(ierr); 5148a126751eSBarry Smith ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,sizeof(neu_prefix));CHKERRQ(ierr); 5149a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,"pc_bddc_dirichlet_",sizeof(dir_prefix));CHKERRQ(ierr); 5150a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,"pc_bddc_neumann_",sizeof(neu_prefix));CHKERRQ(ierr); 5151e604994aSStefano Zampini } else { 515235529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 5153e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5154e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 5155312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5156312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 5157a126751eSBarry Smith /* Nonstandard use of PetscStrncpy() to only copy a portion of the input string */ 515834d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 515934d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5160a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,"pc_bddc_dirichlet_",sizeof(dir_prefix));CHKERRQ(ierr); 5161a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,"pc_bddc_neumann_",sizeof(neu_prefix));CHKERRQ(ierr); 5162a126751eSBarry Smith ierr = PetscStrlcat(dir_prefix,str_level,sizeof(dir_prefix));CHKERRQ(ierr); 5163a126751eSBarry Smith ierr = PetscStrlcat(neu_prefix,str_level,sizeof(neu_prefix));CHKERRQ(ierr); 5164e604994aSStefano Zampini } 5165e604994aSStefano Zampini 5166304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 5167684f6988SStefano Zampini if (dirichlet) { 5168d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5169450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 51709a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 5171450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 5172a3df083aSStefano Zampini Mat A_IIn; 5173a3df083aSStefano Zampini 5174a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 5175a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 5176a3df083aSStefano Zampini pcis->A_II = A_IIn; 5177a3df083aSStefano Zampini } 5178450f8f5eSStefano Zampini } 51793301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 51803301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 5181964fefecSStefano Zampini } 5182ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 5183964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 5184304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 5185cd18cfedSStefano Zampini void (*f)(void) = 0; 5186cd18cfedSStefano Zampini 5187304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 5188304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 5189304d26faSStefano Zampini /* default */ 5190304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 5191e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 51929577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 5193304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 51949577ea80SStefano Zampini if (issbaij) { 51959577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 51969577ea80SStefano Zampini } else { 5197304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 51989577ea80SStefano Zampini } 5199304d26faSStefano Zampini /* Allow user's customization */ 5200304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 5201cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 5202cd18cfedSStefano Zampini if (f && pcbddc->mat_graph->cloc) { 5203cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5204cd18cfedSStefano Zampini const PetscInt *idxs; 5205cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5206cd18cfedSStefano Zampini 5207cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcis->is_I_local,&nl);CHKERRQ(ierr); 5208cd18cfedSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5209cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5210cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5211cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5212cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5213cd18cfedSStefano Zampini } 5214cd18cfedSStefano Zampini } 5215cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5216cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5217cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5218cd18cfedSStefano Zampini } 5219304d26faSStefano Zampini } 5220d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 5221b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5222df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5223d62866d3SStefano Zampini 5224df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 5225d5574798SStefano Zampini } 5226304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5227304d26faSStefano Zampini if (!n_D) { 5228304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 5229304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5230304d26faSStefano Zampini } 5231304d26faSStefano Zampini /* set ksp_D into pcis data */ 5232304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 5233304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 5234304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 5235684f6988SStefano Zampini } 5236304d26faSStefano Zampini 5237304d26faSStefano Zampini /* NEUMANN PROBLEM */ 5238684f6988SStefano Zampini A_RR = 0; 5239684f6988SStefano Zampini if (neumann) { 5240d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 524104708bb6SStefano Zampini PetscInt ibs,mbs; 52420aa714b2SStefano Zampini PetscBool issbaij, reuse_neumann_solver; 524304708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 52440aa714b2SStefano Zampini 52450aa714b2SStefano Zampini reuse_neumann_solver = PETSC_FALSE; 52460aa714b2SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 52470aa714b2SStefano Zampini IS iP; 52480aa714b2SStefano Zampini 52490aa714b2SStefano Zampini reuse_neumann_solver = PETSC_TRUE; 52500aa714b2SStefano Zampini ierr = PetscObjectQuery((PetscObject)sub_schurs->A,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 52510aa714b2SStefano Zampini if (iP) reuse_neumann_solver = PETSC_FALSE; 52520aa714b2SStefano Zampini } 5253f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 52548ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 5255f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 5256f4ddd8eeSStefano Zampini PetscInt nn_R; 525781d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 5258f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5259f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 5260f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 5261f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 5262f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5263f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5264f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 5265727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 5266f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5267f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5268f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 5269f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 5270f4ddd8eeSStefano Zampini } 5271f4ddd8eeSStefano Zampini } 5272f4ddd8eeSStefano Zampini /* last check */ 5273d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 5274f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5275f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5276f4ddd8eeSStefano Zampini } 5277f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 5278f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5279f4ddd8eeSStefano Zampini } 5280a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 5281af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 5282af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 528304708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 528404708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 528504708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 528604708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 528704708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 5288af732b37SStefano Zampini } else { 5289511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 52906816873aSStefano Zampini } 529104708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 529204708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 529304708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 529404708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 529504708bb6SStefano Zampini } else { 5296511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 529704708bb6SStefano Zampini } 529804708bb6SStefano Zampini } 5299a00504b5SStefano Zampini /* extract A_RR */ 53000aa714b2SStefano Zampini if (reuse_neumann_solver) { 5301a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5302a00504b5SStefano Zampini 5303a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 530416e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5305a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 530616e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 530716e386b8SStefano Zampini } else { 53087dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 5309a00504b5SStefano Zampini } 5310a00504b5SStefano Zampini } else { 5311a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5312a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 5313a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5314a00504b5SStefano Zampini } 5315a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 53167dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 531716e386b8SStefano Zampini } 53183301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 53193301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 53206816873aSStefano Zampini } 5321f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 5322cd18cfedSStefano Zampini void (*f)(void) = 0; 5323cd18cfedSStefano Zampini 5324304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 5325304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 5326304d26faSStefano Zampini /* default */ 5327304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 5328e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 5329304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 53309577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 53319577ea80SStefano Zampini if (issbaij) { 53329577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 53339577ea80SStefano Zampini } else { 5334304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 53359577ea80SStefano Zampini } 5336304d26faSStefano Zampini /* Allow user's customization */ 5337304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 5338cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 5339cd18cfedSStefano Zampini if (f && pcbddc->mat_graph->cloc) { 5340cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5341cd18cfedSStefano Zampini const PetscInt *idxs; 5342cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5343cd18cfedSStefano Zampini 5344cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcbddc->is_R_local,&nl);CHKERRQ(ierr); 5345cd18cfedSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5346cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5347cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5348cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5349cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5350cd18cfedSStefano Zampini } 5351cd18cfedSStefano Zampini } 5352cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5353cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5354cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5355cd18cfedSStefano Zampini } 5356304d26faSStefano Zampini } 5357304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5358304d26faSStefano Zampini if (!n_R) { 5359304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 5360304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5361304d26faSStefano Zampini } 53625cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 5363df4d28bfSStefano Zampini /* Reuse solver if it is present */ 53640aa714b2SStefano Zampini if (reuse_neumann_solver) { 5365df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5366d62866d3SStefano Zampini 5367df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 5368d62866d3SStefano Zampini } 5369684f6988SStefano Zampini } 5370304d26faSStefano Zampini 5371684f6988SStefano Zampini if (pcbddc->dbg_flag) { 5372684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 53731575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5374684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5375684f6988SStefano Zampini } 5376c7017625SStefano Zampini 5377c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 537835529e7bSStefano Zampini check_corr = PETSC_FALSE; 5379c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 5380c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 5381c7017625SStefano Zampini } 5382c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 538335529e7bSStefano Zampini check_corr = PETSC_TRUE; 5384c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 5385c7017625SStefano Zampini } 5386c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 538735529e7bSStefano Zampini check_corr = PETSC_TRUE; 5388c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 5389c7017625SStefano Zampini } 5390c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 5391c7017625SStefano Zampini if (pcbddc->dbg_flag) { 5392684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 53930fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 53940fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 53950fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 53960fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 53970fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 5398e604994aSStefano 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); 539935529e7bSStefano Zampini if (check_corr) { 5400c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 5401c7017625SStefano Zampini } 5402304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5403304d26faSStefano Zampini } 5404684f6988SStefano Zampini if (neumann) { /* Neumann */ 54050fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 54060fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 54070fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 54080fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 54090fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 5410e604994aSStefano 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); 541135529e7bSStefano Zampini if (check_corr) { 5412c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 5413c7017625SStefano Zampini } 5414304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5415304d26faSStefano Zampini } 5416684f6988SStefano Zampini } 54175cbda25cSStefano Zampini /* free Neumann problem's matrix */ 54185cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5419304d26faSStefano Zampini PetscFunctionReturn(0); 5420304d26faSStefano Zampini } 5421304d26faSStefano Zampini 542280677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 5423674ae819SStefano Zampini { 5424674ae819SStefano Zampini PetscErrorCode ierr; 5425674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5426be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5427b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 5428674ae819SStefano Zampini 5429674ae819SStefano Zampini PetscFunctionBegin; 5430b334f244SStefano Zampini if (!reuse_solver) { 543180677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 543220c7b377SStefano Zampini } 543380677318SStefano Zampini if (!pcbddc->switch_static) { 543480677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 543580677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 543680677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 543720c7b377SStefano Zampini } 5438b334f244SStefano Zampini if (!reuse_solver) { 543980677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 544080677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 544120c7b377SStefano Zampini } else { 5442df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5443be83ff47SStefano Zampini 5444df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5445df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 544620c7b377SStefano Zampini } 5447be83ff47SStefano Zampini } else { 544880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 544980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 545080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 545180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 545280677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 545380677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 545480677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 545580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 545680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5457674ae819SStefano Zampini } 5458674ae819SStefano Zampini } 5459b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 546080677318SStefano Zampini if (applytranspose) { 546180677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 546280677318SStefano Zampini } else { 546380677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 546480677318SStefano Zampini } 5465be83ff47SStefano Zampini } else { 5466df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5467be83ff47SStefano Zampini 5468be83ff47SStefano Zampini if (applytranspose) { 5469df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5470be83ff47SStefano Zampini } else { 5471df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5472be83ff47SStefano Zampini } 5473be83ff47SStefano Zampini } 547480677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 547580677318SStefano Zampini if (!pcbddc->switch_static) { 5476b334f244SStefano Zampini if (!reuse_solver) { 547780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 547880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5479be83ff47SStefano Zampini } else { 5480df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5481be83ff47SStefano Zampini 5482df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5483df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5484be83ff47SStefano Zampini } 548580677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 548680677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 548780677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 548880677318SStefano Zampini } 548980677318SStefano Zampini } else { 549080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 549180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 549280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 549380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 549480677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 549580677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 549680677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 549780677318SStefano Zampini } 549880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 549980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 550080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 550180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5502674ae819SStefano Zampini } 5503674ae819SStefano Zampini PetscFunctionReturn(0); 5504674ae819SStefano Zampini } 5505674ae819SStefano Zampini 5506dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 5507dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 5508674ae819SStefano Zampini { 5509674ae819SStefano Zampini PetscErrorCode ierr; 5510674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5511674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 5512674ae819SStefano Zampini const PetscScalar zero = 0.0; 5513674ae819SStefano Zampini 5514674ae819SStefano Zampini PetscFunctionBegin; 5515dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 55164fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5517dc359a40SStefano Zampini if (applytranspose) { 5518674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 55198eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 5520dc359a40SStefano Zampini } else { 5521674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 5522674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 552315aaf578SStefano Zampini } 55244fee134fSStefano Zampini } else { 55254fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 55264fee134fSStefano Zampini } 5527efc2fbd9SStefano Zampini 5528efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 55294f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5530efc2fbd9SStefano Zampini PetscScalar *array; 55314f1b2e48SStefano Zampini PetscInt j; 5532efc2fbd9SStefano Zampini 5533efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 55344f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 5535efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5536efc2fbd9SStefano Zampini } 5537efc2fbd9SStefano Zampini 553812edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 553912edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 554012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 554112edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 554212edc857SStefano Zampini 55439f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 554412edc857SStefano Zampini if (pcbddc->coarse_ksp) { 554551694757SStefano Zampini Mat coarse_mat; 5546964fefecSStefano Zampini Vec rhs,sol; 554751694757SStefano Zampini MatNullSpace nullsp; 554827b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 5549964fefecSStefano Zampini 555027b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 555127b6a85dSStefano Zampini PC coarse_pc; 555227b6a85dSStefano Zampini 555327b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 555427b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 555527b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 555627b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 555727b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 555827b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 55593bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 556027b6a85dSStefano Zampini } 556127b6a85dSStefano Zampini } 5562964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 5563964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 556451694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 556551694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 556651694757SStefano Zampini if (nullsp) { 556751694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 556851694757SStefano Zampini } 556912edc857SStefano Zampini if (applytranspose) { 55709a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 5571964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 55722701bc32SStefano Zampini } else { 55731f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 55742701bc32SStefano Zampini PC coarse_pc; 55752701bc32SStefano Zampini 55762701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 55772701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 55783e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 55792701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 558012edc857SStefano Zampini } else { 5581964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 558212edc857SStefano Zampini } 55832701bc32SStefano Zampini } 55841d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 558527b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 558627b6a85dSStefano Zampini PC coarse_pc; 558727b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 558827b6a85dSStefano Zampini 558927b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 559027b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 559127b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 55923bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 559327b6a85dSStefano Zampini } 559451694757SStefano Zampini if (nullsp) { 559551694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 559651694757SStefano Zampini } 559712edc857SStefano Zampini } 5598674ae819SStefano Zampini 5599674ae819SStefano Zampini /* Local solution on R nodes */ 56004fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 560180677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 56029f00e9b4SStefano Zampini } 56039f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 56049f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 560512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5606674ae819SStefano Zampini 56074fee134fSStefano Zampini /* Sum contributions from the two levels */ 56084fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5609dc359a40SStefano Zampini if (applytranspose) { 5610dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5611dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5612dc359a40SStefano Zampini } else { 5613674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 56148eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5615dc359a40SStefano Zampini } 5616efc2fbd9SStefano Zampini /* store p0 */ 56174f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5618efc2fbd9SStefano Zampini PetscScalar *array; 56194f1b2e48SStefano Zampini PetscInt j; 5620efc2fbd9SStefano Zampini 5621efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 56224f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 5623efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5624efc2fbd9SStefano Zampini } 56254fee134fSStefano Zampini } else { /* expand the coarse solution */ 56264fee134fSStefano Zampini if (applytranspose) { 56274fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 56284fee134fSStefano Zampini } else { 56294fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 56304fee134fSStefano Zampini } 56314fee134fSStefano Zampini } 5632674ae819SStefano Zampini PetscFunctionReturn(0); 5633674ae819SStefano Zampini } 5634674ae819SStefano Zampini 563512edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 5636674ae819SStefano Zampini { 5637674ae819SStefano Zampini PetscErrorCode ierr; 5638674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 563958da7f69SStefano Zampini PetscScalar *array; 564012edc857SStefano Zampini Vec from,to; 5641674ae819SStefano Zampini 5642674ae819SStefano Zampini PetscFunctionBegin; 564312edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 564412edc857SStefano Zampini from = pcbddc->coarse_vec; 564512edc857SStefano Zampini to = pcbddc->vec1_P; 564612edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 564712edc857SStefano Zampini Vec tvec; 564858da7f69SStefano Zampini 564958da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 565058da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 565112edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 565258da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 565358da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 565458da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 565512edc857SStefano Zampini } 565612edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 565712edc857SStefano Zampini from = pcbddc->vec1_P; 565812edc857SStefano Zampini to = pcbddc->coarse_vec; 565912edc857SStefano Zampini } 566012edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 5661674ae819SStefano Zampini PetscFunctionReturn(0); 5662674ae819SStefano Zampini } 5663674ae819SStefano Zampini 566412edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 5665674ae819SStefano Zampini { 5666674ae819SStefano Zampini PetscErrorCode ierr; 5667674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 566858da7f69SStefano Zampini PetscScalar *array; 566912edc857SStefano Zampini Vec from,to; 5670674ae819SStefano Zampini 5671674ae819SStefano Zampini PetscFunctionBegin; 567212edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 567312edc857SStefano Zampini from = pcbddc->coarse_vec; 567412edc857SStefano Zampini to = pcbddc->vec1_P; 567512edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 567612edc857SStefano Zampini from = pcbddc->vec1_P; 567712edc857SStefano Zampini to = pcbddc->coarse_vec; 567812edc857SStefano Zampini } 567912edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 568012edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 568112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 568212edc857SStefano Zampini Vec tvec; 568358da7f69SStefano Zampini 568412edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 568558da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 568658da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 568758da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 568858da7f69SStefano Zampini } 568958da7f69SStefano Zampini } else { 569058da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 569158da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 569212edc857SStefano Zampini } 569312edc857SStefano Zampini } 5694674ae819SStefano Zampini PetscFunctionReturn(0); 5695674ae819SStefano Zampini } 5696674ae819SStefano Zampini 5697984c4197SStefano Zampini /* uncomment for testing purposes */ 5698984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 5699674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 5700674ae819SStefano Zampini { 5701674ae819SStefano Zampini PetscErrorCode ierr; 5702674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5703674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5704674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5705984c4197SStefano Zampini /* one and zero */ 5706984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 5707984c4197SStefano Zampini /* space to store constraints and their local indices */ 57089162d606SStefano Zampini PetscScalar *constraints_data; 57099162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 57109162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 57119162d606SStefano Zampini PetscInt *constraints_n; 5712984c4197SStefano Zampini /* iterators */ 5713b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 5714984c4197SStefano Zampini /* BLAS integers */ 5715e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 5716e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 5717c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 5718727cdba6SStefano Zampini /* reuse */ 57190e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 57200e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 5721984c4197SStefano Zampini /* change of basis */ 5722b3d85658SStefano Zampini PetscBool qr_needed; 57239162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 5724984c4197SStefano Zampini /* auxiliary stuff */ 572564efe560SStefano Zampini PetscInt *nnz,*is_indices; 57268a0068c3SStefano Zampini PetscInt ncc; 5727984c4197SStefano Zampini /* some quantities */ 572845a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 5729a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 573057715f18SStefano Zampini PetscReal tol; /* tolerance for retaining eigenmodes */ 5731984c4197SStefano Zampini 5732674ae819SStefano Zampini PetscFunctionBegin; 573357715f18SStefano Zampini tol = PetscSqrtReal(PETSC_SMALL); 57348e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 57358e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 57368e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 573716909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 5738088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 5739088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 57400e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 57410e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 57420e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 57430e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 57440e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 5745088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5746cf5a6209SStefano Zampini 5747cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 57489162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 5749cf5a6209SStefano Zampini MatNullSpace nearnullsp; 5750cf5a6209SStefano Zampini const Vec *nearnullvecs; 5751cf5a6209SStefano Zampini Vec *localnearnullsp; 5752cf5a6209SStefano Zampini PetscScalar *array; 5753cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 5754cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 5755674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 5756b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 5757674ae819SStefano Zampini PetscScalar *work; 5758674ae819SStefano Zampini PetscReal *singular_vals; 5759674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5760674ae819SStefano Zampini PetscReal *rwork; 5761674ae819SStefano Zampini #endif 5762674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5763674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 5764674ae819SStefano Zampini #else 5765964fefecSStefano Zampini PetscBLASInt dummy_int=1; 5766964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 5767674ae819SStefano Zampini #endif 5768674ae819SStefano Zampini 5769674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 5770d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 5771e4d548c7SStefano Zampini /* print some info */ 57725c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 5773e4d548c7SStefano Zampini PetscInt nv; 5774e4d548c7SStefano Zampini 5775c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5776e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 5777e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5778e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5779e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 5780e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 5781e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 5782e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5783e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5784e4d548c7SStefano Zampini } 5785e4d548c7SStefano Zampini 5786d06fc5fdSStefano Zampini /* free unneeded index sets */ 5787d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 5788d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 5789674ae819SStefano Zampini } 5790d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 5791d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5792d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5793d06fc5fdSStefano Zampini } 5794d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5795d06fc5fdSStefano Zampini n_ISForEdges = 0; 5796d06fc5fdSStefano Zampini } 5797d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 5798d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5799d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5800d06fc5fdSStefano Zampini } 5801d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5802d06fc5fdSStefano Zampini n_ISForFaces = 0; 5803d06fc5fdSStefano Zampini } 580470022509SStefano Zampini 5805674ae819SStefano Zampini /* check if near null space is attached to global mat */ 5806674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 5807674ae819SStefano Zampini if (nearnullsp) { 5808674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 5809f4ddd8eeSStefano Zampini /* remove any stored info */ 5810f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 5811f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5812f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 5813f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 5814f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 5815473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5816f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 5817f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 5818f4ddd8eeSStefano Zampini } 5819984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 5820984c4197SStefano Zampini nnsp_size = 0; 5821674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 5822674ae819SStefano Zampini } 5823984c4197SStefano Zampini /* get max number of constraints on a single cc */ 5824984c4197SStefano Zampini max_constraints = nnsp_size; 5825984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 5826984c4197SStefano Zampini 5827674ae819SStefano Zampini /* 5828674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 58299162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 58309162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 58319162d606SStefano Zampini There can be multiple constraints per connected component 5832674ae819SStefano Zampini */ 5833674ae819SStefano Zampini n_vertices = 0; 5834674ae819SStefano Zampini if (ISForVertices) { 5835674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 5836674ae819SStefano Zampini } 58379162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 58389162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 58399162d606SStefano Zampini 58409162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 58419162d606SStefano Zampini total_counts *= max_constraints; 5842674ae819SStefano Zampini total_counts += n_vertices; 58434641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 58449162d606SStefano Zampini 5845674ae819SStefano Zampini total_counts = 0; 5846674ae819SStefano Zampini max_size_of_constraint = 0; 5847674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 58489162d606SStefano Zampini IS used_is; 5849674ae819SStefano Zampini if (i<n_ISForEdges) { 58509162d606SStefano Zampini used_is = ISForEdges[i]; 5851674ae819SStefano Zampini } else { 58529162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 5853674ae819SStefano Zampini } 58549162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 5855674ae819SStefano Zampini total_counts += j; 5856674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 5857674ae819SStefano Zampini } 58589162d606SStefano 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); 58599162d606SStefano Zampini 5860984c4197SStefano Zampini /* get local part of global near null space vectors */ 5861785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 5862984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5863984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 5864e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5865e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5866984c4197SStefano Zampini } 5867674ae819SStefano Zampini 5868242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 5869242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 5870a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 5871242a89d7SStefano Zampini 5872984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 5873a773dcb8SStefano Zampini if (!skip_lapack) { 5874674ae819SStefano Zampini PetscScalar temp_work; 5875911cabfeSStefano Zampini 5876674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5877984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 5878785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 5879785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 5880785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 5881674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5882785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 5883674ae819SStefano Zampini #endif 5884674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5885c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 5886c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 5887674ae819SStefano Zampini lwork = -1; 5888674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5889674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5890c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 5891674ae819SStefano Zampini #else 5892c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 5893674ae819SStefano Zampini #endif 5894674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5895984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 5896674ae819SStefano Zampini #else /* on missing GESVD */ 5897674ae819SStefano Zampini /* SVD */ 5898674ae819SStefano Zampini PetscInt max_n,min_n; 5899674ae819SStefano Zampini max_n = max_size_of_constraint; 5900984c4197SStefano Zampini min_n = max_constraints; 5901984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 5902674ae819SStefano Zampini min_n = max_size_of_constraint; 5903984c4197SStefano Zampini max_n = max_constraints; 5904674ae819SStefano Zampini } 5905785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 5906674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5907785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 5908674ae819SStefano Zampini #endif 5909674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5910674ae819SStefano Zampini lwork = -1; 5911e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 5912e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 5913b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 5914674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5915674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 59169162d606SStefano 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)); 5917674ae819SStefano Zampini #else 59189162d606SStefano 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)); 5919674ae819SStefano Zampini #endif 5920674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5921984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 5922984c4197SStefano Zampini #endif /* on missing GESVD */ 5923674ae819SStefano Zampini /* Allocate optimal workspace */ 5924674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 5925854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 5926674ae819SStefano Zampini } 5927674ae819SStefano Zampini /* Now we can loop on constraining sets */ 5928674ae819SStefano Zampini total_counts = 0; 59299162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 59309162d606SStefano Zampini constraints_data_ptr[0] = 0; 5931674ae819SStefano Zampini /* vertices */ 59329162d606SStefano Zampini if (n_vertices) { 5933674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 59349162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 5935674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 59369162d606SStefano Zampini constraints_n[total_counts] = 1; 59379162d606SStefano Zampini constraints_data[total_counts] = 1.0; 59389162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 59399162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 5940674ae819SStefano Zampini total_counts++; 5941674ae819SStefano Zampini } 5942674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5943674ae819SStefano Zampini n_vertices = total_counts; 5944674ae819SStefano Zampini } 5945984c4197SStefano Zampini 5946674ae819SStefano Zampini /* edges and faces */ 59479162d606SStefano Zampini total_counts_cc = total_counts; 5948911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 59499162d606SStefano Zampini IS used_is; 59509162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 59519162d606SStefano Zampini 5952911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 59539162d606SStefano Zampini used_is = ISForEdges[ncc]; 5954984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 5955674ae819SStefano Zampini } else { 59569162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 5957984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 5958674ae819SStefano Zampini } 5959674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 59609162d606SStefano Zampini 59619162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 59629162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5963984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 5964984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 5965674ae819SStefano Zampini if (nnsp_has_cnst) { 59665b08dc53SStefano Zampini PetscScalar quad_value; 59679162d606SStefano Zampini 59689162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 59699162d606SStefano Zampini idxs_copied = PETSC_TRUE; 59709162d606SStefano Zampini 5971a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 5972674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 5973a773dcb8SStefano Zampini } else { 5974a773dcb8SStefano Zampini quad_value = 1.0; 5975a773dcb8SStefano Zampini } 5976674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 59779162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 5978674ae819SStefano Zampini } 59799162d606SStefano Zampini temp_constraints++; 5980674ae819SStefano Zampini total_counts++; 5981674ae819SStefano Zampini } 5982674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 5983984c4197SStefano Zampini PetscReal real_value; 59849162d606SStefano Zampini PetscScalar *ptr_to_data; 59859162d606SStefano Zampini 5986984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 59879162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 5988674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 59899162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 5990674ae819SStefano Zampini } 5991984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 5992984c4197SStefano Zampini /* check if array is null on the connected component */ 5993e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 59949162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 599557715f18SStefano Zampini if (real_value > tol*size_of_constraint) { /* keep indices and values */ 5996674ae819SStefano Zampini temp_constraints++; 5997674ae819SStefano Zampini total_counts++; 59989162d606SStefano Zampini if (!idxs_copied) { 59999162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 60009162d606SStefano Zampini idxs_copied = PETSC_TRUE; 6001674ae819SStefano Zampini } 6002674ae819SStefano Zampini } 60039162d606SStefano Zampini } 60049162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 600545a1bb75SStefano Zampini valid_constraints = temp_constraints; 6006eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 6007a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 60089162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 60099162d606SStefano Zampini 60109162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 6011a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 60129162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 6013a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 60149162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 6015a773dcb8SStefano Zampini } else { /* perform SVD */ 60169162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 6017674ae819SStefano Zampini 6018674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 6019984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 6020984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 6021984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 6022984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 6023984c4197SStefano Zampini from that computed using LAPACKgesvd 6024984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 6025984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 6026984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 6027674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 6028e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6029984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6030674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 6031674ae819SStefano Zampini for (k=0;k<j+1;k++) { 60329162d606SStefano 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)); 6033674ae819SStefano Zampini } 6034674ae819SStefano Zampini } 6035e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 6036e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6037e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 6038674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 6039c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 6040674ae819SStefano Zampini #else 6041c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 6042674ae819SStefano Zampini #endif 6043674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6044984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 6045984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 6046674ae819SStefano Zampini j = 0; 6047984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 6048674ae819SStefano Zampini total_counts = total_counts-j; 604945a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 6050e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 6051c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 6052c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6053c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 6054c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6055c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 6056c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6057674ae819SStefano Zampini if (j<temp_constraints) { 6058984c4197SStefano Zampini PetscInt ii; 6059984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 6060674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 60619162d606SStefano 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)); 6062674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6063984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 6064674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 60659162d606SStefano 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]; 6066674ae819SStefano Zampini } 6067674ae819SStefano Zampini } 6068674ae819SStefano Zampini } 6069674ae819SStefano Zampini #else /* on missing GESVD */ 6070e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 6071e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 6072b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6073674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6074674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 60759162d606SStefano 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)); 6076674ae819SStefano Zampini #else 60779162d606SStefano 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)); 6078674ae819SStefano Zampini #endif 6079984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 6080674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6081984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 6082e310c8b4SStefano Zampini k = temp_constraints; 6083e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 6084674ae819SStefano Zampini j = 0; 6085e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 608645a1bb75SStefano Zampini valid_constraints = k-j; 6087911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 6088984c4197SStefano Zampini #endif /* on missing GESVD */ 6089674ae819SStefano Zampini } 6090a773dcb8SStefano Zampini } 60919162d606SStefano Zampini /* update pointers information */ 60929162d606SStefano Zampini if (valid_constraints) { 60939162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 60949162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 60959162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 60969162d606SStefano Zampini /* set change_of_basis flag */ 609745a1bb75SStefano Zampini if (boolforchange) { 6098b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 60999162d606SStefano Zampini } 6100b3d85658SStefano Zampini total_counts_cc++; 610145a1bb75SStefano Zampini } 610245a1bb75SStefano Zampini } 6103984c4197SStefano Zampini /* free workspace */ 61048f1c130eSStefano Zampini if (!skip_lapack) { 6105984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 6106984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 6107984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 6108984c4197SStefano Zampini #endif 6109984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 6110984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 6111984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 6112984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 6113984c4197SStefano Zampini #endif 6114984c4197SStefano Zampini } 6115984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 6116984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 6117984c4197SStefano Zampini } 6118984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 6119cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 6120cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 6121cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 6122cf5a6209SStefano Zampini } 6123cf5a6209SStefano Zampini if (n_ISForFaces) { 6124cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 6125cf5a6209SStefano Zampini } 6126cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 6127cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 6128cf5a6209SStefano Zampini } 6129cf5a6209SStefano Zampini if (n_ISForEdges) { 6130cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 6131cf5a6209SStefano Zampini } 6132cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 613308122e43SStefano Zampini } else { 613408122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 6135984c4197SStefano Zampini 613608122e43SStefano Zampini total_counts = 0; 613708122e43SStefano Zampini n_vertices = 0; 6138d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 6139d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 614008122e43SStefano Zampini } 614108122e43SStefano Zampini max_constraints = 0; 61429162d606SStefano Zampini total_counts_cc = 0; 614308122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 614408122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 61459162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 614608122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 614708122e43SStefano Zampini } 61489162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 61499162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 61509162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 61519162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 615274d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 61539162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 61549162d606SStefano Zampini total_counts_cc = 0; 61559162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 61569162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 61579162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 615808122e43SStefano Zampini } 615908122e43SStefano Zampini } 61609162d606SStefano Zampini #if 0 61619162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 61629162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 61639162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 61649162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 61659162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 61669162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 61679162d606SStefano Zampini } 61689162d606SStefano Zampini printf("\n"); 61699162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 61709162d606SStefano Zampini } 61711b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 61728bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 61731b968477SStefano Zampini } 61741b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 61758bec7fa6SStefano 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]); 61761b968477SStefano Zampini } 617708122e43SStefano Zampini #endif 617808122e43SStefano Zampini 61798bec7fa6SStefano Zampini max_size_of_constraint = 0; 61809162d606SStefano 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]); 61819162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 618208122e43SStefano Zampini /* Change of basis */ 6183b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 618408122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 618508122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 618608122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 6187b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 618808122e43SStefano Zampini } 618908122e43SStefano Zampini } 619008122e43SStefano Zampini } 619108122e43SStefano Zampini } 6192984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 61934f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 619408122e43SStefano Zampini 61959162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 61969162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 6197eee23b56SStefano 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); 6198674ae819SStefano Zampini 6199674ae819SStefano Zampini /* Create constraint matrix */ 6200674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 620116f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 6202984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 6203984c4197SStefano Zampini 6204984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 6205a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 6206a717540cSStefano Zampini qr_needed = PETSC_FALSE; 620774d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 6208984c4197SStefano Zampini total_primal_vertices=0; 6209b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 62109162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 62119162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 621272b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 62139162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 6214b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 621564efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 62169162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 62179162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 6218a717540cSStefano Zampini } 6219b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 622091af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 6221a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 6222a717540cSStefano Zampini qr_needed = PETSC_TRUE; 6223a717540cSStefano Zampini } 6224fa434743SStefano Zampini } else { 6225b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 6226fa434743SStefano Zampini } 6227a717540cSStefano Zampini } 6228b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 6229b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 6230674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 623170022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 62324f1b2e48SStefano 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); 62330e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 62340e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 6235984c4197SStefano Zampini 6236984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 623774d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 6238785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 6239984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 624074d5cdf7SStefano Zampini 6241984c4197SStefano Zampini j = total_primal_vertices; 624274d5cdf7SStefano Zampini total_counts = total_primal_vertices; 6243b3d85658SStefano Zampini cum = total_primal_vertices; 62449162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 62454641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 6246b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 6247b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 6248b3d85658SStefano Zampini cum++; 62499162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 625074d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 625174d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 625274d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 625374d5cdf7SStefano Zampini } 62549162d606SStefano Zampini j += constraints_n[i]; 6255674ae819SStefano Zampini } 6256674ae819SStefano Zampini } 6257674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 6258674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 6259088faed8SStefano Zampini 6260674ae819SStefano Zampini /* set values in constraint matrix */ 6261984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 62620e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6263674ae819SStefano Zampini } 6264984c4197SStefano Zampini total_counts = total_primal_vertices; 62659162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 62664641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 62679162d606SStefano Zampini PetscInt *cols; 62689162d606SStefano Zampini 62699162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 62709162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 62719162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 62729162d606SStefano Zampini PetscInt row = total_counts+k; 62739162d606SStefano Zampini PetscScalar *vals; 62749162d606SStefano Zampini 62759162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 62769162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 62779162d606SStefano Zampini } 62789162d606SStefano Zampini total_counts += constraints_n[i]; 6279674ae819SStefano Zampini } 6280674ae819SStefano Zampini } 6281674ae819SStefano Zampini /* assembling */ 6282674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6283674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 62843272d46bSStefano Zampini ierr = MatChop(pcbddc->ConstraintMatrix,PETSC_SMALL);CHKERRQ(ierr); 62853272d46bSStefano Zampini ierr = MatSeqAIJCompress(pcbddc->ConstraintMatrix,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 62863272d46bSStefano Zampini ierr = MatViewFromOptions(pcbddc->ConstraintMatrix,NULL,"-pc_bddc_constraint_mat_view");CHKERRQ(ierr); 6287088faed8SStefano Zampini 6288984c4197SStefano Zampini /* 62896a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 6290984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 6291f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 6292984c4197SStefano Zampini */ 6293674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 6294674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 6295026de310SStefano Zampini /* dual and primal dofs on a single cc */ 6296984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 6297984c4197SStefano Zampini /* working stuff for GEQRF */ 629881d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 6299984c4197SStefano Zampini PetscBLASInt lqr_work; 6300984c4197SStefano Zampini /* working stuff for UNGQR */ 6301984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 6302984c4197SStefano Zampini PetscBLASInt lgqr_work; 6303984c4197SStefano Zampini /* working stuff for TRTRS */ 6304984c4197SStefano Zampini PetscScalar *trs_rhs; 63053f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 6306984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 6307984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 6308984c4197SStefano Zampini PetscScalar *start_vals; 6309984c4197SStefano Zampini /* working stuff for values insertion */ 63104641a718SStefano Zampini PetscBT is_primal; 631164efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 6312906d46d4SStefano Zampini /* matrix sizes */ 6313906d46d4SStefano Zampini PetscInt global_size,local_size; 6314906d46d4SStefano Zampini /* temporary change of basis */ 6315906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 6316cf5a6209SStefano Zampini /* extra space for debugging */ 6317cf5a6209SStefano Zampini PetscScalar *dbg_work; 6318984c4197SStefano Zampini 6319906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 6320906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 632116f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 6322bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 6323906d46d4SStefano Zampini /* nonzeros for local mat */ 6324bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 63251dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6326bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 63271dd7afcfSStefano Zampini } else { 63281dd7afcfSStefano Zampini const PetscInt *ii; 63291dd7afcfSStefano Zampini PetscInt n; 63301dd7afcfSStefano Zampini PetscBool flg_row; 63311dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 63321dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 63331dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 63341dd7afcfSStefano Zampini } 63359162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 6336a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 63379162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 6338a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 63399162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 6340a717540cSStefano Zampini } else { 63419162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 63429162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 6343a717540cSStefano Zampini } 6344a717540cSStefano Zampini } 6345a717540cSStefano Zampini } 6346906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 6347bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 63481dd7afcfSStefano Zampini /* Set interior change in the matrix */ 63491dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6350bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 6351906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 6352a717540cSStefano Zampini } 63531dd7afcfSStefano Zampini } else { 63541dd7afcfSStefano Zampini const PetscInt *ii,*jj; 63551dd7afcfSStefano Zampini PetscScalar *aa; 63561dd7afcfSStefano Zampini PetscInt n; 63571dd7afcfSStefano Zampini PetscBool flg_row; 63581dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 63591dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 63601dd7afcfSStefano Zampini for (i=0;i<n;i++) { 63611dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 63621dd7afcfSStefano Zampini } 63631dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 63641dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 63651dd7afcfSStefano Zampini } 6366a717540cSStefano Zampini 6367a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6368a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6369a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6370a717540cSStefano Zampini } 6371a717540cSStefano Zampini 6372a717540cSStefano Zampini 6373a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 6374a717540cSStefano Zampini /* 6375a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 6376a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 6377a717540cSStefano Zampini 6378a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 6379a717540cSStefano Zampini 6380a6b551f4SStefano 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) 6381a6b551f4SStefano Zampini 6382a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 6383a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 6384a717540cSStefano Zampini | ... | 6385a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 6386a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 6387a717540cSStefano Zampini 6388a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 6389a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 6390a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 6391a6b551f4SStefano Zampini 6392a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 6393a717540cSStefano Zampini */ 6394a717540cSStefano Zampini if (qr_needed) { 6395984c4197SStefano Zampini /* space to store Q */ 6396854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 63974e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 63984e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 6399984c4197SStefano Zampini /* first we issue queries for optimal work */ 64003f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 64013f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 64023f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6403984c4197SStefano Zampini lqr_work = -1; 64043f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 6405984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 6406984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 6407785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 6408984c4197SStefano Zampini lgqr_work = -1; 64093f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 64103f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 64113f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 64123f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 64133f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 6414c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 6415c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to ORGQR/UNGQR Lapack routine %d",(int)lierr); 6416984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 6417785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 6418984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 6419785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 6420a717540cSStefano Zampini /* allocating workspace for check */ 6421a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6422cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 6423a717540cSStefano Zampini } 6424a717540cSStefano Zampini } 6425984c4197SStefano Zampini /* array to store whether a node is primal or not */ 64264641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 6427473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 64280e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 6429eee23b56SStefano 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); 643039e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 643139e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 643239e2fb2aSStefano Zampini } 643339e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 6434984c4197SStefano Zampini 6435a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 64369162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 64379162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 64384641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 6439984c4197SStefano Zampini /* get constraint info */ 64409162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 6441984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 6442984c4197SStefano Zampini 6443984c4197SStefano Zampini if (pcbddc->dbg_flag) { 64449162d606SStefano 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); 6445674ae819SStefano Zampini } 6446984c4197SStefano Zampini 6447fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 6448a717540cSStefano Zampini 6449a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 6450a717540cSStefano Zampini if (pcbddc->dbg_flag) { 64519162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6452a717540cSStefano Zampini } 6453984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 64549162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6455984c4197SStefano Zampini 6456984c4197SStefano Zampini /* compute QR decomposition of constraints */ 64573f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 64583f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 64593f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6460674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 64613f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 6462984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 6463674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6464984c4197SStefano Zampini 6465984c4197SStefano Zampini /* explictly compute R^-T */ 6466984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 6467984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 64683f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 64693f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 64703f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 64713f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 6472984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 64733f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 6474984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 6475984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6476984c4197SStefano Zampini 6477a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 64783f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 64793f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 64803f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 64813f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6482984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6483c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 6484c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in ORGQR/UNGQR Lapack routine %d",(int)lierr); 6485984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6486984c4197SStefano Zampini 6487984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 6488984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 6489984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 64903f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 64913f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 64923f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 64933f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 64943f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 64953f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6496984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 64979162d606SStefano 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)); 6498984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 64999162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6500984c4197SStefano Zampini 6501984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 65029162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 6503984c4197SStefano Zampini /* insert cols for primal dofs */ 6504984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 6505984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 65069162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6507906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6508984c4197SStefano Zampini } 6509984c4197SStefano Zampini /* insert cols for dual dofs */ 6510984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 65119162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 6512984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 65139162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6514906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6515984c4197SStefano Zampini j++; 6516674ae819SStefano Zampini } 6517674ae819SStefano Zampini } 6518984c4197SStefano Zampini 6519984c4197SStefano Zampini /* check change of basis */ 6520984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6521984c4197SStefano Zampini PetscInt ii,jj; 6522984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 6523c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 6524c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6525c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 6526c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6527c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 6528c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 6529984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6530cf5a6209SStefano 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)); 6531984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6532984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6533984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6534cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 6535c068d9bbSLisandro 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; 6536674ae819SStefano Zampini } 6537674ae819SStefano Zampini } 6538984c4197SStefano Zampini if (!valid_qr) { 653922d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 6540984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6541984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6542cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 6543cf5a6209SStefano 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])); 6544674ae819SStefano Zampini } 6545c068d9bbSLisandro Dalcin if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-(PetscReal)1) > 1.e-12) { 6546cf5a6209SStefano 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])); 6547984c4197SStefano Zampini } 6548984c4197SStefano Zampini } 6549984c4197SStefano Zampini } 6550674ae819SStefano Zampini } else { 655122d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 6552674ae819SStefano Zampini } 6553674ae819SStefano Zampini } 6554a717540cSStefano Zampini } else { /* simple transformation block */ 6555a717540cSStefano Zampini PetscInt row,col; 6556a6b551f4SStefano Zampini PetscScalar val,norm; 6557a6b551f4SStefano Zampini 6558a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 65599162d606SStefano 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)); 6560a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 65619162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 65629162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6563bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 65649162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 6565906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 65669162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 6567a717540cSStefano Zampini } else { 6568a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 65699162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6570a717540cSStefano Zampini if (row != col) { 65719162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 6572a717540cSStefano Zampini } else { 65739162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 6574a717540cSStefano Zampini } 6575906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 6576a717540cSStefano Zampini } 6577a717540cSStefano Zampini } 6578a717540cSStefano Zampini } 657998a51de6SStefano Zampini if (pcbddc->dbg_flag) { 658022d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 6581a717540cSStefano Zampini } 6582674ae819SStefano Zampini } 6583984c4197SStefano Zampini } else { 6584984c4197SStefano Zampini if (pcbddc->dbg_flag) { 65859162d606SStefano 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); 6586674ae819SStefano Zampini } 6587674ae819SStefano Zampini } 6588674ae819SStefano Zampini } 6589a717540cSStefano Zampini 6590a717540cSStefano Zampini /* free workspace */ 6591a717540cSStefano Zampini if (qr_needed) { 6592984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6593cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 6594984c4197SStefano Zampini } 6595984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 6596984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 6597984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 6598984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 6599984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 6600674ae819SStefano Zampini } 6601a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 6602906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6603906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6604906d46d4SStefano Zampini 6605906d46d4SStefano Zampini /* assembling of global change of variable */ 660688c03ad3SStefano Zampini if (!pcbddc->fake_change) { 6607bbb9e6c6SStefano Zampini Mat tmat; 660816f15bc4SStefano Zampini PetscInt bs; 660916f15bc4SStefano Zampini 6610906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 6611906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 6612bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 6613bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 6614bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6615bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 661616f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 661716f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 6618906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 6619bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 6620bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6621bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6622bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6623bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6624e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6625e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6626bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 6627bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 662888c03ad3SStefano Zampini 6629906d46d4SStefano Zampini /* check */ 6630906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 6631906d46d4SStefano Zampini PetscReal error; 6632906d46d4SStefano Zampini Vec x,x_change; 6633906d46d4SStefano Zampini 6634906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 6635906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 6636906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 6637906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 6638e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6639e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6640bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 6641e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6642e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6643906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 6644906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 6645906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 6646637e8532SStefano Zampini if (error > PETSC_SMALL) { 6647637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 6648637e8532SStefano Zampini } 6649906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 6650906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 6651906d46d4SStefano Zampini } 6652b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 6653b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 6654b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6655bf3a8328SStefano Zampini 665613903a91SSatish 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"); 6657b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 6658ac632422SStefano Zampini Mat S_new,tmat; 6659bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 6660bbb9e6c6SStefano Zampini 6661bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 66627dae84e0SHong Zhang ierr = MatCreateSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 6663bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6664bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 6665bf3a8328SStefano Zampini IS is_V; 6666b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 6667b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 6668b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 6669b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 6670b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 6671bf3a8328SStefano Zampini } 6672bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 6673ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6674b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 6675ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6676bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6677bf3a8328SStefano Zampini const PetscScalar *array; 6678bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 6679bf3a8328SStefano Zampini PetscInt i,n_V; 6680bf3a8328SStefano Zampini 6681b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6682b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 6683b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6684b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6685b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 6686b087196eSStefano Zampini for (i=0;i<n_V;i++) { 6687b087196eSStefano Zampini PetscScalar val; 6688b087196eSStefano Zampini PetscInt idx; 6689b087196eSStefano Zampini 6690b087196eSStefano Zampini idx = idxs_V[i]; 6691b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 6692b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 6693b087196eSStefano Zampini } 6694b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6695b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6696bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 6697bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6698bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6699bf3a8328SStefano Zampini } 6700ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 6701ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6702ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 6703ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6704b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 6705ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6706bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6707b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6708bf3a8328SStefano Zampini } 6709ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 6710ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6711ac632422SStefano Zampini } 6712b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 671388c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6714b96c3477SStefano Zampini } 6715c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 6716b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 6717c9db6a07SStefano Zampini PetscInt i; 6718c9db6a07SStefano Zampini 6719c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 6720c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 6721c9db6a07SStefano Zampini } 6722c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 6723c9db6a07SStefano Zampini } 6724b96c3477SStefano Zampini } 672516909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 672616909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 672716909a7fSStefano Zampini } else { 6728906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 672916909a7fSStefano Zampini } 67301dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 673127b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 673272b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 673372b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 673472b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 673572b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 673672b8c272SStefano Zampini } 67371dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 673827b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 6739b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 6740b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 6741906d46d4SStefano Zampini } else { 67421dd7afcfSStefano Zampini Mat benign_global = NULL; 674327b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 67441dd7afcfSStefano Zampini Mat tmat; 67451dd7afcfSStefano Zampini 67461dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 67471dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 67481dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 67491dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 67501dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 67511dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 67521dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 67531dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 67541dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 67551dd7afcfSStefano Zampini if (pcbddc->benign_change) { 67561dd7afcfSStefano Zampini Mat M; 67571dd7afcfSStefano Zampini 67581dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 67591dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 67601dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 67611dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 6762906d46d4SStefano Zampini } else { 67631dd7afcfSStefano Zampini Mat eye; 67641dd7afcfSStefano Zampini PetscScalar *array; 67651dd7afcfSStefano Zampini 67661dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 67671dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 67681dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 67691dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 6770906d46d4SStefano Zampini } 67711dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 67721dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 67731dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 67741dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 67751dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 67761dd7afcfSStefano Zampini } 67771dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 67781dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 67791dd7afcfSStefano Zampini } 67801dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 67811dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 67821dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 678327b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 67841dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 67851dd7afcfSStefano Zampini } 67861dd7afcfSStefano Zampini } 678716909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 678816909a7fSStefano Zampini IS is_global; 678916909a7fSStefano Zampini const PetscInt *gidxs; 679016909a7fSStefano Zampini 679116909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 679216909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 679316909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 67947dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 679516909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 679616909a7fSStefano Zampini } 67971dd7afcfSStefano Zampini } 67981dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 67991dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 6800b9b85e73SStefano Zampini } 6801a717540cSStefano Zampini 680272b8c272SStefano Zampini if (!pcbddc->fake_change) { 68034f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 68044f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 68054f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 68064f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 6807019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 6808019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 6809019a44ceSStefano Zampini pcbddc->local_primal_size++; 6810019a44ceSStefano Zampini } 6811019a44ceSStefano Zampini 6812019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 6813727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 6814727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 68159f47a83aSStefano 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); 6816c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 68170e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 68189f47a83aSStefano 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); 6819727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 6820727cdba6SStefano Zampini } 68210e6343abSStefano Zampini } 6822727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 6823b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 682472b8c272SStefano Zampini } 682572b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 6826727cdba6SStefano Zampini 6827a717540cSStefano Zampini /* flush dbg viewer */ 6828b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 6829b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6830b8ffe317SStefano Zampini } 6831a717540cSStefano Zampini 6832e310c8b4SStefano Zampini /* free workspace */ 6833a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 68344641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 683508122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 68369162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 68379162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 683808122e43SStefano Zampini } else { 68399162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 68409162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 68419162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 684208122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 684308122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 68449162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 68459162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 684608122e43SStefano Zampini } 6847674ae819SStefano Zampini PetscFunctionReturn(0); 6848674ae819SStefano Zampini } 684904a6f24aSStefano Zampini /* #undef PETSC_MISSING_LAPACK_GESVD */ 6850674ae819SStefano Zampini 6851674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 6852674ae819SStefano Zampini { 685371582508SStefano Zampini ISLocalToGlobalMapping map; 6854674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6855674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 685666da6bd7Sstefano_zampini PetscInt i,N; 685766da6bd7Sstefano_zampini PetscBool rcsr = PETSC_FALSE; 685866da6bd7Sstefano_zampini PetscErrorCode ierr; 6859674ae819SStefano Zampini 6860674ae819SStefano Zampini PetscFunctionBegin; 68618af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 6862b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 68638e61c736SStefano Zampini /* Reset previously computed graph */ 68648e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 6865674ae819SStefano Zampini /* Init local Graph struct */ 68667fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 686771582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 6868be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 6869674ae819SStefano Zampini 68707a0e7b2cSstefano_zampini if (pcbddc->user_primal_vertices_local && !pcbddc->user_primal_vertices) { 68717a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 68727a0e7b2cSstefano_zampini } 6873575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 6874ab8c8b98SStefano 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); 68759577ea80SStefano Zampini 6876674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 687766da6bd7Sstefano_zampini if (!pcbddc->mat_graph->xadj && pcbddc->use_local_adj) { 68784d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 68794d379d7bSStefano Zampini PetscInt nvtxs; 6880e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 6881674ae819SStefano Zampini 68822fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 68832fffb893SStefano Zampini if (flg_row) { 68844d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 6885b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 68862fffb893SStefano Zampini } 68872fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 688866da6bd7Sstefano_zampini rcsr = PETSC_TRUE; 6889674ae819SStefano Zampini } 68909b28b941SStefano Zampini if (pcbddc->dbg_flag) { 68919b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6892674ae819SStefano Zampini } 6893674ae819SStefano Zampini 6894ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cdim && !pcbddc->mat_graph->cloc) { 6895ab8c8b98SStefano Zampini PetscReal *lcoords; 6896ab8c8b98SStefano Zampini PetscInt n; 6897ab8c8b98SStefano Zampini MPI_Datatype dimrealtype; 6898ab8c8b98SStefano Zampini 6899ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cnloc != pc->pmat->rmap->n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Invalid number of local coordinates! Got %D, expected %D",pcbddc->mat_graph->cnloc,pc->pmat->rmap->n); 6900ab8c8b98SStefano Zampini ierr = MatGetLocalSize(matis->A,&n,NULL);CHKERRQ(ierr); 6901ab8c8b98SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 6902ab8c8b98SStefano Zampini ierr = PetscMalloc1(pcbddc->mat_graph->cdim*n,&lcoords);CHKERRQ(ierr); 6903ab8c8b98SStefano Zampini ierr = MPI_Type_contiguous(pcbddc->mat_graph->cdim,MPIU_REAL,&dimrealtype);CHKERRQ(ierr); 6904ab8c8b98SStefano Zampini ierr = MPI_Type_commit(&dimrealtype);CHKERRQ(ierr); 6905ab8c8b98SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 6906ab8c8b98SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 6907ab8c8b98SStefano Zampini ierr = MPI_Type_free(&dimrealtype);CHKERRQ(ierr); 6908ab8c8b98SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->coords);CHKERRQ(ierr); 6909ab8c8b98SStefano Zampini 6910ab8c8b98SStefano Zampini pcbddc->mat_graph->coords = lcoords; 6911ab8c8b98SStefano Zampini pcbddc->mat_graph->cloc = PETSC_TRUE; 6912ab8c8b98SStefano Zampini pcbddc->mat_graph->cnloc = n; 6913ab8c8b98SStefano Zampini } 6914ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cnloc && pcbddc->mat_graph->cnloc != pcbddc->mat_graph->nvtxs) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Invalid number of local subdomain coordinates! Got %D, expected %D",pcbddc->mat_graph->cnloc,pcbddc->mat_graph->nvtxs); 69151c7a958bSStefano Zampini pcbddc->mat_graph->active_coords = (PetscBool)(pcbddc->corner_selection && !pcbddc->corner_selected); 6916ab8c8b98SStefano Zampini 6917674ae819SStefano Zampini /* Setup of Graph */ 69184b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 691914f95afaSStefano 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); 6920674ae819SStefano Zampini 69214f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 69224f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 69234f1b2e48SStefano Zampini PetscInt *local_subs; 69244f1b2e48SStefano Zampini 69254f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 69264f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 69274f1b2e48SStefano Zampini const PetscInt *idxs; 69284f1b2e48SStefano Zampini PetscInt nl,j; 69294f1b2e48SStefano Zampini 69304f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 69314f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 693271582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 69334f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 69344f1b2e48SStefano Zampini } 69354f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 69364f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 69374f1b2e48SStefano Zampini } 69388af8fcf9SStefano Zampini } 69394f1b2e48SStefano Zampini 6940cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 6941674ae819SStefano Zampini /* Graph's connected components analysis */ 6942674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 694371582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 69448af8fcf9SStefano Zampini } 694566da6bd7Sstefano_zampini if (rcsr) pcbddc->mat_graph->nvtxs_csr = 0; 6946674ae819SStefano Zampini PetscFunctionReturn(0); 6947674ae819SStefano Zampini } 6948674ae819SStefano Zampini 69499a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 69509a7d3425SStefano Zampini { 69519a7d3425SStefano Zampini PetscInt i,j; 69529a7d3425SStefano Zampini PetscScalar *alphas; 69539a7d3425SStefano Zampini PetscErrorCode ierr; 69549a7d3425SStefano Zampini 69559a7d3425SStefano Zampini PetscFunctionBegin; 69568c0031efSStefano Zampini if (!n) PetscFunctionReturn(0); 6957785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 69588c0031efSStefano Zampini ierr = VecNormalize(vecs[0],NULL);CHKERRQ(ierr); 69598c0031efSStefano Zampini for (i=1;i<n;i++) { 69608c0031efSStefano Zampini ierr = VecMDot(vecs[i],i,vecs,alphas);CHKERRQ(ierr); 69618c0031efSStefano Zampini for (j=0;j<i;j++) alphas[j] = PetscConj(-alphas[j]); 69628c0031efSStefano Zampini ierr = VecMAXPY(vecs[i],i,alphas,vecs);CHKERRQ(ierr); 69639a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 69649a7d3425SStefano Zampini } 69659a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 69669a7d3425SStefano Zampini PetscFunctionReturn(0); 69679a7d3425SStefano Zampini } 69689a7d3425SStefano Zampini 6969bb360cb4SStefano Zampini PetscErrorCode PCBDDCMatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 6970e7931f94SStefano Zampini { 697157de7509SStefano Zampini Mat A; 6972e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 6973e7931f94SStefano Zampini PetscMPIInt size,rank,color; 697452e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 697552e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 6976bb360cb4SStefano Zampini PetscInt im_active,active_procs,N,n,i,j,threshold = 2; 697757de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 697827b6a85dSStefano Zampini PetscInt xadj_count,*count; 697927b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 698027b6a85dSStefano Zampini PetscSubcomm psubcomm; 698127b6a85dSStefano Zampini MPI_Comm subcomm; 698252e5ac9dSStefano Zampini PetscErrorCode ierr; 6983a57a6d2fSStefano Zampini 6984e7931f94SStefano Zampini PetscFunctionBegin; 698557de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 698657de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 6987fbfcfee5SBarry 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); 698857de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 698957de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 699057de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 699157de7509SStefano Zampini 699257de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 699357de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 699457de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 699557de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 699657de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 6997bb360cb4SStefano Zampini im_active = !!n; 699857de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 699957de7509SStefano Zampini void_procs = size - active_procs; 700057de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 700157de7509SStefano Zampini if (void_procs) { 700257de7509SStefano Zampini PetscInt ncand; 700357de7509SStefano Zampini 700457de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 700557de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 700657de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 700757de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 700857de7509SStefano Zampini if (!procs_candidates[i]) { 700957de7509SStefano Zampini procs_candidates[ncand++] = i; 701057de7509SStefano Zampini } 701157de7509SStefano Zampini } 701257de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 701357de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 701457de7509SStefano Zampini } 701557de7509SStefano Zampini 7016bb360cb4SStefano Zampini /* number of subdomains requested greater than active processes or matrix size -> just shift the matrix 701714f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 7018bb360cb4SStefano Zampini ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 7019bb360cb4SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1 || N <= *n_subdomains) { 702014f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 702114f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 702214f0bfb9SStefano Zampini else dest = rank; 702357de7509SStefano Zampini if (im_active) { 702457de7509SStefano Zampini issize = 1; 702557de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 702614f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 702757de7509SStefano Zampini } else { 702814f0bfb9SStefano Zampini isidx = dest; 702957de7509SStefano Zampini } 703057de7509SStefano Zampini } else { 703157de7509SStefano Zampini issize = 0; 703257de7509SStefano Zampini isidx = -1; 703357de7509SStefano Zampini } 7034bb360cb4SStefano Zampini if (*n_subdomains != 1) *n_subdomains = active_procs; 703557de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 7036daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 703757de7509SStefano Zampini PetscFunctionReturn(0); 703857de7509SStefano Zampini } 7039c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 7040c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 704127b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 7042e7931f94SStefano Zampini 7043e7931f94SStefano Zampini /* Get info on mapping */ 70443bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 7045e7931f94SStefano Zampini 7046e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 7047785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 7048e7931f94SStefano Zampini xadj[0] = 0; 7049e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 7050785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 7051785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 7052bb360cb4SStefano Zampini ierr = PetscCalloc1(n,&count);CHKERRQ(ierr); 705327b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 705427b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 705527b6a85dSStefano Zampini count[shared[i][j]] += 1; 7056e7931f94SStefano Zampini 705727b6a85dSStefano Zampini xadj_count = 0; 70582b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 705927b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 706027b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 7061d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 7062d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 7063d023bfaeSStefano Zampini xadj_count++; 706427b6a85dSStefano Zampini break; 706527b6a85dSStefano Zampini } 7066e7931f94SStefano Zampini } 7067e7931f94SStefano Zampini } 7068d023bfaeSStefano Zampini xadj[1] = xadj_count; 706927b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 70703bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 7071e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 7072e7931f94SStefano Zampini 70733837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 7074e7931f94SStefano Zampini 707527b6a85dSStefano Zampini /* Restrict work on active processes only */ 707627b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 707727b6a85dSStefano Zampini if (void_procs) { 707827b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 707927b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 708027b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 708127b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 708227b6a85dSStefano Zampini } else { 708327b6a85dSStefano Zampini psubcomm = NULL; 708427b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 708527b6a85dSStefano Zampini } 708627b6a85dSStefano Zampini 708727b6a85dSStefano Zampini v_wgt = NULL; 708827b6a85dSStefano Zampini if (!color) { 7089e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 7090e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 7091e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 7092c8587f34SStefano Zampini } else { 709352e5ac9dSStefano Zampini Mat subdomain_adj; 709452e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 709552e5ac9dSStefano Zampini MatPartitioning partitioner; 709627b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 709752e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 709857de7509SStefano Zampini PetscMPIInt size; 7099b0c7d250SStefano Zampini PetscBool aggregate; 7100b0c7d250SStefano Zampini 710127b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 710227b6a85dSStefano Zampini if (void_procs) { 710327b6a85dSStefano Zampini PetscInt prank = rank; 7104785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 710527b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 7106e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 7107e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 7108c8587f34SStefano Zampini } 7109e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 711027b6a85dSStefano Zampini } else { 711127b6a85dSStefano Zampini oldranks = NULL; 711227b6a85dSStefano Zampini } 7113b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 711427b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 7115b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 7116b0c7d250SStefano Zampini PetscMPIInt nrank; 7117b0c7d250SStefano Zampini PetscScalar *vals; 7118b0c7d250SStefano Zampini 711927b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 7120b0c7d250SStefano Zampini lrows = 0; 7121b0c7d250SStefano Zampini if (nrank<redprocs) { 7122b0c7d250SStefano Zampini lrows = size/redprocs; 7123b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 7124b0c7d250SStefano Zampini } 712527b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 7126b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 7127b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7128b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7129b0c7d250SStefano Zampini row = nrank; 7130b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 7131b0c7d250SStefano Zampini cols = adjncy; 7132b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 7133b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 7134b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 7135b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7136b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 713752e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 713852e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 713952e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 7140b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 714127b6a85dSStefano Zampini if (use_vwgt) { 714227b6a85dSStefano Zampini Vec v; 714327b6a85dSStefano Zampini const PetscScalar *array; 714427b6a85dSStefano Zampini PetscInt nl; 714527b6a85dSStefano Zampini 714627b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 7147bb360cb4SStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)n,INSERT_VALUES);CHKERRQ(ierr); 714827b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 714927b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 715027b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 715127b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 715227b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 715322db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 715427b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 715527b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 715627b6a85dSStefano Zampini } 7157b0c7d250SStefano Zampini } else { 715827b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 715927b6a85dSStefano Zampini if (use_vwgt) { 716027b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 7161bb360cb4SStefano Zampini v_wgt[0] = n; 716227b6a85dSStefano Zampini } 7163b0c7d250SStefano Zampini } 716422b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 7165e7931f94SStefano Zampini 7166e7931f94SStefano Zampini /* Partition */ 716727b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 7168e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 716927b6a85dSStefano Zampini if (v_wgt) { 7170e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 7171c8587f34SStefano Zampini } 717257de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 717357de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 7174e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 7175e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 717622b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 7177e7931f94SStefano Zampini 717852e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 71796583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 718052e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 718152e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 718257de7509SStefano Zampini if (!aggregate) { 718357de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 718427b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 718527b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 718627b6a85dSStefano Zampini #endif 718757de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 718827b6a85dSStefano Zampini } else if (oldranks) { 7189b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 719027b6a85dSStefano Zampini } else { 719127b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 719257de7509SStefano Zampini } 719328143c3dSStefano Zampini } else { 71947fb8a5e4SKarl Rupp PetscInt idx = 0; 7195b0c7d250SStefano Zampini PetscMPIInt tag; 7196b0c7d250SStefano Zampini MPI_Request *reqs; 7197b0c7d250SStefano Zampini 7198b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 7199b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 7200b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 720127b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 720228143c3dSStefano Zampini } 72037fb8a5e4SKarl Rupp ierr = MPI_Recv(&idx,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 7204b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7205b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 720657de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 720727b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 720827b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 720927b6a85dSStefano Zampini #endif 72107fb8a5e4SKarl Rupp ranks_send_to_idx[0] = procs_candidates[oldranks[idx]]; 721127b6a85dSStefano Zampini } else if (oldranks) { 72127fb8a5e4SKarl Rupp ranks_send_to_idx[0] = oldranks[idx]; 721327b6a85dSStefano Zampini } else { 72147fb8a5e4SKarl Rupp ranks_send_to_idx[0] = idx; 7215e7931f94SStefano Zampini } 721657de7509SStefano Zampini } 721752e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 7218e7931f94SStefano Zampini /* clean up */ 7219e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 722052e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 7221e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 7222e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 7223e7931f94SStefano Zampini } 722427b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 722557de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 7226e7931f94SStefano Zampini 7227e7931f94SStefano Zampini /* assemble parallel IS for sends */ 7228e7931f94SStefano Zampini i = 1; 722927b6a85dSStefano Zampini if (!color) i=0; 723057de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 7231e7931f94SStefano Zampini PetscFunctionReturn(0); 7232e7931f94SStefano Zampini } 7233e7931f94SStefano Zampini 7234e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 7235e7931f94SStefano Zampini 72361e0482f5SStefano 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[]) 7237e7931f94SStefano Zampini { 723870cf5478SStefano Zampini Mat local_mat; 7239e7931f94SStefano Zampini IS is_sends_internal; 72409d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 72411ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 72429d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 7243e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 7244e7931f94SStefano Zampini PetscInt* l2gmap_indices; 7245e7931f94SStefano Zampini const PetscInt* is_indices; 7246e7931f94SStefano Zampini MatType new_local_type; 7247e7931f94SStefano Zampini /* buffers */ 7248e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 724928143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 72509d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 7251e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 72521ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 7253e7931f94SStefano Zampini /* MPI */ 725428143c3dSStefano Zampini MPI_Comm comm,comm_n; 725528143c3dSStefano Zampini PetscSubcomm subcomm; 7256e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 725728143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 725828143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 72591ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 72601ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 72611ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 7262e7931f94SStefano Zampini PetscErrorCode ierr; 7263e7931f94SStefano Zampini 7264e7931f94SStefano Zampini PetscFunctionBegin; 726557de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7266e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 7267fbfcfee5SBarry 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); 726857de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 726957de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 727057de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 727157de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 727257de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 72731ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 72741ae86dd6SStefano Zampini if (nvecs) { 72751ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 72761ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 72771ae86dd6SStefano Zampini } 727857de7509SStefano Zampini /* further checks */ 7279e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7280e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 7281e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 7282e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 7283e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 728457de7509SStefano Zampini if (reuse && *mat_n) { 728570cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 728657de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 728770cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 728828143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 728970cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 729070cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 729170cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 729270cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 729370cf5478SStefano Zampini } 7294e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 7295e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 729657de7509SStefano Zampini 7297e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 7298e7931f94SStefano Zampini if (!is_sends) { 729928143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 7300bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 7301c8587f34SStefano Zampini } else { 7302e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 7303e7931f94SStefano Zampini is_sends_internal = is_sends; 7304c8587f34SStefano Zampini } 7305e7931f94SStefano Zampini 7306e7931f94SStefano Zampini /* get comm */ 7307a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 7308e7931f94SStefano Zampini 7309e7931f94SStefano Zampini /* compute number of sends */ 7310e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 7311e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 7312e7931f94SStefano Zampini 7313e7931f94SStefano Zampini /* compute number of receives */ 7314e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 7315785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 7316e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 7317e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7318e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 7319e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 7320e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 7321e7931f94SStefano Zampini 732228143c3dSStefano Zampini /* restrict comm if requested */ 732328143c3dSStefano Zampini subcomm = 0; 732428143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 732528143c3dSStefano Zampini if (restrict_comm) { 7326779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 7327779c1cceSStefano Zampini 732828143c3dSStefano Zampini color = 0; 732953a05cb3SStefano Zampini if (restrict_full) { 733053a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 733153a05cb3SStefano Zampini } else { 733253a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 733353a05cb3SStefano Zampini } 7334b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 733528143c3dSStefano Zampini subcommsize = commsize - subcommsize; 733628143c3dSStefano Zampini /* check if reuse has been requested */ 733757de7509SStefano Zampini if (reuse) { 733828143c3dSStefano Zampini if (*mat_n) { 733928143c3dSStefano Zampini PetscMPIInt subcommsize2; 734028143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 734128143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 734228143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 734328143c3dSStefano Zampini } else { 734428143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 734528143c3dSStefano Zampini } 734628143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 7347779c1cceSStefano Zampini PetscMPIInt rank; 7348779c1cceSStefano Zampini 7349779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 735028143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 735128143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 735228143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 7353306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 735428143c3dSStefano Zampini } 735528143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 735628143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 735728143c3dSStefano Zampini } else { 735828143c3dSStefano Zampini comm_n = comm; 735928143c3dSStefano Zampini } 736028143c3dSStefano Zampini 7361e7931f94SStefano Zampini /* prepare send/receive buffers */ 7362785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 7363e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 7364785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 7365e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 736628143c3dSStefano Zampini if (nis) { 7367854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 736828143c3dSStefano Zampini } 7369e7931f94SStefano Zampini 737028143c3dSStefano Zampini /* Get data from local matrices */ 73716c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 7372e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 7373e7931f94SStefano Zampini /* 7374e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 7375e7931f94SStefano Zampini send_buffer_idxs should contain: 7376e7931f94SStefano Zampini - MatType_PRIVATE type 7377e7931f94SStefano Zampini - PetscInt size_of_l2gmap 7378e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 7379e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 7380e7931f94SStefano Zampini */ 73816c4ed002SBarry Smith else { 7382e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 73833bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 7384854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 7385e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 7386e7931f94SStefano Zampini send_buffer_idxs[1] = i; 73873bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7388e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 73893bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7390e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 7391e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7392e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 7393e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 7394c8587f34SStefano Zampini } 7395c8587f34SStefano Zampini } 7396e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 739728143c3dSStefano Zampini /* additional is (if any) */ 739828143c3dSStefano Zampini if (nis) { 739928143c3dSStefano Zampini PetscMPIInt psum; 740028143c3dSStefano Zampini PetscInt j; 740128143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 740228143c3dSStefano Zampini PetscInt plen; 740328143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 740428143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 740528143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 740628143c3dSStefano Zampini } 7407854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 740828143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 740928143c3dSStefano Zampini PetscInt plen; 741028143c3dSStefano Zampini const PetscInt *is_array_idxs; 741128143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 741228143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 741328143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 741428143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 741528143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 741628143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 741728143c3dSStefano Zampini } 741828143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 741928143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 742028143c3dSStefano Zampini } 742128143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 742228143c3dSStefano Zampini } 74233b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 742428143c3dSStefano Zampini 7425e7931f94SStefano Zampini buf_size_idxs = 0; 7426e7931f94SStefano Zampini buf_size_vals = 0; 742728143c3dSStefano Zampini buf_size_idxs_is = 0; 74281ae86dd6SStefano Zampini buf_size_vecs = 0; 7429e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7430e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 7431e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 743228143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 74331ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 7434e7931f94SStefano Zampini } 7435785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 7436785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 743795ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 74381ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 7439e7931f94SStefano Zampini 7440e7931f94SStefano Zampini /* get new tags for clean communications */ 7441e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 7442e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 744328143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 74441ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 7445e7931f94SStefano Zampini 7446e7931f94SStefano Zampini /* allocate for requests */ 7447785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 7448785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 744995ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 74501ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 7451785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 7452785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 745395ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 74541ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 7455e7931f94SStefano Zampini 7456e7931f94SStefano Zampini /* communications */ 7457e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7458e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 745928143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 74601ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 7461e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7462e7931f94SStefano Zampini source_dest = onodes[i]; 7463e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 7464e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 7465e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7466e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 746728143c3dSStefano Zampini if (nis) { 746857de7509SStefano Zampini source_dest = onodes_is[i]; 746928143c3dSStefano 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); 747028143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 747128143c3dSStefano Zampini } 74721ae86dd6SStefano Zampini if (nvecs) { 74731ae86dd6SStefano Zampini source_dest = onodes[i]; 74741ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 74751ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 74761ae86dd6SStefano Zampini } 7477e7931f94SStefano Zampini } 7478e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7479e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 7480e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 7481e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 748228143c3dSStefano Zampini if (nis) { 748328143c3dSStefano 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); 748428143c3dSStefano Zampini } 74851ae86dd6SStefano Zampini if (nvecs) { 74861ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 74871ae86dd6SStefano 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); 74881ae86dd6SStefano Zampini } 7489e7931f94SStefano Zampini } 7490e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7491e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 7492e7931f94SStefano Zampini 7493e7931f94SStefano Zampini /* assemble new l2g map */ 7494e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7495e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 74969d30be91SStefano Zampini new_local_rows = 0; 7497e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 74989d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7499e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7500e7931f94SStefano Zampini } 75019d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 7502e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 75039d30be91SStefano Zampini new_local_rows = 0; 7504e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 75059d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 75069d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7507e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7508e7931f94SStefano Zampini } 75099d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 75109d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 7511e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 7512e7931f94SStefano Zampini 7513e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 7514e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 7515e7931f94SStefano 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) */ 7516e7931f94SStefano Zampini if (n_recvs) { 751728143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 7518e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7519e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7520e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 7521e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 7522e7931f94SStefano Zampini break; 7523e7931f94SStefano Zampini } 7524e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7525e7931f94SStefano Zampini } 7526e7931f94SStefano Zampini switch (new_local_type_private) { 752728143c3dSStefano Zampini case MATDENSE_PRIVATE: 7528e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7529e7931f94SStefano Zampini bs = 1; 7530e7931f94SStefano Zampini break; 7531e7931f94SStefano Zampini case MATAIJ_PRIVATE: 7532e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7533e7931f94SStefano Zampini bs = 1; 7534e7931f94SStefano Zampini break; 7535e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 7536e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 7537e7931f94SStefano Zampini break; 7538e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 7539e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 7540e7931f94SStefano Zampini break; 7541e7931f94SStefano Zampini default: 7542fbfcfee5SBarry Smith SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,PETSC_FUNCTION_NAME); 7543e7931f94SStefano Zampini break; 7544e7931f94SStefano Zampini } 7545ed8ed4edSstefano_zampini } else { /* by default, new_local_type is seqaij */ 7546ed8ed4edSstefano_zampini new_local_type = MATSEQAIJ; 754728143c3dSStefano Zampini bs = 1; 7548e7931f94SStefano Zampini } 7549e7931f94SStefano Zampini 755070cf5478SStefano Zampini /* create MATIS object if needed */ 755157de7509SStefano Zampini if (!reuse) { 7552e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 7553e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 755470cf5478SStefano Zampini } else { 755570cf5478SStefano Zampini /* it also destroys the local matrices */ 755657de7509SStefano Zampini if (*mat_n) { 755770cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 755857de7509SStefano Zampini } else { /* this is a fake object */ 755957de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 756057de7509SStefano Zampini } 756170cf5478SStefano Zampini } 756270cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 7563e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 75649d30be91SStefano Zampini 75659d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 75669d30be91SStefano Zampini 75679d30be91SStefano Zampini /* Global to local map of received indices */ 75689d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 75699d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 75709d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 75719d30be91SStefano Zampini 75729d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 75739d30be91SStefano Zampini buf_size_idxs = 0; 75749d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 75759d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 75769d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 75779d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 75789d30be91SStefano Zampini } 75799d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 75809d30be91SStefano Zampini 75819d30be91SStefano Zampini /* set preallocation */ 75829d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 75839d30be91SStefano Zampini if (!newisdense) { 75849d30be91SStefano Zampini PetscInt *new_local_nnz=0; 75859d30be91SStefano Zampini 75869d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 75879d30be91SStefano Zampini if (n_recvs) { 75889d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 75899d30be91SStefano Zampini } 75909d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 75919d30be91SStefano Zampini PetscInt j; 75929d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 75939d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 75949d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 75959d30be91SStefano Zampini } 75969d30be91SStefano Zampini } else { 75979d30be91SStefano Zampini /* TODO */ 75989d30be91SStefano Zampini } 75999d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 76009d30be91SStefano Zampini } 76019d30be91SStefano Zampini if (new_local_nnz) { 76029d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 76039d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 76049d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 76059d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 76069d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 76079d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 76089d30be91SStefano Zampini } else { 76099d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 76109d30be91SStefano Zampini } 76119d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 76129d30be91SStefano Zampini } else { 76139d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 76149d30be91SStefano Zampini } 7615e7931f94SStefano Zampini 7616e7931f94SStefano Zampini /* set values */ 7617e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 76189d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 7619e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7620e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 7621e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 76229d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 7623e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7624e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7625e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 762628143c3dSStefano Zampini } else { 762728143c3dSStefano Zampini /* TODO */ 7628e7931f94SStefano Zampini } 7629e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7630e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 7631e7931f94SStefano Zampini } 7632e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7633e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 76343b3b1effSJed Brown ierr = MatISRestoreLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 763570cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 763670cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 76379d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 7638e7931f94SStefano Zampini 7639dfd14d43SStefano Zampini #if 0 764028143c3dSStefano Zampini if (!restrict_comm) { /* check */ 7641e7931f94SStefano Zampini Vec lvec,rvec; 7642e7931f94SStefano Zampini PetscReal infty_error; 7643e7931f94SStefano Zampini 76442a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 7645e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 7646e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 7647e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 764870cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 7649e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 7650e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 7651e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 7652e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 7653e7931f94SStefano Zampini } 765428143c3dSStefano Zampini #endif 7655e7931f94SStefano Zampini 765628143c3dSStefano Zampini /* assemble new additional is (if any) */ 765728143c3dSStefano Zampini if (nis) { 765828143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 765928143c3dSStefano Zampini 766028143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7661854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 766228143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 766328143c3dSStefano Zampini psum = 0; 766428143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 766528143c3dSStefano Zampini for (j=0;j<nis;j++) { 766628143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 766728143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 766828143c3dSStefano Zampini psum += plen; 766928143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 767028143c3dSStefano Zampini } 767128143c3dSStefano Zampini } 7672854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 7673854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 767428143c3dSStefano Zampini for (i=1;i<nis;i++) { 767528143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 767628143c3dSStefano Zampini } 767728143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 767828143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 767928143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 768028143c3dSStefano Zampini for (j=0;j<nis;j++) { 768128143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 768228143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 768328143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 768428143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 768528143c3dSStefano Zampini } 768628143c3dSStefano Zampini } 768728143c3dSStefano Zampini for (i=0;i<nis;i++) { 768828143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 768928143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 769028143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 769128143c3dSStefano Zampini } 769228143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 769328143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 769428143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 769528143c3dSStefano Zampini } 7696e7931f94SStefano Zampini /* free workspace */ 769728143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 7698e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7699e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 7700e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7701e7931f94SStefano Zampini if (isdense) { 7702e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7703e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 77043b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 7705e7931f94SStefano Zampini } else { 7706e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 7707e7931f94SStefano Zampini } 770828143c3dSStefano Zampini if (nis) { 770928143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 771028143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 771128143c3dSStefano Zampini } 77121ae86dd6SStefano Zampini 77131ae86dd6SStefano Zampini if (nvecs) { 77141ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 77151ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 77161ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 77171ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 77181ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 77191ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 77201ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 77211ae86dd6SStefano Zampini /* set values */ 77221ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 77231ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 77241ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 77251ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 77261ae86dd6SStefano Zampini PetscInt j; 77271ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 77281ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 77291ae86dd6SStefano Zampini } 77301ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 77311ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 77321ae86dd6SStefano Zampini } 77331ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 77341ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 77351ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 77361ae86dd6SStefano Zampini } 77371ae86dd6SStefano Zampini 77381ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 77391ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 7740e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 7741e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 77421ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 774328143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 7744e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 7745e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 77461ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 774728143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 7748e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 7749e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 7750e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 7751e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 7752e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 775328143c3dSStefano Zampini if (nis) { 775428143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 775528143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 775628143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 775728143c3dSStefano Zampini } 775828143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 775928143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 776028143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 776128143c3dSStefano Zampini for (i=0;i<nis;i++) { 776228143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 776328143c3dSStefano Zampini } 77641ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 77651ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 77661ae86dd6SStefano Zampini } 776753a05cb3SStefano Zampini *mat_n = NULL; 776828143c3dSStefano Zampini } 7769e7931f94SStefano Zampini PetscFunctionReturn(0); 7770e7931f94SStefano Zampini } 7771a57a6d2fSStefano Zampini 777212edc857SStefano Zampini /* temporary hack into ksp private data structure */ 7773af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 777412edc857SStefano Zampini 7775c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 7776c8587f34SStefano Zampini { 7777c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7778c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 777920a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 77801ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 77811e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 77829881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 778320a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 77846e683305SStefano Zampini IS coarse_is,*isarray; 77856e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 778630368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 7787f9eb5b7dSStefano Zampini PC pc_temp; 7788c8587f34SStefano Zampini PCType coarse_pc_type; 7789c8587f34SStefano Zampini KSPType coarse_ksp_type; 7790f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 77917274672aSStefano Zampini PetscBool coarse_reuse; 77921e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 779368457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 779422bc73bbSStefano Zampini PetscScalar *array; 779557de7509SStefano Zampini MatReuse coarse_mat_reuse; 779657de7509SStefano Zampini PetscBool restr, full_restr, have_void; 77977de4f681Sstefano_zampini PetscMPIInt commsize; 77989881197aSStefano Zampini PetscErrorCode ierr; 7799fdc09c96SStefano Zampini 7800c8587f34SStefano Zampini PetscFunctionBegin; 7801c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 780268457ee5SStefano 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 */ 7803fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 78045a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 78057de4f681Sstefano_zampini 78067de4f681Sstefano_zampini pcbddc->new_primal_space = PETSC_TRUE; 7807fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 7808f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 7809f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 7810f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 7811fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 781251bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 781351bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 7814727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 7815fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7816fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 7817fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7818f4ddd8eeSStefano Zampini } 7819fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 7820fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7821f4ddd8eeSStefano Zampini } 782270cf5478SStefano Zampini /* reset any subassembling information */ 782357de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 782470cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 782557de7509SStefano Zampini } 78266e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 7827fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7828f4ddd8eeSStefano Zampini } 782957de7509SStefano Zampini /* assemble coarse matrix */ 783057de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 783157de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 783257de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 783357de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 783418a45a71SStefano Zampini } else { 783557de7509SStefano Zampini coarse_mat = NULL; 783657de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 78376e683305SStefano Zampini } 7838e7931f94SStefano Zampini 7839abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 7840abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 7841abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 7842abbbba34SStefano Zampini 7843abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 784422bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 784522bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 784622bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 784722bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 7848e176bc59SStefano 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); 78496e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 78506e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 78516e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7852abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 7853abbbba34SStefano Zampini 785457de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 785557de7509SStefano Zampini im_active = !!(pcis->n); 785657de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 785757de7509SStefano Zampini 785814f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 785957de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 786057de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 78617de4f681Sstefano_zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&commsize);CHKERRQ(ierr); 786257de7509SStefano Zampini coarse_mat_is = NULL; 786357de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 786457de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 78651ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 786657de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 786757de7509SStefano Zampini if (multilevel_requested) { 786857de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 786957de7509SStefano Zampini restr = PETSC_FALSE; 787057de7509SStefano Zampini full_restr = PETSC_FALSE; 787157de7509SStefano Zampini } else { 787257de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 787357de7509SStefano Zampini restr = PETSC_TRUE; 787457de7509SStefano Zampini full_restr = PETSC_TRUE; 787557de7509SStefano Zampini } 78767de4f681Sstefano_zampini if (!pcbddc->coarse_size || commsize == 1) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 787757de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 787857de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 7879a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 7880bb360cb4SStefano Zampini if (multilevel_requested) { 7881bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7882bb360cb4SStefano Zampini } else { 7883bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7884bb360cb4SStefano Zampini } 7885a198735bSStefano Zampini } else { 78867de4f681Sstefano_zampini PetscMPIInt rank; 7887a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 78887de4f681Sstefano_zampini have_void = (active_procs == (PetscInt)commsize) ? PETSC_FALSE : PETSC_TRUE; 7889a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 7890a198735bSStefano Zampini } 789157de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 789257de7509SStefano Zampini PetscInt psum; 789357de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 789457de7509SStefano Zampini else psum = 0; 789557de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 78967de4f681Sstefano_zampini if (ncoarse < commsize) have_void = PETSC_TRUE; 789757de7509SStefano Zampini } 789857de7509SStefano Zampini /* determine if we can go multilevel */ 789957de7509SStefano Zampini if (multilevel_requested) { 790057de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 790157de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 790257de7509SStefano Zampini } 790357de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 790457de7509SStefano Zampini 7905e4d548c7SStefano Zampini /* dump subassembling pattern */ 7906e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 7907e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 7908e4d548c7SStefano Zampini } 7909e4d548c7SStefano Zampini 79106e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 79111e0482f5SStefano Zampini nedcfield = -1; 79121e0482f5SStefano Zampini if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal)) { /* protects from unneded computations */ 79136e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 79146e683305SStefano Zampini const PetscInt *idxs; 79156e683305SStefano Zampini ISLocalToGlobalMapping tmap; 79166e683305SStefano Zampini 79176e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 79180be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 79196e683305SStefano Zampini /* allocate space for temporary storage */ 7920854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 7921854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 79226e683305SStefano Zampini /* allocate for IS array */ 79236e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 79241e0482f5SStefano Zampini if (pcbddc->nedclocal) { 79251e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 79261e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 79271e0482f5SStefano Zampini } else { 79281e0482f5SStefano Zampini nedcfield = 0; 79291e0482f5SStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%d)",nisdofs); 79301e0482f5SStefano Zampini nisdofs = 1; 79311e0482f5SStefano Zampini } 79321e0482f5SStefano Zampini } 79336e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 793427b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 793530368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 7936854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 79376e683305SStefano Zampini /* dofs splitting */ 79386e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 79396e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 79401e0482f5SStefano Zampini if (nedcfield != i) { 79416e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 79426e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 79436e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 79446e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 79451e0482f5SStefano Zampini } else { 79461e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 79471e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 79481e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 7949eee23b56SStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping coarse nedelec field! %d != %d\n",tsize,nout); 79501e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 79511e0482f5SStefano Zampini } 79526e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 795330368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 79546e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 79556e683305SStefano Zampini } 79566e683305SStefano Zampini /* neumann boundaries */ 79576e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 79586e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 79596e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 79606e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 79616e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 79626e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 79636e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 796430368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 79656e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 79666e683305SStefano Zampini } 79676e683305SStefano Zampini /* free memory */ 79686e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 79696e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 79706e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 79716e683305SStefano Zampini } else { 79726e683305SStefano Zampini nis = 0; 79736e683305SStefano Zampini nisdofs = 0; 79746e683305SStefano Zampini nisneu = 0; 797530368db7SStefano Zampini nisvert = 0; 79766e683305SStefano Zampini isarray = NULL; 79776e683305SStefano Zampini } 79786e683305SStefano Zampini /* destroy no longer needed map */ 79796e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 79806e683305SStefano Zampini 798157de7509SStefano Zampini /* subassemble */ 798257de7509SStefano Zampini if (multilevel_allowed) { 79831ae86dd6SStefano Zampini Vec vp[1]; 79841ae86dd6SStefano Zampini PetscInt nvecs = 0; 798557de7509SStefano Zampini PetscBool reuse,reuser; 79861ae86dd6SStefano Zampini 798757de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 798857de7509SStefano Zampini else reuse = PETSC_FALSE; 798957de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 79901ae86dd6SStefano Zampini vp[0] = NULL; 79911ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 79921ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 79931ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 79941ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 79951ae86dd6SStefano Zampini nvecs = 1; 79961ae86dd6SStefano Zampini 79971ae86dd6SStefano Zampini if (pcbddc->divudotp) { 7998a198735bSStefano Zampini Mat B,loc_divudotp; 79991ae86dd6SStefano Zampini Vec v,p; 80001ae86dd6SStefano Zampini IS dummy; 80011ae86dd6SStefano Zampini PetscInt np; 80021ae86dd6SStefano Zampini 8003a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 8004a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 80051ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 80067dae84e0SHong Zhang ierr = MatCreateSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 80071ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 80081ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 80091ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 80101ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 80111ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 80121ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 80131ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 80141ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 80151ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 80161ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 80171ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 80181ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 801974e2c79eSStefano Zampini } 80201ae86dd6SStefano Zampini } 80211ae86dd6SStefano Zampini if (reuser) { 80221e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 802374e2c79eSStefano Zampini } else { 80241e0482f5SStefano 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); 80251ae86dd6SStefano Zampini } 80261ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 80271ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 80281ae86dd6SStefano Zampini PetscInt nl; 80291ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 80301ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 80311ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 80321ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 80331ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 80341ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 80351ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 80361ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 8037a198735bSStefano Zampini } else { 8038a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 80391ae86dd6SStefano Zampini } 80401ae86dd6SStefano Zampini } else { 80411e0482f5SStefano 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); 80426e683305SStefano Zampini } 804357de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 804457de7509SStefano Zampini PetscMPIInt size; 8045f913dca9SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size);CHKERRQ(ierr); 804657de7509SStefano Zampini if (!multilevel_allowed) { 804757de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 80486e683305SStefano Zampini } else { 804957de7509SStefano Zampini Mat A; 8050779c1cceSStefano Zampini 805157de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 805257de7509SStefano Zampini if (coarse_mat_is) { 805357de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 805457de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 805557de7509SStefano Zampini coarse_mat = coarse_mat_is; 805657de7509SStefano Zampini } 805757de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 805857de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 805957de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 8060779c1cceSStefano Zampini } 8061779c1cceSStefano Zampini } 806257de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 806357de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 80646e683305SStefano Zampini 80656e683305SStefano Zampini /* create local to global scatters for coarse problem */ 806668457ee5SStefano Zampini if (compute_vecs) { 80676e683305SStefano Zampini PetscInt lrows; 80686e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 806957de7509SStefano Zampini if (coarse_mat) { 807057de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 80716e683305SStefano Zampini } else { 80726e683305SStefano Zampini lrows = 0; 80736e683305SStefano Zampini } 80746e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 80756e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 80766e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 80776e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 80786e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 80796e683305SStefano Zampini } 80806e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 8081c8587f34SStefano Zampini 8082f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 8083f9eb5b7dSStefano Zampini if (multilevel_allowed) { 8084f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 8085f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 8086f9eb5b7dSStefano Zampini } else { 8087f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 8088f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 8089c8587f34SStefano Zampini } 8090c8587f34SStefano Zampini 80916e683305SStefano Zampini /* print some info if requested */ 80926e683305SStefano Zampini if (pcbddc->dbg_flag) { 80936e683305SStefano Zampini if (!multilevel_allowed) { 80946e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 80956e683305SStefano Zampini if (multilevel_requested) { 80966e683305SStefano 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); 80976e683305SStefano Zampini } else if (pcbddc->max_levels) { 80986e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 80996e683305SStefano Zampini } 81006e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 81016e683305SStefano Zampini } 81026e683305SStefano Zampini } 81036e683305SStefano Zampini 81041e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 81051e0482f5SStefano Zampini coarseG = NULL; 81061e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 81071e0482f5SStefano Zampini MPI_Comm ccomm; 81081e0482f5SStefano Zampini if (coarse_mat) { 81091e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 81101e0482f5SStefano Zampini } else { 81111e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 81121e0482f5SStefano Zampini } 81131e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 81141e0482f5SStefano Zampini } 81151e0482f5SStefano Zampini 8116f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 811757de7509SStefano Zampini if (coarse_mat) { 81187274672aSStefano Zampini PetscBool isredundant,isnn,isbddc; 81196a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 81207274672aSStefano Zampini 81216e683305SStefano Zampini if (pcbddc->dbg_flag) { 812257de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 81236e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 81246e683305SStefano Zampini } 8125f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 8126312be037SStefano Zampini char prefix[256],str_level[16]; 8127e604994aSStefano Zampini size_t len; 81281e0482f5SStefano Zampini 812957de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 8130422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 8131c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 8132f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 813357de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8134c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 81356e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 8136c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 81371e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 8138c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8139e604994aSStefano Zampini /* prefix */ 8140e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 8141e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 8142e604994aSStefano Zampini if (!pcbddc->current_level) { 8143a126751eSBarry Smith ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,sizeof(prefix));CHKERRQ(ierr); 8144a126751eSBarry Smith ierr = PetscStrlcat(prefix,"pc_bddc_coarse_",sizeof(prefix));CHKERRQ(ierr); 8145c8587f34SStefano Zampini } else { 8146e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 8147312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 8148312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 8149a126751eSBarry Smith /* Nonstandard use of PetscStrncpy() to copy only a portion of the string */ 815034d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 815135529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 8152a126751eSBarry Smith ierr = PetscStrlcat(prefix,str_level,sizeof(prefix));CHKERRQ(ierr); 8153e604994aSStefano Zampini } 8154e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 81553e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 81563e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 81573e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 81583e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 8159f9eb5b7dSStefano Zampini /* allow user customization */ 8160f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 81613e3c6dadSStefano Zampini } 81623e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 816351bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 81643e3c6dadSStefano Zampini if (nisdofs) { 81653e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 81663e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 81673e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 81683e3c6dadSStefano Zampini } 81693e3c6dadSStefano Zampini } 81703e3c6dadSStefano Zampini if (nisneu) { 81713e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 81723e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 8173312be037SStefano Zampini } 817430368db7SStefano Zampini if (nisvert) { 817530368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 817630368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 817730368db7SStefano Zampini } 81781e0482f5SStefano Zampini if (coarseG) { 81791e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 81801e0482f5SStefano Zampini } 8181f9eb5b7dSStefano Zampini 8182f9eb5b7dSStefano Zampini /* get some info after set from options */ 8183f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 8184b76f3995Sstefano_zampini /* multilevel can only be requested via -pc_bddc_levels or PCBDDCSetLevels */ 8185b76f3995Sstefano_zampini if (isbddc && !multilevel_allowed) { 8186f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8187f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 8188f9eb5b7dSStefano Zampini } 8189b76f3995Sstefano_zampini /* multilevel cannot be done with coarse PCs different from BDDC or NN */ 81907274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 81917274672aSStefano Zampini if (multilevel_requested && multilevel_allowed && !isbddc && !isnn) { 8192b76f3995Sstefano_zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 8193b76f3995Sstefano_zampini isbddc = PETSC_TRUE; 8194b76f3995Sstefano_zampini } 81957274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 81964f3a063dSStefano Zampini if (isredundant) { 81974f3a063dSStefano Zampini KSP inner_ksp; 81984f3a063dSStefano Zampini PC inner_pc; 81999326c5c6Sstefano_zampini 82004f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 82014f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 82024f3a063dSStefano Zampini } 8203f9eb5b7dSStefano Zampini 820457de7509SStefano Zampini /* parameters which miss an API */ 82057274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 820657de7509SStefano Zampini if (isbddc) { 8207720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 82087274672aSStefano Zampini 8209720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 821057de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 821127b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 821227b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 8213a198735bSStefano Zampini Mat coarsedivudotp_is; 8214a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 8215a198735bSStefano Zampini IS row,col; 8216a198735bSStefano Zampini const PetscInt *gidxs; 8217a198735bSStefano Zampini PetscInt n,st,M,N; 8218a198735bSStefano Zampini 8219a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 8220a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 8221a198735bSStefano Zampini st = st-n; 8222a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 8223a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 8224a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 8225a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8226a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 8227a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8228a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 8229a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 8230a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 8231a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 8232a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 8233a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 8234a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 8235a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 8236a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 8237a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 8238a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 8239a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 8240a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 8241a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 82428ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 8243a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 8244720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 8245bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[0] == 0.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 8246720d30f9SStefano Zampini } 8247d4d8cf7bSStefano Zampini } 82489881197aSStefano Zampini 82493301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 82505a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 82513301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 82523301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 82533301b35fSStefano Zampini } 82543301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 82553301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 82563301b35fSStefano Zampini } 82573301b35fSStefano Zampini if (pc->pmat->spd_set) { 82583301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 82593301b35fSStefano Zampini } 826027b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 826127b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 826227b6a85dSStefano Zampini } 82636e683305SStefano Zampini /* set operators */ 826404fe1396SStefano Zampini ierr = MatViewFromOptions(coarse_mat,(PetscObject)pc,"-pc_bddc_coarse_mat_view");CHKERRQ(ierr); 82655f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 82666e683305SStefano Zampini if (pcbddc->dbg_flag) { 82676e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 82686e683305SStefano Zampini } 82696e683305SStefano Zampini } 82701e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 82716e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 8272b1ecc7b1SStefano Zampini #if 0 8273b9b85e73SStefano Zampini { 8274b9b85e73SStefano Zampini PetscViewer viewer; 8275b9b85e73SStefano Zampini char filename[256]; 8276b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 8277b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 82786a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 8279b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 8280f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 8281b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 8282b9b85e73SStefano Zampini } 8283b9b85e73SStefano Zampini #endif 8284f9eb5b7dSStefano Zampini 828598a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 828698a51de6SStefano Zampini Vec crhs,csol; 828704708bb6SStefano Zampini 8288f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 8289f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 8290f347579bSStefano Zampini if (!csol) { 82912a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 8292f9eb5b7dSStefano Zampini } 8293f347579bSStefano Zampini if (!crhs) { 82942a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 8295f347579bSStefano Zampini } 8296b0f5fe93SStefano Zampini } 82971ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 8298b0f5fe93SStefano Zampini 8299b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 8300b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 8301b0f5fe93SStefano Zampini 8302b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 83034f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 83044f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 83054f1b2e48SStefano Zampini } 8306b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 8307b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 8308b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8309b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8310b0f5fe93SStefano Zampini if (coarse_mat) { 8311b0f5fe93SStefano Zampini Vec nullv; 8312b0f5fe93SStefano Zampini PetscScalar *array,*array2; 8313b0f5fe93SStefano Zampini PetscInt nl; 8314b0f5fe93SStefano Zampini 8315b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 8316b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 8317b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8318b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 8319b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 8320b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 8321b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8322b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 8323b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 8324b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 8325b0f5fe93SStefano Zampini } 8326b0f5fe93SStefano Zampini } 8327b0f5fe93SStefano Zampini 8328b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 8329b0f5fe93SStefano Zampini PetscBool ispreonly; 8330b0f5fe93SStefano Zampini 8331b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8332b0f5fe93SStefano Zampini PetscBool isnull; 8333b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 8334bef83e63SStefano Zampini if (isnull) { 8335b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 8336b0f5fe93SStefano Zampini } 8337bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 8338b0f5fe93SStefano Zampini } 8339b0f5fe93SStefano Zampini /* setup coarse ksp */ 8340b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 8341cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 8342cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 83436e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 8344c8587f34SStefano Zampini KSP check_ksp; 83452b510759SStefano Zampini KSPType check_ksp_type; 8346c8587f34SStefano Zampini PC check_pc; 83476e683305SStefano Zampini Vec check_vec,coarse_vec; 83486a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 83492b510759SStefano Zampini PetscInt its; 83506e683305SStefano Zampini PetscBool compute_eigs; 83516e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 83526e683305SStefano Zampini PetscInt neigs; 83538e185a42SStefano Zampini const char *prefix; 8354c8587f34SStefano Zampini 83552b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 83566e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 8357422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 835823ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8359f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 8360e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 8361e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 8362e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 83632b510759SStefano Zampini if (ispreonly) { 83642b510759SStefano Zampini check_ksp_type = KSPPREONLY; 83656e683305SStefano Zampini compute_eigs = PETSC_FALSE; 83662b510759SStefano Zampini } else { 8367cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 83686e683305SStefano Zampini compute_eigs = PETSC_TRUE; 8369c8587f34SStefano Zampini } 8370c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 83716e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 83726e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 83736e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 8374a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 8375a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 8376a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 8377a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 8378c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 8379c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 8380c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 8381c8587f34SStefano Zampini /* create random vec */ 83822701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 8383c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 83846e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 8385c8587f34SStefano Zampini /* solve coarse problem */ 83866e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 8387cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 83886e683305SStefano Zampini if (compute_eigs) { 8389854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 8390854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 83916e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 83921ae86dd6SStefano Zampini if (neigs) { 83936e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 83946e683305SStefano Zampini lambda_min = eigs_r[0]; 83956e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 83962701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 83972701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 8398cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 8399cbcc2c2aSStefano Zampini } 8400c8587f34SStefano Zampini } 8401c8587f34SStefano Zampini } 84021ae86dd6SStefano Zampini } 8403cbcc2c2aSStefano Zampini 8404c8587f34SStefano Zampini /* check coarse problem residual error */ 84056e683305SStefano Zampini if (pcbddc->dbg_flag) { 84066e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 84076e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 84086e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 8409c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 84106e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 84116e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 8412779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 84136e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 84146e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 84156e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 84166e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 8417b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8418b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 8419b0f5fe93SStefano Zampini } 84206e683305SStefano Zampini if (compute_eigs) { 84216e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 8422b03ebc13SStefano Zampini KSPConvergedReason reason; 8423deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 8424c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 8425b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 84266e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 8427b03ebc13SStefano 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); 84286e683305SStefano Zampini for (i=0;i<neigs;i++) { 84296e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 8430c8587f34SStefano Zampini } 84316e683305SStefano Zampini } 84326e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 84336e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 84346e683305SStefano Zampini } 8435e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 84362701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 8437c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 84386e683305SStefano Zampini if (compute_eigs) { 84396e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 84406e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 8441c8587f34SStefano Zampini } 84426e683305SStefano Zampini } 84436e683305SStefano Zampini } 8444bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 8445cbcc2c2aSStefano Zampini /* print additional info */ 8446cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 84476e683305SStefano Zampini /* waits until all processes reaches this point */ 84486e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 8449cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 8450cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8451cbcc2c2aSStefano Zampini } 8452cbcc2c2aSStefano Zampini 84532b510759SStefano Zampini /* free memory */ 8454fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 8455c8587f34SStefano Zampini PetscFunctionReturn(0); 8456c8587f34SStefano Zampini } 8457674ae819SStefano Zampini 8458f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 8459f34684f1SStefano Zampini { 8460f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 8461f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 8462f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 8463dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 8464dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 846573be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 8466dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 8467f34684f1SStefano Zampini PetscErrorCode ierr; 8468f34684f1SStefano Zampini 8469f34684f1SStefano Zampini PetscFunctionBegin; 8470f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 84716c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 8472dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 84733bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 8474dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8475dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 84766583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 8477dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 8478dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 8479dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 84806c4ed002SBarry 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); 8481dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 8482dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8483dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 8484dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8485dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8486f34684f1SStefano Zampini 8487f34684f1SStefano Zampini /* check numbering */ 8488f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 8489019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 8490dc456d91SStefano Zampini PetscInt i; 8491b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 8492f34684f1SStefano Zampini 8493f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8494f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8495f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 84961575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8497019a44ceSStefano Zampini /* counter */ 8498019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8499019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 8500019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8501019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8502019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8503019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8504f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 8505f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 8506727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 8507f34684f1SStefano Zampini } 8508f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8509f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8510f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8511e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8512e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8513e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8514e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8515f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8516019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8517f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8518019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 85192c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 852075c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 8521b9b85e73SStefano Zampini set_error = PETSC_TRUE; 85222c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 85232c66d082SStefano 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); 8524f34684f1SStefano Zampini } 8525f34684f1SStefano Zampini } 8526019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8527b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8528f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8529f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8530f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 8531f34684f1SStefano Zampini } 8532f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8533f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8534e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8535e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8536f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 8537f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 8538b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 8539ca8b9ea9SStefano Zampini PetscInt *gidxs; 8540ca8b9ea9SStefano Zampini 8541ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 85423bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 8543f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 8544f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8545f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 8546f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 85474bc2dc4bSStefano 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); 8548f34684f1SStefano Zampini } 8549f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8550ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 8551f34684f1SStefano Zampini } 8552f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 85531575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8554302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 8555f34684f1SStefano Zampini } 85568bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 8557f34684f1SStefano Zampini /* get back data */ 8558f34684f1SStefano Zampini *coarse_size_n = coarse_size; 8559f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 8560674ae819SStefano Zampini PetscFunctionReturn(0); 8561674ae819SStefano Zampini } 8562674ae819SStefano Zampini 8563a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 8564e456f2a8SStefano Zampini { 8565e456f2a8SStefano Zampini IS localis_t; 8566a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 8567e456f2a8SStefano Zampini PetscScalar *vals; 8568e456f2a8SStefano Zampini PetscErrorCode ierr; 8569e456f2a8SStefano Zampini 8570e456f2a8SStefano Zampini PetscFunctionBegin; 8571a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 8572e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 8573854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 8574e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 8575e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8576a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 8577a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 85781035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 85793151afb1SStefano Zampini ierr = VecSetOption(gwork,VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE);CHKERRQ(ierr); 8580a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 85811035eff8SStefano Zampini } 8582a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 8583e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8584e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 8585a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 8586a7dc3881SStefano Zampini /* now compute set in local ordering */ 8587a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8588a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8589a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8590a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 8591a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8592ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8593e456f2a8SStefano Zampini lsize++; 8594e456f2a8SStefano Zampini } 8595e456f2a8SStefano Zampini } 8596854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 8597a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8598ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8599e456f2a8SStefano Zampini idxs[lsize++] = i; 8600e456f2a8SStefano Zampini } 8601e456f2a8SStefano Zampini } 8602a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8603a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 8604e456f2a8SStefano Zampini *localis = localis_t; 8605e456f2a8SStefano Zampini PetscFunctionReturn(0); 8606e456f2a8SStefano Zampini } 8607906d46d4SStefano Zampini 860808122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 8609b96c3477SStefano Zampini { 8610a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8611b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8612b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 8613a64f4aa4SStefano Zampini Mat S_j; 8614b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 8615b96c3477SStefano Zampini PetscBool free_used_adj; 8616b96c3477SStefano Zampini PetscErrorCode ierr; 8617b96c3477SStefano Zampini 8618b96c3477SStefano Zampini PetscFunctionBegin; 8619b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 8620b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 862108122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 8622b96c3477SStefano Zampini used_xadj = NULL; 8623b96c3477SStefano Zampini used_adjncy = NULL; 8624b96c3477SStefano Zampini } else { 862508122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 862608122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 862708122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 862808122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 8629b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 8630b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 8631b96c3477SStefano Zampini } else { 86322fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 8633b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 8634b96c3477SStefano Zampini PetscInt nvtxs; 8635b96c3477SStefano Zampini 86362fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 86372fffb893SStefano Zampini if (flg_row) { 8638b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 8639b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 8640b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 8641b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 86422fffb893SStefano Zampini } else { 86432fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 86442fffb893SStefano Zampini used_xadj = NULL; 86452fffb893SStefano Zampini used_adjncy = NULL; 86462fffb893SStefano Zampini } 86472fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 8648b96c3477SStefano Zampini } 8649b96c3477SStefano Zampini } 8650d5574798SStefano Zampini 8651d5574798SStefano Zampini /* setup sub_schurs data */ 8652a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8653df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 8654df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 8655a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 865691af6908SStefano 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); 8657a64f4aa4SStefano Zampini } else { 865872b8c272SStefano Zampini Mat change = NULL; 86599d54b7f4SStefano Zampini Vec scaling = NULL; 8660111315fdSstefano_zampini IS change_primal = NULL, iP; 8661111315fdSstefano_zampini PetscInt benign_n; 8662111315fdSstefano_zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 8663111315fdSstefano_zampini PetscBool isseqaij,need_change = PETSC_FALSE; 8664111315fdSstefano_zampini PetscBool discrete_harmonic = PETSC_FALSE; 8665a3df083aSStefano Zampini 86665feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 86675feab87aSStefano Zampini PetscInt n_vertices; 86685feab87aSStefano Zampini 86695feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 86702034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 86715feab87aSStefano Zampini } 867204708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 867304708bb6SStefano Zampini if (!isseqaij) { 867404708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 867504708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 867604708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 867704708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 867804708bb6SStefano Zampini } else { 8679511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 868004708bb6SStefano Zampini } 868104708bb6SStefano Zampini } 8682a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 8683a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 8684ca92afb2SStefano Zampini } else { 8685a3df083aSStefano Zampini benign_n = 0; 8686ca92afb2SStefano Zampini } 8687b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 8688b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 8689b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 869072b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 869122db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 8692b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 869322db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 8694b7ab4a40SStefano Zampini } 8695b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 8696b7ab4a40SStefano 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 */ 8697b7ab4a40SStefano Zampini if (need_change) { 869888c03ad3SStefano Zampini PC_IS *pcisf; 869988c03ad3SStefano Zampini PC_BDDC *pcbddcf; 870088c03ad3SStefano Zampini PC pcf; 870188c03ad3SStefano Zampini 8702e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 870388c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 870488c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 870588c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 8706b9be95fcSstefano_zampini 870788c03ad3SStefano Zampini /* hacks */ 870888c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 870972b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 871072b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 871172b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 871272b8c272SStefano Zampini pcisf->n = pcis->n; 871372b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 871488c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 871588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 871688c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 871788c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 871888c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 871988c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 872072b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 872188c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 8722b9be95fcSstefano_zampini 8723b9be95fcSstefano_zampini /* setup constraints so that we can get information on primal vertices and change of basis (in local numbering) */ 872488c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 872572b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 872672b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 872772b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 872872b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 8729b9be95fcSstefano_zampini 873088c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 873172b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 873288c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 873388c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 873488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 873588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 873688c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 873788c03ad3SStefano Zampini pcf->ops->destroy = NULL; 8738b9be95fcSstefano_zampini pcf->ops->reset = NULL; 873988c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 874088c03ad3SStefano Zampini } 87419d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 8742111315fdSstefano_zampini 8743111315fdSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 8744111315fdSstefano_zampini if (iP) { 8745111315fdSstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)iP),sub_schurs->prefix,"BDDC sub_schurs options","PC");CHKERRQ(ierr); 8746111315fdSstefano_zampini ierr = PetscOptionsBool("-sub_schurs_discrete_harmonic",NULL,NULL,discrete_harmonic,&discrete_harmonic,NULL);CHKERRQ(ierr); 8747111315fdSstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 8748111315fdSstefano_zampini } 8749111315fdSstefano_zampini if (discrete_harmonic) { 8750111315fdSstefano_zampini Mat A; 8751111315fdSstefano_zampini ierr = MatDuplicate(pcbddc->local_mat,MAT_COPY_VALUES,&A);CHKERRQ(ierr); 8752111315fdSstefano_zampini ierr = MatZeroRowsColumnsIS(A,iP,1.0,NULL,NULL);CHKERRQ(ierr); 8753111315fdSstefano_zampini ierr = PetscObjectCompose((PetscObject)A,"__KSPFETIDP_iP",(PetscObject)iP);CHKERRQ(ierr); 8754111315fdSstefano_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); 8755111315fdSstefano_zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 8756111315fdSstefano_zampini } else { 875791af6908SStefano 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); 8758111315fdSstefano_zampini } 875972b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 876072b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 8761ca92afb2SStefano Zampini } 8762d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8763b96c3477SStefano Zampini 8764b96c3477SStefano Zampini /* free adjacency */ 8765b96c3477SStefano Zampini if (free_used_adj) { 8766b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 8767b96c3477SStefano Zampini } 8768b96c3477SStefano Zampini PetscFunctionReturn(0); 8769b96c3477SStefano Zampini } 8770b96c3477SStefano Zampini 877108122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 8772b96c3477SStefano Zampini { 8773b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8774b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8775b96c3477SStefano Zampini PCBDDCGraph graph; 8776b96c3477SStefano Zampini PetscErrorCode ierr; 8777b96c3477SStefano Zampini 8778b96c3477SStefano Zampini PetscFunctionBegin; 8779b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 878008122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 87813301b35fSStefano Zampini IS verticesIS,verticescomm; 87823301b35fSStefano Zampini PetscInt vsize,*idxs; 8783b96c3477SStefano Zampini 8784b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 87853301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 87863301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 87873301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 87883301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 8789c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 8790b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 8791be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 8792441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 87933301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 8794b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 8795b96c3477SStefano Zampini } else { 8796b96c3477SStefano Zampini graph = pcbddc->mat_graph; 8797b96c3477SStefano Zampini } 8798e4d548c7SStefano Zampini /* print some info */ 87995c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 8800e4d548c7SStefano Zampini IS vertices; 8801e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 8802c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 8803e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8804e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 8805e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8806e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 8807e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 8808e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 8809e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 8810e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8811e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8812c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8813e4d548c7SStefano Zampini } 8814b96c3477SStefano Zampini 8815b96c3477SStefano Zampini /* sub_schurs init */ 8816b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 8817b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 8818b334f244SStefano Zampini } 881988113c35SStefano Zampini ierr = PCBDDCSubSchursInit(pcbddc->sub_schurs,((PetscObject)pc)->prefix,pcis->is_I_local,pcis->is_B_local,graph,pcis->BtoNmap,pcbddc->sub_schurs_rebuild);CHKERRQ(ierr); 8820a64f4aa4SStefano Zampini 8821b96c3477SStefano Zampini /* free graph struct */ 882208122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 8823b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 8824b96c3477SStefano Zampini } 8825b96c3477SStefano Zampini PetscFunctionReturn(0); 8826b96c3477SStefano Zampini } 8827fa34dd3eSStefano Zampini 8828fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 8829fa34dd3eSStefano Zampini { 8830fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8831fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8832fa34dd3eSStefano Zampini PetscErrorCode ierr; 8833fa34dd3eSStefano Zampini 8834fa34dd3eSStefano Zampini PetscFunctionBegin; 8835fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 8836fa34dd3eSStefano Zampini IS zerodiag = NULL; 88374f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 8838fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 88394f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 884075c01103SStefano Zampini PetscReal norm; 8841fa34dd3eSStefano Zampini PetscInt i; 8842fa34dd3eSStefano Zampini 8843fa34dd3eSStefano Zampini /* B0 and B0_B */ 8844fa34dd3eSStefano Zampini if (zerodiag) { 8845fa34dd3eSStefano Zampini IS dummy; 8846fa34dd3eSStefano Zampini 88474f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 88487dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 8849fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 8850fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 8851fa34dd3eSStefano Zampini } 8852fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 8853fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 8854fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 8855fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8856fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8857fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8858fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8859fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 8860fa34dd3eSStefano Zampini /* S_j */ 8861fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8862fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 8863fa34dd3eSStefano Zampini 8864fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 8865fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 8866fa34dd3eSStefano Zampini /* continuous in primal space */ 8867fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 8868fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8869fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8870fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 88714f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 88724f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 8873fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8874fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8875fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8876fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8877fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8878fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8879fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 8880fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 8881fa34dd3eSStefano Zampini 8882fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 8883fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 8884fa34dd3eSStefano Zampini /* local with Schur */ 8885fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 8886fa34dd3eSStefano Zampini if (zerodiag) { 8887fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 88884f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 8889fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8890fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 8891fa34dd3eSStefano Zampini } 8892fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 8893fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8894fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8895fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8896fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8897fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 8898fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8899fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8900fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 8901fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8902fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8903fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8904fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8905fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8906fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 8907fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 8908fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8909fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8910fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8911fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8912fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8913fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8914fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 8915fa34dd3eSStefano Zampini if (zerodiag) { 8916fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 8917fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 89184f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 8919fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8920fa34dd3eSStefano Zampini } 8921fa34dd3eSStefano Zampini /* BDDC */ 8922fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 8923fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 8924fa34dd3eSStefano Zampini 8925fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 8926fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 8927fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 8928fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 89294f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 89304f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 8931fa34dd3eSStefano Zampini } 89324f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 8933fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 8934fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 8935fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 8936fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8937fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 8938fa34dd3eSStefano Zampini } 8939fa34dd3eSStefano Zampini PetscFunctionReturn(0); 8940fa34dd3eSStefano Zampini } 89411e0482f5SStefano Zampini 89421e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 89431e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 89441e0482f5SStefano Zampini { 89451e0482f5SStefano Zampini Mat At; 89461e0482f5SStefano Zampini IS rows; 89471e0482f5SStefano Zampini PetscInt rst,ren; 89481e0482f5SStefano Zampini PetscErrorCode ierr; 89491e0482f5SStefano Zampini PetscLayout rmap; 89501e0482f5SStefano Zampini 89511e0482f5SStefano Zampini PetscFunctionBegin; 89521e0482f5SStefano Zampini rst = ren = 0; 89531e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 89541e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 89551e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 89561e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 89571e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 89581e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 89591e0482f5SStefano Zampini } 8960e07686f2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),ren-rst,rst,1,&rows);CHKERRQ(ierr); 89617dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 89621e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 89631e0482f5SStefano Zampini 89641e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 89651e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 89661e0482f5SStefano Zampini IS from,to; 89671e0482f5SStefano Zampini Vec gvec; 89681e0482f5SStefano Zampini PetscInt lsize; 89691e0482f5SStefano Zampini 89701e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 89711e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 89721e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 89731e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 89741e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 89751e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 89761e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 89771e0482f5SStefano Zampini ierr = MPI_Comm_size(ccomm,&b->size);CHKERRQ(ierr); 89781e0482f5SStefano Zampini ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRQ(ierr); 89791e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 89801e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 89811e0482f5SStefano Zampini b->A = a->A; 89821e0482f5SStefano Zampini b->B = a->B; 89831e0482f5SStefano Zampini 89841e0482f5SStefano Zampini b->donotstash = a->donotstash; 89851e0482f5SStefano Zampini b->roworiented = a->roworiented; 89861e0482f5SStefano Zampini b->rowindices = 0; 89871e0482f5SStefano Zampini b->rowvalues = 0; 89881e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 89891e0482f5SStefano Zampini 89901e0482f5SStefano Zampini (*B)->rmap = rmap; 89911e0482f5SStefano Zampini (*B)->factortype = A->factortype; 89921e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 89931e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 89941e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 89951e0482f5SStefano Zampini 89961e0482f5SStefano Zampini if (a->colmap) { 89971e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 89981e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 89991e0482f5SStefano Zampini #else 90001e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 90011e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 90021e0482f5SStefano Zampini ierr = PetscMemcpy(b->colmap,a->colmap,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 90031e0482f5SStefano Zampini #endif 90041e0482f5SStefano Zampini } else b->colmap = 0; 90051e0482f5SStefano Zampini if (a->garray) { 90061e0482f5SStefano Zampini PetscInt len; 90071e0482f5SStefano Zampini len = a->B->cmap->n; 90081e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 90091e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 90101e0482f5SStefano Zampini if (len) { ierr = PetscMemcpy(b->garray,a->garray,len*sizeof(PetscInt));CHKERRQ(ierr); } 90111e0482f5SStefano Zampini } else b->garray = 0; 90121e0482f5SStefano Zampini 90131e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 90141e0482f5SStefano Zampini b->lvec = a->lvec; 90151e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 90161e0482f5SStefano Zampini 90171e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 90181e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 90191e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 90201e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 90211e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 90221e0482f5SStefano Zampini ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 90231e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 90241e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 90251e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 90261e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 90271e0482f5SStefano Zampini } 90281e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 90291e0482f5SStefano Zampini PetscFunctionReturn(0); 90301e0482f5SStefano Zampini } 9031