11cf9b237SStefano Zampini #include <../src/mat/impls/aij/seq/aij.h> 2ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddc.h> 3ab5c6b0cSJed Brown #include <../src/ksp/pc/impls/bddc/bddcprivate.h> 4837cedc9SStefano Zampini #include <../src/mat/impls/dense/seq/dense.h> 5c80a6c00SStefano Zampini #include <petscdmplex.h> 6674ae819SStefano Zampini #include <petscblaslapack.h> 7daf8a457SStefano Zampini #include <petsc/private/sfimpl.h> 8c80a6c00SStefano Zampini #include <petsc/private/dmpleximpl.h> 97620a527SStefano Zampini #include <petscdmda.h> 10674ae819SStefano Zampini 111e0482f5SStefano Zampini static PetscErrorCode MatMPIAIJRestrict(Mat,MPI_Comm,Mat*); 121e0482f5SStefano Zampini 13f498cd09SStefano Zampini /* if range is true, it returns B s.t. span{B} = range(A) 14f498cd09SStefano Zampini if range is false, it returns B s.t. range(B) _|_ range(A) */ 15f498cd09SStefano Zampini PetscErrorCode MatDenseOrthogonalRangeOrComplement(Mat A, PetscBool range, PetscInt lw, PetscScalar *work, PetscReal *rwork, Mat *B) 16a13144ffSStefano Zampini { 17a13144ffSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 18a13144ffSStefano Zampini PetscScalar *uwork,*data,*U, ds = 0.; 19a13144ffSStefano Zampini PetscReal *sing; 20a13144ffSStefano Zampini PetscBLASInt bM,bN,lwork,lierr,di = 1; 21a13144ffSStefano Zampini PetscInt ulw,i,nr,nc,n; 22a13144ffSStefano Zampini PetscErrorCode ierr; 23a13144ffSStefano Zampini 24a13144ffSStefano Zampini PetscFunctionBegin; 25a13144ffSStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 26a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"LAPACK _GESVD not available"); 27614dbb09SStefano Zampini #else 28a13144ffSStefano Zampini ierr = MatGetSize(A,&nr,&nc);CHKERRQ(ierr); 29a13144ffSStefano Zampini if (!nr || !nc) PetscFunctionReturn(0); 30a13144ffSStefano Zampini 31a13144ffSStefano Zampini /* workspace */ 32a13144ffSStefano Zampini if (!work) { 33a13144ffSStefano Zampini ulw = PetscMax(PetscMax(1,5*PetscMin(nr,nc)),3*PetscMin(nr,nc)+PetscMax(nr,nc)); 34f913dca9SStefano Zampini ierr = PetscMalloc1(ulw,&uwork);CHKERRQ(ierr); 35a13144ffSStefano Zampini } else { 36a13144ffSStefano Zampini ulw = lw; 37a13144ffSStefano Zampini uwork = work; 38a13144ffSStefano Zampini } 39a13144ffSStefano Zampini n = PetscMin(nr,nc); 40a13144ffSStefano Zampini if (!rwork) { 41a13144ffSStefano Zampini ierr = PetscMalloc1(n,&sing);CHKERRQ(ierr); 42a13144ffSStefano Zampini } else { 43a13144ffSStefano Zampini sing = rwork; 44a13144ffSStefano Zampini } 45a13144ffSStefano Zampini 46a13144ffSStefano Zampini /* SVD */ 47a13144ffSStefano Zampini ierr = PetscMalloc1(nr*nr,&U);CHKERRQ(ierr); 48a13144ffSStefano Zampini ierr = PetscBLASIntCast(nr,&bM);CHKERRQ(ierr); 49a13144ffSStefano Zampini ierr = PetscBLASIntCast(nc,&bN);CHKERRQ(ierr); 50a13144ffSStefano Zampini ierr = PetscBLASIntCast(ulw,&lwork);CHKERRQ(ierr); 51a13144ffSStefano Zampini ierr = MatDenseGetArray(A,&data);CHKERRQ(ierr); 52a13144ffSStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 53a13144ffSStefano Zampini PetscStackCallBLAS("LAPACKgesvd",LAPACKgesvd_("A","N",&bM,&bN,data,&bM,sing,U,&bM,&ds,&di,uwork,&lwork,&lierr)); 54a13144ffSStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 55a13144ffSStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 56a13144ffSStefano Zampini ierr = MatDenseRestoreArray(A,&data);CHKERRQ(ierr); 57a13144ffSStefano Zampini for (i=0;i<n;i++) if (sing[i] < PETSC_SMALL) break; 58a13144ffSStefano Zampini if (!rwork) { 59a13144ffSStefano Zampini ierr = PetscFree(sing);CHKERRQ(ierr); 60a13144ffSStefano Zampini } 61a13144ffSStefano Zampini if (!work) { 62a13144ffSStefano Zampini ierr = PetscFree(uwork);CHKERRQ(ierr); 63a13144ffSStefano Zampini } 64a13144ffSStefano Zampini /* create B */ 65f498cd09SStefano Zampini if (!range) { 66a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,nr-i,NULL,B);CHKERRQ(ierr); 67a13144ffSStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 68a13144ffSStefano Zampini ierr = PetscMemcpy(data,U+nr*i,(nr-i)*nr*sizeof(PetscScalar));CHKERRQ(ierr); 69f498cd09SStefano Zampini } else { 70f498cd09SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,nr,i,NULL,B);CHKERRQ(ierr); 71f498cd09SStefano Zampini ierr = MatDenseGetArray(*B,&data);CHKERRQ(ierr); 72f498cd09SStefano Zampini ierr = PetscMemcpy(data,U,i*nr*sizeof(PetscScalar));CHKERRQ(ierr); 73f498cd09SStefano Zampini } 74a13144ffSStefano Zampini ierr = MatDenseRestoreArray(*B,&data);CHKERRQ(ierr); 75a13144ffSStefano Zampini ierr = PetscFree(U);CHKERRQ(ierr); 76614dbb09SStefano Zampini #endif 77614dbb09SStefano Zampini #else /* PETSC_USE_COMPLEX */ 78a13144ffSStefano Zampini PetscFunctionBegin; 79a13144ffSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented for complexes"); 80a13144ffSStefano Zampini #endif 81a13144ffSStefano Zampini PetscFunctionReturn(0); 82a13144ffSStefano Zampini } 83a13144ffSStefano Zampini 841e0482f5SStefano Zampini /* TODO REMOVE */ 851e0482f5SStefano Zampini #if defined(PRINT_GDET) 861e0482f5SStefano Zampini static int inc = 0; 871e0482f5SStefano Zampini static int lev = 0; 881e0482f5SStefano Zampini #endif 891e0482f5SStefano Zampini 901e0482f5SStefano Zampini PetscErrorCode PCBDDCComputeNedelecChangeEdge(Mat lG, IS edge, IS extrow, IS extcol, IS corners, Mat* Gins, Mat* GKins, PetscScalar cvals[2], PetscScalar *work, PetscReal *rwork) 91a13144ffSStefano Zampini { 92a13144ffSStefano Zampini PetscErrorCode ierr; 93a13144ffSStefano Zampini Mat GE,GEd; 94a13144ffSStefano Zampini PetscInt rsize,csize,esize; 95a13144ffSStefano Zampini PetscScalar *ptr; 96a13144ffSStefano Zampini 97a13144ffSStefano Zampini PetscFunctionBegin; 98a13144ffSStefano Zampini ierr = ISGetSize(edge,&esize);CHKERRQ(ierr); 99c3c0e390SStefano Zampini if (!esize) PetscFunctionReturn(0); 100a13144ffSStefano Zampini ierr = ISGetSize(extrow,&rsize);CHKERRQ(ierr); 101a13144ffSStefano Zampini ierr = ISGetSize(extcol,&csize);CHKERRQ(ierr); 102a13144ffSStefano Zampini 103a13144ffSStefano Zampini /* gradients */ 104a13144ffSStefano Zampini ptr = work + 5*esize; 1057dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,extrow,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 106a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,rsize,csize,ptr,Gins);CHKERRQ(ierr); 107a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,Gins);CHKERRQ(ierr); 108a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 109a13144ffSStefano Zampini 110a13144ffSStefano Zampini /* constants */ 111a13144ffSStefano Zampini ptr += rsize*csize; 112a13144ffSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,esize,csize,ptr,&GEd);CHKERRQ(ierr); 1137dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,edge,extcol,MAT_INITIAL_MATRIX,&GE);CHKERRQ(ierr); 114a13144ffSStefano Zampini ierr = MatConvert(GE,MATSEQDENSE,MAT_REUSE_MATRIX,&GEd);CHKERRQ(ierr); 115a13144ffSStefano Zampini ierr = MatDestroy(&GE);CHKERRQ(ierr); 116f498cd09SStefano Zampini ierr = MatDenseOrthogonalRangeOrComplement(GEd,PETSC_FALSE,5*esize,work,rwork,GKins);CHKERRQ(ierr); 117a13144ffSStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1181e0482f5SStefano Zampini 1191e0482f5SStefano Zampini if (corners) { 1201e0482f5SStefano Zampini Mat GEc; 1211e0482f5SStefano Zampini PetscScalar *vals,v; 1221e0482f5SStefano Zampini 1237dae84e0SHong Zhang ierr = MatCreateSubMatrix(lG,edge,corners,MAT_INITIAL_MATRIX,&GEc);CHKERRQ(ierr); 1241e0482f5SStefano Zampini ierr = MatTransposeMatMult(GEc,*GKins,MAT_INITIAL_MATRIX,1.0,&GEd);CHKERRQ(ierr); 1251e0482f5SStefano Zampini ierr = MatDenseGetArray(GEd,&vals);CHKERRQ(ierr); 126637e8532SStefano Zampini /* v = PetscAbsScalar(vals[0]) */; 127637e8532SStefano Zampini v = 1.; 1281e0482f5SStefano Zampini cvals[0] = vals[0]/v; 1291e0482f5SStefano Zampini cvals[1] = vals[1]/v; 1301e0482f5SStefano Zampini ierr = MatDenseRestoreArray(GEd,&vals);CHKERRQ(ierr); 1311e0482f5SStefano Zampini ierr = MatScale(*GKins,1./v);CHKERRQ(ierr); 1321e0482f5SStefano Zampini #if defined(PRINT_GDET) 1331e0482f5SStefano Zampini { 1341e0482f5SStefano Zampini PetscViewer viewer; 1351e0482f5SStefano Zampini char filename[256]; 1361e0482f5SStefano Zampini sprintf(filename,"Gdet_l%d_r%d_cc%d.m",lev,PetscGlobalRank,inc++); 1371e0482f5SStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 1381e0482f5SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 1391e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEc,"GEc");CHKERRQ(ierr); 1401e0482f5SStefano Zampini ierr = MatView(GEc,viewer);CHKERRQ(ierr); 1411e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)(*GKins),"GK");CHKERRQ(ierr); 1421e0482f5SStefano Zampini ierr = MatView(*GKins,viewer);CHKERRQ(ierr); 1431e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)GEd,"Gproj");CHKERRQ(ierr); 1441e0482f5SStefano Zampini ierr = MatView(GEd,viewer);CHKERRQ(ierr); 1451e0482f5SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1461e0482f5SStefano Zampini } 1471e0482f5SStefano Zampini #endif 1481e0482f5SStefano Zampini ierr = MatDestroy(&GEd);CHKERRQ(ierr); 1491e0482f5SStefano Zampini ierr = MatDestroy(&GEc);CHKERRQ(ierr); 1501e0482f5SStefano Zampini } 1511e0482f5SStefano Zampini 152a13144ffSStefano Zampini PetscFunctionReturn(0); 153a13144ffSStefano Zampini } 154a13144ffSStefano Zampini 155a13144ffSStefano Zampini PetscErrorCode PCBDDCNedelecSupport(PC pc) 156a13144ffSStefano Zampini { 157a13144ffSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 158a13144ffSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 1590569b399SStefano Zampini Mat G,T,conn,lG,lGt,lGis,lGall,lGe,lGinit; 160eee23b56SStefano Zampini Vec tvec; 161a13144ffSStefano Zampini PetscSF sfv; 1621e0482f5SStefano Zampini ISLocalToGlobalMapping el2g,vl2g,fl2g,al2g; 163a13144ffSStefano Zampini MPI_Comm comm; 164c2151214SStefano Zampini IS lned,primals,allprimals,nedfieldlocal; 165c2151214SStefano Zampini IS *eedges,*extrows,*extcols,*alleedges; 1667d871cd7SStefano Zampini PetscBT btv,bte,btvc,btb,btbd,btvcand,btvi,btee,bter; 167a13144ffSStefano Zampini PetscScalar *vals,*work; 168a13144ffSStefano Zampini PetscReal *rwork; 169a13144ffSStefano Zampini const PetscInt *idxs,*ii,*jj,*iit,*jjt; 1701e0482f5SStefano Zampini PetscInt ne,nv,Lv,order,n,field; 171a13144ffSStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 172eee23b56SStefano Zampini PetscInt i,j,extmem,cum,maxsize,nee; 173b03ebc13SStefano Zampini PetscInt *extrow,*extrowcum,*marks,*vmarks,*gidxs; 174a13144ffSStefano Zampini PetscInt *sfvleaves,*sfvroots; 175b03ebc13SStefano Zampini PetscInt *corners,*cedges; 176637e8532SStefano Zampini PetscInt *ecount,**eneighs,*vcount,**vneighs; 177b03ebc13SStefano Zampini #if defined(PETSC_USE_DEBUG) 178b03ebc13SStefano Zampini PetscInt *emarks; 179b03ebc13SStefano Zampini #endif 180213b8bfaSStefano Zampini PetscBool print,eerr,done,lrc[2],conforming,global,singular,setprimal; 181a13144ffSStefano Zampini PetscErrorCode ierr; 182a13144ffSStefano Zampini 183a13144ffSStefano Zampini PetscFunctionBegin; 184213b8bfaSStefano Zampini /* If the discrete gradient is defined for a subset of dofs and global is true, 185213b8bfaSStefano Zampini it assumes G is given in global ordering for all the dofs. 186213b8bfaSStefano Zampini Otherwise, the ordering is global for the Nedelec field */ 187213b8bfaSStefano Zampini order = pcbddc->nedorder; 188213b8bfaSStefano Zampini conforming = pcbddc->conforming; 189213b8bfaSStefano Zampini field = pcbddc->nedfield; 190213b8bfaSStefano Zampini global = pcbddc->nedglobal; 191213b8bfaSStefano Zampini setprimal = PETSC_FALSE; 192a13144ffSStefano Zampini print = PETSC_FALSE; 193213b8bfaSStefano Zampini singular = PETSC_FALSE; 194a13144ffSStefano Zampini 195213b8bfaSStefano Zampini /* Command line customization */ 196213b8bfaSStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC Nedelec options","PC");CHKERRQ(ierr); 197213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_field_primal","All edge dofs set as primals: Toselli's algorithm C",NULL,setprimal,&setprimal,NULL);CHKERRQ(ierr); 198213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_singular","Infer nullspace from discrete gradient",NULL,singular,&singular,NULL);CHKERRQ(ierr); 199213b8bfaSStefano Zampini ierr = PetscOptionsInt("-pc_bddc_nedelec_order","Test variable order code (to be removed)",NULL,order,&order,NULL);CHKERRQ(ierr); 200213b8bfaSStefano Zampini /* print debug info TODO: to be removed */ 201213b8bfaSStefano Zampini ierr = PetscOptionsBool("-pc_bddc_nedelec_print","Print debug info",NULL,print,&print,NULL);CHKERRQ(ierr); 202213b8bfaSStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 203213b8bfaSStefano Zampini 204213b8bfaSStefano Zampini /* Return if there are no edges in the decomposition and the problem is not singular */ 2051e0482f5SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&al2g,NULL);CHKERRQ(ierr); 2061e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingGetSize(al2g,&n);CHKERRQ(ierr); 207213b8bfaSStefano Zampini ierr = PetscObjectGetComm((PetscObject)pc,&comm);CHKERRQ(ierr); 208213b8bfaSStefano Zampini if (!singular) { 209a13144ffSStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 210a13144ffSStefano Zampini lrc[0] = PETSC_FALSE; 211c2151214SStefano Zampini for (i=0;i<n;i++) { 212a13144ffSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 213a13144ffSStefano Zampini lrc[0] = PETSC_TRUE; 214a13144ffSStefano Zampini break; 215a13144ffSStefano Zampini } 216a13144ffSStefano Zampini } 217a13144ffSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 218a13144ffSStefano Zampini ierr = MPIU_Allreduce(&lrc[0],&lrc[1],1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 219a13144ffSStefano Zampini if (!lrc[1]) PetscFunctionReturn(0); 220213b8bfaSStefano Zampini } 221a13144ffSStefano Zampini 222213b8bfaSStefano Zampini /* Get Nedelec field */ 223213b8bfaSStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 224c2151214SStefano Zampini if (pcbddc->n_ISForDofsLocal && field >= pcbddc->n_ISForDofsLocal) SETERRQ2(comm,PETSC_ERR_USER,"Invalid field for Nedelec %d: number of fields is %d",field,pcbddc->n_ISForDofsLocal); 225213b8bfaSStefano Zampini if (pcbddc->n_ISForDofsLocal && field >= 0) { 226c2151214SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ISForDofsLocal[field]);CHKERRQ(ierr); 227c2151214SStefano Zampini nedfieldlocal = pcbddc->ISForDofsLocal[field]; 228c2151214SStefano Zampini ierr = ISGetLocalSize(nedfieldlocal,&ne);CHKERRQ(ierr); 229213b8bfaSStefano Zampini } else if (!pcbddc->n_ISForDofsLocal && field != PETSC_DECIDE) { 230213b8bfaSStefano Zampini ne = n; 231213b8bfaSStefano Zampini nedfieldlocal = NULL; 232213b8bfaSStefano Zampini global = PETSC_TRUE; 233213b8bfaSStefano Zampini } else if (field == PETSC_DECIDE) { 234213b8bfaSStefano Zampini PetscInt rst,ren,*idx; 235213b8bfaSStefano Zampini 236213b8bfaSStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 237213b8bfaSStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 238213b8bfaSStefano Zampini ierr = MatGetOwnershipRange(pcbddc->discretegradient,&rst,&ren);CHKERRQ(ierr); 239213b8bfaSStefano Zampini for (i=rst;i<ren;i++) { 240213b8bfaSStefano Zampini PetscInt nc; 241213b8bfaSStefano Zampini 242213b8bfaSStefano Zampini ierr = MatGetRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 243213b8bfaSStefano Zampini if (nc > 1) matis->sf_rootdata[i-rst] = 1; 244213b8bfaSStefano Zampini ierr = MatRestoreRow(pcbddc->discretegradient,i,&nc,NULL,NULL);CHKERRQ(ierr); 245213b8bfaSStefano Zampini } 246213b8bfaSStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 247213b8bfaSStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 248213b8bfaSStefano Zampini ierr = PetscMalloc1(n,&idx);CHKERRQ(ierr); 249213b8bfaSStefano Zampini for (i=0,ne=0;i<n;i++) if (matis->sf_leafdata[i]) idx[ne++] = i; 250213b8bfaSStefano Zampini ierr = ISCreateGeneral(comm,ne,idx,PETSC_OWN_POINTER,&nedfieldlocal);CHKERRQ(ierr); 251213b8bfaSStefano Zampini } else { 252213b8bfaSStefano Zampini SETERRQ(comm,PETSC_ERR_USER,"When multiple fields are present, the Nedelec field has to be specified"); 253213b8bfaSStefano Zampini } 254213b8bfaSStefano Zampini 255213b8bfaSStefano Zampini /* Sanity checks */ 256213b8bfaSStefano Zampini if (!order && !conforming) SETERRQ(comm,PETSC_ERR_SUP,"Variable order and non-conforming spaces are not supported at the same time"); 257213b8bfaSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) SETERRQ(comm,PETSC_ERR_SUP,"Cannot generate Nedelec support with user defined change of basis"); 258213b8bfaSStefano Zampini if (order && ne%order) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"The number of local edge dofs %d it's not a multiple of the order %d",ne,order); 259213b8bfaSStefano Zampini 260213b8bfaSStefano Zampini /* Just set primal dofs and return */ 2611e0482f5SStefano Zampini if (setprimal) { 262eee23b56SStefano Zampini IS enedfieldlocal; 263eee23b56SStefano Zampini PetscInt *eidxs; 264eee23b56SStefano Zampini 265eee23b56SStefano Zampini ierr = PetscMalloc1(ne,&eidxs);CHKERRQ(ierr); 266eee23b56SStefano Zampini ierr = VecGetArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 267213b8bfaSStefano Zampini if (nedfieldlocal) { 268213b8bfaSStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 269eee23b56SStefano Zampini for (i=0,cum=0;i<ne;i++) { 270eee23b56SStefano Zampini if (PetscRealPart(vals[idxs[i]]) > 2.) { 271eee23b56SStefano Zampini eidxs[cum++] = idxs[i]; 272eee23b56SStefano Zampini } 273eee23b56SStefano Zampini } 274eee23b56SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 275213b8bfaSStefano Zampini } else { 276213b8bfaSStefano Zampini for (i=0,cum=0;i<ne;i++) { 277213b8bfaSStefano Zampini if (PetscRealPart(vals[i]) > 2.) { 278213b8bfaSStefano Zampini eidxs[cum++] = i; 279213b8bfaSStefano Zampini } 280213b8bfaSStefano Zampini } 281213b8bfaSStefano Zampini } 282213b8bfaSStefano Zampini ierr = VecRestoreArrayRead(matis->counter,(const PetscScalar**)&vals);CHKERRQ(ierr); 283eee23b56SStefano Zampini ierr = ISCreateGeneral(comm,cum,eidxs,PETSC_COPY_VALUES,&enedfieldlocal);CHKERRQ(ierr); 284eee23b56SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,enedfieldlocal);CHKERRQ(ierr); 285eee23b56SStefano Zampini ierr = PetscFree(eidxs);CHKERRQ(ierr); 2861e0482f5SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 287eee23b56SStefano Zampini ierr = ISDestroy(&enedfieldlocal);CHKERRQ(ierr); 2881e0482f5SStefano Zampini PetscFunctionReturn(0); 2891e0482f5SStefano Zampini } 290a13144ffSStefano Zampini 291213b8bfaSStefano Zampini /* Compute some l2g maps */ 292213b8bfaSStefano Zampini if (nedfieldlocal) { 293c2151214SStefano Zampini IS is; 294c2151214SStefano Zampini 295c2151214SStefano Zampini /* need to map from the local Nedelec field to local numbering */ 296c2151214SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(nedfieldlocal,&fl2g);CHKERRQ(ierr); 2971e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering for the whole dofs*/ 2981e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(al2g,nedfieldlocal,&is);CHKERRQ(ierr); 2991e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is,&al2g);CHKERRQ(ierr); 3001e0482f5SStefano Zampini /* need to map from the local Nedelec field to global numbering (for Nedelec only) */ 3011e0482f5SStefano Zampini if (global) { 3021e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3031e0482f5SStefano Zampini el2g = al2g; 3041e0482f5SStefano Zampini } else { 3051e0482f5SStefano Zampini IS gis; 3061e0482f5SStefano Zampini 3071e0482f5SStefano Zampini ierr = ISRenumber(is,NULL,NULL,&gis);CHKERRQ(ierr); 3081e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(gis,&el2g);CHKERRQ(ierr); 3091e0482f5SStefano Zampini ierr = ISDestroy(&gis);CHKERRQ(ierr); 3101e0482f5SStefano Zampini } 311c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 312c2151214SStefano Zampini } else { 3131e0482f5SStefano Zampini /* restore default */ 3141e0482f5SStefano Zampini pcbddc->nedfield = -1; 3151e0482f5SStefano Zampini /* one ref for the destruction of al2g, one for el2g */ 3161e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3171e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)al2g);CHKERRQ(ierr); 3181e0482f5SStefano Zampini el2g = al2g; 319c2151214SStefano Zampini fl2g = NULL; 320c2151214SStefano Zampini } 321a13144ffSStefano Zampini 322213b8bfaSStefano Zampini /* Start communication to drop connections for interior edges (for cc analysis only) */ 323c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_leafdata,n*sizeof(PetscInt));CHKERRQ(ierr); 324c2151214SStefano Zampini ierr = PetscMemzero(matis->sf_rootdata,pc->pmat->rmap->n*sizeof(PetscInt));CHKERRQ(ierr); 325c2151214SStefano Zampini if (nedfieldlocal) { 326c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 327c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[idxs[i]] = 1; 328c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 329c2151214SStefano Zampini } else { 330c2151214SStefano Zampini for (i=0;i<ne;i++) matis->sf_leafdata[i] = 1; 331c2151214SStefano Zampini } 332c2151214SStefano Zampini ierr = PetscSFReduceBegin(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 333c2151214SStefano Zampini ierr = PetscSFReduceEnd(matis->sf,MPIU_INT,matis->sf_leafdata,matis->sf_rootdata,MPI_SUM);CHKERRQ(ierr); 334213b8bfaSStefano Zampini 335213b8bfaSStefano Zampini if (!singular) { /* drop connections with interior edges to avoid unneeded communications and memory movements */ 336213b8bfaSStefano Zampini ierr = MatDuplicate(pcbddc->discretegradient,MAT_COPY_VALUES,&G);CHKERRQ(ierr); 337213b8bfaSStefano Zampini ierr = MatSetOption(G,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 3381e0482f5SStefano Zampini if (global) { 3391e0482f5SStefano Zampini PetscInt rst; 3401e0482f5SStefano Zampini 341c2151214SStefano Zampini ierr = MatGetOwnershipRange(G,&rst,NULL);CHKERRQ(ierr); 342c2151214SStefano Zampini for (i=0,cum=0;i<pc->pmat->rmap->n;i++) { 343c2151214SStefano Zampini if (matis->sf_rootdata[i] < 2) { 344c2151214SStefano Zampini matis->sf_rootdata[cum++] = i + rst; 345c2151214SStefano Zampini } 346c2151214SStefano Zampini } 347a13144ffSStefano Zampini ierr = MatSetOption(G,MAT_NO_OFF_PROC_ZERO_ROWS,PETSC_TRUE);CHKERRQ(ierr); 348c2151214SStefano Zampini ierr = MatZeroRows(G,cum,matis->sf_rootdata,0.,NULL,NULL);CHKERRQ(ierr); 3491e0482f5SStefano Zampini } else { 3501e0482f5SStefano Zampini PetscInt *tbz; 3511e0482f5SStefano Zampini 3521e0482f5SStefano Zampini ierr = PetscMalloc1(ne,&tbz);CHKERRQ(ierr); 3531e0482f5SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3541e0482f5SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,MPIU_INT,matis->sf_rootdata,matis->sf_leafdata);CHKERRQ(ierr); 3551e0482f5SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3561e0482f5SStefano Zampini for (i=0,cum=0;i<ne;i++) 3571e0482f5SStefano Zampini if (matis->sf_leafdata[idxs[i]] == 1) 3581e0482f5SStefano Zampini tbz[cum++] = i; 3591e0482f5SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 3601e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApply(el2g,cum,tbz,tbz);CHKERRQ(ierr); 3611e0482f5SStefano Zampini ierr = MatZeroRows(G,cum,tbz,0.,NULL,NULL);CHKERRQ(ierr); 3621e0482f5SStefano Zampini ierr = PetscFree(tbz);CHKERRQ(ierr); 3631e0482f5SStefano Zampini } 364213b8bfaSStefano Zampini } else { /* we need the entire G to infer the nullspace */ 365213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->discretegradient);CHKERRQ(ierr); 366213b8bfaSStefano Zampini G = pcbddc->discretegradient; 367213b8bfaSStefano Zampini } 368a13144ffSStefano Zampini 369a13144ffSStefano Zampini /* Extract subdomain relevant rows of G */ 370a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(el2g,&idxs);CHKERRQ(ierr); 371a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,ne,idxs,PETSC_USE_POINTER,&lned);CHKERRQ(ierr); 3727dae84e0SHong Zhang ierr = MatCreateSubMatrix(G,lned,NULL,MAT_INITIAL_MATRIX,&lGall);CHKERRQ(ierr); 373a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(el2g,&idxs);CHKERRQ(ierr); 374a13144ffSStefano Zampini ierr = ISDestroy(&lned);CHKERRQ(ierr); 375a13144ffSStefano Zampini ierr = MatConvert(lGall,MATIS,MAT_INITIAL_MATRIX,&lGis);CHKERRQ(ierr); 376a13144ffSStefano Zampini ierr = MatDestroy(&lGall);CHKERRQ(ierr); 377a13144ffSStefano Zampini ierr = MatISGetLocalMat(lGis,&lG);CHKERRQ(ierr); 378a13144ffSStefano Zampini 379213b8bfaSStefano Zampini /* SF for nodal dofs communications */ 380c2151214SStefano Zampini ierr = MatGetLocalSize(G,NULL,&Lv);CHKERRQ(ierr); 381a13144ffSStefano Zampini ierr = MatGetLocalToGlobalMapping(lGis,NULL,&vl2g);CHKERRQ(ierr); 382a13144ffSStefano Zampini ierr = PetscObjectReference((PetscObject)vl2g);CHKERRQ(ierr); 383a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(vl2g,&nv);CHKERRQ(ierr); 384a13144ffSStefano Zampini ierr = PetscSFCreate(comm,&sfv);CHKERRQ(ierr); 385a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(vl2g,&idxs);CHKERRQ(ierr); 386a13144ffSStefano Zampini ierr = PetscSFSetGraphLayout(sfv,lGis->cmap,nv,NULL,PETSC_OWN_POINTER,idxs);CHKERRQ(ierr); 387a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(vl2g,&idxs);CHKERRQ(ierr); 388213b8bfaSStefano Zampini i = singular ? 2 : 1; 389213b8bfaSStefano Zampini ierr = PetscMalloc2(i*nv,&sfvleaves,i*Lv,&sfvroots);CHKERRQ(ierr); 390a13144ffSStefano Zampini 3911e0482f5SStefano Zampini /* Destroy temporary G created in MATIS format and modified G */ 392213b8bfaSStefano Zampini ierr = PetscObjectReference((PetscObject)lG);CHKERRQ(ierr); 393a13144ffSStefano Zampini ierr = MatDestroy(&lGis);CHKERRQ(ierr); 394213b8bfaSStefano Zampini ierr = MatDestroy(&G);CHKERRQ(ierr); 395a13144ffSStefano Zampini 396213b8bfaSStefano Zampini if (print) { 397213b8bfaSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"initial_lG");CHKERRQ(ierr); 398213b8bfaSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 399213b8bfaSStefano Zampini } 400213b8bfaSStefano Zampini 401213b8bfaSStefano Zampini /* Save lG for values insertion in change of basis */ 4020569b399SStefano Zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGinit);CHKERRQ(ierr); 4030569b399SStefano Zampini 404a13144ffSStefano Zampini /* Analyze the edge-nodes connections (duplicate lG) */ 4054e64d54eSstefano_zampini ierr = MatDuplicate(lG,MAT_COPY_VALUES,&lGe);CHKERRQ(ierr); 4064e64d54eSstefano_zampini ierr = MatSetOption(lGe,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 407a13144ffSStefano Zampini ierr = PetscBTCreate(nv,&btv);CHKERRQ(ierr); 408a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&bte);CHKERRQ(ierr); 409a13144ffSStefano Zampini ierr = PetscBTCreate(ne,&btb);CHKERRQ(ierr); 4107d871cd7SStefano Zampini ierr = PetscBTCreate(ne,&btbd);CHKERRQ(ierr); 411c2151214SStefano Zampini ierr = PetscBTCreate(nv,&btvcand);CHKERRQ(ierr); 412a13144ffSStefano Zampini /* need to import the boundary specification to ensure the 413a13144ffSStefano Zampini proper detection of coarse edges' endpoints */ 414a13144ffSStefano Zampini if (pcbddc->DirichletBoundariesLocal) { 415c2151214SStefano Zampini IS is; 416c2151214SStefano Zampini 417c2151214SStefano Zampini if (fl2g) { 418c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->DirichletBoundariesLocal,&is);CHKERRQ(ierr); 419c2151214SStefano Zampini } else { 420c2151214SStefano Zampini is = pcbddc->DirichletBoundariesLocal; 421c2151214SStefano Zampini } 422c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 423c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 424a13144ffSStefano Zampini for (i=0;i<cum;i++) { 425a13144ffSStefano Zampini if (idxs[i] >= 0) { 426a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 4277d871cd7SStefano Zampini ierr = PetscBTSet(btbd,idxs[i]);CHKERRQ(ierr); 428a13144ffSStefano Zampini } 429a13144ffSStefano Zampini } 430c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 431c2151214SStefano Zampini if (fl2g) { 432c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 433c2151214SStefano Zampini } 434a13144ffSStefano Zampini } 435a13144ffSStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 436c2151214SStefano Zampini IS is; 437c2151214SStefano Zampini 438c2151214SStefano Zampini if (fl2g) { 439c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_MASK,pcbddc->NeumannBoundariesLocal,&is);CHKERRQ(ierr); 440c2151214SStefano Zampini } else { 441c2151214SStefano Zampini is = pcbddc->NeumannBoundariesLocal; 442c2151214SStefano Zampini } 443c2151214SStefano Zampini ierr = ISGetLocalSize(is,&cum);CHKERRQ(ierr); 444c2151214SStefano Zampini ierr = ISGetIndices(is,&idxs);CHKERRQ(ierr); 445a13144ffSStefano Zampini for (i=0;i<cum;i++) { 446a13144ffSStefano Zampini if (idxs[i] >= 0) { 447a13144ffSStefano Zampini ierr = PetscBTSet(btb,idxs[i]);CHKERRQ(ierr); 448a13144ffSStefano Zampini } 449a13144ffSStefano Zampini } 450c2151214SStefano Zampini ierr = ISRestoreIndices(is,&idxs);CHKERRQ(ierr); 451c2151214SStefano Zampini if (fl2g) { 452c2151214SStefano Zampini ierr = ISDestroy(&is);CHKERRQ(ierr); 453a13144ffSStefano Zampini } 454c2151214SStefano Zampini } 455c2151214SStefano Zampini 456213b8bfaSStefano Zampini /* Count neighs per dof */ 457637e8532SStefano Zampini ierr = PetscCalloc1(ne,&ecount);CHKERRQ(ierr); 458637e8532SStefano Zampini ierr = PetscMalloc1(ne,&eneighs);CHKERRQ(ierr); 459637e8532SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 460637e8532SStefano Zampini for (i=1,cum=0;i<n_neigh;i++) { 461637e8532SStefano Zampini cum += n_shared[i]; 462637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 463637e8532SStefano Zampini ecount[shared[i][j]]++; 464637e8532SStefano Zampini } 465637e8532SStefano Zampini } 466637e8532SStefano Zampini if (ne) { 467637e8532SStefano Zampini ierr = PetscMalloc1(cum,&eneighs[0]);CHKERRQ(ierr); 468637e8532SStefano Zampini } 469637e8532SStefano Zampini for (i=1;i<ne;i++) eneighs[i] = eneighs[i-1] + ecount[i-1]; 470637e8532SStefano Zampini ierr = PetscMemzero(ecount,ne*sizeof(PetscInt));CHKERRQ(ierr); 471637e8532SStefano Zampini for (i=1;i<n_neigh;i++) { 472637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 473637e8532SStefano Zampini PetscInt k = shared[i][j]; 474637e8532SStefano Zampini eneighs[k][ecount[k]] = neigh[i]; 475637e8532SStefano Zampini ecount[k]++; 476637e8532SStefano Zampini } 477637e8532SStefano Zampini } 478637e8532SStefano Zampini for (i=0;i<ne;i++) { 479637e8532SStefano Zampini ierr = PetscSortRemoveDupsInt(&ecount[i],eneighs[i]);CHKERRQ(ierr); 480637e8532SStefano Zampini } 481637e8532SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(el2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 482637e8532SStefano Zampini ierr = PetscCalloc1(nv,&vcount);CHKERRQ(ierr); 483637e8532SStefano Zampini ierr = PetscMalloc1(nv,&vneighs);CHKERRQ(ierr); 484637e8532SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 485637e8532SStefano Zampini for (i=1,cum=0;i<n_neigh;i++) { 486637e8532SStefano Zampini cum += n_shared[i]; 487637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 488637e8532SStefano Zampini vcount[shared[i][j]]++; 489637e8532SStefano Zampini } 490637e8532SStefano Zampini } 491637e8532SStefano Zampini if (nv) { 492637e8532SStefano Zampini ierr = PetscMalloc1(cum,&vneighs[0]);CHKERRQ(ierr); 493637e8532SStefano Zampini } 494637e8532SStefano Zampini for (i=1;i<nv;i++) vneighs[i] = vneighs[i-1] + vcount[i-1]; 495637e8532SStefano Zampini ierr = PetscMemzero(vcount,nv*sizeof(PetscInt));CHKERRQ(ierr); 496637e8532SStefano Zampini for (i=1;i<n_neigh;i++) { 497637e8532SStefano Zampini for (j=0;j<n_shared[i];j++) { 498637e8532SStefano Zampini PetscInt k = shared[i][j]; 499637e8532SStefano Zampini vneighs[k][vcount[k]] = neigh[i]; 500637e8532SStefano Zampini vcount[k]++; 501637e8532SStefano Zampini } 502637e8532SStefano Zampini } 503637e8532SStefano Zampini for (i=0;i<nv;i++) { 504637e8532SStefano Zampini ierr = PetscSortRemoveDupsInt(&vcount[i],vneighs[i]);CHKERRQ(ierr); 505637e8532SStefano Zampini } 506637e8532SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 507637e8532SStefano Zampini 5087d871cd7SStefano Zampini /* need to remove coarse faces' dofs and coarse edges' dirichlet dofs 5097d871cd7SStefano Zampini for proper detection of coarse edges' endpoints */ 51062b0c6f7SStefano Zampini ierr = PetscBTCreate(ne,&btee);CHKERRQ(ierr); 51162b0c6f7SStefano Zampini for (i=0;i<ne;i++) { 5127d871cd7SStefano Zampini if ((ecount[i] > 1 && !PetscBTLookup(btbd,i)) || (ecount[i] == 1 && PetscBTLookup(btb,i))) { 51362b0c6f7SStefano Zampini ierr = PetscBTSet(btee,i);CHKERRQ(ierr); 51462b0c6f7SStefano Zampini } 51562b0c6f7SStefano Zampini } 516637e8532SStefano Zampini ierr = PetscMalloc1(ne,&marks);CHKERRQ(ierr); 51762b0c6f7SStefano Zampini if (!conforming) { 51862b0c6f7SStefano Zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 51962b0c6f7SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 52062b0c6f7SStefano Zampini } 5214e64d54eSstefano_zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 522dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGe,&vals);CHKERRQ(ierr); 52362b0c6f7SStefano Zampini cum = 0; 524a13144ffSStefano Zampini for (i=0;i<ne;i++) { 525dec27d64SStefano Zampini /* eliminate rows corresponding to edge dofs belonging to coarse faces */ 52662b0c6f7SStefano Zampini if (!PetscBTLookup(btee,i)) { 527a13144ffSStefano Zampini marks[cum++] = i; 528dec27d64SStefano Zampini continue; 529dec27d64SStefano Zampini } 530dec27d64SStefano Zampini /* set badly connected edge dofs as primal */ 53162b0c6f7SStefano Zampini if (!conforming) { 53262b0c6f7SStefano Zampini if (ii[i+1]-ii[i] != order + 1) { /* every row of G on the coarse edge should list order+1 nodal dofs */ 533a13144ffSStefano Zampini marks[cum++] = i; 534a13144ffSStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 535a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 536a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 537a13144ffSStefano Zampini } 53862b0c6f7SStefano Zampini } else { 53962b0c6f7SStefano Zampini /* every edge dofs should be connected trough a certain number of nodal dofs 54062b0c6f7SStefano Zampini to other edge dofs belonging to coarse edges 54162b0c6f7SStefano Zampini - at most 2 endpoints 54262b0c6f7SStefano Zampini - order-1 interior nodal dofs 54362b0c6f7SStefano Zampini - no undefined nodal dofs (nconn < order) 54462b0c6f7SStefano Zampini */ 54562b0c6f7SStefano Zampini PetscInt ends = 0,ints = 0, undef = 0; 54662b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 54762b0c6f7SStefano Zampini PetscInt v = jj[j],k; 54862b0c6f7SStefano Zampini PetscInt nconn = iit[v+1]-iit[v]; 54962b0c6f7SStefano Zampini for (k=iit[v];k<iit[v+1];k++) if (!PetscBTLookup(btee,jjt[k])) nconn--; 55062b0c6f7SStefano Zampini if (nconn > order) ends++; 55162b0c6f7SStefano Zampini else if (nconn == order) ints++; 55262b0c6f7SStefano Zampini else undef++; 55362b0c6f7SStefano Zampini } 55462b0c6f7SStefano Zampini if (undef || ends > 2 || ints != order -1) { 55562b0c6f7SStefano Zampini marks[cum++] = i; 55662b0c6f7SStefano Zampini ierr = PetscBTSet(bte,i);CHKERRQ(ierr); 55762b0c6f7SStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 55862b0c6f7SStefano Zampini ierr = PetscBTSet(btv,jj[j]);CHKERRQ(ierr); 55962b0c6f7SStefano Zampini } 56062b0c6f7SStefano Zampini } 56162b0c6f7SStefano Zampini } 562a13144ffSStefano Zampini } 563dec27d64SStefano Zampini /* We assume the order on the element edge is ii[i+1]-ii[i]-1 */ 564dec27d64SStefano Zampini if (!order && ii[i+1] != ii[i]) { 565dec27d64SStefano Zampini PetscScalar val = 1./(ii[i+1]-ii[i]-1); 566dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vals[j] = val; 567a13144ffSStefano Zampini } 568dec27d64SStefano Zampini } 56962b0c6f7SStefano Zampini ierr = PetscBTDestroy(&btee);CHKERRQ(ierr); 570dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGe,&vals);CHKERRQ(ierr); 5714e64d54eSstefano_zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 57262b0c6f7SStefano Zampini if (!conforming) { 57362b0c6f7SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 57462b0c6f7SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 57562b0c6f7SStefano Zampini } 5764e64d54eSstefano_zampini ierr = MatZeroRows(lGe,cum,marks,0.,NULL,NULL);CHKERRQ(ierr); 577637e8532SStefano Zampini 578b03ebc13SStefano Zampini /* identify splitpoints and corner candidates */ 5794e64d54eSstefano_zampini ierr = MatTranspose(lGe,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 580a13144ffSStefano Zampini if (print) { 5814e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGe,"edgerestr_lG");CHKERRQ(ierr); 5824e64d54eSstefano_zampini ierr = MatView(lGe,NULL);CHKERRQ(ierr); 5834e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)lGt,"edgerestr_lGt");CHKERRQ(ierr); 584a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 585a13144ffSStefano Zampini } 586a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 587dec27d64SStefano Zampini ierr = MatSeqAIJGetArray(lGt,&vals);CHKERRQ(ierr); 588a13144ffSStefano Zampini for (i=0;i<nv;i++) { 589637e8532SStefano Zampini PetscInt ord = order, test = ii[i+1]-ii[i], vc = vcount[i]; 5907d871cd7SStefano Zampini PetscBool sneighs = PETSC_TRUE, bdir = PETSC_FALSE; 591b03ebc13SStefano Zampini if (!order) { /* variable order */ 592dec27d64SStefano Zampini PetscReal vorder = 0.; 593dec27d64SStefano Zampini 594dec27d64SStefano Zampini for (j=ii[i];j<ii[i+1];j++) vorder += PetscRealPart(vals[j]); 595dec27d64SStefano Zampini test = PetscFloorReal(vorder+10.*PETSC_SQRT_MACHINE_EPSILON); 596dec27d64SStefano Zampini if (vorder-test > PETSC_SQRT_MACHINE_EPSILON) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected value for vorder: %g (%d)",vorder,test); 597dec27d64SStefano Zampini ord = 1; 598dec27d64SStefano Zampini } 599a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 600dec27d64SStefano Zampini if (test%ord) SETERRQ3(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected number of edge dofs %d connected with nodal dof %d with order %d",test,i,ord); 601a13144ffSStefano Zampini #endif 602637e8532SStefano Zampini for (j=ii[i];j<ii[i+1] && sneighs;j++) { 6037d871cd7SStefano Zampini if (PetscBTLookup(btbd,jj[j])) { 6047d871cd7SStefano Zampini bdir = PETSC_TRUE; 6057d871cd7SStefano Zampini break; 6067d871cd7SStefano Zampini } 607637e8532SStefano Zampini if (vc != ecount[jj[j]]) { 608637e8532SStefano Zampini sneighs = PETSC_FALSE; 609637e8532SStefano Zampini } else { 610637e8532SStefano Zampini PetscInt k,*vn = vneighs[i], *en = eneighs[jj[j]]; 611637e8532SStefano Zampini for (k=0;k<vc;k++) { 612637e8532SStefano Zampini if (vn[k] != en[k]) { 613637e8532SStefano Zampini sneighs = PETSC_FALSE; 614637e8532SStefano Zampini break; 615637e8532SStefano Zampini } 616637e8532SStefano Zampini } 617637e8532SStefano Zampini } 618637e8532SStefano Zampini } 6197d871cd7SStefano Zampini if (!sneighs || test >= 3*ord || bdir) { /* splitpoints */ 6207d871cd7SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"SPLITPOINT %d (%d %d %d)\n",i,!sneighs,test >= 3*ord,bdir); 621a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 622dec27d64SStefano Zampini } else if (test == ord) { 623b03ebc13SStefano Zampini if (order == 1 || (!order && ii[i+1]-ii[i] == 1)) { 624a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"ENDPOINT %d\n",i); 625a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 626a13144ffSStefano Zampini } else { 627a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"CORNER CANDIDATE %d\n",i); 628a13144ffSStefano Zampini ierr = PetscBTSet(btvcand,i);CHKERRQ(ierr); 629a13144ffSStefano Zampini } 630a13144ffSStefano Zampini } 631a13144ffSStefano Zampini } 632637e8532SStefano Zampini ierr = PetscFree(ecount);CHKERRQ(ierr); 633637e8532SStefano Zampini ierr = PetscFree(vcount);CHKERRQ(ierr); 634637e8532SStefano Zampini if (ne) { 635637e8532SStefano Zampini ierr = PetscFree(eneighs[0]);CHKERRQ(ierr); 636637e8532SStefano Zampini } 637637e8532SStefano Zampini if (nv) { 638637e8532SStefano Zampini ierr = PetscFree(vneighs[0]);CHKERRQ(ierr); 639637e8532SStefano Zampini } 640637e8532SStefano Zampini ierr = PetscFree(eneighs);CHKERRQ(ierr); 641637e8532SStefano Zampini ierr = PetscFree(vneighs);CHKERRQ(ierr); 6427d871cd7SStefano Zampini ierr = PetscBTDestroy(&btbd);CHKERRQ(ierr); 643b03ebc13SStefano Zampini 644b03ebc13SStefano Zampini /* a candidate is valid if it is connected to another candidate via a non-primal edge dof */ 645b03ebc13SStefano Zampini if (order != 1) { 646b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"INSPECTING CANDIDATES\n"); 647b03ebc13SStefano Zampini ierr = MatGetRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 648b03ebc13SStefano Zampini for (i=0;i<nv;i++) { 649b03ebc13SStefano Zampini if (PetscBTLookup(btvcand,i)) { 650b03ebc13SStefano Zampini PetscBool found = PETSC_FALSE; 651b03ebc13SStefano Zampini for (j=ii[i];j<ii[i+1] && !found;j++) { 652b03ebc13SStefano Zampini PetscInt k,e = jj[j]; 653b03ebc13SStefano Zampini if (PetscBTLookup(bte,e)) continue; 654b03ebc13SStefano Zampini for (k=iit[e];k<iit[e+1];k++) { 655b03ebc13SStefano Zampini PetscInt v = jjt[k]; 656b03ebc13SStefano Zampini if (v != i && PetscBTLookup(btvcand,v)) { 657b03ebc13SStefano Zampini found = PETSC_TRUE; 658b03ebc13SStefano Zampini break; 659b03ebc13SStefano Zampini } 660b03ebc13SStefano Zampini } 661b03ebc13SStefano Zampini } 662b03ebc13SStefano Zampini if (!found) { 663b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d CLEARED\n",i); 664b03ebc13SStefano Zampini ierr = PetscBTClear(btvcand,i);CHKERRQ(ierr); 665b03ebc13SStefano Zampini } else { 666b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," CANDIDATE %d ACCEPTED\n",i); 667b03ebc13SStefano Zampini } 668b03ebc13SStefano Zampini } 669b03ebc13SStefano Zampini } 670b03ebc13SStefano Zampini ierr = MatRestoreRowIJ(lGe,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 671b03ebc13SStefano Zampini } 672dec27d64SStefano Zampini ierr = MatSeqAIJRestoreArray(lGt,&vals);CHKERRQ(ierr); 673a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 674b03ebc13SStefano Zampini ierr = MatDestroy(&lGe);CHKERRQ(ierr); 675a13144ffSStefano Zampini 676a13144ffSStefano Zampini /* Get the local G^T explicitly */ 6770569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 678a13144ffSStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 6794e64d54eSstefano_zampini ierr = MatSetOption(lGt,MAT_KEEP_NONZERO_PATTERN,PETSC_FALSE);CHKERRQ(ierr); 680a13144ffSStefano Zampini 6814e64d54eSstefano_zampini /* Mark interior nodal dofs */ 682a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 6834e64d54eSstefano_zampini ierr = PetscBTCreate(nv,&btvi);CHKERRQ(ierr); 684a13144ffSStefano Zampini for (i=1;i<n_neigh;i++) { 685a13144ffSStefano Zampini for (j=0;j<n_shared[i];j++) { 6864e64d54eSstefano_zampini ierr = PetscBTSet(btvi,shared[i][j]);CHKERRQ(ierr); 687a13144ffSStefano Zampini } 688a13144ffSStefano Zampini } 689a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(vl2g,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 690a13144ffSStefano Zampini 691a13144ffSStefano Zampini /* communicate corners and splitpoints */ 692a13144ffSStefano Zampini ierr = PetscMalloc1(nv,&vmarks);CHKERRQ(ierr); 693a13144ffSStefano Zampini ierr = PetscMemzero(sfvleaves,nv*sizeof(PetscInt));CHKERRQ(ierr); 694a13144ffSStefano Zampini ierr = PetscMemzero(sfvroots,Lv*sizeof(PetscInt));CHKERRQ(ierr); 695a13144ffSStefano Zampini for (i=0;i<nv;i++) if (PetscUnlikely(PetscBTLookup(btv,i))) sfvleaves[i] = 1; 696a13144ffSStefano Zampini 697a13144ffSStefano Zampini if (print) { 698a13144ffSStefano Zampini IS tbz; 699a13144ffSStefano Zampini 700a13144ffSStefano Zampini cum = 0; 701a13144ffSStefano Zampini for (i=0;i<nv;i++) 702a13144ffSStefano Zampini if (sfvleaves[i]) 703a13144ffSStefano Zampini vmarks[cum++] = i; 704a13144ffSStefano Zampini 705a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 706a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_local");CHKERRQ(ierr); 707a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 708a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 709a13144ffSStefano Zampini } 710a13144ffSStefano Zampini 711a13144ffSStefano Zampini ierr = PetscSFReduceBegin(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 712a13144ffSStefano Zampini ierr = PetscSFReduceEnd(sfv,MPIU_INT,sfvleaves,sfvroots,MPI_SUM);CHKERRQ(ierr); 713a13144ffSStefano Zampini ierr = PetscSFBcastBegin(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 714a13144ffSStefano Zampini ierr = PetscSFBcastEnd(sfv,MPIU_INT,sfvroots,sfvleaves);CHKERRQ(ierr); 715a13144ffSStefano Zampini 7164e64d54eSstefano_zampini /* Zero rows of lGt corresponding to identified corners 7174e64d54eSstefano_zampini and interior nodal dofs */ 718a13144ffSStefano Zampini cum = 0; 719a13144ffSStefano Zampini for (i=0;i<nv;i++) { 720a13144ffSStefano Zampini if (sfvleaves[i]) { 721a13144ffSStefano Zampini vmarks[cum++] = i; 722a13144ffSStefano Zampini ierr = PetscBTSet(btv,i);CHKERRQ(ierr); 723a13144ffSStefano Zampini } 7244e64d54eSstefano_zampini if (!PetscBTLookup(btvi,i)) vmarks[cum++] = i; 725a13144ffSStefano Zampini } 7264e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvi);CHKERRQ(ierr); 727a13144ffSStefano Zampini if (print) { 728a13144ffSStefano Zampini IS tbz; 729a13144ffSStefano Zampini 730a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,vmarks,PETSC_COPY_VALUES,&tbz);CHKERRQ(ierr); 7314e64d54eSstefano_zampini ierr = PetscObjectSetName((PetscObject)tbz,"corners_to_be_zeroed_with_interior");CHKERRQ(ierr); 732a13144ffSStefano Zampini ierr = ISView(tbz,NULL);CHKERRQ(ierr); 733a13144ffSStefano Zampini ierr = ISDestroy(&tbz);CHKERRQ(ierr); 734a13144ffSStefano Zampini } 735a13144ffSStefano Zampini ierr = MatZeroRows(lGt,cum,vmarks,0.,NULL,NULL);CHKERRQ(ierr); 736a13144ffSStefano Zampini ierr = PetscFree(vmarks);CHKERRQ(ierr); 737a13144ffSStefano Zampini ierr = PetscSFDestroy(&sfv);CHKERRQ(ierr); 738a13144ffSStefano Zampini ierr = PetscFree2(sfvleaves,sfvroots);CHKERRQ(ierr); 739a13144ffSStefano Zampini 740a13144ffSStefano Zampini /* Recompute G */ 741a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 742a13144ffSStefano Zampini ierr = MatTranspose(lGt,MAT_INITIAL_MATRIX,&lG);CHKERRQ(ierr); 743a13144ffSStefano Zampini if (print) { 744a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lG,"used_lG");CHKERRQ(ierr); 745a13144ffSStefano Zampini ierr = MatView(lG,NULL);CHKERRQ(ierr); 746a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)lGt,"used_lGt");CHKERRQ(ierr); 747a13144ffSStefano Zampini ierr = MatView(lGt,NULL);CHKERRQ(ierr); 748a13144ffSStefano Zampini } 749a13144ffSStefano Zampini 750a13144ffSStefano Zampini /* Get primal dofs (if any) */ 751a13144ffSStefano Zampini cum = 0; 752a13144ffSStefano Zampini for (i=0;i<ne;i++) { 753a13144ffSStefano Zampini if (PetscUnlikely(PetscBTLookup(bte,i))) marks[cum++] = i; 754a13144ffSStefano Zampini } 755c2151214SStefano Zampini if (fl2g) { 756c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,marks,marks);CHKERRQ(ierr); 757c2151214SStefano Zampini } 758a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,marks,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 759a13144ffSStefano Zampini if (print) { 760a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"prescribed_primal_dofs");CHKERRQ(ierr); 761a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 762a13144ffSStefano Zampini } 763a13144ffSStefano Zampini ierr = PetscBTDestroy(&bte);CHKERRQ(ierr); 764c2151214SStefano Zampini /* TODO: what if the user passed in some of them ? */ 765a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 766a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 767a13144ffSStefano Zampini 768a13144ffSStefano Zampini /* Compute edge connectivity */ 769a13144ffSStefano Zampini ierr = PetscObjectSetOptionsPrefix((PetscObject)lG,"econn_");CHKERRQ(ierr); 770a13144ffSStefano Zampini ierr = MatMatMultSymbolic(lG,lGt,PETSC_DEFAULT,&conn);CHKERRQ(ierr); 771a13144ffSStefano Zampini ierr = MatGetRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 772c2151214SStefano Zampini if (fl2g) { 773c2151214SStefano Zampini PetscBT btf; 774c2151214SStefano Zampini PetscInt *iia,*jja,*iiu,*jju; 775c2151214SStefano Zampini PetscBool rest = PETSC_FALSE,free = PETSC_FALSE; 776c2151214SStefano Zampini 777c2151214SStefano Zampini /* create CSR for all local dofs */ 778c2151214SStefano Zampini ierr = PetscMalloc1(n+1,&iia);CHKERRQ(ierr); 779c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr) { /* the user has passed in a CSR graph */ 780c2151214SStefano Zampini if (pcbddc->mat_graph->nvtxs_csr != n) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_USER,"Invalid size of CSR graph %d. Should be %d\n",pcbddc->mat_graph->nvtxs_csr,n); 781c2151214SStefano Zampini iiu = pcbddc->mat_graph->xadj; 782c2151214SStefano Zampini jju = pcbddc->mat_graph->adjncy; 783c2151214SStefano Zampini } else if (pcbddc->use_local_adj) { 784c2151214SStefano Zampini rest = PETSC_TRUE; 785c2151214SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 786c2151214SStefano Zampini } else { 787c2151214SStefano Zampini free = PETSC_TRUE; 788c2151214SStefano Zampini ierr = PetscMalloc2(n+1,&iiu,n,&jju);CHKERRQ(ierr); 789c2151214SStefano Zampini iiu[0] = 0; 790c2151214SStefano Zampini for (i=0;i<n;i++) { 791c2151214SStefano Zampini iiu[i+1] = i+1; 792c2151214SStefano Zampini jju[i] = -1; 793d904f53bSStefano Zampini } 794c2151214SStefano Zampini } 795c2151214SStefano Zampini 796c2151214SStefano Zampini /* import sizes of CSR */ 797c2151214SStefano Zampini iia[0] = 0; 798c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] = iiu[i+1]-iiu[i]; 799c2151214SStefano Zampini 800c2151214SStefano Zampini /* overwrite entries corresponding to the Nedelec field */ 801c2151214SStefano Zampini ierr = PetscBTCreate(n,&btf);CHKERRQ(ierr); 802c2151214SStefano Zampini ierr = ISGetIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 803c2151214SStefano Zampini for (i=0;i<ne;i++) { 804c2151214SStefano Zampini ierr = PetscBTSet(btf,idxs[i]);CHKERRQ(ierr); 805c2151214SStefano Zampini iia[idxs[i]+1] = ii[i+1]-ii[i]; 806c2151214SStefano Zampini } 807c2151214SStefano Zampini 808c2151214SStefano Zampini /* iia in CSR */ 809c2151214SStefano Zampini for (i=0;i<n;i++) iia[i+1] += iia[i]; 810c2151214SStefano Zampini 811c2151214SStefano Zampini /* jja in CSR */ 812c2151214SStefano Zampini ierr = PetscMalloc1(iia[n],&jja);CHKERRQ(ierr); 813c2151214SStefano Zampini for (i=0;i<n;i++) 814c2151214SStefano Zampini if (!PetscBTLookup(btf,i)) 815c2151214SStefano Zampini for (j=0;j<iiu[i+1]-iiu[i];j++) 816c2151214SStefano Zampini jja[iia[i]+j] = jju[iiu[i]+j]; 817c2151214SStefano Zampini 818c2151214SStefano Zampini /* map edge dofs connectivity */ 8191e0482f5SStefano Zampini if (jj) { 820c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,ii[ne],jj,(PetscInt *)jj);CHKERRQ(ierr); 821c2151214SStefano Zampini for (i=0;i<ne;i++) { 822c2151214SStefano Zampini PetscInt e = idxs[i]; 823c2151214SStefano Zampini for (j=0;j<ii[i+1]-ii[i];j++) jja[iia[e]+j] = jj[ii[i]+j]; 824c2151214SStefano Zampini } 8251e0482f5SStefano Zampini } 826c2151214SStefano Zampini ierr = ISRestoreIndices(nedfieldlocal,&idxs);CHKERRQ(ierr); 827c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,iia,jja,PETSC_OWN_POINTER);CHKERRQ(ierr); 828c2151214SStefano Zampini if (rest) { 829c2151214SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&i,(const PetscInt**)&iiu,(const PetscInt**)&jju,&done);CHKERRQ(ierr); 830c2151214SStefano Zampini } 831c2151214SStefano Zampini if (free) { 832c2151214SStefano Zampini ierr = PetscFree2(iiu,jju);CHKERRQ(ierr); 833c2151214SStefano Zampini } 834c2151214SStefano Zampini ierr = PetscBTDestroy(&btf);CHKERRQ(ierr); 835c2151214SStefano Zampini } else { 836c2151214SStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,n,ii,jj,PETSC_USE_POINTER);CHKERRQ(ierr); 837c2151214SStefano Zampini } 838c2151214SStefano Zampini 839a13144ffSStefano Zampini /* Analyze interface for edge dofs */ 840a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 841213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 842a13144ffSStefano Zampini 843a13144ffSStefano Zampini /* Get coarse edges in the edge space */ 844c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 845a13144ffSStefano Zampini ierr = MatRestoreRowIJ(conn,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 846a13144ffSStefano Zampini 847c2151214SStefano Zampini if (fl2g) { 848c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 849c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 850c2151214SStefano Zampini for (i=0;i<nee;i++) { 851c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 852c2151214SStefano Zampini } 853c2151214SStefano Zampini } else { 854c2151214SStefano Zampini eedges = alleedges; 855c2151214SStefano Zampini primals = allprimals; 856c2151214SStefano Zampini } 857c2151214SStefano Zampini 858a13144ffSStefano Zampini /* Mark fine edge dofs with their coarse edge id */ 859a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 860c2151214SStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 861c2151214SStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 862c2151214SStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = nee+1; 863c2151214SStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 864c2151214SStefano Zampini if (print) { 865c2151214SStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs");CHKERRQ(ierr); 866c2151214SStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 867c2151214SStefano Zampini } 868c2151214SStefano Zampini 869c2151214SStefano Zampini maxsize = 0; 870a13144ffSStefano Zampini for (i=0;i<nee;i++) { 871a13144ffSStefano Zampini PetscInt size,mark = i+1; 872a13144ffSStefano Zampini 873a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 874a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 875a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 876a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 877a13144ffSStefano Zampini maxsize = PetscMax(maxsize,size); 878a13144ffSStefano Zampini } 879a13144ffSStefano Zampini 880a13144ffSStefano Zampini /* Find coarse edge endpoints */ 881a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 882a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 883a13144ffSStefano Zampini for (i=0;i<nee;i++) { 884a13144ffSStefano Zampini PetscInt mark = i+1,size; 885a13144ffSStefano Zampini 886a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 8871e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 8881e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 889a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 890a13144ffSStefano Zampini if (print) { 891a13144ffSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"ENDPOINTS ANALYSIS EDGE %d\n",i); 892a13144ffSStefano Zampini ISView(eedges[i],NULL); 893a13144ffSStefano Zampini } 894a13144ffSStefano Zampini for (j=0;j<size;j++) { 895a13144ffSStefano Zampini PetscInt k, ee = idxs[j]; 896a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," idx %d\n",ee); 897a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 898a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," inspect %d\n",jj[k]); 899a13144ffSStefano Zampini if (PetscBTLookup(btv,jj[k])) { 900a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found (already set) %d\n",jj[k]); 901a13144ffSStefano Zampini } else if (PetscBTLookup(btvcand,jj[k])) { /* is it ok? */ 902a13144ffSStefano Zampini PetscInt k2; 903a13144ffSStefano Zampini PetscBool corner = PETSC_FALSE; 904a13144ffSStefano Zampini for (k2 = iit[jj[k]];k2 < iit[jj[k]+1];k2++) { 905c2151214SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," INSPECTING %d: mark %d (ref mark %d), boundary %d\n",jjt[k2],marks[jjt[k2]],mark,!!PetscBTLookup(btb,jjt[k2])); 906c2151214SStefano Zampini /* it's a corner if either is connected with an edge dof belonging to a different cc or 907c2151214SStefano Zampini if the edge dof lie on the natural part of the boundary */ 908c2151214SStefano Zampini if ((marks[jjt[k2]] && marks[jjt[k2]] != mark) || (!marks[jjt[k2]] && PetscBTLookup(btb,jjt[k2]))) { 909a13144ffSStefano Zampini corner = PETSC_TRUE; 910a13144ffSStefano Zampini break; 911a13144ffSStefano Zampini } 912a13144ffSStefano Zampini } 913a13144ffSStefano Zampini if (corner) { /* found the nodal dof corresponding to the endpoint of the edge */ 914a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," corner found %d\n",jj[k]); 915a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 916a13144ffSStefano Zampini } else { 917a13144ffSStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," no corners found\n"); 918a13144ffSStefano Zampini } 919a13144ffSStefano Zampini } 920a13144ffSStefano Zampini } 921a13144ffSStefano Zampini } 922a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 923a13144ffSStefano Zampini } 924a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 925a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 926c2151214SStefano Zampini ierr = PetscBTDestroy(&btb);CHKERRQ(ierr); 927a13144ffSStefano Zampini 928a13144ffSStefano Zampini /* Reset marked primal dofs */ 929a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 930a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 931a13144ffSStefano Zampini for (i=0;i<cum;i++) marks[idxs[i]] = 0; 932a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 933a13144ffSStefano Zampini 9340569b399SStefano Zampini /* Now use the initial lG */ 9350569b399SStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 9360569b399SStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 9370569b399SStefano Zampini lG = lGinit; 9380569b399SStefano Zampini ierr = MatTranspose(lG,MAT_INITIAL_MATRIX,&lGt);CHKERRQ(ierr); 9390569b399SStefano Zampini 940a13144ffSStefano Zampini /* Compute extended cols indices */ 941b03ebc13SStefano Zampini ierr = PetscBTCreate(nv,&btvc);CHKERRQ(ierr); 942b03ebc13SStefano Zampini ierr = PetscBTCreate(nee,&bter);CHKERRQ(ierr); 943a13144ffSStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 944a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lG,&i);CHKERRQ(ierr); 945a13144ffSStefano Zampini i *= maxsize; 946b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 947a13144ffSStefano Zampini ierr = PetscMalloc2(i,&extrow,i,&gidxs);CHKERRQ(ierr); 948a13144ffSStefano Zampini eerr = PETSC_FALSE; 949a13144ffSStefano Zampini for (i=0;i<nee;i++) { 950b03ebc13SStefano Zampini PetscInt size,found = 0; 951a13144ffSStefano Zampini 952a13144ffSStefano Zampini cum = 0; 953a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 9541e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 9551e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 956a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 957b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 958a13144ffSStefano Zampini for (j=0;j<size;j++) { 959a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 960b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 961b03ebc13SStefano Zampini PetscInt vv = jj[k]; 962b03ebc13SStefano Zampini if (!PetscBTLookup(btv,vv)) extrow[cum++] = vv; 963b03ebc13SStefano Zampini else if (!PetscBTLookupSet(btvc,vv)) found++; 964b03ebc13SStefano Zampini } 965a13144ffSStefano Zampini } 966a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 967a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 968a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 969a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 970a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 971a13144ffSStefano Zampini /* it may happen that endpoints are not defined at this point 972a13144ffSStefano Zampini if it is the case, mark this edge for a second pass */ 973b03ebc13SStefano Zampini if (cum != size -1 || found != 2) { 974b03ebc13SStefano Zampini ierr = PetscBTSet(bter,i);CHKERRQ(ierr); 975a13144ffSStefano Zampini if (print) { 976a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge");CHKERRQ(ierr); 977a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 978a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol");CHKERRQ(ierr); 979a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 980a13144ffSStefano Zampini } 981a13144ffSStefano Zampini eerr = PETSC_TRUE; 982a13144ffSStefano Zampini } 983a13144ffSStefano Zampini } 9844e64d54eSstefano_zampini /* if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL FIRST PASS"); */ 985a13144ffSStefano Zampini ierr = MPIU_Allreduce(&eerr,&done,1,MPIU_BOOL,MPI_LOR,comm);CHKERRQ(ierr); 986a13144ffSStefano Zampini if (done) { 987a13144ffSStefano Zampini PetscInt *newprimals; 988a13144ffSStefano Zampini 989a13144ffSStefano Zampini ierr = PetscMalloc1(ne,&newprimals);CHKERRQ(ierr); 990a13144ffSStefano Zampini ierr = ISGetLocalSize(primals,&cum);CHKERRQ(ierr); 991a13144ffSStefano Zampini ierr = ISGetIndices(primals,&idxs);CHKERRQ(ierr); 992a13144ffSStefano Zampini ierr = PetscMemcpy(newprimals,idxs,cum*sizeof(PetscInt));CHKERRQ(ierr); 993a13144ffSStefano Zampini ierr = ISRestoreIndices(primals,&idxs);CHKERRQ(ierr); 9940569b399SStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 995b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"DOING SECOND PASS (eerr %d)\n",eerr); 996a13144ffSStefano Zampini for (i=0;i<nee;i++) { 997b03ebc13SStefano Zampini PetscBool has_candidates = PETSC_FALSE; 998b03ebc13SStefano Zampini if (PetscBTLookup(bter,i)) { 999a13144ffSStefano Zampini PetscInt size,mark = i+1; 1000a13144ffSStefano Zampini 1001a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 1002a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1003c2151214SStefano Zampini /* for (j=0;j<size;j++) newprimals[cum++] = idxs[j]; */ 1004a13144ffSStefano Zampini for (j=0;j<size;j++) { 1005a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 1006b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"Inspecting edge dof %d [%d %d)\n",ee,ii[ee],ii[ee+1]); 1007a13144ffSStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 1008a13144ffSStefano Zampini /* set all candidates located on the edge as corners */ 1009a13144ffSStefano Zampini if (PetscBTLookup(btvcand,jj[k])) { 1010a13144ffSStefano Zampini PetscInt k2,vv = jj[k]; 1011b03ebc13SStefano Zampini has_candidates = PETSC_TRUE; 1012b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Candidate set to vertex %d\n",vv); 1013a13144ffSStefano Zampini ierr = PetscBTSet(btv,vv);CHKERRQ(ierr); 1014a13144ffSStefano Zampini /* set all edge dofs connected to candidate as primals */ 1015a13144ffSStefano Zampini for (k2=iit[vv];k2<iit[vv+1];k2++) { 1016a13144ffSStefano Zampini if (marks[jjt[k2]] == mark) { 1017a13144ffSStefano Zampini PetscInt k3,ee2 = jjt[k2]; 1018b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected edge dof set to primal %d\n",ee2); 1019a13144ffSStefano Zampini newprimals[cum++] = ee2; 1020a13144ffSStefano Zampini /* finally set the new corners */ 1021a13144ffSStefano Zampini for (k3=ii[ee2];k3<ii[ee2+1];k3++) { 1022b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Connected nodal dof set to vertex %d\n",jj[k3]); 1023a13144ffSStefano Zampini ierr = PetscBTSet(btv,jj[k3]);CHKERRQ(ierr); 1024a13144ffSStefano Zampini } 1025a13144ffSStefano Zampini } 1026a13144ffSStefano Zampini } 1027b03ebc13SStefano Zampini } else { 1028b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Not a candidate vertex %d\n",jj[k]); 1029a13144ffSStefano Zampini } 1030a13144ffSStefano Zampini } 1031a13144ffSStefano Zampini } 1032b03ebc13SStefano Zampini if (!has_candidates) { /* circular edge */ 1033b03ebc13SStefano Zampini PetscInt k, ee = idxs[0],*tmarks; 1034b03ebc13SStefano Zampini 1035b03ebc13SStefano Zampini ierr = PetscCalloc1(ne,&tmarks);CHKERRQ(ierr); 1036b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Circular edge %d\n",i); 1037b03ebc13SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) { 1038b03ebc13SStefano Zampini PetscInt k2; 1039b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Set to corner %d\n",jj[k]); 1040b03ebc13SStefano Zampini ierr = PetscBTSet(btv,jj[k]);CHKERRQ(ierr); 1041b03ebc13SStefano Zampini for (k2=iit[jj[k]];k2<iit[jj[k]+1];k2++) tmarks[jjt[k2]]++; 1042b03ebc13SStefano Zampini } 1043b03ebc13SStefano Zampini for (j=0;j<size;j++) { 1044b03ebc13SStefano Zampini if (tmarks[idxs[j]] > 1) { 1045b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF," Edge dof set to primal %d\n",idxs[j]); 1046b03ebc13SStefano Zampini newprimals[cum++] = idxs[j]; 1047b03ebc13SStefano Zampini } 1048b03ebc13SStefano Zampini } 1049b03ebc13SStefano Zampini ierr = PetscFree(tmarks);CHKERRQ(ierr); 1050b03ebc13SStefano Zampini } 1051a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1052a13144ffSStefano Zampini } 1053a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 1054a13144ffSStefano Zampini } 1055b03ebc13SStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 10560569b399SStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&iit,&jjt,&done);CHKERRQ(ierr); 1057a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,newprimals);CHKERRQ(ierr); 1058c2151214SStefano Zampini if (fl2g) { 1059c2151214SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,cum,newprimals,newprimals);CHKERRQ(ierr); 1060c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1061c2151214SStefano Zampini for (i=0;i<nee;i++) { 1062c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1063c2151214SStefano Zampini } 1064c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1065c2151214SStefano Zampini } 1066c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1067a13144ffSStefano Zampini ierr = ISCreateGeneral(comm,cum,newprimals,PETSC_COPY_VALUES,&primals);CHKERRQ(ierr); 1068a13144ffSStefano Zampini ierr = PetscFree(newprimals);CHKERRQ(ierr); 1069a13144ffSStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primals);CHKERRQ(ierr); 1070a13144ffSStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1071a13144ffSStefano Zampini ierr = PCBDDCAnalyzeInterface(pc);CHKERRQ(ierr); 1072213b8bfaSStefano Zampini pcbddc->mat_graph->twodim = PETSC_FALSE; 1073c2151214SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1074c2151214SStefano Zampini if (fl2g) { 1075c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,allprimals,&primals);CHKERRQ(ierr); 1076c2151214SStefano Zampini ierr = PetscMalloc1(nee,&eedges);CHKERRQ(ierr); 1077c2151214SStefano Zampini for (i=0;i<nee;i++) { 1078c2151214SStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(fl2g,IS_GTOLM_DROP,alleedges[i],&eedges[i]);CHKERRQ(ierr); 1079c2151214SStefano Zampini } 1080c2151214SStefano Zampini } else { 1081c2151214SStefano Zampini eedges = alleedges; 1082c2151214SStefano Zampini primals = allprimals; 1083c2151214SStefano Zampini } 1084b03ebc13SStefano Zampini ierr = PetscCalloc1(nee,&extcols);CHKERRQ(ierr); 1085a13144ffSStefano Zampini 1086a13144ffSStefano Zampini /* Mark again */ 1087a13144ffSStefano Zampini ierr = PetscMemzero(marks,ne*sizeof(PetscInt));CHKERRQ(ierr); 1088a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1089a13144ffSStefano Zampini PetscInt size,mark = i+1; 1090a13144ffSStefano Zampini 1091a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 1092a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1093a13144ffSStefano Zampini for (j=0;j<size;j++) marks[idxs[j]] = mark; 1094a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1095a13144ffSStefano Zampini } 1096a13144ffSStefano Zampini if (print) { 1097a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)primals,"obtained_primal_dofs_secondpass");CHKERRQ(ierr); 1098a13144ffSStefano Zampini ierr = ISView(primals,NULL);CHKERRQ(ierr); 1099a13144ffSStefano Zampini } 1100a13144ffSStefano Zampini 1101a13144ffSStefano Zampini /* Recompute extended cols */ 1102a13144ffSStefano Zampini eerr = PETSC_FALSE; 1103a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1104a13144ffSStefano Zampini PetscInt size; 1105a13144ffSStefano Zampini 1106a13144ffSStefano Zampini cum = 0; 1107a13144ffSStefano Zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 11081e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 11091e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 1110a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1111a13144ffSStefano Zampini for (j=0;j<size;j++) { 1112a13144ffSStefano Zampini PetscInt k,ee = idxs[j]; 11131e0482f5SStefano Zampini for (k=ii[ee];k<ii[ee+1];k++) if (!PetscBTLookup(btv,jj[k])) extrow[cum++] = jj[k]; 1114a13144ffSStefano Zampini } 1115a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1116a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&cum,extrow);CHKERRQ(ierr); 1117a13144ffSStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,cum,extrow,gidxs);CHKERRQ(ierr); 1118a13144ffSStefano Zampini ierr = PetscSortIntWithArray(cum,gidxs,extrow);CHKERRQ(ierr); 1119a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,cum,extrow,PETSC_COPY_VALUES,&extcols[i]);CHKERRQ(ierr); 1120a13144ffSStefano Zampini if (cum != size -1) { 1121a13144ffSStefano Zampini if (print) { 1122a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)eedges[i],"error_edge_secondpass");CHKERRQ(ierr); 1123a13144ffSStefano Zampini ierr = ISView(eedges[i],NULL);CHKERRQ(ierr); 1124a13144ffSStefano Zampini ierr = PetscObjectSetName((PetscObject)extcols[i],"error_extcol_secondpass");CHKERRQ(ierr); 1125a13144ffSStefano Zampini ierr = ISView(extcols[i],NULL);CHKERRQ(ierr); 1126a13144ffSStefano Zampini } 1127a13144ffSStefano Zampini eerr = PETSC_TRUE; 1128a13144ffSStefano Zampini } 1129a13144ffSStefano Zampini } 1130a13144ffSStefano Zampini } 1131a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1132a13144ffSStefano Zampini ierr = PetscFree2(extrow,gidxs);CHKERRQ(ierr); 1133b03ebc13SStefano Zampini ierr = PetscBTDestroy(&bter);CHKERRQ(ierr); 11347d871cd7SStefano Zampini if (print) { ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,5,PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); } 1135a13144ffSStefano Zampini /* an error should not occur at this point */ 1136a13144ffSStefano Zampini if (eerr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected SIZE OF EDGE > EXTCOL SECOND PASS"); 1137a13144ffSStefano Zampini 11384e64d54eSstefano_zampini /* Check the number of endpoints */ 11390569b399SStefano Zampini ierr = MatGetRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1140b03ebc13SStefano Zampini ierr = PetscMalloc1(2*nee,&corners);CHKERRQ(ierr); 1141b03ebc13SStefano Zampini ierr = PetscMalloc1(nee,&cedges);CHKERRQ(ierr); 11424e64d54eSstefano_zampini for (i=0;i<nee;i++) { 1143b03ebc13SStefano Zampini PetscInt size, found = 0, gc[2]; 11444e64d54eSstefano_zampini 1145b03ebc13SStefano Zampini /* init with defaults */ 1146b03ebc13SStefano Zampini cedges[i] = corners[i*2] = corners[i*2+1] = -1; 11474e64d54eSstefano_zampini ierr = ISGetLocalSize(eedges[i],&size);CHKERRQ(ierr); 11481e0482f5SStefano Zampini if (!size && nedfieldlocal) continue; 11491e0482f5SStefano Zampini if (!size) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Unexpected zero sized edge %d",i); 11504e64d54eSstefano_zampini ierr = ISGetIndices(eedges[i],&idxs);CHKERRQ(ierr); 1151b03ebc13SStefano Zampini ierr = PetscBTMemzero(nv,btvc);CHKERRQ(ierr); 11524e64d54eSstefano_zampini for (j=0;j<size;j++) { 11534e64d54eSstefano_zampini PetscInt k,ee = idxs[j]; 11544e64d54eSstefano_zampini for (k=ii[ee];k<ii[ee+1];k++) { 11554e64d54eSstefano_zampini PetscInt vv = jj[k]; 11564e64d54eSstefano_zampini if (PetscBTLookup(btv,vv) && !PetscBTLookupSet(btvc,vv)) { 1157b03ebc13SStefano Zampini if (found == 2) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found more then two corners for edge %d\n",i); 1158b03ebc13SStefano Zampini corners[i*2+found++] = vv; 11594e64d54eSstefano_zampini } 11604e64d54eSstefano_zampini } 11614e64d54eSstefano_zampini } 1162b03ebc13SStefano Zampini if (found != 2) { 1163b03ebc13SStefano Zampini PetscInt e; 1164b03ebc13SStefano Zampini if (fl2g) { 1165b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,1,idxs,&e);CHKERRQ(ierr); 1166b03ebc13SStefano Zampini } else { 1167b03ebc13SStefano Zampini e = idxs[0]; 1168b03ebc13SStefano Zampini } 1169b03ebc13SStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Found %d corners for edge %d (astart %d, estart %d)\n",found,i,e,idxs[0]); 1170b03ebc13SStefano Zampini } 1171eee23b56SStefano Zampini 1172eee23b56SStefano Zampini /* get primal dof index on this coarse edge */ 1173b03ebc13SStefano Zampini ierr = ISLocalToGlobalMappingApply(vl2g,2,corners+2*i,gc);CHKERRQ(ierr); 1174b03ebc13SStefano Zampini if (gc[0] > gc[1]) { 1175b03ebc13SStefano Zampini PetscInt swap = corners[2*i]; 1176b03ebc13SStefano Zampini corners[2*i] = corners[2*i+1]; 1177b03ebc13SStefano Zampini corners[2*i+1] = swap; 1178b03ebc13SStefano Zampini } 1179eee23b56SStefano Zampini cedges[i] = idxs[size-1]; 11804e64d54eSstefano_zampini ierr = ISRestoreIndices(eedges[i],&idxs);CHKERRQ(ierr); 1181b03ebc13SStefano Zampini if (print) PetscPrintf(PETSC_COMM_SELF,"EDGE %d: ce %d, corners (%d,%d)\n",i,cedges[i],corners[2*i],corners[2*i+1]); 11824e64d54eSstefano_zampini } 11830569b399SStefano Zampini ierr = MatRestoreRowIJ(lG,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 11844e64d54eSstefano_zampini ierr = PetscBTDestroy(&btvc);CHKERRQ(ierr); 11854e64d54eSstefano_zampini 1186a13144ffSStefano Zampini #if defined(PETSC_USE_DEBUG) 1187a13144ffSStefano Zampini /* Inspects columns of lG (rows of lGt) and make sure the change of basis will 1188a13144ffSStefano Zampini not interfere with neighbouring coarse edges */ 1189a13144ffSStefano Zampini ierr = PetscMalloc1(nee+1,&emarks);CHKERRQ(ierr); 1190a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1191a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1192a13144ffSStefano Zampini PetscInt emax = 0,eemax = 0; 1193a13144ffSStefano Zampini 1194a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1195a13144ffSStefano Zampini ierr = PetscMemzero(emarks,(nee+1)*sizeof(PetscInt));CHKERRQ(ierr); 1196a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) emarks[marks[jj[j]]]++; 1197a13144ffSStefano Zampini for (j=1;j<nee+1;j++) { 1198a13144ffSStefano Zampini if (emax < emarks[j]) { 1199a13144ffSStefano Zampini emax = emarks[j]; 1200a13144ffSStefano Zampini eemax = j; 1201a13144ffSStefano Zampini } 1202a13144ffSStefano Zampini } 1203a13144ffSStefano Zampini /* not relevant for edges */ 1204a13144ffSStefano Zampini if (!eemax) continue; 1205a13144ffSStefano Zampini 1206a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) { 1207a13144ffSStefano Zampini if (marks[jj[j]] && marks[jj[j]] != eemax) { 1208c2151214SStefano Zampini SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_SUP,"Found 2 coarse edges (id %d and %d) connected through the %d nodal dof at edge dof %d\n",marks[jj[j]]-1,eemax,i,jj[j]); 1209a13144ffSStefano Zampini } 1210a13144ffSStefano Zampini } 1211a13144ffSStefano Zampini } 1212a13144ffSStefano Zampini ierr = PetscFree(emarks);CHKERRQ(ierr); 1213a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1214a13144ffSStefano Zampini #endif 1215a13144ffSStefano Zampini 1216a13144ffSStefano Zampini /* Compute extended rows indices for edge blocks of the change of basis */ 1217a13144ffSStefano Zampini ierr = MatGetRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1218a13144ffSStefano Zampini ierr = MatSeqAIJGetMaxRowNonzeros(lGt,&extmem);CHKERRQ(ierr); 1219a13144ffSStefano Zampini extmem *= maxsize; 1220a13144ffSStefano Zampini ierr = PetscMalloc1(extmem*nee,&extrow);CHKERRQ(ierr); 1221a13144ffSStefano Zampini ierr = PetscMalloc1(nee,&extrows);CHKERRQ(ierr); 1222a13144ffSStefano Zampini ierr = PetscCalloc1(nee,&extrowcum);CHKERRQ(ierr); 1223a13144ffSStefano Zampini for (i=0;i<nv;i++) { 1224a13144ffSStefano Zampini PetscInt mark = 0,size,start; 1225213b8bfaSStefano Zampini 1226a13144ffSStefano Zampini if (ii[i+1]==ii[i] || PetscBTLookup(btv,i)) continue; 1227a13144ffSStefano Zampini for (j=ii[i];j<ii[i+1];j++) 1228a13144ffSStefano Zampini if (marks[jj[j]] && !mark) 1229a13144ffSStefano Zampini mark = marks[jj[j]]; 1230a13144ffSStefano Zampini 1231a13144ffSStefano Zampini /* not relevant */ 1232a13144ffSStefano Zampini if (!mark) continue; 1233a13144ffSStefano Zampini 1234a13144ffSStefano Zampini /* import extended row */ 1235a13144ffSStefano Zampini mark--; 1236a13144ffSStefano Zampini start = mark*extmem+extrowcum[mark]; 1237a13144ffSStefano Zampini size = ii[i+1]-ii[i]; 1238a13144ffSStefano Zampini if (extrowcum[mark] + size > extmem) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Not enough memory allocated %d > %d",extrowcum[mark] + size,extmem); 1239a13144ffSStefano Zampini ierr = PetscMemcpy(extrow+start,jj+ii[i],size*sizeof(PetscInt));CHKERRQ(ierr); 1240a13144ffSStefano Zampini extrowcum[mark] += size; 1241a13144ffSStefano Zampini } 1242a13144ffSStefano Zampini ierr = MatRestoreRowIJ(lGt,0,PETSC_FALSE,PETSC_FALSE,&i,&ii,&jj,&done);CHKERRQ(ierr); 1243213b8bfaSStefano Zampini ierr = MatDestroy(&lGt);CHKERRQ(ierr); 1244213b8bfaSStefano Zampini ierr = PetscFree(marks);CHKERRQ(ierr); 1245213b8bfaSStefano Zampini 1246213b8bfaSStefano Zampini /* Compress extrows */ 1247a13144ffSStefano Zampini cum = 0; 1248a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1249a13144ffSStefano Zampini PetscInt size = extrowcum[i],*start = extrow + i*extmem; 1250a13144ffSStefano Zampini ierr = PetscSortRemoveDupsInt(&size,start);CHKERRQ(ierr); 1251a13144ffSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,size,start,PETSC_USE_POINTER,&extrows[i]);CHKERRQ(ierr); 1252a13144ffSStefano Zampini cum = PetscMax(cum,size); 1253a13144ffSStefano Zampini } 1254a13144ffSStefano Zampini ierr = PetscFree(extrowcum);CHKERRQ(ierr); 1255a13144ffSStefano Zampini ierr = PetscBTDestroy(&btv);CHKERRQ(ierr); 1256a13144ffSStefano Zampini ierr = PetscBTDestroy(&btvcand);CHKERRQ(ierr); 1257a13144ffSStefano Zampini 1258a13144ffSStefano Zampini /* Workspace for lapack inner calls and VecSetValues */ 1259a13144ffSStefano Zampini ierr = PetscMalloc2((5+cum+maxsize)*maxsize,&work,maxsize,&rwork);CHKERRQ(ierr); 1260a13144ffSStefano Zampini 1261a13144ffSStefano Zampini /* Create change of basis matrix (preallocation can be improved) */ 1262a13144ffSStefano Zampini ierr = MatCreate(comm,&T);CHKERRQ(ierr); 1263c2151214SStefano Zampini ierr = MatSetSizes(T,pc->pmat->rmap->n,pc->pmat->rmap->n, 1264c2151214SStefano Zampini pc->pmat->rmap->N,pc->pmat->rmap->N);CHKERRQ(ierr); 1265a13144ffSStefano Zampini ierr = MatSetType(T,MATAIJ);CHKERRQ(ierr); 1266a13144ffSStefano Zampini ierr = MatSeqAIJSetPreallocation(T,10,NULL);CHKERRQ(ierr); 1267a13144ffSStefano Zampini ierr = MatMPIAIJSetPreallocation(T,10,NULL,10,NULL);CHKERRQ(ierr); 12681e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(T,al2g,al2g);CHKERRQ(ierr); 1269a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 1270a13144ffSStefano Zampini ierr = MatSetOption(T,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 1271213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&al2g);CHKERRQ(ierr); 1272a13144ffSStefano Zampini 1273a13144ffSStefano Zampini /* Defaults to identity */ 1274c2151214SStefano Zampini ierr = MatCreateVecs(pc->pmat,&tvec,NULL);CHKERRQ(ierr); 1275a13144ffSStefano Zampini ierr = VecSet(tvec,1.0);CHKERRQ(ierr); 1276a13144ffSStefano Zampini ierr = MatDiagonalSet(T,tvec,INSERT_VALUES);CHKERRQ(ierr); 1277a13144ffSStefano Zampini ierr = VecDestroy(&tvec);CHKERRQ(ierr); 1278a13144ffSStefano Zampini 12791e0482f5SStefano Zampini /* Create discrete gradient for the coarser level if needed */ 12801e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 12811e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 12821e0482f5SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) { 12831e0482f5SStefano Zampini ISLocalToGlobalMapping cel2g,cvl2g; 12841e0482f5SStefano Zampini IS wis,gwis; 12851e0482f5SStefano Zampini PetscInt cnv,cne; 12861e0482f5SStefano Zampini 12871e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,nee,cedges,PETSC_COPY_VALUES,&wis);CHKERRQ(ierr); 12881e0482f5SStefano Zampini if (fl2g) { 12891e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(fl2g,wis,&pcbddc->nedclocal);CHKERRQ(ierr); 12901e0482f5SStefano Zampini } else { 12911e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)wis);CHKERRQ(ierr); 12921e0482f5SStefano Zampini pcbddc->nedclocal = wis; 12931e0482f5SStefano Zampini } 12941e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(el2g,wis,&gwis);CHKERRQ(ierr); 12951e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12961e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cne,&wis);CHKERRQ(ierr); 12971e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cel2g);CHKERRQ(ierr); 12981e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 12991e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 13001e0482f5SStefano Zampini 13011e0482f5SStefano Zampini ierr = ISCreateGeneral(comm,2*nee,corners,PETSC_USE_POINTER,&wis);CHKERRQ(ierr); 13021e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(vl2g,wis,&gwis);CHKERRQ(ierr); 13031e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 13041e0482f5SStefano Zampini ierr = ISRenumber(gwis,NULL,&cnv,&wis);CHKERRQ(ierr); 13051e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(wis,&cvl2g);CHKERRQ(ierr); 13061e0482f5SStefano Zampini ierr = ISDestroy(&wis);CHKERRQ(ierr); 13071e0482f5SStefano Zampini ierr = ISDestroy(&gwis);CHKERRQ(ierr); 13081e0482f5SStefano Zampini 13091e0482f5SStefano Zampini ierr = MatCreate(comm,&pcbddc->nedcG);CHKERRQ(ierr); 13101e0482f5SStefano Zampini ierr = MatSetSizes(pcbddc->nedcG,PETSC_DECIDE,PETSC_DECIDE,cne,cnv);CHKERRQ(ierr); 13111e0482f5SStefano Zampini ierr = MatSetType(pcbddc->nedcG,MATAIJ);CHKERRQ(ierr); 13121e0482f5SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->nedcG,2,NULL);CHKERRQ(ierr); 13131e0482f5SStefano Zampini ierr = MatMPIAIJSetPreallocation(pcbddc->nedcG,2,NULL,2,NULL);CHKERRQ(ierr); 13141e0482f5SStefano Zampini ierr = MatSetLocalToGlobalMapping(pcbddc->nedcG,cel2g,cvl2g);CHKERRQ(ierr); 13151e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cel2g);CHKERRQ(ierr); 13161e0482f5SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cvl2g);CHKERRQ(ierr); 13171e0482f5SStefano Zampini } 1318213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&vl2g);CHKERRQ(ierr); 13191e0482f5SStefano Zampini 13201e0482f5SStefano Zampini #if defined(PRINT_GDET) 13211e0482f5SStefano Zampini inc = 0; 13221e0482f5SStefano Zampini lev = pcbddc->current_level; 13231e0482f5SStefano Zampini #endif 1324213b8bfaSStefano Zampini 1325213b8bfaSStefano Zampini /* Insert values in the change of basis matrix */ 1326a13144ffSStefano Zampini for (i=0;i<nee;i++) { 1327a13144ffSStefano Zampini Mat Gins = NULL, GKins = NULL; 13281e0482f5SStefano Zampini IS cornersis = NULL; 13291e0482f5SStefano Zampini PetscScalar cvals[2]; 1330a13144ffSStefano Zampini 13311e0482f5SStefano Zampini if (pcbddc->nedcG) { 13321e0482f5SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,2,corners+2*i,PETSC_USE_POINTER,&cornersis);CHKERRQ(ierr); 13331e0482f5SStefano Zampini } 13341e0482f5SStefano Zampini ierr = PCBDDCComputeNedelecChangeEdge(lG,eedges[i],extrows[i],extcols[i],cornersis,&Gins,&GKins,cvals,work,rwork);CHKERRQ(ierr); 1335a13144ffSStefano Zampini if (Gins && GKins) { 1336a13144ffSStefano Zampini PetscScalar *data; 1337a13144ffSStefano Zampini const PetscInt *rows,*cols; 1338a13144ffSStefano Zampini PetscInt nrh,nch,nrc,ncc; 1339a13144ffSStefano Zampini 1340a13144ffSStefano Zampini ierr = ISGetIndices(eedges[i],&cols);CHKERRQ(ierr); 1341a13144ffSStefano Zampini /* H1 */ 1342a13144ffSStefano Zampini ierr = ISGetIndices(extrows[i],&rows);CHKERRQ(ierr); 1343a13144ffSStefano Zampini ierr = MatGetSize(Gins,&nrh,&nch);CHKERRQ(ierr); 1344a13144ffSStefano Zampini ierr = MatDenseGetArray(Gins,&data);CHKERRQ(ierr); 1345a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrh,rows,nch,cols,data,INSERT_VALUES);CHKERRQ(ierr); 1346a13144ffSStefano Zampini ierr = MatDenseRestoreArray(Gins,&data);CHKERRQ(ierr); 1347a13144ffSStefano Zampini ierr = ISRestoreIndices(extrows[i],&rows);CHKERRQ(ierr); 1348a13144ffSStefano Zampini /* complement */ 1349a13144ffSStefano Zampini ierr = MatGetSize(GKins,&nrc,&ncc);CHKERRQ(ierr); 13501e0482f5SStefano Zampini if (!ncc) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Constant function has not been generated for coarse edge %d",i); 1351213b8bfaSStefano Zampini if (ncc + nch != nrc) SETERRQ4(PETSC_COMM_SELF,PETSC_ERR_PLIB,"The sum of the number of columns of GKins %d and Gins %d does not match %d for coarse edge %d",ncc,nch,nrc,i); 1352213b8bfaSStefano Zampini if (ncc != 1 && pcbddc->nedcG) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot generate the coarse discrete gradient for coarse edge %d with ncc %d",i,ncc); 1353a13144ffSStefano Zampini ierr = MatDenseGetArray(GKins,&data);CHKERRQ(ierr); 1354a13144ffSStefano Zampini ierr = MatSetValuesLocal(T,nrc,cols,ncc,cols+nch,data,INSERT_VALUES);CHKERRQ(ierr); 1355a13144ffSStefano Zampini ierr = MatDenseRestoreArray(GKins,&data);CHKERRQ(ierr); 13561e0482f5SStefano Zampini 13571e0482f5SStefano Zampini /* coarse discrete gradient */ 13581e0482f5SStefano Zampini if (pcbddc->nedcG) { 13591e0482f5SStefano Zampini PetscInt cols[2]; 13601e0482f5SStefano Zampini 13611e0482f5SStefano Zampini cols[0] = 2*i; 13621e0482f5SStefano Zampini cols[1] = 2*i+1; 13631e0482f5SStefano Zampini ierr = MatSetValuesLocal(pcbddc->nedcG,1,&i,2,cols,cvals,INSERT_VALUES);CHKERRQ(ierr); 13641e0482f5SStefano Zampini } 1365a13144ffSStefano Zampini ierr = ISRestoreIndices(eedges[i],&cols);CHKERRQ(ierr); 1366a13144ffSStefano Zampini } 1367a13144ffSStefano Zampini ierr = ISDestroy(&extrows[i]);CHKERRQ(ierr); 1368a13144ffSStefano Zampini ierr = ISDestroy(&extcols[i]);CHKERRQ(ierr); 13691e0482f5SStefano Zampini ierr = ISDestroy(&cornersis);CHKERRQ(ierr); 1370a13144ffSStefano Zampini ierr = MatDestroy(&Gins);CHKERRQ(ierr); 1371a13144ffSStefano Zampini ierr = MatDestroy(&GKins);CHKERRQ(ierr); 1372a13144ffSStefano Zampini } 1373213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&el2g);CHKERRQ(ierr); 1374a13144ffSStefano Zampini 1375a13144ffSStefano Zampini /* Start assembling */ 1376a13144ffSStefano Zampini ierr = MatAssemblyBegin(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13771e0482f5SStefano Zampini if (pcbddc->nedcG) { 13781e0482f5SStefano Zampini ierr = MatAssemblyBegin(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 13791e0482f5SStefano Zampini } 1380a13144ffSStefano Zampini 1381a13144ffSStefano Zampini /* Free */ 1382c2151214SStefano Zampini if (fl2g) { 1383c2151214SStefano Zampini ierr = ISDestroy(&primals);CHKERRQ(ierr); 1384c2151214SStefano Zampini for (i=0;i<nee;i++) { 1385c2151214SStefano Zampini ierr = ISDestroy(&eedges[i]);CHKERRQ(ierr); 1386c2151214SStefano Zampini } 1387c2151214SStefano Zampini ierr = PetscFree(eedges);CHKERRQ(ierr); 1388c2151214SStefano Zampini } 1389eee23b56SStefano Zampini 1390eee23b56SStefano Zampini /* hack mat_graph with primal dofs on the coarse edges */ 1391eee23b56SStefano Zampini { 1392eee23b56SStefano Zampini PCBDDCGraph graph = pcbddc->mat_graph; 1393eee23b56SStefano Zampini PetscInt *oqueue = graph->queue; 1394eee23b56SStefano Zampini PetscInt *ocptr = graph->cptr; 1395eee23b56SStefano Zampini PetscInt ncc,*idxs; 1396eee23b56SStefano Zampini 1397eee23b56SStefano Zampini /* find first primal edge */ 1398eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1399eee23b56SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1400eee23b56SStefano Zampini } else { 1401eee23b56SStefano Zampini if (fl2g) { 1402eee23b56SStefano Zampini ierr = ISLocalToGlobalMappingApply(fl2g,nee,cedges,cedges);CHKERRQ(ierr); 1403eee23b56SStefano Zampini } 1404eee23b56SStefano Zampini idxs = cedges; 1405eee23b56SStefano Zampini } 1406eee23b56SStefano Zampini cum = 0; 1407eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1408eee23b56SStefano Zampini 1409eee23b56SStefano Zampini /* adapt connected components */ 1410eee23b56SStefano Zampini ierr = PetscMalloc2(graph->nvtxs+1,&graph->cptr,ocptr[graph->ncc],&graph->queue);CHKERRQ(ierr); 1411eee23b56SStefano Zampini graph->cptr[0] = 0; 1412eee23b56SStefano Zampini for (i=0,ncc=0;i<graph->ncc;i++) { 1413eee23b56SStefano Zampini PetscInt lc = ocptr[i+1]-ocptr[i]; 1414eee23b56SStefano Zampini if (cum != nee && oqueue[ocptr[i+1]-1] == cedges[cum]) { /* this cc has a primal dof */ 1415eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc]+1; 1416eee23b56SStefano Zampini graph->queue[graph->cptr[ncc]] = cedges[cum]; 1417eee23b56SStefano Zampini ncc++; 1418eee23b56SStefano Zampini lc--; 1419eee23b56SStefano Zampini cum++; 1420eee23b56SStefano Zampini while (cum < nee && cedges[cum] < 0) cum++; 1421eee23b56SStefano Zampini } 1422eee23b56SStefano Zampini graph->cptr[ncc+1] = graph->cptr[ncc] + lc; 1423eee23b56SStefano Zampini for (j=0;j<lc;j++) graph->queue[graph->cptr[ncc]+j] = oqueue[ocptr[i]+j]; 1424eee23b56SStefano Zampini ncc++; 1425eee23b56SStefano Zampini } 1426eee23b56SStefano Zampini graph->ncc = ncc; 1427eee23b56SStefano Zampini if (pcbddc->nedclocal) { 1428eee23b56SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,(const PetscInt**)&idxs);CHKERRQ(ierr); 1429eee23b56SStefano Zampini } 1430eee23b56SStefano Zampini ierr = PetscFree2(ocptr,oqueue);CHKERRQ(ierr); 1431eee23b56SStefano Zampini } 1432213b8bfaSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&fl2g);CHKERRQ(ierr); 1433c2151214SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,&nee,&alleedges,&allprimals);CHKERRQ(ierr); 1434c2151214SStefano Zampini ierr = PCBDDCGraphResetCSR(pcbddc->mat_graph);CHKERRQ(ierr); 1435213b8bfaSStefano Zampini ierr = MatDestroy(&conn);CHKERRQ(ierr); 1436eee23b56SStefano Zampini 1437c2151214SStefano Zampini ierr = ISDestroy(&nedfieldlocal);CHKERRQ(ierr); 1438a13144ffSStefano Zampini ierr = PetscFree(extrow);CHKERRQ(ierr); 1439a13144ffSStefano Zampini ierr = PetscFree2(work,rwork);CHKERRQ(ierr); 1440b03ebc13SStefano Zampini ierr = PetscFree(corners);CHKERRQ(ierr); 1441b03ebc13SStefano Zampini ierr = PetscFree(cedges);CHKERRQ(ierr); 1442a13144ffSStefano Zampini ierr = PetscFree(extrows);CHKERRQ(ierr); 1443a13144ffSStefano Zampini ierr = PetscFree(extcols);CHKERRQ(ierr); 1444a13144ffSStefano Zampini ierr = MatDestroy(&lG);CHKERRQ(ierr); 1445a13144ffSStefano Zampini 1446a13144ffSStefano Zampini /* Complete assembling */ 1447a13144ffSStefano Zampini ierr = MatAssemblyEnd(T,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14481e0482f5SStefano Zampini if (pcbddc->nedcG) { 14491e0482f5SStefano Zampini ierr = MatAssemblyEnd(pcbddc->nedcG,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 14501e0482f5SStefano Zampini #if 0 14511e0482f5SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->nedcG,"coarse_G");CHKERRQ(ierr); 14521e0482f5SStefano Zampini ierr = MatView(pcbddc->nedcG,NULL);CHKERRQ(ierr); 14531e0482f5SStefano Zampini #endif 14541e0482f5SStefano Zampini } 1455a13144ffSStefano Zampini 1456a13144ffSStefano Zampini /* set change of basis */ 1457213b8bfaSStefano Zampini ierr = PCBDDCSetChangeOfBasisMat(pc,T,singular);CHKERRQ(ierr); 1458a13144ffSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 1459a13144ffSStefano Zampini 1460a13144ffSStefano Zampini PetscFunctionReturn(0); 1461a13144ffSStefano Zampini } 1462a13144ffSStefano Zampini 1463d8203eabSStefano Zampini /* the near-null space of BDDC carries information on quadrature weights, 1464d8203eabSStefano Zampini and these can be collinear -> so cheat with MatNullSpaceCreate 1465d8203eabSStefano Zampini and create a suitable set of basis vectors first */ 1466d8203eabSStefano Zampini PetscErrorCode PCBDDCNullSpaceCreate(MPI_Comm comm, PetscBool has_const, PetscInt nvecs, Vec quad_vecs[], MatNullSpace *nnsp) 1467d8203eabSStefano Zampini { 1468d8203eabSStefano Zampini PetscErrorCode ierr; 1469d8203eabSStefano Zampini PetscInt i; 1470d8203eabSStefano Zampini 1471d8203eabSStefano Zampini PetscFunctionBegin; 1472d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { 1473d8203eabSStefano Zampini PetscInt first,last; 1474d8203eabSStefano Zampini 1475d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 147686fa73c5SStefano Zampini if (last-first < 2*nvecs && has_const) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not implemented"); 1477d8203eabSStefano Zampini if (i>=first && i < last) { 1478d8203eabSStefano Zampini PetscScalar *data; 1479d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1480d8203eabSStefano Zampini if (!has_const) { 1481d8203eabSStefano Zampini data[i-first] = 1.; 1482d8203eabSStefano Zampini } else { 148386fa73c5SStefano Zampini data[2*i-first] = 1./PetscSqrtReal(2.); 148486fa73c5SStefano Zampini data[2*i-first+1] = -1./PetscSqrtReal(2.); 1485d8203eabSStefano Zampini } 1486d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1487d8203eabSStefano Zampini } 1488d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1489d8203eabSStefano Zampini } 1490d8203eabSStefano Zampini ierr = MatNullSpaceCreate(comm,has_const,nvecs,quad_vecs,nnsp);CHKERRQ(ierr); 1491d8203eabSStefano Zampini for (i=0;i<nvecs;i++) { /* reset vectors */ 1492d8203eabSStefano Zampini PetscInt first,last; 1493ddc40e2cSstefano_zampini ierr = VecLockPop(quad_vecs[i]);CHKERRQ(ierr); 1494d8203eabSStefano Zampini ierr = VecGetOwnershipRange(quad_vecs[i],&first,&last);CHKERRQ(ierr); 1495d8203eabSStefano Zampini if (i>=first && i < last) { 1496d8203eabSStefano Zampini PetscScalar *data; 1497d8203eabSStefano Zampini ierr = VecGetArray(quad_vecs[i],&data);CHKERRQ(ierr); 1498d8203eabSStefano Zampini if (!has_const) { 1499d8203eabSStefano Zampini data[i-first] = 0.; 1500d8203eabSStefano Zampini } else { 150186fa73c5SStefano Zampini data[2*i-first] = 0.; 150286fa73c5SStefano Zampini data[2*i-first+1] = 0.; 1503d8203eabSStefano Zampini } 1504d8203eabSStefano Zampini ierr = VecRestoreArray(quad_vecs[i],&data);CHKERRQ(ierr); 1505d8203eabSStefano Zampini } 1506d8203eabSStefano Zampini ierr = PetscObjectStateIncrease((PetscObject)quad_vecs[i]);CHKERRQ(ierr); 1507ddc40e2cSstefano_zampini ierr = VecLockPush(quad_vecs[i]);CHKERRQ(ierr); 1508d8203eabSStefano Zampini } 1509d8203eabSStefano Zampini PetscFunctionReturn(0); 1510d8203eabSStefano Zampini } 1511d8203eabSStefano Zampini 15128ae0ca82SStefano Zampini PetscErrorCode PCBDDCComputeNoNetFlux(Mat A, Mat divudotp, PetscBool transpose, IS vl2l, PCBDDCGraph graph, MatNullSpace *nnsp) 1513669cc0f4SStefano Zampini { 1514a198735bSStefano Zampini Mat loc_divudotp; 1515fa23a32eSStefano Zampini Vec p,v,vins,quad_vec,*quad_vecs; 15168ae0ca82SStefano Zampini ISLocalToGlobalMapping map; 1517669cc0f4SStefano Zampini PetscScalar *vals; 1518669cc0f4SStefano Zampini const PetscScalar *array; 1519a040e873SStefano Zampini PetscInt i,maxneighs,maxsize; 1520a040e873SStefano Zampini PetscInt n_neigh,*neigh,*n_shared,**shared; 15211ae86dd6SStefano Zampini PetscMPIInt rank; 1522a198735bSStefano Zampini PetscErrorCode ierr; 1523669cc0f4SStefano Zampini 1524669cc0f4SStefano Zampini PetscFunctionBegin; 1525a040e873SStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1526a040e873SStefano Zampini ierr = MPIU_Allreduce(&n_neigh,&maxneighs,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)A));CHKERRQ(ierr); 1527669cc0f4SStefano Zampini maxsize = 0; 1528a040e873SStefano Zampini for (i=0;i<n_neigh;i++) maxsize = PetscMax(n_shared[i],maxsize); 1529669cc0f4SStefano Zampini ierr = PetscMalloc1(maxsize,&vals);CHKERRQ(ierr); 1530669cc0f4SStefano Zampini /* create vectors to hold quadrature weights */ 1531669cc0f4SStefano Zampini ierr = MatCreateVecs(A,&quad_vec,NULL);CHKERRQ(ierr); 15328ae0ca82SStefano Zampini if (!transpose) { 15338ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,&map,NULL);CHKERRQ(ierr); 15348ae0ca82SStefano Zampini } else { 15358ae0ca82SStefano Zampini ierr = MatGetLocalToGlobalMapping(A,NULL,&map);CHKERRQ(ierr); 15368ae0ca82SStefano Zampini } 1537669cc0f4SStefano Zampini ierr = VecDuplicateVecs(quad_vec,maxneighs,&quad_vecs);CHKERRQ(ierr); 15381ae86dd6SStefano Zampini ierr = VecDestroy(&quad_vec);CHKERRQ(ierr); 1539d8203eabSStefano Zampini ierr = PCBDDCNullSpaceCreate(PetscObjectComm((PetscObject)A),PETSC_FALSE,maxneighs,quad_vecs,nnsp);CHKERRQ(ierr); 1540669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1541ddc40e2cSstefano_zampini ierr = VecLockPop(quad_vecs[i]);CHKERRQ(ierr); 15428ae0ca82SStefano Zampini ierr = VecSetLocalToGlobalMapping(quad_vecs[i],map);CHKERRQ(ierr); 1543669cc0f4SStefano Zampini } 1544d8203eabSStefano Zampini 1545669cc0f4SStefano Zampini /* compute local quad vec */ 1546a198735bSStefano Zampini ierr = MatISGetLocalMat(divudotp,&loc_divudotp);CHKERRQ(ierr); 15478ae0ca82SStefano Zampini if (!transpose) { 1548a198735bSStefano Zampini ierr = MatCreateVecs(loc_divudotp,&v,&p);CHKERRQ(ierr); 15498ae0ca82SStefano Zampini } else { 15508ae0ca82SStefano Zampini ierr = MatCreateVecs(loc_divudotp,&p,&v);CHKERRQ(ierr); 15518ae0ca82SStefano Zampini } 1552669cc0f4SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 15538ae0ca82SStefano Zampini if (!transpose) { 1554a198735bSStefano Zampini ierr = MatMultTranspose(loc_divudotp,p,v);CHKERRQ(ierr); 15558ae0ca82SStefano Zampini } else { 15568ae0ca82SStefano Zampini ierr = MatMult(loc_divudotp,p,v);CHKERRQ(ierr); 15578ae0ca82SStefano Zampini } 1558fa23a32eSStefano Zampini if (vl2l) { 1559187c917aSStefano Zampini Mat lA; 1560187c917aSStefano Zampini VecScatter sc; 1561187c917aSStefano Zampini 1562187c917aSStefano Zampini ierr = MatISGetLocalMat(A,&lA);CHKERRQ(ierr); 1563187c917aSStefano Zampini ierr = MatCreateVecs(lA,&vins,NULL);CHKERRQ(ierr); 1564187c917aSStefano Zampini ierr = VecScatterCreate(v,vl2l,vins,NULL,&sc);CHKERRQ(ierr); 1565187c917aSStefano Zampini ierr = VecScatterBegin(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1566187c917aSStefano Zampini ierr = VecScatterEnd(sc,v,vins,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 1567187c917aSStefano Zampini ierr = VecScatterDestroy(&sc);CHKERRQ(ierr); 1568fa23a32eSStefano Zampini } else { 1569fa23a32eSStefano Zampini vins = v; 1570fa23a32eSStefano Zampini } 1571fa23a32eSStefano Zampini ierr = VecGetArrayRead(vins,&array);CHKERRQ(ierr); 1572669cc0f4SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 15739a962809SStefano Zampini 15741ae86dd6SStefano Zampini /* insert in global quadrature vecs */ 15751ae86dd6SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)A),&rank);CHKERRQ(ierr); 1576a040e873SStefano Zampini for (i=0;i<n_neigh;i++) { 1577669cc0f4SStefano Zampini const PetscInt *idxs; 1578669cc0f4SStefano Zampini PetscInt idx,nn,j; 1579669cc0f4SStefano Zampini 1580a040e873SStefano Zampini idxs = shared[i]; 1581a040e873SStefano Zampini nn = n_shared[i]; 1582669cc0f4SStefano Zampini for (j=0;j<nn;j++) vals[j] = array[idxs[j]]; 15831ae86dd6SStefano Zampini ierr = PetscFindInt(rank,graph->count[idxs[0]],graph->neighbours_set[idxs[0]],&idx);CHKERRQ(ierr); 1584669cc0f4SStefano Zampini idx = -(idx+1); 1585669cc0f4SStefano Zampini ierr = VecSetValuesLocal(quad_vecs[idx],nn,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 1586669cc0f4SStefano Zampini } 1587a040e873SStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(graph->l2gmap,&n_neigh,&neigh,&n_shared,&shared);CHKERRQ(ierr); 1588fa23a32eSStefano Zampini ierr = VecRestoreArrayRead(vins,&array);CHKERRQ(ierr); 1589fa23a32eSStefano Zampini if (vl2l) { 1590187c917aSStefano Zampini ierr = VecDestroy(&vins);CHKERRQ(ierr); 1591fa23a32eSStefano Zampini } 1592669cc0f4SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 1593669cc0f4SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 1594669cc0f4SStefano Zampini 1595669cc0f4SStefano Zampini /* assemble near null space */ 1596669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1597669cc0f4SStefano Zampini ierr = VecAssemblyBegin(quad_vecs[i]);CHKERRQ(ierr); 1598669cc0f4SStefano Zampini } 1599669cc0f4SStefano Zampini for (i=0;i<maxneighs;i++) { 1600669cc0f4SStefano Zampini ierr = VecAssemblyEnd(quad_vecs[i]);CHKERRQ(ierr); 16013272d46bSStefano Zampini ierr = VecViewFromOptions(quad_vecs[i],NULL,"-pc_bddc_quad_vecs_view");CHKERRQ(ierr); 1602ddc40e2cSstefano_zampini ierr = VecLockPush(quad_vecs[i]);CHKERRQ(ierr); 1603669cc0f4SStefano Zampini } 1604669cc0f4SStefano Zampini ierr = VecDestroyVecs(maxneighs,&quad_vecs);CHKERRQ(ierr); 1605669cc0f4SStefano Zampini PetscFunctionReturn(0); 1606669cc0f4SStefano Zampini } 1607669cc0f4SStefano Zampini 16087620a527SStefano Zampini PetscErrorCode PCBDDCAddPrimalVerticesLocalIS(PC pc, IS primalv) 16097620a527SStefano Zampini { 16107620a527SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16117620a527SStefano Zampini PetscErrorCode ierr; 16127620a527SStefano Zampini 16137620a527SStefano Zampini PetscFunctionBegin; 16147620a527SStefano Zampini if (primalv) { 16157620a527SStefano Zampini if (pcbddc->user_primal_vertices_local) { 16167620a527SStefano Zampini IS list[2], newp; 16177620a527SStefano Zampini 16187620a527SStefano Zampini list[0] = primalv; 16197620a527SStefano Zampini list[1] = pcbddc->user_primal_vertices_local; 16207620a527SStefano Zampini ierr = ISConcatenate(PetscObjectComm((PetscObject)pc),2,list,&newp);CHKERRQ(ierr); 16217620a527SStefano Zampini ierr = ISSortRemoveDups(newp);CHKERRQ(ierr); 16227620a527SStefano Zampini ierr = ISDestroy(&list[1]);CHKERRQ(ierr); 16237620a527SStefano Zampini pcbddc->user_primal_vertices_local = newp; 16247620a527SStefano Zampini } else { 16257620a527SStefano Zampini ierr = PCBDDCSetPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 16267620a527SStefano Zampini } 16277620a527SStefano Zampini } 16287620a527SStefano Zampini PetscFunctionReturn(0); 16297620a527SStefano Zampini } 1630669cc0f4SStefano Zampini 16311f4df5f7SStefano Zampini PetscErrorCode PCBDDCComputeLocalTopologyInfo(PC pc) 16321f4df5f7SStefano Zampini { 16331f4df5f7SStefano Zampini PetscErrorCode ierr; 16341f4df5f7SStefano Zampini Vec local,global; 16351f4df5f7SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 16361f4df5f7SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 16375c5e10d6SStefano Zampini PetscBool monolithic = PETSC_FALSE; 16381f4df5f7SStefano Zampini 16391f4df5f7SStefano Zampini PetscFunctionBegin; 16405c5e10d6SStefano Zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)pc),((PetscObject)pc)->prefix,"BDDC topology options","PC");CHKERRQ(ierr); 16415c5e10d6SStefano Zampini ierr = PetscOptionsBool("-pc_bddc_monolithic","Discard any information on dofs splitting",NULL,monolithic,&monolithic,NULL);CHKERRQ(ierr); 16425c5e10d6SStefano Zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 16431f4df5f7SStefano Zampini /* need to convert from global to local topology information and remove references to information in global ordering */ 164421ef3d20SStefano Zampini ierr = MatCreateVecs(pc->pmat,&global,NULL);CHKERRQ(ierr); 16451f4df5f7SStefano Zampini ierr = MatCreateVecs(matis->A,&local,NULL);CHKERRQ(ierr); 16466a8fc67bSStefano Zampini if (monolithic) { /* just get block size to properly compute vertices */ 16476a8fc67bSStefano Zampini if (pcbddc->vertex_size == 1) { 16486a8fc67bSStefano Zampini ierr = MatGetBlockSize(pc->pmat,&pcbddc->vertex_size);CHKERRQ(ierr); 16496a8fc67bSStefano Zampini } 16506a8fc67bSStefano Zampini goto boundary; 16516a8fc67bSStefano Zampini } 16525c5e10d6SStefano Zampini 16531f4df5f7SStefano Zampini if (pcbddc->user_provided_isfordofs) { 16541f4df5f7SStefano Zampini if (pcbddc->n_ISForDofs) { 16551f4df5f7SStefano Zampini PetscInt i; 16561f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofs,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16571f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofs;i++) { 16581f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->ISForDofs[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 16591f4df5f7SStefano Zampini ierr = ISDestroy(&pcbddc->ISForDofs[i]);CHKERRQ(ierr); 16601f4df5f7SStefano Zampini } 16611f4df5f7SStefano Zampini pcbddc->n_ISForDofsLocal = pcbddc->n_ISForDofs; 16621f4df5f7SStefano Zampini pcbddc->n_ISForDofs = 0; 16631f4df5f7SStefano Zampini ierr = PetscFree(pcbddc->ISForDofs);CHKERRQ(ierr); 16641f4df5f7SStefano Zampini } 16651f4df5f7SStefano Zampini } else { 166621ef3d20SStefano Zampini if (!pcbddc->n_ISForDofsLocal) { /* field split not present */ 166721ef3d20SStefano Zampini DM dm; 166821ef3d20SStefano Zampini 166921ef3d20SStefano Zampini ierr = PCGetDM(pc, &dm);CHKERRQ(ierr); 167021ef3d20SStefano Zampini if (!dm) { 167121ef3d20SStefano Zampini ierr = MatGetDM(pc->pmat, &dm);CHKERRQ(ierr); 167221ef3d20SStefano Zampini } 167321ef3d20SStefano Zampini if (dm) { 167421ef3d20SStefano Zampini IS *fields; 167521ef3d20SStefano Zampini PetscInt nf,i; 167621ef3d20SStefano Zampini ierr = DMCreateFieldDecomposition(dm,&nf,NULL,&fields,NULL);CHKERRQ(ierr); 167721ef3d20SStefano Zampini ierr = PetscMalloc1(nf,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 167821ef3d20SStefano Zampini for (i=0;i<nf;i++) { 167921ef3d20SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,fields[i],&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 168021ef3d20SStefano Zampini ierr = ISDestroy(&fields[i]);CHKERRQ(ierr); 168121ef3d20SStefano Zampini } 168221ef3d20SStefano Zampini ierr = PetscFree(fields);CHKERRQ(ierr); 168321ef3d20SStefano Zampini pcbddc->n_ISForDofsLocal = nf; 168421ef3d20SStefano Zampini } else { /* See if MATIS has fields attached by the conversion from MatNest */ 168521ef3d20SStefano Zampini PetscContainer c; 168621ef3d20SStefano Zampini 168721ef3d20SStefano Zampini ierr = PetscObjectQuery((PetscObject)pc->pmat,"_convert_nest_lfields",(PetscObject*)&c);CHKERRQ(ierr); 168821ef3d20SStefano Zampini if (c) { 168921ef3d20SStefano Zampini MatISLocalFields lf; 169021ef3d20SStefano Zampini ierr = PetscContainerGetPointer(c,(void**)&lf);CHKERRQ(ierr); 169121ef3d20SStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,lf->nr,lf->rf);CHKERRQ(ierr); 169221ef3d20SStefano Zampini } else { /* fallback, create the default fields if bs > 1 */ 16931f4df5f7SStefano Zampini PetscInt i, n = matis->A->rmap->n; 1694986cdee1SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&i);CHKERRQ(ierr); 169521ef3d20SStefano Zampini if (i > 1) { 1696986cdee1SStefano Zampini pcbddc->n_ISForDofsLocal = i; 16971f4df5f7SStefano Zampini ierr = PetscMalloc1(pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal);CHKERRQ(ierr); 16981f4df5f7SStefano Zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 16991f4df5f7SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),n/pcbddc->n_ISForDofsLocal,i,pcbddc->n_ISForDofsLocal,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 17001f4df5f7SStefano Zampini } 17011f4df5f7SStefano Zampini } 170221ef3d20SStefano Zampini } 170321ef3d20SStefano Zampini } 17047a0e7b2cSstefano_zampini } else { 17057a0e7b2cSstefano_zampini PetscInt i; 17067a0e7b2cSstefano_zampini for (i=0;i<pcbddc->n_ISForDofsLocal;i++) { 17077a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->ISForDofsLocal[i]);CHKERRQ(ierr); 17087a0e7b2cSstefano_zampini } 17091f4df5f7SStefano Zampini } 1710986cdee1SStefano Zampini } 17111f4df5f7SStefano Zampini 17125c5e10d6SStefano Zampini boundary: 17131f4df5f7SStefano Zampini if (!pcbddc->DirichletBoundariesLocal && pcbddc->DirichletBoundaries) { 17141f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->DirichletBoundaries,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 17157a0e7b2cSstefano_zampini } else if (pcbddc->DirichletBoundariesLocal) { 17167a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LAND,&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 17171f4df5f7SStefano Zampini } 17181f4df5f7SStefano Zampini if (!pcbddc->NeumannBoundariesLocal && pcbddc->NeumannBoundaries) { 17191f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->NeumannBoundaries,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 17207a0e7b2cSstefano_zampini } else if (pcbddc->NeumannBoundariesLocal) { 17217a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 17221f4df5f7SStefano Zampini } 17231f4df5f7SStefano Zampini if (!pcbddc->user_primal_vertices_local && pcbddc->user_primal_vertices) { 17241f4df5f7SStefano Zampini ierr = PCBDDCGlobalToLocal(matis->rctx,global,local,pcbddc->user_primal_vertices,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 17251f4df5f7SStefano Zampini } 17261f4df5f7SStefano Zampini ierr = VecDestroy(&global);CHKERRQ(ierr); 17271f4df5f7SStefano Zampini ierr = VecDestroy(&local);CHKERRQ(ierr); 17287620a527SStefano Zampini /* detect local disconnected subdomains if requested (use matis->A) */ 17297620a527SStefano Zampini if (pcbddc->detect_disconnected) { 17307620a527SStefano Zampini IS primalv = NULL; 17317620a527SStefano Zampini PetscInt i; 17327a0e7b2cSstefano_zampini 17337620a527SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 17347620a527SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 17357620a527SStefano Zampini } 17367620a527SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 17377620a527SStefano Zampini ierr = PCBDDCDetectDisconnectedComponents(pc,&pcbddc->n_local_subs,&pcbddc->local_subs,&primalv);CHKERRQ(ierr); 17387620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,primalv);CHKERRQ(ierr); 17397620a527SStefano Zampini ierr = ISDestroy(&primalv);CHKERRQ(ierr); 17407620a527SStefano Zampini } 17417620a527SStefano Zampini /* early stage corner detection */ 17427620a527SStefano Zampini { 17437620a527SStefano Zampini DM dm; 17447620a527SStefano Zampini 17457620a527SStefano Zampini ierr = MatGetDM(pc->pmat,&dm);CHKERRQ(ierr); 17467620a527SStefano Zampini if (dm) { 17477620a527SStefano Zampini PetscBool isda; 17487620a527SStefano Zampini 17497620a527SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)dm,DMDA,&isda);CHKERRQ(ierr); 17507620a527SStefano Zampini if (isda) { 17517620a527SStefano Zampini ISLocalToGlobalMapping l2l; 17527620a527SStefano Zampini IS corners; 17537620a527SStefano Zampini Mat lA; 17547620a527SStefano Zampini 1755d4a6ed37SStefano Zampini ierr = DMDAGetSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17567620a527SStefano Zampini ierr = MatISGetLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17577620a527SStefano Zampini ierr = MatGetLocalToGlobalMapping(lA,&l2l,NULL);CHKERRQ(ierr); 17587620a527SStefano Zampini ierr = MatISRestoreLocalMat(pc->pmat,&lA);CHKERRQ(ierr); 17597620a527SStefano Zampini if (l2l) { 17607620a527SStefano Zampini const PetscInt *idx; 17617620a527SStefano Zampini PetscInt bs,*idxout,n; 17627620a527SStefano Zampini 17637620a527SStefano Zampini ierr = ISLocalToGlobalMappingGetBlockSize(l2l,&bs);CHKERRQ(ierr); 17647620a527SStefano Zampini ierr = ISGetLocalSize(corners,&n);CHKERRQ(ierr); 17657620a527SStefano Zampini ierr = ISGetIndices(corners,&idx);CHKERRQ(ierr); 17667620a527SStefano Zampini ierr = PetscMalloc1(n,&idxout);CHKERRQ(ierr); 17677620a527SStefano Zampini ierr = ISLocalToGlobalMappingApplyBlock(l2l,n,idx,idxout);CHKERRQ(ierr); 17687620a527SStefano Zampini ierr = ISRestoreIndices(corners,&idx);CHKERRQ(ierr); 1769d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17707620a527SStefano Zampini ierr = ISCreateBlock(PetscObjectComm((PetscObject)pc),bs,n,idxout,PETSC_OWN_POINTER,&corners);CHKERRQ(ierr); 17717620a527SStefano Zampini ierr = PCBDDCAddPrimalVerticesLocalIS(pc,corners);CHKERRQ(ierr); 17727620a527SStefano Zampini ierr = ISDestroy(&corners);CHKERRQ(ierr); 17737620a527SStefano Zampini } else { /* not from DMDA */ 1774d4a6ed37SStefano Zampini ierr = DMDARestoreSubdomainCornersIS(dm,&corners);CHKERRQ(ierr); 17757620a527SStefano Zampini } 17767620a527SStefano Zampini } 17777620a527SStefano Zampini } 17787620a527SStefano 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 */ 284827b6a85dSStefano Zampini ierr = MPI_Allreduce(&have_null,&pcbddc->benign_have_null,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 2849339f8db1SStefano Zampini *zerodiaglocal = zerodiag; 2850339f8db1SStefano Zampini PetscFunctionReturn(0); 2851339f8db1SStefano Zampini } 2852339f8db1SStefano Zampini 2853015636ebSStefano Zampini PetscErrorCode PCBDDCBenignGetOrSetP0(PC pc, Vec v, PetscBool get) 2854efc2fbd9SStefano Zampini { 2855efc2fbd9SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2856de9d7bd0SStefano Zampini PetscScalar *array; 2857efc2fbd9SStefano Zampini PetscErrorCode ierr; 2858efc2fbd9SStefano Zampini 2859efc2fbd9SStefano Zampini PetscFunctionBegin; 2860efc2fbd9SStefano Zampini if (!pcbddc->benign_sf) { 2861efc2fbd9SStefano Zampini ierr = PetscSFCreate(PetscObjectComm((PetscObject)pc),&pcbddc->benign_sf);CHKERRQ(ierr); 28624f1b2e48SStefano Zampini ierr = PetscSFSetGraphLayout(pcbddc->benign_sf,pc->pmat->rmap,pcbddc->benign_n,NULL,PETSC_OWN_POINTER,pcbddc->benign_p0_gidx);CHKERRQ(ierr); 2863efc2fbd9SStefano Zampini } 2864de9d7bd0SStefano Zampini if (get) { 2865efc2fbd9SStefano Zampini ierr = VecGetArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 28664f1b2e48SStefano Zampini ierr = PetscSFBcastBegin(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 28674f1b2e48SStefano Zampini ierr = PetscSFBcastEnd(pcbddc->benign_sf,MPIU_SCALAR,array,pcbddc->benign_p0);CHKERRQ(ierr); 2868efc2fbd9SStefano Zampini ierr = VecRestoreArrayRead(v,(const PetscScalar**)&array);CHKERRQ(ierr); 2869de9d7bd0SStefano Zampini } else { 2870de9d7bd0SStefano Zampini ierr = VecGetArray(v,&array);CHKERRQ(ierr); 2871de9d7bd0SStefano Zampini ierr = PetscSFReduceBegin(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2872de9d7bd0SStefano Zampini ierr = PetscSFReduceEnd(pcbddc->benign_sf,MPIU_SCALAR,pcbddc->benign_p0,array,MPIU_REPLACE);CHKERRQ(ierr); 2873de9d7bd0SStefano Zampini ierr = VecRestoreArray(v,&array);CHKERRQ(ierr); 2874efc2fbd9SStefano Zampini } 2875efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2876efc2fbd9SStefano Zampini } 2877efc2fbd9SStefano Zampini 2878c263805aSStefano Zampini PetscErrorCode PCBDDCBenignPopOrPushB0(PC pc, PetscBool pop) 2879c263805aSStefano Zampini { 2880c263805aSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 2881c263805aSStefano Zampini PetscErrorCode ierr; 2882c263805aSStefano Zampini 2883c263805aSStefano Zampini PetscFunctionBegin; 2884c263805aSStefano Zampini /* TODO: add error checking 2885c263805aSStefano Zampini - avoid nested pop (or push) calls. 2886c263805aSStefano Zampini - cannot push before pop. 28871c604dc7SStefano Zampini - cannot call this if pcbddc->local_mat is NULL 2888c263805aSStefano Zampini */ 28894f1b2e48SStefano Zampini if (!pcbddc->benign_n) { 2890efc2fbd9SStefano Zampini PetscFunctionReturn(0); 2891efc2fbd9SStefano Zampini } 2892c263805aSStefano Zampini if (pop) { 2893a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 28944f1b2e48SStefano Zampini IS is_p0; 28954f1b2e48SStefano Zampini MatReuse reuse; 2896c263805aSStefano Zampini 2897c263805aSStefano Zampini /* extract B_0 */ 28984f1b2e48SStefano Zampini reuse = MAT_INITIAL_MATRIX; 28994f1b2e48SStefano Zampini if (pcbddc->benign_B0) { 29004f1b2e48SStefano Zampini reuse = MAT_REUSE_MATRIX; 29014f1b2e48SStefano Zampini } 29024f1b2e48SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->benign_n,pcbddc->benign_p0_lidx,PETSC_COPY_VALUES,&is_p0);CHKERRQ(ierr); 29037dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_p0,NULL,reuse,&pcbddc->benign_B0);CHKERRQ(ierr); 2904c263805aSStefano Zampini /* remove rows and cols from local problem */ 2905c263805aSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_KEEP_NONZERO_PATTERN,PETSC_TRUE);CHKERRQ(ierr); 290697d764eeSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 29074f1b2e48SStefano Zampini ierr = MatZeroRowsColumnsIS(pcbddc->local_mat,is_p0,1.0,NULL,NULL);CHKERRQ(ierr); 29084f1b2e48SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 2909a3df083aSStefano Zampini } else { 2910a3df083aSStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 2911a3df083aSStefano Zampini PetscScalar *vals; 2912a3df083aSStefano Zampini PetscInt i,n,*idxs_ins; 2913a3df083aSStefano Zampini 2914a3df083aSStefano Zampini ierr = VecGetLocalSize(matis->y,&n);CHKERRQ(ierr); 2915a3df083aSStefano Zampini ierr = PetscMalloc2(n,&idxs_ins,n,&vals);CHKERRQ(ierr); 2916a3df083aSStefano Zampini if (!pcbddc->benign_B0) { 29170b5adadeSStefano Zampini PetscInt *nnz; 2918a3df083aSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pcbddc->local_mat),&pcbddc->benign_B0);CHKERRQ(ierr); 2919a3df083aSStefano Zampini ierr = MatSetType(pcbddc->benign_B0,MATAIJ);CHKERRQ(ierr); 2920a3df083aSStefano Zampini ierr = MatSetSizes(pcbddc->benign_B0,pcbddc->benign_n,n,PETSC_DECIDE,PETSC_DECIDE);CHKERRQ(ierr); 2921331e053bSStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&nnz);CHKERRQ(ierr); 2922331e053bSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2923331e053bSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nnz[i]);CHKERRQ(ierr); 2924331e053bSStefano Zampini nnz[i] = n - nnz[i]; 2925331e053bSStefano Zampini } 2926331e053bSStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->benign_B0,0,nnz);CHKERRQ(ierr); 2927331e053bSStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 2928331e053bSStefano Zampini } 2929a3df083aSStefano Zampini 2930a3df083aSStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 2931a3df083aSStefano Zampini PetscScalar *array; 2932a3df083aSStefano Zampini PetscInt *idxs,j,nz,cum; 2933a3df083aSStefano Zampini 2934a3df083aSStefano Zampini ierr = VecSet(matis->x,0.);CHKERRQ(ierr); 2935a3df083aSStefano Zampini ierr = ISGetLocalSize(pcbddc->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 2936a3df083aSStefano Zampini ierr = ISGetIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2937a3df083aSStefano Zampini for (j=0;j<nz;j++) vals[j] = 1.; 2938a3df083aSStefano Zampini ierr = VecSetValues(matis->x,nz,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 2939a3df083aSStefano Zampini ierr = VecAssemblyBegin(matis->x);CHKERRQ(ierr); 2940a3df083aSStefano Zampini ierr = VecAssemblyEnd(matis->x);CHKERRQ(ierr); 2941a3df083aSStefano Zampini ierr = VecSet(matis->y,0.);CHKERRQ(ierr); 2942a3df083aSStefano Zampini ierr = MatMult(matis->A,matis->x,matis->y);CHKERRQ(ierr); 2943a3df083aSStefano Zampini ierr = VecGetArray(matis->y,&array);CHKERRQ(ierr); 2944a3df083aSStefano Zampini cum = 0; 2945a3df083aSStefano Zampini for (j=0;j<n;j++) { 294622db5ddcSStefano Zampini if (PetscUnlikely(PetscAbsScalar(array[j]) > PETSC_SMALL)) { 2947a3df083aSStefano Zampini vals[cum] = array[j]; 2948a3df083aSStefano Zampini idxs_ins[cum] = j; 2949a3df083aSStefano Zampini cum++; 2950a3df083aSStefano Zampini } 2951a3df083aSStefano Zampini } 2952a3df083aSStefano Zampini ierr = MatSetValues(pcbddc->benign_B0,1,&i,cum,idxs_ins,vals,INSERT_VALUES);CHKERRQ(ierr); 2953a3df083aSStefano Zampini ierr = VecRestoreArray(matis->y,&array);CHKERRQ(ierr); 2954a3df083aSStefano Zampini ierr = ISRestoreIndices(pcbddc->benign_zerodiag_subs[i],(const PetscInt**)&idxs);CHKERRQ(ierr); 2955a3df083aSStefano Zampini } 2956a3df083aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2957a3df083aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->benign_B0,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2958a3df083aSStefano Zampini ierr = PetscFree2(idxs_ins,vals);CHKERRQ(ierr); 2959a3df083aSStefano Zampini } 2960c263805aSStefano Zampini } else { /* push */ 2961a3df083aSStefano Zampini if (pcbddc->benign_change_explicit) { 29624f1b2e48SStefano Zampini PetscInt i; 29634f1b2e48SStefano Zampini 29644f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 29654f1b2e48SStefano Zampini PetscScalar *B0_vals; 29664f1b2e48SStefano Zampini PetscInt *B0_cols,B0_ncol; 29674f1b2e48SStefano Zampini 29684f1b2e48SStefano Zampini ierr = MatGetRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 29694f1b2e48SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,1,pcbddc->benign_p0_lidx+i,B0_ncol,B0_cols,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 29707b034428SStefano Zampini ierr = MatSetValues(pcbddc->local_mat,B0_ncol,B0_cols,1,pcbddc->benign_p0_lidx+i,B0_vals,INSERT_VALUES);CHKERRQ(ierr); 29714f1b2e48SStefano Zampini ierr = MatSetValue(pcbddc->local_mat,pcbddc->benign_p0_lidx[i],pcbddc->benign_p0_lidx[i],0.0,INSERT_VALUES);CHKERRQ(ierr); 29724f1b2e48SStefano Zampini ierr = MatRestoreRow(pcbddc->benign_B0,i,&B0_ncol,(const PetscInt**)&B0_cols,(const PetscScalar**)&B0_vals);CHKERRQ(ierr); 29734f1b2e48SStefano Zampini } 2974c263805aSStefano Zampini ierr = MatAssemblyBegin(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2975c263805aSStefano Zampini ierr = MatAssemblyEnd(pcbddc->local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 2976a3df083aSStefano Zampini } else { 2977a3df083aSStefano Zampini SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Cannot push B0!\n"); 2978a3df083aSStefano Zampini } 2979c263805aSStefano Zampini } 2980c263805aSStefano Zampini PetscFunctionReturn(0); 2981c263805aSStefano Zampini } 2982c263805aSStefano Zampini 298308122e43SStefano Zampini PetscErrorCode PCBDDCAdaptiveSelection(PC pc) 2984b1b3d7a2SStefano Zampini { 2985b1b3d7a2SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 298608122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 298708122e43SStefano Zampini PetscBLASInt B_dummyint,B_neigs,B_ierr,B_lwork; 298808122e43SStefano Zampini PetscBLASInt *B_iwork,*B_ifail; 298908122e43SStefano Zampini PetscScalar *work,lwork; 299008122e43SStefano Zampini PetscScalar *St,*S,*eigv; 299108122e43SStefano Zampini PetscScalar *Sarray,*Starray; 2992bd2a564bSStefano Zampini PetscReal *eigs,thresh,lthresh,uthresh; 29931b968477SStefano Zampini PetscInt i,nmax,nmin,nv,cum,mss,cum2,cumarray,maxneigs; 2994f6f667cfSStefano Zampini PetscBool allocated_S_St; 299508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 299608122e43SStefano Zampini PetscReal *rwork; 299708122e43SStefano Zampini #endif 2998b1b3d7a2SStefano Zampini PetscErrorCode ierr; 2999b1b3d7a2SStefano Zampini 3000b1b3d7a2SStefano Zampini PetscFunctionBegin; 3001b334f244SStefano Zampini if (!sub_schurs) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Adaptive selection of constraints requires SubSchurs data"); 3002af25d912SStefano Zampini if (!sub_schurs->schur_explicit) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Adaptive selection of constraints requires MUMPS and/or MKL_CPARDISO"); 3003bd2a564bSStefano 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); 300406a4e24aSStefano Zampini 3005fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3006fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3007fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 3008fd14bc51SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check adaptive selection of constraints\n");CHKERRQ(ierr); 30091575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 3010fd14bc51SStefano Zampini } 3011fd14bc51SStefano Zampini 3012e496cd5dSStefano Zampini if (pcbddc->dbg_flag) { 3013e496cd5dSStefano 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); 3014e496cd5dSStefano Zampini } 3015e496cd5dSStefano Zampini 301608122e43SStefano Zampini /* max size of subsets */ 301708122e43SStefano Zampini mss = 0; 301808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 301908122e43SStefano Zampini PetscInt subset_size; 3020862806e4SStefano Zampini 302108122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 302208122e43SStefano Zampini mss = PetscMax(mss,subset_size); 302308122e43SStefano Zampini } 302408122e43SStefano Zampini 302508122e43SStefano Zampini /* min/max and threshold */ 302608122e43SStefano Zampini nmax = pcbddc->adaptive_nmax > 0 ? pcbddc->adaptive_nmax : mss; 3027f6f667cfSStefano Zampini nmin = pcbddc->adaptive_nmin > 0 ? pcbddc->adaptive_nmin : 0; 302808122e43SStefano Zampini nmax = PetscMax(nmin,nmax); 3029f6f667cfSStefano Zampini allocated_S_St = PETSC_FALSE; 3030bd2a564bSStefano Zampini if (nmin || !sub_schurs->is_posdef) { /* XXX */ 3031f6f667cfSStefano Zampini allocated_S_St = PETSC_TRUE; 3032f6f667cfSStefano Zampini } 303308122e43SStefano Zampini 303408122e43SStefano Zampini /* allocate lapack workspace */ 303508122e43SStefano Zampini cum = cum2 = 0; 303608122e43SStefano Zampini maxneigs = 0; 303708122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 303808122e43SStefano Zampini PetscInt n,subset_size; 3039f6f667cfSStefano Zampini 304008122e43SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 304108122e43SStefano Zampini n = PetscMin(subset_size,nmax); 30429162d606SStefano Zampini cum += subset_size; 30439162d606SStefano Zampini cum2 += subset_size*n; 304408122e43SStefano Zampini maxneigs = PetscMax(maxneigs,n); 304508122e43SStefano Zampini } 304608122e43SStefano Zampini if (mss) { 3047bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 304808122e43SStefano Zampini PetscBLASInt B_itype = 1; 304908122e43SStefano Zampini PetscBLASInt B_N = mss; 30504c6709b3SStefano Zampini PetscReal zero = 0.0; 30514c6709b3SStefano Zampini PetscReal eps = 0.0; /* dlamch? */ 305208122e43SStefano Zampini 305308122e43SStefano Zampini B_lwork = -1; 305408122e43SStefano Zampini S = NULL; 305508122e43SStefano Zampini St = NULL; 3056a58a30b4SStefano Zampini eigs = NULL; 3057a58a30b4SStefano Zampini eigv = NULL; 3058a58a30b4SStefano Zampini B_iwork = NULL; 3059a58a30b4SStefano Zampini B_ifail = NULL; 3060d1710679SStefano Zampini #if defined(PETSC_USE_COMPLEX) 3061d1710679SStefano Zampini rwork = NULL; 3062d1710679SStefano Zampini #endif 30638bec7fa6SStefano Zampini thresh = 1.0; 306408122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 306508122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 306608122e43SStefano 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)); 306708122e43SStefano Zampini #else 306808122e43SStefano 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)); 306908122e43SStefano Zampini #endif 307008122e43SStefano Zampini if (B_ierr != 0) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYGVX Lapack routine %d",(int)B_ierr); 307108122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 3072bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 307308122e43SStefano Zampini } else { 307408122e43SStefano Zampini lwork = 0; 307508122e43SStefano Zampini } 307608122e43SStefano Zampini 307708122e43SStefano Zampini nv = 0; 3078d62866d3SStefano 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) */ 3079d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&nv);CHKERRQ(ierr); 308008122e43SStefano Zampini } 30814c6709b3SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lwork),&B_lwork);CHKERRQ(ierr); 3082f6f667cfSStefano Zampini if (allocated_S_St) { 3083f6f667cfSStefano Zampini ierr = PetscMalloc2(mss*mss,&S,mss*mss,&St);CHKERRQ(ierr); 3084f6f667cfSStefano Zampini } 3085f6f667cfSStefano Zampini ierr = PetscMalloc5(mss*mss,&eigv,mss,&eigs,B_lwork,&work,5*mss,&B_iwork,mss,&B_ifail);CHKERRQ(ierr); 308608122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 308708122e43SStefano Zampini ierr = PetscMalloc1(7*mss,&rwork);CHKERRQ(ierr); 308808122e43SStefano Zampini #endif 30899162d606SStefano Zampini ierr = PetscMalloc5(nv+sub_schurs->n_subs,&pcbddc->adaptive_constraints_n, 30909162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_idxs_ptr, 30919162d606SStefano Zampini nv+sub_schurs->n_subs+1,&pcbddc->adaptive_constraints_data_ptr, 309208122e43SStefano Zampini nv+cum,&pcbddc->adaptive_constraints_idxs, 30939162d606SStefano Zampini nv+cum2,&pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 309408122e43SStefano Zampini ierr = PetscMemzero(pcbddc->adaptive_constraints_n,(nv+sub_schurs->n_subs)*sizeof(PetscInt));CHKERRQ(ierr); 309508122e43SStefano Zampini 309608122e43SStefano Zampini maxneigs = 0; 309772b8c272SStefano Zampini cum = cumarray = 0; 30989162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[0] = 0; 30999162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[0] = 0; 3100d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 310108122e43SStefano Zampini const PetscInt *idxs; 310208122e43SStefano Zampini 3103d62866d3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 310408122e43SStefano Zampini for (cum=0;cum<nv;cum++) { 310508122e43SStefano Zampini pcbddc->adaptive_constraints_n[cum] = 1; 310608122e43SStefano Zampini pcbddc->adaptive_constraints_idxs[cum] = idxs[cum]; 310708122e43SStefano Zampini pcbddc->adaptive_constraints_data[cum] = 1.0; 31089162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum]+1; 31099162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum]+1; 311008122e43SStefano Zampini } 3111d62866d3SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_vertices,&idxs);CHKERRQ(ierr); 311208122e43SStefano Zampini } 311308122e43SStefano Zampini 311408122e43SStefano Zampini if (mss) { /* multilevel */ 311508122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 311608122e43SStefano Zampini ierr = MatSeqAIJGetArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 311708122e43SStefano Zampini } 311808122e43SStefano Zampini 3119bd2a564bSStefano Zampini lthresh = pcbddc->adaptive_threshold[0]; 3120bd2a564bSStefano Zampini uthresh = pcbddc->adaptive_threshold[1]; 312108122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 312208122e43SStefano Zampini const PetscInt *idxs; 31239d54b7f4SStefano Zampini PetscReal upper,lower; 3124862806e4SStefano Zampini PetscInt j,subset_size,eigs_start = 0; 312508122e43SStefano Zampini PetscBLASInt B_N; 3126aff50787SStefano Zampini PetscBool same_data = PETSC_FALSE; 3127bd2a564bSStefano Zampini PetscBool scal = PETSC_FALSE; 312808122e43SStefano Zampini 31299d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 31309d54b7f4SStefano Zampini upper = PETSC_MAX_REAL; 3131bd2a564bSStefano Zampini lower = uthresh; 31329d54b7f4SStefano Zampini } else { 3133bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented without deluxe scaling"); 3134bd2a564bSStefano Zampini upper = 1./uthresh; 31359d54b7f4SStefano Zampini lower = 0.; 31369d54b7f4SStefano Zampini } 3137862806e4SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_subs[i],&subset_size);CHKERRQ(ierr); 3138ffd830a3SStefano Zampini ierr = ISGetIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 3139f6f667cfSStefano Zampini ierr = PetscBLASIntCast(subset_size,&B_N);CHKERRQ(ierr); 3140bd2a564bSStefano Zampini /* this is experimental: we assume the dofs have been properly grouped to have 3141bd2a564bSStefano Zampini the diagonal blocks Schur complements either positive or negative definite (true for Stokes) */ 3142bd2a564bSStefano Zampini if (!sub_schurs->is_posdef) { 3143bd2a564bSStefano Zampini Mat T; 3144bd2a564bSStefano Zampini 3145bd2a564bSStefano Zampini for (j=0;j<subset_size;j++) { 3146bd2a564bSStefano Zampini if (PetscRealPart(*(Sarray+cumarray+j*(subset_size+1))) < 0.0) { 3147bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Sarray+cumarray,&T);CHKERRQ(ierr); 3148bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3149bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3150bd2a564bSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,subset_size,Starray+cumarray,&T);CHKERRQ(ierr); 3151bd2a564bSStefano Zampini ierr = MatScale(T,-1.0);CHKERRQ(ierr); 3152bd2a564bSStefano Zampini ierr = MatDestroy(&T);CHKERRQ(ierr); 3153bd2a564bSStefano Zampini if (sub_schurs->change_primal_sub) { 3154bd2a564bSStefano Zampini PetscInt nz,k; 3155bd2a564bSStefano Zampini const PetscInt *idxs; 3156bd2a564bSStefano Zampini 3157bd2a564bSStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nz);CHKERRQ(ierr); 3158bd2a564bSStefano Zampini ierr = ISGetIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3159bd2a564bSStefano Zampini for (k=0;k<nz;k++) { 3160bd2a564bSStefano Zampini *( Sarray + cumarray + idxs[k]*(subset_size+1)) *= -1.0; 3161bd2a564bSStefano Zampini *(Starray + cumarray + idxs[k]*(subset_size+1)) = 0.0; 3162bd2a564bSStefano Zampini } 3163bd2a564bSStefano Zampini ierr = ISRestoreIndices(sub_schurs->change_primal_sub[i],&idxs);CHKERRQ(ierr); 3164bd2a564bSStefano Zampini } 3165bd2a564bSStefano Zampini scal = PETSC_TRUE; 3166bd2a564bSStefano Zampini break; 3167bd2a564bSStefano Zampini } 3168bd2a564bSStefano Zampini } 3169bd2a564bSStefano Zampini } 3170bd2a564bSStefano Zampini 3171f6f667cfSStefano Zampini if (allocated_S_St) { /* S and S_t should be copied since we could need them later */ 3172bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 3173aff50787SStefano Zampini PetscInt j,k; 3174aff50787SStefano Zampini if (sub_schurs->n_subs == 1) { /* zeroing memory to use PetscMemcmp later */ 3175aff50787SStefano Zampini ierr = PetscMemzero(S,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 3176aff50787SStefano Zampini ierr = PetscMemzero(St,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 317708122e43SStefano Zampini } 317808122e43SStefano Zampini for (j=0;j<subset_size;j++) { 3179aff50787SStefano Zampini for (k=j;k<subset_size;k++) { 3180aff50787SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 3181aff50787SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 3182aff50787SStefano Zampini } 318308122e43SStefano Zampini } 318408122e43SStefano Zampini } else { 318508122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 318608122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 318708122e43SStefano Zampini } 31888bec7fa6SStefano Zampini } else { 3189f6f667cfSStefano Zampini S = Sarray + cumarray; 3190f6f667cfSStefano Zampini St = Starray + cumarray; 31918bec7fa6SStefano Zampini } 3192aff50787SStefano Zampini /* see if we can save some work */ 3193b7ab4a40SStefano Zampini if (sub_schurs->n_subs == 1 && pcbddc->use_deluxe_scaling) { 3194aff50787SStefano Zampini ierr = PetscMemcmp(S,St,subset_size*subset_size*sizeof(PetscScalar),&same_data);CHKERRQ(ierr); 3195aff50787SStefano Zampini } 3196aff50787SStefano Zampini 3197b7ab4a40SStefano Zampini if (same_data && !sub_schurs->change) { /* there's no need of constraints here */ 3198aff50787SStefano Zampini B_neigs = 0; 3199aff50787SStefano Zampini } else { 3200bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 320108122e43SStefano Zampini PetscBLASInt B_itype = 1; 3202f6f667cfSStefano Zampini PetscBLASInt B_IL, B_IU; 32034c6709b3SStefano Zampini PetscReal eps = -1.0; /* dlamch? */ 32049552c7c7SStefano Zampini PetscInt nmin_s; 3205bd2a564bSStefano Zampini PetscBool compute_range; 3206bd2a564bSStefano Zampini 3207bd2a564bSStefano Zampini compute_range = (PetscBool)!same_data; 3208bd2a564bSStefano Zampini if (nmin >= subset_size) compute_range = PETSC_FALSE; 320908122e43SStefano Zampini 3210fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3211bd2a564bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Computing for sub %d/%d size %d count %d fid %d (range %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);CHKERRQ(ierr); 3212b7ab4a40SStefano Zampini } 3213b7ab4a40SStefano Zampini 321408122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 3215b7ab4a40SStefano Zampini if (compute_range) { 3216d16cbb6bSStefano Zampini 3217d16cbb6bSStefano Zampini /* ask for eigenvalues larger than thresh */ 3218bd2a564bSStefano Zampini if (sub_schurs->is_posdef) { 321908122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 32209d54b7f4SStefano 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)); 322108122e43SStefano Zampini #else 32229d54b7f4SStefano 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)); 322308122e43SStefano Zampini #endif 3224bd2a564bSStefano Zampini } else { /* no theory so far, but it works nicely */ 3225bd2a564bSStefano Zampini PetscInt recipe = 0; 3226bd2a564bSStefano Zampini PetscReal bb[2]; 3227bd2a564bSStefano Zampini 3228bd2a564bSStefano Zampini ierr = PetscOptionsGetInt(NULL,((PetscObject)pc)->prefix,"-pc_bddc_adaptive_recipe",&recipe,NULL);CHKERRQ(ierr); 3229bd2a564bSStefano Zampini switch (recipe) { 3230bd2a564bSStefano Zampini case 0: 3231bd2a564bSStefano Zampini if (scal) { bb[0] = PETSC_MIN_REAL; bb[1] = lthresh; } 3232bd2a564bSStefano Zampini else { bb[0] = uthresh; bb[1] = PETSC_MAX_REAL; } 3233bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3234bd2a564bSStefano 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)); 3235bd2a564bSStefano Zampini #else 3236bd2a564bSStefano 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)); 3237bd2a564bSStefano Zampini #endif 3238bd2a564bSStefano Zampini break; 3239bd2a564bSStefano Zampini case 1: 3240bd2a564bSStefano Zampini bb[0] = PETSC_MIN_REAL; bb[1] = lthresh*lthresh; 3241bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3242bd2a564bSStefano 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)); 3243bd2a564bSStefano Zampini #else 3244bd2a564bSStefano 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)); 3245bd2a564bSStefano Zampini #endif 3246bd2a564bSStefano Zampini if (!scal) { 3247bd2a564bSStefano Zampini PetscBLASInt B_neigs2; 3248bd2a564bSStefano Zampini 3249bd2a564bSStefano Zampini bb[0] = uthresh; bb[1] = PETSC_MAX_REAL; 3250bd2a564bSStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 3251bd2a564bSStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 3252bd2a564bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3253bd2a564bSStefano 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)); 3254bd2a564bSStefano Zampini #else 3255bd2a564bSStefano 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)); 3256bd2a564bSStefano Zampini #endif 3257bd2a564bSStefano Zampini B_neigs += B_neigs2; 3258bd2a564bSStefano Zampini } 3259bd2a564bSStefano Zampini break; 3260bd2a564bSStefano Zampini default: 3261bd2a564bSStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_SUP,"Unknown recipe %D",recipe); 3262bd2a564bSStefano Zampini break; 3263bd2a564bSStefano Zampini } 3264bd2a564bSStefano Zampini } 3265bd2a564bSStefano Zampini } else if (!same_data) { /* this is just to see all the eigenvalues */ 3266d16cbb6bSStefano Zampini B_IU = PetscMax(1,PetscMin(B_N,nmax)); 3267d16cbb6bSStefano Zampini B_IL = 1; 3268d16cbb6bSStefano Zampini #if defined(PETSC_USE_COMPLEX) 32699d54b7f4SStefano 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)); 3270d16cbb6bSStefano Zampini #else 32719d54b7f4SStefano 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)); 3272d16cbb6bSStefano Zampini #endif 3273b03ebc13SStefano Zampini } else { /* same_data is true, so just get the adaptive functional requested by the user */ 3274b7ab4a40SStefano Zampini PetscInt k; 3275b7ab4a40SStefano Zampini if (!sub_schurs->change_primal_sub) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 3276b7ab4a40SStefano Zampini ierr = ISGetLocalSize(sub_schurs->change_primal_sub[i],&nmax);CHKERRQ(ierr); 3277b7ab4a40SStefano Zampini ierr = PetscBLASIntCast(nmax,&B_neigs);CHKERRQ(ierr); 3278b7ab4a40SStefano Zampini nmin = nmax; 3279b7ab4a40SStefano Zampini ierr = PetscMemzero(eigv,subset_size*nmax*sizeof(PetscScalar));CHKERRQ(ierr); 3280b7ab4a40SStefano Zampini for (k=0;k<nmax;k++) { 3281b7ab4a40SStefano Zampini eigs[k] = 1./PETSC_SMALL; 3282b7ab4a40SStefano Zampini eigv[k*(subset_size+1)] = 1.0; 3283b7ab4a40SStefano Zampini } 3284d16cbb6bSStefano Zampini } 328508122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 328608122e43SStefano Zampini if (B_ierr) { 32876c4ed002SBarry 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); 32886c4ed002SBarry 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); 32896c4ed002SBarry 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); 329008122e43SStefano Zampini } 329108122e43SStefano Zampini 329208122e43SStefano Zampini if (B_neigs > nmax) { 3293fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3294bd2a564bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," found %d eigs, more than maximum required %d.\n",B_neigs,nmax);CHKERRQ(ierr); 3295fd14bc51SStefano Zampini } 3296bd2a564bSStefano Zampini if (pcbddc->use_deluxe_scaling) eigs_start = scal ? 0 : B_neigs-nmax; 329708122e43SStefano Zampini B_neigs = nmax; 329808122e43SStefano Zampini } 329908122e43SStefano Zampini 33009552c7c7SStefano Zampini nmin_s = PetscMin(nmin,B_N); 33019552c7c7SStefano Zampini if (B_neigs < nmin_s) { 330208122e43SStefano Zampini PetscBLASInt B_neigs2; 330308122e43SStefano Zampini 33049d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3305bd2a564bSStefano Zampini if (scal) { 3306bd2a564bSStefano Zampini B_IU = nmin_s; 3307bd2a564bSStefano Zampini B_IL = B_neigs + 1; 3308bd2a564bSStefano Zampini } else { 3309f6f667cfSStefano Zampini B_IL = B_N - nmin_s + 1; 33109d54b7f4SStefano Zampini B_IU = B_N - B_neigs; 3311bd2a564bSStefano Zampini } 33129d54b7f4SStefano Zampini } else { 33139d54b7f4SStefano Zampini B_IL = B_neigs + 1; 33149d54b7f4SStefano Zampini B_IU = nmin_s; 33159d54b7f4SStefano Zampini } 3316fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3317fd14bc51SStefano 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); 3318fd14bc51SStefano Zampini } 3319bd2a564bSStefano Zampini if (sub_schurs->is_symmetric) { 33201ae86dd6SStefano Zampini PetscInt j,k; 332108122e43SStefano Zampini for (j=0;j<subset_size;j++) { 33221ae86dd6SStefano Zampini for (k=j;k<subset_size;k++) { 33231ae86dd6SStefano Zampini S [j*subset_size+k] = Sarray [cumarray+j*subset_size+k]; 33241ae86dd6SStefano Zampini St[j*subset_size+k] = Starray[cumarray+j*subset_size+k]; 332508122e43SStefano Zampini } 332608122e43SStefano Zampini } 332708122e43SStefano Zampini } else { 332808122e43SStefano Zampini ierr = PetscMemcpy(S,Sarray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 332908122e43SStefano Zampini ierr = PetscMemcpy(St,Starray+cumarray,subset_size*subset_size*sizeof(PetscScalar));CHKERRQ(ierr); 333008122e43SStefano Zampini } 333108122e43SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 333208122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 33339d54b7f4SStefano 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)); 333408122e43SStefano Zampini #else 33359d54b7f4SStefano 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)); 333608122e43SStefano Zampini #endif 333708122e43SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 333808122e43SStefano Zampini B_neigs += B_neigs2; 333908122e43SStefano Zampini } 334008122e43SStefano Zampini if (B_ierr) { 33416c4ed002SBarry 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); 33426c4ed002SBarry 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); 33436c4ed002SBarry 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); 334408122e43SStefano Zampini } 3345fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3346ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Got %d eigs\n",B_neigs);CHKERRQ(ierr); 334708122e43SStefano Zampini for (j=0;j<B_neigs;j++) { 334808122e43SStefano Zampini if (eigs[j] == 0.0) { 3349ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," Inf\n");CHKERRQ(ierr); 335008122e43SStefano Zampini } else { 33519d54b7f4SStefano Zampini if (pcbddc->use_deluxe_scaling) { 3352ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",eigs[j+eigs_start]);CHKERRQ(ierr); 33539d54b7f4SStefano Zampini } else { 33549d54b7f4SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.6e\n",1./eigs[j+eigs_start]);CHKERRQ(ierr); 33559d54b7f4SStefano Zampini } 3356fd14bc51SStefano Zampini } 335708122e43SStefano Zampini } 335808122e43SStefano Zampini } 3359bd2a564bSStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented"); 3360aff50787SStefano Zampini } 33616c3e6151SStefano Zampini /* change the basis back to the original one */ 33626c3e6151SStefano Zampini if (sub_schurs->change) { 336372b8c272SStefano Zampini Mat change,phi,phit; 33646c3e6151SStefano Zampini 336503dfb2d7SStefano Zampini if (pcbddc->dbg_flag > 2) { 33666c3e6151SStefano Zampini PetscInt ii; 33676c3e6151SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 33686c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector (old basis) %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 33696c3e6151SStefano Zampini for (j=0;j<B_N;j++) { 3370684229deSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3371684229deSStefano Zampini PetscReal r = PetscRealPart(eigv[(ii+eigs_start)*subset_size+j]); 3372684229deSStefano Zampini PetscReal c = PetscImaginaryPart(eigv[(ii+eigs_start)*subset_size+j]); 3373684229deSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3374684229deSStefano Zampini #else 33756c3e6151SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e\n",eigv[(ii+eigs_start)*subset_size+j]);CHKERRQ(ierr); 3376684229deSStefano Zampini #endif 33776c3e6151SStefano Zampini } 33786c3e6151SStefano Zampini } 33796c3e6151SStefano Zampini } 338072b8c272SStefano Zampini ierr = KSPGetOperators(sub_schurs->change[i],&change,NULL);CHKERRQ(ierr); 33816c3e6151SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,subset_size,B_neigs,eigv+eigs_start*subset_size,&phit);CHKERRQ(ierr); 338272b8c272SStefano Zampini ierr = MatMatMult(change,phit,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&phi);CHKERRQ(ierr); 33836c3e6151SStefano Zampini ierr = MatCopy(phi,phit,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 33846c3e6151SStefano Zampini ierr = MatDestroy(&phit);CHKERRQ(ierr); 33856c3e6151SStefano Zampini ierr = MatDestroy(&phi);CHKERRQ(ierr); 33866c3e6151SStefano Zampini } 33878bec7fa6SStefano Zampini maxneigs = PetscMax(B_neigs,maxneigs); 33888bec7fa6SStefano Zampini pcbddc->adaptive_constraints_n[i+nv] = B_neigs; 33899162d606SStefano Zampini if (B_neigs) { 33909162d606SStefano 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); 3391fd14bc51SStefano Zampini 3392fd14bc51SStefano Zampini if (pcbddc->dbg_flag > 1) { 33939552c7c7SStefano Zampini PetscInt ii; 33949552c7c7SStefano Zampini for (ii=0;ii<B_neigs;ii++) { 3395ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," -> Eigenvector %d/%d (%d)\n",ii,B_neigs,B_N);CHKERRQ(ierr); 33969552c7c7SStefano Zampini for (j=0;j<B_N;j++) { 3397ac47001eSStefano Zampini #if defined(PETSC_USE_COMPLEX) 3398ac47001eSStefano Zampini PetscReal r = PetscRealPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3399ac47001eSStefano Zampini PetscReal c = PetscImaginaryPart(pcbddc->adaptive_constraints_data[ii*subset_size+j+pcbddc->adaptive_constraints_data_ptr[cum]]); 3400ac47001eSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer," %1.4e + %1.4e i\n",r,c);CHKERRQ(ierr); 3401ac47001eSStefano Zampini #else 3402ac47001eSStefano 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); 3403ac47001eSStefano Zampini #endif 34049552c7c7SStefano Zampini } 34059552c7c7SStefano Zampini } 3406fd14bc51SStefano Zampini } 34079162d606SStefano Zampini ierr = PetscMemcpy(pcbddc->adaptive_constraints_idxs+pcbddc->adaptive_constraints_idxs_ptr[cum],idxs,subset_size*sizeof(PetscInt));CHKERRQ(ierr); 34089162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr[cum+1] = pcbddc->adaptive_constraints_idxs_ptr[cum] + subset_size; 34099162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr[cum+1] = pcbddc->adaptive_constraints_data_ptr[cum] + subset_size*B_neigs; 34109162d606SStefano Zampini cum++; 341108122e43SStefano Zampini } 341208122e43SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_subs[i],&idxs);CHKERRQ(ierr); 341308122e43SStefano Zampini /* shift for next computation */ 341408122e43SStefano Zampini cumarray += subset_size*subset_size; 341508122e43SStefano Zampini } 3416fd14bc51SStefano Zampini if (pcbddc->dbg_flag) { 3417fd14bc51SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 3418fd14bc51SStefano Zampini } 341908122e43SStefano Zampini 342008122e43SStefano Zampini if (mss) { 342108122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_inv_all,&Sarray);CHKERRQ(ierr); 342208122e43SStefano Zampini ierr = MatSeqAIJRestoreArray(sub_schurs->sum_S_Ej_tilda_all,&Starray);CHKERRQ(ierr); 3423f6f667cfSStefano Zampini /* destroy matrices (junk) */ 3424f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_inv_all);CHKERRQ(ierr); 3425f6f667cfSStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_tilda_all);CHKERRQ(ierr); 342608122e43SStefano Zampini } 3427f6f667cfSStefano Zampini if (allocated_S_St) { 3428f6f667cfSStefano Zampini ierr = PetscFree2(S,St);CHKERRQ(ierr); 3429f6f667cfSStefano Zampini } 3430f6f667cfSStefano Zampini ierr = PetscFree5(eigv,eigs,work,B_iwork,B_ifail);CHKERRQ(ierr); 343108122e43SStefano Zampini #if defined(PETSC_USE_COMPLEX) 343208122e43SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 343308122e43SStefano Zampini #endif 343408122e43SStefano Zampini if (pcbddc->dbg_flag) { 34351b968477SStefano Zampini PetscInt maxneigs_r; 3436b2566f29SBarry Smith ierr = MPIU_Allreduce(&maxneigs,&maxneigs_r,1,MPIU_INT,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 34379b28b941SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of constraints per cc %d\n",maxneigs_r);CHKERRQ(ierr); 343808122e43SStefano Zampini } 343908122e43SStefano Zampini PetscFunctionReturn(0); 344008122e43SStefano Zampini } 3441b1b3d7a2SStefano Zampini 3442c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpSolvers(PC pc) 3443c8587f34SStefano Zampini { 34448629588bSStefano Zampini PetscScalar *coarse_submat_vals; 3445c8587f34SStefano Zampini PetscErrorCode ierr; 3446c8587f34SStefano Zampini 3447c8587f34SStefano Zampini PetscFunctionBegin; 3448f4ddd8eeSStefano Zampini /* Setup local scatters R_to_B and (optionally) R_to_D */ 34495e8657edSStefano Zampini /* PCBDDCSetUpLocalWorkVectors should be called first! */ 3450c8587f34SStefano Zampini ierr = PCBDDCSetUpLocalScatters(pc);CHKERRQ(ierr); 3451c8587f34SStefano Zampini 3452684f6988SStefano Zampini /* Setup local neumann solver ksp_R */ 34530fccc4e9SStefano Zampini /* PCBDDCSetUpLocalScatters should be called first! */ 3454684f6988SStefano Zampini ierr = PCBDDCSetUpLocalSolvers(pc,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 3455c8587f34SStefano Zampini 34568629588bSStefano Zampini /* 34578629588bSStefano Zampini Setup local correction and local part of coarse basis. 34588629588bSStefano Zampini Gives back the dense local part of the coarse matrix in column major ordering 34598629588bSStefano Zampini */ 346047f4ddc3SStefano Zampini ierr = PCBDDCSetUpCorrection(pc,&coarse_submat_vals);CHKERRQ(ierr); 34618629588bSStefano Zampini 34628629588bSStefano Zampini /* Compute total number of coarse nodes and setup coarse solver */ 34638629588bSStefano Zampini ierr = PCBDDCSetUpCoarseSolver(pc,coarse_submat_vals);CHKERRQ(ierr); 34648629588bSStefano Zampini 34658629588bSStefano Zampini /* free */ 34668629588bSStefano Zampini ierr = PetscFree(coarse_submat_vals);CHKERRQ(ierr); 3467c8587f34SStefano Zampini PetscFunctionReturn(0); 3468c8587f34SStefano Zampini } 3469c8587f34SStefano Zampini 3470674ae819SStefano Zampini PetscErrorCode PCBDDCResetCustomization(PC pc) 3471674ae819SStefano Zampini { 3472674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3473674ae819SStefano Zampini PetscErrorCode ierr; 3474674ae819SStefano Zampini 3475674ae819SStefano Zampini PetscFunctionBegin; 3476674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices);CHKERRQ(ierr); 347730368db7SStefano Zampini ierr = ISDestroy(&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 3478674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundaries);CHKERRQ(ierr); 3479785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->NeumannBoundariesLocal);CHKERRQ(ierr); 3480674ae819SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundaries);CHKERRQ(ierr); 3481f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 3482f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 3483785d1243SStefano Zampini ierr = ISDestroy(&pcbddc->DirichletBoundariesLocal);CHKERRQ(ierr); 348463602bcaSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc,0,NULL);CHKERRQ(ierr); 348563602bcaSStefano Zampini ierr = PCBDDCSetDofsSplittingLocal(pc,0,NULL);CHKERRQ(ierr); 3486674ae819SStefano Zampini PetscFunctionReturn(0); 3487674ae819SStefano Zampini } 3488674ae819SStefano Zampini 3489674ae819SStefano Zampini PetscErrorCode PCBDDCResetTopography(PC pc) 3490674ae819SStefano Zampini { 3491674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 34924f1b2e48SStefano Zampini PetscInt i; 3493674ae819SStefano Zampini PetscErrorCode ierr; 3494674ae819SStefano Zampini 3495674ae819SStefano Zampini PetscFunctionBegin; 34961e0482f5SStefano Zampini ierr = MatDestroy(&pcbddc->nedcG);CHKERRQ(ierr); 34971e0482f5SStefano Zampini ierr = ISDestroy(&pcbddc->nedclocal);CHKERRQ(ierr); 3498a13144ffSStefano Zampini ierr = MatDestroy(&pcbddc->discretegradient);CHKERRQ(ierr); 3499b9b85e73SStefano Zampini ierr = MatDestroy(&pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 3500674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 350116909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 35021dd7afcfSStefano Zampini ierr = VecDestroy(&pcbddc->work_change);CHKERRQ(ierr); 3503674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 3504669cc0f4SStefano Zampini ierr = MatDestroy(&pcbddc->divudotp);CHKERRQ(ierr); 3505fa23a32eSStefano Zampini ierr = ISDestroy(&pcbddc->divudotp_vl2l);CHKERRQ(ierr); 35069326c5c6Sstefano_zampini ierr = PCBDDCGraphDestroy(&pcbddc->mat_graph);CHKERRQ(ierr); 35074f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 35084f1b2e48SStefano Zampini ierr = ISDestroy(&pcbddc->local_subs[i]);CHKERRQ(ierr); 35094f1b2e48SStefano Zampini } 3510e68a0315Sstefano_zampini pcbddc->n_local_subs = 0; 35114f1b2e48SStefano Zampini ierr = PetscFree(pcbddc->local_subs);CHKERRQ(ierr); 3512e68a0315Sstefano_zampini ierr = PCBDDCSubSchursDestroy(&pcbddc->sub_schurs);CHKERRQ(ierr); 3513c703fcc7SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 35148af8fcf9SStefano Zampini pcbddc->recompute_topography = PETSC_TRUE; 3515674ae819SStefano Zampini PetscFunctionReturn(0); 3516674ae819SStefano Zampini } 3517674ae819SStefano Zampini 3518674ae819SStefano Zampini PetscErrorCode PCBDDCResetSolvers(PC pc) 3519674ae819SStefano Zampini { 3520674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 3521674ae819SStefano Zampini PetscErrorCode ierr; 3522674ae819SStefano Zampini 3523674ae819SStefano Zampini PetscFunctionBegin; 3524674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 352558da7f69SStefano Zampini if (pcbddc->coarse_phi_B) { 3526ca92afb2SStefano Zampini PetscScalar *array; 352706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&array);CHKERRQ(ierr); 352806656605SStefano Zampini ierr = PetscFree(array);CHKERRQ(ierr); 352958da7f69SStefano Zampini } 3530674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3531674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 353215aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 353315aaf578SStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3534674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 3535674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 3536674ae819SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 353706656605SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 3538674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3539674ae819SStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 35408ce42a96SStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 3541674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 3542674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 3543674ae819SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 35449326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_D);CHKERRQ(ierr); 35459326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 35469326c5c6Sstefano_zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 3547f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 3548727cdba6SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 35490e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 3550f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 355170cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 355281d14e9dSStefano Zampini ierr = MatDestroy(&pcbddc->benign_change);CHKERRQ(ierr); 35530369aaf7SStefano Zampini ierr = VecDestroy(&pcbddc->benign_vec);CHKERRQ(ierr); 35541dd7afcfSStefano Zampini ierr = PCBDDCBenignShellMat(pc,PETSC_TRUE);CHKERRQ(ierr); 35554f1b2e48SStefano Zampini ierr = MatDestroy(&pcbddc->benign_B0);CHKERRQ(ierr); 35568b9f24d4SStefano Zampini ierr = PetscSFDestroy(&pcbddc->benign_sf);CHKERRQ(ierr); 3557ca92afb2SStefano Zampini if (pcbddc->benign_zerodiag_subs) { 3558ca92afb2SStefano Zampini PetscInt i; 3559ca92afb2SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 3560ca92afb2SStefano Zampini ierr = ISDestroy(&pcbddc->benign_zerodiag_subs[i]);CHKERRQ(ierr); 3561ca92afb2SStefano Zampini } 3562ca92afb2SStefano Zampini ierr = PetscFree(pcbddc->benign_zerodiag_subs);CHKERRQ(ierr); 3563ca92afb2SStefano Zampini } 35644f1b2e48SStefano Zampini ierr = PetscFree3(pcbddc->benign_p0_lidx,pcbddc->benign_p0_gidx,pcbddc->benign_p0);CHKERRQ(ierr); 3565674ae819SStefano Zampini PetscFunctionReturn(0); 3566674ae819SStefano Zampini } 3567674ae819SStefano Zampini 3568f4ddd8eeSStefano Zampini PetscErrorCode PCBDDCSetUpLocalWorkVectors(PC pc) 35696bfb1811SStefano Zampini { 35706bfb1811SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 35716bfb1811SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 35726bfb1811SStefano Zampini VecType impVecType; 35734f1b2e48SStefano Zampini PetscInt n_constraints,n_R,old_size; 35746bfb1811SStefano Zampini PetscErrorCode ierr; 35756bfb1811SStefano Zampini 35766bfb1811SStefano Zampini PetscFunctionBegin; 35774f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - pcbddc->n_vertices; 3578b371cd4fSStefano Zampini n_R = pcis->n - pcbddc->n_vertices; 35796bfb1811SStefano Zampini ierr = VecGetType(pcis->vec1_N,&impVecType);CHKERRQ(ierr); 3580e7b262bdSStefano Zampini /* local work vectors (try to avoid unneeded work)*/ 3581e7b262bdSStefano Zampini /* R nodes */ 3582e7b262bdSStefano Zampini old_size = -1; 3583e7b262bdSStefano Zampini if (pcbddc->vec1_R) { 3584e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_R,&old_size);CHKERRQ(ierr); 3585e7b262bdSStefano Zampini } 3586e7b262bdSStefano Zampini if (n_R != old_size) { 3587e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_R);CHKERRQ(ierr); 3588e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec2_R);CHKERRQ(ierr); 35896bfb1811SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_R);CHKERRQ(ierr); 35906bfb1811SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_R,PETSC_DECIDE,n_R);CHKERRQ(ierr); 35916bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_R,impVecType);CHKERRQ(ierr); 35926bfb1811SStefano Zampini ierr = VecDuplicate(pcbddc->vec1_R,&pcbddc->vec2_R);CHKERRQ(ierr); 3593e7b262bdSStefano Zampini } 3594e7b262bdSStefano Zampini /* local primal dofs */ 3595e7b262bdSStefano Zampini old_size = -1; 3596e7b262bdSStefano Zampini if (pcbddc->vec1_P) { 3597e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_P,&old_size);CHKERRQ(ierr); 3598e7b262bdSStefano Zampini } 3599e9189074SStefano Zampini if (pcbddc->local_primal_size != old_size) { 3600e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_P);CHKERRQ(ierr); 360183b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_P);CHKERRQ(ierr); 3602e9189074SStefano Zampini ierr = VecSetSizes(pcbddc->vec1_P,PETSC_DECIDE,pcbddc->local_primal_size);CHKERRQ(ierr); 36036bfb1811SStefano Zampini ierr = VecSetType(pcbddc->vec1_P,impVecType);CHKERRQ(ierr); 3604e7b262bdSStefano Zampini } 3605e7b262bdSStefano Zampini /* local explicit constraints */ 3606e7b262bdSStefano Zampini old_size = -1; 3607e7b262bdSStefano Zampini if (pcbddc->vec1_C) { 3608e7b262bdSStefano Zampini ierr = VecGetSize(pcbddc->vec1_C,&old_size);CHKERRQ(ierr); 3609e7b262bdSStefano Zampini } 3610e7b262bdSStefano Zampini if (n_constraints && n_constraints != old_size) { 3611e7b262bdSStefano Zampini ierr = VecDestroy(&pcbddc->vec1_C);CHKERRQ(ierr); 361283b7ccabSStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pcis->vec1_N),&pcbddc->vec1_C);CHKERRQ(ierr); 361383b7ccabSStefano Zampini ierr = VecSetSizes(pcbddc->vec1_C,PETSC_DECIDE,n_constraints);CHKERRQ(ierr); 361483b7ccabSStefano Zampini ierr = VecSetType(pcbddc->vec1_C,impVecType);CHKERRQ(ierr); 361583b7ccabSStefano Zampini } 36166bfb1811SStefano Zampini PetscFunctionReturn(0); 36176bfb1811SStefano Zampini } 36186bfb1811SStefano Zampini 361947f4ddc3SStefano Zampini PetscErrorCode PCBDDCSetUpCorrection(PC pc, PetscScalar **coarse_submat_vals_n) 362088ebb749SStefano Zampini { 362125084f0cSStefano Zampini PetscErrorCode ierr; 362225084f0cSStefano Zampini /* pointers to pcis and pcbddc */ 362388ebb749SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 362488ebb749SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 3625d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 362625084f0cSStefano Zampini /* submatrices of local problem */ 362780677318SStefano Zampini Mat A_RV,A_VR,A_VV,local_auxmat2_R; 362806656605SStefano Zampini /* submatrices of local coarse problem */ 362906656605SStefano Zampini Mat S_VV,S_CV,S_VC,S_CC; 363025084f0cSStefano Zampini /* working matrices */ 363106656605SStefano Zampini Mat C_CR; 363225084f0cSStefano Zampini /* additional working stuff */ 363306656605SStefano Zampini PC pc_R; 3634c58f9fdbSStefano Zampini Mat F,Brhs = NULL; 36355cbda25cSStefano Zampini Vec dummy_vec; 3636c58f9fdbSStefano Zampini PetscBool isLU,isCHOL,isILU,need_benign_correction,sparserhs; 363725084f0cSStefano Zampini PetscScalar *coarse_submat_vals; /* TODO: use a PETSc matrix */ 363806656605SStefano Zampini PetscScalar *work; 363906656605SStefano Zampini PetscInt *idx_V_B; 3640ffd830a3SStefano Zampini PetscInt lda_rhs,n,n_vertices,n_constraints,*p0_lidx_I; 364106656605SStefano Zampini PetscInt i,n_R,n_D,n_B; 3642ffd830a3SStefano Zampini 364325084f0cSStefano Zampini /* some shortcuts to scalars */ 364406656605SStefano Zampini PetscScalar one=1.0,m_one=-1.0; 364588ebb749SStefano Zampini 364688ebb749SStefano Zampini PetscFunctionBegin; 36479a962809SStefano 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"); 3648ffd830a3SStefano Zampini 3649ffd830a3SStefano Zampini /* Set Non-overlapping dimensions */ 3650b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 36514f1b2e48SStefano Zampini n_constraints = pcbddc->local_primal_size - pcbddc->benign_n - n_vertices; 3652b371cd4fSStefano Zampini n_B = pcis->n_B; 3653b371cd4fSStefano Zampini n_D = pcis->n - n_B; 365488ebb749SStefano Zampini n_R = pcis->n - n_vertices; 365588ebb749SStefano Zampini 365688ebb749SStefano Zampini /* vertices in boundary numbering */ 3657785e854fSJed Brown ierr = PetscMalloc1(n_vertices,&idx_V_B);CHKERRQ(ierr); 36580e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,n_vertices,pcbddc->local_primal_ref_node,&i,idx_V_B);CHKERRQ(ierr); 36596c4ed002SBarry 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); 366088ebb749SStefano Zampini 366106656605SStefano Zampini /* Subdomain contribution (Non-overlapping) to coarse matrix */ 3662019a44ceSStefano Zampini ierr = PetscCalloc1(pcbddc->local_primal_size*pcbddc->local_primal_size,&coarse_submat_vals);CHKERRQ(ierr); 366306656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_vertices,coarse_submat_vals,&S_VV);CHKERRQ(ierr); 366406656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VV,pcbddc->local_primal_size);CHKERRQ(ierr); 366506656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_vertices,coarse_submat_vals+n_vertices,&S_CV);CHKERRQ(ierr); 366606656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CV,pcbddc->local_primal_size);CHKERRQ(ierr); 366706656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_vertices,n_constraints,coarse_submat_vals+pcbddc->local_primal_size*n_vertices,&S_VC);CHKERRQ(ierr); 366806656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_VC,pcbddc->local_primal_size);CHKERRQ(ierr); 366906656605SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_constraints,n_constraints,coarse_submat_vals+(pcbddc->local_primal_size+1)*n_vertices,&S_CC);CHKERRQ(ierr); 367006656605SStefano Zampini ierr = MatSeqDenseSetLDA(S_CC,pcbddc->local_primal_size);CHKERRQ(ierr); 367106656605SStefano Zampini 367206656605SStefano Zampini /* determine if can use MatSolve routines instead of calling KSPSolve on ksp_R */ 367306656605SStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_R);CHKERRQ(ierr); 367406656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCLU,&isLU);CHKERRQ(ierr); 367506656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCILU,&isILU);CHKERRQ(ierr); 367606656605SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_R,PCCHOLESKY,&isCHOL);CHKERRQ(ierr); 3677ffd830a3SStefano Zampini lda_rhs = n_R; 3678a3df083aSStefano Zampini need_benign_correction = PETSC_FALSE; 367906656605SStefano Zampini if (isLU || isILU || isCHOL) { 368006656605SStefano Zampini ierr = PCFactorGetMatrix(pc_R,&F);CHKERRQ(ierr); 3681b334f244SStefano Zampini } else if (sub_schurs && sub_schurs->reuse_solver) { 3682df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3683d62866d3SStefano Zampini MatFactorType type; 3684d62866d3SStefano Zampini 3685df4d28bfSStefano Zampini F = reuse_solver->F; 36866816873aSStefano Zampini ierr = MatGetFactorType(F,&type);CHKERRQ(ierr); 3687d62866d3SStefano Zampini if (type == MAT_FACTOR_CHOLESKY) isCHOL = PETSC_TRUE; 3688ffd830a3SStefano Zampini ierr = MatGetSize(F,&lda_rhs,NULL);CHKERRQ(ierr); 368922db5ddcSStefano Zampini need_benign_correction = (PetscBool)(!!reuse_solver->benign_n); 369006656605SStefano Zampini } else { 369106656605SStefano Zampini F = NULL; 369206656605SStefano Zampini } 369306656605SStefano Zampini 3694c58f9fdbSStefano Zampini /* determine if we can use a sparse right-hand side */ 3695c58f9fdbSStefano Zampini sparserhs = PETSC_FALSE; 3696c58f9fdbSStefano Zampini if (F) { 3697ea799195SBarry Smith MatSolverType solver; 3698c58f9fdbSStefano Zampini 36993ca39a21SBarry Smith ierr = MatFactorGetSolverType(F,&solver);CHKERRQ(ierr); 3700c58f9fdbSStefano Zampini ierr = PetscStrcmp(solver,MATSOLVERMUMPS,&sparserhs);CHKERRQ(ierr); 3701c58f9fdbSStefano Zampini } 3702c58f9fdbSStefano Zampini 3703ffd830a3SStefano Zampini /* allocate workspace */ 3704ffd830a3SStefano Zampini n = 0; 3705ffd830a3SStefano Zampini if (n_constraints) { 3706ffd830a3SStefano Zampini n += lda_rhs*n_constraints; 3707ffd830a3SStefano Zampini } 3708ffd830a3SStefano Zampini if (n_vertices) { 3709ffd830a3SStefano Zampini n = PetscMax(2*lda_rhs*n_vertices,n); 3710ffd830a3SStefano Zampini n = PetscMax((lda_rhs+n_B)*n_vertices,n); 3711ffd830a3SStefano Zampini } 37122a3a6641Sstefano_zampini if (!pcbddc->symmetric_primal) { 37132a3a6641Sstefano_zampini n = PetscMax(2*lda_rhs*pcbddc->local_primal_size,n); 37142a3a6641Sstefano_zampini } 3715ffd830a3SStefano Zampini ierr = PetscMalloc1(n,&work);CHKERRQ(ierr); 3716ffd830a3SStefano Zampini 37175cbda25cSStefano Zampini /* create dummy vector to modify rhs and sol of MatMatSolve (work array will never be used) */ 37185cbda25cSStefano Zampini dummy_vec = NULL; 37195cbda25cSStefano Zampini if (need_benign_correction && lda_rhs != n_R && F) { 37205cbda25cSStefano Zampini ierr = VecCreateSeqWithArray(PETSC_COMM_SELF,1,lda_rhs,work,&dummy_vec);CHKERRQ(ierr); 37215cbda25cSStefano Zampini } 37225cbda25cSStefano Zampini 372388ebb749SStefano Zampini /* Precompute stuffs needed for preprocessing and application of BDDC*/ 372488ebb749SStefano Zampini if (n_constraints) { 3725837cedc9SStefano Zampini Mat M3,C_B; 372606656605SStefano Zampini IS is_aux; 372780677318SStefano Zampini PetscScalar *array,*array2; 372806656605SStefano Zampini 3729f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat1);CHKERRQ(ierr); 373080677318SStefano Zampini ierr = MatDestroy(&pcbddc->local_auxmat2);CHKERRQ(ierr); 373188ebb749SStefano Zampini 373225084f0cSStefano Zampini /* Extract constraints on R nodes: C_{CR} */ 373325084f0cSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_constraints,n_vertices,1,&is_aux);CHKERRQ(ierr); 37347dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&C_CR);CHKERRQ(ierr); 37357dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_aux,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 373688ebb749SStefano Zampini 373780677318SStefano Zampini /* Assemble local_auxmat2_R = (- A_{RR}^{-1} C^T_{CR}) needed by BDDC setup */ 373880677318SStefano Zampini /* Assemble pcbddc->local_auxmat2 = R_to_B (- A_{RR}^{-1} C^T_{CR}) needed by BDDC application */ 3739c58f9fdbSStefano Zampini if (!sparserhs) { 3740ffd830a3SStefano Zampini ierr = PetscMemzero(work,lda_rhs*n_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 374188ebb749SStefano Zampini for (i=0;i<n_constraints;i++) { 374206656605SStefano Zampini const PetscScalar *row_cmat_values; 374306656605SStefano Zampini const PetscInt *row_cmat_indices; 374406656605SStefano Zampini PetscInt size_of_constraint,j; 374588ebb749SStefano Zampini 374606656605SStefano Zampini ierr = MatGetRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 374706656605SStefano Zampini for (j=0;j<size_of_constraint;j++) { 3748ffd830a3SStefano Zampini work[row_cmat_indices[j]+i*lda_rhs] = -row_cmat_values[j]; 374906656605SStefano Zampini } 375006656605SStefano Zampini ierr = MatRestoreRow(C_CR,i,&size_of_constraint,&row_cmat_indices,&row_cmat_values);CHKERRQ(ierr); 375106656605SStefano Zampini } 3752c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&Brhs);CHKERRQ(ierr); 3753c58f9fdbSStefano Zampini } else { 3754c58f9fdbSStefano Zampini Mat tC_CR; 3755c58f9fdbSStefano Zampini 3756c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3757c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 3758c58f9fdbSStefano Zampini PetscScalar *aa; 3759c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 3760c58f9fdbSStefano Zampini PetscBool done; 3761c58f9fdbSStefano Zampini 3762c58f9fdbSStefano Zampini ierr = MatGetRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 376313903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 3764c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(C_CR,&aa);CHKERRQ(ierr); 3765c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_constraints,lda_rhs,ii,jj,aa,&tC_CR);CHKERRQ(ierr); 3766c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(C_CR,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 376713903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 3768c58f9fdbSStefano Zampini } else { 3769c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)C_CR);CHKERRQ(ierr); 3770c58f9fdbSStefano Zampini tC_CR = C_CR; 3771c58f9fdbSStefano Zampini } 3772c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tC_CR,&Brhs);CHKERRQ(ierr); 3773c58f9fdbSStefano Zampini ierr = MatDestroy(&tC_CR);CHKERRQ(ierr); 3774c58f9fdbSStefano Zampini } 3775ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,NULL,&local_auxmat2_R);CHKERRQ(ierr); 377606656605SStefano Zampini if (F) { 3777a3df083aSStefano Zampini if (need_benign_correction) { 3778df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3779a3df083aSStefano Zampini 378072b8c272SStefano Zampini /* rhs is already zero on interior dofs, no need to change the rhs */ 378172b8c272SStefano Zampini ierr = PetscMemzero(reuse_solver->benign_save_vals,pcbddc->benign_n*sizeof(PetscScalar));CHKERRQ(ierr); 3782a3df083aSStefano Zampini } 3783c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,local_auxmat2_R);CHKERRQ(ierr); 3784a3df083aSStefano Zampini if (need_benign_correction) { 3785a3df083aSStefano Zampini PetscScalar *marr; 3786df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 3787a3df083aSStefano Zampini 3788a3df083aSStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 37895cbda25cSStefano Zampini if (lda_rhs != n_R) { 37905cbda25cSStefano Zampini for (i=0;i<n_constraints;i++) { 37915cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 37925cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 37935cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 37945cbda25cSStefano Zampini } 37955cbda25cSStefano Zampini } else { 3796a3df083aSStefano Zampini for (i=0;i<n_constraints;i++) { 3797a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 37985cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 3799a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 3800a3df083aSStefano Zampini } 38015cbda25cSStefano Zampini } 3802a3df083aSStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 3803a3df083aSStefano Zampini } 380406656605SStefano Zampini } else { 380580677318SStefano Zampini PetscScalar *marr; 380680677318SStefano Zampini 380780677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 380806656605SStefano Zampini for (i=0;i<n_constraints;i++) { 3809ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 3810ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,marr+i*lda_rhs);CHKERRQ(ierr); 381106656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 381206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 381306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 381406656605SStefano Zampini } 381580677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&marr);CHKERRQ(ierr); 381606656605SStefano Zampini } 3817c58f9fdbSStefano Zampini if (sparserhs) { 3818c58f9fdbSStefano Zampini ierr = MatScale(C_CR,-1.0);CHKERRQ(ierr); 3819c58f9fdbSStefano Zampini } 3820c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 382180677318SStefano Zampini if (!pcbddc->switch_static) { 382280677318SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_constraints,NULL,&pcbddc->local_auxmat2);CHKERRQ(ierr); 382380677318SStefano Zampini ierr = MatDenseGetArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 382480677318SStefano Zampini ierr = MatDenseGetArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 382580677318SStefano Zampini for (i=0;i<n_constraints;i++) { 3826ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,array2+i*lda_rhs);CHKERRQ(ierr); 382780677318SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,array+i*n_B);CHKERRQ(ierr); 382880677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 382980677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 383080677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 383180677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 383280677318SStefano Zampini } 383380677318SStefano Zampini ierr = MatDenseRestoreArray(local_auxmat2_R,&array2);CHKERRQ(ierr); 383480677318SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->local_auxmat2,&array);CHKERRQ(ierr); 383572b8c272SStefano Zampini ierr = MatMatMult(C_B,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 383680677318SStefano Zampini } else { 3837ffd830a3SStefano Zampini if (lda_rhs != n_R) { 3838ffd830a3SStefano Zampini IS dummy; 3839ffd830a3SStefano Zampini 3840ffd830a3SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_R,0,1,&dummy);CHKERRQ(ierr); 38417dae84e0SHong Zhang ierr = MatCreateSubMatrix(local_auxmat2_R,dummy,NULL,MAT_INITIAL_MATRIX,&pcbddc->local_auxmat2);CHKERRQ(ierr); 3842ffd830a3SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 3843ffd830a3SStefano Zampini } else { 384480677318SStefano Zampini ierr = PetscObjectReference((PetscObject)local_auxmat2_R);CHKERRQ(ierr); 384580677318SStefano Zampini pcbddc->local_auxmat2 = local_auxmat2_R; 3846ffd830a3SStefano Zampini } 384725084f0cSStefano Zampini ierr = MatMatMult(C_CR,pcbddc->local_auxmat2,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&M3);CHKERRQ(ierr); 384880677318SStefano Zampini } 384980677318SStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 385080677318SStefano Zampini /* Assemble explicitly S_CC = ( C_{CR} A_{RR}^{-1} C^T_{CR} )^{-1} */ 385180677318SStefano Zampini ierr = MatScale(M3,m_one);CHKERRQ(ierr); 385280677318SStefano Zampini if (isCHOL) { 385380677318SStefano Zampini ierr = MatCholeskyFactor(M3,NULL,NULL);CHKERRQ(ierr); 385480677318SStefano Zampini } else { 385525084f0cSStefano Zampini ierr = MatLUFactor(M3,NULL,NULL,NULL);CHKERRQ(ierr); 385680677318SStefano Zampini } 3857837cedc9SStefano Zampini ierr = MatSeqDenseInvertFactors_Private(M3);CHKERRQ(ierr); 385880677318SStefano Zampini /* Assemble local_auxmat1 = S_CC*C_{CB} needed by BDDC application in KSP and in preproc */ 3859837cedc9SStefano Zampini ierr = MatMatMult(M3,C_B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->local_auxmat1);CHKERRQ(ierr); 386072b8c272SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 3861837cedc9SStefano Zampini ierr = MatCopy(M3,S_CC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); /* S_CC can have a different LDA, MatMatSolve doesn't support it */ 3862837cedc9SStefano Zampini ierr = MatDestroy(&M3);CHKERRQ(ierr); 3863f4ddd8eeSStefano Zampini } 3864fc227af8SStefano Zampini 3865fc227af8SStefano Zampini /* Get submatrices from subdomain matrix */ 386688ebb749SStefano Zampini if (n_vertices) { 386706656605SStefano Zampini IS is_aux; 3868c58f9fdbSStefano Zampini PetscBool isseqaij; 38693a50541eSStefano Zampini 3870b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { /* is_R_local is not sorted, ISComplement doesn't like it */ 38716816873aSStefano Zampini IS tis; 38726816873aSStefano Zampini 38736816873aSStefano Zampini ierr = ISDuplicate(pcbddc->is_R_local,&tis);CHKERRQ(ierr); 38746816873aSStefano Zampini ierr = ISSort(tis);CHKERRQ(ierr); 38756816873aSStefano Zampini ierr = ISComplement(tis,0,pcis->n,&is_aux);CHKERRQ(ierr); 38766816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 38776816873aSStefano Zampini } else { 38783a50541eSStefano Zampini ierr = ISComplement(pcbddc->is_R_local,0,pcis->n,&is_aux);CHKERRQ(ierr); 38796816873aSStefano Zampini } 38807dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,is_aux,MAT_INITIAL_MATRIX,&A_RV);CHKERRQ(ierr); 38817dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_VR);CHKERRQ(ierr); 3882c58f9fdbSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_VR,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 3883c58f9fdbSStefano Zampini if (!isseqaij) { /* MatMatMult(A_VR,A_RRmA_RV) below will raise an error */ 3884c58f9fdbSStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 3885c58f9fdbSStefano Zampini } 38867dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,is_aux,is_aux,MAT_INITIAL_MATRIX,&A_VV);CHKERRQ(ierr); 388725084f0cSStefano Zampini ierr = ISDestroy(&is_aux);CHKERRQ(ierr); 388888ebb749SStefano Zampini } 388988ebb749SStefano Zampini 389088ebb749SStefano Zampini /* Matrix of coarse basis functions (local) */ 3891f4ddd8eeSStefano Zampini if (pcbddc->coarse_phi_B) { 389206656605SStefano Zampini PetscInt on_B,on_primal,on_D=n_D; 389306656605SStefano Zampini if (pcbddc->coarse_phi_D) { 389406656605SStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_D,&on_D,NULL);CHKERRQ(ierr); 389506656605SStefano Zampini } 3896f4ddd8eeSStefano Zampini ierr = MatGetSize(pcbddc->coarse_phi_B,&on_B,&on_primal);CHKERRQ(ierr); 389706656605SStefano Zampini if (on_B != n_B || on_primal != pcbddc->local_primal_size || on_D != n_D) { 389806656605SStefano Zampini PetscScalar *marray; 389906656605SStefano Zampini 390006656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&marray);CHKERRQ(ierr); 390106656605SStefano Zampini ierr = PetscFree(marray);CHKERRQ(ierr); 3902f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3903f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3904f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3905f4ddd8eeSStefano Zampini ierr = MatDestroy(&pcbddc->coarse_psi_D);CHKERRQ(ierr); 3906f4ddd8eeSStefano Zampini } 3907f4ddd8eeSStefano Zampini } 390806656605SStefano Zampini 3909f4ddd8eeSStefano Zampini if (!pcbddc->coarse_phi_B) { 3910a6e023c1Sstefano_zampini PetscScalar *marr; 391188ebb749SStefano Zampini 3912a6e023c1Sstefano_zampini /* memory size */ 391306656605SStefano Zampini n = n_B*pcbddc->local_primal_size; 3914a6e023c1Sstefano_zampini if (pcbddc->switch_static || pcbddc->dbg_flag) n += n_D*pcbddc->local_primal_size; 3915a6e023c1Sstefano_zampini if (!pcbddc->symmetric_primal) n *= 2; 3916a6e023c1Sstefano_zampini ierr = PetscCalloc1(n,&marr);CHKERRQ(ierr); 3917a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_B);CHKERRQ(ierr); 3918a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 39198eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3920a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_phi_D);CHKERRQ(ierr); 3921a6e023c1Sstefano_zampini marr += n_D*pcbddc->local_primal_size; 392288ebb749SStefano Zampini } 39233301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 3924a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_B);CHKERRQ(ierr); 3925a6e023c1Sstefano_zampini marr += n_B*pcbddc->local_primal_size; 39268eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3927a6e023c1Sstefano_zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_D,pcbddc->local_primal_size,marr,&pcbddc->coarse_psi_D);CHKERRQ(ierr); 392888ebb749SStefano Zampini } 392988ebb749SStefano Zampini } else { 3930c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_B);CHKERRQ(ierr); 3931c0553b1fSStefano Zampini pcbddc->coarse_psi_B = pcbddc->coarse_phi_B; 39321b968477SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 3933c0553b1fSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->coarse_phi_D);CHKERRQ(ierr); 3934c0553b1fSStefano Zampini pcbddc->coarse_psi_D = pcbddc->coarse_phi_D; 3935c0553b1fSStefano Zampini } 393688ebb749SStefano Zampini } 393706656605SStefano Zampini } 3938019a44ceSStefano Zampini 393906656605SStefano Zampini /* We are now ready to evaluate coarse basis functions and subdomain contribution to coarse problem */ 39404f1b2e48SStefano Zampini p0_lidx_I = NULL; 39414f1b2e48SStefano Zampini if (pcbddc->benign_n && (pcbddc->switch_static || pcbddc->dbg_flag)) { 3942d12edf2fSStefano Zampini const PetscInt *idxs; 3943d12edf2fSStefano Zampini 3944d12edf2fSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 39454f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&p0_lidx_I);CHKERRQ(ierr); 39464f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 39474f1b2e48SStefano Zampini ierr = PetscFindInt(pcbddc->benign_p0_lidx[i],pcis->n-pcis->n_B,idxs,&p0_lidx_I[i]);CHKERRQ(ierr); 39484f1b2e48SStefano Zampini } 3949d12edf2fSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 3950d12edf2fSStefano Zampini } 3951d16cbb6bSStefano Zampini 395206656605SStefano Zampini /* vertices */ 395306656605SStefano Zampini if (n_vertices) { 3954c58f9fdbSStefano Zampini PetscBool restoreavr = PETSC_FALSE; 395516f15bc4SStefano Zampini 3956af25d912SStefano Zampini ierr = MatConvert(A_VV,MATDENSE,MAT_INPLACE_MATRIX,&A_VV);CHKERRQ(ierr); 395704708bb6SStefano Zampini 395816f15bc4SStefano Zampini if (n_R) { 395914393ed6SStefano Zampini Mat A_RRmA_RV,A_RV_bcorr=NULL,S_VVt; /* S_VVt with LDA=N */ 396006656605SStefano Zampini PetscBLASInt B_N,B_one = 1; 396116f15bc4SStefano Zampini PetscScalar *x,*y; 396206656605SStefano Zampini 396321eccb56SStefano Zampini ierr = MatScale(A_RV,m_one);CHKERRQ(ierr); 396414393ed6SStefano Zampini if (need_benign_correction) { 396514393ed6SStefano Zampini ISLocalToGlobalMapping RtoN; 396614393ed6SStefano Zampini IS is_p0; 396714393ed6SStefano Zampini PetscInt *idxs_p0,n; 396814393ed6SStefano Zampini 396914393ed6SStefano Zampini ierr = PetscMalloc1(pcbddc->benign_n,&idxs_p0);CHKERRQ(ierr); 397014393ed6SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(pcbddc->is_R_local,&RtoN);CHKERRQ(ierr); 397114393ed6SStefano Zampini ierr = ISGlobalToLocalMappingApply(RtoN,IS_GTOLM_DROP,pcbddc->benign_n,pcbddc->benign_p0_lidx,&n,idxs_p0);CHKERRQ(ierr); 3972af25d912SStefano 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); 397314393ed6SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&RtoN);CHKERRQ(ierr); 397414393ed6SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,n,idxs_p0,PETSC_OWN_POINTER,&is_p0);CHKERRQ(ierr); 39757dae84e0SHong Zhang ierr = MatCreateSubMatrix(A_RV,is_p0,NULL,MAT_INITIAL_MATRIX,&A_RV_bcorr);CHKERRQ(ierr); 397614393ed6SStefano Zampini ierr = ISDestroy(&is_p0);CHKERRQ(ierr); 397714393ed6SStefano Zampini } 397814393ed6SStefano Zampini 3979c58f9fdbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 3980c58f9fdbSStefano Zampini if (!sparserhs || need_benign_correction) { 3981ffd830a3SStefano Zampini if (lda_rhs == n_R) { 3982af25d912SStefano Zampini ierr = MatConvert(A_RV,MATDENSE,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3983ffd830a3SStefano Zampini } else { 3984ca92afb2SStefano Zampini PetscScalar *av,*array; 3985ca92afb2SStefano Zampini const PetscInt *xadj,*adjncy; 3986ca92afb2SStefano Zampini PetscInt n; 3987ca92afb2SStefano Zampini PetscBool flg_row; 3988ffd830a3SStefano Zampini 3989ca92afb2SStefano Zampini array = work+lda_rhs*n_vertices; 3990ca92afb2SStefano Zampini ierr = PetscMemzero(array,lda_rhs*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 39919d54b7f4SStefano Zampini ierr = MatConvert(A_RV,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_RV);CHKERRQ(ierr); 3992ca92afb2SStefano Zampini ierr = MatGetRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3993ca92afb2SStefano Zampini ierr = MatSeqAIJGetArray(A_RV,&av);CHKERRQ(ierr); 3994ca92afb2SStefano Zampini for (i=0;i<n;i++) { 3995ca92afb2SStefano Zampini PetscInt j; 3996ca92afb2SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) array[lda_rhs*adjncy[j]+i] = av[j]; 3997ffd830a3SStefano Zampini } 3998ca92afb2SStefano Zampini ierr = MatRestoreRowIJ(A_RV,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 3999ca92afb2SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4000ca92afb2SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,array,&A_RV);CHKERRQ(ierr); 4001ffd830a3SStefano Zampini } 4002a3df083aSStefano Zampini if (need_benign_correction) { 4003df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4004a3df083aSStefano Zampini PetscScalar *marr; 4005a3df083aSStefano Zampini 4006a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RV,&marr);CHKERRQ(ierr); 400714393ed6SStefano Zampini /* need \Phi^T A_RV = (I+L)A_RV, L given by 400814393ed6SStefano Zampini 400914393ed6SStefano Zampini | 0 0 0 | (V) 401014393ed6SStefano Zampini L = | 0 0 -1 | (P-p0) 401114393ed6SStefano Zampini | 0 0 -1 | (p0) 401214393ed6SStefano Zampini 401314393ed6SStefano Zampini */ 4014df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 401514393ed6SStefano Zampini const PetscScalar *vals; 401614393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 401714393ed6SStefano Zampini PetscInt n,j,nz; 401814393ed6SStefano Zampini 4019df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4020df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 402114393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 402214393ed6SStefano Zampini for (j=0;j<n;j++) { 402314393ed6SStefano Zampini PetscScalar val = vals[j]; 402414393ed6SStefano Zampini PetscInt k,col = idxs[j]; 402514393ed6SStefano Zampini for (k=0;k<nz;k++) marr[idxs_zero[k]+lda_rhs*col] -= val; 402614393ed6SStefano Zampini } 402714393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4028df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 402914393ed6SStefano Zampini } 403072b8c272SStefano Zampini ierr = MatDenseRestoreArray(A_RV,&marr);CHKERRQ(ierr); 403172b8c272SStefano Zampini } 4032c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RV);CHKERRQ(ierr); 4033c58f9fdbSStefano Zampini Brhs = A_RV; 4034c58f9fdbSStefano Zampini } else { 4035c58f9fdbSStefano Zampini Mat tA_RVT,A_RVT; 4036c58f9fdbSStefano Zampini 4037c58f9fdbSStefano Zampini if (!pcbddc->symmetric_primal) { 4038fb6280fbSStefano Zampini /* A_RV already scaled by -1 */ 4039c58f9fdbSStefano Zampini ierr = MatTranspose(A_RV,MAT_INITIAL_MATRIX,&A_RVT);CHKERRQ(ierr); 4040c58f9fdbSStefano Zampini } else { 4041c58f9fdbSStefano Zampini restoreavr = PETSC_TRUE; 4042c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4043c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_VR);CHKERRQ(ierr); 4044c58f9fdbSStefano Zampini A_RVT = A_VR; 4045c58f9fdbSStefano Zampini } 4046c58f9fdbSStefano Zampini if (lda_rhs != n_R) { 4047c58f9fdbSStefano Zampini PetscScalar *aa; 4048c58f9fdbSStefano Zampini PetscInt r,*ii,*jj; 4049c58f9fdbSStefano Zampini PetscBool done; 4050c58f9fdbSStefano Zampini 4051c58f9fdbSStefano Zampini ierr = MatGetRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 405213903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"GetRowIJ failed"); 4053c58f9fdbSStefano Zampini ierr = MatSeqAIJGetArray(A_RVT,&aa);CHKERRQ(ierr); 4054c58f9fdbSStefano Zampini ierr = MatCreateSeqAIJWithArrays(PETSC_COMM_SELF,n_vertices,lda_rhs,ii,jj,aa,&tA_RVT);CHKERRQ(ierr); 4055c58f9fdbSStefano Zampini ierr = MatRestoreRowIJ(A_RVT,0,PETSC_FALSE,PETSC_FALSE,&r,(const PetscInt**)&ii,(const PetscInt**)&jj,&done);CHKERRQ(ierr); 405613903a91SSatish Balay if (!done) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"RestoreRowIJ failed"); 4057c58f9fdbSStefano Zampini } else { 4058c58f9fdbSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RVT);CHKERRQ(ierr); 4059c58f9fdbSStefano Zampini tA_RVT = A_RVT; 4060c58f9fdbSStefano Zampini } 4061c58f9fdbSStefano Zampini ierr = MatCreateTranspose(tA_RVT,&Brhs);CHKERRQ(ierr); 4062c58f9fdbSStefano Zampini ierr = MatDestroy(&tA_RVT);CHKERRQ(ierr); 4063c58f9fdbSStefano Zampini ierr = MatDestroy(&A_RVT);CHKERRQ(ierr); 4064c58f9fdbSStefano Zampini } 406572b8c272SStefano Zampini if (F) { 406614393ed6SStefano Zampini /* need to correct the rhs */ 406772b8c272SStefano Zampini if (need_benign_correction) { 406872b8c272SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 406972b8c272SStefano Zampini PetscScalar *marr; 407072b8c272SStefano Zampini 4071c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&marr);CHKERRQ(ierr); 40725cbda25cSStefano Zampini if (lda_rhs != n_R) { 40735cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 40745cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 40755cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 40765cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 40775cbda25cSStefano Zampini } 40785cbda25cSStefano Zampini } else { 4079a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4080a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 40815cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 4082a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4083a3df083aSStefano Zampini } 40845cbda25cSStefano Zampini } 4085c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&marr);CHKERRQ(ierr); 4086a3df083aSStefano Zampini } 4087c58f9fdbSStefano Zampini ierr = MatMatSolve(F,Brhs,A_RRmA_RV);CHKERRQ(ierr); 4088c58f9fdbSStefano Zampini if (restoreavr) { 4089c58f9fdbSStefano Zampini ierr = MatScale(A_VR,-1.0);CHKERRQ(ierr); 4090c58f9fdbSStefano Zampini } 409114393ed6SStefano Zampini /* need to correct the solution */ 4092a3df083aSStefano Zampini if (need_benign_correction) { 4093df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 4094a3df083aSStefano Zampini PetscScalar *marr; 4095a3df083aSStefano Zampini 4096a3df083aSStefano Zampini ierr = MatDenseGetArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 40975cbda25cSStefano Zampini if (lda_rhs != n_R) { 40985cbda25cSStefano Zampini for (i=0;i<n_vertices;i++) { 40995cbda25cSStefano Zampini ierr = VecPlaceArray(dummy_vec,marr+i*lda_rhs);CHKERRQ(ierr); 41005cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,dummy_vec,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 41015cbda25cSStefano Zampini ierr = VecResetArray(dummy_vec);CHKERRQ(ierr); 41025cbda25cSStefano Zampini } 41035cbda25cSStefano Zampini } else { 4104a3df083aSStefano Zampini for (i=0;i<n_vertices;i++) { 4105a3df083aSStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marr+i*lda_rhs);CHKERRQ(ierr); 41065cbda25cSStefano Zampini ierr = PCBDDCReuseSolversBenignAdapt(reuse_solver,pcbddc->vec1_R,NULL,PETSC_TRUE,PETSC_TRUE);CHKERRQ(ierr); 4107a3df083aSStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4108a3df083aSStefano Zampini } 41095cbda25cSStefano Zampini } 4110a3df083aSStefano Zampini ierr = MatDenseRestoreArray(A_RRmA_RV,&marr);CHKERRQ(ierr); 4111a3df083aSStefano Zampini } 411206656605SStefano Zampini } else { 4113c58f9fdbSStefano Zampini ierr = MatDenseGetArray(Brhs,&y);CHKERRQ(ierr); 411406656605SStefano Zampini for (i=0;i<n_vertices;i++) { 4115ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,y+i*lda_rhs);CHKERRQ(ierr); 4116ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*lda_rhs);CHKERRQ(ierr); 411706656605SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 411806656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 411906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 412006656605SStefano Zampini } 4121c58f9fdbSStefano Zampini ierr = MatDenseRestoreArray(Brhs,&y);CHKERRQ(ierr); 412206656605SStefano Zampini } 412380677318SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 4124c58f9fdbSStefano Zampini ierr = MatDestroy(&Brhs);CHKERRQ(ierr); 4125ffd830a3SStefano Zampini /* S_VV and S_CV */ 412606656605SStefano Zampini if (n_constraints) { 412706656605SStefano Zampini Mat B; 412880677318SStefano Zampini 4129ffd830a3SStefano Zampini ierr = PetscMemzero(work+lda_rhs*n_vertices,n_B*n_vertices*sizeof(PetscScalar));CHKERRQ(ierr); 413080677318SStefano Zampini for (i=0;i<n_vertices;i++) { 4131ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*lda_rhs);CHKERRQ(ierr); 4132ffd830a3SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,work+lda_rhs*n_vertices+i*n_B);CHKERRQ(ierr); 413380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 413480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 413580677318SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 413680677318SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 413780677318SStefano Zampini } 4138ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_B,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 413980677318SStefano Zampini ierr = MatMatMult(pcbddc->local_auxmat1,B,MAT_REUSE_MATRIX,PETSC_DEFAULT,&S_CV);CHKERRQ(ierr); 414080677318SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 4141ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_vertices,work+lda_rhs*n_vertices,&B);CHKERRQ(ierr); 414280677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CV,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 414306656605SStefano Zampini ierr = MatScale(S_CV,m_one);CHKERRQ(ierr); 4144ffd830a3SStefano Zampini ierr = PetscBLASIntCast(lda_rhs*n_vertices,&B_N);CHKERRQ(ierr); 4145ffd830a3SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,work+lda_rhs*n_vertices,&B_one,work,&B_one)); 414606656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 414706656605SStefano Zampini } 4148ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4149ffd830a3SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 4150ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,work,&A_RRmA_RV);CHKERRQ(ierr); 4151ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(A_RRmA_RV,lda_rhs);CHKERRQ(ierr); 4152ffd830a3SStefano Zampini } 415306656605SStefano Zampini ierr = MatMatMult(A_VR,A_RRmA_RV,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VVt);CHKERRQ(ierr); 415414393ed6SStefano Zampini /* need A_VR * \Phi * A_RRmA_RV = A_VR * (I+L)^T * A_RRmA_RV, L given as before */ 415514393ed6SStefano Zampini if (need_benign_correction) { 4156df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 415714393ed6SStefano Zampini PetscScalar *marr,*sums; 415814393ed6SStefano Zampini 415914393ed6SStefano Zampini ierr = PetscMalloc1(n_vertices,&sums);CHKERRQ(ierr); 4160f913dca9SStefano Zampini ierr = MatDenseGetArray(S_VVt,&marr);CHKERRQ(ierr); 4161df4d28bfSStefano Zampini for (i=0;i<reuse_solver->benign_n;i++) { 416214393ed6SStefano Zampini const PetscScalar *vals; 416314393ed6SStefano Zampini const PetscInt *idxs,*idxs_zero; 416414393ed6SStefano Zampini PetscInt n,j,nz; 416514393ed6SStefano Zampini 4166df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->benign_zerodiag_subs[i],&nz);CHKERRQ(ierr); 4167df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 416814393ed6SStefano Zampini for (j=0;j<n_vertices;j++) { 416914393ed6SStefano Zampini PetscInt k; 417014393ed6SStefano Zampini sums[j] = 0.; 417114393ed6SStefano Zampini for (k=0;k<nz;k++) sums[j] += work[idxs_zero[k]+j*lda_rhs]; 417214393ed6SStefano Zampini } 417314393ed6SStefano Zampini ierr = MatGetRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 417414393ed6SStefano Zampini for (j=0;j<n;j++) { 417514393ed6SStefano Zampini PetscScalar val = vals[j]; 417614393ed6SStefano Zampini PetscInt k; 417714393ed6SStefano Zampini for (k=0;k<n_vertices;k++) { 417814393ed6SStefano Zampini marr[idxs[j]+k*n_vertices] += val*sums[k]; 417914393ed6SStefano Zampini } 418014393ed6SStefano Zampini } 418114393ed6SStefano Zampini ierr = MatRestoreRow(A_RV_bcorr,i,&n,&idxs,&vals);CHKERRQ(ierr); 4182df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->benign_zerodiag_subs[i],&idxs_zero);CHKERRQ(ierr); 418314393ed6SStefano Zampini } 418414393ed6SStefano Zampini ierr = PetscFree(sums);CHKERRQ(ierr); 4185f913dca9SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&marr);CHKERRQ(ierr); 418614393ed6SStefano Zampini ierr = MatDestroy(&A_RV_bcorr);CHKERRQ(ierr); 418714393ed6SStefano Zampini } 418880677318SStefano Zampini ierr = MatDestroy(&A_RRmA_RV);CHKERRQ(ierr); 418906656605SStefano Zampini ierr = PetscBLASIntCast(n_vertices*n_vertices,&B_N);CHKERRQ(ierr); 419006656605SStefano Zampini ierr = MatDenseGetArray(A_VV,&x);CHKERRQ(ierr); 419106656605SStefano Zampini ierr = MatDenseGetArray(S_VVt,&y);CHKERRQ(ierr); 419206656605SStefano Zampini PetscStackCallBLAS("BLASaxpy",BLASaxpy_(&B_N,&one,x,&B_one,y,&B_one)); 419306656605SStefano Zampini ierr = MatDenseRestoreArray(A_VV,&x);CHKERRQ(ierr); 419406656605SStefano Zampini ierr = MatDenseRestoreArray(S_VVt,&y);CHKERRQ(ierr); 419506656605SStefano Zampini ierr = MatCopy(S_VVt,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4196d16cbb6bSStefano Zampini ierr = MatDestroy(&S_VVt);CHKERRQ(ierr); 4197019a44ceSStefano Zampini } else { 4198d16cbb6bSStefano Zampini ierr = MatCopy(A_VV,S_VV,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 4199d16cbb6bSStefano Zampini } 420021eccb56SStefano Zampini ierr = MatDestroy(&A_VV);CHKERRQ(ierr); 4201d16cbb6bSStefano Zampini 420206656605SStefano Zampini /* coarse basis functions */ 420306656605SStefano Zampini for (i=0;i<n_vertices;i++) { 420416f15bc4SStefano Zampini PetscScalar *y; 420516f15bc4SStefano Zampini 4206ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 420706656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 420806656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 420906656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 421006656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 421106656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 421206656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 421306656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 421406656605SStefano Zampini 421506656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 42164f1b2e48SStefano Zampini PetscInt j; 42174f1b2e48SStefano Zampini 421806656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 421906656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 422006656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 422106656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 422206656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 42234f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 422406656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 422506656605SStefano Zampini } 422606656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 422706656605SStefano Zampini } 422804708bb6SStefano Zampini /* if n_R == 0 the object is not destroyed */ 422904708bb6SStefano Zampini ierr = MatDestroy(&A_RV);CHKERRQ(ierr); 423006656605SStefano Zampini } 42315cbda25cSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 423206656605SStefano Zampini 423306656605SStefano Zampini if (n_constraints) { 423406656605SStefano Zampini Mat B; 423506656605SStefano Zampini 4236ffd830a3SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,lda_rhs,n_constraints,work,&B);CHKERRQ(ierr); 423706656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 423880677318SStefano Zampini ierr = MatMatMult(local_auxmat2_R,S_CC,MAT_REUSE_MATRIX,PETSC_DEFAULT,&B);CHKERRQ(ierr); 423906656605SStefano Zampini ierr = MatScale(S_CC,m_one);CHKERRQ(ierr); 424006656605SStefano Zampini if (n_vertices) { 424103dfb2d7SStefano Zampini if (isCHOL || need_benign_correction) { /* if we can solve the interior problem with cholesky, we should also be fine with transposing here */ 424280677318SStefano Zampini ierr = MatTranspose(S_CV,MAT_REUSE_MATRIX,&S_VC);CHKERRQ(ierr); 424380677318SStefano Zampini } else { 424480677318SStefano Zampini Mat S_VCt; 424580677318SStefano Zampini 4246ffd830a3SStefano Zampini if (lda_rhs != n_R) { 4247ffd830a3SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 424872b8c272SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_constraints,work,&B);CHKERRQ(ierr); 4249ffd830a3SStefano Zampini ierr = MatSeqDenseSetLDA(B,lda_rhs);CHKERRQ(ierr); 4250ffd830a3SStefano Zampini } 425180677318SStefano Zampini ierr = MatMatMult(A_VR,B,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&S_VCt);CHKERRQ(ierr); 425280677318SStefano Zampini ierr = MatCopy(S_VCt,S_VC,SAME_NONZERO_PATTERN);CHKERRQ(ierr); 425380677318SStefano Zampini ierr = MatDestroy(&S_VCt);CHKERRQ(ierr); 425480677318SStefano Zampini } 425506656605SStefano Zampini } 425606656605SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 425706656605SStefano Zampini /* coarse basis functions */ 425806656605SStefano Zampini for (i=0;i<n_constraints;i++) { 425906656605SStefano Zampini PetscScalar *y; 426006656605SStefano Zampini 4261ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+lda_rhs*i);CHKERRQ(ierr); 426206656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 426306656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*(i+n_vertices));CHKERRQ(ierr); 426406656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 426506656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 426606656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&y);CHKERRQ(ierr); 426706656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 426806656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 42694f1b2e48SStefano Zampini PetscInt j; 42704f1b2e48SStefano Zampini 427106656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 427206656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*(i+n_vertices));CHKERRQ(ierr); 427306656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 427406656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 427506656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 42764f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) y[n_D*i+p0_lidx_I[j]] = 0.0; 427706656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_D,&y);CHKERRQ(ierr); 427806656605SStefano Zampini } 427906656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 428006656605SStefano Zampini } 428106656605SStefano Zampini } 428280677318SStefano Zampini if (n_constraints) { 428380677318SStefano Zampini ierr = MatDestroy(&local_auxmat2_R);CHKERRQ(ierr); 428480677318SStefano Zampini } 42854f1b2e48SStefano Zampini ierr = PetscFree(p0_lidx_I);CHKERRQ(ierr); 428672b8c272SStefano Zampini 428772b8c272SStefano Zampini /* coarse matrix entries relative to B_0 */ 428872b8c272SStefano Zampini if (pcbddc->benign_n) { 428972b8c272SStefano Zampini Mat B0_B,B0_BPHI; 429072b8c272SStefano Zampini IS is_dummy; 429172b8c272SStefano Zampini PetscScalar *data; 429272b8c272SStefano Zampini PetscInt j; 429372b8c272SStefano Zampini 429472b8c272SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 42957dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 429672b8c272SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 429772b8c272SStefano Zampini ierr = MatMatMult(B0_B,pcbddc->coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 429886c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 429972b8c272SStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data);CHKERRQ(ierr); 430072b8c272SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 430172b8c272SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 430272b8c272SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 430372b8c272SStefano Zampini coarse_submat_vals[primal_idx*pcbddc->local_primal_size+i] = data[i*pcbddc->benign_n+j]; 430472b8c272SStefano Zampini coarse_submat_vals[i*pcbddc->local_primal_size+primal_idx] = data[i*pcbddc->benign_n+j]; 430572b8c272SStefano Zampini } 430672b8c272SStefano Zampini } 430772b8c272SStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data);CHKERRQ(ierr); 430872b8c272SStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 430972b8c272SStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 431072b8c272SStefano Zampini } 4311019a44ceSStefano Zampini 431206656605SStefano Zampini /* compute other basis functions for non-symmetric problems */ 43133301b35fSStefano Zampini if (!pcbddc->symmetric_primal) { 4314ffd830a3SStefano Zampini Mat B_V=NULL,B_C=NULL; 4315ffd830a3SStefano Zampini PetscScalar *marray; 431606656605SStefano Zampini 431706656605SStefano Zampini if (n_constraints) { 4318ffd830a3SStefano Zampini Mat S_CCT,C_CRT; 431906656605SStefano Zampini 4320abc8f43dSstefano_zampini ierr = MatTranspose(C_CR,MAT_INITIAL_MATRIX,&C_CRT);CHKERRQ(ierr); 432106656605SStefano Zampini ierr = MatTranspose(S_CC,MAT_INITIAL_MATRIX,&S_CCT);CHKERRQ(ierr); 4322ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_CCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_C);CHKERRQ(ierr); 432316f15bc4SStefano Zampini ierr = MatDestroy(&S_CCT);CHKERRQ(ierr); 432406656605SStefano Zampini if (n_vertices) { 4325ffd830a3SStefano Zampini Mat S_VCT; 432606656605SStefano Zampini 432706656605SStefano Zampini ierr = MatTranspose(S_VC,MAT_INITIAL_MATRIX,&S_VCT);CHKERRQ(ierr); 4328ffd830a3SStefano Zampini ierr = MatMatMult(C_CRT,S_VCT,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&B_V);CHKERRQ(ierr); 432916f15bc4SStefano Zampini ierr = MatDestroy(&S_VCT);CHKERRQ(ierr); 433006656605SStefano Zampini } 4331ffd830a3SStefano Zampini ierr = MatDestroy(&C_CRT);CHKERRQ(ierr); 43325b782168SStefano Zampini } else { 43335b782168SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,n_R,n_vertices,NULL,&B_V);CHKERRQ(ierr); 433406656605SStefano Zampini } 433516f15bc4SStefano Zampini if (n_vertices && n_R) { 4336ffd830a3SStefano Zampini PetscScalar *av,*marray; 4337ffd830a3SStefano Zampini const PetscInt *xadj,*adjncy; 4338ffd830a3SStefano Zampini PetscInt n; 4339ffd830a3SStefano Zampini PetscBool flg_row; 434006656605SStefano Zampini 4341ffd830a3SStefano Zampini /* B_V = B_V - A_VR^T */ 4342af25d912SStefano Zampini ierr = MatConvert(A_VR,MATSEQAIJ,MAT_INPLACE_MATRIX,&A_VR);CHKERRQ(ierr); 4343ffd830a3SStefano Zampini ierr = MatGetRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4344ffd830a3SStefano Zampini ierr = MatSeqAIJGetArray(A_VR,&av);CHKERRQ(ierr); 4345ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4346ffd830a3SStefano Zampini for (i=0;i<n;i++) { 4347ffd830a3SStefano Zampini PetscInt j; 4348ffd830a3SStefano Zampini for (j=xadj[i];j<xadj[i+1];j++) marray[i*n_R + adjncy[j]] -= av[j]; 4349ffd830a3SStefano Zampini } 4350ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4351ffd830a3SStefano Zampini ierr = MatRestoreRowIJ(A_VR,0,PETSC_FALSE,PETSC_FALSE,&n,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 4352ffd830a3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 435306656605SStefano Zampini } 435406656605SStefano Zampini 4355ffd830a3SStefano Zampini /* currently there's no support for MatTransposeMatSolve(F,B,X) */ 4356abc8f43dSstefano_zampini if (n_vertices) { 4357ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_V,&marray);CHKERRQ(ierr); 4358ffd830a3SStefano Zampini for (i=0;i<n_vertices;i++) { 4359ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+i*n_R);CHKERRQ(ierr); 4360ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 436106656605SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 436206656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 436306656605SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 436406656605SStefano Zampini } 4365ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_V,&marray);CHKERRQ(ierr); 4366abc8f43dSstefano_zampini } 43675b782168SStefano Zampini if (B_C) { 4368ffd830a3SStefano Zampini ierr = MatDenseGetArray(B_C,&marray);CHKERRQ(ierr); 4369ffd830a3SStefano Zampini for (i=n_vertices;i<n_constraints+n_vertices;i++) { 4370ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,marray+(i-n_vertices)*n_R);CHKERRQ(ierr); 4371ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec2_R,work+i*n_R);CHKERRQ(ierr); 4372ffd830a3SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 4373ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 4374ffd830a3SStefano Zampini ierr = VecResetArray(pcbddc->vec2_R);CHKERRQ(ierr); 437506656605SStefano Zampini } 4376ffd830a3SStefano Zampini ierr = MatDenseRestoreArray(B_C,&marray);CHKERRQ(ierr); 43775b782168SStefano Zampini } 437806656605SStefano Zampini /* coarse basis functions */ 437906656605SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 438006656605SStefano Zampini PetscScalar *y; 438106656605SStefano Zampini 4382ffd830a3SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_R,work+i*n_R);CHKERRQ(ierr); 438306656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 438406656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_B,y+n_B*i);CHKERRQ(ierr); 438506656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 438606656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 438706656605SStefano Zampini if (i<n_vertices) { 438806656605SStefano Zampini y[n_B*i+idx_V_B[i]] = 1.0; 438906656605SStefano Zampini } 439006656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_B,&y);CHKERRQ(ierr); 439106656605SStefano Zampini ierr = VecResetArray(pcis->vec1_B);CHKERRQ(ierr); 439206656605SStefano Zampini 439306656605SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 439406656605SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 439506656605SStefano Zampini ierr = VecPlaceArray(pcis->vec1_D,y+n_D*i);CHKERRQ(ierr); 439606656605SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 439706656605SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,pcis->vec1_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 439806656605SStefano Zampini ierr = VecResetArray(pcis->vec1_D);CHKERRQ(ierr); 439906656605SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_psi_D,&y);CHKERRQ(ierr); 440006656605SStefano Zampini } 440106656605SStefano Zampini ierr = VecResetArray(pcbddc->vec1_R);CHKERRQ(ierr); 440206656605SStefano Zampini } 4403ffd830a3SStefano Zampini ierr = MatDestroy(&B_V);CHKERRQ(ierr); 4404ffd830a3SStefano Zampini ierr = MatDestroy(&B_C);CHKERRQ(ierr); 440506656605SStefano Zampini } 4406a6e023c1Sstefano_zampini 4407d62866d3SStefano Zampini /* free memory */ 440888ebb749SStefano Zampini ierr = PetscFree(idx_V_B);CHKERRQ(ierr); 440906656605SStefano Zampini ierr = MatDestroy(&S_VV);CHKERRQ(ierr); 441006656605SStefano Zampini ierr = MatDestroy(&S_CV);CHKERRQ(ierr); 441106656605SStefano Zampini ierr = MatDestroy(&S_VC);CHKERRQ(ierr); 441206656605SStefano Zampini ierr = MatDestroy(&S_CC);CHKERRQ(ierr); 4413d62866d3SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 4414d62866d3SStefano Zampini if (n_vertices) { 4415d62866d3SStefano Zampini ierr = MatDestroy(&A_VR);CHKERRQ(ierr); 4416d62866d3SStefano Zampini } 4417d62866d3SStefano Zampini if (n_constraints) { 4418d62866d3SStefano Zampini ierr = MatDestroy(&C_CR);CHKERRQ(ierr); 4419d62866d3SStefano Zampini } 442088ebb749SStefano Zampini /* Checking coarse_sub_mat and coarse basis functios */ 442188ebb749SStefano Zampini /* Symmetric case : It should be \Phi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 442288ebb749SStefano Zampini /* Non-symmetric case : It should be \Psi^{(j)^T} A^{(j)} \Phi^{(j)}=coarse_sub_mat */ 4423d12edf2fSStefano Zampini if (pcbddc->dbg_flag) { 442488ebb749SStefano Zampini Mat coarse_sub_mat; 442525084f0cSStefano Zampini Mat AUXMAT,TM1,TM2,TM3,TM4; 442688ebb749SStefano Zampini Mat coarse_phi_D,coarse_phi_B; 442788ebb749SStefano Zampini Mat coarse_psi_D,coarse_psi_B; 442888ebb749SStefano Zampini Mat A_II,A_BB,A_IB,A_BI; 44298bec7fa6SStefano Zampini Mat C_B,CPHI; 44308bec7fa6SStefano Zampini IS is_dummy; 44318bec7fa6SStefano Zampini Vec mones; 443288ebb749SStefano Zampini MatType checkmattype=MATSEQAIJ; 443388ebb749SStefano Zampini PetscReal real_value; 443488ebb749SStefano Zampini 4435a3df083aSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 4436a3df083aSStefano Zampini Mat A; 4437a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,NULL,NULL,&A);CHKERRQ(ierr); 44387dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 44397dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_I_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 44407dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_I_local,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 44417dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,pcis->is_B_local,pcis->is_B_local,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4442a3df083aSStefano Zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 4443a3df083aSStefano Zampini } else { 444488ebb749SStefano Zampini ierr = MatConvert(pcis->A_II,checkmattype,MAT_INITIAL_MATRIX,&A_II);CHKERRQ(ierr); 444588ebb749SStefano Zampini ierr = MatConvert(pcis->A_IB,checkmattype,MAT_INITIAL_MATRIX,&A_IB);CHKERRQ(ierr); 444688ebb749SStefano Zampini ierr = MatConvert(pcis->A_BI,checkmattype,MAT_INITIAL_MATRIX,&A_BI);CHKERRQ(ierr); 444788ebb749SStefano Zampini ierr = MatConvert(pcis->A_BB,checkmattype,MAT_INITIAL_MATRIX,&A_BB);CHKERRQ(ierr); 4448a3df083aSStefano Zampini } 444988ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_D);CHKERRQ(ierr); 445088ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_phi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_phi_B);CHKERRQ(ierr); 4451ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 445288ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_D,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_D);CHKERRQ(ierr); 445388ebb749SStefano Zampini ierr = MatConvert(pcbddc->coarse_psi_B,checkmattype,MAT_INITIAL_MATRIX,&coarse_psi_B);CHKERRQ(ierr); 445488ebb749SStefano Zampini } 445588ebb749SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,coarse_submat_vals,&coarse_sub_mat);CHKERRQ(ierr); 445688ebb749SStefano Zampini 445725084f0cSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 44583301b35fSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse sub mat computation (symmetric %d)\n",pcbddc->symmetric_primal);CHKERRQ(ierr); 445925084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4460ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 446188ebb749SStefano Zampini ierr = MatMatMult(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 446288ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 446388ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 446488ebb749SStefano Zampini ierr = MatMatMult(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 446588ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 446688ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 446788ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 446888ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 446988ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 447088ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 447188ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_psi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 447288ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 447388ebb749SStefano Zampini } else { 447488ebb749SStefano Zampini ierr = MatPtAP(A_II,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&TM1);CHKERRQ(ierr); 447588ebb749SStefano Zampini ierr = MatPtAP(A_BB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&TM2);CHKERRQ(ierr); 447688ebb749SStefano Zampini ierr = MatMatMult(A_IB,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 447788ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_D,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM3);CHKERRQ(ierr); 447888ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 447988ebb749SStefano Zampini ierr = MatMatMult(A_BI,coarse_phi_D,MAT_INITIAL_MATRIX,1.0,&AUXMAT);CHKERRQ(ierr); 448088ebb749SStefano Zampini ierr = MatTransposeMatMult(coarse_phi_B,AUXMAT,MAT_INITIAL_MATRIX,1.0,&TM4);CHKERRQ(ierr); 448188ebb749SStefano Zampini ierr = MatDestroy(&AUXMAT);CHKERRQ(ierr); 448288ebb749SStefano Zampini } 448388ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM2,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 448488ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM3,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 448588ebb749SStefano Zampini ierr = MatAXPY(TM1,one,TM4,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 4486511c6705SHong Zhang ierr = MatConvert(TM1,MATSEQDENSE,MAT_INPLACE_MATRIX,&TM1);CHKERRQ(ierr); 44874f1b2e48SStefano Zampini if (pcbddc->benign_n) { 4488fc227af8SStefano Zampini Mat B0_B,B0_BPHI; 4489d12edf2fSStefano Zampini PetscScalar *data,*data2; 44904f1b2e48SStefano Zampini PetscInt j; 4491d12edf2fSStefano Zampini 44924f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 44937dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 4494d12edf2fSStefano Zampini ierr = MatMatMult(B0_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&B0_BPHI);CHKERRQ(ierr); 449586c38910SStefano Zampini ierr = MatConvert(B0_BPHI,MATSEQDENSE,MAT_INPLACE_MATRIX,&B0_BPHI);CHKERRQ(ierr); 4496d12edf2fSStefano Zampini ierr = MatDenseGetArray(TM1,&data);CHKERRQ(ierr); 4497d12edf2fSStefano Zampini ierr = MatDenseGetArray(B0_BPHI,&data2);CHKERRQ(ierr); 44984f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) { 44994f1b2e48SStefano Zampini PetscInt primal_idx = pcbddc->local_primal_size - pcbddc->benign_n + j; 4500d12edf2fSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 45014f1b2e48SStefano Zampini data[primal_idx*pcbddc->local_primal_size+i] += data2[i*pcbddc->benign_n+j]; 45024f1b2e48SStefano Zampini data[i*pcbddc->local_primal_size+primal_idx] += data2[i*pcbddc->benign_n+j]; 45034f1b2e48SStefano Zampini } 4504d12edf2fSStefano Zampini } 4505d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(TM1,&data);CHKERRQ(ierr); 4506d12edf2fSStefano Zampini ierr = MatDenseRestoreArray(B0_BPHI,&data2);CHKERRQ(ierr); 4507d12edf2fSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 4508d12edf2fSStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 4509d12edf2fSStefano Zampini ierr = MatDestroy(&B0_BPHI);CHKERRQ(ierr); 4510d12edf2fSStefano Zampini } 4511d12edf2fSStefano Zampini #if 0 4512d12edf2fSStefano Zampini { 4513d12edf2fSStefano Zampini PetscViewer viewer; 4514d12edf2fSStefano Zampini char filename[256]; 4515ffd830a3SStefano Zampini sprintf(filename,"details_local_coarse_mat%d_level%d.m",PetscGlobalRank,pcbddc->current_level); 4516d12edf2fSStefano Zampini ierr = PetscViewerASCIIOpen(PETSC_COMM_SELF,filename,&viewer);CHKERRQ(ierr); 4517a7414863SStefano Zampini ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 4518ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)coarse_sub_mat,"computed");CHKERRQ(ierr); 4519ffd830a3SStefano Zampini ierr = MatView(coarse_sub_mat,viewer);CHKERRQ(ierr); 4520ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)TM1,"projected");CHKERRQ(ierr); 4521d12edf2fSStefano Zampini ierr = MatView(TM1,viewer);CHKERRQ(ierr); 4522a7414863SStefano Zampini if (pcbddc->coarse_phi_B) { 4523ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_B,"phi_B");CHKERRQ(ierr); 4524ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_B,viewer);CHKERRQ(ierr); 452572b8c272SStefano Zampini } 4526ffd830a3SStefano Zampini if (pcbddc->coarse_phi_D) { 4527ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_phi_D,"phi_D");CHKERRQ(ierr); 4528ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_phi_D,viewer);CHKERRQ(ierr); 4529ffd830a3SStefano Zampini } 4530ffd830a3SStefano Zampini if (pcbddc->coarse_psi_B) { 4531ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_B,"psi_B");CHKERRQ(ierr); 4532ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_B,viewer);CHKERRQ(ierr); 4533ffd830a3SStefano Zampini } 453472b8c272SStefano Zampini if (pcbddc->coarse_psi_D) { 4535ffd830a3SStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->coarse_psi_D,"psi_D");CHKERRQ(ierr); 4536ffd830a3SStefano Zampini ierr = MatView(pcbddc->coarse_psi_D,viewer);CHKERRQ(ierr); 4537ffd830a3SStefano Zampini } 4538fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->local_mat,"A");CHKERRQ(ierr); 4539fb6280fbSStefano Zampini ierr = MatView(pcbddc->local_mat,viewer);CHKERRQ(ierr); 4540fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->ConstraintMatrix,"C");CHKERRQ(ierr); 4541fb6280fbSStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,viewer);CHKERRQ(ierr); 4542fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_I_local,"I");CHKERRQ(ierr); 4543fb6280fbSStefano Zampini ierr = ISView(pcis->is_I_local,viewer);CHKERRQ(ierr); 4544fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcis->is_B_local,"B");CHKERRQ(ierr); 4545fb6280fbSStefano Zampini ierr = ISView(pcis->is_B_local,viewer);CHKERRQ(ierr); 4546fb6280fbSStefano Zampini ierr = PetscObjectSetName((PetscObject)pcbddc->is_R_local,"R");CHKERRQ(ierr); 4547fb6280fbSStefano Zampini ierr = ISView(pcbddc->is_R_local,viewer);CHKERRQ(ierr); 4548d12edf2fSStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 4549d12edf2fSStefano Zampini } 4550d12edf2fSStefano Zampini #endif 455181d9aea3SBarry Smith ierr = MatAXPY(TM1,m_one,coarse_sub_mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr); 45528bec7fa6SStefano Zampini ierr = MatNorm(TM1,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 45531575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 455406656605SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d matrix error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 45558bec7fa6SStefano Zampini 45568bec7fa6SStefano Zampini /* check constraints */ 4557a00504b5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->local_primal_size-pcbddc->benign_n,0,1,&is_dummy);CHKERRQ(ierr); 45587dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->ConstraintMatrix,is_dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&C_B);CHKERRQ(ierr); 45594f1b2e48SStefano Zampini if (!pcbddc->benign_n) { /* TODO: add benign case */ 45608bec7fa6SStefano Zampini ierr = MatMatMult(C_B,coarse_phi_B,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4561a00504b5SStefano Zampini } else { 4562a00504b5SStefano Zampini PetscScalar *data; 4563a00504b5SStefano Zampini Mat tmat; 4564a00504b5SStefano Zampini ierr = MatDenseGetArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4565a00504b5SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcis->n_B,pcbddc->local_primal_size-pcbddc->benign_n,data,&tmat);CHKERRQ(ierr); 4566a00504b5SStefano Zampini ierr = MatDenseRestoreArray(pcbddc->coarse_phi_B,&data);CHKERRQ(ierr); 4567a00504b5SStefano Zampini ierr = MatMatMult(C_B,tmat,MAT_INITIAL_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4568a00504b5SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 4569a00504b5SStefano Zampini } 45708bec7fa6SStefano Zampini ierr = MatCreateVecs(CPHI,&mones,NULL);CHKERRQ(ierr); 45718bec7fa6SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 45728bec7fa6SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 45738bec7fa6SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4574bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d phi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 4575ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 4576bdae7319SStefano Zampini ierr = MatMatMult(C_B,coarse_psi_B,MAT_REUSE_MATRIX,1.0,&CPHI);CHKERRQ(ierr); 4577bdae7319SStefano Zampini ierr = VecSet(mones,-1.0);CHKERRQ(ierr); 4578bdae7319SStefano Zampini ierr = MatDiagonalSet(CPHI,mones,ADD_VALUES);CHKERRQ(ierr); 4579bdae7319SStefano Zampini ierr = MatNorm(CPHI,NORM_FROBENIUS,&real_value);CHKERRQ(ierr); 4580bdae7319SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d psi constraints error % 1.14e\n",PetscGlobalRank,real_value);CHKERRQ(ierr); 458188ebb749SStefano Zampini } 45828bec7fa6SStefano Zampini ierr = MatDestroy(&C_B);CHKERRQ(ierr); 45838bec7fa6SStefano Zampini ierr = MatDestroy(&CPHI);CHKERRQ(ierr); 45848bec7fa6SStefano Zampini ierr = ISDestroy(&is_dummy);CHKERRQ(ierr); 45858bec7fa6SStefano Zampini ierr = VecDestroy(&mones);CHKERRQ(ierr); 458625084f0cSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 458788ebb749SStefano Zampini ierr = MatDestroy(&A_II);CHKERRQ(ierr); 458888ebb749SStefano Zampini ierr = MatDestroy(&A_BB);CHKERRQ(ierr); 458988ebb749SStefano Zampini ierr = MatDestroy(&A_IB);CHKERRQ(ierr); 459088ebb749SStefano Zampini ierr = MatDestroy(&A_BI);CHKERRQ(ierr); 459188ebb749SStefano Zampini ierr = MatDestroy(&TM1);CHKERRQ(ierr); 459288ebb749SStefano Zampini ierr = MatDestroy(&TM2);CHKERRQ(ierr); 459388ebb749SStefano Zampini ierr = MatDestroy(&TM3);CHKERRQ(ierr); 459488ebb749SStefano Zampini ierr = MatDestroy(&TM4);CHKERRQ(ierr); 459588ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_D);CHKERRQ(ierr); 459688ebb749SStefano Zampini ierr = MatDestroy(&coarse_phi_B);CHKERRQ(ierr); 4597ffd830a3SStefano Zampini if (!pcbddc->symmetric_primal) { 459888ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_D);CHKERRQ(ierr); 459988ebb749SStefano Zampini ierr = MatDestroy(&coarse_psi_B);CHKERRQ(ierr); 460088ebb749SStefano Zampini } 460188ebb749SStefano Zampini ierr = MatDestroy(&coarse_sub_mat);CHKERRQ(ierr); 460288ebb749SStefano Zampini } 46038629588bSStefano Zampini /* get back data */ 46048629588bSStefano Zampini *coarse_submat_vals_n = coarse_submat_vals; 460588ebb749SStefano Zampini PetscFunctionReturn(0); 460688ebb749SStefano Zampini } 460788ebb749SStefano Zampini 46087dae84e0SHong Zhang PetscErrorCode MatCreateSubMatrixUnsorted(Mat A, IS isrow, IS iscol, Mat* B) 4609aa0d41d4SStefano Zampini { 4610d65f70fdSStefano Zampini Mat *work_mat; 4611d65f70fdSStefano Zampini IS isrow_s,iscol_s; 4612d65f70fdSStefano Zampini PetscBool rsorted,csorted; 4613c43ebad9SStefano Zampini PetscInt rsize,*idxs_perm_r=NULL,csize,*idxs_perm_c=NULL; 4614aa0d41d4SStefano Zampini PetscErrorCode ierr; 4615aa0d41d4SStefano Zampini 4616aa0d41d4SStefano Zampini PetscFunctionBegin; 4617d65f70fdSStefano Zampini ierr = ISSorted(isrow,&rsorted);CHKERRQ(ierr); 4618d65f70fdSStefano Zampini ierr = ISSorted(iscol,&csorted);CHKERRQ(ierr); 4619d65f70fdSStefano Zampini ierr = ISGetLocalSize(isrow,&rsize);CHKERRQ(ierr); 4620d65f70fdSStefano Zampini ierr = ISGetLocalSize(iscol,&csize);CHKERRQ(ierr); 4621aa0d41d4SStefano Zampini 4622d65f70fdSStefano Zampini if (!rsorted) { 4623906d46d4SStefano Zampini const PetscInt *idxs; 4624906d46d4SStefano Zampini PetscInt *idxs_sorted,i; 4625aa0d41d4SStefano Zampini 4626d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_perm_r);CHKERRQ(ierr); 4627d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_sorted);CHKERRQ(ierr); 4628d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4629d65f70fdSStefano Zampini idxs_perm_r[i] = i; 4630aa0d41d4SStefano Zampini } 4631d65f70fdSStefano Zampini ierr = ISGetIndices(isrow,&idxs);CHKERRQ(ierr); 4632d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(rsize,idxs,idxs_perm_r);CHKERRQ(ierr); 4633d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4634d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_r[i]]; 4635aa0d41d4SStefano Zampini } 4636d65f70fdSStefano Zampini ierr = ISRestoreIndices(isrow,&idxs);CHKERRQ(ierr); 4637d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_sorted,PETSC_OWN_POINTER,&isrow_s);CHKERRQ(ierr); 4638d65f70fdSStefano Zampini } else { 4639d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow);CHKERRQ(ierr); 4640d65f70fdSStefano Zampini isrow_s = isrow; 4641aa0d41d4SStefano Zampini } 4642906d46d4SStefano Zampini 4643d65f70fdSStefano Zampini if (!csorted) { 4644d65f70fdSStefano Zampini if (isrow == iscol) { 4645d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)isrow_s);CHKERRQ(ierr); 4646d65f70fdSStefano Zampini iscol_s = isrow_s; 4647d65f70fdSStefano Zampini } else { 4648d65f70fdSStefano Zampini const PetscInt *idxs; 4649d65f70fdSStefano Zampini PetscInt *idxs_sorted,i; 4650906d46d4SStefano Zampini 4651d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_perm_c);CHKERRQ(ierr); 4652d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_sorted);CHKERRQ(ierr); 4653d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4654d65f70fdSStefano Zampini idxs_perm_c[i] = i; 4655d65f70fdSStefano Zampini } 4656d65f70fdSStefano Zampini ierr = ISGetIndices(iscol,&idxs);CHKERRQ(ierr); 4657d65f70fdSStefano Zampini ierr = PetscSortIntWithPermutation(csize,idxs,idxs_perm_c);CHKERRQ(ierr); 4658d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4659d65f70fdSStefano Zampini idxs_sorted[i] = idxs[idxs_perm_c[i]]; 4660d65f70fdSStefano Zampini } 4661d65f70fdSStefano Zampini ierr = ISRestoreIndices(iscol,&idxs);CHKERRQ(ierr); 4662d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_sorted,PETSC_OWN_POINTER,&iscol_s);CHKERRQ(ierr); 4663d65f70fdSStefano Zampini } 4664d65f70fdSStefano Zampini } else { 4665d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)iscol);CHKERRQ(ierr); 4666d65f70fdSStefano Zampini iscol_s = iscol; 4667d65f70fdSStefano Zampini } 4668d65f70fdSStefano Zampini 46697dae84e0SHong Zhang ierr = MatCreateSubMatrices(A,1,&isrow_s,&iscol_s,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4670d65f70fdSStefano Zampini 4671d65f70fdSStefano Zampini if (!rsorted || !csorted) { 4672906d46d4SStefano Zampini Mat new_mat; 4673d65f70fdSStefano Zampini IS is_perm_r,is_perm_c; 4674906d46d4SStefano Zampini 4675d65f70fdSStefano Zampini if (!rsorted) { 4676d65f70fdSStefano Zampini PetscInt *idxs_r,i; 4677d65f70fdSStefano Zampini ierr = PetscMalloc1(rsize,&idxs_r);CHKERRQ(ierr); 4678d65f70fdSStefano Zampini for (i=0;i<rsize;i++) { 4679d65f70fdSStefano Zampini idxs_r[idxs_perm_r[i]] = i; 4680906d46d4SStefano Zampini } 4681d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_r);CHKERRQ(ierr); 4682d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,rsize,idxs_r,PETSC_OWN_POINTER,&is_perm_r);CHKERRQ(ierr); 4683d65f70fdSStefano Zampini } else { 4684d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,rsize,0,1,&is_perm_r);CHKERRQ(ierr); 4685906d46d4SStefano Zampini } 4686d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_r);CHKERRQ(ierr); 4687d65f70fdSStefano Zampini 4688d65f70fdSStefano Zampini if (!csorted) { 4689d65f70fdSStefano Zampini if (isrow_s == iscol_s) { 4690d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)is_perm_r);CHKERRQ(ierr); 4691d65f70fdSStefano Zampini is_perm_c = is_perm_r; 4692d65f70fdSStefano Zampini } else { 4693d65f70fdSStefano Zampini PetscInt *idxs_c,i; 4694f913dca9SStefano Zampini if (!idxs_perm_c) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Permutation array not present"); 4695d65f70fdSStefano Zampini ierr = PetscMalloc1(csize,&idxs_c);CHKERRQ(ierr); 4696d65f70fdSStefano Zampini for (i=0;i<csize;i++) { 4697d65f70fdSStefano Zampini idxs_c[idxs_perm_c[i]] = i; 4698d65f70fdSStefano Zampini } 4699d65f70fdSStefano Zampini ierr = PetscFree(idxs_perm_c);CHKERRQ(ierr); 4700d65f70fdSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,csize,idxs_c,PETSC_OWN_POINTER,&is_perm_c);CHKERRQ(ierr); 4701d65f70fdSStefano Zampini } 4702d65f70fdSStefano Zampini } else { 4703d65f70fdSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,csize,0,1,&is_perm_c);CHKERRQ(ierr); 4704d65f70fdSStefano Zampini } 4705d65f70fdSStefano Zampini ierr = ISSetPermutation(is_perm_c);CHKERRQ(ierr); 4706d65f70fdSStefano Zampini 4707d65f70fdSStefano Zampini ierr = MatPermute(work_mat[0],is_perm_r,is_perm_c,&new_mat);CHKERRQ(ierr); 4708d65f70fdSStefano Zampini ierr = MatDestroy(&work_mat[0]);CHKERRQ(ierr); 4709d65f70fdSStefano Zampini work_mat[0] = new_mat; 4710d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_r);CHKERRQ(ierr); 4711d65f70fdSStefano Zampini ierr = ISDestroy(&is_perm_c);CHKERRQ(ierr); 4712d65f70fdSStefano Zampini } 4713d65f70fdSStefano Zampini 4714d65f70fdSStefano Zampini ierr = PetscObjectReference((PetscObject)work_mat[0]);CHKERRQ(ierr); 4715d65f70fdSStefano Zampini *B = work_mat[0]; 4716d65f70fdSStefano Zampini ierr = MatDestroyMatrices(1,&work_mat);CHKERRQ(ierr); 4717d65f70fdSStefano Zampini ierr = ISDestroy(&isrow_s);CHKERRQ(ierr); 4718d65f70fdSStefano Zampini ierr = ISDestroy(&iscol_s);CHKERRQ(ierr); 4719d65f70fdSStefano Zampini PetscFunctionReturn(0); 4720d65f70fdSStefano Zampini } 4721d65f70fdSStefano Zampini 47225e8657edSStefano Zampini PetscErrorCode PCBDDCComputeLocalMatrix(PC pc, Mat ChangeOfBasisMatrix) 4723aa0d41d4SStefano Zampini { 4724aa0d41d4SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 47255e8657edSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4726022d8d2bSstefano_zampini Mat new_mat,lA; 47275e8657edSStefano Zampini IS is_local,is_global; 4728d65f70fdSStefano Zampini PetscInt local_size; 4729d65f70fdSStefano Zampini PetscBool isseqaij; 4730aa0d41d4SStefano Zampini PetscErrorCode ierr; 4731aa0d41d4SStefano Zampini 4732aa0d41d4SStefano Zampini PetscFunctionBegin; 4733aa0d41d4SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 47345e8657edSStefano Zampini ierr = MatGetSize(matis->A,&local_size,NULL);CHKERRQ(ierr); 47355e8657edSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)matis->A),local_size,0,1,&is_local);CHKERRQ(ierr); 4736b087196eSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pc->pmat->rmap->mapping,is_local,&is_global);CHKERRQ(ierr); 4737aa0d41d4SStefano Zampini ierr = ISDestroy(&is_local);CHKERRQ(ierr); 47387dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(ChangeOfBasisMatrix,is_global,is_global,&new_mat);CHKERRQ(ierr); 4739aa0d41d4SStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 4740906d46d4SStefano Zampini 4741906d46d4SStefano Zampini /* check */ 4742906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 4743906d46d4SStefano Zampini Vec x,x_change; 4744906d46d4SStefano Zampini PetscReal error; 4745906d46d4SStefano Zampini 47465e8657edSStefano Zampini ierr = MatCreateVecs(ChangeOfBasisMatrix,&x,&x_change);CHKERRQ(ierr); 4747906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 47485e8657edSStefano Zampini ierr = MatMult(ChangeOfBasisMatrix,x,x_change);CHKERRQ(ierr); 4749e176bc59SStefano Zampini ierr = VecScatterBegin(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4750e176bc59SStefano Zampini ierr = VecScatterEnd(matis->cctx,x,matis->x,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 4751d65f70fdSStefano Zampini ierr = MatMult(new_mat,matis->x,matis->y);CHKERRQ(ierr); 475288428137SStefano Zampini if (!pcbddc->change_interior) { 475388428137SStefano Zampini const PetscScalar *x,*y,*v; 475488428137SStefano Zampini PetscReal lerror = 0.; 475588428137SStefano Zampini PetscInt i; 475688428137SStefano Zampini 475788428137SStefano Zampini ierr = VecGetArrayRead(matis->x,&x);CHKERRQ(ierr); 475888428137SStefano Zampini ierr = VecGetArrayRead(matis->y,&y);CHKERRQ(ierr); 475988428137SStefano Zampini ierr = VecGetArrayRead(matis->counter,&v);CHKERRQ(ierr); 476088428137SStefano Zampini for (i=0;i<local_size;i++) 476188428137SStefano Zampini if (PetscRealPart(v[i]) < 1.5 && PetscAbsScalar(x[i]-y[i]) > lerror) 476288428137SStefano Zampini lerror = PetscAbsScalar(x[i]-y[i]); 476388428137SStefano Zampini ierr = VecRestoreArrayRead(matis->x,&x);CHKERRQ(ierr); 476488428137SStefano Zampini ierr = VecRestoreArrayRead(matis->y,&y);CHKERRQ(ierr); 476588428137SStefano Zampini ierr = VecRestoreArrayRead(matis->counter,&v);CHKERRQ(ierr); 476688428137SStefano Zampini ierr = MPIU_Allreduce(&lerror,&error,1,MPIU_REAL,MPI_MAX,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 4767637e8532SStefano Zampini if (error > PETSC_SMALL) { 4768637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4769637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on I: %1.6e\n",error); 4770637e8532SStefano Zampini } else { 4771637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on I: %1.6e\n",error); 4772637e8532SStefano Zampini } 4773637e8532SStefano Zampini } 477488428137SStefano Zampini } 4775e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4776e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,matis->y,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 4777906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 4778906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 4779637e8532SStefano Zampini if (error > PETSC_SMALL) { 4780637e8532SStefano Zampini if (!pcbddc->user_ChangeOfBasisMatrix || pcbddc->current_level) { 4781637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 4782637e8532SStefano Zampini } else { 4783637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_USER,"Error global vs local change on N: %1.6e\n",error); 4784637e8532SStefano Zampini } 4785637e8532SStefano Zampini } 4786906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 4787906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 4788906d46d4SStefano Zampini } 4789906d46d4SStefano Zampini 4790022d8d2bSstefano_zampini /* lA is present if we are setting up an inner BDDC for a saddle point FETI-DP */ 4791022d8d2bSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject*)&lA);CHKERRQ(ierr); 4792022d8d2bSstefano_zampini 479322d5777bSStefano Zampini /* TODO: HOW TO WORK WITH BAIJ and SBAIJ and SEQDENSE? */ 47949b28b3ffSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)matis->A,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 479522d5777bSStefano Zampini if (isseqaij) { 4796a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4797a00504b5SStefano Zampini ierr = MatPtAP(matis->A,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 4798022d8d2bSstefano_zampini if (lA) { 4799022d8d2bSstefano_zampini Mat work; 4800022d8d2bSstefano_zampini ierr = MatPtAP(lA,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4801022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4802022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4803022d8d2bSstefano_zampini } 4804aa0d41d4SStefano Zampini } else { 4805a00504b5SStefano Zampini Mat work_mat; 48061cf9b237SStefano Zampini 4807a00504b5SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 4808aa0d41d4SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4809a00504b5SStefano Zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&pcbddc->local_mat);CHKERRQ(ierr); 48101d82a3b6SStefano Zampini ierr = MatDestroy(&work_mat);CHKERRQ(ierr); 4811022d8d2bSstefano_zampini if (lA) { 4812022d8d2bSstefano_zampini Mat work; 4813022d8d2bSstefano_zampini ierr = MatConvert(lA,MATSEQAIJ,MAT_INITIAL_MATRIX,&work_mat);CHKERRQ(ierr); 4814022d8d2bSstefano_zampini ierr = MatPtAP(work_mat,new_mat,MAT_INITIAL_MATRIX,2.0,&work);CHKERRQ(ierr); 4815022d8d2bSstefano_zampini ierr = PetscObjectCompose((PetscObject)pc,"__KSPFETIDP_lA" ,(PetscObject)work);CHKERRQ(ierr); 4816022d8d2bSstefano_zampini ierr = MatDestroy(&work);CHKERRQ(ierr); 4817022d8d2bSstefano_zampini } 4818aa0d41d4SStefano Zampini } 48193301b35fSStefano Zampini if (matis->A->symmetric_set) { 48203301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_SYMMETRIC,matis->A->symmetric);CHKERRQ(ierr); 4821e496cd5dSStefano Zampini #if !defined(PETSC_USE_COMPLEX) 48223301b35fSStefano Zampini ierr = MatSetOption(pcbddc->local_mat,MAT_HERMITIAN,matis->A->symmetric);CHKERRQ(ierr); 4823e496cd5dSStefano Zampini #endif 48243301b35fSStefano Zampini } 4825d65f70fdSStefano Zampini ierr = MatDestroy(&new_mat);CHKERRQ(ierr); 4826aa0d41d4SStefano Zampini PetscFunctionReturn(0); 4827aa0d41d4SStefano Zampini } 4828aa0d41d4SStefano Zampini 48298ce42a96SStefano Zampini PetscErrorCode PCBDDCSetUpLocalScatters(PC pc) 4830a64d13efSStefano Zampini { 4831a64d13efSStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 4832a64d13efSStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 4833d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 483453892102SStefano Zampini PetscInt *idx_R_local=NULL; 48353a50541eSStefano Zampini PetscInt n_vertices,i,j,n_R,n_D,n_B; 48363a50541eSStefano Zampini PetscInt vbs,bs; 48376816873aSStefano Zampini PetscBT bitmask=NULL; 4838a64d13efSStefano Zampini PetscErrorCode ierr; 4839a64d13efSStefano Zampini 4840a64d13efSStefano Zampini PetscFunctionBegin; 4841b23d619eSStefano Zampini /* 4842b23d619eSStefano Zampini No need to setup local scatters if 4843b23d619eSStefano Zampini - primal space is unchanged 4844b23d619eSStefano Zampini AND 4845b23d619eSStefano Zampini - we actually have locally some primal dofs (could not be true in multilevel or for isolated subdomains) 4846b23d619eSStefano Zampini AND 4847b23d619eSStefano Zampini - we are not in debugging mode (this is needed since there are Synchronized prints at the end of the subroutine 4848b23d619eSStefano Zampini */ 4849b23d619eSStefano Zampini if (!pcbddc->new_primal_space_local && pcbddc->local_primal_size && !pcbddc->dbg_flag) { 4850f4ddd8eeSStefano Zampini PetscFunctionReturn(0); 4851f4ddd8eeSStefano Zampini } 4852f4ddd8eeSStefano Zampini /* destroy old objects */ 4853f4ddd8eeSStefano Zampini ierr = ISDestroy(&pcbddc->is_R_local);CHKERRQ(ierr); 4854f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_B);CHKERRQ(ierr); 4855f4ddd8eeSStefano Zampini ierr = VecScatterDestroy(&pcbddc->R_to_D);CHKERRQ(ierr); 4856a64d13efSStefano Zampini /* Set Non-overlapping dimensions */ 4857b371cd4fSStefano Zampini n_B = pcis->n_B; 4858b371cd4fSStefano Zampini n_D = pcis->n - n_B; 4859b371cd4fSStefano Zampini n_vertices = pcbddc->n_vertices; 48603a50541eSStefano Zampini 4861a64d13efSStefano Zampini /* Dohrmann's notation: dofs splitted in R (Remaining: all dofs but the vertices) and V (Vertices) */ 48626816873aSStefano Zampini 486353892102SStefano Zampini /* create auxiliary bitmask and allocate workspace */ 4864b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4865854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n-n_vertices,&idx_R_local);CHKERRQ(ierr); 4866a64d13efSStefano Zampini ierr = PetscBTCreate(pcis->n,&bitmask);CHKERRQ(ierr); 4867a64d13efSStefano Zampini for (i=0;i<n_vertices;i++) { 48680e6343abSStefano Zampini ierr = PetscBTSet(bitmask,pcbddc->local_primal_ref_node[i]);CHKERRQ(ierr); 4869a64d13efSStefano Zampini } 4870a64d13efSStefano Zampini 4871a64d13efSStefano Zampini for (i=0, n_R=0; i<pcis->n; i++) { 48724641a718SStefano Zampini if (!PetscBTLookup(bitmask,i)) { 48736816873aSStefano Zampini idx_R_local[n_R++] = i; 4874a64d13efSStefano Zampini } 4875a64d13efSStefano Zampini } 4876df4d28bfSStefano Zampini } else { /* A different ordering (already computed) is present if we are reusing the Schur solver */ 4877df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 48786816873aSStefano Zampini 4879df4d28bfSStefano Zampini ierr = ISGetIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4880df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_R,&n_R);CHKERRQ(ierr); 48816816873aSStefano Zampini } 48823a50541eSStefano Zampini 48833a50541eSStefano Zampini /* Block code */ 48843a50541eSStefano Zampini vbs = 1; 48853a50541eSStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&bs);CHKERRQ(ierr); 48863a50541eSStefano Zampini if (bs>1 && !(n_vertices%bs)) { 48873a50541eSStefano Zampini PetscBool is_blocked = PETSC_TRUE; 48883a50541eSStefano Zampini PetscInt *vary; 4889b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 4890785e854fSJed Brown ierr = PetscMalloc1(pcis->n/bs,&vary);CHKERRQ(ierr); 48913a50541eSStefano Zampini ierr = PetscMemzero(vary,pcis->n/bs*sizeof(PetscInt));CHKERRQ(ierr); 4892d3df7717SStefano Zampini /* Verify that the vertex indices correspond to each element in a block (code taken from sbaij2.c) */ 4893d3df7717SStefano 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 */ 48940e6343abSStefano Zampini for (i=0; i<n_vertices; i++) vary[pcbddc->local_primal_ref_node[i]/bs]++; 4895d3df7717SStefano Zampini for (i=0; i<pcis->n/bs; i++) { 48963a50541eSStefano Zampini if (vary[i]!=0 && vary[i]!=bs) { 48973a50541eSStefano Zampini is_blocked = PETSC_FALSE; 48983a50541eSStefano Zampini break; 48993a50541eSStefano Zampini } 49003a50541eSStefano Zampini } 4901d3df7717SStefano Zampini ierr = PetscFree(vary);CHKERRQ(ierr); 4902d3df7717SStefano Zampini } else { 4903d3df7717SStefano Zampini /* Verify directly the R set */ 4904d3df7717SStefano Zampini for (i=0; i<n_R/bs; i++) { 4905d3df7717SStefano Zampini PetscInt j,node=idx_R_local[bs*i]; 4906d3df7717SStefano Zampini for (j=1; j<bs; j++) { 4907d3df7717SStefano Zampini if (node != idx_R_local[bs*i+j]-j) { 4908d3df7717SStefano Zampini is_blocked = PETSC_FALSE; 4909d3df7717SStefano Zampini break; 4910d3df7717SStefano Zampini } 4911d3df7717SStefano Zampini } 4912d3df7717SStefano Zampini } 4913d3df7717SStefano Zampini } 49143a50541eSStefano Zampini if (is_blocked) { /* build compressed IS for R nodes (complement of vertices) */ 49153a50541eSStefano Zampini vbs = bs; 49163a50541eSStefano Zampini for (i=0;i<n_R/vbs;i++) { 49173a50541eSStefano Zampini idx_R_local[i] = idx_R_local[vbs*i]/vbs; 49183a50541eSStefano Zampini } 49193a50541eSStefano Zampini } 49203a50541eSStefano Zampini } 49213a50541eSStefano Zampini ierr = ISCreateBlock(PETSC_COMM_SELF,vbs,n_R/vbs,idx_R_local,PETSC_COPY_VALUES,&pcbddc->is_R_local);CHKERRQ(ierr); 4922b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 4923df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 492453892102SStefano Zampini 4925df4d28bfSStefano Zampini ierr = ISRestoreIndices(reuse_solver->is_R,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4926df4d28bfSStefano Zampini ierr = ISDestroy(&reuse_solver->is_R);CHKERRQ(ierr); 492753892102SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->is_R_local);CHKERRQ(ierr); 4928df4d28bfSStefano Zampini reuse_solver->is_R = pcbddc->is_R_local; 492953892102SStefano Zampini } else { 49303a50541eSStefano Zampini ierr = PetscFree(idx_R_local);CHKERRQ(ierr); 493153892102SStefano Zampini } 4932a64d13efSStefano Zampini 4933a64d13efSStefano Zampini /* print some info if requested */ 4934a64d13efSStefano Zampini if (pcbddc->dbg_flag) { 4935a64d13efSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 4936a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 49371575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 4938a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d local dimensions\n",PetscGlobalRank);CHKERRQ(ierr); 4939a64d13efSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"local_size = %d, dirichlet_size = %d, boundary_size = %d\n",pcis->n,n_D,n_B);CHKERRQ(ierr); 49404f1b2e48SStefano 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); 4941a64d13efSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 4942a64d13efSStefano Zampini } 4943a64d13efSStefano Zampini 4944a64d13efSStefano Zampini /* VecScatters pcbddc->R_to_B and (optionally) pcbddc->R_to_D */ 4945b334f244SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) { 49466816873aSStefano Zampini IS is_aux1,is_aux2; 49476816873aSStefano Zampini PetscInt *aux_array1,*aux_array2,*is_indices,*idx_R_local; 49486816873aSStefano Zampini 49493a50541eSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4950854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array1);CHKERRQ(ierr); 4951854ce69bSBarry Smith ierr = PetscMalloc1(pcis->n_B-n_vertices,&aux_array2);CHKERRQ(ierr); 4952a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 49534641a718SStefano Zampini for (i=0; i<n_D; i++) { 49544641a718SStefano Zampini ierr = PetscBTSet(bitmask,is_indices[i]);CHKERRQ(ierr); 49554641a718SStefano Zampini } 4956a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4957a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 49584641a718SStefano Zampini if (!PetscBTLookup(bitmask,idx_R_local[i])) { 49594641a718SStefano Zampini aux_array1[j++] = i; 4960a64d13efSStefano Zampini } 4961a64d13efSStefano Zampini } 4962a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4963a64d13efSStefano Zampini ierr = ISGetIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4964a64d13efSStefano Zampini for (i=0, j=0; i<n_B; i++) { 49654641a718SStefano Zampini if (!PetscBTLookup(bitmask,is_indices[i])) { 49664641a718SStefano Zampini aux_array2[j++] = i; 4967a64d13efSStefano Zampini } 4968a64d13efSStefano Zampini } 4969a64d13efSStefano Zampini ierr = ISRestoreIndices(pcis->is_B_local,(const PetscInt**)&is_indices);CHKERRQ(ierr); 4970a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array2,PETSC_OWN_POINTER,&is_aux2);CHKERRQ(ierr); 4971a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_B,is_aux2,&pcbddc->R_to_B);CHKERRQ(ierr); 4972a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4973a64d13efSStefano Zampini ierr = ISDestroy(&is_aux2);CHKERRQ(ierr); 4974a64d13efSStefano Zampini 49758eeda7d8SStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 4976785e854fSJed Brown ierr = PetscMalloc1(n_D,&aux_array1);CHKERRQ(ierr); 4977a64d13efSStefano Zampini for (i=0, j=0; i<n_R; i++) { 49784641a718SStefano Zampini if (PetscBTLookup(bitmask,idx_R_local[i])) { 49794641a718SStefano Zampini aux_array1[j++] = i; 4980a64d13efSStefano Zampini } 4981a64d13efSStefano Zampini } 4982a64d13efSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,j,aux_array1,PETSC_OWN_POINTER,&is_aux1);CHKERRQ(ierr); 4983a64d13efSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,is_aux1,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 4984a64d13efSStefano Zampini ierr = ISDestroy(&is_aux1);CHKERRQ(ierr); 4985a64d13efSStefano Zampini } 49864641a718SStefano Zampini ierr = PetscBTDestroy(&bitmask);CHKERRQ(ierr); 49873a50541eSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,(const PetscInt**)&idx_R_local);CHKERRQ(ierr); 4988d62866d3SStefano Zampini } else { 4989df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 49906816873aSStefano Zampini IS tis; 49916816873aSStefano Zampini PetscInt schur_size; 49926816873aSStefano Zampini 4993df4d28bfSStefano Zampini ierr = ISGetLocalSize(reuse_solver->is_B,&schur_size);CHKERRQ(ierr); 49946816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,schur_size,n_D,1,&tis);CHKERRQ(ierr); 4995df4d28bfSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_B,reuse_solver->is_B,&pcbddc->R_to_B);CHKERRQ(ierr); 49966816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 49976816873aSStefano Zampini if (pcbddc->switch_static || pcbddc->dbg_flag) { 49986816873aSStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,n_D,0,1,&tis);CHKERRQ(ierr); 49996816873aSStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_R,tis,pcis->vec1_D,(IS)0,&pcbddc->R_to_D);CHKERRQ(ierr); 50006816873aSStefano Zampini ierr = ISDestroy(&tis);CHKERRQ(ierr); 5001d62866d3SStefano Zampini } 5002d62866d3SStefano Zampini } 5003a64d13efSStefano Zampini PetscFunctionReturn(0); 5004a64d13efSStefano Zampini } 5005a64d13efSStefano Zampini 5006304d26faSStefano Zampini 5007684f6988SStefano Zampini PetscErrorCode PCBDDCSetUpLocalSolvers(PC pc, PetscBool dirichlet, PetscBool neumann) 5008304d26faSStefano Zampini { 5009304d26faSStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 5010304d26faSStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 5011304d26faSStefano Zampini PC pc_temp; 5012304d26faSStefano Zampini Mat A_RR; 5013f4ddd8eeSStefano Zampini MatReuse reuse; 5014304d26faSStefano Zampini PetscScalar m_one = -1.0; 5015304d26faSStefano Zampini PetscReal value; 501604708bb6SStefano Zampini PetscInt n_D,n_R; 501735529e7bSStefano Zampini PetscBool check_corr,issbaij; 5018304d26faSStefano Zampini PetscErrorCode ierr; 5019e604994aSStefano Zampini /* prefixes stuff */ 5020312be037SStefano Zampini char dir_prefix[256],neu_prefix[256],str_level[16]; 5021e604994aSStefano Zampini size_t len; 5022304d26faSStefano Zampini 5023304d26faSStefano Zampini PetscFunctionBegin; 5024304d26faSStefano Zampini 5025e604994aSStefano Zampini /* compute prefixes */ 5026e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,"");CHKERRQ(ierr); 5027e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,"");CHKERRQ(ierr); 5028e604994aSStefano Zampini if (!pcbddc->current_level) { 5029e604994aSStefano Zampini ierr = PetscStrcpy(dir_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5030e604994aSStefano Zampini ierr = PetscStrcpy(neu_prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 5031e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 5032e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 5033e604994aSStefano Zampini } else { 503435529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 5035e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 5036e604994aSStefano Zampini len -= 15; /* remove "pc_bddc_coarse_" */ 5037312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 5038312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 503934d6797cSStefano Zampini ierr = PetscStrncpy(dir_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 504034d6797cSStefano Zampini ierr = PetscStrncpy(neu_prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 5041e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,"pc_bddc_dirichlet_");CHKERRQ(ierr); 5042e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,"pc_bddc_neumann_");CHKERRQ(ierr); 5043e604994aSStefano Zampini ierr = PetscStrcat(dir_prefix,str_level);CHKERRQ(ierr); 5044e604994aSStefano Zampini ierr = PetscStrcat(neu_prefix,str_level);CHKERRQ(ierr); 5045e604994aSStefano Zampini } 5046e604994aSStefano Zampini 5047304d26faSStefano Zampini /* DIRICHLET PROBLEM */ 5048684f6988SStefano Zampini if (dirichlet) { 5049d5574798SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5050450f8f5eSStefano Zampini if (pcbddc->benign_n && !pcbddc->benign_change_explicit) { 50519a962809SStefano Zampini if (!sub_schurs || !sub_schurs->reuse_solver) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Not yet implemented\n"); 5052450f8f5eSStefano Zampini if (pcbddc->dbg_flag) { 5053a3df083aSStefano Zampini Mat A_IIn; 5054a3df083aSStefano Zampini 5055a3df083aSStefano Zampini ierr = PCBDDCBenignProject(pc,pcis->is_I_local,pcis->is_I_local,&A_IIn);CHKERRQ(ierr); 5056a3df083aSStefano Zampini ierr = MatDestroy(&pcis->A_II);CHKERRQ(ierr); 5057a3df083aSStefano Zampini pcis->A_II = A_IIn; 5058a3df083aSStefano Zampini } 5059450f8f5eSStefano Zampini } 50603301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 50613301b35fSStefano Zampini ierr = MatSetOption(pcis->A_II,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 5062964fefecSStefano Zampini } 5063ac78edfcSStefano Zampini /* Matrix for Dirichlet problem is pcis->A_II */ 5064964fefecSStefano Zampini n_D = pcis->n - pcis->n_B; 5065304d26faSStefano Zampini if (!pcbddc->ksp_D) { /* create object if not yet build */ 5066*cd18cfedSStefano Zampini void (*f)(void) = 0; 5067*cd18cfedSStefano Zampini 5068304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_D);CHKERRQ(ierr); 5069304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_D,(PetscObject)pc,1);CHKERRQ(ierr); 5070304d26faSStefano Zampini /* default */ 5071304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_D,KSPPREONLY);CHKERRQ(ierr); 5072e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_D,dir_prefix);CHKERRQ(ierr); 50739577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcis->A_II,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 5074304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 50759577ea80SStefano Zampini if (issbaij) { 50769577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 50779577ea80SStefano Zampini } else { 5078304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 50799577ea80SStefano Zampini } 5080304d26faSStefano Zampini /* Allow user's customization */ 5081304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_D);CHKERRQ(ierr); 5082*cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 5083*cd18cfedSStefano Zampini if (f && pcbddc->mat_graph->cloc) { 5084*cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5085*cd18cfedSStefano Zampini const PetscInt *idxs; 5086*cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5087*cd18cfedSStefano Zampini 5088*cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcis->is_I_local,&nl);CHKERRQ(ierr); 5089*cd18cfedSStefano Zampini ierr = ISGetIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5090*cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5091*cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5092*cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5093*cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5094*cd18cfedSStefano Zampini } 5095*cd18cfedSStefano Zampini } 5096*cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcis->is_I_local,&idxs);CHKERRQ(ierr); 5097*cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5098*cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5099*cd18cfedSStefano Zampini } 5100304d26faSStefano Zampini } 5101d1e9a80fSBarry Smith ierr = KSPSetOperators(pcbddc->ksp_D,pcis->A_II,pcis->A_II);CHKERRQ(ierr); 5102b334f244SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 5103df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5104d62866d3SStefano Zampini 5105df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_D,reuse_solver->interior_solver);CHKERRQ(ierr); 5106d5574798SStefano Zampini } 5107304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5108304d26faSStefano Zampini if (!n_D) { 5109304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_D,&pc_temp);CHKERRQ(ierr); 5110304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5111304d26faSStefano Zampini } 5112304d26faSStefano Zampini /* Set Up KSP for Dirichlet problem of BDDC */ 5113304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_D);CHKERRQ(ierr); 5114304d26faSStefano Zampini /* set ksp_D into pcis data */ 5115304d26faSStefano Zampini ierr = KSPDestroy(&pcis->ksp_D);CHKERRQ(ierr); 5116304d26faSStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->ksp_D);CHKERRQ(ierr); 5117304d26faSStefano Zampini pcis->ksp_D = pcbddc->ksp_D; 5118684f6988SStefano Zampini } 5119304d26faSStefano Zampini 5120304d26faSStefano Zampini /* NEUMANN PROBLEM */ 5121684f6988SStefano Zampini A_RR = 0; 5122684f6988SStefano Zampini if (neumann) { 5123d62866d3SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 512404708bb6SStefano Zampini PetscInt ibs,mbs; 51250aa714b2SStefano Zampini PetscBool issbaij, reuse_neumann_solver; 512604708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 51270aa714b2SStefano Zampini 51280aa714b2SStefano Zampini reuse_neumann_solver = PETSC_FALSE; 51290aa714b2SStefano Zampini if (sub_schurs && sub_schurs->reuse_solver) { 51300aa714b2SStefano Zampini IS iP; 51310aa714b2SStefano Zampini 51320aa714b2SStefano Zampini reuse_neumann_solver = PETSC_TRUE; 51330aa714b2SStefano Zampini ierr = PetscObjectQuery((PetscObject)sub_schurs->A,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 51340aa714b2SStefano Zampini if (iP) reuse_neumann_solver = PETSC_FALSE; 51350aa714b2SStefano Zampini } 5136f4ddd8eeSStefano Zampini /* Matrix for Neumann problem is A_RR -> we need to create/reuse it at this point */ 51378ce42a96SStefano Zampini ierr = ISGetSize(pcbddc->is_R_local,&n_R);CHKERRQ(ierr); 5138f4ddd8eeSStefano Zampini if (pcbddc->ksp_R) { /* already created ksp */ 5139f4ddd8eeSStefano Zampini PetscInt nn_R; 514081d9aea3SBarry Smith ierr = KSPGetOperators(pcbddc->ksp_R,NULL,&A_RR);CHKERRQ(ierr); 5141f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5142f4ddd8eeSStefano Zampini ierr = MatGetSize(A_RR,&nn_R,NULL);CHKERRQ(ierr); 5143f4ddd8eeSStefano Zampini if (nn_R != n_R) { /* old ksp is not reusable, so reset it */ 5144f4ddd8eeSStefano Zampini ierr = KSPReset(pcbddc->ksp_R);CHKERRQ(ierr); 5145f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5146f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5147f4ddd8eeSStefano Zampini } else { /* same sizes, but nonzero pattern depend on primal vertices so it can be changed */ 5148727cdba6SStefano Zampini if (pcbddc->new_primal_space_local) { /* we are not sure the matrix will have the same nonzero pattern */ 5149f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5150f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5151f4ddd8eeSStefano Zampini } else { /* safe to reuse the matrix */ 5152f4ddd8eeSStefano Zampini reuse = MAT_REUSE_MATRIX; 5153f4ddd8eeSStefano Zampini } 5154f4ddd8eeSStefano Zampini } 5155f4ddd8eeSStefano Zampini /* last check */ 5156d1e9a80fSBarry Smith if (pc->flag == DIFFERENT_NONZERO_PATTERN) { 5157f4ddd8eeSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5158f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5159f4ddd8eeSStefano Zampini } 5160f4ddd8eeSStefano Zampini } else { /* first time, so we need to create the matrix */ 5161f4ddd8eeSStefano Zampini reuse = MAT_INITIAL_MATRIX; 5162f4ddd8eeSStefano Zampini } 5163a00504b5SStefano Zampini /* convert pcbddc->local_mat if needed later in PCBDDCSetUpCorrection */ 5164af732b37SStefano Zampini ierr = MatGetBlockSize(pcbddc->local_mat,&mbs);CHKERRQ(ierr); 5165af732b37SStefano Zampini ierr = ISGetBlockSize(pcbddc->is_R_local,&ibs);CHKERRQ(ierr); 516604708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 516704708bb6SStefano Zampini if (ibs != mbs) { /* need to convert to SEQAIJ to extract any submatrix with is_R_local */ 516804708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 516904708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 517004708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 5171af732b37SStefano Zampini } else { 5172511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 51736816873aSStefano Zampini } 517404708bb6SStefano Zampini } else if (issbaij) { /* need to convert to BAIJ to get offdiagonal blocks */ 517504708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 517604708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 517704708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQBAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 517804708bb6SStefano Zampini } else { 5179511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQBAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 518004708bb6SStefano Zampini } 518104708bb6SStefano Zampini } 5182a00504b5SStefano Zampini /* extract A_RR */ 51830aa714b2SStefano Zampini if (reuse_neumann_solver) { 5184a00504b5SStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5185a00504b5SStefano Zampini 5186a00504b5SStefano Zampini if (pcbddc->dbg_flag) { /* we need A_RR to test the solver later */ 518716e386b8SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5188a00504b5SStefano Zampini if (reuse_solver->benign_n) { /* we are not using the explicit change of basis on the pressures */ 518916e386b8SStefano Zampini ierr = PCBDDCBenignProject(pc,pcbddc->is_R_local,pcbddc->is_R_local,&A_RR);CHKERRQ(ierr); 519016e386b8SStefano Zampini } else { 51917dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,MAT_INITIAL_MATRIX,&A_RR);CHKERRQ(ierr); 5192a00504b5SStefano Zampini } 5193a00504b5SStefano Zampini } else { 5194a00504b5SStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5195a00504b5SStefano Zampini ierr = PCGetOperators(reuse_solver->correction_solver,&A_RR,NULL);CHKERRQ(ierr); 5196a00504b5SStefano Zampini ierr = PetscObjectReference((PetscObject)A_RR);CHKERRQ(ierr); 5197a00504b5SStefano Zampini } 5198a00504b5SStefano Zampini } else { /* we have to build the neumann solver, so we need to extract the relevant matrix */ 51997dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->local_mat,pcbddc->is_R_local,pcbddc->is_R_local,reuse,&A_RR);CHKERRQ(ierr); 520016e386b8SStefano Zampini } 52013301b35fSStefano Zampini if (pcbddc->local_mat->symmetric_set) { 52023301b35fSStefano Zampini ierr = MatSetOption(A_RR,MAT_SYMMETRIC,pcbddc->local_mat->symmetric_set);CHKERRQ(ierr); 52036816873aSStefano Zampini } 5204f4ddd8eeSStefano Zampini if (!pcbddc->ksp_R) { /* create object if not present */ 5205*cd18cfedSStefano Zampini void (*f)(void) = 0; 5206*cd18cfedSStefano Zampini 5207304d26faSStefano Zampini ierr = KSPCreate(PETSC_COMM_SELF,&pcbddc->ksp_R);CHKERRQ(ierr); 5208304d26faSStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->ksp_R,(PetscObject)pc,1);CHKERRQ(ierr); 5209304d26faSStefano Zampini /* default */ 5210304d26faSStefano Zampini ierr = KSPSetType(pcbddc->ksp_R,KSPPREONLY);CHKERRQ(ierr); 5211e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->ksp_R,neu_prefix);CHKERRQ(ierr); 5212304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 52139577ea80SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)A_RR,MATSEQSBAIJ,&issbaij);CHKERRQ(ierr); 52149577ea80SStefano Zampini if (issbaij) { 52159577ea80SStefano Zampini ierr = PCSetType(pc_temp,PCCHOLESKY);CHKERRQ(ierr); 52169577ea80SStefano Zampini } else { 5217304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCLU);CHKERRQ(ierr); 52189577ea80SStefano Zampini } 5219304d26faSStefano Zampini /* Allow user's customization */ 5220304d26faSStefano Zampini ierr = KSPSetFromOptions(pcbddc->ksp_R);CHKERRQ(ierr); 5221*cd18cfedSStefano Zampini ierr = PetscObjectQueryFunction((PetscObject)pc_temp,"PCSetCoordinates_C",&f);CHKERRQ(ierr); 5222*cd18cfedSStefano Zampini if (f && pcbddc->mat_graph->cloc) { 5223*cd18cfedSStefano Zampini PetscReal *coords = pcbddc->mat_graph->coords,*scoords; 5224*cd18cfedSStefano Zampini const PetscInt *idxs; 5225*cd18cfedSStefano Zampini PetscInt cdim = pcbddc->mat_graph->cdim,nl,i,d; 5226*cd18cfedSStefano Zampini 5227*cd18cfedSStefano Zampini ierr = ISGetLocalSize(pcbddc->is_R_local,&nl);CHKERRQ(ierr); 5228*cd18cfedSStefano Zampini ierr = ISGetIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5229*cd18cfedSStefano Zampini ierr = PetscMalloc1(nl*cdim,&scoords);CHKERRQ(ierr); 5230*cd18cfedSStefano Zampini for (i=0;i<nl;i++) { 5231*cd18cfedSStefano Zampini for (d=0;d<cdim;d++) { 5232*cd18cfedSStefano Zampini scoords[i*cdim+d] = coords[idxs[i]*cdim+d]; 5233*cd18cfedSStefano Zampini } 5234*cd18cfedSStefano Zampini } 5235*cd18cfedSStefano Zampini ierr = ISRestoreIndices(pcbddc->is_R_local,&idxs);CHKERRQ(ierr); 5236*cd18cfedSStefano Zampini ierr = PCSetCoordinates(pc_temp,cdim,nl,scoords);CHKERRQ(ierr); 5237*cd18cfedSStefano Zampini ierr = PetscFree(scoords);CHKERRQ(ierr); 5238*cd18cfedSStefano Zampini } 5239304d26faSStefano Zampini } 5240304d26faSStefano Zampini /* umfpack interface has a bug when matrix dimension is zero. TODO solve from umfpack interface */ 5241304d26faSStefano Zampini if (!n_R) { 5242304d26faSStefano Zampini ierr = KSPGetPC(pcbddc->ksp_R,&pc_temp);CHKERRQ(ierr); 5243304d26faSStefano Zampini ierr = PCSetType(pc_temp,PCNONE);CHKERRQ(ierr); 5244304d26faSStefano Zampini } 52455cbda25cSStefano Zampini ierr = KSPSetOperators(pcbddc->ksp_R,A_RR,A_RR);CHKERRQ(ierr); 5246df4d28bfSStefano Zampini /* Reuse solver if it is present */ 52470aa714b2SStefano Zampini if (reuse_neumann_solver) { 5248df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5249d62866d3SStefano Zampini 5250df4d28bfSStefano Zampini ierr = KSPSetPC(pcbddc->ksp_R,reuse_solver->correction_solver);CHKERRQ(ierr); 5251d62866d3SStefano Zampini } 5252304d26faSStefano Zampini /* Set Up KSP for Neumann problem of BDDC */ 5253304d26faSStefano Zampini ierr = KSPSetUp(pcbddc->ksp_R);CHKERRQ(ierr); 5254684f6988SStefano Zampini } 5255304d26faSStefano Zampini 5256684f6988SStefano Zampini if (pcbddc->dbg_flag) { 5257684f6988SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 52581575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5259684f6988SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 5260684f6988SStefano Zampini } 5261c7017625SStefano Zampini 5262c7017625SStefano Zampini /* adapt Dirichlet and Neumann solvers if a nullspace correction has been requested */ 526335529e7bSStefano Zampini check_corr = PETSC_FALSE; 5264c7017625SStefano Zampini if (pcbddc->NullSpace_corr[0]) { 5265c7017625SStefano Zampini ierr = PCBDDCSetUseExactDirichlet(pc,PETSC_FALSE);CHKERRQ(ierr); 5266c7017625SStefano Zampini } 5267c7017625SStefano Zampini if (dirichlet && pcbddc->NullSpace_corr[0] && !pcbddc->switch_static) { 526835529e7bSStefano Zampini check_corr = PETSC_TRUE; 5269c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_TRUE,pcbddc->NullSpace_corr[1]);CHKERRQ(ierr); 5270c7017625SStefano Zampini } 5271c7017625SStefano Zampini if (neumann && pcbddc->NullSpace_corr[2]) { 527235529e7bSStefano Zampini check_corr = PETSC_TRUE; 5273c7017625SStefano Zampini ierr = PCBDDCNullSpaceAssembleCorrection(pc,PETSC_FALSE,pcbddc->NullSpace_corr[3]);CHKERRQ(ierr); 5274c7017625SStefano Zampini } 5275c7017625SStefano Zampini /* check Dirichlet and Neumann solvers */ 5276c7017625SStefano Zampini if (pcbddc->dbg_flag) { 5277684f6988SStefano Zampini if (dirichlet) { /* Dirichlet */ 52780fccc4e9SStefano Zampini ierr = VecSetRandom(pcis->vec1_D,NULL);CHKERRQ(ierr); 52790fccc4e9SStefano Zampini ierr = MatMult(pcis->A_II,pcis->vec1_D,pcis->vec2_D);CHKERRQ(ierr); 52800fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_D,pcis->vec2_D,pcis->vec2_D);CHKERRQ(ierr); 52810fccc4e9SStefano Zampini ierr = VecAXPY(pcis->vec1_D,m_one,pcis->vec2_D);CHKERRQ(ierr); 52820fccc4e9SStefano Zampini ierr = VecNorm(pcis->vec1_D,NORM_INFINITY,&value);CHKERRQ(ierr); 5283e604994aSStefano 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); 528435529e7bSStefano Zampini if (check_corr) { 5285c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_TRUE);CHKERRQ(ierr); 5286c7017625SStefano Zampini } 5287304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5288304d26faSStefano Zampini } 5289684f6988SStefano Zampini if (neumann) { /* Neumann */ 52900fccc4e9SStefano Zampini ierr = VecSetRandom(pcbddc->vec1_R,NULL);CHKERRQ(ierr); 52910fccc4e9SStefano Zampini ierr = MatMult(A_RR,pcbddc->vec1_R,pcbddc->vec2_R);CHKERRQ(ierr); 52920fccc4e9SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec2_R,pcbddc->vec2_R);CHKERRQ(ierr); 52930fccc4e9SStefano Zampini ierr = VecAXPY(pcbddc->vec1_R,m_one,pcbddc->vec2_R);CHKERRQ(ierr); 52940fccc4e9SStefano Zampini ierr = VecNorm(pcbddc->vec1_R,NORM_INFINITY,&value);CHKERRQ(ierr); 5295e604994aSStefano 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); 529635529e7bSStefano Zampini if (check_corr) { 5297c7017625SStefano Zampini ierr = PCBDDCNullSpaceCheckCorrection(pc,PETSC_FALSE);CHKERRQ(ierr); 5298c7017625SStefano Zampini } 5299304d26faSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5300304d26faSStefano Zampini } 5301684f6988SStefano Zampini } 53025cbda25cSStefano Zampini /* free Neumann problem's matrix */ 53035cbda25cSStefano Zampini ierr = MatDestroy(&A_RR);CHKERRQ(ierr); 5304304d26faSStefano Zampini PetscFunctionReturn(0); 5305304d26faSStefano Zampini } 5306304d26faSStefano Zampini 530780677318SStefano Zampini static PetscErrorCode PCBDDCSolveSubstructureCorrection(PC pc, Vec inout_B, Vec inout_D, PetscBool applytranspose) 5308674ae819SStefano Zampini { 5309674ae819SStefano Zampini PetscErrorCode ierr; 5310674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5311be83ff47SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 5312b334f244SStefano Zampini PetscBool reuse_solver = sub_schurs ? ( sub_schurs->reuse_solver ? PETSC_TRUE : PETSC_FALSE ) : PETSC_FALSE; 5313674ae819SStefano Zampini 5314674ae819SStefano Zampini PetscFunctionBegin; 5315b334f244SStefano Zampini if (!reuse_solver) { 531680677318SStefano Zampini ierr = VecSet(pcbddc->vec1_R,0.);CHKERRQ(ierr); 531720c7b377SStefano Zampini } 531880677318SStefano Zampini if (!pcbddc->switch_static) { 531980677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 532080677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 532180677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 532220c7b377SStefano Zampini } 5323b334f244SStefano Zampini if (!reuse_solver) { 532480677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 532580677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 532620c7b377SStefano Zampini } else { 5327df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5328be83ff47SStefano Zampini 5329df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5330df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,inout_B,reuse_solver->rhs_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 533120c7b377SStefano Zampini } 5332be83ff47SStefano Zampini } else { 533380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 533480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 533580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 533680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,inout_D,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 533780677318SStefano Zampini if (applytranspose && pcbddc->local_auxmat1) { 533880677318SStefano Zampini ierr = MatMultTranspose(pcbddc->local_auxmat2,pcbddc->vec1_R,pcbddc->vec1_C);CHKERRQ(ierr); 533980677318SStefano Zampini ierr = MatMultTransposeAdd(pcbddc->local_auxmat1,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 534080677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 534180677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,inout_B,pcbddc->vec1_R,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5342674ae819SStefano Zampini } 5343674ae819SStefano Zampini } 5344b334f244SStefano Zampini if (!reuse_solver || pcbddc->switch_static) { 534580677318SStefano Zampini if (applytranspose) { 534680677318SStefano Zampini ierr = KSPSolveTranspose(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 534780677318SStefano Zampini } else { 534880677318SStefano Zampini ierr = KSPSolve(pcbddc->ksp_R,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 534980677318SStefano Zampini } 5350be83ff47SStefano Zampini } else { 5351df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5352be83ff47SStefano Zampini 5353be83ff47SStefano Zampini if (applytranspose) { 5354df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplementTranspose(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5355be83ff47SStefano Zampini } else { 5356df4d28bfSStefano Zampini ierr = MatFactorSolveSchurComplement(reuse_solver->F,reuse_solver->rhs_B,reuse_solver->sol_B);CHKERRQ(ierr); 5357be83ff47SStefano Zampini } 5358be83ff47SStefano Zampini } 535980677318SStefano Zampini ierr = VecSet(inout_B,0.);CHKERRQ(ierr); 536080677318SStefano Zampini if (!pcbddc->switch_static) { 5361b334f244SStefano Zampini if (!reuse_solver) { 536280677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 536380677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5364be83ff47SStefano Zampini } else { 5365df4d28bfSStefano Zampini PCBDDCReuseSolvers reuse_solver = sub_schurs->reuse_solver; 5366be83ff47SStefano Zampini 5367df4d28bfSStefano Zampini ierr = VecScatterBegin(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5368df4d28bfSStefano Zampini ierr = VecScatterEnd(reuse_solver->correction_scatter_B,reuse_solver->sol_B,inout_B,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5369be83ff47SStefano Zampini } 537080677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 537180677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 537280677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,inout_B,inout_B);CHKERRQ(ierr); 537380677318SStefano Zampini } 537480677318SStefano Zampini } else { 537580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 537680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 537780677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 537880677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 537980677318SStefano Zampini if (!applytranspose && pcbddc->local_auxmat1) { 538080677318SStefano Zampini ierr = MatMult(pcbddc->local_auxmat1,inout_B,pcbddc->vec1_C);CHKERRQ(ierr); 538180677318SStefano Zampini ierr = MatMultAdd(pcbddc->local_auxmat2,pcbddc->vec1_C,pcbddc->vec1_R,pcbddc->vec1_R);CHKERRQ(ierr); 538280677318SStefano Zampini } 538380677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 538480677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_B,pcbddc->vec1_R,inout_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 538580677318SStefano Zampini ierr = VecScatterBegin(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 538680677318SStefano Zampini ierr = VecScatterEnd(pcbddc->R_to_D,pcbddc->vec1_R,inout_D,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5387674ae819SStefano Zampini } 5388674ae819SStefano Zampini PetscFunctionReturn(0); 5389674ae819SStefano Zampini } 5390674ae819SStefano Zampini 5391dc359a40SStefano Zampini /* parameter apply transpose determines if the interface preconditioner should be applied transposed or not */ 5392dc359a40SStefano Zampini PetscErrorCode PCBDDCApplyInterfacePreconditioner(PC pc, PetscBool applytranspose) 5393674ae819SStefano Zampini { 5394674ae819SStefano Zampini PetscErrorCode ierr; 5395674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 5396674ae819SStefano Zampini PC_IS* pcis = (PC_IS*) (pc->data); 5397674ae819SStefano Zampini const PetscScalar zero = 0.0; 5398674ae819SStefano Zampini 5399674ae819SStefano Zampini PetscFunctionBegin; 5400dc359a40SStefano Zampini /* Application of PSI^T or PHI^T (depending on applytranspose, see comment above) */ 54014fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5402dc359a40SStefano Zampini if (applytranspose) { 5403674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 54048eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_phi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 5405dc359a40SStefano Zampini } else { 5406674ae819SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_psi_B,pcis->vec1_B,pcbddc->vec1_P);CHKERRQ(ierr); 5407674ae819SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultTransposeAdd(pcbddc->coarse_psi_D,pcis->vec1_D,pcbddc->vec1_P,pcbddc->vec1_P);CHKERRQ(ierr); } 540815aaf578SStefano Zampini } 54094fee134fSStefano Zampini } else { 54104fee134fSStefano Zampini ierr = VecSet(pcbddc->vec1_P,zero);CHKERRQ(ierr); 54114fee134fSStefano Zampini } 5412efc2fbd9SStefano Zampini 5413efc2fbd9SStefano Zampini /* add p0 to the last value of vec1_P holding the coarse dof relative to p0 */ 54144f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5415efc2fbd9SStefano Zampini PetscScalar *array; 54164f1b2e48SStefano Zampini PetscInt j; 5417efc2fbd9SStefano Zampini 5418efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 54194f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) array[pcbddc->local_primal_size-pcbddc->benign_n+j] += pcbddc->benign_p0[j]; 5420efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5421efc2fbd9SStefano Zampini } 5422efc2fbd9SStefano Zampini 542312edc857SStefano Zampini /* start communications from local primal nodes to rhs of coarse solver */ 542412edc857SStefano Zampini ierr = VecSet(pcbddc->coarse_vec,zero);CHKERRQ(ierr); 542512edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 542612edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 542712edc857SStefano Zampini 54289f00e9b4SStefano Zampini /* Coarse solution -> rhs and sol updated inside PCBDDCScattarCoarseDataBegin/End */ 542912edc857SStefano Zampini if (pcbddc->coarse_ksp) { 543051694757SStefano Zampini Mat coarse_mat; 5431964fefecSStefano Zampini Vec rhs,sol; 543251694757SStefano Zampini MatNullSpace nullsp; 543327b6a85dSStefano Zampini PetscBool isbddc = PETSC_FALSE; 5434964fefecSStefano Zampini 543527b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 543627b6a85dSStefano Zampini PC coarse_pc; 543727b6a85dSStefano Zampini 543827b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 543927b6a85dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)coarse_pc,PCBDDC,&isbddc);CHKERRQ(ierr); 544027b6a85dSStefano Zampini /* we need to propagate to coarser levels the need for a possible benign correction */ 544127b6a85dSStefano Zampini if (isbddc && pcbddc->benign_apply_coarse_only && !pcbddc->benign_skip_correction) { 544227b6a85dSStefano Zampini PC_BDDC* coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 544327b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_FALSE; 54443bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_TRUE; 544527b6a85dSStefano Zampini } 544627b6a85dSStefano Zampini } 5447964fefecSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&rhs);CHKERRQ(ierr); 5448964fefecSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&sol);CHKERRQ(ierr); 544951694757SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 545051694757SStefano Zampini ierr = MatGetNullSpace(coarse_mat,&nullsp);CHKERRQ(ierr); 545151694757SStefano Zampini if (nullsp) { 545251694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,rhs);CHKERRQ(ierr); 545351694757SStefano Zampini } 545412edc857SStefano Zampini if (applytranspose) { 54559a962809SStefano Zampini if (pcbddc->benign_apply_coarse_only) SETERRQ(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),PETSC_ERR_SUP,"Not yet implemented"); 5456964fefecSStefano Zampini ierr = KSPSolveTranspose(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 54572701bc32SStefano Zampini } else { 54581f4df5f7SStefano Zampini if (pcbddc->benign_apply_coarse_only && isbddc) { /* need just to apply the coarse preconditioner during presolve */ 54592701bc32SStefano Zampini PC coarse_pc; 54602701bc32SStefano Zampini 54612701bc32SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 54622701bc32SStefano Zampini ierr = PCPreSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 54633e589ea0SStefano Zampini ierr = PCBDDCBenignRemoveInterior(coarse_pc,rhs,sol);CHKERRQ(ierr); 54642701bc32SStefano Zampini ierr = PCPostSolve(coarse_pc,pcbddc->coarse_ksp);CHKERRQ(ierr); 546512edc857SStefano Zampini } else { 5466964fefecSStefano Zampini ierr = KSPSolve(pcbddc->coarse_ksp,rhs,sol);CHKERRQ(ierr); 546712edc857SStefano Zampini } 54682701bc32SStefano Zampini } 54691d82a3b6SStefano Zampini /* we don't need the benign correction at coarser levels anymore */ 547027b6a85dSStefano Zampini if (pcbddc->benign_have_null && isbddc) { 547127b6a85dSStefano Zampini PC coarse_pc; 547227b6a85dSStefano Zampini PC_BDDC* coarsepcbddc; 547327b6a85dSStefano Zampini 547427b6a85dSStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&coarse_pc);CHKERRQ(ierr); 547527b6a85dSStefano Zampini coarsepcbddc = (PC_BDDC*)(coarse_pc->data); 547627b6a85dSStefano Zampini coarsepcbddc->benign_skip_correction = PETSC_TRUE; 54773bca92a6SStefano Zampini coarsepcbddc->benign_apply_coarse_only = PETSC_FALSE; 547827b6a85dSStefano Zampini } 547951694757SStefano Zampini if (nullsp) { 548051694757SStefano Zampini ierr = MatNullSpaceRemove(nullsp,sol);CHKERRQ(ierr); 548151694757SStefano Zampini } 548212edc857SStefano Zampini } 5483674ae819SStefano Zampini 5484674ae819SStefano Zampini /* Local solution on R nodes */ 54854fee134fSStefano Zampini if (pcis->n && !pcbddc->benign_apply_coarse_only) { 548680677318SStefano Zampini ierr = PCBDDCSolveSubstructureCorrection(pc,pcis->vec1_B,pcis->vec1_D,applytranspose);CHKERRQ(ierr); 54879f00e9b4SStefano Zampini } 54889f00e9b4SStefano Zampini /* communications from coarse sol to local primal nodes */ 54899f00e9b4SStefano Zampini ierr = PCBDDCScatterCoarseDataBegin(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 549012edc857SStefano Zampini ierr = PCBDDCScatterCoarseDataEnd(pc,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 5491674ae819SStefano Zampini 54924fee134fSStefano Zampini /* Sum contributions from the two levels */ 54934fee134fSStefano Zampini if (!pcbddc->benign_apply_coarse_only) { 5494dc359a40SStefano Zampini if (applytranspose) { 5495dc359a40SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 5496dc359a40SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_psi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5497dc359a40SStefano Zampini } else { 5498674ae819SStefano Zampini ierr = MatMultAdd(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 54998eeda7d8SStefano Zampini if (pcbddc->switch_static) { ierr = MatMultAdd(pcbddc->coarse_phi_D,pcbddc->vec1_P,pcis->vec1_D,pcis->vec1_D);CHKERRQ(ierr); } 5500dc359a40SStefano Zampini } 5501efc2fbd9SStefano Zampini /* store p0 */ 55024f1b2e48SStefano Zampini if (pcbddc->benign_n) { 5503efc2fbd9SStefano Zampini PetscScalar *array; 55044f1b2e48SStefano Zampini PetscInt j; 5505efc2fbd9SStefano Zampini 5506efc2fbd9SStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 55074f1b2e48SStefano Zampini for (j=0;j<pcbddc->benign_n;j++) pcbddc->benign_p0[j] = array[pcbddc->local_primal_size-pcbddc->benign_n+j]; 5508efc2fbd9SStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 5509efc2fbd9SStefano Zampini } 55104fee134fSStefano Zampini } else { /* expand the coarse solution */ 55114fee134fSStefano Zampini if (applytranspose) { 55124fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_psi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 55134fee134fSStefano Zampini } else { 55144fee134fSStefano Zampini ierr = MatMult(pcbddc->coarse_phi_B,pcbddc->vec1_P,pcis->vec1_B);CHKERRQ(ierr); 55154fee134fSStefano Zampini } 55164fee134fSStefano Zampini } 5517674ae819SStefano Zampini PetscFunctionReturn(0); 5518674ae819SStefano Zampini } 5519674ae819SStefano Zampini 552012edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataBegin(PC pc,InsertMode imode, ScatterMode smode) 5521674ae819SStefano Zampini { 5522674ae819SStefano Zampini PetscErrorCode ierr; 5523674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 552458da7f69SStefano Zampini PetscScalar *array; 552512edc857SStefano Zampini Vec from,to; 5526674ae819SStefano Zampini 5527674ae819SStefano Zampini PetscFunctionBegin; 552812edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 552912edc857SStefano Zampini from = pcbddc->coarse_vec; 553012edc857SStefano Zampini to = pcbddc->vec1_P; 553112edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 553212edc857SStefano Zampini Vec tvec; 553358da7f69SStefano Zampini 553458da7f69SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 553558da7f69SStefano Zampini ierr = VecResetArray(tvec);CHKERRQ(ierr); 553612edc857SStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 553758da7f69SStefano Zampini ierr = VecGetArray(tvec,&array);CHKERRQ(ierr); 553858da7f69SStefano Zampini ierr = VecPlaceArray(from,array);CHKERRQ(ierr); 553958da7f69SStefano Zampini ierr = VecRestoreArray(tvec,&array);CHKERRQ(ierr); 554012edc857SStefano Zampini } 554112edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 554212edc857SStefano Zampini from = pcbddc->vec1_P; 554312edc857SStefano Zampini to = pcbddc->coarse_vec; 554412edc857SStefano Zampini } 554512edc857SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 5546674ae819SStefano Zampini PetscFunctionReturn(0); 5547674ae819SStefano Zampini } 5548674ae819SStefano Zampini 554912edc857SStefano Zampini PetscErrorCode PCBDDCScatterCoarseDataEnd(PC pc, InsertMode imode, ScatterMode smode) 5550674ae819SStefano Zampini { 5551674ae819SStefano Zampini PetscErrorCode ierr; 5552674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)(pc->data); 555358da7f69SStefano Zampini PetscScalar *array; 555412edc857SStefano Zampini Vec from,to; 5555674ae819SStefano Zampini 5556674ae819SStefano Zampini PetscFunctionBegin; 555712edc857SStefano Zampini if (smode == SCATTER_REVERSE) { /* from global to local -> get data from coarse solution */ 555812edc857SStefano Zampini from = pcbddc->coarse_vec; 555912edc857SStefano Zampini to = pcbddc->vec1_P; 556012edc857SStefano Zampini } else { /* from local to global -> put data in coarse right hand side */ 556112edc857SStefano Zampini from = pcbddc->vec1_P; 556212edc857SStefano Zampini to = pcbddc->coarse_vec; 556312edc857SStefano Zampini } 556412edc857SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,from,to,imode,smode);CHKERRQ(ierr); 556512edc857SStefano Zampini if (smode == SCATTER_FORWARD) { 556612edc857SStefano Zampini if (pcbddc->coarse_ksp) { /* get array from coarse processes */ 556712edc857SStefano Zampini Vec tvec; 556858da7f69SStefano Zampini 556912edc857SStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&tvec);CHKERRQ(ierr); 557058da7f69SStefano Zampini ierr = VecGetArray(to,&array);CHKERRQ(ierr); 557158da7f69SStefano Zampini ierr = VecPlaceArray(tvec,array);CHKERRQ(ierr); 557258da7f69SStefano Zampini ierr = VecRestoreArray(to,&array);CHKERRQ(ierr); 557358da7f69SStefano Zampini } 557458da7f69SStefano Zampini } else { 557558da7f69SStefano Zampini if (pcbddc->coarse_ksp) { /* restore array of pcbddc->coarse_vec */ 557658da7f69SStefano Zampini ierr = VecResetArray(from);CHKERRQ(ierr); 557712edc857SStefano Zampini } 557812edc857SStefano Zampini } 5579674ae819SStefano Zampini PetscFunctionReturn(0); 5580674ae819SStefano Zampini } 5581674ae819SStefano Zampini 5582984c4197SStefano Zampini /* uncomment for testing purposes */ 5583984c4197SStefano Zampini /* #define PETSC_MISSING_LAPACK_GESVD 1 */ 5584674ae819SStefano Zampini PetscErrorCode PCBDDCConstraintsSetUp(PC pc) 5585674ae819SStefano Zampini { 5586674ae819SStefano Zampini PetscErrorCode ierr; 5587674ae819SStefano Zampini PC_IS* pcis = (PC_IS*)(pc->data); 5588674ae819SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 5589674ae819SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 5590984c4197SStefano Zampini /* one and zero */ 5591984c4197SStefano Zampini PetscScalar one=1.0,zero=0.0; 5592984c4197SStefano Zampini /* space to store constraints and their local indices */ 55939162d606SStefano Zampini PetscScalar *constraints_data; 55949162d606SStefano Zampini PetscInt *constraints_idxs,*constraints_idxs_B; 55959162d606SStefano Zampini PetscInt *constraints_idxs_ptr,*constraints_data_ptr; 55969162d606SStefano Zampini PetscInt *constraints_n; 5597984c4197SStefano Zampini /* iterators */ 5598b3d85658SStefano Zampini PetscInt i,j,k,total_counts,total_counts_cc,cum; 5599984c4197SStefano Zampini /* BLAS integers */ 5600e310c8b4SStefano Zampini PetscBLASInt lwork,lierr; 5601e310c8b4SStefano Zampini PetscBLASInt Blas_N,Blas_M,Blas_K,Blas_one=1; 5602c4303822SStefano Zampini PetscBLASInt Blas_LDA,Blas_LDB,Blas_LDC; 5603727cdba6SStefano Zampini /* reuse */ 56040e6343abSStefano Zampini PetscInt olocal_primal_size,olocal_primal_size_cc; 56050e6343abSStefano Zampini PetscInt *olocal_primal_ref_node,*olocal_primal_ref_mult; 5606984c4197SStefano Zampini /* change of basis */ 5607b3d85658SStefano Zampini PetscBool qr_needed; 56089162d606SStefano Zampini PetscBT change_basis,qr_needed_idx; 5609984c4197SStefano Zampini /* auxiliary stuff */ 561064efe560SStefano Zampini PetscInt *nnz,*is_indices; 56118a0068c3SStefano Zampini PetscInt ncc; 5612984c4197SStefano Zampini /* some quantities */ 561345a1bb75SStefano Zampini PetscInt n_vertices,total_primal_vertices,valid_constraints; 5614a58a30b4SStefano Zampini PetscInt size_of_constraint,max_size_of_constraint=0,max_constraints,temp_constraints; 561557715f18SStefano Zampini PetscReal tol; /* tolerance for retaining eigenmodes */ 5616984c4197SStefano Zampini 5617674ae819SStefano Zampini PetscFunctionBegin; 561857715f18SStefano Zampini tol = PetscSqrtReal(PETSC_SMALL); 56198e61c736SStefano Zampini /* Destroy Mat objects computed previously */ 56208e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 56218e61c736SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 562216909a7fSStefano Zampini ierr = MatDestroy(&pcbddc->switch_static_change);CHKERRQ(ierr); 5623088faed8SStefano Zampini /* save info on constraints from previous setup (if any) */ 5624088faed8SStefano Zampini olocal_primal_size = pcbddc->local_primal_size; 56250e6343abSStefano Zampini olocal_primal_size_cc = pcbddc->local_primal_size_cc; 56260e6343abSStefano Zampini ierr = PetscMalloc2(olocal_primal_size_cc,&olocal_primal_ref_node,olocal_primal_size_cc,&olocal_primal_ref_mult);CHKERRQ(ierr); 56270e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_node,pcbddc->local_primal_ref_node,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 56280e6343abSStefano Zampini ierr = PetscMemcpy(olocal_primal_ref_mult,pcbddc->local_primal_ref_mult,olocal_primal_size_cc*sizeof(PetscInt));CHKERRQ(ierr); 56290e6343abSStefano Zampini ierr = PetscFree2(pcbddc->local_primal_ref_node,pcbddc->local_primal_ref_mult);CHKERRQ(ierr); 5630088faed8SStefano Zampini ierr = PetscFree(pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 5631cf5a6209SStefano Zampini 5632cf5a6209SStefano Zampini if (!pcbddc->adaptive_selection) { 56339162d606SStefano Zampini IS ISForVertices,*ISForFaces,*ISForEdges; 5634cf5a6209SStefano Zampini MatNullSpace nearnullsp; 5635cf5a6209SStefano Zampini const Vec *nearnullvecs; 5636cf5a6209SStefano Zampini Vec *localnearnullsp; 5637cf5a6209SStefano Zampini PetscScalar *array; 5638cf5a6209SStefano Zampini PetscInt n_ISForFaces,n_ISForEdges,nnsp_size; 5639cf5a6209SStefano Zampini PetscBool nnsp_has_cnst; 5640674ae819SStefano Zampini /* LAPACK working arrays for SVD or POD */ 5641b3d85658SStefano Zampini PetscBool skip_lapack,boolforchange; 5642674ae819SStefano Zampini PetscScalar *work; 5643674ae819SStefano Zampini PetscReal *singular_vals; 5644674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5645674ae819SStefano Zampini PetscReal *rwork; 5646674ae819SStefano Zampini #endif 5647674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5648674ae819SStefano Zampini PetscScalar *temp_basis,*correlation_mat; 5649674ae819SStefano Zampini #else 5650964fefecSStefano Zampini PetscBLASInt dummy_int=1; 5651964fefecSStefano Zampini PetscScalar dummy_scalar=1.; 5652674ae819SStefano Zampini #endif 5653674ae819SStefano Zampini 5654674ae819SStefano Zampini /* Get index sets for faces, edges and vertices from graph */ 5655d06fc5fdSStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,&n_ISForFaces,&ISForFaces,&n_ISForEdges,&ISForEdges,&ISForVertices);CHKERRQ(ierr); 5656e4d548c7SStefano Zampini /* print some info */ 56575c643e28SStefano Zampini if (pcbddc->dbg_flag && (!pcbddc->sub_schurs || pcbddc->sub_schurs_rebuild)) { 5658e4d548c7SStefano Zampini PetscInt nv; 5659e4d548c7SStefano Zampini 5660c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(pcbddc->mat_graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 5661e4d548c7SStefano Zampini ierr = ISGetSize(ISForVertices,&nv);CHKERRQ(ierr); 5662e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5663e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 5664e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 5665e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,n_ISForEdges,pcbddc->use_edges);CHKERRQ(ierr); 5666e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,n_ISForFaces,pcbddc->use_faces);CHKERRQ(ierr); 5667e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 5668e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 5669e4d548c7SStefano Zampini } 5670e4d548c7SStefano Zampini 5671d06fc5fdSStefano Zampini /* free unneeded index sets */ 5672d06fc5fdSStefano Zampini if (!pcbddc->use_vertices) { 5673d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 5674674ae819SStefano Zampini } 5675d06fc5fdSStefano Zampini if (!pcbddc->use_edges) { 5676d06fc5fdSStefano Zampini for (i=0;i<n_ISForEdges;i++) { 5677d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 5678d06fc5fdSStefano Zampini } 5679d06fc5fdSStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 5680d06fc5fdSStefano Zampini n_ISForEdges = 0; 5681d06fc5fdSStefano Zampini } 5682d06fc5fdSStefano Zampini if (!pcbddc->use_faces) { 5683d06fc5fdSStefano Zampini for (i=0;i<n_ISForFaces;i++) { 5684d06fc5fdSStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 5685d06fc5fdSStefano Zampini } 5686d06fc5fdSStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 5687d06fc5fdSStefano Zampini n_ISForFaces = 0; 5688d06fc5fdSStefano Zampini } 568970022509SStefano Zampini 5690674ae819SStefano Zampini /* check if near null space is attached to global mat */ 5691674ae819SStefano Zampini ierr = MatGetNearNullSpace(pc->pmat,&nearnullsp);CHKERRQ(ierr); 5692674ae819SStefano Zampini if (nearnullsp) { 5693674ae819SStefano Zampini ierr = MatNullSpaceGetVecs(nearnullsp,&nnsp_has_cnst,&nnsp_size,&nearnullvecs);CHKERRQ(ierr); 5694f4ddd8eeSStefano Zampini /* remove any stored info */ 5695f4ddd8eeSStefano Zampini ierr = MatNullSpaceDestroy(&pcbddc->onearnullspace);CHKERRQ(ierr); 5696f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5697f4ddd8eeSStefano Zampini /* store information for BDDC solver reuse */ 5698f4ddd8eeSStefano Zampini ierr = PetscObjectReference((PetscObject)nearnullsp);CHKERRQ(ierr); 5699f4ddd8eeSStefano Zampini pcbddc->onearnullspace = nearnullsp; 5700473ba861SJed Brown ierr = PetscMalloc1(nnsp_size,&pcbddc->onearnullvecs_state);CHKERRQ(ierr); 5701f4ddd8eeSStefano Zampini for (i=0;i<nnsp_size;i++) { 5702f4ddd8eeSStefano Zampini ierr = PetscObjectStateGet((PetscObject)nearnullvecs[i],&pcbddc->onearnullvecs_state[i]);CHKERRQ(ierr); 5703f4ddd8eeSStefano Zampini } 5704984c4197SStefano Zampini } else { /* if near null space is not provided BDDC uses constants by default */ 5705984c4197SStefano Zampini nnsp_size = 0; 5706674ae819SStefano Zampini nnsp_has_cnst = PETSC_TRUE; 5707674ae819SStefano Zampini } 5708984c4197SStefano Zampini /* get max number of constraints on a single cc */ 5709984c4197SStefano Zampini max_constraints = nnsp_size; 5710984c4197SStefano Zampini if (nnsp_has_cnst) max_constraints++; 5711984c4197SStefano Zampini 5712674ae819SStefano Zampini /* 5713674ae819SStefano Zampini Evaluate maximum storage size needed by the procedure 57149162d606SStefano Zampini - Indices for connected component i stored at "constraints_idxs + constraints_idxs_ptr[i]" 57159162d606SStefano Zampini - Values for constraints on connected component i stored at "constraints_data + constraints_data_ptr[i]" 57169162d606SStefano Zampini There can be multiple constraints per connected component 5717674ae819SStefano Zampini */ 5718674ae819SStefano Zampini n_vertices = 0; 5719674ae819SStefano Zampini if (ISForVertices) { 5720674ae819SStefano Zampini ierr = ISGetSize(ISForVertices,&n_vertices);CHKERRQ(ierr); 5721674ae819SStefano Zampini } 57229162d606SStefano Zampini ncc = n_vertices+n_ISForFaces+n_ISForEdges; 57239162d606SStefano Zampini ierr = PetscMalloc3(ncc+1,&constraints_idxs_ptr,ncc+1,&constraints_data_ptr,ncc,&constraints_n);CHKERRQ(ierr); 57249162d606SStefano Zampini 57259162d606SStefano Zampini total_counts = n_ISForFaces+n_ISForEdges; 57269162d606SStefano Zampini total_counts *= max_constraints; 5727674ae819SStefano Zampini total_counts += n_vertices; 57284641a718SStefano Zampini ierr = PetscBTCreate(total_counts,&change_basis);CHKERRQ(ierr); 57299162d606SStefano Zampini 5730674ae819SStefano Zampini total_counts = 0; 5731674ae819SStefano Zampini max_size_of_constraint = 0; 5732674ae819SStefano Zampini for (i=0;i<n_ISForEdges+n_ISForFaces;i++) { 57339162d606SStefano Zampini IS used_is; 5734674ae819SStefano Zampini if (i<n_ISForEdges) { 57359162d606SStefano Zampini used_is = ISForEdges[i]; 5736674ae819SStefano Zampini } else { 57379162d606SStefano Zampini used_is = ISForFaces[i-n_ISForEdges]; 5738674ae819SStefano Zampini } 57399162d606SStefano Zampini ierr = ISGetSize(used_is,&j);CHKERRQ(ierr); 5740674ae819SStefano Zampini total_counts += j; 5741674ae819SStefano Zampini max_size_of_constraint = PetscMax(j,max_size_of_constraint); 5742674ae819SStefano Zampini } 57439162d606SStefano 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); 57449162d606SStefano Zampini 5745984c4197SStefano Zampini /* get local part of global near null space vectors */ 5746785e854fSJed Brown ierr = PetscMalloc1(nnsp_size,&localnearnullsp);CHKERRQ(ierr); 5747984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 5748984c4197SStefano Zampini ierr = VecDuplicate(pcis->vec1_N,&localnearnullsp[k]);CHKERRQ(ierr); 5749e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5750e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,nearnullvecs[k],localnearnullsp[k],INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 5751984c4197SStefano Zampini } 5752674ae819SStefano Zampini 5753242a89d7SStefano Zampini /* whether or not to skip lapack calls */ 5754242a89d7SStefano Zampini skip_lapack = PETSC_TRUE; 5755a773dcb8SStefano Zampini if (n_ISForFaces+n_ISForEdges && max_constraints > 1 && !pcbddc->use_nnsp_true) skip_lapack = PETSC_FALSE; 5756242a89d7SStefano Zampini 5757984c4197SStefano Zampini /* First we issue queries to allocate optimal workspace for LAPACKgesvd (or LAPACKsyev if SVD is missing) */ 5758a773dcb8SStefano Zampini if (!skip_lapack) { 5759674ae819SStefano Zampini PetscScalar temp_work; 5760911cabfeSStefano Zampini 5761674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5762984c4197SStefano Zampini /* Proper Orthogonal Decomposition (POD) using the snapshot method */ 5763785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&correlation_mat);CHKERRQ(ierr); 5764785e854fSJed Brown ierr = PetscMalloc1(max_constraints,&singular_vals);CHKERRQ(ierr); 5765785e854fSJed Brown ierr = PetscMalloc1(max_size_of_constraint*max_constraints,&temp_basis);CHKERRQ(ierr); 5766674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5767785e854fSJed Brown ierr = PetscMalloc1(3*max_constraints,&rwork);CHKERRQ(ierr); 5768674ae819SStefano Zampini #endif 5769674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5770c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 5771c8244a33SStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_LDA);CHKERRQ(ierr); 5772674ae819SStefano Zampini lwork = -1; 5773674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5774674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5775c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,&lierr)); 5776674ae819SStefano Zampini #else 5777c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,&temp_work,&lwork,rwork,&lierr)); 5778674ae819SStefano Zampini #endif 5779674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5780984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to SYEV Lapack routine %d",(int)lierr); 5781674ae819SStefano Zampini #else /* on missing GESVD */ 5782674ae819SStefano Zampini /* SVD */ 5783674ae819SStefano Zampini PetscInt max_n,min_n; 5784674ae819SStefano Zampini max_n = max_size_of_constraint; 5785984c4197SStefano Zampini min_n = max_constraints; 5786984c4197SStefano Zampini if (max_size_of_constraint < max_constraints) { 5787674ae819SStefano Zampini min_n = max_size_of_constraint; 5788984c4197SStefano Zampini max_n = max_constraints; 5789674ae819SStefano Zampini } 5790785e854fSJed Brown ierr = PetscMalloc1(min_n,&singular_vals);CHKERRQ(ierr); 5791674ae819SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5792785e854fSJed Brown ierr = PetscMalloc1(5*min_n,&rwork);CHKERRQ(ierr); 5793674ae819SStefano Zampini #endif 5794674ae819SStefano Zampini /* now we evaluate the optimal workspace using query with lwork=-1 */ 5795674ae819SStefano Zampini lwork = -1; 5796e310c8b4SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_M);CHKERRQ(ierr); 5797e310c8b4SStefano Zampini ierr = PetscBLASIntCast(min_n,&Blas_N);CHKERRQ(ierr); 5798b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(max_n,&Blas_LDA);CHKERRQ(ierr); 5799674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5800674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 58019162d606SStefano 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)); 5802674ae819SStefano Zampini #else 58039162d606SStefano 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)); 5804674ae819SStefano Zampini #endif 5805674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5806984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GESVD Lapack routine %d",(int)lierr); 5807984c4197SStefano Zampini #endif /* on missing GESVD */ 5808674ae819SStefano Zampini /* Allocate optimal workspace */ 5809674ae819SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(temp_work),&lwork);CHKERRQ(ierr); 5810854ce69bSBarry Smith ierr = PetscMalloc1(lwork,&work);CHKERRQ(ierr); 5811674ae819SStefano Zampini } 5812674ae819SStefano Zampini /* Now we can loop on constraining sets */ 5813674ae819SStefano Zampini total_counts = 0; 58149162d606SStefano Zampini constraints_idxs_ptr[0] = 0; 58159162d606SStefano Zampini constraints_data_ptr[0] = 0; 5816674ae819SStefano Zampini /* vertices */ 58179162d606SStefano Zampini if (n_vertices) { 5818674ae819SStefano Zampini ierr = ISGetIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 58199162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs,is_indices,n_vertices*sizeof(PetscInt));CHKERRQ(ierr); 5820674ae819SStefano Zampini for (i=0;i<n_vertices;i++) { 58219162d606SStefano Zampini constraints_n[total_counts] = 1; 58229162d606SStefano Zampini constraints_data[total_counts] = 1.0; 58239162d606SStefano Zampini constraints_idxs_ptr[total_counts+1] = constraints_idxs_ptr[total_counts]+1; 58249162d606SStefano Zampini constraints_data_ptr[total_counts+1] = constraints_data_ptr[total_counts]+1; 5825674ae819SStefano Zampini total_counts++; 5826674ae819SStefano Zampini } 5827674ae819SStefano Zampini ierr = ISRestoreIndices(ISForVertices,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5828674ae819SStefano Zampini n_vertices = total_counts; 5829674ae819SStefano Zampini } 5830984c4197SStefano Zampini 5831674ae819SStefano Zampini /* edges and faces */ 58329162d606SStefano Zampini total_counts_cc = total_counts; 5833911cabfeSStefano Zampini for (ncc=0;ncc<n_ISForEdges+n_ISForFaces;ncc++) { 58349162d606SStefano Zampini IS used_is; 58359162d606SStefano Zampini PetscBool idxs_copied = PETSC_FALSE; 58369162d606SStefano Zampini 5837911cabfeSStefano Zampini if (ncc<n_ISForEdges) { 58389162d606SStefano Zampini used_is = ISForEdges[ncc]; 5839984c4197SStefano Zampini boolforchange = pcbddc->use_change_of_basis; /* change or not the basis on the edge */ 5840674ae819SStefano Zampini } else { 58419162d606SStefano Zampini used_is = ISForFaces[ncc-n_ISForEdges]; 5842984c4197SStefano Zampini boolforchange = (PetscBool)(pcbddc->use_change_of_basis && pcbddc->use_change_on_faces); /* change or not the basis on the face */ 5843674ae819SStefano Zampini } 5844674ae819SStefano Zampini temp_constraints = 0; /* zero the number of constraints I have on this conn comp */ 58459162d606SStefano Zampini 58469162d606SStefano Zampini ierr = ISGetSize(used_is,&size_of_constraint);CHKERRQ(ierr); 58479162d606SStefano Zampini ierr = ISGetIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 5848984c4197SStefano Zampini /* change of basis should not be performed on local periodic nodes */ 5849984c4197SStefano Zampini if (pcbddc->mat_graph->mirrors && pcbddc->mat_graph->mirrors[is_indices[0]]) boolforchange = PETSC_FALSE; 5850674ae819SStefano Zampini if (nnsp_has_cnst) { 58515b08dc53SStefano Zampini PetscScalar quad_value; 58529162d606SStefano Zampini 58539162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 58549162d606SStefano Zampini idxs_copied = PETSC_TRUE; 58559162d606SStefano Zampini 5856a773dcb8SStefano Zampini if (!pcbddc->use_nnsp_true) { 5857674ae819SStefano Zampini quad_value = (PetscScalar)(1.0/PetscSqrtReal((PetscReal)size_of_constraint)); 5858a773dcb8SStefano Zampini } else { 5859a773dcb8SStefano Zampini quad_value = 1.0; 5860a773dcb8SStefano Zampini } 5861674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 58629162d606SStefano Zampini constraints_data[constraints_data_ptr[total_counts_cc]+j] = quad_value; 5863674ae819SStefano Zampini } 58649162d606SStefano Zampini temp_constraints++; 5865674ae819SStefano Zampini total_counts++; 5866674ae819SStefano Zampini } 5867674ae819SStefano Zampini for (k=0;k<nnsp_size;k++) { 5868984c4197SStefano Zampini PetscReal real_value; 58699162d606SStefano Zampini PetscScalar *ptr_to_data; 58709162d606SStefano Zampini 5871984c4197SStefano Zampini ierr = VecGetArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 58729162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]+temp_constraints*size_of_constraint]; 5873674ae819SStefano Zampini for (j=0;j<size_of_constraint;j++) { 58749162d606SStefano Zampini ptr_to_data[j] = array[is_indices[j]]; 5875674ae819SStefano Zampini } 5876984c4197SStefano Zampini ierr = VecRestoreArrayRead(localnearnullsp[k],(const PetscScalar**)&array);CHKERRQ(ierr); 5877984c4197SStefano Zampini /* check if array is null on the connected component */ 5878e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 58799162d606SStefano Zampini PetscStackCallBLAS("BLASasum",real_value = BLASasum_(&Blas_N,ptr_to_data,&Blas_one)); 588057715f18SStefano Zampini if (real_value > tol*size_of_constraint) { /* keep indices and values */ 5881674ae819SStefano Zampini temp_constraints++; 5882674ae819SStefano Zampini total_counts++; 58839162d606SStefano Zampini if (!idxs_copied) { 58849162d606SStefano Zampini ierr = PetscMemcpy(constraints_idxs + constraints_idxs_ptr[total_counts_cc],is_indices,size_of_constraint*sizeof(PetscInt));CHKERRQ(ierr); 58859162d606SStefano Zampini idxs_copied = PETSC_TRUE; 5886674ae819SStefano Zampini } 5887674ae819SStefano Zampini } 58889162d606SStefano Zampini } 58899162d606SStefano Zampini ierr = ISRestoreIndices(used_is,(const PetscInt**)&is_indices);CHKERRQ(ierr); 589045a1bb75SStefano Zampini valid_constraints = temp_constraints; 5891eb97c9d2SStefano Zampini if (!pcbddc->use_nnsp_true && temp_constraints) { 5892a773dcb8SStefano Zampini if (temp_constraints == 1) { /* just normalize the constraint */ 58939162d606SStefano Zampini PetscScalar norm,*ptr_to_data; 58949162d606SStefano Zampini 58959162d606SStefano Zampini ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5896a773dcb8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 58979162d606SStefano Zampini PetscStackCallBLAS("BLASdot",norm = BLASdot_(&Blas_N,ptr_to_data,&Blas_one,ptr_to_data,&Blas_one)); 5898a773dcb8SStefano Zampini norm = 1.0/PetscSqrtReal(PetscRealPart(norm)); 58999162d606SStefano Zampini PetscStackCallBLAS("BLASscal",BLASscal_(&Blas_N,&norm,ptr_to_data,&Blas_one)); 5900a773dcb8SStefano Zampini } else { /* perform SVD */ 59019162d606SStefano Zampini PetscScalar *ptr_to_data = &constraints_data[constraints_data_ptr[total_counts_cc]]; 5902674ae819SStefano Zampini 5903674ae819SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5904984c4197SStefano Zampini /* SVD: Y = U*S*V^H -> U (eigenvectors of Y*Y^H) = Y*V*(S)^\dag 5905984c4197SStefano Zampini POD: Y^H*Y = V*D*V^H, D = S^H*S -> U = Y*V*D^(-1/2) 5906984c4197SStefano Zampini -> When PETSC_USE_COMPLEX and PETSC_MISSING_LAPACK_GESVD are defined 5907984c4197SStefano Zampini the constraints basis will differ (by a complex factor with absolute value equal to 1) 5908984c4197SStefano Zampini from that computed using LAPACKgesvd 5909984c4197SStefano Zampini -> This is due to a different computation of eigenvectors in LAPACKheev 5910984c4197SStefano Zampini -> The quality of the POD-computed basis will be the same */ 5911984c4197SStefano Zampini ierr = PetscMemzero(correlation_mat,temp_constraints*temp_constraints*sizeof(PetscScalar));CHKERRQ(ierr); 5912674ae819SStefano Zampini /* Store upper triangular part of correlation matrix */ 5913e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 5914984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5915674ae819SStefano Zampini for (j=0;j<temp_constraints;j++) { 5916674ae819SStefano Zampini for (k=0;k<j+1;k++) { 59179162d606SStefano 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)); 5918674ae819SStefano Zampini } 5919674ae819SStefano Zampini } 5920e310c8b4SStefano Zampini /* compute eigenvalues and eigenvectors of correlation matrix */ 5921e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5922e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDA);CHKERRQ(ierr); 5923674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 5924c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,&lierr)); 5925674ae819SStefano Zampini #else 5926c8244a33SStefano Zampini PetscStackCallBLAS("LAPACKsyev",LAPACKsyev_("V","U",&Blas_N,correlation_mat,&Blas_LDA,singular_vals,work,&lwork,rwork,&lierr)); 5927674ae819SStefano Zampini #endif 5928674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5929984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in SYEV Lapack routine %d",(int)lierr); 5930984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKsyev gives eigs in ascending order */ 5931674ae819SStefano Zampini j = 0; 5932984c4197SStefano Zampini while (j < temp_constraints && singular_vals[j] < tol) j++; 5933674ae819SStefano Zampini total_counts = total_counts-j; 593445a1bb75SStefano Zampini valid_constraints = temp_constraints-j; 5935e310c8b4SStefano Zampini /* scale and copy POD basis into used quadrature memory */ 5936c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5937c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5938c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_K);CHKERRQ(ierr); 5939c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5940c4303822SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_LDB);CHKERRQ(ierr); 5941c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 5942674ae819SStefano Zampini if (j<temp_constraints) { 5943984c4197SStefano Zampini PetscInt ii; 5944984c4197SStefano Zampini for (k=j;k<temp_constraints;k++) singular_vals[k] = 1.0/PetscSqrtReal(singular_vals[k]); 5945674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 59469162d606SStefano 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)); 5947674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5948984c4197SStefano Zampini for (k=0;k<temp_constraints-j;k++) { 5949674ae819SStefano Zampini for (ii=0;ii<size_of_constraint;ii++) { 59509162d606SStefano 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]; 5951674ae819SStefano Zampini } 5952674ae819SStefano Zampini } 5953674ae819SStefano Zampini } 5954674ae819SStefano Zampini #else /* on missing GESVD */ 5955e310c8b4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 5956e310c8b4SStefano Zampini ierr = PetscBLASIntCast(temp_constraints,&Blas_N);CHKERRQ(ierr); 5957b7d8b9f8SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 5958674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 5959674ae819SStefano Zampini #if !defined(PETSC_USE_COMPLEX) 59609162d606SStefano 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)); 5961674ae819SStefano Zampini #else 59629162d606SStefano 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)); 5963674ae819SStefano Zampini #endif 5964984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GESVD Lapack routine %d",(int)lierr); 5965674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 5966984c4197SStefano Zampini /* retain eigenvalues greater than tol: note that LAPACKgesvd gives eigs in descending order */ 5967e310c8b4SStefano Zampini k = temp_constraints; 5968e310c8b4SStefano Zampini if (k > size_of_constraint) k = size_of_constraint; 5969674ae819SStefano Zampini j = 0; 5970e310c8b4SStefano Zampini while (j < k && singular_vals[k-j-1] < tol) j++; 597145a1bb75SStefano Zampini valid_constraints = k-j; 5972911cabfeSStefano Zampini total_counts = total_counts-temp_constraints+valid_constraints; 5973984c4197SStefano Zampini #endif /* on missing GESVD */ 5974674ae819SStefano Zampini } 5975a773dcb8SStefano Zampini } 59769162d606SStefano Zampini /* update pointers information */ 59779162d606SStefano Zampini if (valid_constraints) { 59789162d606SStefano Zampini constraints_n[total_counts_cc] = valid_constraints; 59799162d606SStefano Zampini constraints_idxs_ptr[total_counts_cc+1] = constraints_idxs_ptr[total_counts_cc]+size_of_constraint; 59809162d606SStefano Zampini constraints_data_ptr[total_counts_cc+1] = constraints_data_ptr[total_counts_cc]+size_of_constraint*valid_constraints; 59819162d606SStefano Zampini /* set change_of_basis flag */ 598245a1bb75SStefano Zampini if (boolforchange) { 5983b3d85658SStefano Zampini PetscBTSet(change_basis,total_counts_cc); 59849162d606SStefano Zampini } 5985b3d85658SStefano Zampini total_counts_cc++; 598645a1bb75SStefano Zampini } 598745a1bb75SStefano Zampini } 5988984c4197SStefano Zampini /* free workspace */ 59898f1c130eSStefano Zampini if (!skip_lapack) { 5990984c4197SStefano Zampini ierr = PetscFree(work);CHKERRQ(ierr); 5991984c4197SStefano Zampini #if defined(PETSC_USE_COMPLEX) 5992984c4197SStefano Zampini ierr = PetscFree(rwork);CHKERRQ(ierr); 5993984c4197SStefano Zampini #endif 5994984c4197SStefano Zampini ierr = PetscFree(singular_vals);CHKERRQ(ierr); 5995984c4197SStefano Zampini #if defined(PETSC_MISSING_LAPACK_GESVD) 5996984c4197SStefano Zampini ierr = PetscFree(correlation_mat);CHKERRQ(ierr); 5997984c4197SStefano Zampini ierr = PetscFree(temp_basis);CHKERRQ(ierr); 5998984c4197SStefano Zampini #endif 5999984c4197SStefano Zampini } 6000984c4197SStefano Zampini for (k=0;k<nnsp_size;k++) { 6001984c4197SStefano Zampini ierr = VecDestroy(&localnearnullsp[k]);CHKERRQ(ierr); 6002984c4197SStefano Zampini } 6003984c4197SStefano Zampini ierr = PetscFree(localnearnullsp);CHKERRQ(ierr); 6004cf5a6209SStefano Zampini /* free index sets of faces, edges and vertices */ 6005cf5a6209SStefano Zampini for (i=0;i<n_ISForFaces;i++) { 6006cf5a6209SStefano Zampini ierr = ISDestroy(&ISForFaces[i]);CHKERRQ(ierr); 6007cf5a6209SStefano Zampini } 6008cf5a6209SStefano Zampini if (n_ISForFaces) { 6009cf5a6209SStefano Zampini ierr = PetscFree(ISForFaces);CHKERRQ(ierr); 6010cf5a6209SStefano Zampini } 6011cf5a6209SStefano Zampini for (i=0;i<n_ISForEdges;i++) { 6012cf5a6209SStefano Zampini ierr = ISDestroy(&ISForEdges[i]);CHKERRQ(ierr); 6013cf5a6209SStefano Zampini } 6014cf5a6209SStefano Zampini if (n_ISForEdges) { 6015cf5a6209SStefano Zampini ierr = PetscFree(ISForEdges);CHKERRQ(ierr); 6016cf5a6209SStefano Zampini } 6017cf5a6209SStefano Zampini ierr = ISDestroy(&ISForVertices);CHKERRQ(ierr); 601808122e43SStefano Zampini } else { 601908122e43SStefano Zampini PCBDDCSubSchurs sub_schurs = pcbddc->sub_schurs; 6020984c4197SStefano Zampini 602108122e43SStefano Zampini total_counts = 0; 602208122e43SStefano Zampini n_vertices = 0; 6023d62866d3SStefano Zampini if (sub_schurs->is_vertices && pcbddc->use_vertices) { 6024d62866d3SStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 602508122e43SStefano Zampini } 602608122e43SStefano Zampini max_constraints = 0; 60279162d606SStefano Zampini total_counts_cc = 0; 602808122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 602908122e43SStefano Zampini total_counts += pcbddc->adaptive_constraints_n[i]; 60309162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) total_counts_cc++; 603108122e43SStefano Zampini max_constraints = PetscMax(max_constraints,pcbddc->adaptive_constraints_n[i]); 603208122e43SStefano Zampini } 60339162d606SStefano Zampini constraints_idxs_ptr = pcbddc->adaptive_constraints_idxs_ptr; 60349162d606SStefano Zampini constraints_data_ptr = pcbddc->adaptive_constraints_data_ptr; 60359162d606SStefano Zampini constraints_idxs = pcbddc->adaptive_constraints_idxs; 60369162d606SStefano Zampini constraints_data = pcbddc->adaptive_constraints_data; 603774d5cdf7SStefano Zampini /* constraints_n differs from pcbddc->adaptive_constraints_n */ 60389162d606SStefano Zampini ierr = PetscMalloc1(total_counts_cc,&constraints_n);CHKERRQ(ierr); 60399162d606SStefano Zampini total_counts_cc = 0; 60409162d606SStefano Zampini for (i=0;i<sub_schurs->n_subs+n_vertices;i++) { 60419162d606SStefano Zampini if (pcbddc->adaptive_constraints_n[i]) { 60429162d606SStefano Zampini constraints_n[total_counts_cc++] = pcbddc->adaptive_constraints_n[i]; 604308122e43SStefano Zampini } 604408122e43SStefano Zampini } 60459162d606SStefano Zampini #if 0 60469162d606SStefano Zampini printf("Found %d totals (%d)\n",total_counts_cc,total_counts); 60479162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 60489162d606SStefano Zampini printf("const %d, start %d",i,constraints_idxs_ptr[i]); 60499162d606SStefano Zampini printf(" end %d:\n",constraints_idxs_ptr[i+1]); 60509162d606SStefano Zampini for (j=constraints_idxs_ptr[i];j<constraints_idxs_ptr[i+1];j++) { 60519162d606SStefano Zampini printf(" %d",constraints_idxs[j]); 60529162d606SStefano Zampini } 60539162d606SStefano Zampini printf("\n"); 60549162d606SStefano Zampini printf("number of cc: %d\n",constraints_n[i]); 60559162d606SStefano Zampini } 60561b968477SStefano Zampini for (i=0;i<n_vertices;i++) { 60578bec7fa6SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] vertex %d, n %d\n",PetscGlobalRank,i,pcbddc->adaptive_constraints_n[i]); 60581b968477SStefano Zampini } 60591b968477SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 60608bec7fa6SStefano 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]); 60611b968477SStefano Zampini } 606208122e43SStefano Zampini #endif 606308122e43SStefano Zampini 60648bec7fa6SStefano Zampini max_size_of_constraint = 0; 60659162d606SStefano 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]); 60669162d606SStefano Zampini ierr = PetscMalloc1(constraints_idxs_ptr[total_counts_cc],&constraints_idxs_B);CHKERRQ(ierr); 606708122e43SStefano Zampini /* Change of basis */ 6068b3d85658SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&change_basis);CHKERRQ(ierr); 606908122e43SStefano Zampini if (pcbddc->use_change_of_basis) { 607008122e43SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 607108122e43SStefano Zampini if (PetscBTLookup(sub_schurs->is_edge,i) || pcbddc->use_change_on_faces) { 6072b3d85658SStefano Zampini ierr = PetscBTSet(change_basis,i+n_vertices);CHKERRQ(ierr); 607308122e43SStefano Zampini } 607408122e43SStefano Zampini } 607508122e43SStefano Zampini } 607608122e43SStefano Zampini } 6077984c4197SStefano Zampini pcbddc->local_primal_size = total_counts; 60784f1b2e48SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size+pcbddc->benign_n,&pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 607908122e43SStefano Zampini 60809162d606SStefano Zampini /* map constraints_idxs in boundary numbering */ 60819162d606SStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,constraints_idxs_ptr[total_counts_cc],constraints_idxs,&i,constraints_idxs_B);CHKERRQ(ierr); 6082eee23b56SStefano 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); 6083674ae819SStefano Zampini 6084674ae819SStefano Zampini /* Create constraint matrix */ 6085674ae819SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 608616f15bc4SStefano Zampini ierr = MatSetType(pcbddc->ConstraintMatrix,MATAIJ);CHKERRQ(ierr); 6087984c4197SStefano Zampini ierr = MatSetSizes(pcbddc->ConstraintMatrix,pcbddc->local_primal_size,pcis->n,pcbddc->local_primal_size,pcis->n);CHKERRQ(ierr); 6088984c4197SStefano Zampini 6089984c4197SStefano Zampini /* find primal_dofs: subdomain corners plus dofs selected as primal after change of basis */ 6090a717540cSStefano Zampini /* determine if a QR strategy is needed for change of basis */ 6091a717540cSStefano Zampini qr_needed = PETSC_FALSE; 609274d5cdf7SStefano Zampini ierr = PetscBTCreate(total_counts_cc,&qr_needed_idx);CHKERRQ(ierr); 6093984c4197SStefano Zampini total_primal_vertices=0; 6094b3d85658SStefano Zampini pcbddc->local_primal_size_cc = 0; 60959162d606SStefano Zampini for (i=0;i<total_counts_cc;i++) { 60969162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 609772b8c272SStefano Zampini if (size_of_constraint == 1 && pcbddc->mat_graph->custom_minimal_size) { 60989162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]]; 6099b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 610064efe560SStefano Zampini } else if (PetscBTLookup(change_basis,i)) { 61019162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 61029162d606SStefano Zampini pcbddc->primal_indices_local_idxs[total_primal_vertices++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 6103a717540cSStefano Zampini } 6104b3d85658SStefano Zampini pcbddc->local_primal_size_cc += constraints_n[i]; 610591af6908SStefano Zampini if (constraints_n[i] > 1 || pcbddc->use_qr_single) { 6106a717540cSStefano Zampini PetscBTSet(qr_needed_idx,i); 6107a717540cSStefano Zampini qr_needed = PETSC_TRUE; 6108a717540cSStefano Zampini } 6109fa434743SStefano Zampini } else { 6110b3d85658SStefano Zampini pcbddc->local_primal_size_cc += 1; 6111fa434743SStefano Zampini } 6112a717540cSStefano Zampini } 6113b371cd4fSStefano Zampini /* note that the local variable n_vertices used below stores the number of pointwise constraints */ 6114b371cd4fSStefano Zampini pcbddc->n_vertices = total_primal_vertices; 6115674ae819SStefano Zampini /* permute indices in order to have a sorted set of vertices */ 611670022509SStefano Zampini ierr = PetscSortInt(total_primal_vertices,pcbddc->primal_indices_local_idxs);CHKERRQ(ierr); 61174f1b2e48SStefano 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); 61180e6343abSStefano Zampini ierr = PetscMemcpy(pcbddc->local_primal_ref_node,pcbddc->primal_indices_local_idxs,total_primal_vertices*sizeof(PetscInt));CHKERRQ(ierr); 61190e6343abSStefano Zampini for (i=0;i<total_primal_vertices;i++) pcbddc->local_primal_ref_mult[i] = 1; 6120984c4197SStefano Zampini 6121984c4197SStefano Zampini /* nonzero structure of constraint matrix */ 612274d5cdf7SStefano Zampini /* and get reference dof for local constraints */ 6123785e854fSJed Brown ierr = PetscMalloc1(pcbddc->local_primal_size,&nnz);CHKERRQ(ierr); 6124984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) nnz[i] = 1; 612574d5cdf7SStefano Zampini 6126984c4197SStefano Zampini j = total_primal_vertices; 612774d5cdf7SStefano Zampini total_counts = total_primal_vertices; 6128b3d85658SStefano Zampini cum = total_primal_vertices; 61299162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 61304641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 6131b3d85658SStefano Zampini pcbddc->local_primal_ref_node[cum] = constraints_idxs[constraints_idxs_ptr[i]]; 6132b3d85658SStefano Zampini pcbddc->local_primal_ref_mult[cum] = constraints_n[i]; 6133b3d85658SStefano Zampini cum++; 61349162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 613574d5cdf7SStefano Zampini for (k=0;k<constraints_n[i];k++) { 613674d5cdf7SStefano Zampini pcbddc->primal_indices_local_idxs[total_counts++] = constraints_idxs[constraints_idxs_ptr[i]+k]; 613774d5cdf7SStefano Zampini nnz[j+k] = size_of_constraint; 613874d5cdf7SStefano Zampini } 61399162d606SStefano Zampini j += constraints_n[i]; 6140674ae819SStefano Zampini } 6141674ae819SStefano Zampini } 6142674ae819SStefano Zampini ierr = MatSeqAIJSetPreallocation(pcbddc->ConstraintMatrix,0,nnz);CHKERRQ(ierr); 6143674ae819SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 6144088faed8SStefano Zampini 6145674ae819SStefano Zampini /* set values in constraint matrix */ 6146984c4197SStefano Zampini for (i=0;i<total_primal_vertices;i++) { 61470e6343abSStefano Zampini ierr = MatSetValue(pcbddc->ConstraintMatrix,i,pcbddc->local_primal_ref_node[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 6148674ae819SStefano Zampini } 6149984c4197SStefano Zampini total_counts = total_primal_vertices; 61509162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 61514641a718SStefano Zampini if (!PetscBTLookup(change_basis,i)) { 61529162d606SStefano Zampini PetscInt *cols; 61539162d606SStefano Zampini 61549162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 61559162d606SStefano Zampini cols = constraints_idxs+constraints_idxs_ptr[i]; 61569162d606SStefano Zampini for (k=0;k<constraints_n[i];k++) { 61579162d606SStefano Zampini PetscInt row = total_counts+k; 61589162d606SStefano Zampini PetscScalar *vals; 61599162d606SStefano Zampini 61609162d606SStefano Zampini vals = constraints_data+constraints_data_ptr[i]+k*size_of_constraint; 61619162d606SStefano Zampini ierr = MatSetValues(pcbddc->ConstraintMatrix,1,&row,size_of_constraint,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 61629162d606SStefano Zampini } 61639162d606SStefano Zampini total_counts += constraints_n[i]; 6164674ae819SStefano Zampini } 6165674ae819SStefano Zampini } 6166674ae819SStefano Zampini /* assembling */ 6167674ae819SStefano Zampini ierr = MatAssemblyBegin(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6168674ae819SStefano Zampini ierr = MatAssemblyEnd(pcbddc->ConstraintMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 61693272d46bSStefano Zampini ierr = MatChop(pcbddc->ConstraintMatrix,PETSC_SMALL);CHKERRQ(ierr); 61703272d46bSStefano Zampini ierr = MatSeqAIJCompress(pcbddc->ConstraintMatrix,&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 61713272d46bSStefano Zampini ierr = MatViewFromOptions(pcbddc->ConstraintMatrix,NULL,"-pc_bddc_constraint_mat_view");CHKERRQ(ierr); 6172088faed8SStefano Zampini 6173984c4197SStefano Zampini /* 61746a9046bcSBarry Smith ierr = PetscViewerPushFormat(PETSC_VIEWER_STDOUT_SELF,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 6175984c4197SStefano Zampini ierr = MatView(pcbddc->ConstraintMatrix,(PetscViewer)0);CHKERRQ(ierr); 6176f159cad9SBarry Smith ierr = PetscViewerPopFormat(PETSC_VIEWER_STDOUT_SELF);CHKERRQ(ierr); 6177984c4197SStefano Zampini */ 6178674ae819SStefano Zampini /* Create matrix for change of basis. We don't need it in case pcbddc->use_change_of_basis is FALSE */ 6179674ae819SStefano Zampini if (pcbddc->use_change_of_basis) { 6180026de310SStefano Zampini /* dual and primal dofs on a single cc */ 6181984c4197SStefano Zampini PetscInt dual_dofs,primal_dofs; 6182984c4197SStefano Zampini /* working stuff for GEQRF */ 618381d9aea3SBarry Smith PetscScalar *qr_basis,*qr_tau = NULL,*qr_work,lqr_work_t; 6184984c4197SStefano Zampini PetscBLASInt lqr_work; 6185984c4197SStefano Zampini /* working stuff for UNGQR */ 6186984c4197SStefano Zampini PetscScalar *gqr_work,lgqr_work_t; 6187984c4197SStefano Zampini PetscBLASInt lgqr_work; 6188984c4197SStefano Zampini /* working stuff for TRTRS */ 6189984c4197SStefano Zampini PetscScalar *trs_rhs; 61903f08241aSStefano Zampini PetscBLASInt Blas_NRHS; 6191984c4197SStefano Zampini /* pointers for values insertion into change of basis matrix */ 6192984c4197SStefano Zampini PetscInt *start_rows,*start_cols; 6193984c4197SStefano Zampini PetscScalar *start_vals; 6194984c4197SStefano Zampini /* working stuff for values insertion */ 61954641a718SStefano Zampini PetscBT is_primal; 619664efe560SStefano Zampini PetscInt *aux_primal_numbering_B; 6197906d46d4SStefano Zampini /* matrix sizes */ 6198906d46d4SStefano Zampini PetscInt global_size,local_size; 6199906d46d4SStefano Zampini /* temporary change of basis */ 6200906d46d4SStefano Zampini Mat localChangeOfBasisMatrix; 6201cf5a6209SStefano Zampini /* extra space for debugging */ 6202cf5a6209SStefano Zampini PetscScalar *dbg_work; 6203984c4197SStefano Zampini 6204906d46d4SStefano Zampini /* local temporary change of basis acts on local interfaces -> dimension is n_B x n_B */ 6205906d46d4SStefano Zampini ierr = MatCreate(PETSC_COMM_SELF,&localChangeOfBasisMatrix);CHKERRQ(ierr); 620616f15bc4SStefano Zampini ierr = MatSetType(localChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 6207bbb9e6c6SStefano Zampini ierr = MatSetSizes(localChangeOfBasisMatrix,pcis->n,pcis->n,pcis->n,pcis->n);CHKERRQ(ierr); 6208906d46d4SStefano Zampini /* nonzeros for local mat */ 6209bbb9e6c6SStefano Zampini ierr = PetscMalloc1(pcis->n,&nnz);CHKERRQ(ierr); 62101dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6211bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) nnz[i]=1; 62121dd7afcfSStefano Zampini } else { 62131dd7afcfSStefano Zampini const PetscInt *ii; 62141dd7afcfSStefano Zampini PetscInt n; 62151dd7afcfSStefano Zampini PetscBool flg_row; 62161dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 62171dd7afcfSStefano Zampini for (i=0;i<n;i++) nnz[i] = ii[i+1]-ii[i]; 62181dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,NULL,&flg_row);CHKERRQ(ierr); 62191dd7afcfSStefano Zampini } 62209162d606SStefano Zampini for (i=n_vertices;i<total_counts_cc;i++) { 6221a717540cSStefano Zampini if (PetscBTLookup(change_basis,i)) { 62229162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[i+1]-constraints_idxs_ptr[i]; 6223a717540cSStefano Zampini if (PetscBTLookup(qr_needed_idx,i)) { 62249162d606SStefano Zampini for (j=0;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = size_of_constraint; 6225a717540cSStefano Zampini } else { 62269162d606SStefano Zampini nnz[constraints_idxs[constraints_idxs_ptr[i]]] = size_of_constraint; 62279162d606SStefano Zampini for (j=1;j<size_of_constraint;j++) nnz[constraints_idxs[constraints_idxs_ptr[i]+j]] = 2; 6228a717540cSStefano Zampini } 6229a717540cSStefano Zampini } 6230a717540cSStefano Zampini } 6231906d46d4SStefano Zampini ierr = MatSeqAIJSetPreallocation(localChangeOfBasisMatrix,0,nnz);CHKERRQ(ierr); 6232bbb9e6c6SStefano Zampini ierr = PetscFree(nnz);CHKERRQ(ierr); 62331dd7afcfSStefano Zampini /* Set interior change in the matrix */ 62341dd7afcfSStefano Zampini if (!pcbddc->benign_change || pcbddc->fake_change) { 6235bbb9e6c6SStefano Zampini for (i=0;i<pcis->n;i++) { 6236906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,i,i,1.0,INSERT_VALUES);CHKERRQ(ierr); 6237a717540cSStefano Zampini } 62381dd7afcfSStefano Zampini } else { 62391dd7afcfSStefano Zampini const PetscInt *ii,*jj; 62401dd7afcfSStefano Zampini PetscScalar *aa; 62411dd7afcfSStefano Zampini PetscInt n; 62421dd7afcfSStefano Zampini PetscBool flg_row; 62431dd7afcfSStefano Zampini ierr = MatGetRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 62441dd7afcfSStefano Zampini ierr = MatSeqAIJGetArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 62451dd7afcfSStefano Zampini for (i=0;i<n;i++) { 62461dd7afcfSStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,1,&i,ii[i+1]-ii[i],jj+ii[i],aa+ii[i],INSERT_VALUES);CHKERRQ(ierr); 62471dd7afcfSStefano Zampini } 62481dd7afcfSStefano Zampini ierr = MatSeqAIJRestoreArray(pcbddc->benign_change,&aa);CHKERRQ(ierr); 62491dd7afcfSStefano Zampini ierr = MatRestoreRowIJ(pcbddc->benign_change,0,PETSC_FALSE,PETSC_FALSE,&n,&ii,&jj,&flg_row);CHKERRQ(ierr); 62501dd7afcfSStefano Zampini } 6251a717540cSStefano Zampini 6252a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6253a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 6254a717540cSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Checking change of basis computation for subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 6255a717540cSStefano Zampini } 6256a717540cSStefano Zampini 6257a717540cSStefano Zampini 6258a717540cSStefano Zampini /* Now we loop on the constraints which need a change of basis */ 6259a717540cSStefano Zampini /* 6260a717540cSStefano Zampini Change of basis matrix is evaluated similarly to the FIRST APPROACH in 6261a717540cSStefano Zampini Klawonn and Widlund, Dual-primal FETI-DP methods for linear elasticity, (see Sect 6.2.1) 6262a717540cSStefano Zampini 6263a6b551f4SStefano Zampini Basic blocks of change of basis matrix T computed by 6264a717540cSStefano Zampini 6265a6b551f4SStefano 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) 6266a6b551f4SStefano Zampini 6267a6b551f4SStefano Zampini | 1 0 ... 0 s_1/S | 6268a6b551f4SStefano Zampini | 0 1 ... 0 s_2/S | 6269a717540cSStefano Zampini | ... | 6270a6b551f4SStefano Zampini | 0 ... 1 s_{n-1}/S | 6271a6b551f4SStefano Zampini | -s_1/s_n ... -s_{n-1}/s_n s_n/S | 6272a717540cSStefano Zampini 6273a6b551f4SStefano Zampini with S = \sum_{i=1}^n s_i^2 6274a6b551f4SStefano Zampini NOTE: in the above example, the primal dof is the last one of the edge in LOCAL ordering 6275a6b551f4SStefano Zampini in the current implementation, the primal dof is the first one of the edge in GLOBAL ordering 6276a6b551f4SStefano Zampini 6277a6b551f4SStefano Zampini - QR decomposition of constraints otherwise 6278a717540cSStefano Zampini */ 6279a717540cSStefano Zampini if (qr_needed) { 6280984c4197SStefano Zampini /* space to store Q */ 6281854ce69bSBarry Smith ierr = PetscMalloc1(max_size_of_constraint*max_size_of_constraint,&qr_basis);CHKERRQ(ierr); 62824e64d54eSstefano_zampini /* array to store scaling factors for reflectors */ 62834e64d54eSstefano_zampini ierr = PetscMalloc1(max_constraints,&qr_tau);CHKERRQ(ierr); 6284984c4197SStefano Zampini /* first we issue queries for optimal work */ 62853f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 62863f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_N);CHKERRQ(ierr); 62873f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6288984c4197SStefano Zampini lqr_work = -1; 62893f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,&lqr_work_t,&lqr_work,&lierr)); 6290984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to GEQRF Lapack routine %d",(int)lierr); 6291984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lqr_work_t),&lqr_work);CHKERRQ(ierr); 6292785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lqr_work_t),&qr_work);CHKERRQ(ierr); 6293984c4197SStefano Zampini lgqr_work = -1; 62943f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_M);CHKERRQ(ierr); 62953f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_N);CHKERRQ(ierr); 62963f08241aSStefano Zampini ierr = PetscBLASIntCast(max_constraints,&Blas_K);CHKERRQ(ierr); 62973f08241aSStefano Zampini ierr = PetscBLASIntCast(max_size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 62983f08241aSStefano Zampini if (Blas_K>Blas_M) Blas_K=Blas_M; /* adjust just for computing optimal work */ 6299c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,&lgqr_work_t,&lgqr_work,&lierr)); 6300c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in query to ORGQR/UNGQR Lapack routine %d",(int)lierr); 6301984c4197SStefano Zampini ierr = PetscBLASIntCast((PetscInt)PetscRealPart(lgqr_work_t),&lgqr_work);CHKERRQ(ierr); 6302785e854fSJed Brown ierr = PetscMalloc1((PetscInt)PetscRealPart(lgqr_work_t),&gqr_work);CHKERRQ(ierr); 6303984c4197SStefano Zampini /* array to store rhs and solution of triangular solver */ 6304785e854fSJed Brown ierr = PetscMalloc1(max_constraints*max_constraints,&trs_rhs);CHKERRQ(ierr); 6305a717540cSStefano Zampini /* allocating workspace for check */ 6306a717540cSStefano Zampini if (pcbddc->dbg_flag) { 6307cf5a6209SStefano Zampini ierr = PetscMalloc1(max_size_of_constraint*(max_constraints+max_size_of_constraint),&dbg_work);CHKERRQ(ierr); 6308a717540cSStefano Zampini } 6309a717540cSStefano Zampini } 6310984c4197SStefano Zampini /* array to store whether a node is primal or not */ 63114641a718SStefano Zampini ierr = PetscBTCreate(pcis->n_B,&is_primal);CHKERRQ(ierr); 6312473ba861SJed Brown ierr = PetscMalloc1(total_primal_vertices,&aux_primal_numbering_B);CHKERRQ(ierr); 63130e6343abSStefano Zampini ierr = ISGlobalToLocalMappingApply(pcis->BtoNmap,IS_GTOLM_DROP,total_primal_vertices,pcbddc->local_primal_ref_node,&i,aux_primal_numbering_B);CHKERRQ(ierr); 6314eee23b56SStefano 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); 631539e2fb2aSStefano Zampini for (i=0;i<total_primal_vertices;i++) { 631639e2fb2aSStefano Zampini ierr = PetscBTSet(is_primal,aux_primal_numbering_B[i]);CHKERRQ(ierr); 631739e2fb2aSStefano Zampini } 631839e2fb2aSStefano Zampini ierr = PetscFree(aux_primal_numbering_B);CHKERRQ(ierr); 6319984c4197SStefano Zampini 6320a717540cSStefano Zampini /* loop on constraints and see whether or not they need a change of basis and compute it */ 63219162d606SStefano Zampini for (total_counts=n_vertices;total_counts<total_counts_cc;total_counts++) { 63229162d606SStefano Zampini size_of_constraint = constraints_idxs_ptr[total_counts+1]-constraints_idxs_ptr[total_counts]; 63234641a718SStefano Zampini if (PetscBTLookup(change_basis,total_counts)) { 6324984c4197SStefano Zampini /* get constraint info */ 63259162d606SStefano Zampini primal_dofs = constraints_n[total_counts]; 6326984c4197SStefano Zampini dual_dofs = size_of_constraint-primal_dofs; 6327984c4197SStefano Zampini 6328984c4197SStefano Zampini if (pcbddc->dbg_flag) { 63299162d606SStefano 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); 6330674ae819SStefano Zampini } 6331984c4197SStefano Zampini 6332fa434743SStefano Zampini if (PetscBTLookup(qr_needed_idx,total_counts)) { /* QR */ 6333a717540cSStefano Zampini 6334a717540cSStefano Zampini /* copy quadrature constraints for change of basis check */ 6335a717540cSStefano Zampini if (pcbddc->dbg_flag) { 63369162d606SStefano Zampini ierr = PetscMemcpy(dbg_work,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6337a717540cSStefano Zampini } 6338984c4197SStefano Zampini /* copy temporary constraints into larger work vector (in order to store all columns of Q) */ 63399162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6340984c4197SStefano Zampini 6341984c4197SStefano Zampini /* compute QR decomposition of constraints */ 63423f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 63433f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 63443f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6345674ae819SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 63463f08241aSStefano Zampini PetscStackCallBLAS("LAPACKgeqrf",LAPACKgeqrf_(&Blas_M,&Blas_N,qr_basis,&Blas_LDA,qr_tau,qr_work,&lqr_work,&lierr)); 6347984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in GEQRF Lapack routine %d",(int)lierr); 6348674ae819SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6349984c4197SStefano Zampini 6350984c4197SStefano Zampini /* explictly compute R^-T */ 6351984c4197SStefano Zampini ierr = PetscMemzero(trs_rhs,primal_dofs*primal_dofs*sizeof(*trs_rhs));CHKERRQ(ierr); 6352984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) trs_rhs[j*(primal_dofs+1)] = 1.0; 63533f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 63543f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_NRHS);CHKERRQ(ierr); 63553f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 63563f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 6357984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 63583f08241aSStefano Zampini PetscStackCallBLAS("LAPACKtrtrs",LAPACKtrtrs_("U","T","N",&Blas_N,&Blas_NRHS,qr_basis,&Blas_LDA,trs_rhs,&Blas_LDB,&lierr)); 6359984c4197SStefano Zampini if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in TRTRS Lapack routine %d",(int)lierr); 6360984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6361984c4197SStefano Zampini 6362a717540cSStefano Zampini /* explicitly compute all columns of Q (Q = [Q1 | Q2] ) overwriting QR factorization in qr_basis */ 63633f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 63643f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 63653f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 63663f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6367984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6368c964aadfSJose E. Roman PetscStackCallBLAS("LAPACKorgqr",LAPACKorgqr_(&Blas_M,&Blas_N,&Blas_K,qr_basis,&Blas_LDA,qr_tau,gqr_work,&lgqr_work,&lierr)); 6369c964aadfSJose E. Roman if (lierr) SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_LIB,"Error in ORGQR/UNGQR Lapack routine %d",(int)lierr); 6370984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6371984c4197SStefano Zampini 6372984c4197SStefano Zampini /* first primal_dofs columns of Q need to be re-scaled in order to be unitary w.r.t constraints 6373984c4197SStefano Zampini i.e. C_{pxn}*Q_{nxn} should be equal to [I_pxp | 0_pxd] (see check below) 6374984c4197SStefano Zampini where n=size_of_constraint, p=primal_dofs, d=dual_dofs (n=p+d), I and 0 identity and null matrix resp. */ 63753f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_M);CHKERRQ(ierr); 63763f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_N);CHKERRQ(ierr); 63773f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_K);CHKERRQ(ierr); 63783f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 63793f08241aSStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDB);CHKERRQ(ierr); 63803f08241aSStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDC);CHKERRQ(ierr); 6381984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 63829162d606SStefano 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)); 6383984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 63849162d606SStefano Zampini ierr = PetscMemcpy(qr_basis,&constraints_data[constraints_data_ptr[total_counts]],size_of_constraint*primal_dofs*sizeof(PetscScalar));CHKERRQ(ierr); 6385984c4197SStefano Zampini 6386984c4197SStefano Zampini /* insert values in change of basis matrix respecting global ordering of new primal dofs */ 63879162d606SStefano Zampini start_rows = &constraints_idxs[constraints_idxs_ptr[total_counts]]; 6388984c4197SStefano Zampini /* insert cols for primal dofs */ 6389984c4197SStefano Zampini for (j=0;j<primal_dofs;j++) { 6390984c4197SStefano Zampini start_vals = &qr_basis[j*size_of_constraint]; 63919162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6392906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6393984c4197SStefano Zampini } 6394984c4197SStefano Zampini /* insert cols for dual dofs */ 6395984c4197SStefano Zampini for (j=0,k=0;j<dual_dofs;k++) { 63969162d606SStefano Zampini if (!PetscBTLookup(is_primal,constraints_idxs_B[constraints_idxs_ptr[total_counts]+k])) { 6397984c4197SStefano Zampini start_vals = &qr_basis[(primal_dofs+j)*size_of_constraint]; 63989162d606SStefano Zampini start_cols = &constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6399906d46d4SStefano Zampini ierr = MatSetValues(localChangeOfBasisMatrix,size_of_constraint,start_rows,1,start_cols,start_vals,INSERT_VALUES);CHKERRQ(ierr); 6400984c4197SStefano Zampini j++; 6401674ae819SStefano Zampini } 6402674ae819SStefano Zampini } 6403984c4197SStefano Zampini 6404984c4197SStefano Zampini /* check change of basis */ 6405984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6406984c4197SStefano Zampini PetscInt ii,jj; 6407984c4197SStefano Zampini PetscBool valid_qr=PETSC_TRUE; 6408c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_M);CHKERRQ(ierr); 6409c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 6410c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_K);CHKERRQ(ierr); 6411c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDA);CHKERRQ(ierr); 6412c4303822SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_LDB);CHKERRQ(ierr); 6413c4303822SStefano Zampini ierr = PetscBLASIntCast(primal_dofs,&Blas_LDC);CHKERRQ(ierr); 6414984c4197SStefano Zampini ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr); 6415cf5a6209SStefano 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)); 6416984c4197SStefano Zampini ierr = PetscFPTrapPop();CHKERRQ(ierr); 6417984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6418984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6419cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) valid_qr = PETSC_FALSE; 6420c068d9bbSLisandro 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; 6421674ae819SStefano Zampini } 6422674ae819SStefano Zampini } 6423984c4197SStefano Zampini if (!valid_qr) { 642422d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> wrong change of basis!\n");CHKERRQ(ierr); 6425984c4197SStefano Zampini for (jj=0;jj<size_of_constraint;jj++) { 6426984c4197SStefano Zampini for (ii=0;ii<primal_dofs;ii++) { 6427cf5a6209SStefano Zampini if (ii != jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]) > 1.e-12) { 6428cf5a6209SStefano 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])); 6429674ae819SStefano Zampini } 6430c068d9bbSLisandro Dalcin if (ii == jj && PetscAbsScalar(dbg_work[size_of_constraint*primal_dofs+jj*primal_dofs+ii]-(PetscReal)1) > 1.e-12) { 6431cf5a6209SStefano 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])); 6432984c4197SStefano Zampini } 6433984c4197SStefano Zampini } 6434984c4197SStefano Zampini } 6435674ae819SStefano Zampini } else { 643622d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> right change of basis!\n");CHKERRQ(ierr); 6437674ae819SStefano Zampini } 6438674ae819SStefano Zampini } 6439a717540cSStefano Zampini } else { /* simple transformation block */ 6440a717540cSStefano Zampini PetscInt row,col; 6441a6b551f4SStefano Zampini PetscScalar val,norm; 6442a6b551f4SStefano Zampini 6443a6b551f4SStefano Zampini ierr = PetscBLASIntCast(size_of_constraint,&Blas_N);CHKERRQ(ierr); 64449162d606SStefano 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)); 6445a717540cSStefano Zampini for (j=0;j<size_of_constraint;j++) { 64469162d606SStefano Zampini PetscInt row_B = constraints_idxs_B[constraints_idxs_ptr[total_counts]+j]; 64479162d606SStefano Zampini row = constraints_idxs[constraints_idxs_ptr[total_counts]+j]; 6448bbb9e6c6SStefano Zampini if (!PetscBTLookup(is_primal,row_B)) { 64499162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]]; 6450906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,row,1.0,INSERT_VALUES);CHKERRQ(ierr); 64519162d606SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,constraints_data[constraints_data_ptr[total_counts]+j]/norm,INSERT_VALUES);CHKERRQ(ierr); 6452a717540cSStefano Zampini } else { 6453a717540cSStefano Zampini for (k=0;k<size_of_constraint;k++) { 64549162d606SStefano Zampini col = constraints_idxs[constraints_idxs_ptr[total_counts]+k]; 6455a717540cSStefano Zampini if (row != col) { 64569162d606SStefano Zampini val = -constraints_data[constraints_data_ptr[total_counts]+k]/constraints_data[constraints_data_ptr[total_counts]]; 6457a717540cSStefano Zampini } else { 64589162d606SStefano Zampini val = constraints_data[constraints_data_ptr[total_counts]]/norm; 6459a717540cSStefano Zampini } 6460906d46d4SStefano Zampini ierr = MatSetValue(localChangeOfBasisMatrix,row,col,val,INSERT_VALUES);CHKERRQ(ierr); 6461a717540cSStefano Zampini } 6462a717540cSStefano Zampini } 6463a717540cSStefano Zampini } 646498a51de6SStefano Zampini if (pcbddc->dbg_flag) { 646522d5777bSStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"\t-> using standard change of basis\n");CHKERRQ(ierr); 6466a717540cSStefano Zampini } 6467674ae819SStefano Zampini } 6468984c4197SStefano Zampini } else { 6469984c4197SStefano Zampini if (pcbddc->dbg_flag) { 64709162d606SStefano 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); 6471674ae819SStefano Zampini } 6472674ae819SStefano Zampini } 6473674ae819SStefano Zampini } 6474a717540cSStefano Zampini 6475a717540cSStefano Zampini /* free workspace */ 6476a717540cSStefano Zampini if (qr_needed) { 6477984c4197SStefano Zampini if (pcbddc->dbg_flag) { 6478cf5a6209SStefano Zampini ierr = PetscFree(dbg_work);CHKERRQ(ierr); 6479984c4197SStefano Zampini } 6480984c4197SStefano Zampini ierr = PetscFree(trs_rhs);CHKERRQ(ierr); 6481984c4197SStefano Zampini ierr = PetscFree(qr_tau);CHKERRQ(ierr); 6482984c4197SStefano Zampini ierr = PetscFree(qr_work);CHKERRQ(ierr); 6483984c4197SStefano Zampini ierr = PetscFree(gqr_work);CHKERRQ(ierr); 6484984c4197SStefano Zampini ierr = PetscFree(qr_basis);CHKERRQ(ierr); 6485674ae819SStefano Zampini } 6486a717540cSStefano Zampini ierr = PetscBTDestroy(&is_primal);CHKERRQ(ierr); 6487906d46d4SStefano Zampini ierr = MatAssemblyBegin(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6488906d46d4SStefano Zampini ierr = MatAssemblyEnd(localChangeOfBasisMatrix,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6489906d46d4SStefano Zampini 6490906d46d4SStefano Zampini /* assembling of global change of variable */ 649188c03ad3SStefano Zampini if (!pcbddc->fake_change) { 6492bbb9e6c6SStefano Zampini Mat tmat; 649316f15bc4SStefano Zampini PetscInt bs; 649416f15bc4SStefano Zampini 6495906d46d4SStefano Zampini ierr = VecGetSize(pcis->vec1_global,&global_size);CHKERRQ(ierr); 6496906d46d4SStefano Zampini ierr = VecGetLocalSize(pcis->vec1_global,&local_size);CHKERRQ(ierr); 6497bbb9e6c6SStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 6498bbb9e6c6SStefano Zampini ierr = MatISSetLocalMat(tmat,localChangeOfBasisMatrix);CHKERRQ(ierr); 6499bbb9e6c6SStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)pc),&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6500bbb9e6c6SStefano Zampini ierr = MatSetType(pcbddc->ChangeOfBasisMatrix,MATAIJ);CHKERRQ(ierr); 650116f15bc4SStefano Zampini ierr = MatGetBlockSize(pc->pmat,&bs);CHKERRQ(ierr); 650216f15bc4SStefano Zampini ierr = MatSetBlockSize(pcbddc->ChangeOfBasisMatrix,bs);CHKERRQ(ierr); 6503906d46d4SStefano Zampini ierr = MatSetSizes(pcbddc->ChangeOfBasisMatrix,local_size,local_size,global_size,global_size);CHKERRQ(ierr); 6504bbb9e6c6SStefano Zampini ierr = MatISSetMPIXAIJPreallocation_Private(tmat,pcbddc->ChangeOfBasisMatrix,PETSC_TRUE);CHKERRQ(ierr); 6505bbb9e6c6SStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_REUSE_MATRIX,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 6506bbb9e6c6SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6507bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 6508bbb9e6c6SStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 6509e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6510e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6511bbb9e6c6SStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 6512bbb9e6c6SStefano Zampini ierr = MatDiagonalScale(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,NULL);CHKERRQ(ierr); 651388c03ad3SStefano Zampini 6514906d46d4SStefano Zampini /* check */ 6515906d46d4SStefano Zampini if (pcbddc->dbg_flag) { 6516906d46d4SStefano Zampini PetscReal error; 6517906d46d4SStefano Zampini Vec x,x_change; 6518906d46d4SStefano Zampini 6519906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x);CHKERRQ(ierr); 6520906d46d4SStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&x_change);CHKERRQ(ierr); 6521906d46d4SStefano Zampini ierr = VecSetRandom(x,NULL);CHKERRQ(ierr); 6522906d46d4SStefano Zampini ierr = VecCopy(x,pcis->vec1_global);CHKERRQ(ierr); 6523e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6524e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,x,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 6525bbb9e6c6SStefano Zampini ierr = MatMult(localChangeOfBasisMatrix,pcis->vec1_N,pcis->vec2_N);CHKERRQ(ierr); 6526e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6527e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec2_N,x,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 6528906d46d4SStefano Zampini ierr = MatMult(pcbddc->ChangeOfBasisMatrix,pcis->vec1_global,x_change);CHKERRQ(ierr); 6529906d46d4SStefano Zampini ierr = VecAXPY(x,-1.0,x_change);CHKERRQ(ierr); 6530906d46d4SStefano Zampini ierr = VecNorm(x,NORM_INFINITY,&error);CHKERRQ(ierr); 6531637e8532SStefano Zampini if (error > PETSC_SMALL) { 6532637e8532SStefano Zampini SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"Error global vs local change on N: %1.6e\n",error); 6533637e8532SStefano Zampini } 6534906d46d4SStefano Zampini ierr = VecDestroy(&x);CHKERRQ(ierr); 6535906d46d4SStefano Zampini ierr = VecDestroy(&x_change);CHKERRQ(ierr); 6536906d46d4SStefano Zampini } 6537b96c3477SStefano Zampini /* adapt sub_schurs computed (if any) */ 6538b96c3477SStefano Zampini if (pcbddc->use_deluxe_scaling) { 6539b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 6540bf3a8328SStefano Zampini 654113903a91SSatish 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"); 6542b334f244SStefano Zampini if (sub_schurs && sub_schurs->S_Ej_all) { 6543ac632422SStefano Zampini Mat S_new,tmat; 6544bf3a8328SStefano Zampini IS is_all_N,is_V_Sall = NULL; 6545bbb9e6c6SStefano Zampini 6546bbb9e6c6SStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->BtoNmap,sub_schurs->is_Ej_all,&is_all_N);CHKERRQ(ierr); 65477dae84e0SHong Zhang ierr = MatCreateSubMatrix(localChangeOfBasisMatrix,is_all_N,is_all_N,MAT_INITIAL_MATRIX,&tmat);CHKERRQ(ierr); 6548bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6549bf3a8328SStefano Zampini ISLocalToGlobalMapping NtoSall; 6550bf3a8328SStefano Zampini IS is_V; 6551b087196eSStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddc->n_vertices,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&is_V);CHKERRQ(ierr); 6552b087196eSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(is_all_N,&NtoSall);CHKERRQ(ierr); 6553b087196eSStefano Zampini ierr = ISGlobalToLocalMappingApplyIS(NtoSall,IS_GTOLM_DROP,is_V,&is_V_Sall);CHKERRQ(ierr); 6554b087196eSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&NtoSall);CHKERRQ(ierr); 6555b087196eSStefano Zampini ierr = ISDestroy(&is_V);CHKERRQ(ierr); 6556bf3a8328SStefano Zampini } 6557bf3a8328SStefano Zampini ierr = ISDestroy(&is_all_N);CHKERRQ(ierr); 6558ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6559b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->S_Ej_all);CHKERRQ(ierr); 6560ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6561bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6562bf3a8328SStefano Zampini const PetscScalar *array; 6563bf3a8328SStefano Zampini const PetscInt *idxs_V,*idxs_all; 6564bf3a8328SStefano Zampini PetscInt i,n_V; 6565bf3a8328SStefano Zampini 6566b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6567b087196eSStefano Zampini ierr = ISGetLocalSize(is_V_Sall,&n_V);CHKERRQ(ierr); 6568b087196eSStefano Zampini ierr = ISGetIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6569b087196eSStefano Zampini ierr = ISGetIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6570b087196eSStefano Zampini ierr = VecGetArrayRead(pcis->D,&array);CHKERRQ(ierr); 6571b087196eSStefano Zampini for (i=0;i<n_V;i++) { 6572b087196eSStefano Zampini PetscScalar val; 6573b087196eSStefano Zampini PetscInt idx; 6574b087196eSStefano Zampini 6575b087196eSStefano Zampini idx = idxs_V[i]; 6576b087196eSStefano Zampini val = array[idxs_all[idxs_V[i]]]; 6577b087196eSStefano Zampini ierr = MatSetValue(S_new,idx,idx,val,INSERT_VALUES);CHKERRQ(ierr); 6578b087196eSStefano Zampini } 6579b087196eSStefano Zampini ierr = MatAssemblyBegin(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6580b087196eSStefano Zampini ierr = MatAssemblyEnd(S_new,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 6581bf3a8328SStefano Zampini ierr = VecRestoreArrayRead(pcis->D,&array);CHKERRQ(ierr); 6582bf3a8328SStefano Zampini ierr = ISRestoreIndices(sub_schurs->is_Ej_all,&idxs_all);CHKERRQ(ierr); 6583bf3a8328SStefano Zampini ierr = ISRestoreIndices(is_V_Sall,&idxs_V);CHKERRQ(ierr); 6584bf3a8328SStefano Zampini } 6585ac632422SStefano Zampini sub_schurs->S_Ej_all = S_new; 6586ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6587ac632422SStefano Zampini if (sub_schurs->sum_S_Ej_all) { 6588ac632422SStefano Zampini ierr = MatPtAP(sub_schurs->sum_S_Ej_all,tmat,MAT_INITIAL_MATRIX,1.0,&S_new);CHKERRQ(ierr); 6589b96c3477SStefano Zampini ierr = MatDestroy(&sub_schurs->sum_S_Ej_all);CHKERRQ(ierr); 6590ac632422SStefano Zampini ierr = PetscObjectReference((PetscObject)S_new);CHKERRQ(ierr); 6591bf3a8328SStefano Zampini if (pcbddc->deluxe_zerorows) { 6592b087196eSStefano Zampini ierr = MatZeroRowsColumnsIS(S_new,is_V_Sall,1.,NULL,NULL);CHKERRQ(ierr); 6593bf3a8328SStefano Zampini } 6594ac632422SStefano Zampini sub_schurs->sum_S_Ej_all = S_new; 6595ac632422SStefano Zampini ierr = MatDestroy(&S_new);CHKERRQ(ierr); 6596ac632422SStefano Zampini } 6597b087196eSStefano Zampini ierr = ISDestroy(&is_V_Sall);CHKERRQ(ierr); 659888c03ad3SStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 6599b96c3477SStefano Zampini } 6600c9db6a07SStefano Zampini /* destroy any change of basis context in sub_schurs */ 6601b334f244SStefano Zampini if (sub_schurs && sub_schurs->change) { 6602c9db6a07SStefano Zampini PetscInt i; 6603c9db6a07SStefano Zampini 6604c9db6a07SStefano Zampini for (i=0;i<sub_schurs->n_subs;i++) { 6605c9db6a07SStefano Zampini ierr = KSPDestroy(&sub_schurs->change[i]);CHKERRQ(ierr); 6606c9db6a07SStefano Zampini } 6607c9db6a07SStefano Zampini ierr = PetscFree(sub_schurs->change);CHKERRQ(ierr); 6608c9db6a07SStefano Zampini } 6609b96c3477SStefano Zampini } 661016909a7fSStefano Zampini if (pcbddc->switch_static) { /* need to save the local change */ 661116909a7fSStefano Zampini pcbddc->switch_static_change = localChangeOfBasisMatrix; 661216909a7fSStefano Zampini } else { 6613906d46d4SStefano Zampini ierr = MatDestroy(&localChangeOfBasisMatrix);CHKERRQ(ierr); 661416909a7fSStefano Zampini } 66151dd7afcfSStefano Zampini /* determine if any process has changed the pressures locally */ 661627b6a85dSStefano Zampini pcbddc->change_interior = pcbddc->benign_have_null; 661772b8c272SStefano Zampini } else { /* fake change (get back change of basis into ConstraintMatrix and info on qr) */ 661872b8c272SStefano Zampini ierr = MatDestroy(&pcbddc->ConstraintMatrix);CHKERRQ(ierr); 661972b8c272SStefano Zampini pcbddc->ConstraintMatrix = localChangeOfBasisMatrix; 662072b8c272SStefano Zampini pcbddc->use_qr_single = qr_needed; 662172b8c272SStefano Zampini } 66221dd7afcfSStefano Zampini } else if (pcbddc->user_ChangeOfBasisMatrix || pcbddc->benign_saddle_point) { 662327b6a85dSStefano Zampini if (!pcbddc->benign_have_null && pcbddc->user_ChangeOfBasisMatrix) { 6624b9b85e73SStefano Zampini ierr = PetscObjectReference((PetscObject)pcbddc->user_ChangeOfBasisMatrix);CHKERRQ(ierr); 6625b9b85e73SStefano Zampini pcbddc->ChangeOfBasisMatrix = pcbddc->user_ChangeOfBasisMatrix; 6626906d46d4SStefano Zampini } else { 66271dd7afcfSStefano Zampini Mat benign_global = NULL; 662827b6a85dSStefano Zampini if (pcbddc->benign_have_null) { 66291dd7afcfSStefano Zampini Mat tmat; 66301dd7afcfSStefano Zampini 66311dd7afcfSStefano Zampini pcbddc->change_interior = PETSC_TRUE; 66321dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 66331dd7afcfSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 66341dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 66351dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 66361dd7afcfSStefano Zampini ierr = VecReciprocal(pcis->vec1_global);CHKERRQ(ierr); 66371dd7afcfSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 66381dd7afcfSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 66391dd7afcfSStefano Zampini ierr = MatDuplicate(pc->pmat,MAT_DO_NOT_COPY_VALUES,&tmat);CHKERRQ(ierr); 66401dd7afcfSStefano Zampini if (pcbddc->benign_change) { 66411dd7afcfSStefano Zampini Mat M; 66421dd7afcfSStefano Zampini 66431dd7afcfSStefano Zampini ierr = MatDuplicate(pcbddc->benign_change,MAT_COPY_VALUES,&M);CHKERRQ(ierr); 66441dd7afcfSStefano Zampini ierr = MatDiagonalScale(M,pcis->vec1_N,NULL);CHKERRQ(ierr); 66451dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,M);CHKERRQ(ierr); 66461dd7afcfSStefano Zampini ierr = MatDestroy(&M);CHKERRQ(ierr); 6647906d46d4SStefano Zampini } else { 66481dd7afcfSStefano Zampini Mat eye; 66491dd7afcfSStefano Zampini PetscScalar *array; 66501dd7afcfSStefano Zampini 66511dd7afcfSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 66521dd7afcfSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,pcis->n,pcis->n,1,NULL,&eye);CHKERRQ(ierr); 66531dd7afcfSStefano Zampini for (i=0;i<pcis->n;i++) { 66541dd7afcfSStefano Zampini ierr = MatSetValue(eye,i,i,array[i],INSERT_VALUES);CHKERRQ(ierr); 6655906d46d4SStefano Zampini } 66561dd7afcfSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 66571dd7afcfSStefano Zampini ierr = MatAssemblyBegin(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 66581dd7afcfSStefano Zampini ierr = MatAssemblyEnd(eye,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 66591dd7afcfSStefano Zampini ierr = MatISSetLocalMat(tmat,eye);CHKERRQ(ierr); 66601dd7afcfSStefano Zampini ierr = MatDestroy(&eye);CHKERRQ(ierr); 66611dd7afcfSStefano Zampini } 66621dd7afcfSStefano Zampini ierr = MatISGetMPIXAIJ(tmat,MAT_INITIAL_MATRIX,&benign_global);CHKERRQ(ierr); 66631dd7afcfSStefano Zampini ierr = MatDestroy(&tmat);CHKERRQ(ierr); 66641dd7afcfSStefano Zampini } 66651dd7afcfSStefano Zampini if (pcbddc->user_ChangeOfBasisMatrix) { 66661dd7afcfSStefano Zampini ierr = MatMatMult(pcbddc->user_ChangeOfBasisMatrix,benign_global,MAT_INITIAL_MATRIX,PETSC_DEFAULT,&pcbddc->ChangeOfBasisMatrix);CHKERRQ(ierr); 66671dd7afcfSStefano Zampini ierr = MatDestroy(&benign_global);CHKERRQ(ierr); 666827b6a85dSStefano Zampini } else if (pcbddc->benign_have_null) { 66691dd7afcfSStefano Zampini pcbddc->ChangeOfBasisMatrix = benign_global; 66701dd7afcfSStefano Zampini } 66711dd7afcfSStefano Zampini } 667216909a7fSStefano Zampini if (pcbddc->switch_static && pcbddc->ChangeOfBasisMatrix) { /* need to save the local change */ 667316909a7fSStefano Zampini IS is_global; 667416909a7fSStefano Zampini const PetscInt *gidxs; 667516909a7fSStefano Zampini 667616909a7fSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 667716909a7fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcis->n,gidxs,PETSC_COPY_VALUES,&is_global);CHKERRQ(ierr); 667816909a7fSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(pc->pmat->rmap->mapping,&gidxs);CHKERRQ(ierr); 66797dae84e0SHong Zhang ierr = MatCreateSubMatrixUnsorted(pcbddc->ChangeOfBasisMatrix,is_global,is_global,&pcbddc->switch_static_change);CHKERRQ(ierr); 668016909a7fSStefano Zampini ierr = ISDestroy(&is_global);CHKERRQ(ierr); 668116909a7fSStefano Zampini } 66821dd7afcfSStefano Zampini } 66831dd7afcfSStefano Zampini if (!pcbddc->fake_change && pcbddc->ChangeOfBasisMatrix && !pcbddc->work_change) { 66841dd7afcfSStefano Zampini ierr = VecDuplicate(pcis->vec1_global,&pcbddc->work_change);CHKERRQ(ierr); 6685b9b85e73SStefano Zampini } 6686a717540cSStefano Zampini 668772b8c272SStefano Zampini if (!pcbddc->fake_change) { 66884f1b2e48SStefano Zampini /* add pressure dofs to set of primal nodes for numbering purposes */ 66894f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 66904f1b2e48SStefano Zampini pcbddc->local_primal_ref_node[pcbddc->local_primal_size_cc] = pcbddc->benign_p0_lidx[i]; 66914f1b2e48SStefano Zampini pcbddc->primal_indices_local_idxs[pcbddc->local_primal_size] = pcbddc->benign_p0_lidx[i]; 6692019a44ceSStefano Zampini pcbddc->local_primal_ref_mult[pcbddc->local_primal_size_cc] = 1; 6693019a44ceSStefano Zampini pcbddc->local_primal_size_cc++; 6694019a44ceSStefano Zampini pcbddc->local_primal_size++; 6695019a44ceSStefano Zampini } 6696019a44ceSStefano Zampini 6697019a44ceSStefano Zampini /* check if a new primal space has been introduced (also take into account benign trick) */ 6698727cdba6SStefano Zampini pcbddc->new_primal_space_local = PETSC_TRUE; 6699727cdba6SStefano Zampini if (olocal_primal_size == pcbddc->local_primal_size) { 67009f47a83aSStefano 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); 6701c1c8e736SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 67020e6343abSStefano Zampini if (!pcbddc->new_primal_space_local) { 67039f47a83aSStefano 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); 6704727cdba6SStefano Zampini pcbddc->new_primal_space_local = (PetscBool)(!pcbddc->new_primal_space_local); 6705727cdba6SStefano Zampini } 67060e6343abSStefano Zampini } 6707727cdba6SStefano Zampini /* new_primal_space will be used for numbering of coarse dofs, so it should be the same across all subdomains */ 6708b2566f29SBarry Smith ierr = MPIU_Allreduce(&pcbddc->new_primal_space_local,&pcbddc->new_primal_space,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 670972b8c272SStefano Zampini } 671072b8c272SStefano Zampini ierr = PetscFree2(olocal_primal_ref_node,olocal_primal_ref_mult);CHKERRQ(ierr); 6711727cdba6SStefano Zampini 6712a717540cSStefano Zampini /* flush dbg viewer */ 6713b8ffe317SStefano Zampini if (pcbddc->dbg_flag) { 6714b8ffe317SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6715b8ffe317SStefano Zampini } 6716a717540cSStefano Zampini 6717e310c8b4SStefano Zampini /* free workspace */ 6718a717540cSStefano Zampini ierr = PetscBTDestroy(&qr_needed_idx);CHKERRQ(ierr); 67194641a718SStefano Zampini ierr = PetscBTDestroy(&change_basis);CHKERRQ(ierr); 672008122e43SStefano Zampini if (!pcbddc->adaptive_selection) { 67219162d606SStefano Zampini ierr = PetscFree3(constraints_idxs_ptr,constraints_data_ptr,constraints_n);CHKERRQ(ierr); 67229162d606SStefano Zampini ierr = PetscFree3(constraints_data,constraints_idxs,constraints_idxs_B);CHKERRQ(ierr); 672308122e43SStefano Zampini } else { 67249162d606SStefano Zampini ierr = PetscFree5(pcbddc->adaptive_constraints_n, 67259162d606SStefano Zampini pcbddc->adaptive_constraints_idxs_ptr, 67269162d606SStefano Zampini pcbddc->adaptive_constraints_data_ptr, 672708122e43SStefano Zampini pcbddc->adaptive_constraints_idxs, 672808122e43SStefano Zampini pcbddc->adaptive_constraints_data);CHKERRQ(ierr); 67299162d606SStefano Zampini ierr = PetscFree(constraints_n);CHKERRQ(ierr); 67309162d606SStefano Zampini ierr = PetscFree(constraints_idxs_B);CHKERRQ(ierr); 673108122e43SStefano Zampini } 6732674ae819SStefano Zampini PetscFunctionReturn(0); 6733674ae819SStefano Zampini } 673404a6f24aSStefano Zampini /* #undef PETSC_MISSING_LAPACK_GESVD */ 6735674ae819SStefano Zampini 6736674ae819SStefano Zampini PetscErrorCode PCBDDCAnalyzeInterface(PC pc) 6737674ae819SStefano Zampini { 673871582508SStefano Zampini ISLocalToGlobalMapping map; 6739674ae819SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 6740674ae819SStefano Zampini Mat_IS *matis = (Mat_IS*)pc->pmat->data; 674166da6bd7Sstefano_zampini PetscInt i,N; 674266da6bd7Sstefano_zampini PetscBool rcsr = PETSC_FALSE; 674366da6bd7Sstefano_zampini PetscErrorCode ierr; 6744674ae819SStefano Zampini 6745674ae819SStefano Zampini PetscFunctionBegin; 67468af8fcf9SStefano Zampini if (pcbddc->recompute_topography) { 6747b03ebc13SStefano Zampini pcbddc->graphanalyzed = PETSC_FALSE; 67488e61c736SStefano Zampini /* Reset previously computed graph */ 67498e61c736SStefano Zampini ierr = PCBDDCGraphReset(pcbddc->mat_graph);CHKERRQ(ierr); 6750674ae819SStefano Zampini /* Init local Graph struct */ 67517fb0e2dbSStefano Zampini ierr = MatGetSize(pc->pmat,&N,NULL);CHKERRQ(ierr); 675271582508SStefano Zampini ierr = MatGetLocalToGlobalMapping(pc->pmat,&map,NULL);CHKERRQ(ierr); 6753be12c134Sstefano_zampini ierr = PCBDDCGraphInit(pcbddc->mat_graph,map,N,pcbddc->graphmaxcount);CHKERRQ(ierr); 6754674ae819SStefano Zampini 67557a0e7b2cSstefano_zampini if (pcbddc->user_primal_vertices_local && !pcbddc->user_primal_vertices) { 67567a0e7b2cSstefano_zampini ierr = PCBDDCConsistencyCheckIS(pc,MPI_LOR,&pcbddc->user_primal_vertices_local);CHKERRQ(ierr); 67577a0e7b2cSstefano_zampini } 6758575ad6abSStefano Zampini /* Check validity of the csr graph passed in by the user */ 6759ab8c8b98SStefano 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); 67609577ea80SStefano Zampini 6761674ae819SStefano Zampini /* Set default CSR adjacency of local dofs if not provided by the user with PCBDDCSetLocalAdjacencyGraph */ 676266da6bd7Sstefano_zampini if (!pcbddc->mat_graph->xadj && pcbddc->use_local_adj) { 67634d379d7bSStefano Zampini PetscInt *xadj,*adjncy; 67644d379d7bSStefano Zampini PetscInt nvtxs; 6765e496cd5dSStefano Zampini PetscBool flg_row=PETSC_FALSE; 6766674ae819SStefano Zampini 67672fffb893SStefano Zampini ierr = MatGetRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 67682fffb893SStefano Zampini if (flg_row) { 67694d379d7bSStefano Zampini ierr = PCBDDCSetLocalAdjacencyGraph(pc,nvtxs,xadj,adjncy,PETSC_COPY_VALUES);CHKERRQ(ierr); 6770b96c3477SStefano Zampini pcbddc->computed_rowadj = PETSC_TRUE; 67712fffb893SStefano Zampini } 67722fffb893SStefano Zampini ierr = MatRestoreRowIJ(matis->A,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,(const PetscInt**)&xadj,(const PetscInt**)&adjncy,&flg_row);CHKERRQ(ierr); 677366da6bd7Sstefano_zampini rcsr = PETSC_TRUE; 6774674ae819SStefano Zampini } 67759b28b941SStefano Zampini if (pcbddc->dbg_flag) { 67769b28b941SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 6777674ae819SStefano Zampini } 6778674ae819SStefano Zampini 6779ab8c8b98SStefano Zampini if (pcbddc->mat_graph->cdim && !pcbddc->mat_graph->cloc) { 6780ab8c8b98SStefano Zampini PetscReal *lcoords; 6781ab8c8b98SStefano Zampini PetscInt n; 6782ab8c8b98SStefano Zampini MPI_Datatype dimrealtype; 6783ab8c8b98SStefano Zampini 6784ab8c8b98SStefano 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); 6785ab8c8b98SStefano Zampini ierr = MatGetLocalSize(matis->A,&n,NULL);CHKERRQ(ierr); 6786ab8c8b98SStefano Zampini ierr = MatISSetUpSF(pc->pmat);CHKERRQ(ierr); 6787ab8c8b98SStefano Zampini ierr = PetscMalloc1(pcbddc->mat_graph->cdim*n,&lcoords);CHKERRQ(ierr); 6788ab8c8b98SStefano Zampini ierr = MPI_Type_contiguous(pcbddc->mat_graph->cdim,MPIU_REAL,&dimrealtype);CHKERRQ(ierr); 6789ab8c8b98SStefano Zampini ierr = MPI_Type_commit(&dimrealtype);CHKERRQ(ierr); 6790ab8c8b98SStefano Zampini ierr = PetscSFBcastBegin(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 6791ab8c8b98SStefano Zampini ierr = PetscSFBcastEnd(matis->sf,dimrealtype,pcbddc->mat_graph->coords,lcoords);CHKERRQ(ierr); 6792ab8c8b98SStefano Zampini ierr = MPI_Type_free(&dimrealtype);CHKERRQ(ierr); 6793ab8c8b98SStefano Zampini ierr = PetscFree(pcbddc->mat_graph->coords);CHKERRQ(ierr); 6794ab8c8b98SStefano Zampini 6795ab8c8b98SStefano Zampini pcbddc->mat_graph->coords = lcoords; 6796ab8c8b98SStefano Zampini pcbddc->mat_graph->cloc = PETSC_TRUE; 6797ab8c8b98SStefano Zampini pcbddc->mat_graph->cnloc = n; 6798ab8c8b98SStefano Zampini } 6799ab8c8b98SStefano 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); 6800ab8c8b98SStefano Zampini 6801674ae819SStefano Zampini /* Setup of Graph */ 68024b2aedd3SStefano Zampini pcbddc->mat_graph->commsizelimit = 0; /* don't use the COMM_SELF variant of the graph */ 680314f95afaSStefano 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); 6804674ae819SStefano Zampini 68054f1b2e48SStefano Zampini /* attach info on disconnected subdomains if present */ 68064f1b2e48SStefano Zampini if (pcbddc->n_local_subs) { 68074f1b2e48SStefano Zampini PetscInt *local_subs; 68084f1b2e48SStefano Zampini 68094f1b2e48SStefano Zampini ierr = PetscMalloc1(N,&local_subs);CHKERRQ(ierr); 68104f1b2e48SStefano Zampini for (i=0;i<pcbddc->n_local_subs;i++) { 68114f1b2e48SStefano Zampini const PetscInt *idxs; 68124f1b2e48SStefano Zampini PetscInt nl,j; 68134f1b2e48SStefano Zampini 68144f1b2e48SStefano Zampini ierr = ISGetLocalSize(pcbddc->local_subs[i],&nl);CHKERRQ(ierr); 68154f1b2e48SStefano Zampini ierr = ISGetIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 681671582508SStefano Zampini for (j=0;j<nl;j++) local_subs[idxs[j]] = i; 68174f1b2e48SStefano Zampini ierr = ISRestoreIndices(pcbddc->local_subs[i],&idxs);CHKERRQ(ierr); 68184f1b2e48SStefano Zampini } 68194f1b2e48SStefano Zampini pcbddc->mat_graph->n_local_subs = pcbddc->n_local_subs; 68204f1b2e48SStefano Zampini pcbddc->mat_graph->local_subs = local_subs; 68214f1b2e48SStefano Zampini } 68228af8fcf9SStefano Zampini } 68234f1b2e48SStefano Zampini 6824cac5312eSStefano Zampini if (!pcbddc->graphanalyzed) { 6825674ae819SStefano Zampini /* Graph's connected components analysis */ 6826674ae819SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(pcbddc->mat_graph);CHKERRQ(ierr); 682771582508SStefano Zampini pcbddc->graphanalyzed = PETSC_TRUE; 68288af8fcf9SStefano Zampini } 682966da6bd7Sstefano_zampini if (rcsr) pcbddc->mat_graph->nvtxs_csr = 0; 6830674ae819SStefano Zampini PetscFunctionReturn(0); 6831674ae819SStefano Zampini } 6832674ae819SStefano Zampini 68339a7d3425SStefano Zampini PetscErrorCode PCBDDCOrthonormalizeVecs(PetscInt n, Vec vecs[]) 68349a7d3425SStefano Zampini { 68359a7d3425SStefano Zampini PetscInt i,j; 68369a7d3425SStefano Zampini PetscScalar *alphas; 68379a7d3425SStefano Zampini PetscErrorCode ierr; 68389a7d3425SStefano Zampini 68399a7d3425SStefano Zampini PetscFunctionBegin; 6840785e854fSJed Brown ierr = PetscMalloc1(n,&alphas);CHKERRQ(ierr); 68419a7d3425SStefano Zampini for (i=0;i<n;i++) { 68429a7d3425SStefano Zampini ierr = VecNormalize(vecs[i],NULL);CHKERRQ(ierr); 6843669cc0f4SStefano Zampini ierr = VecMDot(vecs[i],n-i-1,&vecs[i+1],alphas);CHKERRQ(ierr); 6844669cc0f4SStefano Zampini for (j=0;j<n-i-1;j++) alphas[j] = PetscConj(-alphas[j]); 6845669cc0f4SStefano Zampini ierr = VecMAXPY(vecs[j],n-i-1,alphas,vecs+i);CHKERRQ(ierr); 68469a7d3425SStefano Zampini } 68479a7d3425SStefano Zampini ierr = PetscFree(alphas);CHKERRQ(ierr); 68489a7d3425SStefano Zampini PetscFunctionReturn(0); 68499a7d3425SStefano Zampini } 68509a7d3425SStefano Zampini 6851bb360cb4SStefano Zampini PetscErrorCode PCBDDCMatISGetSubassemblingPattern(Mat mat, PetscInt *n_subdomains, PetscInt redprocs, IS* is_sends, PetscBool *have_void) 6852e7931f94SStefano Zampini { 685357de7509SStefano Zampini Mat A; 6854e7931f94SStefano Zampini PetscInt n_neighs,*neighs,*n_shared,**shared; 6855e7931f94SStefano Zampini PetscMPIInt size,rank,color; 685652e5ac9dSStefano Zampini PetscInt *xadj,*adjncy; 685752e5ac9dSStefano Zampini PetscInt *adjncy_wgt,*v_wgt,*ranks_send_to_idx; 6858bb360cb4SStefano Zampini PetscInt im_active,active_procs,N,n,i,j,threshold = 2; 685957de7509SStefano Zampini PetscInt void_procs,*procs_candidates = NULL; 686027b6a85dSStefano Zampini PetscInt xadj_count,*count; 686127b6a85dSStefano Zampini PetscBool ismatis,use_vwgt=PETSC_FALSE; 686227b6a85dSStefano Zampini PetscSubcomm psubcomm; 686327b6a85dSStefano Zampini MPI_Comm subcomm; 686452e5ac9dSStefano Zampini PetscErrorCode ierr; 6865a57a6d2fSStefano Zampini 6866e7931f94SStefano Zampini PetscFunctionBegin; 686757de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 686857de7509SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 6869fbfcfee5SBarry 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); 687057de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,*n_subdomains,2); 687157de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,redprocs,3); 687257de7509SStefano Zampini if (*n_subdomains <=0) SETERRQ1(PetscObjectComm((PetscObject)mat),PETSC_ERR_ARG_WRONG,"Invalid number of subdomains requested %d\n",*n_subdomains); 687357de7509SStefano Zampini 687457de7509SStefano Zampini if (have_void) *have_void = PETSC_FALSE; 687557de7509SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)mat),&size);CHKERRQ(ierr); 687657de7509SStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)mat),&rank);CHKERRQ(ierr); 687757de7509SStefano Zampini ierr = MatISGetLocalMat(mat,&A);CHKERRQ(ierr); 687857de7509SStefano Zampini ierr = MatGetLocalSize(A,&n,NULL);CHKERRQ(ierr); 6879bb360cb4SStefano Zampini im_active = !!n; 688057de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 688157de7509SStefano Zampini void_procs = size - active_procs; 688257de7509SStefano Zampini /* get ranks of of non-active processes in mat communicator */ 688357de7509SStefano Zampini if (void_procs) { 688457de7509SStefano Zampini PetscInt ncand; 688557de7509SStefano Zampini 688657de7509SStefano Zampini if (have_void) *have_void = PETSC_TRUE; 688757de7509SStefano Zampini ierr = PetscMalloc1(size,&procs_candidates);CHKERRQ(ierr); 688857de7509SStefano Zampini ierr = MPI_Allgather(&im_active,1,MPIU_INT,procs_candidates,1,MPIU_INT,PetscObjectComm((PetscObject)mat));CHKERRQ(ierr); 688957de7509SStefano Zampini for (i=0,ncand=0;i<size;i++) { 689057de7509SStefano Zampini if (!procs_candidates[i]) { 689157de7509SStefano Zampini procs_candidates[ncand++] = i; 689257de7509SStefano Zampini } 689357de7509SStefano Zampini } 689457de7509SStefano Zampini /* force n_subdomains to be not greater that the number of non-active processes */ 689557de7509SStefano Zampini *n_subdomains = PetscMin(void_procs,*n_subdomains); 689657de7509SStefano Zampini } 689757de7509SStefano Zampini 6898bb360cb4SStefano Zampini /* number of subdomains requested greater than active processes or matrix size -> just shift the matrix 689914f0bfb9SStefano Zampini number of subdomains requested 1 -> send to master or first candidate in voids */ 6900bb360cb4SStefano Zampini ierr = MatGetSize(mat,&N,NULL);CHKERRQ(ierr); 6901bb360cb4SStefano Zampini if (active_procs < *n_subdomains || *n_subdomains == 1 || N <= *n_subdomains) { 690214f0bfb9SStefano Zampini PetscInt issize,isidx,dest; 690314f0bfb9SStefano Zampini if (*n_subdomains == 1) dest = 0; 690414f0bfb9SStefano Zampini else dest = rank; 690557de7509SStefano Zampini if (im_active) { 690657de7509SStefano Zampini issize = 1; 690757de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 690814f0bfb9SStefano Zampini isidx = procs_candidates[dest]; 690957de7509SStefano Zampini } else { 691014f0bfb9SStefano Zampini isidx = dest; 691157de7509SStefano Zampini } 691257de7509SStefano Zampini } else { 691357de7509SStefano Zampini issize = 0; 691457de7509SStefano Zampini isidx = -1; 691557de7509SStefano Zampini } 6916bb360cb4SStefano Zampini if (*n_subdomains != 1) *n_subdomains = active_procs; 691757de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),issize,&isidx,PETSC_COPY_VALUES,is_sends);CHKERRQ(ierr); 6918daf8a457SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 691957de7509SStefano Zampini PetscFunctionReturn(0); 692057de7509SStefano Zampini } 6921c5929fdfSBarry Smith ierr = PetscOptionsGetBool(NULL,NULL,"-matis_partitioning_use_vwgt",&use_vwgt,NULL);CHKERRQ(ierr); 6922c5929fdfSBarry Smith ierr = PetscOptionsGetInt(NULL,NULL,"-matis_partitioning_threshold",&threshold,NULL);CHKERRQ(ierr); 692327b6a85dSStefano Zampini threshold = PetscMax(threshold,2); 6924e7931f94SStefano Zampini 6925e7931f94SStefano Zampini /* Get info on mapping */ 69263bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6927e7931f94SStefano Zampini 6928e7931f94SStefano Zampini /* build local CSR graph of subdomains' connectivity */ 6929785e854fSJed Brown ierr = PetscMalloc1(2,&xadj);CHKERRQ(ierr); 6930e7931f94SStefano Zampini xadj[0] = 0; 6931e7931f94SStefano Zampini xadj[1] = PetscMax(n_neighs-1,0); 6932785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy);CHKERRQ(ierr); 6933785e854fSJed Brown ierr = PetscMalloc1(xadj[1],&adjncy_wgt);CHKERRQ(ierr); 6934bb360cb4SStefano Zampini ierr = PetscCalloc1(n,&count);CHKERRQ(ierr); 693527b6a85dSStefano Zampini for (i=1;i<n_neighs;i++) 693627b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) 693727b6a85dSStefano Zampini count[shared[i][j]] += 1; 6938e7931f94SStefano Zampini 693927b6a85dSStefano Zampini xadj_count = 0; 69402b510759SStefano Zampini for (i=1;i<n_neighs;i++) { 694127b6a85dSStefano Zampini for (j=0;j<n_shared[i];j++) { 694227b6a85dSStefano Zampini if (count[shared[i][j]] < threshold) { 6943d023bfaeSStefano Zampini adjncy[xadj_count] = neighs[i]; 6944d023bfaeSStefano Zampini adjncy_wgt[xadj_count] = n_shared[i]; 6945d023bfaeSStefano Zampini xadj_count++; 694627b6a85dSStefano Zampini break; 694727b6a85dSStefano Zampini } 6948e7931f94SStefano Zampini } 6949e7931f94SStefano Zampini } 6950d023bfaeSStefano Zampini xadj[1] = xadj_count; 695127b6a85dSStefano Zampini ierr = PetscFree(count);CHKERRQ(ierr); 69523bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreInfo(mat->rmap->mapping,&n_neighs,&neighs,&n_shared,&shared);CHKERRQ(ierr); 6953e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 6954e7931f94SStefano Zampini 69553837a79fSStefano Zampini ierr = PetscMalloc1(1,&ranks_send_to_idx);CHKERRQ(ierr); 6956e7931f94SStefano Zampini 695727b6a85dSStefano Zampini /* Restrict work on active processes only */ 695827b6a85dSStefano Zampini ierr = PetscMPIIntCast(im_active,&color);CHKERRQ(ierr); 695927b6a85dSStefano Zampini if (void_procs) { 696027b6a85dSStefano Zampini ierr = PetscSubcommCreate(PetscObjectComm((PetscObject)mat),&psubcomm);CHKERRQ(ierr); 696127b6a85dSStefano Zampini ierr = PetscSubcommSetNumber(psubcomm,2);CHKERRQ(ierr); /* 2 groups, active process and not active processes */ 696227b6a85dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(psubcomm,color,rank);CHKERRQ(ierr); 696327b6a85dSStefano Zampini subcomm = PetscSubcommChild(psubcomm); 696427b6a85dSStefano Zampini } else { 696527b6a85dSStefano Zampini psubcomm = NULL; 696627b6a85dSStefano Zampini subcomm = PetscObjectComm((PetscObject)mat); 696727b6a85dSStefano Zampini } 696827b6a85dSStefano Zampini 696927b6a85dSStefano Zampini v_wgt = NULL; 697027b6a85dSStefano Zampini if (!color) { 6971e7931f94SStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 6972e7931f94SStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 6973e7931f94SStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 6974c8587f34SStefano Zampini } else { 697552e5ac9dSStefano Zampini Mat subdomain_adj; 697652e5ac9dSStefano Zampini IS new_ranks,new_ranks_contig; 697752e5ac9dSStefano Zampini MatPartitioning partitioner; 697827b6a85dSStefano Zampini PetscInt rstart=0,rend=0; 697952e5ac9dSStefano Zampini PetscInt *is_indices,*oldranks; 698057de7509SStefano Zampini PetscMPIInt size; 6981b0c7d250SStefano Zampini PetscBool aggregate; 6982b0c7d250SStefano Zampini 698327b6a85dSStefano Zampini ierr = MPI_Comm_size(subcomm,&size);CHKERRQ(ierr); 698427b6a85dSStefano Zampini if (void_procs) { 698527b6a85dSStefano Zampini PetscInt prank = rank; 6986785e854fSJed Brown ierr = PetscMalloc1(size,&oldranks);CHKERRQ(ierr); 698727b6a85dSStefano Zampini ierr = MPI_Allgather(&prank,1,MPIU_INT,oldranks,1,MPIU_INT,subcomm);CHKERRQ(ierr); 6988e7931f94SStefano Zampini for (i=0;i<xadj[1];i++) { 6989e7931f94SStefano Zampini ierr = PetscFindInt(adjncy[i],size,oldranks,&adjncy[i]);CHKERRQ(ierr); 6990c8587f34SStefano Zampini } 6991e7931f94SStefano Zampini ierr = PetscSortIntWithArray(xadj[1],adjncy,adjncy_wgt);CHKERRQ(ierr); 699227b6a85dSStefano Zampini } else { 699327b6a85dSStefano Zampini oldranks = NULL; 699427b6a85dSStefano Zampini } 6995b0c7d250SStefano Zampini aggregate = ((redprocs > 0 && redprocs < size) ? PETSC_TRUE : PETSC_FALSE); 699627b6a85dSStefano Zampini if (aggregate) { /* TODO: all this part could be made more efficient */ 6997b0c7d250SStefano Zampini PetscInt lrows,row,ncols,*cols; 6998b0c7d250SStefano Zampini PetscMPIInt nrank; 6999b0c7d250SStefano Zampini PetscScalar *vals; 7000b0c7d250SStefano Zampini 700127b6a85dSStefano Zampini ierr = MPI_Comm_rank(subcomm,&nrank);CHKERRQ(ierr); 7002b0c7d250SStefano Zampini lrows = 0; 7003b0c7d250SStefano Zampini if (nrank<redprocs) { 7004b0c7d250SStefano Zampini lrows = size/redprocs; 7005b0c7d250SStefano Zampini if (nrank<size%redprocs) lrows++; 7006b0c7d250SStefano Zampini } 700727b6a85dSStefano Zampini ierr = MatCreateAIJ(subcomm,lrows,lrows,size,size,50,NULL,50,NULL,&subdomain_adj);CHKERRQ(ierr); 7008b0c7d250SStefano Zampini ierr = MatGetOwnershipRange(subdomain_adj,&rstart,&rend);CHKERRQ(ierr); 7009b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_LOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7010b0c7d250SStefano Zampini ierr = MatSetOption(subdomain_adj,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE);CHKERRQ(ierr); 7011b0c7d250SStefano Zampini row = nrank; 7012b0c7d250SStefano Zampini ncols = xadj[1]-xadj[0]; 7013b0c7d250SStefano Zampini cols = adjncy; 7014b0c7d250SStefano Zampini ierr = PetscMalloc1(ncols,&vals);CHKERRQ(ierr); 7015b0c7d250SStefano Zampini for (i=0;i<ncols;i++) vals[i] = adjncy_wgt[i]; 7016b0c7d250SStefano Zampini ierr = MatSetValues(subdomain_adj,1,&row,ncols,cols,vals,INSERT_VALUES);CHKERRQ(ierr); 7017b0c7d250SStefano Zampini ierr = MatAssemblyBegin(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7018b0c7d250SStefano Zampini ierr = MatAssemblyEnd(subdomain_adj,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 701952e5ac9dSStefano Zampini ierr = PetscFree(xadj);CHKERRQ(ierr); 702052e5ac9dSStefano Zampini ierr = PetscFree(adjncy);CHKERRQ(ierr); 702152e5ac9dSStefano Zampini ierr = PetscFree(adjncy_wgt);CHKERRQ(ierr); 7022b0c7d250SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 702327b6a85dSStefano Zampini if (use_vwgt) { 702427b6a85dSStefano Zampini Vec v; 702527b6a85dSStefano Zampini const PetscScalar *array; 702627b6a85dSStefano Zampini PetscInt nl; 702727b6a85dSStefano Zampini 702827b6a85dSStefano Zampini ierr = MatCreateVecs(subdomain_adj,&v,NULL);CHKERRQ(ierr); 7029bb360cb4SStefano Zampini ierr = VecSetValue(v,row,(PetscScalar)n,INSERT_VALUES);CHKERRQ(ierr); 703027b6a85dSStefano Zampini ierr = VecAssemblyBegin(v);CHKERRQ(ierr); 703127b6a85dSStefano Zampini ierr = VecAssemblyEnd(v);CHKERRQ(ierr); 703227b6a85dSStefano Zampini ierr = VecGetLocalSize(v,&nl);CHKERRQ(ierr); 703327b6a85dSStefano Zampini ierr = VecGetArrayRead(v,&array);CHKERRQ(ierr); 703427b6a85dSStefano Zampini ierr = PetscMalloc1(nl,&v_wgt);CHKERRQ(ierr); 703522db5ddcSStefano Zampini for (i=0;i<nl;i++) v_wgt[i] = (PetscInt)PetscRealPart(array[i]); 703627b6a85dSStefano Zampini ierr = VecRestoreArrayRead(v,&array);CHKERRQ(ierr); 703727b6a85dSStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 703827b6a85dSStefano Zampini } 7039b0c7d250SStefano Zampini } else { 704027b6a85dSStefano Zampini ierr = MatCreateMPIAdj(subcomm,1,(PetscInt)size,xadj,adjncy,adjncy_wgt,&subdomain_adj);CHKERRQ(ierr); 704127b6a85dSStefano Zampini if (use_vwgt) { 704227b6a85dSStefano Zampini ierr = PetscMalloc1(1,&v_wgt);CHKERRQ(ierr); 7043bb360cb4SStefano Zampini v_wgt[0] = n; 704427b6a85dSStefano Zampini } 7045b0c7d250SStefano Zampini } 704622b6e8a2SStefano Zampini /* ierr = MatView(subdomain_adj,0);CHKERRQ(ierr); */ 7047e7931f94SStefano Zampini 7048e7931f94SStefano Zampini /* Partition */ 704927b6a85dSStefano Zampini ierr = MatPartitioningCreate(subcomm,&partitioner);CHKERRQ(ierr); 7050e7931f94SStefano Zampini ierr = MatPartitioningSetAdjacency(partitioner,subdomain_adj);CHKERRQ(ierr); 705127b6a85dSStefano Zampini if (v_wgt) { 7052e7931f94SStefano Zampini ierr = MatPartitioningSetVertexWeights(partitioner,v_wgt);CHKERRQ(ierr); 7053c8587f34SStefano Zampini } 705457de7509SStefano Zampini *n_subdomains = PetscMin((PetscInt)size,*n_subdomains); 705557de7509SStefano Zampini ierr = MatPartitioningSetNParts(partitioner,*n_subdomains);CHKERRQ(ierr); 7056e7931f94SStefano Zampini ierr = MatPartitioningSetFromOptions(partitioner);CHKERRQ(ierr); 7057e7931f94SStefano Zampini ierr = MatPartitioningApply(partitioner,&new_ranks);CHKERRQ(ierr); 705822b6e8a2SStefano Zampini /* ierr = MatPartitioningView(partitioner,0);CHKERRQ(ierr); */ 7059e7931f94SStefano Zampini 706052e5ac9dSStefano Zampini /* renumber new_ranks to avoid "holes" in new set of processors */ 70616583bcc1SStefano Zampini ierr = ISRenumber(new_ranks,NULL,NULL,&new_ranks_contig);CHKERRQ(ierr); 706252e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks);CHKERRQ(ierr); 706352e5ac9dSStefano Zampini ierr = ISGetIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 706457de7509SStefano Zampini if (!aggregate) { 706557de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 706627b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 706727b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 706827b6a85dSStefano Zampini #endif 706957de7509SStefano Zampini ranks_send_to_idx[0] = procs_candidates[oldranks[is_indices[0]]]; 707027b6a85dSStefano Zampini } else if (oldranks) { 7071b0c7d250SStefano Zampini ranks_send_to_idx[0] = oldranks[is_indices[0]]; 707227b6a85dSStefano Zampini } else { 707327b6a85dSStefano Zampini ranks_send_to_idx[0] = is_indices[0]; 707457de7509SStefano Zampini } 707528143c3dSStefano Zampini } else { 70767fb8a5e4SKarl Rupp PetscInt idx = 0; 7077b0c7d250SStefano Zampini PetscMPIInt tag; 7078b0c7d250SStefano Zampini MPI_Request *reqs; 7079b0c7d250SStefano Zampini 7080b0c7d250SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)subdomain_adj,&tag);CHKERRQ(ierr); 7081b0c7d250SStefano Zampini ierr = PetscMalloc1(rend-rstart,&reqs);CHKERRQ(ierr); 7082b0c7d250SStefano Zampini for (i=rstart;i<rend;i++) { 708327b6a85dSStefano Zampini ierr = MPI_Isend(is_indices+i-rstart,1,MPIU_INT,i,tag,subcomm,&reqs[i-rstart]);CHKERRQ(ierr); 708428143c3dSStefano Zampini } 70857fb8a5e4SKarl Rupp ierr = MPI_Recv(&idx,1,MPIU_INT,MPI_ANY_SOURCE,tag,subcomm,MPI_STATUS_IGNORE);CHKERRQ(ierr); 7086b0c7d250SStefano Zampini ierr = MPI_Waitall(rend-rstart,reqs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7087b0c7d250SStefano Zampini ierr = PetscFree(reqs);CHKERRQ(ierr); 708857de7509SStefano Zampini if (procs_candidates) { /* shift the pattern on non-active candidates (if any) */ 708927b6a85dSStefano Zampini #if defined(PETSC_USE_DEBUG) 709027b6a85dSStefano Zampini if (!oldranks) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"This should not happen"); 709127b6a85dSStefano Zampini #endif 70927fb8a5e4SKarl Rupp ranks_send_to_idx[0] = procs_candidates[oldranks[idx]]; 709327b6a85dSStefano Zampini } else if (oldranks) { 70947fb8a5e4SKarl Rupp ranks_send_to_idx[0] = oldranks[idx]; 709527b6a85dSStefano Zampini } else { 70967fb8a5e4SKarl Rupp ranks_send_to_idx[0] = idx; 7097e7931f94SStefano Zampini } 709857de7509SStefano Zampini } 709952e5ac9dSStefano Zampini ierr = ISRestoreIndices(new_ranks_contig,(const PetscInt**)&is_indices);CHKERRQ(ierr); 7100e7931f94SStefano Zampini /* clean up */ 7101e7931f94SStefano Zampini ierr = PetscFree(oldranks);CHKERRQ(ierr); 710252e5ac9dSStefano Zampini ierr = ISDestroy(&new_ranks_contig);CHKERRQ(ierr); 7103e7931f94SStefano Zampini ierr = MatDestroy(&subdomain_adj);CHKERRQ(ierr); 7104e7931f94SStefano Zampini ierr = MatPartitioningDestroy(&partitioner);CHKERRQ(ierr); 7105e7931f94SStefano Zampini } 710627b6a85dSStefano Zampini ierr = PetscSubcommDestroy(&psubcomm);CHKERRQ(ierr); 710757de7509SStefano Zampini ierr = PetscFree(procs_candidates);CHKERRQ(ierr); 7108e7931f94SStefano Zampini 7109e7931f94SStefano Zampini /* assemble parallel IS for sends */ 7110e7931f94SStefano Zampini i = 1; 711127b6a85dSStefano Zampini if (!color) i=0; 711257de7509SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)mat),i,ranks_send_to_idx,PETSC_OWN_POINTER,is_sends);CHKERRQ(ierr); 7113e7931f94SStefano Zampini PetscFunctionReturn(0); 7114e7931f94SStefano Zampini } 7115e7931f94SStefano Zampini 7116e7931f94SStefano Zampini typedef enum {MATDENSE_PRIVATE=0,MATAIJ_PRIVATE,MATBAIJ_PRIVATE,MATSBAIJ_PRIVATE}MatTypePrivate; 7117e7931f94SStefano Zampini 71181e0482f5SStefano 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[]) 7119e7931f94SStefano Zampini { 712070cf5478SStefano Zampini Mat local_mat; 7121e7931f94SStefano Zampini IS is_sends_internal; 71229d30be91SStefano Zampini PetscInt rows,cols,new_local_rows; 71231ae86dd6SStefano Zampini PetscInt i,bs,buf_size_idxs,buf_size_idxs_is,buf_size_vals,buf_size_vecs; 71249d30be91SStefano Zampini PetscBool ismatis,isdense,newisdense,destroy_mat; 7125e7931f94SStefano Zampini ISLocalToGlobalMapping l2gmap; 7126e7931f94SStefano Zampini PetscInt* l2gmap_indices; 7127e7931f94SStefano Zampini const PetscInt* is_indices; 7128e7931f94SStefano Zampini MatType new_local_type; 7129e7931f94SStefano Zampini /* buffers */ 7130e7931f94SStefano Zampini PetscInt *ptr_idxs,*send_buffer_idxs,*recv_buffer_idxs; 713128143c3dSStefano Zampini PetscInt *ptr_idxs_is,*send_buffer_idxs_is,*recv_buffer_idxs_is; 71329d30be91SStefano Zampini PetscInt *recv_buffer_idxs_local; 7133e7931f94SStefano Zampini PetscScalar *ptr_vals,*send_buffer_vals,*recv_buffer_vals; 71341ae86dd6SStefano Zampini PetscScalar *ptr_vecs,*send_buffer_vecs,*recv_buffer_vecs; 7135e7931f94SStefano Zampini /* MPI */ 713628143c3dSStefano Zampini MPI_Comm comm,comm_n; 713728143c3dSStefano Zampini PetscSubcomm subcomm; 7138e7931f94SStefano Zampini PetscMPIInt n_sends,n_recvs,commsize; 713928143c3dSStefano Zampini PetscMPIInt *iflags,*ilengths_idxs,*ilengths_vals,*ilengths_idxs_is; 714028143c3dSStefano Zampini PetscMPIInt *onodes,*onodes_is,*olengths_idxs,*olengths_idxs_is,*olengths_vals; 71411ae86dd6SStefano Zampini PetscMPIInt len,tag_idxs,tag_idxs_is,tag_vals,tag_vecs,source_dest; 71421ae86dd6SStefano Zampini MPI_Request *send_req_idxs,*send_req_idxs_is,*send_req_vals,*send_req_vecs; 71431ae86dd6SStefano Zampini MPI_Request *recv_req_idxs,*recv_req_idxs_is,*recv_req_vals,*recv_req_vecs; 7144e7931f94SStefano Zampini PetscErrorCode ierr; 7145e7931f94SStefano Zampini 7146e7931f94SStefano Zampini PetscFunctionBegin; 714757de7509SStefano Zampini PetscValidHeaderSpecific(mat,MAT_CLASSID,1); 7148e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)mat,MATIS,&ismatis);CHKERRQ(ierr); 7149fbfcfee5SBarry 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); 715057de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,n_subdomains,3); 715157de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_comm,4); 715257de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,restrict_full,5); 715357de7509SStefano Zampini PetscValidLogicalCollectiveBool(mat,reuse,6); 715457de7509SStefano Zampini PetscValidLogicalCollectiveInt(mat,nis,8); 71551ae86dd6SStefano Zampini PetscValidLogicalCollectiveInt(mat,nvecs,10); 71561ae86dd6SStefano Zampini if (nvecs) { 71571ae86dd6SStefano Zampini if (nvecs > 1) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Just 1 vector supported"); 71581ae86dd6SStefano Zampini PetscValidHeaderSpecific(nnsp_vec[0],VEC_CLASSID,11); 71591ae86dd6SStefano Zampini } 716057de7509SStefano Zampini /* further checks */ 7161e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7162e7931f94SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&isdense);CHKERRQ(ierr); 7163e7931f94SStefano Zampini if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Currently cannot subassemble MATIS when local matrix type is not of type SEQDENSE"); 7164e7931f94SStefano Zampini ierr = MatGetSize(local_mat,&rows,&cols);CHKERRQ(ierr); 7165e7931f94SStefano Zampini if (rows != cols) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Local MATIS matrices should be square"); 716657de7509SStefano Zampini if (reuse && *mat_n) { 716770cf5478SStefano Zampini PetscInt mrows,mcols,mnrows,mncols; 716857de7509SStefano Zampini PetscValidHeaderSpecific(*mat_n,MAT_CLASSID,7); 716970cf5478SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)*mat_n,MATIS,&ismatis);CHKERRQ(ierr); 717028143c3dSStefano Zampini if (!ismatis) SETERRQ(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_SUP,"Cannot reuse a matrix which is not of type MATIS"); 717170cf5478SStefano Zampini ierr = MatGetSize(mat,&mrows,&mcols);CHKERRQ(ierr); 717270cf5478SStefano Zampini ierr = MatGetSize(*mat_n,&mnrows,&mncols);CHKERRQ(ierr); 717370cf5478SStefano Zampini if (mrows != mnrows) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of rows %D != %D",mrows,mnrows); 717470cf5478SStefano Zampini if (mcols != mncols) SETERRQ2(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Cannot reuse matrix! Wrong number of cols %D != %D",mcols,mncols); 717570cf5478SStefano Zampini } 7176e7931f94SStefano Zampini ierr = MatGetBlockSize(local_mat,&bs);CHKERRQ(ierr); 7177e7931f94SStefano Zampini PetscValidLogicalCollectiveInt(mat,bs,0); 717857de7509SStefano Zampini 7179e7931f94SStefano Zampini /* prepare IS for sending if not provided */ 7180e7931f94SStefano Zampini if (!is_sends) { 718128143c3dSStefano Zampini if (!n_subdomains) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"You should specify either an IS or a target number of subdomains"); 7182bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(mat,&n_subdomains,0,&is_sends_internal,NULL);CHKERRQ(ierr); 7183c8587f34SStefano Zampini } else { 7184e7931f94SStefano Zampini ierr = PetscObjectReference((PetscObject)is_sends);CHKERRQ(ierr); 7185e7931f94SStefano Zampini is_sends_internal = is_sends; 7186c8587f34SStefano Zampini } 7187e7931f94SStefano Zampini 7188e7931f94SStefano Zampini /* get comm */ 7189a316fed8SStefano Zampini ierr = PetscObjectGetComm((PetscObject)mat,&comm);CHKERRQ(ierr); 7190e7931f94SStefano Zampini 7191e7931f94SStefano Zampini /* compute number of sends */ 7192e7931f94SStefano Zampini ierr = ISGetLocalSize(is_sends_internal,&i);CHKERRQ(ierr); 7193e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&n_sends);CHKERRQ(ierr); 7194e7931f94SStefano Zampini 7195e7931f94SStefano Zampini /* compute number of receives */ 7196e7931f94SStefano Zampini ierr = MPI_Comm_size(comm,&commsize);CHKERRQ(ierr); 7197785e854fSJed Brown ierr = PetscMalloc1(commsize,&iflags);CHKERRQ(ierr); 7198e7931f94SStefano Zampini ierr = PetscMemzero(iflags,commsize*sizeof(*iflags));CHKERRQ(ierr); 7199e7931f94SStefano Zampini ierr = ISGetIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7200e7931f94SStefano Zampini for (i=0;i<n_sends;i++) iflags[is_indices[i]] = 1; 7201e7931f94SStefano Zampini ierr = PetscGatherNumberOfMessages(comm,iflags,NULL,&n_recvs);CHKERRQ(ierr); 7202e7931f94SStefano Zampini ierr = PetscFree(iflags);CHKERRQ(ierr); 7203e7931f94SStefano Zampini 720428143c3dSStefano Zampini /* restrict comm if requested */ 720528143c3dSStefano Zampini subcomm = 0; 720628143c3dSStefano Zampini destroy_mat = PETSC_FALSE; 720728143c3dSStefano Zampini if (restrict_comm) { 7208779c1cceSStefano Zampini PetscMPIInt color,subcommsize; 7209779c1cceSStefano Zampini 721028143c3dSStefano Zampini color = 0; 721153a05cb3SStefano Zampini if (restrict_full) { 721253a05cb3SStefano Zampini if (!n_recvs) color = 1; /* processes not receiving anything will not partecipate in new comm (full restriction) */ 721353a05cb3SStefano Zampini } else { 721453a05cb3SStefano Zampini if (!n_recvs && n_sends) color = 1; /* just those processes that are sending but not receiving anything will not partecipate in new comm */ 721553a05cb3SStefano Zampini } 7216b2566f29SBarry Smith ierr = MPIU_Allreduce(&color,&subcommsize,1,MPI_INT,MPI_SUM,comm);CHKERRQ(ierr); 721728143c3dSStefano Zampini subcommsize = commsize - subcommsize; 721828143c3dSStefano Zampini /* check if reuse has been requested */ 721957de7509SStefano Zampini if (reuse) { 722028143c3dSStefano Zampini if (*mat_n) { 722128143c3dSStefano Zampini PetscMPIInt subcommsize2; 722228143c3dSStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)*mat_n),&subcommsize2);CHKERRQ(ierr); 722328143c3dSStefano Zampini if (subcommsize != subcommsize2) SETERRQ2(PetscObjectComm((PetscObject)*mat_n),PETSC_ERR_PLIB,"Cannot reuse matrix! wrong subcomm size %d != %d",subcommsize,subcommsize2); 722428143c3dSStefano Zampini comm_n = PetscObjectComm((PetscObject)*mat_n); 722528143c3dSStefano Zampini } else { 722628143c3dSStefano Zampini comm_n = PETSC_COMM_SELF; 722728143c3dSStefano Zampini } 722828143c3dSStefano Zampini } else { /* MAT_INITIAL_MATRIX */ 7229779c1cceSStefano Zampini PetscMPIInt rank; 7230779c1cceSStefano Zampini 7231779c1cceSStefano Zampini ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 723228143c3dSStefano Zampini ierr = PetscSubcommCreate(comm,&subcomm);CHKERRQ(ierr); 723328143c3dSStefano Zampini ierr = PetscSubcommSetNumber(subcomm,2);CHKERRQ(ierr); 723428143c3dSStefano Zampini ierr = PetscSubcommSetTypeGeneral(subcomm,color,rank);CHKERRQ(ierr); 7235306c2d5bSBarry Smith comm_n = PetscSubcommChild(subcomm); 723628143c3dSStefano Zampini } 723728143c3dSStefano Zampini /* flag to destroy *mat_n if not significative */ 723828143c3dSStefano Zampini if (color) destroy_mat = PETSC_TRUE; 723928143c3dSStefano Zampini } else { 724028143c3dSStefano Zampini comm_n = comm; 724128143c3dSStefano Zampini } 724228143c3dSStefano Zampini 7243e7931f94SStefano Zampini /* prepare send/receive buffers */ 7244785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_idxs);CHKERRQ(ierr); 7245e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_idxs,commsize*sizeof(*ilengths_idxs));CHKERRQ(ierr); 7246785e854fSJed Brown ierr = PetscMalloc1(commsize,&ilengths_vals);CHKERRQ(ierr); 7247e7931f94SStefano Zampini ierr = PetscMemzero(ilengths_vals,commsize*sizeof(*ilengths_vals));CHKERRQ(ierr); 724828143c3dSStefano Zampini if (nis) { 7249854ce69bSBarry Smith ierr = PetscCalloc1(commsize,&ilengths_idxs_is);CHKERRQ(ierr); 725028143c3dSStefano Zampini } 7251e7931f94SStefano Zampini 725228143c3dSStefano Zampini /* Get data from local matrices */ 72536c4ed002SBarry Smith if (!isdense) SETERRQ(PetscObjectComm((PetscObject)mat),PETSC_ERR_SUP,"Subassembling of AIJ local matrices not yet implemented"); 7254e7931f94SStefano Zampini /* TODO: See below some guidelines on how to prepare the local buffers */ 7255e7931f94SStefano Zampini /* 7256e7931f94SStefano Zampini send_buffer_vals should contain the raw values of the local matrix 7257e7931f94SStefano Zampini send_buffer_idxs should contain: 7258e7931f94SStefano Zampini - MatType_PRIVATE type 7259e7931f94SStefano Zampini - PetscInt size_of_l2gmap 7260e7931f94SStefano Zampini - PetscInt global_row_indices[size_of_l2gmap] 7261e7931f94SStefano Zampini - PetscInt all_other_info_which_is_needed_to_compute_preallocation_and_set_values 7262e7931f94SStefano Zampini */ 72636c4ed002SBarry Smith else { 7264e7931f94SStefano Zampini ierr = MatDenseGetArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 72653bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(mat->rmap->mapping,&i);CHKERRQ(ierr); 7266854ce69bSBarry Smith ierr = PetscMalloc1(i+2,&send_buffer_idxs);CHKERRQ(ierr); 7267e7931f94SStefano Zampini send_buffer_idxs[0] = (PetscInt)MATDENSE_PRIVATE; 7268e7931f94SStefano Zampini send_buffer_idxs[1] = i; 72693bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7270e7931f94SStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs[2],ptr_idxs,i*sizeof(PetscInt));CHKERRQ(ierr); 72713bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(mat->rmap->mapping,(const PetscInt**)&ptr_idxs);CHKERRQ(ierr); 7272e7931f94SStefano Zampini ierr = PetscMPIIntCast(i,&len);CHKERRQ(ierr); 7273e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7274e7931f94SStefano Zampini ilengths_vals[is_indices[i]] = len*len; 7275e7931f94SStefano Zampini ilengths_idxs[is_indices[i]] = len+2; 7276c8587f34SStefano Zampini } 7277c8587f34SStefano Zampini } 7278e7931f94SStefano Zampini ierr = PetscGatherMessageLengths2(comm,n_sends,n_recvs,ilengths_idxs,ilengths_vals,&onodes,&olengths_idxs,&olengths_vals);CHKERRQ(ierr); 727928143c3dSStefano Zampini /* additional is (if any) */ 728028143c3dSStefano Zampini if (nis) { 728128143c3dSStefano Zampini PetscMPIInt psum; 728228143c3dSStefano Zampini PetscInt j; 728328143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 728428143c3dSStefano Zampini PetscInt plen; 728528143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 728628143c3dSStefano Zampini ierr = PetscMPIIntCast(plen,&len);CHKERRQ(ierr); 728728143c3dSStefano Zampini psum += len+1; /* indices + lenght */ 728828143c3dSStefano Zampini } 7289854ce69bSBarry Smith ierr = PetscMalloc1(psum,&send_buffer_idxs_is);CHKERRQ(ierr); 729028143c3dSStefano Zampini for (j=0,psum=0;j<nis;j++) { 729128143c3dSStefano Zampini PetscInt plen; 729228143c3dSStefano Zampini const PetscInt *is_array_idxs; 729328143c3dSStefano Zampini ierr = ISGetLocalSize(isarray[j],&plen);CHKERRQ(ierr); 729428143c3dSStefano Zampini send_buffer_idxs_is[psum] = plen; 729528143c3dSStefano Zampini ierr = ISGetIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 729628143c3dSStefano Zampini ierr = PetscMemcpy(&send_buffer_idxs_is[psum+1],is_array_idxs,plen*sizeof(PetscInt));CHKERRQ(ierr); 729728143c3dSStefano Zampini ierr = ISRestoreIndices(isarray[j],&is_array_idxs);CHKERRQ(ierr); 729828143c3dSStefano Zampini psum += plen+1; /* indices + lenght */ 729928143c3dSStefano Zampini } 730028143c3dSStefano Zampini for (i=0;i<n_sends;i++) { 730128143c3dSStefano Zampini ilengths_idxs_is[is_indices[i]] = psum; 730228143c3dSStefano Zampini } 730328143c3dSStefano Zampini ierr = PetscGatherMessageLengths(comm,n_sends,n_recvs,ilengths_idxs_is,&onodes_is,&olengths_idxs_is);CHKERRQ(ierr); 730428143c3dSStefano Zampini } 73053b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 730628143c3dSStefano Zampini 7307e7931f94SStefano Zampini buf_size_idxs = 0; 7308e7931f94SStefano Zampini buf_size_vals = 0; 730928143c3dSStefano Zampini buf_size_idxs_is = 0; 73101ae86dd6SStefano Zampini buf_size_vecs = 0; 7311e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7312e7931f94SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 7313e7931f94SStefano Zampini buf_size_vals += (PetscInt)olengths_vals[i]; 731428143c3dSStefano Zampini if (nis) buf_size_idxs_is += (PetscInt)olengths_idxs_is[i]; 73151ae86dd6SStefano Zampini if (nvecs) buf_size_vecs += (PetscInt)olengths_idxs[i]; 7316e7931f94SStefano Zampini } 7317785e854fSJed Brown ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs);CHKERRQ(ierr); 7318785e854fSJed Brown ierr = PetscMalloc1(buf_size_vals,&recv_buffer_vals);CHKERRQ(ierr); 731995ecbf38SStefano Zampini ierr = PetscMalloc1(buf_size_idxs_is,&recv_buffer_idxs_is);CHKERRQ(ierr); 73201ae86dd6SStefano Zampini ierr = PetscMalloc1(buf_size_vecs,&recv_buffer_vecs);CHKERRQ(ierr); 7321e7931f94SStefano Zampini 7322e7931f94SStefano Zampini /* get new tags for clean communications */ 7323e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs);CHKERRQ(ierr); 7324e7931f94SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vals);CHKERRQ(ierr); 732528143c3dSStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_idxs_is);CHKERRQ(ierr); 73261ae86dd6SStefano Zampini ierr = PetscObjectGetNewTag((PetscObject)mat,&tag_vecs);CHKERRQ(ierr); 7327e7931f94SStefano Zampini 7328e7931f94SStefano Zampini /* allocate for requests */ 7329785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_idxs);CHKERRQ(ierr); 7330785e854fSJed Brown ierr = PetscMalloc1(n_sends,&send_req_vals);CHKERRQ(ierr); 733195ecbf38SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_idxs_is);CHKERRQ(ierr); 73321ae86dd6SStefano Zampini ierr = PetscMalloc1(n_sends,&send_req_vecs);CHKERRQ(ierr); 7333785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_idxs);CHKERRQ(ierr); 7334785e854fSJed Brown ierr = PetscMalloc1(n_recvs,&recv_req_vals);CHKERRQ(ierr); 733595ecbf38SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_idxs_is);CHKERRQ(ierr); 73361ae86dd6SStefano Zampini ierr = PetscMalloc1(n_recvs,&recv_req_vecs);CHKERRQ(ierr); 7337e7931f94SStefano Zampini 7338e7931f94SStefano Zampini /* communications */ 7339e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7340e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 734128143c3dSStefano Zampini ptr_idxs_is = recv_buffer_idxs_is; 73421ae86dd6SStefano Zampini ptr_vecs = recv_buffer_vecs; 7343e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7344e7931f94SStefano Zampini source_dest = onodes[i]; 7345e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_idxs,olengths_idxs[i],MPIU_INT,source_dest,tag_idxs,comm,&recv_req_idxs[i]);CHKERRQ(ierr); 7346e7931f94SStefano Zampini ierr = MPI_Irecv(ptr_vals,olengths_vals[i],MPIU_SCALAR,source_dest,tag_vals,comm,&recv_req_vals[i]);CHKERRQ(ierr); 7347e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7348e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 734928143c3dSStefano Zampini if (nis) { 735057de7509SStefano Zampini source_dest = onodes_is[i]; 735128143c3dSStefano 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); 735228143c3dSStefano Zampini ptr_idxs_is += olengths_idxs_is[i]; 735328143c3dSStefano Zampini } 73541ae86dd6SStefano Zampini if (nvecs) { 73551ae86dd6SStefano Zampini source_dest = onodes[i]; 73561ae86dd6SStefano Zampini ierr = MPI_Irecv(ptr_vecs,olengths_idxs[i]-2,MPIU_SCALAR,source_dest,tag_vecs,comm,&recv_req_vecs[i]);CHKERRQ(ierr); 73571ae86dd6SStefano Zampini ptr_vecs += olengths_idxs[i]-2; 73581ae86dd6SStefano Zampini } 7359e7931f94SStefano Zampini } 7360e7931f94SStefano Zampini for (i=0;i<n_sends;i++) { 7361e7931f94SStefano Zampini ierr = PetscMPIIntCast(is_indices[i],&source_dest);CHKERRQ(ierr); 7362e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_idxs,ilengths_idxs[source_dest],MPIU_INT,source_dest,tag_idxs,comm,&send_req_idxs[i]);CHKERRQ(ierr); 7363e7931f94SStefano Zampini ierr = MPI_Isend(send_buffer_vals,ilengths_vals[source_dest],MPIU_SCALAR,source_dest,tag_vals,comm,&send_req_vals[i]);CHKERRQ(ierr); 736428143c3dSStefano Zampini if (nis) { 736528143c3dSStefano 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); 736628143c3dSStefano Zampini } 73671ae86dd6SStefano Zampini if (nvecs) { 73681ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 73691ae86dd6SStefano 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); 73701ae86dd6SStefano Zampini } 7371e7931f94SStefano Zampini } 7372e7931f94SStefano Zampini ierr = ISRestoreIndices(is_sends_internal,&is_indices);CHKERRQ(ierr); 7373e7931f94SStefano Zampini ierr = ISDestroy(&is_sends_internal);CHKERRQ(ierr); 7374e7931f94SStefano Zampini 7375e7931f94SStefano Zampini /* assemble new l2g map */ 7376e7931f94SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7377e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 73789d30be91SStefano Zampini new_local_rows = 0; 7379e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 73809d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7381e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7382e7931f94SStefano Zampini } 73839d30be91SStefano Zampini ierr = PetscMalloc1(new_local_rows,&l2gmap_indices);CHKERRQ(ierr); 7384e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 73859d30be91SStefano Zampini new_local_rows = 0; 7386e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 73879d30be91SStefano Zampini ierr = PetscMemcpy(&l2gmap_indices[new_local_rows],ptr_idxs+2,(*(ptr_idxs+1))*sizeof(PetscInt));CHKERRQ(ierr); 73889d30be91SStefano Zampini new_local_rows += *(ptr_idxs+1); /* second element is the local size of the l2gmap */ 7389e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7390e7931f94SStefano Zampini } 73919d30be91SStefano Zampini ierr = PetscSortRemoveDupsInt(&new_local_rows,l2gmap_indices);CHKERRQ(ierr); 73929d30be91SStefano Zampini ierr = ISLocalToGlobalMappingCreate(comm_n,1,new_local_rows,l2gmap_indices,PETSC_COPY_VALUES,&l2gmap);CHKERRQ(ierr); 7393e7931f94SStefano Zampini ierr = PetscFree(l2gmap_indices);CHKERRQ(ierr); 7394e7931f94SStefano Zampini 7395e7931f94SStefano Zampini /* infer new local matrix type from received local matrices type */ 7396e7931f94SStefano Zampini /* currently if all local matrices are of type X, then the resulting matrix will be of type X, except for the dense case */ 7397e7931f94SStefano 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) */ 7398e7931f94SStefano Zampini if (n_recvs) { 739928143c3dSStefano Zampini MatTypePrivate new_local_type_private = (MatTypePrivate)send_buffer_idxs[0]; 7400e7931f94SStefano Zampini ptr_idxs = recv_buffer_idxs; 7401e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7402e7931f94SStefano Zampini if ((PetscInt)new_local_type_private != *ptr_idxs) { 7403e7931f94SStefano Zampini new_local_type_private = MATAIJ_PRIVATE; 7404e7931f94SStefano Zampini break; 7405e7931f94SStefano Zampini } 7406e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7407e7931f94SStefano Zampini } 7408e7931f94SStefano Zampini switch (new_local_type_private) { 740928143c3dSStefano Zampini case MATDENSE_PRIVATE: 7410e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7411e7931f94SStefano Zampini bs = 1; 7412e7931f94SStefano Zampini break; 7413e7931f94SStefano Zampini case MATAIJ_PRIVATE: 7414e7931f94SStefano Zampini new_local_type = MATSEQAIJ; 7415e7931f94SStefano Zampini bs = 1; 7416e7931f94SStefano Zampini break; 7417e7931f94SStefano Zampini case MATBAIJ_PRIVATE: 7418e7931f94SStefano Zampini new_local_type = MATSEQBAIJ; 7419e7931f94SStefano Zampini break; 7420e7931f94SStefano Zampini case MATSBAIJ_PRIVATE: 7421e7931f94SStefano Zampini new_local_type = MATSEQSBAIJ; 7422e7931f94SStefano Zampini break; 7423e7931f94SStefano Zampini default: 7424fbfcfee5SBarry Smith SETERRQ2(comm,PETSC_ERR_SUP,"Unsupported private type %d in %s",new_local_type_private,PETSC_FUNCTION_NAME); 7425e7931f94SStefano Zampini break; 7426e7931f94SStefano Zampini } 7427ed8ed4edSstefano_zampini } else { /* by default, new_local_type is seqaij */ 7428ed8ed4edSstefano_zampini new_local_type = MATSEQAIJ; 742928143c3dSStefano Zampini bs = 1; 7430e7931f94SStefano Zampini } 7431e7931f94SStefano Zampini 743270cf5478SStefano Zampini /* create MATIS object if needed */ 743357de7509SStefano Zampini if (!reuse) { 7434e7931f94SStefano Zampini ierr = MatGetSize(mat,&rows,&cols);CHKERRQ(ierr); 7435e176bc59SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 743670cf5478SStefano Zampini } else { 743770cf5478SStefano Zampini /* it also destroys the local matrices */ 743857de7509SStefano Zampini if (*mat_n) { 743970cf5478SStefano Zampini ierr = MatSetLocalToGlobalMapping(*mat_n,l2gmap,l2gmap);CHKERRQ(ierr); 744057de7509SStefano Zampini } else { /* this is a fake object */ 744157de7509SStefano Zampini ierr = MatCreateIS(comm_n,bs,PETSC_DECIDE,PETSC_DECIDE,rows,cols,l2gmap,NULL,mat_n);CHKERRQ(ierr); 744257de7509SStefano Zampini } 744370cf5478SStefano Zampini } 744470cf5478SStefano Zampini ierr = MatISGetLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 7445e7931f94SStefano Zampini ierr = MatSetType(local_mat,new_local_type);CHKERRQ(ierr); 74469d30be91SStefano Zampini 74479d30be91SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 74489d30be91SStefano Zampini 74499d30be91SStefano Zampini /* Global to local map of received indices */ 74509d30be91SStefano Zampini ierr = PetscMalloc1(buf_size_idxs,&recv_buffer_idxs_local);CHKERRQ(ierr); /* needed for values insertion */ 74519d30be91SStefano Zampini ierr = ISGlobalToLocalMappingApply(l2gmap,IS_GTOLM_MASK,buf_size_idxs,recv_buffer_idxs,&i,recv_buffer_idxs_local);CHKERRQ(ierr); 74529d30be91SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&l2gmap);CHKERRQ(ierr); 74539d30be91SStefano Zampini 74549d30be91SStefano Zampini /* restore attributes -> type of incoming data and its size */ 74559d30be91SStefano Zampini buf_size_idxs = 0; 74569d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 74579d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs] = recv_buffer_idxs[buf_size_idxs]; 74589d30be91SStefano Zampini recv_buffer_idxs_local[buf_size_idxs+1] = recv_buffer_idxs[buf_size_idxs+1]; 74599d30be91SStefano Zampini buf_size_idxs += (PetscInt)olengths_idxs[i]; 74609d30be91SStefano Zampini } 74619d30be91SStefano Zampini ierr = PetscFree(recv_buffer_idxs);CHKERRQ(ierr); 74629d30be91SStefano Zampini 74639d30be91SStefano Zampini /* set preallocation */ 74649d30be91SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)local_mat,MATSEQDENSE,&newisdense);CHKERRQ(ierr); 74659d30be91SStefano Zampini if (!newisdense) { 74669d30be91SStefano Zampini PetscInt *new_local_nnz=0; 74679d30be91SStefano Zampini 74689d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 74699d30be91SStefano Zampini if (n_recvs) { 74709d30be91SStefano Zampini ierr = PetscCalloc1(new_local_rows,&new_local_nnz);CHKERRQ(ierr); 74719d30be91SStefano Zampini } 74729d30be91SStefano Zampini for (i=0;i<n_recvs;i++) { 74739d30be91SStefano Zampini PetscInt j; 74749d30be91SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* preallocation provided for dense case only */ 74759d30be91SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 74769d30be91SStefano Zampini new_local_nnz[*(ptr_idxs+2+j)] += *(ptr_idxs+1); 74779d30be91SStefano Zampini } 74789d30be91SStefano Zampini } else { 74799d30be91SStefano Zampini /* TODO */ 74809d30be91SStefano Zampini } 74819d30be91SStefano Zampini ptr_idxs += olengths_idxs[i]; 74829d30be91SStefano Zampini } 74839d30be91SStefano Zampini if (new_local_nnz) { 74849d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMin(new_local_nnz[i],new_local_rows); 74859d30be91SStefano Zampini ierr = MatSeqAIJSetPreallocation(local_mat,0,new_local_nnz);CHKERRQ(ierr); 74869d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] /= bs; 74879d30be91SStefano Zampini ierr = MatSeqBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 74889d30be91SStefano Zampini for (i=0;i<new_local_rows;i++) new_local_nnz[i] = PetscMax(new_local_nnz[i]-i,0); 74899d30be91SStefano Zampini ierr = MatSeqSBAIJSetPreallocation(local_mat,bs,0,new_local_nnz);CHKERRQ(ierr); 74909d30be91SStefano Zampini } else { 74919d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 74929d30be91SStefano Zampini } 74939d30be91SStefano Zampini ierr = PetscFree(new_local_nnz);CHKERRQ(ierr); 74949d30be91SStefano Zampini } else { 74959d30be91SStefano Zampini ierr = MatSetUp(local_mat);CHKERRQ(ierr); 74969d30be91SStefano Zampini } 7497e7931f94SStefano Zampini 7498e7931f94SStefano Zampini /* set values */ 7499e7931f94SStefano Zampini ptr_vals = recv_buffer_vals; 75009d30be91SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 7501e7931f94SStefano Zampini for (i=0;i<n_recvs;i++) { 7502e7931f94SStefano Zampini if (*ptr_idxs == (PetscInt)MATDENSE_PRIVATE) { /* values insertion provided for dense case only */ 7503e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_FALSE);CHKERRQ(ierr); 75049d30be91SStefano Zampini ierr = MatSetValues(local_mat,*(ptr_idxs+1),ptr_idxs+2,*(ptr_idxs+1),ptr_idxs+2,ptr_vals,ADD_VALUES);CHKERRQ(ierr); 7505e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7506e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FLUSH_ASSEMBLY);CHKERRQ(ierr); 7507e7931f94SStefano Zampini ierr = MatSetOption(local_mat,MAT_ROW_ORIENTED,PETSC_TRUE);CHKERRQ(ierr); 750828143c3dSStefano Zampini } else { 750928143c3dSStefano Zampini /* TODO */ 7510e7931f94SStefano Zampini } 7511e7931f94SStefano Zampini ptr_idxs += olengths_idxs[i]; 7512e7931f94SStefano Zampini ptr_vals += olengths_vals[i]; 7513e7931f94SStefano Zampini } 7514e7931f94SStefano Zampini ierr = MatAssemblyBegin(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7515e7931f94SStefano Zampini ierr = MatAssemblyEnd(local_mat,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 75163b3b1effSJed Brown ierr = MatISRestoreLocalMat(*mat_n,&local_mat);CHKERRQ(ierr); 751770cf5478SStefano Zampini ierr = MatAssemblyBegin(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 751870cf5478SStefano Zampini ierr = MatAssemblyEnd(*mat_n,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 75199d30be91SStefano Zampini ierr = PetscFree(recv_buffer_vals);CHKERRQ(ierr); 7520e7931f94SStefano Zampini 7521dfd14d43SStefano Zampini #if 0 752228143c3dSStefano Zampini if (!restrict_comm) { /* check */ 7523e7931f94SStefano Zampini Vec lvec,rvec; 7524e7931f94SStefano Zampini PetscReal infty_error; 7525e7931f94SStefano Zampini 75262a7a6963SBarry Smith ierr = MatCreateVecs(mat,&rvec,&lvec);CHKERRQ(ierr); 7527e7931f94SStefano Zampini ierr = VecSetRandom(rvec,NULL);CHKERRQ(ierr); 7528e7931f94SStefano Zampini ierr = MatMult(mat,rvec,lvec);CHKERRQ(ierr); 7529e7931f94SStefano Zampini ierr = VecScale(lvec,-1.0);CHKERRQ(ierr); 753070cf5478SStefano Zampini ierr = MatMultAdd(*mat_n,rvec,lvec,lvec);CHKERRQ(ierr); 7531e7931f94SStefano Zampini ierr = VecNorm(lvec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 7532e7931f94SStefano Zampini ierr = PetscPrintf(PetscObjectComm((PetscObject)mat),"Infinity error subassembling %1.6e\n",infty_error); 7533e7931f94SStefano Zampini ierr = VecDestroy(&rvec);CHKERRQ(ierr); 7534e7931f94SStefano Zampini ierr = VecDestroy(&lvec);CHKERRQ(ierr); 7535e7931f94SStefano Zampini } 753628143c3dSStefano Zampini #endif 7537e7931f94SStefano Zampini 753828143c3dSStefano Zampini /* assemble new additional is (if any) */ 753928143c3dSStefano Zampini if (nis) { 754028143c3dSStefano Zampini PetscInt **temp_idxs,*count_is,j,psum; 754128143c3dSStefano Zampini 754228143c3dSStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7543854ce69bSBarry Smith ierr = PetscCalloc1(nis,&count_is);CHKERRQ(ierr); 754428143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 754528143c3dSStefano Zampini psum = 0; 754628143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 754728143c3dSStefano Zampini for (j=0;j<nis;j++) { 754828143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 754928143c3dSStefano Zampini count_is[j] += plen; /* increment counting of buffer for j-th IS */ 755028143c3dSStefano Zampini psum += plen; 755128143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 755228143c3dSStefano Zampini } 755328143c3dSStefano Zampini } 7554854ce69bSBarry Smith ierr = PetscMalloc1(nis,&temp_idxs);CHKERRQ(ierr); 7555854ce69bSBarry Smith ierr = PetscMalloc1(psum,&temp_idxs[0]);CHKERRQ(ierr); 755628143c3dSStefano Zampini for (i=1;i<nis;i++) { 755728143c3dSStefano Zampini temp_idxs[i] = temp_idxs[i-1]+count_is[i-1]; 755828143c3dSStefano Zampini } 755928143c3dSStefano Zampini ierr = PetscMemzero(count_is,nis*sizeof(PetscInt));CHKERRQ(ierr); 756028143c3dSStefano Zampini ptr_idxs = recv_buffer_idxs_is; 756128143c3dSStefano Zampini for (i=0;i<n_recvs;i++) { 756228143c3dSStefano Zampini for (j=0;j<nis;j++) { 756328143c3dSStefano Zampini PetscInt plen = *(ptr_idxs); /* first element is the local size of IS's indices */ 756428143c3dSStefano Zampini ierr = PetscMemcpy(&temp_idxs[j][count_is[j]],ptr_idxs+1,plen*sizeof(PetscInt));CHKERRQ(ierr); 756528143c3dSStefano Zampini count_is[j] += plen; /* increment starting point of buffer for j-th IS */ 756628143c3dSStefano Zampini ptr_idxs += plen+1; /* shift pointer to received data */ 756728143c3dSStefano Zampini } 756828143c3dSStefano Zampini } 756928143c3dSStefano Zampini for (i=0;i<nis;i++) { 757028143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 757128143c3dSStefano Zampini ierr = PetscSortRemoveDupsInt(&count_is[i],temp_idxs[i]);CHKERRQ(ierr);CHKERRQ(ierr); 757228143c3dSStefano Zampini ierr = ISCreateGeneral(comm_n,count_is[i],temp_idxs[i],PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 757328143c3dSStefano Zampini } 757428143c3dSStefano Zampini ierr = PetscFree(count_is);CHKERRQ(ierr); 757528143c3dSStefano Zampini ierr = PetscFree(temp_idxs[0]);CHKERRQ(ierr); 757628143c3dSStefano Zampini ierr = PetscFree(temp_idxs);CHKERRQ(ierr); 757728143c3dSStefano Zampini } 7578e7931f94SStefano Zampini /* free workspace */ 757928143c3dSStefano Zampini ierr = PetscFree(recv_buffer_idxs_is);CHKERRQ(ierr); 7580e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7581e7931f94SStefano Zampini ierr = PetscFree(send_buffer_idxs);CHKERRQ(ierr); 7582e7931f94SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vals,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 7583e7931f94SStefano Zampini if (isdense) { 7584e7931f94SStefano Zampini ierr = MatISGetLocalMat(mat,&local_mat);CHKERRQ(ierr); 7585e7931f94SStefano Zampini ierr = MatDenseRestoreArray(local_mat,&send_buffer_vals);CHKERRQ(ierr); 75863b3b1effSJed Brown ierr = MatISRestoreLocalMat(mat,&local_mat);CHKERRQ(ierr); 7587e7931f94SStefano Zampini } else { 7588e7931f94SStefano Zampini /* ierr = PetscFree(send_buffer_vals);CHKERRQ(ierr); */ 7589e7931f94SStefano Zampini } 759028143c3dSStefano Zampini if (nis) { 759128143c3dSStefano Zampini ierr = MPI_Waitall(n_sends,send_req_idxs_is,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 759228143c3dSStefano Zampini ierr = PetscFree(send_buffer_idxs_is);CHKERRQ(ierr); 759328143c3dSStefano Zampini } 75941ae86dd6SStefano Zampini 75951ae86dd6SStefano Zampini if (nvecs) { 75961ae86dd6SStefano Zampini ierr = MPI_Waitall(n_recvs,recv_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 75971ae86dd6SStefano Zampini ierr = MPI_Waitall(n_sends,send_req_vecs,MPI_STATUSES_IGNORE);CHKERRQ(ierr); 75981ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 75991ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 76001ae86dd6SStefano Zampini ierr = VecCreate(comm_n,&nnsp_vec[0]);CHKERRQ(ierr); 76011ae86dd6SStefano Zampini ierr = VecSetSizes(nnsp_vec[0],new_local_rows,PETSC_DECIDE);CHKERRQ(ierr); 76021ae86dd6SStefano Zampini ierr = VecSetType(nnsp_vec[0],VECSTANDARD);CHKERRQ(ierr); 76031ae86dd6SStefano Zampini /* set values */ 76041ae86dd6SStefano Zampini ptr_vals = recv_buffer_vecs; 76051ae86dd6SStefano Zampini ptr_idxs = recv_buffer_idxs_local; 76061ae86dd6SStefano Zampini ierr = VecGetArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 76071ae86dd6SStefano Zampini for (i=0;i<n_recvs;i++) { 76081ae86dd6SStefano Zampini PetscInt j; 76091ae86dd6SStefano Zampini for (j=0;j<*(ptr_idxs+1);j++) { 76101ae86dd6SStefano Zampini send_buffer_vecs[*(ptr_idxs+2+j)] += *(ptr_vals + j); 76111ae86dd6SStefano Zampini } 76121ae86dd6SStefano Zampini ptr_idxs += olengths_idxs[i]; 76131ae86dd6SStefano Zampini ptr_vals += olengths_idxs[i]-2; 76141ae86dd6SStefano Zampini } 76151ae86dd6SStefano Zampini ierr = VecRestoreArray(nnsp_vec[0],&send_buffer_vecs);CHKERRQ(ierr); 76161ae86dd6SStefano Zampini ierr = VecAssemblyBegin(nnsp_vec[0]);CHKERRQ(ierr); 76171ae86dd6SStefano Zampini ierr = VecAssemblyEnd(nnsp_vec[0]);CHKERRQ(ierr); 76181ae86dd6SStefano Zampini } 76191ae86dd6SStefano Zampini 76201ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_vecs);CHKERRQ(ierr); 76211ae86dd6SStefano Zampini ierr = PetscFree(recv_buffer_idxs_local);CHKERRQ(ierr); 7622e7931f94SStefano Zampini ierr = PetscFree(recv_req_idxs);CHKERRQ(ierr); 7623e7931f94SStefano Zampini ierr = PetscFree(recv_req_vals);CHKERRQ(ierr); 76241ae86dd6SStefano Zampini ierr = PetscFree(recv_req_vecs);CHKERRQ(ierr); 762528143c3dSStefano Zampini ierr = PetscFree(recv_req_idxs_is);CHKERRQ(ierr); 7626e7931f94SStefano Zampini ierr = PetscFree(send_req_idxs);CHKERRQ(ierr); 7627e7931f94SStefano Zampini ierr = PetscFree(send_req_vals);CHKERRQ(ierr); 76281ae86dd6SStefano Zampini ierr = PetscFree(send_req_vecs);CHKERRQ(ierr); 762928143c3dSStefano Zampini ierr = PetscFree(send_req_idxs_is);CHKERRQ(ierr); 7630e7931f94SStefano Zampini ierr = PetscFree(ilengths_vals);CHKERRQ(ierr); 7631e7931f94SStefano Zampini ierr = PetscFree(ilengths_idxs);CHKERRQ(ierr); 7632e7931f94SStefano Zampini ierr = PetscFree(olengths_vals);CHKERRQ(ierr); 7633e7931f94SStefano Zampini ierr = PetscFree(olengths_idxs);CHKERRQ(ierr); 7634e7931f94SStefano Zampini ierr = PetscFree(onodes);CHKERRQ(ierr); 763528143c3dSStefano Zampini if (nis) { 763628143c3dSStefano Zampini ierr = PetscFree(ilengths_idxs_is);CHKERRQ(ierr); 763728143c3dSStefano Zampini ierr = PetscFree(olengths_idxs_is);CHKERRQ(ierr); 763828143c3dSStefano Zampini ierr = PetscFree(onodes_is);CHKERRQ(ierr); 763928143c3dSStefano Zampini } 764028143c3dSStefano Zampini ierr = PetscSubcommDestroy(&subcomm);CHKERRQ(ierr); 764128143c3dSStefano Zampini if (destroy_mat) { /* destroy mat is true only if restrict comm is true and process will not partecipate */ 764228143c3dSStefano Zampini ierr = MatDestroy(mat_n);CHKERRQ(ierr); 764328143c3dSStefano Zampini for (i=0;i<nis;i++) { 764428143c3dSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 764528143c3dSStefano Zampini } 76461ae86dd6SStefano Zampini if (nvecs) { /* need to match VecDestroy nnsp_vec called in the other code path */ 76471ae86dd6SStefano Zampini ierr = VecDestroy(&nnsp_vec[0]);CHKERRQ(ierr); 76481ae86dd6SStefano Zampini } 764953a05cb3SStefano Zampini *mat_n = NULL; 765028143c3dSStefano Zampini } 7651e7931f94SStefano Zampini PetscFunctionReturn(0); 7652e7931f94SStefano Zampini } 7653a57a6d2fSStefano Zampini 765412edc857SStefano Zampini /* temporary hack into ksp private data structure */ 7655af0996ceSBarry Smith #include <petsc/private/kspimpl.h> 765612edc857SStefano Zampini 7657c8587f34SStefano Zampini PetscErrorCode PCBDDCSetUpCoarseSolver(PC pc,PetscScalar* coarse_submat_vals) 7658c8587f34SStefano Zampini { 7659c8587f34SStefano Zampini PC_BDDC *pcbddc = (PC_BDDC*)pc->data; 7660c8587f34SStefano Zampini PC_IS *pcis = (PC_IS*)pc->data; 766120a2ab83SStefano Zampini Mat coarse_mat,coarse_mat_is,coarse_submat_dense; 76621ae86dd6SStefano Zampini Mat coarsedivudotp = NULL; 76631e0482f5SStefano Zampini Mat coarseG,t_coarse_mat_is; 76649881197aSStefano Zampini MatNullSpace CoarseNullSpace = NULL; 766520a2ab83SStefano Zampini ISLocalToGlobalMapping coarse_islg; 76666e683305SStefano Zampini IS coarse_is,*isarray; 76676e683305SStefano Zampini PetscInt i,im_active=-1,active_procs=-1; 766830368db7SStefano Zampini PetscInt nis,nisdofs,nisneu,nisvert; 7669f9eb5b7dSStefano Zampini PC pc_temp; 7670c8587f34SStefano Zampini PCType coarse_pc_type; 7671c8587f34SStefano Zampini KSPType coarse_ksp_type; 7672f9eb5b7dSStefano Zampini PetscBool multilevel_requested,multilevel_allowed; 76737274672aSStefano Zampini PetscBool coarse_reuse; 76741e0482f5SStefano Zampini PetscInt ncoarse,nedcfield; 767568457ee5SStefano Zampini PetscBool compute_vecs = PETSC_FALSE; 767622bc73bbSStefano Zampini PetscScalar *array; 767757de7509SStefano Zampini MatReuse coarse_mat_reuse; 767857de7509SStefano Zampini PetscBool restr, full_restr, have_void; 76797de4f681Sstefano_zampini PetscMPIInt commsize; 76809881197aSStefano Zampini PetscErrorCode ierr; 7681fdc09c96SStefano Zampini 7682c8587f34SStefano Zampini PetscFunctionBegin; 7683c8587f34SStefano Zampini /* Assign global numbering to coarse dofs */ 768468457ee5SStefano 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 */ 7685fa7f1dd8SStefano Zampini PetscInt ocoarse_size; 76865a75c04eSSatish Balay compute_vecs = PETSC_TRUE; 76877de4f681Sstefano_zampini 76887de4f681Sstefano_zampini pcbddc->new_primal_space = PETSC_TRUE; 7689fa7f1dd8SStefano Zampini ocoarse_size = pcbddc->coarse_size; 7690f4ddd8eeSStefano Zampini ierr = PetscFree(pcbddc->global_primal_indices);CHKERRQ(ierr); 7691f4ddd8eeSStefano Zampini ierr = PCBDDCComputePrimalNumbering(pc,&pcbddc->coarse_size,&pcbddc->global_primal_indices);CHKERRQ(ierr); 7692f4ddd8eeSStefano Zampini /* see if we can avoid some work */ 7693fa7f1dd8SStefano Zampini if (pcbddc->coarse_ksp) { /* coarse ksp has already been created */ 769451bea450SStefano Zampini /* if the coarse size is different or we are using adaptive selection, better to not reuse the coarse matrix */ 769551bea450SStefano Zampini if (ocoarse_size != pcbddc->coarse_size || pcbddc->adaptive_selection) { 7696727cdba6SStefano Zampini ierr = KSPReset(pcbddc->coarse_ksp);CHKERRQ(ierr); 7697fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7698fa7f1dd8SStefano Zampini } else { /* we can safely reuse already computed coarse matrix */ 7699fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7700f4ddd8eeSStefano Zampini } 7701fa7f1dd8SStefano Zampini } else { /* there's no coarse ksp, so we need to create the coarse matrix too */ 7702fa7f1dd8SStefano Zampini coarse_reuse = PETSC_FALSE; 7703f4ddd8eeSStefano Zampini } 770470cf5478SStefano Zampini /* reset any subassembling information */ 770557de7509SStefano Zampini if (!coarse_reuse || pcbddc->recompute_topography) { 770670cf5478SStefano Zampini ierr = ISDestroy(&pcbddc->coarse_subassembling);CHKERRQ(ierr); 770757de7509SStefano Zampini } 77086e683305SStefano Zampini } else { /* primal space is unchanged, so we can reuse coarse matrix */ 7709fa7f1dd8SStefano Zampini coarse_reuse = PETSC_TRUE; 7710f4ddd8eeSStefano Zampini } 771157de7509SStefano Zampini /* assemble coarse matrix */ 771257de7509SStefano Zampini if (coarse_reuse && pcbddc->coarse_ksp) { 771357de7509SStefano Zampini ierr = KSPGetOperators(pcbddc->coarse_ksp,&coarse_mat,NULL);CHKERRQ(ierr); 771457de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat);CHKERRQ(ierr); 771557de7509SStefano Zampini coarse_mat_reuse = MAT_REUSE_MATRIX; 771618a45a71SStefano Zampini } else { 771757de7509SStefano Zampini coarse_mat = NULL; 771857de7509SStefano Zampini coarse_mat_reuse = MAT_INITIAL_MATRIX; 77196e683305SStefano Zampini } 7720e7931f94SStefano Zampini 7721abbbba34SStefano Zampini /* creates temporary l2gmap and IS for coarse indexes */ 7722abbbba34SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),pcbddc->local_primal_size,pcbddc->global_primal_indices,PETSC_COPY_VALUES,&coarse_is);CHKERRQ(ierr); 7723abbbba34SStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(coarse_is,&coarse_islg);CHKERRQ(ierr); 7724abbbba34SStefano Zampini 7725abbbba34SStefano Zampini /* creates temporary MATIS object for coarse matrix */ 772622bc73bbSStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,pcbddc->local_primal_size,pcbddc->local_primal_size,NULL,&coarse_submat_dense);CHKERRQ(ierr); 772722bc73bbSStefano Zampini ierr = MatDenseGetArray(coarse_submat_dense,&array);CHKERRQ(ierr); 772822bc73bbSStefano Zampini ierr = PetscMemcpy(array,coarse_submat_vals,sizeof(*coarse_submat_vals)*pcbddc->local_primal_size*pcbddc->local_primal_size);CHKERRQ(ierr); 772922bc73bbSStefano Zampini ierr = MatDenseRestoreArray(coarse_submat_dense,&array);CHKERRQ(ierr); 7730e176bc59SStefano 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); 77316e683305SStefano Zampini ierr = MatISSetLocalMat(t_coarse_mat_is,coarse_submat_dense);CHKERRQ(ierr); 77326e683305SStefano Zampini ierr = MatAssemblyBegin(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 77336e683305SStefano Zampini ierr = MatAssemblyEnd(t_coarse_mat_is,MAT_FINAL_ASSEMBLY);CHKERRQ(ierr); 7734abbbba34SStefano Zampini ierr = MatDestroy(&coarse_submat_dense);CHKERRQ(ierr); 7735abbbba34SStefano Zampini 773657de7509SStefano Zampini /* count "active" (i.e. with positive local size) and "void" processes */ 773757de7509SStefano Zampini im_active = !!(pcis->n); 773857de7509SStefano Zampini ierr = MPIU_Allreduce(&im_active,&active_procs,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 773957de7509SStefano Zampini 774014f0bfb9SStefano Zampini /* determine number of processes partecipating to coarse solver and compute subassembling pattern */ 774157de7509SStefano Zampini /* restr : whether if we want to exclude senders (which are not receivers) from the subassembling pattern */ 774257de7509SStefano Zampini /* full_restr : just use the receivers from the subassembling pattern */ 77437de4f681Sstefano_zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)pc),&commsize);CHKERRQ(ierr); 774457de7509SStefano Zampini coarse_mat_is = NULL; 774557de7509SStefano Zampini multilevel_allowed = PETSC_FALSE; 774657de7509SStefano Zampini multilevel_requested = PETSC_FALSE; 77471ae86dd6SStefano Zampini pcbddc->coarse_eqs_per_proc = PetscMin(PetscMax(pcbddc->coarse_size,1),pcbddc->coarse_eqs_per_proc); 774857de7509SStefano Zampini if (pcbddc->current_level < pcbddc->max_levels) multilevel_requested = PETSC_TRUE; 774957de7509SStefano Zampini if (multilevel_requested) { 775057de7509SStefano Zampini ncoarse = active_procs/pcbddc->coarsening_ratio; 775157de7509SStefano Zampini restr = PETSC_FALSE; 775257de7509SStefano Zampini full_restr = PETSC_FALSE; 775357de7509SStefano Zampini } else { 775457de7509SStefano Zampini ncoarse = pcbddc->coarse_size/pcbddc->coarse_eqs_per_proc; 775557de7509SStefano Zampini restr = PETSC_TRUE; 775657de7509SStefano Zampini full_restr = PETSC_TRUE; 775757de7509SStefano Zampini } 77587de4f681Sstefano_zampini if (!pcbddc->coarse_size || commsize == 1) multilevel_allowed = multilevel_requested = restr = full_restr = PETSC_FALSE; 775957de7509SStefano Zampini ncoarse = PetscMax(1,ncoarse); 776057de7509SStefano Zampini if (!pcbddc->coarse_subassembling) { 7761a198735bSStefano Zampini if (pcbddc->coarsening_ratio > 1) { 7762bb360cb4SStefano Zampini if (multilevel_requested) { 7763bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(pc->pmat,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7764bb360cb4SStefano Zampini } else { 7765bb360cb4SStefano Zampini ierr = PCBDDCMatISGetSubassemblingPattern(t_coarse_mat_is,&ncoarse,pcbddc->coarse_adj_red,&pcbddc->coarse_subassembling,&have_void);CHKERRQ(ierr); 7766bb360cb4SStefano Zampini } 7767a198735bSStefano Zampini } else { 77687de4f681Sstefano_zampini PetscMPIInt rank; 7769a198735bSStefano Zampini ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)pc),&rank);CHKERRQ(ierr); 77707de4f681Sstefano_zampini have_void = (active_procs == (PetscInt)commsize) ? PETSC_FALSE : PETSC_TRUE; 7771a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)pc),1,rank,1,&pcbddc->coarse_subassembling);CHKERRQ(ierr); 7772a198735bSStefano Zampini } 777357de7509SStefano Zampini } else { /* if a subassembling pattern exists, then we can reuse the coarse ksp and compute the number of process involved */ 777457de7509SStefano Zampini PetscInt psum; 777557de7509SStefano Zampini if (pcbddc->coarse_ksp) psum = 1; 777657de7509SStefano Zampini else psum = 0; 777757de7509SStefano Zampini ierr = MPIU_Allreduce(&psum,&ncoarse,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 77787de4f681Sstefano_zampini if (ncoarse < commsize) have_void = PETSC_TRUE; 777957de7509SStefano Zampini } 778057de7509SStefano Zampini /* determine if we can go multilevel */ 778157de7509SStefano Zampini if (multilevel_requested) { 778257de7509SStefano Zampini if (ncoarse > 1) multilevel_allowed = PETSC_TRUE; /* found enough processes */ 778357de7509SStefano Zampini else restr = full_restr = PETSC_TRUE; /* 1 subdomain, use a direct solver */ 778457de7509SStefano Zampini } 778557de7509SStefano Zampini if (multilevel_allowed && have_void) restr = PETSC_TRUE; 778657de7509SStefano Zampini 7787e4d548c7SStefano Zampini /* dump subassembling pattern */ 7788e4d548c7SStefano Zampini if (pcbddc->dbg_flag && multilevel_allowed) { 7789e4d548c7SStefano Zampini ierr = ISView(pcbddc->coarse_subassembling,pcbddc->dbg_viewer);CHKERRQ(ierr); 7790e4d548c7SStefano Zampini } 7791e4d548c7SStefano Zampini 77926e683305SStefano Zampini /* compute dofs splitting and neumann boundaries for coarse dofs */ 77931e0482f5SStefano Zampini nedcfield = -1; 77941e0482f5SStefano Zampini if (multilevel_allowed && !coarse_reuse && (pcbddc->n_ISForDofsLocal || pcbddc->NeumannBoundariesLocal || pcbddc->nedclocal)) { /* protects from unneded computations */ 77956e683305SStefano Zampini PetscInt *tidxs,*tidxs2,nout,tsize,i; 77966e683305SStefano Zampini const PetscInt *idxs; 77976e683305SStefano Zampini ISLocalToGlobalMapping tmap; 77986e683305SStefano Zampini 77996e683305SStefano Zampini /* create map between primal indices (in local representative ordering) and local primal numbering */ 78000be93d54SStefano Zampini ierr = ISLocalToGlobalMappingCreate(PETSC_COMM_SELF,1,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,PETSC_COPY_VALUES,&tmap);CHKERRQ(ierr); 78016e683305SStefano Zampini /* allocate space for temporary storage */ 7802854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs);CHKERRQ(ierr); 7803854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->local_primal_size,&tidxs2);CHKERRQ(ierr); 78046e683305SStefano Zampini /* allocate for IS array */ 78056e683305SStefano Zampini nisdofs = pcbddc->n_ISForDofsLocal; 78061e0482f5SStefano Zampini if (pcbddc->nedclocal) { 78071e0482f5SStefano Zampini if (pcbddc->nedfield > -1) { 78081e0482f5SStefano Zampini nedcfield = pcbddc->nedfield; 78091e0482f5SStefano Zampini } else { 78101e0482f5SStefano Zampini nedcfield = 0; 78111e0482f5SStefano Zampini if (nisdofs) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"This should not happen (%d)",nisdofs); 78121e0482f5SStefano Zampini nisdofs = 1; 78131e0482f5SStefano Zampini } 78141e0482f5SStefano Zampini } 78156e683305SStefano Zampini nisneu = !!pcbddc->NeumannBoundariesLocal; 781627b6a85dSStefano Zampini nisvert = 0; /* nisvert is not used */ 781730368db7SStefano Zampini nis = nisdofs + nisneu + nisvert; 7818854ce69bSBarry Smith ierr = PetscMalloc1(nis,&isarray);CHKERRQ(ierr); 78196e683305SStefano Zampini /* dofs splitting */ 78206e683305SStefano Zampini for (i=0;i<nisdofs;i++) { 78216e683305SStefano Zampini /* ierr = ISView(pcbddc->ISForDofsLocal[i],0);CHKERRQ(ierr); */ 78221e0482f5SStefano Zampini if (nedcfield != i) { 78236e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->ISForDofsLocal[i],&tsize);CHKERRQ(ierr); 78246e683305SStefano Zampini ierr = ISGetIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 78256e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 78266e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->ISForDofsLocal[i],&idxs);CHKERRQ(ierr); 78271e0482f5SStefano Zampini } else { 78281e0482f5SStefano Zampini ierr = ISGetLocalSize(pcbddc->nedclocal,&tsize);CHKERRQ(ierr); 78291e0482f5SStefano Zampini ierr = ISGetIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 78301e0482f5SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 7831eee23b56SStefano Zampini if (tsize != nout) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_PLIB,"Failed when mapping coarse nedelec field! %d != %d\n",tsize,nout); 78321e0482f5SStefano Zampini ierr = ISRestoreIndices(pcbddc->nedclocal,&idxs);CHKERRQ(ierr); 78331e0482f5SStefano Zampini } 78346e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 783530368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[i]);CHKERRQ(ierr); 78366e683305SStefano Zampini /* ierr = ISView(isarray[i],0);CHKERRQ(ierr); */ 78376e683305SStefano Zampini } 78386e683305SStefano Zampini /* neumann boundaries */ 78396e683305SStefano Zampini if (pcbddc->NeumannBoundariesLocal) { 78406e683305SStefano Zampini /* ierr = ISView(pcbddc->NeumannBoundariesLocal,0);CHKERRQ(ierr); */ 78416e683305SStefano Zampini ierr = ISGetLocalSize(pcbddc->NeumannBoundariesLocal,&tsize);CHKERRQ(ierr); 78426e683305SStefano Zampini ierr = ISGetIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 78436e683305SStefano Zampini ierr = ISGlobalToLocalMappingApply(tmap,IS_GTOLM_DROP,tsize,idxs,&nout,tidxs);CHKERRQ(ierr); 78446e683305SStefano Zampini ierr = ISRestoreIndices(pcbddc->NeumannBoundariesLocal,&idxs);CHKERRQ(ierr); 78456e683305SStefano Zampini ierr = ISLocalToGlobalMappingApply(coarse_islg,nout,tidxs,tidxs2);CHKERRQ(ierr); 784630368db7SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),nout,tidxs2,PETSC_COPY_VALUES,&isarray[nisdofs]);CHKERRQ(ierr); 78476e683305SStefano Zampini /* ierr = ISView(isarray[nisdofs],0);CHKERRQ(ierr); */ 78486e683305SStefano Zampini } 78496e683305SStefano Zampini /* free memory */ 78506e683305SStefano Zampini ierr = PetscFree(tidxs);CHKERRQ(ierr); 78516e683305SStefano Zampini ierr = PetscFree(tidxs2);CHKERRQ(ierr); 78526e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&tmap);CHKERRQ(ierr); 78536e683305SStefano Zampini } else { 78546e683305SStefano Zampini nis = 0; 78556e683305SStefano Zampini nisdofs = 0; 78566e683305SStefano Zampini nisneu = 0; 785730368db7SStefano Zampini nisvert = 0; 78586e683305SStefano Zampini isarray = NULL; 78596e683305SStefano Zampini } 78606e683305SStefano Zampini /* destroy no longer needed map */ 78616e683305SStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&coarse_islg);CHKERRQ(ierr); 78626e683305SStefano Zampini 786357de7509SStefano Zampini /* subassemble */ 786457de7509SStefano Zampini if (multilevel_allowed) { 78651ae86dd6SStefano Zampini Vec vp[1]; 78661ae86dd6SStefano Zampini PetscInt nvecs = 0; 786757de7509SStefano Zampini PetscBool reuse,reuser; 78681ae86dd6SStefano Zampini 786957de7509SStefano Zampini if (coarse_mat) reuse = PETSC_TRUE; 787057de7509SStefano Zampini else reuse = PETSC_FALSE; 787157de7509SStefano Zampini ierr = MPIU_Allreduce(&reuse,&reuser,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 78721ae86dd6SStefano Zampini vp[0] = NULL; 78731ae86dd6SStefano Zampini if (pcbddc->benign_have_null) { /* propagate no-net-flux quadrature to coarser level */ 78741ae86dd6SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&vp[0]);CHKERRQ(ierr); 78751ae86dd6SStefano Zampini ierr = VecSetSizes(vp[0],pcbddc->local_primal_size,PETSC_DECIDE);CHKERRQ(ierr); 78761ae86dd6SStefano Zampini ierr = VecSetType(vp[0],VECSTANDARD);CHKERRQ(ierr); 78771ae86dd6SStefano Zampini nvecs = 1; 78781ae86dd6SStefano Zampini 78791ae86dd6SStefano Zampini if (pcbddc->divudotp) { 7880a198735bSStefano Zampini Mat B,loc_divudotp; 78811ae86dd6SStefano Zampini Vec v,p; 78821ae86dd6SStefano Zampini IS dummy; 78831ae86dd6SStefano Zampini PetscInt np; 78841ae86dd6SStefano Zampini 7885a198735bSStefano Zampini ierr = MatISGetLocalMat(pcbddc->divudotp,&loc_divudotp);CHKERRQ(ierr); 7886a198735bSStefano Zampini ierr = MatGetSize(loc_divudotp,&np,NULL);CHKERRQ(ierr); 78871ae86dd6SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,np,0,1,&dummy);CHKERRQ(ierr); 78887dae84e0SHong Zhang ierr = MatCreateSubMatrix(loc_divudotp,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B);CHKERRQ(ierr); 78891ae86dd6SStefano Zampini ierr = MatCreateVecs(B,&v,&p);CHKERRQ(ierr); 78901ae86dd6SStefano Zampini ierr = VecSet(p,1.);CHKERRQ(ierr); 78911ae86dd6SStefano Zampini ierr = MatMultTranspose(B,p,v);CHKERRQ(ierr); 78921ae86dd6SStefano Zampini ierr = VecDestroy(&p);CHKERRQ(ierr); 78931ae86dd6SStefano Zampini ierr = MatDestroy(&B);CHKERRQ(ierr); 78941ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&array);CHKERRQ(ierr); 78951ae86dd6SStefano Zampini ierr = VecPlaceArray(pcbddc->vec1_P,array);CHKERRQ(ierr); 78961ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&array);CHKERRQ(ierr); 78971ae86dd6SStefano Zampini ierr = MatMultTranspose(pcbddc->coarse_phi_B,v,pcbddc->vec1_P);CHKERRQ(ierr); 78981ae86dd6SStefano Zampini ierr = VecResetArray(pcbddc->vec1_P);CHKERRQ(ierr); 78991ae86dd6SStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 79001ae86dd6SStefano Zampini ierr = VecDestroy(&v);CHKERRQ(ierr); 790174e2c79eSStefano Zampini } 79021ae86dd6SStefano Zampini } 79031ae86dd6SStefano Zampini if (reuser) { 79041e0482f5SStefano Zampini ierr = PCBDDCMatISSubassemble(t_coarse_mat_is,pcbddc->coarse_subassembling,0,restr,full_restr,PETSC_TRUE,&coarse_mat,nis,isarray,nvecs,vp);CHKERRQ(ierr); 790574e2c79eSStefano Zampini } else { 79061e0482f5SStefano 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); 79071ae86dd6SStefano Zampini } 79081ae86dd6SStefano Zampini if (vp[0]) { /* vp[0] could have been placed on a different set of processes */ 79091ae86dd6SStefano Zampini PetscScalar *arraym,*arrayv; 79101ae86dd6SStefano Zampini PetscInt nl; 79111ae86dd6SStefano Zampini ierr = VecGetLocalSize(vp[0],&nl);CHKERRQ(ierr); 79121ae86dd6SStefano Zampini ierr = MatCreateSeqDense(PETSC_COMM_SELF,1,nl,NULL,&coarsedivudotp);CHKERRQ(ierr); 79131ae86dd6SStefano Zampini ierr = MatDenseGetArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 79141ae86dd6SStefano Zampini ierr = VecGetArray(vp[0],&arrayv);CHKERRQ(ierr); 79151ae86dd6SStefano Zampini ierr = PetscMemcpy(arraym,arrayv,nl*sizeof(PetscScalar));CHKERRQ(ierr); 79161ae86dd6SStefano Zampini ierr = VecRestoreArray(vp[0],&arrayv);CHKERRQ(ierr); 79171ae86dd6SStefano Zampini ierr = MatDenseRestoreArray(coarsedivudotp,&arraym);CHKERRQ(ierr); 79181ae86dd6SStefano Zampini ierr = VecDestroy(&vp[0]);CHKERRQ(ierr); 7919a198735bSStefano Zampini } else { 7920a198735bSStefano Zampini ierr = MatCreateSeqAIJ(PETSC_COMM_SELF,0,0,1,NULL,&coarsedivudotp);CHKERRQ(ierr); 79211ae86dd6SStefano Zampini } 79221ae86dd6SStefano Zampini } else { 79231e0482f5SStefano 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); 79246e683305SStefano Zampini } 792557de7509SStefano Zampini if (coarse_mat_is || coarse_mat) { 792657de7509SStefano Zampini PetscMPIInt size; 7927f913dca9SStefano Zampini ierr = MPI_Comm_size(PetscObjectComm((PetscObject)coarse_mat_is),&size);CHKERRQ(ierr); 792857de7509SStefano Zampini if (!multilevel_allowed) { 792957de7509SStefano Zampini ierr = MatISGetMPIXAIJ(coarse_mat_is,coarse_mat_reuse,&coarse_mat);CHKERRQ(ierr); 79306e683305SStefano Zampini } else { 793157de7509SStefano Zampini Mat A; 7932779c1cceSStefano Zampini 793357de7509SStefano Zampini /* if this matrix is present, it means we are not reusing the coarse matrix */ 793457de7509SStefano Zampini if (coarse_mat_is) { 793557de7509SStefano Zampini if (coarse_mat) SETERRQ(PetscObjectComm((PetscObject)coarse_mat_is),PETSC_ERR_PLIB,"This should not happen"); 793657de7509SStefano Zampini ierr = PetscObjectReference((PetscObject)coarse_mat_is);CHKERRQ(ierr); 793757de7509SStefano Zampini coarse_mat = coarse_mat_is; 793857de7509SStefano Zampini } 793957de7509SStefano Zampini /* be sure we don't have MatSeqDENSE as local mat */ 794057de7509SStefano Zampini ierr = MatISGetLocalMat(coarse_mat,&A);CHKERRQ(ierr); 794157de7509SStefano Zampini ierr = MatConvert(A,MATSEQAIJ,MAT_INPLACE_MATRIX,&A);CHKERRQ(ierr); 7942779c1cceSStefano Zampini } 7943779c1cceSStefano Zampini } 794457de7509SStefano Zampini ierr = MatDestroy(&t_coarse_mat_is);CHKERRQ(ierr); 794557de7509SStefano Zampini ierr = MatDestroy(&coarse_mat_is);CHKERRQ(ierr); 79466e683305SStefano Zampini 79476e683305SStefano Zampini /* create local to global scatters for coarse problem */ 794868457ee5SStefano Zampini if (compute_vecs) { 79496e683305SStefano Zampini PetscInt lrows; 79506e683305SStefano Zampini ierr = VecDestroy(&pcbddc->coarse_vec);CHKERRQ(ierr); 795157de7509SStefano Zampini if (coarse_mat) { 795257de7509SStefano Zampini ierr = MatGetLocalSize(coarse_mat,&lrows,NULL);CHKERRQ(ierr); 79536e683305SStefano Zampini } else { 79546e683305SStefano Zampini lrows = 0; 79556e683305SStefano Zampini } 79566e683305SStefano Zampini ierr = VecCreate(PetscObjectComm((PetscObject)pc),&pcbddc->coarse_vec);CHKERRQ(ierr); 79576e683305SStefano Zampini ierr = VecSetSizes(pcbddc->coarse_vec,lrows,PETSC_DECIDE);CHKERRQ(ierr); 79586e683305SStefano Zampini ierr = VecSetType(pcbddc->coarse_vec,VECSTANDARD);CHKERRQ(ierr); 79596e683305SStefano Zampini ierr = VecScatterDestroy(&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 79606e683305SStefano Zampini ierr = VecScatterCreate(pcbddc->vec1_P,NULL,pcbddc->coarse_vec,coarse_is,&pcbddc->coarse_loc_to_glob);CHKERRQ(ierr); 79616e683305SStefano Zampini } 79626e683305SStefano Zampini ierr = ISDestroy(&coarse_is);CHKERRQ(ierr); 7963c8587f34SStefano Zampini 7964f9eb5b7dSStefano Zampini /* set defaults for coarse KSP and PC */ 7965f9eb5b7dSStefano Zampini if (multilevel_allowed) { 7966f9eb5b7dSStefano Zampini coarse_ksp_type = KSPRICHARDSON; 7967f9eb5b7dSStefano Zampini coarse_pc_type = PCBDDC; 7968f9eb5b7dSStefano Zampini } else { 7969f9eb5b7dSStefano Zampini coarse_ksp_type = KSPPREONLY; 7970f9eb5b7dSStefano Zampini coarse_pc_type = PCREDUNDANT; 7971c8587f34SStefano Zampini } 7972c8587f34SStefano Zampini 79736e683305SStefano Zampini /* print some info if requested */ 79746e683305SStefano Zampini if (pcbddc->dbg_flag) { 79756e683305SStefano Zampini if (!multilevel_allowed) { 79766e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 79776e683305SStefano Zampini if (multilevel_requested) { 79786e683305SStefano 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); 79796e683305SStefano Zampini } else if (pcbddc->max_levels) { 79806e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Maximum number of requested levels reached (%d)\n",pcbddc->max_levels);CHKERRQ(ierr); 79816e683305SStefano Zampini } 79826e683305SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 79836e683305SStefano Zampini } 79846e683305SStefano Zampini } 79856e683305SStefano Zampini 79861e0482f5SStefano Zampini /* communicate coarse discrete gradient */ 79871e0482f5SStefano Zampini coarseG = NULL; 79881e0482f5SStefano Zampini if (pcbddc->nedcG && multilevel_allowed) { 79891e0482f5SStefano Zampini MPI_Comm ccomm; 79901e0482f5SStefano Zampini if (coarse_mat) { 79911e0482f5SStefano Zampini ccomm = PetscObjectComm((PetscObject)coarse_mat); 79921e0482f5SStefano Zampini } else { 79931e0482f5SStefano Zampini ccomm = MPI_COMM_NULL; 79941e0482f5SStefano Zampini } 79951e0482f5SStefano Zampini ierr = MatMPIAIJRestrict(pcbddc->nedcG,ccomm,&coarseG);CHKERRQ(ierr); 79961e0482f5SStefano Zampini } 79971e0482f5SStefano Zampini 7998f9eb5b7dSStefano Zampini /* create the coarse KSP object only once with defaults */ 799957de7509SStefano Zampini if (coarse_mat) { 80007274672aSStefano Zampini PetscBool isredundant,isnn,isbddc; 80016a1308c2SStefano Zampini PetscViewer dbg_viewer = NULL; 80027274672aSStefano Zampini 80036e683305SStefano Zampini if (pcbddc->dbg_flag) { 800457de7509SStefano Zampini dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)coarse_mat)); 80056e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 80066e683305SStefano Zampini } 8007f9eb5b7dSStefano Zampini if (!pcbddc->coarse_ksp) { 8008312be037SStefano Zampini char prefix[256],str_level[16]; 8009e604994aSStefano Zampini size_t len; 80101e0482f5SStefano Zampini 801157de7509SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)coarse_mat),&pcbddc->coarse_ksp);CHKERRQ(ierr); 8012422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 8013c8587f34SStefano Zampini ierr = PetscObjectIncrementTabLevel((PetscObject)pcbddc->coarse_ksp,(PetscObject)pc,1);CHKERRQ(ierr); 8014f9eb5b7dSStefano Zampini ierr = KSPSetTolerances(pcbddc->coarse_ksp,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT,1);CHKERRQ(ierr); 801557de7509SStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8016c8587f34SStefano Zampini ierr = KSPSetType(pcbddc->coarse_ksp,coarse_ksp_type);CHKERRQ(ierr); 80176e683305SStefano Zampini ierr = KSPSetNormType(pcbddc->coarse_ksp,KSP_NORM_NONE);CHKERRQ(ierr); 8018c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 80191e0482f5SStefano Zampini /* TODO is this logic correct? should check for coarse_mat type */ 8020c8587f34SStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8021e604994aSStefano Zampini /* prefix */ 8022e604994aSStefano Zampini ierr = PetscStrcpy(prefix,"");CHKERRQ(ierr); 8023e604994aSStefano Zampini ierr = PetscStrcpy(str_level,"");CHKERRQ(ierr); 8024e604994aSStefano Zampini if (!pcbddc->current_level) { 8025e604994aSStefano Zampini ierr = PetscStrcpy(prefix,((PetscObject)pc)->prefix);CHKERRQ(ierr); 8026e604994aSStefano Zampini ierr = PetscStrcat(prefix,"pc_bddc_coarse_");CHKERRQ(ierr); 8027c8587f34SStefano Zampini } else { 8028e604994aSStefano Zampini ierr = PetscStrlen(((PetscObject)pc)->prefix,&len);CHKERRQ(ierr); 8029312be037SStefano Zampini if (pcbddc->current_level>1) len -= 3; /* remove "lX_" with X level number */ 8030312be037SStefano Zampini if (pcbddc->current_level>10) len -= 1; /* remove another char from level number */ 803134d6797cSStefano Zampini ierr = PetscStrncpy(prefix,((PetscObject)pc)->prefix,len+1);CHKERRQ(ierr); 803235529e7bSStefano Zampini ierr = PetscSNPrintf(str_level,sizeof(str_level),"l%d_",(int)(pcbddc->current_level));CHKERRQ(ierr); 8033e604994aSStefano Zampini ierr = PetscStrcat(prefix,str_level);CHKERRQ(ierr); 8034e604994aSStefano Zampini } 8035e604994aSStefano Zampini ierr = KSPSetOptionsPrefix(pcbddc->coarse_ksp,prefix);CHKERRQ(ierr); 80363e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 80373e3c6dadSStefano Zampini ierr = PCBDDCSetLevel(pc_temp,pcbddc->current_level+1);CHKERRQ(ierr); 80383e3c6dadSStefano Zampini ierr = PCBDDCSetCoarseningRatio(pc_temp,pcbddc->coarsening_ratio);CHKERRQ(ierr); 80393e3c6dadSStefano Zampini ierr = PCBDDCSetLevels(pc_temp,pcbddc->max_levels);CHKERRQ(ierr); 8040f9eb5b7dSStefano Zampini /* allow user customization */ 8041f9eb5b7dSStefano Zampini ierr = KSPSetFromOptions(pcbddc->coarse_ksp);CHKERRQ(ierr); 80423e3c6dadSStefano Zampini } 80433e3c6dadSStefano Zampini /* propagate BDDC info to the next level (these are dummy calls if pc_temp is not of type PCBDDC) */ 804451bea450SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&pc_temp);CHKERRQ(ierr); 80453e3c6dadSStefano Zampini if (nisdofs) { 80463e3c6dadSStefano Zampini ierr = PCBDDCSetDofsSplitting(pc_temp,nisdofs,isarray);CHKERRQ(ierr); 80473e3c6dadSStefano Zampini for (i=0;i<nisdofs;i++) { 80483e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[i]);CHKERRQ(ierr); 80493e3c6dadSStefano Zampini } 80503e3c6dadSStefano Zampini } 80513e3c6dadSStefano Zampini if (nisneu) { 80523e3c6dadSStefano Zampini ierr = PCBDDCSetNeumannBoundaries(pc_temp,isarray[nisdofs]);CHKERRQ(ierr); 80533e3c6dadSStefano Zampini ierr = ISDestroy(&isarray[nisdofs]);CHKERRQ(ierr); 8054312be037SStefano Zampini } 805530368db7SStefano Zampini if (nisvert) { 805630368db7SStefano Zampini ierr = PCBDDCSetPrimalVerticesIS(pc_temp,isarray[nis-1]);CHKERRQ(ierr); 805730368db7SStefano Zampini ierr = ISDestroy(&isarray[nis-1]);CHKERRQ(ierr); 805830368db7SStefano Zampini } 80591e0482f5SStefano Zampini if (coarseG) { 80601e0482f5SStefano Zampini ierr = PCBDDCSetDiscreteGradient(pc_temp,coarseG,1,nedcfield,PETSC_FALSE,PETSC_TRUE);CHKERRQ(ierr); 80611e0482f5SStefano Zampini } 8062f9eb5b7dSStefano Zampini 8063f9eb5b7dSStefano Zampini /* get some info after set from options */ 8064f9eb5b7dSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 8065b76f3995Sstefano_zampini /* multilevel can only be requested via -pc_bddc_levels or PCBDDCSetLevels */ 8066b76f3995Sstefano_zampini if (isbddc && !multilevel_allowed) { 8067f9eb5b7dSStefano Zampini ierr = PCSetType(pc_temp,coarse_pc_type);CHKERRQ(ierr); 8068f9eb5b7dSStefano Zampini isbddc = PETSC_FALSE; 8069f9eb5b7dSStefano Zampini } 8070b76f3995Sstefano_zampini /* multilevel cannot be done with coarse PCs different from BDDC or NN */ 80717274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCNN,&isnn);CHKERRQ(ierr); 80727274672aSStefano Zampini if (multilevel_requested && multilevel_allowed && !isbddc && !isnn) { 8073b76f3995Sstefano_zampini ierr = PCSetType(pc_temp,PCBDDC);CHKERRQ(ierr); 8074b76f3995Sstefano_zampini isbddc = PETSC_TRUE; 8075b76f3995Sstefano_zampini } 80767274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCREDUNDANT,&isredundant);CHKERRQ(ierr); 80774f3a063dSStefano Zampini if (isredundant) { 80784f3a063dSStefano Zampini KSP inner_ksp; 80794f3a063dSStefano Zampini PC inner_pc; 80809326c5c6Sstefano_zampini 80814f3a063dSStefano Zampini ierr = PCRedundantGetKSP(pc_temp,&inner_ksp);CHKERRQ(ierr); 80824f3a063dSStefano Zampini ierr = KSPGetPC(inner_ksp,&inner_pc);CHKERRQ(ierr); 80834f3a063dSStefano Zampini } 8084f9eb5b7dSStefano Zampini 808557de7509SStefano Zampini /* parameters which miss an API */ 80867274672aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pc_temp,PCBDDC,&isbddc);CHKERRQ(ierr); 808757de7509SStefano Zampini if (isbddc) { 8088720d30f9SStefano Zampini PC_BDDC* pcbddc_coarse = (PC_BDDC*)pc_temp->data; 80897274672aSStefano Zampini 8090720d30f9SStefano Zampini pcbddc_coarse->detect_disconnected = PETSC_TRUE; 809157de7509SStefano Zampini pcbddc_coarse->coarse_eqs_per_proc = pcbddc->coarse_eqs_per_proc; 809227b6a85dSStefano Zampini pcbddc_coarse->benign_saddle_point = pcbddc->benign_have_null; 809327b6a85dSStefano Zampini if (pcbddc_coarse->benign_saddle_point) { 8094a198735bSStefano Zampini Mat coarsedivudotp_is; 8095a198735bSStefano Zampini ISLocalToGlobalMapping l2gmap,rl2g,cl2g; 8096a198735bSStefano Zampini IS row,col; 8097a198735bSStefano Zampini const PetscInt *gidxs; 8098a198735bSStefano Zampini PetscInt n,st,M,N; 8099a198735bSStefano Zampini 8100a198735bSStefano Zampini ierr = MatGetSize(coarsedivudotp,&n,NULL);CHKERRQ(ierr); 8101a198735bSStefano Zampini ierr = MPI_Scan(&n,&st,1,MPIU_INT,MPI_SUM,PetscObjectComm((PetscObject)coarse_mat));CHKERRQ(ierr); 8102a198735bSStefano Zampini st = st-n; 8103a198735bSStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)coarse_mat),1,st,1,&row);CHKERRQ(ierr); 8104a198735bSStefano Zampini ierr = MatGetLocalToGlobalMapping(coarse_mat,&l2gmap,NULL);CHKERRQ(ierr); 8105a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetSize(l2gmap,&n);CHKERRQ(ierr); 8106a198735bSStefano Zampini ierr = ISLocalToGlobalMappingGetIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8107a198735bSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)coarse_mat),n,gidxs,PETSC_COPY_VALUES,&col);CHKERRQ(ierr); 8108a198735bSStefano Zampini ierr = ISLocalToGlobalMappingRestoreIndices(l2gmap,&gidxs);CHKERRQ(ierr); 8109a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(row,&rl2g);CHKERRQ(ierr); 8110a198735bSStefano Zampini ierr = ISLocalToGlobalMappingCreateIS(col,&cl2g);CHKERRQ(ierr); 8111a198735bSStefano Zampini ierr = ISGetSize(row,&M);CHKERRQ(ierr); 8112a198735bSStefano Zampini ierr = MatGetSize(coarse_mat,&N,NULL);CHKERRQ(ierr); 8113a198735bSStefano Zampini ierr = ISDestroy(&row);CHKERRQ(ierr); 8114a198735bSStefano Zampini ierr = ISDestroy(&col);CHKERRQ(ierr); 8115a198735bSStefano Zampini ierr = MatCreate(PetscObjectComm((PetscObject)coarse_mat),&coarsedivudotp_is);CHKERRQ(ierr); 8116a198735bSStefano Zampini ierr = MatSetType(coarsedivudotp_is,MATIS);CHKERRQ(ierr); 8117a198735bSStefano Zampini ierr = MatSetSizes(coarsedivudotp_is,PETSC_DECIDE,PETSC_DECIDE,M,N);CHKERRQ(ierr); 8118a198735bSStefano Zampini ierr = MatSetLocalToGlobalMapping(coarsedivudotp_is,rl2g,cl2g);CHKERRQ(ierr); 8119a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&rl2g);CHKERRQ(ierr); 8120a198735bSStefano Zampini ierr = ISLocalToGlobalMappingDestroy(&cl2g);CHKERRQ(ierr); 8121a198735bSStefano Zampini ierr = MatISSetLocalMat(coarsedivudotp_is,coarsedivudotp);CHKERRQ(ierr); 8122a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 81238ae0ca82SStefano Zampini ierr = PCBDDCSetDivergenceMat(pc_temp,coarsedivudotp_is,PETSC_FALSE,NULL);CHKERRQ(ierr); 8124a198735bSStefano Zampini ierr = MatDestroy(&coarsedivudotp_is);CHKERRQ(ierr); 8125720d30f9SStefano Zampini pcbddc_coarse->adaptive_userdefined = PETSC_TRUE; 8126bd2a564bSStefano Zampini if (pcbddc->adaptive_threshold[0] == 0.0) pcbddc_coarse->deluxe_zerorows = PETSC_TRUE; 8127720d30f9SStefano Zampini } 8128d4d8cf7bSStefano Zampini } 81299881197aSStefano Zampini 81303301b35fSStefano Zampini /* propagate symmetry info of coarse matrix */ 81315a16e3a0SStefano Zampini ierr = MatSetOption(coarse_mat,MAT_STRUCTURALLY_SYMMETRIC,PETSC_TRUE);CHKERRQ(ierr); 81323301b35fSStefano Zampini if (pc->pmat->symmetric_set) { 81333301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SYMMETRIC,pc->pmat->symmetric);CHKERRQ(ierr); 81343301b35fSStefano Zampini } 81353301b35fSStefano Zampini if (pc->pmat->hermitian_set) { 81363301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_HERMITIAN,pc->pmat->hermitian);CHKERRQ(ierr); 81373301b35fSStefano Zampini } 81383301b35fSStefano Zampini if (pc->pmat->spd_set) { 81393301b35fSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,pc->pmat->spd);CHKERRQ(ierr); 81403301b35fSStefano Zampini } 814127b6a85dSStefano Zampini if (pcbddc->benign_saddle_point && !pcbddc->benign_have_null) { 814227b6a85dSStefano Zampini ierr = MatSetOption(coarse_mat,MAT_SPD,PETSC_TRUE);CHKERRQ(ierr); 814327b6a85dSStefano Zampini } 81446e683305SStefano Zampini /* set operators */ 81455f76c7aeSStefano Zampini ierr = KSPSetOperators(pcbddc->coarse_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 81466e683305SStefano Zampini if (pcbddc->dbg_flag) { 81476e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*pcbddc->current_level);CHKERRQ(ierr); 81486e683305SStefano Zampini } 81496e683305SStefano Zampini } 81501e0482f5SStefano Zampini ierr = MatDestroy(&coarseG);CHKERRQ(ierr); 81516e683305SStefano Zampini ierr = PetscFree(isarray);CHKERRQ(ierr); 8152b1ecc7b1SStefano Zampini #if 0 8153b9b85e73SStefano Zampini { 8154b9b85e73SStefano Zampini PetscViewer viewer; 8155b9b85e73SStefano Zampini char filename[256]; 8156b1ecc7b1SStefano Zampini sprintf(filename,"coarse_mat_level%d.m",pcbddc->current_level); 8157b1ecc7b1SStefano Zampini ierr = PetscViewerASCIIOpen(PetscObjectComm((PetscObject)coarse_mat),filename,&viewer);CHKERRQ(ierr); 81586a9046bcSBarry Smith ierr = PetscViewerPushFormat(viewer,PETSC_VIEWER_ASCII_MATLAB);CHKERRQ(ierr); 8159b9b85e73SStefano Zampini ierr = MatView(coarse_mat,viewer);CHKERRQ(ierr); 8160f159cad9SBarry Smith ierr = PetscViewerPopFormat(viewer);CHKERRQ(ierr); 8161b9b85e73SStefano Zampini ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 8162b9b85e73SStefano Zampini } 8163b9b85e73SStefano Zampini #endif 8164f9eb5b7dSStefano Zampini 816598a51de6SStefano Zampini if (pcbddc->coarse_ksp) { 816698a51de6SStefano Zampini Vec crhs,csol; 816704708bb6SStefano Zampini 8168f347579bSStefano Zampini ierr = KSPGetSolution(pcbddc->coarse_ksp,&csol);CHKERRQ(ierr); 8169f347579bSStefano Zampini ierr = KSPGetRhs(pcbddc->coarse_ksp,&crhs);CHKERRQ(ierr); 8170f347579bSStefano Zampini if (!csol) { 81712a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,&((pcbddc->coarse_ksp)->vec_sol),NULL);CHKERRQ(ierr); 8172f9eb5b7dSStefano Zampini } 8173f347579bSStefano Zampini if (!crhs) { 81742a7a6963SBarry Smith ierr = MatCreateVecs(coarse_mat,NULL,&((pcbddc->coarse_ksp)->vec_rhs));CHKERRQ(ierr); 8175f347579bSStefano Zampini } 8176b0f5fe93SStefano Zampini } 81771ae86dd6SStefano Zampini ierr = MatDestroy(&coarsedivudotp);CHKERRQ(ierr); 8178b0f5fe93SStefano Zampini 8179b0f5fe93SStefano Zampini /* compute null space for coarse solver if the benign trick has been requested */ 8180b0f5fe93SStefano Zampini if (pcbddc->benign_null) { 8181b0f5fe93SStefano Zampini 8182b0f5fe93SStefano Zampini ierr = VecSet(pcbddc->vec1_P,0.);CHKERRQ(ierr); 81834f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 81844f1b2e48SStefano Zampini ierr = VecSetValue(pcbddc->vec1_P,pcbddc->local_primal_size-pcbddc->benign_n+i,1.0,INSERT_VALUES);CHKERRQ(ierr); 81854f1b2e48SStefano Zampini } 8186b0f5fe93SStefano Zampini ierr = VecAssemblyBegin(pcbddc->vec1_P);CHKERRQ(ierr); 8187b0f5fe93SStefano Zampini ierr = VecAssemblyEnd(pcbddc->vec1_P);CHKERRQ(ierr); 8188b0f5fe93SStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8189b0f5fe93SStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8190b0f5fe93SStefano Zampini if (coarse_mat) { 8191b0f5fe93SStefano Zampini Vec nullv; 8192b0f5fe93SStefano Zampini PetscScalar *array,*array2; 8193b0f5fe93SStefano Zampini PetscInt nl; 8194b0f5fe93SStefano Zampini 8195b0f5fe93SStefano Zampini ierr = MatCreateVecs(coarse_mat,&nullv,NULL);CHKERRQ(ierr); 8196b0f5fe93SStefano Zampini ierr = VecGetLocalSize(nullv,&nl);CHKERRQ(ierr); 8197b0f5fe93SStefano Zampini ierr = VecGetArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8198b0f5fe93SStefano Zampini ierr = VecGetArray(nullv,&array2);CHKERRQ(ierr); 8199b0f5fe93SStefano Zampini ierr = PetscMemcpy(array2,array,nl*sizeof(*array));CHKERRQ(ierr); 8200b0f5fe93SStefano Zampini ierr = VecRestoreArray(nullv,&array2);CHKERRQ(ierr); 8201b0f5fe93SStefano Zampini ierr = VecRestoreArrayRead(pcbddc->coarse_vec,(const PetscScalar**)&array);CHKERRQ(ierr); 8202b0f5fe93SStefano Zampini ierr = VecNormalize(nullv,NULL);CHKERRQ(ierr); 8203b0f5fe93SStefano Zampini ierr = MatNullSpaceCreate(PetscObjectComm((PetscObject)coarse_mat),PETSC_FALSE,1,&nullv,&CoarseNullSpace);CHKERRQ(ierr); 8204b0f5fe93SStefano Zampini ierr = VecDestroy(&nullv);CHKERRQ(ierr); 8205b0f5fe93SStefano Zampini } 8206b0f5fe93SStefano Zampini } 8207b0f5fe93SStefano Zampini 8208b0f5fe93SStefano Zampini if (pcbddc->coarse_ksp) { 8209b0f5fe93SStefano Zampini PetscBool ispreonly; 8210b0f5fe93SStefano Zampini 8211b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8212b0f5fe93SStefano Zampini PetscBool isnull; 8213b0f5fe93SStefano Zampini ierr = MatNullSpaceTest(CoarseNullSpace,coarse_mat,&isnull);CHKERRQ(ierr); 8214bef83e63SStefano Zampini if (isnull) { 8215b0f5fe93SStefano Zampini ierr = MatSetNullSpace(coarse_mat,CoarseNullSpace);CHKERRQ(ierr); 8216b0f5fe93SStefano Zampini } 8217bef83e63SStefano Zampini /* TODO: add local nullspaces (if any) */ 8218b0f5fe93SStefano Zampini } 8219b0f5fe93SStefano Zampini /* setup coarse ksp */ 8220b0f5fe93SStefano Zampini ierr = KSPSetUp(pcbddc->coarse_ksp);CHKERRQ(ierr); 8221cbcc2c2aSStefano Zampini /* Check coarse problem if in debug mode or if solving with an iterative method */ 8222cbcc2c2aSStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->coarse_ksp,KSPPREONLY,&ispreonly);CHKERRQ(ierr); 82236e683305SStefano Zampini if (pcbddc->dbg_flag || (!ispreonly && pcbddc->use_coarse_estimates) ) { 8224c8587f34SStefano Zampini KSP check_ksp; 82252b510759SStefano Zampini KSPType check_ksp_type; 8226c8587f34SStefano Zampini PC check_pc; 82276e683305SStefano Zampini Vec check_vec,coarse_vec; 82286a1308c2SStefano Zampini PetscReal abs_infty_error,infty_error,lambda_min=1.0,lambda_max=1.0; 82292b510759SStefano Zampini PetscInt its; 82306e683305SStefano Zampini PetscBool compute_eigs; 82316e683305SStefano Zampini PetscReal *eigs_r,*eigs_c; 82326e683305SStefano Zampini PetscInt neigs; 82338e185a42SStefano Zampini const char *prefix; 8234c8587f34SStefano Zampini 82352b510759SStefano Zampini /* Create ksp object suitable for estimation of extreme eigenvalues */ 82366e683305SStefano Zampini ierr = KSPCreate(PetscObjectComm((PetscObject)pcbddc->coarse_ksp),&check_ksp);CHKERRQ(ierr); 8237422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(pcbddc->coarse_ksp,pc->erroriffailure);CHKERRQ(ierr); 823823ee1639SBarry Smith ierr = KSPSetOperators(check_ksp,coarse_mat,coarse_mat);CHKERRQ(ierr); 8239f4ddd8eeSStefano Zampini ierr = KSPSetTolerances(check_ksp,1.e-12,1.e-12,PETSC_DEFAULT,pcbddc->coarse_size);CHKERRQ(ierr); 8240e4d548c7SStefano Zampini /* prevent from setup unneeded object */ 8241e4d548c7SStefano Zampini ierr = KSPGetPC(check_ksp,&check_pc);CHKERRQ(ierr); 8242e4d548c7SStefano Zampini ierr = PCSetType(check_pc,PCNONE);CHKERRQ(ierr); 82432b510759SStefano Zampini if (ispreonly) { 82442b510759SStefano Zampini check_ksp_type = KSPPREONLY; 82456e683305SStefano Zampini compute_eigs = PETSC_FALSE; 82462b510759SStefano Zampini } else { 8247cbcc2c2aSStefano Zampini check_ksp_type = KSPGMRES; 82486e683305SStefano Zampini compute_eigs = PETSC_TRUE; 8249c8587f34SStefano Zampini } 8250c8587f34SStefano Zampini ierr = KSPSetType(check_ksp,check_ksp_type);CHKERRQ(ierr); 82516e683305SStefano Zampini ierr = KSPSetComputeSingularValues(check_ksp,compute_eigs);CHKERRQ(ierr); 82526e683305SStefano Zampini ierr = KSPSetComputeEigenvalues(check_ksp,compute_eigs);CHKERRQ(ierr); 82536e683305SStefano Zampini ierr = KSPGMRESSetRestart(check_ksp,pcbddc->coarse_size+1);CHKERRQ(ierr); 8254a7dc3881SStefano Zampini ierr = KSPGetOptionsPrefix(pcbddc->coarse_ksp,&prefix);CHKERRQ(ierr); 8255a7dc3881SStefano Zampini ierr = KSPSetOptionsPrefix(check_ksp,prefix);CHKERRQ(ierr); 8256a7dc3881SStefano Zampini ierr = KSPAppendOptionsPrefix(check_ksp,"check_");CHKERRQ(ierr); 8257a7dc3881SStefano Zampini ierr = KSPSetFromOptions(check_ksp);CHKERRQ(ierr); 8258c8587f34SStefano Zampini ierr = KSPSetUp(check_ksp);CHKERRQ(ierr); 8259c8587f34SStefano Zampini ierr = KSPGetPC(pcbddc->coarse_ksp,&check_pc);CHKERRQ(ierr); 8260c8587f34SStefano Zampini ierr = KSPSetPC(check_ksp,check_pc);CHKERRQ(ierr); 8261c8587f34SStefano Zampini /* create random vec */ 82622701bc32SStefano Zampini ierr = MatCreateVecs(coarse_mat,&coarse_vec,&check_vec);CHKERRQ(ierr); 8263c8587f34SStefano Zampini ierr = VecSetRandom(check_vec,NULL);CHKERRQ(ierr); 82646e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 8265c8587f34SStefano Zampini /* solve coarse problem */ 82666e683305SStefano Zampini ierr = KSPSolve(check_ksp,coarse_vec,coarse_vec);CHKERRQ(ierr); 8267cbcc2c2aSStefano Zampini /* set eigenvalue estimation if preonly has not been requested */ 82686e683305SStefano Zampini if (compute_eigs) { 8269854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_r);CHKERRQ(ierr); 8270854ce69bSBarry Smith ierr = PetscMalloc1(pcbddc->coarse_size+1,&eigs_c);CHKERRQ(ierr); 82716e683305SStefano Zampini ierr = KSPComputeEigenvalues(check_ksp,pcbddc->coarse_size+1,eigs_r,eigs_c,&neigs);CHKERRQ(ierr); 82721ae86dd6SStefano Zampini if (neigs) { 82736e683305SStefano Zampini lambda_max = eigs_r[neigs-1]; 82746e683305SStefano Zampini lambda_min = eigs_r[0]; 82756e683305SStefano Zampini if (pcbddc->use_coarse_estimates) { 82762701bc32SStefano Zampini if (lambda_max>=lambda_min) { /* using PETSC_SMALL since lambda_max == lambda_min is not allowed by KSPChebyshevSetEigenvalues */ 82772701bc32SStefano Zampini ierr = KSPChebyshevSetEigenvalues(pcbddc->coarse_ksp,lambda_max+PETSC_SMALL,lambda_min);CHKERRQ(ierr); 8278cbcc2c2aSStefano Zampini ierr = KSPRichardsonSetScale(pcbddc->coarse_ksp,2.0/(lambda_max+lambda_min));CHKERRQ(ierr); 8279cbcc2c2aSStefano Zampini } 8280c8587f34SStefano Zampini } 8281c8587f34SStefano Zampini } 82821ae86dd6SStefano Zampini } 8283cbcc2c2aSStefano Zampini 8284c8587f34SStefano Zampini /* check coarse problem residual error */ 82856e683305SStefano Zampini if (pcbddc->dbg_flag) { 82866e683305SStefano Zampini PetscViewer dbg_viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)pcbddc->coarse_ksp)); 82876e683305SStefano Zampini ierr = PetscViewerASCIIAddTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 82886e683305SStefano Zampini ierr = VecAXPY(check_vec,-1.0,coarse_vec);CHKERRQ(ierr); 8289c8587f34SStefano Zampini ierr = VecNorm(check_vec,NORM_INFINITY,&infty_error);CHKERRQ(ierr); 82906e683305SStefano Zampini ierr = MatMult(coarse_mat,check_vec,coarse_vec);CHKERRQ(ierr); 82916e683305SStefano Zampini ierr = VecNorm(coarse_vec,NORM_INFINITY,&abs_infty_error);CHKERRQ(ierr); 8292779c1cceSStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem details (use estimates %d)\n",pcbddc->use_coarse_estimates);CHKERRQ(ierr); 82936e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(pcbddc->coarse_ksp),dbg_viewer);CHKERRQ(ierr); 82946e683305SStefano Zampini ierr = PetscObjectPrintClassNamePrefixType((PetscObject)(check_pc),dbg_viewer);CHKERRQ(ierr); 82956e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem exact infty_error : %1.6e\n",infty_error);CHKERRQ(ierr); 82966e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem residual infty_error: %1.6e\n",abs_infty_error);CHKERRQ(ierr); 8297b0f5fe93SStefano Zampini if (CoarseNullSpace) { 8298b0f5fe93SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"Coarse problem is singular\n");CHKERRQ(ierr); 8299b0f5fe93SStefano Zampini } 83006e683305SStefano Zampini if (compute_eigs) { 83016e683305SStefano Zampini PetscReal lambda_max_s,lambda_min_s; 8302b03ebc13SStefano Zampini KSPConvergedReason reason; 8303deec49d1SStefano Zampini ierr = KSPGetType(check_ksp,&check_ksp_type);CHKERRQ(ierr); 8304c8587f34SStefano Zampini ierr = KSPGetIterationNumber(check_ksp,&its);CHKERRQ(ierr); 8305b03ebc13SStefano Zampini ierr = KSPGetConvergedReason(check_ksp,&reason);CHKERRQ(ierr); 83066e683305SStefano Zampini ierr = KSPComputeExtremeSingularValues(check_ksp,&lambda_max_s,&lambda_min_s);CHKERRQ(ierr); 8307b03ebc13SStefano 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); 83086e683305SStefano Zampini for (i=0;i<neigs;i++) { 83096e683305SStefano Zampini ierr = PetscViewerASCIIPrintf(dbg_viewer,"%1.6e %1.6ei\n",eigs_r[i],eigs_c[i]);CHKERRQ(ierr); 8310c8587f34SStefano Zampini } 83116e683305SStefano Zampini } 83126e683305SStefano Zampini ierr = PetscViewerFlush(dbg_viewer);CHKERRQ(ierr); 83136e683305SStefano Zampini ierr = PetscViewerASCIISubtractTab(dbg_viewer,2*(pcbddc->current_level+1));CHKERRQ(ierr); 83146e683305SStefano Zampini } 8315e4d548c7SStefano Zampini ierr = VecDestroy(&check_vec);CHKERRQ(ierr); 83162701bc32SStefano Zampini ierr = VecDestroy(&coarse_vec);CHKERRQ(ierr); 8317c8587f34SStefano Zampini ierr = KSPDestroy(&check_ksp);CHKERRQ(ierr); 83186e683305SStefano Zampini if (compute_eigs) { 83196e683305SStefano Zampini ierr = PetscFree(eigs_r);CHKERRQ(ierr); 83206e683305SStefano Zampini ierr = PetscFree(eigs_c);CHKERRQ(ierr); 8321c8587f34SStefano Zampini } 83226e683305SStefano Zampini } 83236e683305SStefano Zampini } 8324bef83e63SStefano Zampini ierr = MatNullSpaceDestroy(&CoarseNullSpace);CHKERRQ(ierr); 8325cbcc2c2aSStefano Zampini /* print additional info */ 8326cbcc2c2aSStefano Zampini if (pcbddc->dbg_flag) { 83276e683305SStefano Zampini /* waits until all processes reaches this point */ 83286e683305SStefano Zampini ierr = PetscBarrier((PetscObject)pc);CHKERRQ(ierr); 8329cbcc2c2aSStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Coarse solver setup completed at level %d\n",pcbddc->current_level);CHKERRQ(ierr); 8330cbcc2c2aSStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8331cbcc2c2aSStefano Zampini } 8332cbcc2c2aSStefano Zampini 83332b510759SStefano Zampini /* free memory */ 8334fdc635d7SStefano Zampini ierr = MatDestroy(&coarse_mat);CHKERRQ(ierr); 8335c8587f34SStefano Zampini PetscFunctionReturn(0); 8336c8587f34SStefano Zampini } 8337674ae819SStefano Zampini 8338f34684f1SStefano Zampini PetscErrorCode PCBDDCComputePrimalNumbering(PC pc,PetscInt* coarse_size_n,PetscInt** local_primal_indices_n) 8339f34684f1SStefano Zampini { 8340f34684f1SStefano Zampini PC_BDDC* pcbddc = (PC_BDDC*)pc->data; 8341f34684f1SStefano Zampini PC_IS* pcis = (PC_IS*)pc->data; 8342f34684f1SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 8343dc456d91SStefano Zampini IS subset,subset_mult,subset_n; 8344dc456d91SStefano Zampini PetscInt local_size,coarse_size=0; 834573be2a3aSStefano Zampini PetscInt *local_primal_indices=NULL; 8346dc456d91SStefano Zampini const PetscInt *t_local_primal_indices; 8347f34684f1SStefano Zampini PetscErrorCode ierr; 8348f34684f1SStefano Zampini 8349f34684f1SStefano Zampini PetscFunctionBegin; 8350f34684f1SStefano Zampini /* Compute global number of coarse dofs */ 83516c4ed002SBarry Smith if (pcbddc->local_primal_size && !pcbddc->local_primal_ref_node) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_PLIB,"BDDC ConstraintsSetUp should be called first"); 8352dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_node,PETSC_COPY_VALUES,&subset_n);CHKERRQ(ierr); 83533bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApplyIS(pcis->mapping,subset_n,&subset);CHKERRQ(ierr); 8354dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8355dc456d91SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)(pc->pmat)),pcbddc->local_primal_size_cc,pcbddc->local_primal_ref_mult,PETSC_COPY_VALUES,&subset_mult);CHKERRQ(ierr); 83566583bcc1SStefano Zampini ierr = ISRenumber(subset,subset_mult,&coarse_size,&subset_n);CHKERRQ(ierr); 8357dc456d91SStefano Zampini ierr = ISDestroy(&subset);CHKERRQ(ierr); 8358dc456d91SStefano Zampini ierr = ISDestroy(&subset_mult);CHKERRQ(ierr); 8359dc456d91SStefano Zampini ierr = ISGetLocalSize(subset_n,&local_size);CHKERRQ(ierr); 83606c4ed002SBarry 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); 8361dc456d91SStefano Zampini ierr = PetscMalloc1(local_size,&local_primal_indices);CHKERRQ(ierr); 8362dc456d91SStefano Zampini ierr = ISGetIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8363dc456d91SStefano Zampini ierr = PetscMemcpy(local_primal_indices,t_local_primal_indices,local_size*sizeof(PetscInt));CHKERRQ(ierr); 8364dc456d91SStefano Zampini ierr = ISRestoreIndices(subset_n,&t_local_primal_indices);CHKERRQ(ierr); 8365dc456d91SStefano Zampini ierr = ISDestroy(&subset_n);CHKERRQ(ierr); 8366f34684f1SStefano Zampini 8367f34684f1SStefano Zampini /* check numbering */ 8368f34684f1SStefano Zampini if (pcbddc->dbg_flag) { 8369019a44ceSStefano Zampini PetscScalar coarsesum,*array,*array2; 8370dc456d91SStefano Zampini PetscInt i; 8371b9b85e73SStefano Zampini PetscBool set_error = PETSC_FALSE,set_error_reduced = PETSC_FALSE; 8372f34684f1SStefano Zampini 8373f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8374f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"--------------------------------------------------\n");CHKERRQ(ierr); 8375f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Check coarse indices\n");CHKERRQ(ierr); 83761575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8377019a44ceSStefano Zampini /* counter */ 8378019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8379019a44ceSStefano Zampini ierr = VecSet(pcis->vec1_N,1.0);CHKERRQ(ierr); 8380019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8381019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8382019a44ceSStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8383019a44ceSStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec2_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8384f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_N,0.0);CHKERRQ(ierr); 8385f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 8386727cdba6SStefano Zampini ierr = VecSetValue(pcis->vec1_N,pcbddc->primal_indices_local_idxs[i],1.0,INSERT_VALUES);CHKERRQ(ierr); 8387f34684f1SStefano Zampini } 8388f34684f1SStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8389f34684f1SStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8390f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8391e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8392e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8393e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8394e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_global,pcis->vec1_N,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8395f34684f1SStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8396019a44ceSStefano Zampini ierr = VecGetArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8397f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8398019a44ceSStefano Zampini if (array[i] != 0.0 && array[i] != array2[i]) { 83992c66d082SStefano Zampini PetscInt owned = (PetscInt)PetscRealPart(array[i]),gi; 840075c01103SStefano Zampini PetscInt neigh = (PetscInt)PetscRealPart(array2[i]); 8401b9b85e73SStefano Zampini set_error = PETSC_TRUE; 84022c66d082SStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,1,&i,&gi);CHKERRQ(ierr); 84032c66d082SStefano 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); 8404f34684f1SStefano Zampini } 8405f34684f1SStefano Zampini } 8406019a44ceSStefano Zampini ierr = VecRestoreArray(pcis->vec2_N,&array2);CHKERRQ(ierr); 8407b2566f29SBarry Smith ierr = MPIU_Allreduce(&set_error,&set_error_reduced,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 8408f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8409f34684f1SStefano Zampini for (i=0;i<pcis->n;i++) { 8410f34684f1SStefano Zampini if (PetscRealPart(array[i]) > 0.0) array[i] = 1.0/PetscRealPart(array[i]); 8411f34684f1SStefano Zampini } 8412f34684f1SStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8413f34684f1SStefano Zampini ierr = VecSet(pcis->vec1_global,0.0);CHKERRQ(ierr); 8414e176bc59SStefano Zampini ierr = VecScatterBegin(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8415e176bc59SStefano Zampini ierr = VecScatterEnd(matis->rctx,pcis->vec1_N,pcis->vec1_global,ADD_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8416f34684f1SStefano Zampini ierr = VecSum(pcis->vec1_global,&coarsesum);CHKERRQ(ierr); 8417f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Size of coarse problem is %d (%lf)\n",coarse_size,PetscRealPart(coarsesum));CHKERRQ(ierr); 8418b9b85e73SStefano Zampini if (pcbddc->dbg_flag > 1 || set_error_reduced) { 8419ca8b9ea9SStefano Zampini PetscInt *gidxs; 8420ca8b9ea9SStefano Zampini 8421ca8b9ea9SStefano Zampini ierr = PetscMalloc1(pcbddc->local_primal_size,&gidxs);CHKERRQ(ierr); 84223bbff08aSStefano Zampini ierr = ISLocalToGlobalMappingApply(pcis->mapping,pcbddc->local_primal_size,pcbddc->primal_indices_local_idxs,gidxs);CHKERRQ(ierr); 8423f34684f1SStefano Zampini ierr = PetscViewerASCIIPrintf(pcbddc->dbg_viewer,"Distribution of local primal indices\n");CHKERRQ(ierr); 8424f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8425f34684f1SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d\n",PetscGlobalRank);CHKERRQ(ierr); 8426f34684f1SStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) { 84274bc2dc4bSStefano 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); 8428f34684f1SStefano Zampini } 8429f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8430ca8b9ea9SStefano Zampini ierr = PetscFree(gidxs);CHKERRQ(ierr); 8431f34684f1SStefano Zampini } 8432f34684f1SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 84331575c14dSBarry Smith ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8434302440fdSBarry Smith if (set_error_reduced) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_PLIB,"BDDC Numbering of coarse dofs failed"); 8435f34684f1SStefano Zampini } 84368bec7fa6SStefano Zampini /* ierr = PetscPrintf(PetscObjectComm((PetscObject)pc),"Size of coarse problem is %d\n",coarse_size);CHKERRQ(ierr); */ 8437f34684f1SStefano Zampini /* get back data */ 8438f34684f1SStefano Zampini *coarse_size_n = coarse_size; 8439f34684f1SStefano Zampini *local_primal_indices_n = local_primal_indices; 8440674ae819SStefano Zampini PetscFunctionReturn(0); 8441674ae819SStefano Zampini } 8442674ae819SStefano Zampini 8443a7dc3881SStefano Zampini PetscErrorCode PCBDDCGlobalToLocal(VecScatter g2l_ctx,Vec gwork, Vec lwork, IS globalis, IS* localis) 8444e456f2a8SStefano Zampini { 8445e456f2a8SStefano Zampini IS localis_t; 8446a7dc3881SStefano Zampini PetscInt i,lsize,*idxs,n; 8447e456f2a8SStefano Zampini PetscScalar *vals; 8448e456f2a8SStefano Zampini PetscErrorCode ierr; 8449e456f2a8SStefano Zampini 8450e456f2a8SStefano Zampini PetscFunctionBegin; 8451a7dc3881SStefano Zampini /* get indices in local ordering exploiting local to global map */ 8452e456f2a8SStefano Zampini ierr = ISGetLocalSize(globalis,&lsize);CHKERRQ(ierr); 8453854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&vals);CHKERRQ(ierr); 8454e456f2a8SStefano Zampini for (i=0;i<lsize;i++) vals[i] = 1.0; 8455e456f2a8SStefano Zampini ierr = ISGetIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8456a7dc3881SStefano Zampini ierr = VecSet(gwork,0.0);CHKERRQ(ierr); 8457a7dc3881SStefano Zampini ierr = VecSet(lwork,0.0);CHKERRQ(ierr); 84581035eff8SStefano Zampini if (idxs) { /* multilevel guard */ 84593151afb1SStefano Zampini ierr = VecSetOption(gwork,VEC_IGNORE_NEGATIVE_INDICES,PETSC_TRUE);CHKERRQ(ierr); 8460a7dc3881SStefano Zampini ierr = VecSetValues(gwork,lsize,idxs,vals,INSERT_VALUES);CHKERRQ(ierr); 84611035eff8SStefano Zampini } 8462a7dc3881SStefano Zampini ierr = VecAssemblyBegin(gwork);CHKERRQ(ierr); 8463e456f2a8SStefano Zampini ierr = ISRestoreIndices(globalis,(const PetscInt**)&idxs);CHKERRQ(ierr); 8464e456f2a8SStefano Zampini ierr = PetscFree(vals);CHKERRQ(ierr); 8465a7dc3881SStefano Zampini ierr = VecAssemblyEnd(gwork);CHKERRQ(ierr); 8466a7dc3881SStefano Zampini /* now compute set in local ordering */ 8467a7dc3881SStefano Zampini ierr = VecScatterBegin(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8468a7dc3881SStefano Zampini ierr = VecScatterEnd(g2l_ctx,gwork,lwork,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8469a7dc3881SStefano Zampini ierr = VecGetArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8470a7dc3881SStefano Zampini ierr = VecGetSize(lwork,&n);CHKERRQ(ierr); 8471a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8472ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8473e456f2a8SStefano Zampini lsize++; 8474e456f2a8SStefano Zampini } 8475e456f2a8SStefano Zampini } 8476854ce69bSBarry Smith ierr = PetscMalloc1(lsize,&idxs);CHKERRQ(ierr); 8477a7dc3881SStefano Zampini for (i=0,lsize=0;i<n;i++) { 8478ff92baa0SMatthew G. Knepley if (PetscRealPart(vals[i]) > 0.5) { 8479e456f2a8SStefano Zampini idxs[lsize++] = i; 8480e456f2a8SStefano Zampini } 8481e456f2a8SStefano Zampini } 8482a7dc3881SStefano Zampini ierr = VecRestoreArrayRead(lwork,(const PetscScalar**)&vals);CHKERRQ(ierr); 8483a7dc3881SStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)gwork),lsize,idxs,PETSC_OWN_POINTER,&localis_t);CHKERRQ(ierr); 8484e456f2a8SStefano Zampini *localis = localis_t; 8485e456f2a8SStefano Zampini PetscFunctionReturn(0); 8486e456f2a8SStefano Zampini } 8487906d46d4SStefano Zampini 848808122e43SStefano Zampini PetscErrorCode PCBDDCSetUpSubSchurs(PC pc) 8489b96c3477SStefano Zampini { 8490a64f4aa4SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8491b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8492b96c3477SStefano Zampini PCBDDCSubSchurs sub_schurs=pcbddc->sub_schurs; 8493a64f4aa4SStefano Zampini Mat S_j; 8494b96c3477SStefano Zampini PetscInt *used_xadj,*used_adjncy; 8495b96c3477SStefano Zampini PetscBool free_used_adj; 8496b96c3477SStefano Zampini PetscErrorCode ierr; 8497b96c3477SStefano Zampini 8498b96c3477SStefano Zampini PetscFunctionBegin; 8499b96c3477SStefano Zampini /* decide the adjacency to be used for determining internal problems for local schur on subsets */ 8500b96c3477SStefano Zampini free_used_adj = PETSC_FALSE; 850108122e43SStefano Zampini if (pcbddc->sub_schurs_layers == -1) { 8502b96c3477SStefano Zampini used_xadj = NULL; 8503b96c3477SStefano Zampini used_adjncy = NULL; 8504b96c3477SStefano Zampini } else { 850508122e43SStefano Zampini if (pcbddc->sub_schurs_use_useradj && pcbddc->mat_graph->xadj) { 850608122e43SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 850708122e43SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 850808122e43SStefano Zampini } else if (pcbddc->computed_rowadj) { 8509b96c3477SStefano Zampini used_xadj = pcbddc->mat_graph->xadj; 8510b96c3477SStefano Zampini used_adjncy = pcbddc->mat_graph->adjncy; 8511b96c3477SStefano Zampini } else { 85122fffb893SStefano Zampini PetscBool flg_row=PETSC_FALSE; 8513b96c3477SStefano Zampini const PetscInt *xadj,*adjncy; 8514b96c3477SStefano Zampini PetscInt nvtxs; 8515b96c3477SStefano Zampini 85162fffb893SStefano Zampini ierr = MatGetRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 85172fffb893SStefano Zampini if (flg_row) { 8518b96c3477SStefano Zampini ierr = PetscMalloc2(nvtxs+1,&used_xadj,xadj[nvtxs],&used_adjncy);CHKERRQ(ierr); 8519b96c3477SStefano Zampini ierr = PetscMemcpy(used_xadj,xadj,(nvtxs+1)*sizeof(*xadj));CHKERRQ(ierr); 8520b96c3477SStefano Zampini ierr = PetscMemcpy(used_adjncy,adjncy,(xadj[nvtxs])*sizeof(*adjncy));CHKERRQ(ierr); 8521b96c3477SStefano Zampini free_used_adj = PETSC_TRUE; 85222fffb893SStefano Zampini } else { 85232fffb893SStefano Zampini pcbddc->sub_schurs_layers = -1; 85242fffb893SStefano Zampini used_xadj = NULL; 85252fffb893SStefano Zampini used_adjncy = NULL; 85262fffb893SStefano Zampini } 85272fffb893SStefano Zampini ierr = MatRestoreRowIJ(pcbddc->local_mat,0,PETSC_TRUE,PETSC_FALSE,&nvtxs,&xadj,&adjncy,&flg_row);CHKERRQ(ierr); 8528b96c3477SStefano Zampini } 8529b96c3477SStefano Zampini } 8530d5574798SStefano Zampini 8531d5574798SStefano Zampini /* setup sub_schurs data */ 8532a64f4aa4SStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8533df4d28bfSStefano Zampini if (!sub_schurs->schur_explicit) { 8534df4d28bfSStefano Zampini /* pcbddc->ksp_D up to date only if not using MatFactor with Schur complement support */ 8535a64f4aa4SStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 853691af6908SStefano 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); 8537a64f4aa4SStefano Zampini } else { 853872b8c272SStefano Zampini Mat change = NULL; 85399d54b7f4SStefano Zampini Vec scaling = NULL; 8540111315fdSstefano_zampini IS change_primal = NULL, iP; 8541111315fdSstefano_zampini PetscInt benign_n; 8542111315fdSstefano_zampini PetscBool reuse_solvers = (PetscBool)!pcbddc->use_change_of_basis; 8543111315fdSstefano_zampini PetscBool isseqaij,need_change = PETSC_FALSE; 8544111315fdSstefano_zampini PetscBool discrete_harmonic = PETSC_FALSE; 8545a3df083aSStefano Zampini 85465feab87aSStefano Zampini if (!pcbddc->use_vertices && reuse_solvers) { 85475feab87aSStefano Zampini PetscInt n_vertices; 85485feab87aSStefano Zampini 85495feab87aSStefano Zampini ierr = ISGetLocalSize(sub_schurs->is_vertices,&n_vertices);CHKERRQ(ierr); 85502034aafcSStefano Zampini reuse_solvers = (PetscBool)!n_vertices; 85515feab87aSStefano Zampini } 855204708bb6SStefano Zampini ierr = PetscObjectTypeCompare((PetscObject)pcbddc->local_mat,MATSEQAIJ,&isseqaij);CHKERRQ(ierr); 855304708bb6SStefano Zampini if (!isseqaij) { 855404708bb6SStefano Zampini Mat_IS* matis = (Mat_IS*)pc->pmat->data; 855504708bb6SStefano Zampini if (matis->A == pcbddc->local_mat) { 855604708bb6SStefano Zampini ierr = MatDestroy(&pcbddc->local_mat);CHKERRQ(ierr); 855704708bb6SStefano Zampini ierr = MatConvert(matis->A,MATSEQAIJ,MAT_INITIAL_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 855804708bb6SStefano Zampini } else { 8559511c6705SHong Zhang ierr = MatConvert(pcbddc->local_mat,MATSEQAIJ,MAT_INPLACE_MATRIX,&pcbddc->local_mat);CHKERRQ(ierr); 856004708bb6SStefano Zampini } 856104708bb6SStefano Zampini } 8562a3df083aSStefano Zampini if (!pcbddc->benign_change_explicit) { 8563a3df083aSStefano Zampini benign_n = pcbddc->benign_n; 8564ca92afb2SStefano Zampini } else { 8565a3df083aSStefano Zampini benign_n = 0; 8566ca92afb2SStefano Zampini } 8567b7ab4a40SStefano Zampini /* sub_schurs->change is a local object; instead, PCBDDCConstraintsSetUp and the quantities used in the test below are logically collective on pc. 8568b7ab4a40SStefano Zampini We need a global reduction to avoid possible deadlocks. 8569b7ab4a40SStefano Zampini We assume that sub_schurs->change is created once, and then reused for different solves, unless the topography has been recomputed */ 857072b8c272SStefano Zampini if (pcbddc->adaptive_userdefined || (pcbddc->deluxe_zerorows && !pcbddc->use_change_of_basis)) { 857122db5ddcSStefano Zampini PetscBool have_loc_change = (PetscBool)(!!sub_schurs->change); 8572b7ab4a40SStefano Zampini ierr = MPIU_Allreduce(&have_loc_change,&need_change,1,MPIU_BOOL,MPI_LOR,PetscObjectComm((PetscObject)pc));CHKERRQ(ierr); 857322db5ddcSStefano Zampini need_change = (PetscBool)(!need_change); 8574b7ab4a40SStefano Zampini } 8575b7ab4a40SStefano Zampini /* If the user defines additional constraints, we import them here. 8576b7ab4a40SStefano 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 */ 8577b7ab4a40SStefano Zampini if (need_change) { 857888c03ad3SStefano Zampini PC_IS *pcisf; 857988c03ad3SStefano Zampini PC_BDDC *pcbddcf; 858088c03ad3SStefano Zampini PC pcf; 858188c03ad3SStefano Zampini 8582e4d548c7SStefano Zampini if (pcbddc->sub_schurs_rebuild) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP,"Cannot compute change of basis with a different graph"); 858388c03ad3SStefano Zampini ierr = PCCreate(PetscObjectComm((PetscObject)pc),&pcf);CHKERRQ(ierr); 858488c03ad3SStefano Zampini ierr = PCSetOperators(pcf,pc->mat,pc->pmat);CHKERRQ(ierr); 858588c03ad3SStefano Zampini ierr = PCSetType(pcf,PCBDDC);CHKERRQ(ierr); 8586b9be95fcSstefano_zampini 858788c03ad3SStefano Zampini /* hacks */ 858888c03ad3SStefano Zampini pcisf = (PC_IS*)pcf->data; 858972b8c272SStefano Zampini pcisf->is_B_local = pcis->is_B_local; 859072b8c272SStefano Zampini pcisf->vec1_N = pcis->vec1_N; 859172b8c272SStefano Zampini pcisf->BtoNmap = pcis->BtoNmap; 859272b8c272SStefano Zampini pcisf->n = pcis->n; 859372b8c272SStefano Zampini pcisf->n_B = pcis->n_B; 859488c03ad3SStefano Zampini pcbddcf = (PC_BDDC*)pcf->data; 859588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->mat_graph);CHKERRQ(ierr); 859688c03ad3SStefano Zampini pcbddcf->mat_graph = pcbddc->mat_graph; 859788c03ad3SStefano Zampini pcbddcf->use_faces = PETSC_TRUE; 859888c03ad3SStefano Zampini pcbddcf->use_change_of_basis = PETSC_TRUE; 859988c03ad3SStefano Zampini pcbddcf->use_change_on_faces = PETSC_TRUE; 860072b8c272SStefano Zampini pcbddcf->use_qr_single = PETSC_TRUE; 860188c03ad3SStefano Zampini pcbddcf->fake_change = PETSC_TRUE; 8602b9be95fcSstefano_zampini 8603b9be95fcSstefano_zampini /* setup constraints so that we can get information on primal vertices and change of basis (in local numbering) */ 860488c03ad3SStefano Zampini ierr = PCBDDCConstraintsSetUp(pcf);CHKERRQ(ierr); 860572b8c272SStefano Zampini sub_schurs->change_with_qr = pcbddcf->use_qr_single; 860672b8c272SStefano Zampini ierr = ISCreateGeneral(PETSC_COMM_SELF,pcbddcf->n_vertices,pcbddcf->local_primal_ref_node,PETSC_COPY_VALUES,&change_primal);CHKERRQ(ierr); 860772b8c272SStefano Zampini change = pcbddcf->ConstraintMatrix; 860872b8c272SStefano Zampini pcbddcf->ConstraintMatrix = NULL; 8609b9be95fcSstefano_zampini 861088c03ad3SStefano Zampini /* free unneeded memory allocated in PCBDDCConstraintsSetUp */ 861172b8c272SStefano Zampini ierr = PetscFree(pcbddcf->sub_schurs);CHKERRQ(ierr); 861288c03ad3SStefano Zampini ierr = MatNullSpaceDestroy(&pcbddcf->onearnullspace);CHKERRQ(ierr); 861388c03ad3SStefano Zampini ierr = PetscFree2(pcbddcf->local_primal_ref_node,pcbddcf->local_primal_ref_mult);CHKERRQ(ierr); 861488c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->primal_indices_local_idxs);CHKERRQ(ierr); 861588c03ad3SStefano Zampini ierr = PetscFree(pcbddcf->onearnullvecs_state);CHKERRQ(ierr); 861688c03ad3SStefano Zampini ierr = PetscFree(pcf->data);CHKERRQ(ierr); 861788c03ad3SStefano Zampini pcf->ops->destroy = NULL; 8618b9be95fcSstefano_zampini pcf->ops->reset = NULL; 861988c03ad3SStefano Zampini ierr = PCDestroy(&pcf);CHKERRQ(ierr); 862088c03ad3SStefano Zampini } 86219d54b7f4SStefano Zampini if (!pcbddc->use_deluxe_scaling) scaling = pcis->D; 8622111315fdSstefano_zampini 8623111315fdSstefano_zampini ierr = PetscObjectQuery((PetscObject)pc,"__KSPFETIDP_iP",(PetscObject*)&iP);CHKERRQ(ierr); 8624111315fdSstefano_zampini if (iP) { 8625111315fdSstefano_zampini ierr = PetscOptionsBegin(PetscObjectComm((PetscObject)iP),sub_schurs->prefix,"BDDC sub_schurs options","PC");CHKERRQ(ierr); 8626111315fdSstefano_zampini ierr = PetscOptionsBool("-sub_schurs_discrete_harmonic",NULL,NULL,discrete_harmonic,&discrete_harmonic,NULL);CHKERRQ(ierr); 8627111315fdSstefano_zampini ierr = PetscOptionsEnd();CHKERRQ(ierr); 8628111315fdSstefano_zampini } 8629111315fdSstefano_zampini if (discrete_harmonic) { 8630111315fdSstefano_zampini Mat A; 8631111315fdSstefano_zampini ierr = MatDuplicate(pcbddc->local_mat,MAT_COPY_VALUES,&A);CHKERRQ(ierr); 8632111315fdSstefano_zampini ierr = MatZeroRowsColumnsIS(A,iP,1.0,NULL,NULL);CHKERRQ(ierr); 8633111315fdSstefano_zampini ierr = PetscObjectCompose((PetscObject)A,"__KSPFETIDP_iP",(PetscObject)iP);CHKERRQ(ierr); 8634111315fdSstefano_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); 8635111315fdSstefano_zampini ierr = MatDestroy(&A);CHKERRQ(ierr); 8636111315fdSstefano_zampini } else { 863791af6908SStefano 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); 8638111315fdSstefano_zampini } 863972b8c272SStefano Zampini ierr = MatDestroy(&change);CHKERRQ(ierr); 864072b8c272SStefano Zampini ierr = ISDestroy(&change_primal);CHKERRQ(ierr); 8641ca92afb2SStefano Zampini } 8642d12d3064SStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8643b96c3477SStefano Zampini 8644b96c3477SStefano Zampini /* free adjacency */ 8645b96c3477SStefano Zampini if (free_used_adj) { 8646b96c3477SStefano Zampini ierr = PetscFree2(used_xadj,used_adjncy);CHKERRQ(ierr); 8647b96c3477SStefano Zampini } 8648b96c3477SStefano Zampini PetscFunctionReturn(0); 8649b96c3477SStefano Zampini } 8650b96c3477SStefano Zampini 865108122e43SStefano Zampini PetscErrorCode PCBDDCInitSubSchurs(PC pc) 8652b96c3477SStefano Zampini { 8653b96c3477SStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8654b96c3477SStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8655b96c3477SStefano Zampini PCBDDCGraph graph; 8656b96c3477SStefano Zampini PetscErrorCode ierr; 8657b96c3477SStefano Zampini 8658b96c3477SStefano Zampini PetscFunctionBegin; 8659b96c3477SStefano Zampini /* attach interface graph for determining subsets */ 866008122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { /* in case rebuild has been requested, it uses a graph generated only by the neighbouring information */ 86613301b35fSStefano Zampini IS verticesIS,verticescomm; 86623301b35fSStefano Zampini PetscInt vsize,*idxs; 8663b96c3477SStefano Zampini 8664b96c3477SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 86653301b35fSStefano Zampini ierr = ISGetSize(verticesIS,&vsize);CHKERRQ(ierr); 86663301b35fSStefano Zampini ierr = ISGetIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 86673301b35fSStefano Zampini ierr = ISCreateGeneral(PetscObjectComm((PetscObject)pc),vsize,idxs,PETSC_COPY_VALUES,&verticescomm);CHKERRQ(ierr); 86683301b35fSStefano Zampini ierr = ISRestoreIndices(verticesIS,(const PetscInt**)&idxs);CHKERRQ(ierr); 8669c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(pcbddc->mat_graph,NULL,NULL,NULL,NULL,&verticesIS);CHKERRQ(ierr); 8670b96c3477SStefano Zampini ierr = PCBDDCGraphCreate(&graph);CHKERRQ(ierr); 8671be12c134Sstefano_zampini ierr = PCBDDCGraphInit(graph,pcbddc->mat_graph->l2gmap,pcbddc->mat_graph->nvtxs_global,pcbddc->graphmaxcount);CHKERRQ(ierr); 8672441e0de0SStefano Zampini ierr = PCBDDCGraphSetUp(graph,pcbddc->mat_graph->custom_minimal_size,NULL,pcbddc->DirichletBoundariesLocal,0,NULL,verticescomm);CHKERRQ(ierr); 86733301b35fSStefano Zampini ierr = ISDestroy(&verticescomm);CHKERRQ(ierr); 8674b96c3477SStefano Zampini ierr = PCBDDCGraphComputeConnectedComponents(graph);CHKERRQ(ierr); 8675b96c3477SStefano Zampini } else { 8676b96c3477SStefano Zampini graph = pcbddc->mat_graph; 8677b96c3477SStefano Zampini } 8678e4d548c7SStefano Zampini /* print some info */ 86795c643e28SStefano Zampini if (pcbddc->dbg_flag && !pcbddc->sub_schurs_rebuild) { 8680e4d548c7SStefano Zampini IS vertices; 8681e4d548c7SStefano Zampini PetscInt nv,nedges,nfaces; 8682c8272957SStefano Zampini ierr = PCBDDCGraphASCIIView(graph,pcbddc->dbg_flag,pcbddc->dbg_viewer);CHKERRQ(ierr); 8683e4d548c7SStefano Zampini ierr = PCBDDCGraphGetCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8684e4d548c7SStefano Zampini ierr = ISGetSize(vertices,&nv);CHKERRQ(ierr); 8685e4d548c7SStefano Zampini ierr = PetscViewerASCIIPushSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8686e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"--------------------------------------------------------------\n");CHKERRQ(ierr); 8687e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate vertices (%d)\n",PetscGlobalRank,nv,pcbddc->use_vertices);CHKERRQ(ierr); 8688e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate edges (%d)\n",PetscGlobalRank,nedges,pcbddc->use_edges);CHKERRQ(ierr); 8689e4d548c7SStefano Zampini ierr = PetscViewerASCIISynchronizedPrintf(pcbddc->dbg_viewer,"Subdomain %04d got %02d local candidate faces (%d)\n",PetscGlobalRank,nfaces,pcbddc->use_faces);CHKERRQ(ierr); 8690e4d548c7SStefano Zampini ierr = PetscViewerFlush(pcbddc->dbg_viewer);CHKERRQ(ierr); 8691e4d548c7SStefano Zampini ierr = PetscViewerASCIIPopSynchronized(pcbddc->dbg_viewer);CHKERRQ(ierr); 8692c8272957SStefano Zampini ierr = PCBDDCGraphRestoreCandidatesIS(graph,&nfaces,NULL,&nedges,NULL,&vertices);CHKERRQ(ierr); 8693e4d548c7SStefano Zampini } 8694b96c3477SStefano Zampini 8695b96c3477SStefano Zampini /* sub_schurs init */ 8696b334f244SStefano Zampini if (!pcbddc->sub_schurs) { 8697b334f244SStefano Zampini ierr = PCBDDCSubSchursCreate(&pcbddc->sub_schurs);CHKERRQ(ierr); 8698b334f244SStefano Zampini } 869988113c35SStefano 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); 8700a64f4aa4SStefano Zampini 8701b96c3477SStefano Zampini /* free graph struct */ 870208122e43SStefano Zampini if (pcbddc->sub_schurs_rebuild) { 8703b96c3477SStefano Zampini ierr = PCBDDCGraphDestroy(&graph);CHKERRQ(ierr); 8704b96c3477SStefano Zampini } 8705b96c3477SStefano Zampini PetscFunctionReturn(0); 8706b96c3477SStefano Zampini } 8707fa34dd3eSStefano Zampini 8708fa34dd3eSStefano Zampini PetscErrorCode PCBDDCCheckOperator(PC pc) 8709fa34dd3eSStefano Zampini { 8710fa34dd3eSStefano Zampini PC_IS *pcis=(PC_IS*)pc->data; 8711fa34dd3eSStefano Zampini PC_BDDC *pcbddc=(PC_BDDC*)pc->data; 8712fa34dd3eSStefano Zampini PetscErrorCode ierr; 8713fa34dd3eSStefano Zampini 8714fa34dd3eSStefano Zampini PetscFunctionBegin; 8715fa34dd3eSStefano Zampini if (pcbddc->n_vertices == pcbddc->local_primal_size) { 8716fa34dd3eSStefano Zampini IS zerodiag = NULL; 87174f1b2e48SStefano Zampini Mat S_j,B0_B=NULL; 8718fa34dd3eSStefano Zampini Vec dummy_vec=NULL,vec_check_B,vec_scale_P; 87194f1b2e48SStefano Zampini PetscScalar *p0_check,*array,*array2; 872075c01103SStefano Zampini PetscReal norm; 8721fa34dd3eSStefano Zampini PetscInt i; 8722fa34dd3eSStefano Zampini 8723fa34dd3eSStefano Zampini /* B0 and B0_B */ 8724fa34dd3eSStefano Zampini if (zerodiag) { 8725fa34dd3eSStefano Zampini IS dummy; 8726fa34dd3eSStefano Zampini 87274f1b2e48SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,pcbddc->benign_n,0,1,&dummy);CHKERRQ(ierr); 87287dae84e0SHong Zhang ierr = MatCreateSubMatrix(pcbddc->benign_B0,dummy,pcis->is_B_local,MAT_INITIAL_MATRIX,&B0_B);CHKERRQ(ierr); 8729fa34dd3eSStefano Zampini ierr = MatCreateVecs(B0_B,NULL,&dummy_vec);CHKERRQ(ierr); 8730fa34dd3eSStefano Zampini ierr = ISDestroy(&dummy);CHKERRQ(ierr); 8731fa34dd3eSStefano Zampini } 8732fa34dd3eSStefano Zampini /* I need a primal vector to scale primal nodes since BDDC sums contibutions */ 8733fa34dd3eSStefano Zampini ierr = VecDuplicate(pcbddc->vec1_P,&vec_scale_P);CHKERRQ(ierr); 8734fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->vec1_P,1.0);CHKERRQ(ierr); 8735fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8736fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8737fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8738fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,vec_scale_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8739fa34dd3eSStefano Zampini ierr = VecReciprocal(vec_scale_P);CHKERRQ(ierr); 8740fa34dd3eSStefano Zampini /* S_j */ 8741fa34dd3eSStefano Zampini ierr = MatCreateSchurComplement(pcis->A_II,pcis->A_II,pcis->A_IB,pcis->A_BI,pcis->A_BB,&S_j);CHKERRQ(ierr); 8742fa34dd3eSStefano Zampini ierr = MatSchurComplementSetKSP(S_j,pcbddc->ksp_D);CHKERRQ(ierr); 8743fa34dd3eSStefano Zampini 8744fa34dd3eSStefano Zampini /* mimic vector in \widetilde{W}_\Gamma */ 8745fa34dd3eSStefano Zampini ierr = VecSetRandom(pcis->vec1_N,NULL);CHKERRQ(ierr); 8746fa34dd3eSStefano Zampini /* continuous in primal space */ 8747fa34dd3eSStefano Zampini ierr = VecSetRandom(pcbddc->coarse_vec,NULL);CHKERRQ(ierr); 8748fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8749fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8750fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 87514f1b2e48SStefano Zampini ierr = PetscCalloc1(pcbddc->benign_n,&p0_check);CHKERRQ(ierr); 87524f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) p0_check[i] = array[pcbddc->local_primal_size-pcbddc->benign_n+i]; 8753fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8754fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8755fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8756fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8757fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8758fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec2_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8759fa34dd3eSStefano Zampini ierr = VecDuplicate(pcis->vec2_B,&vec_check_B);CHKERRQ(ierr); 8760fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec2_B,vec_check_B);CHKERRQ(ierr); 8761fa34dd3eSStefano Zampini 8762fa34dd3eSStefano Zampini /* assemble rhs for coarse problem */ 8763fa34dd3eSStefano Zampini /* widetilde{S}_\Gamma w_\Gamma + \widetilde{B0}^T_B p0 */ 8764fa34dd3eSStefano Zampini /* local with Schur */ 8765fa34dd3eSStefano Zampini ierr = MatMult(S_j,pcis->vec2_B,pcis->vec1_B);CHKERRQ(ierr); 8766fa34dd3eSStefano Zampini if (zerodiag) { 8767fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 87684f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) array[i] = p0_check[i]; 8769fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8770fa34dd3eSStefano Zampini ierr = MatMultTransposeAdd(B0_B,dummy_vec,pcis->vec1_B,pcis->vec1_B);CHKERRQ(ierr); 8771fa34dd3eSStefano Zampini } 8772fa34dd3eSStefano Zampini /* sum on primal nodes the local contributions */ 8773fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8774fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_B,pcis->vec1_N,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8775fa34dd3eSStefano Zampini ierr = VecGetArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8776fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8777fa34dd3eSStefano Zampini for (i=0;i<pcbddc->local_primal_size;i++) array2[i] = array[pcbddc->local_primal_ref_node[i]]; 8778fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array2);CHKERRQ(ierr); 8779fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcis->vec1_N,&array);CHKERRQ(ierr); 8780fa34dd3eSStefano Zampini ierr = VecSet(pcbddc->coarse_vec,0.);CHKERRQ(ierr); 8781fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8782fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->vec1_P,pcbddc->coarse_vec,ADD_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8783fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8784fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcbddc->coarse_loc_to_glob,pcbddc->coarse_vec,pcbddc->vec1_P,INSERT_VALUES,SCATTER_REVERSE);CHKERRQ(ierr); 8785fa34dd3eSStefano Zampini ierr = VecGetArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8786fa34dd3eSStefano Zampini /* scale primal nodes (BDDC sums contibutions) */ 8787fa34dd3eSStefano Zampini ierr = VecPointwiseMult(pcbddc->vec1_P,vec_scale_P,pcbddc->vec1_P);CHKERRQ(ierr); 8788fa34dd3eSStefano Zampini ierr = VecSetValues(pcis->vec1_N,pcbddc->local_primal_size,pcbddc->local_primal_ref_node,array,INSERT_VALUES);CHKERRQ(ierr); 8789fa34dd3eSStefano Zampini ierr = VecRestoreArray(pcbddc->vec1_P,&array);CHKERRQ(ierr); 8790fa34dd3eSStefano Zampini ierr = VecAssemblyBegin(pcis->vec1_N);CHKERRQ(ierr); 8791fa34dd3eSStefano Zampini ierr = VecAssemblyEnd(pcis->vec1_N);CHKERRQ(ierr); 8792fa34dd3eSStefano Zampini ierr = VecScatterBegin(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8793fa34dd3eSStefano Zampini ierr = VecScatterEnd(pcis->N_to_B,pcis->vec1_N,pcis->vec1_B,INSERT_VALUES,SCATTER_FORWARD);CHKERRQ(ierr); 8794fa34dd3eSStefano Zampini /* global: \widetilde{B0}_B w_\Gamma */ 8795fa34dd3eSStefano Zampini if (zerodiag) { 8796fa34dd3eSStefano Zampini ierr = MatMult(B0_B,pcis->vec2_B,dummy_vec);CHKERRQ(ierr); 8797fa34dd3eSStefano Zampini ierr = VecGetArray(dummy_vec,&array);CHKERRQ(ierr); 87984f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) pcbddc->benign_p0[i] = array[i]; 8799fa34dd3eSStefano Zampini ierr = VecRestoreArray(dummy_vec,&array);CHKERRQ(ierr); 8800fa34dd3eSStefano Zampini } 8801fa34dd3eSStefano Zampini /* BDDC */ 8802fa34dd3eSStefano Zampini ierr = VecSet(pcis->vec1_D,0.);CHKERRQ(ierr); 8803fa34dd3eSStefano Zampini ierr = PCBDDCApplyInterfacePreconditioner(pc,PETSC_FALSE);CHKERRQ(ierr); 8804fa34dd3eSStefano Zampini 8805fa34dd3eSStefano Zampini ierr = VecCopy(pcis->vec1_B,pcis->vec2_B);CHKERRQ(ierr); 8806fa34dd3eSStefano Zampini ierr = VecAXPY(pcis->vec1_B,-1.0,vec_check_B);CHKERRQ(ierr); 8807fa34dd3eSStefano Zampini ierr = VecNorm(pcis->vec1_B,NORM_INFINITY,&norm);CHKERRQ(ierr); 8808fa34dd3eSStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC local error is %1.4e\n",PetscGlobalRank,norm); 88094f1b2e48SStefano Zampini for (i=0;i<pcbddc->benign_n;i++) { 88104f1b2e48SStefano Zampini PetscPrintf(PETSC_COMM_SELF,"[%d] BDDC p0[%d] error is %1.4e\n",PetscGlobalRank,i,PetscAbsScalar(pcbddc->benign_p0[i]-p0_check[i])); 8811fa34dd3eSStefano Zampini } 88124f1b2e48SStefano Zampini ierr = PetscFree(p0_check);CHKERRQ(ierr); 8813fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_scale_P);CHKERRQ(ierr); 8814fa34dd3eSStefano Zampini ierr = VecDestroy(&vec_check_B);CHKERRQ(ierr); 8815fa34dd3eSStefano Zampini ierr = VecDestroy(&dummy_vec);CHKERRQ(ierr); 8816fa34dd3eSStefano Zampini ierr = MatDestroy(&S_j);CHKERRQ(ierr); 8817fa34dd3eSStefano Zampini ierr = MatDestroy(&B0_B);CHKERRQ(ierr); 8818fa34dd3eSStefano Zampini } 8819fa34dd3eSStefano Zampini PetscFunctionReturn(0); 8820fa34dd3eSStefano Zampini } 88211e0482f5SStefano Zampini 88221e0482f5SStefano Zampini #include <../src/mat/impls/aij/mpi/mpiaij.h> 88231e0482f5SStefano Zampini PetscErrorCode MatMPIAIJRestrict(Mat A, MPI_Comm ccomm, Mat *B) 88241e0482f5SStefano Zampini { 88251e0482f5SStefano Zampini Mat At; 88261e0482f5SStefano Zampini IS rows; 88271e0482f5SStefano Zampini PetscInt rst,ren; 88281e0482f5SStefano Zampini PetscErrorCode ierr; 88291e0482f5SStefano Zampini PetscLayout rmap; 88301e0482f5SStefano Zampini 88311e0482f5SStefano Zampini PetscFunctionBegin; 88321e0482f5SStefano Zampini rst = ren = 0; 88331e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 88341e0482f5SStefano Zampini ierr = PetscLayoutCreate(ccomm,&rmap);CHKERRQ(ierr); 88351e0482f5SStefano Zampini ierr = PetscLayoutSetSize(rmap,A->rmap->N);CHKERRQ(ierr); 88361e0482f5SStefano Zampini ierr = PetscLayoutSetBlockSize(rmap,1);CHKERRQ(ierr); 88371e0482f5SStefano Zampini ierr = PetscLayoutSetUp(rmap);CHKERRQ(ierr); 88381e0482f5SStefano Zampini ierr = PetscLayoutGetRange(rmap,&rst,&ren);CHKERRQ(ierr); 88391e0482f5SStefano Zampini } 8840e07686f2SStefano Zampini ierr = ISCreateStride(PetscObjectComm((PetscObject)A),ren-rst,rst,1,&rows);CHKERRQ(ierr); 88417dae84e0SHong Zhang ierr = MatCreateSubMatrix(A,rows,NULL,MAT_INITIAL_MATRIX,&At);CHKERRQ(ierr); 88421e0482f5SStefano Zampini ierr = ISDestroy(&rows);CHKERRQ(ierr); 88431e0482f5SStefano Zampini 88441e0482f5SStefano Zampini if (ccomm != MPI_COMM_NULL) { 88451e0482f5SStefano Zampini Mat_MPIAIJ *a,*b; 88461e0482f5SStefano Zampini IS from,to; 88471e0482f5SStefano Zampini Vec gvec; 88481e0482f5SStefano Zampini PetscInt lsize; 88491e0482f5SStefano Zampini 88501e0482f5SStefano Zampini ierr = MatCreate(ccomm,B);CHKERRQ(ierr); 88511e0482f5SStefano Zampini ierr = MatSetSizes(*B,ren-rst,PETSC_DECIDE,PETSC_DECIDE,At->cmap->N);CHKERRQ(ierr); 88521e0482f5SStefano Zampini ierr = MatSetType(*B,MATAIJ);CHKERRQ(ierr); 88531e0482f5SStefano Zampini ierr = PetscLayoutDestroy(&((*B)->rmap));CHKERRQ(ierr); 88541e0482f5SStefano Zampini ierr = PetscLayoutSetUp((*B)->cmap);CHKERRQ(ierr); 88551e0482f5SStefano Zampini a = (Mat_MPIAIJ*)At->data; 88561e0482f5SStefano Zampini b = (Mat_MPIAIJ*)(*B)->data; 88571e0482f5SStefano Zampini ierr = MPI_Comm_size(ccomm,&b->size);CHKERRQ(ierr); 88581e0482f5SStefano Zampini ierr = MPI_Comm_rank(ccomm,&b->rank);CHKERRQ(ierr); 88591e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->A);CHKERRQ(ierr); 88601e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->B);CHKERRQ(ierr); 88611e0482f5SStefano Zampini b->A = a->A; 88621e0482f5SStefano Zampini b->B = a->B; 88631e0482f5SStefano Zampini 88641e0482f5SStefano Zampini b->donotstash = a->donotstash; 88651e0482f5SStefano Zampini b->roworiented = a->roworiented; 88661e0482f5SStefano Zampini b->rowindices = 0; 88671e0482f5SStefano Zampini b->rowvalues = 0; 88681e0482f5SStefano Zampini b->getrowactive = PETSC_FALSE; 88691e0482f5SStefano Zampini 88701e0482f5SStefano Zampini (*B)->rmap = rmap; 88711e0482f5SStefano Zampini (*B)->factortype = A->factortype; 88721e0482f5SStefano Zampini (*B)->assembled = PETSC_TRUE; 88731e0482f5SStefano Zampini (*B)->insertmode = NOT_SET_VALUES; 88741e0482f5SStefano Zampini (*B)->preallocated = PETSC_TRUE; 88751e0482f5SStefano Zampini 88761e0482f5SStefano Zampini if (a->colmap) { 88771e0482f5SStefano Zampini #if defined(PETSC_USE_CTABLE) 88781e0482f5SStefano Zampini ierr = PetscTableCreateCopy(a->colmap,&b->colmap);CHKERRQ(ierr); 88791e0482f5SStefano Zampini #else 88801e0482f5SStefano Zampini ierr = PetscMalloc1(At->cmap->N,&b->colmap);CHKERRQ(ierr); 88811e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)*B,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 88821e0482f5SStefano Zampini ierr = PetscMemcpy(b->colmap,a->colmap,At->cmap->N*sizeof(PetscInt));CHKERRQ(ierr); 88831e0482f5SStefano Zampini #endif 88841e0482f5SStefano Zampini } else b->colmap = 0; 88851e0482f5SStefano Zampini if (a->garray) { 88861e0482f5SStefano Zampini PetscInt len; 88871e0482f5SStefano Zampini len = a->B->cmap->n; 88881e0482f5SStefano Zampini ierr = PetscMalloc1(len+1,&b->garray);CHKERRQ(ierr); 88891e0482f5SStefano Zampini ierr = PetscLogObjectMemory((PetscObject)(*B),len*sizeof(PetscInt));CHKERRQ(ierr); 88901e0482f5SStefano Zampini if (len) { ierr = PetscMemcpy(b->garray,a->garray,len*sizeof(PetscInt));CHKERRQ(ierr); } 88911e0482f5SStefano Zampini } else b->garray = 0; 88921e0482f5SStefano Zampini 88931e0482f5SStefano Zampini ierr = PetscObjectReference((PetscObject)a->lvec);CHKERRQ(ierr); 88941e0482f5SStefano Zampini b->lvec = a->lvec; 88951e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->lvec);CHKERRQ(ierr); 88961e0482f5SStefano Zampini 88971e0482f5SStefano Zampini /* cannot use VecScatterCopy */ 88981e0482f5SStefano Zampini ierr = VecGetLocalSize(b->lvec,&lsize);CHKERRQ(ierr); 88991e0482f5SStefano Zampini ierr = ISCreateGeneral(ccomm,lsize,b->garray,PETSC_USE_POINTER,&from);CHKERRQ(ierr); 89001e0482f5SStefano Zampini ierr = ISCreateStride(PETSC_COMM_SELF,lsize,0,1,&to);CHKERRQ(ierr); 89011e0482f5SStefano Zampini ierr = MatCreateVecs(*B,&gvec,NULL);CHKERRQ(ierr); 89021e0482f5SStefano Zampini ierr = VecScatterCreate(gvec,from,b->lvec,to,&b->Mvctx);CHKERRQ(ierr); 89031e0482f5SStefano Zampini ierr = PetscLogObjectParent((PetscObject)*B,(PetscObject)b->Mvctx);CHKERRQ(ierr); 89041e0482f5SStefano Zampini ierr = ISDestroy(&from);CHKERRQ(ierr); 89051e0482f5SStefano Zampini ierr = ISDestroy(&to);CHKERRQ(ierr); 89061e0482f5SStefano Zampini ierr = VecDestroy(&gvec);CHKERRQ(ierr); 89071e0482f5SStefano Zampini } 89081e0482f5SStefano Zampini ierr = MatDestroy(&At);CHKERRQ(ierr); 89091e0482f5SStefano Zampini PetscFunctionReturn(0); 89101e0482f5SStefano Zampini } 8911